diff --git a/.env.example b/.env.example index e2999483..ca67114f 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,9 @@ FEYNMAN_MODEL= FEYNMAN_THINKING=medium +# Optional override for PDF scratch Markdown written by fetch_content. +# Default: /.feynman/cache/fetch-content +FEYNMAN_FETCH_CACHE_DIR= # PostHog telemetry defaults to the Feynman project created for this repo. # Set FEYNMAN_TELEMETRY=off to disable, or override these for another PostHog project. FEYNMAN_TELEMETRY=1 diff --git a/.feynman/config/keybindings.json b/.feynman/config/keybindings.json new file mode 100644 index 00000000..ec2edcfd --- /dev/null +++ b/.feynman/config/keybindings.json @@ -0,0 +1,9 @@ +{ + "tui.input.newLine": [ + "ctrl+j", + "alt+enter" + ], + "app.message.followUp": [ + "shift+enter" + ] +} diff --git a/.feynman/runtime-package-lock.json b/.feynman/runtime-package-lock.json new file mode 100644 index 00000000..41f0d7b5 --- /dev/null +++ b/.feynman/runtime-package-lock.json @@ -0,0 +1,6755 @@ +{ + "name": "feynman-runtime", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "feynman-runtime", + "dependencies": { + "@companion-ai/alpha-hub": "0.1.3", + "@earendil-works/pi-agent-core": "0.82.1", + "@earendil-works/pi-ai": "0.82.1", + "@earendil-works/pi-coding-agent": "0.82.1", + "@earendil-works/pi-tui": "0.82.1", + "brace-expansion": "5.0.8", + "pi-btw": "0.4.1", + "pi-docparser": "3.0.1", + "pi-otel": "0.1.0", + "pi-subagents": "0.37.2", + "pi-web-access": "0.15.0", + "typebox": "1.1.38" + } + }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.91.1", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.91.1.tgz", + "integrity": "sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==", + "license": "MIT", + "dependencies": { + "json-schema-to-ts": "^3.1.1" + }, + "bin": { + "anthropic-ai-sdk": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-bedrock-runtime": { + "version": "3.1048.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1048.0.tgz", + "integrity": "sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/credential-provider-node": "^3.972.42", + "@aws-sdk/eventstream-handler-node": "^3.972.16", + "@aws-sdk/middleware-eventstream": "^3.972.12", + "@aws-sdk/middleware-websocket": "^3.972.19", + "@aws-sdk/token-providers": "3.1048.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/fetch-http-handler": "^5.4.2", + "@smithy/node-http-handler": "^4.7.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.977.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.977.1.tgz", + "integrity": "sha512-KVtQRtc00ES/y+Sc3vYXeP6pCIcNlBJCZOwvqSy8ZpVGmbM5+IG+AfhuTKQ2oXmIVqZJewaGMMpzPkywC6xg0w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.974.2", + "@aws-sdk/xml-builder": "^3.972.37", + "@aws/lambda-invoke-store": "^0.3.0", + "@smithy/core": "^3.29.8", + "@smithy/signature-v4": "^5.6.9", + "@smithy/types": "^4.16.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.62", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.62.tgz", + "integrity": "sha512-BkDrk2cNjed31IKin/Oksb2ziF+gfuyRskFVuT4EU9Mep7M8Y/d8DJG4+anHme4Vuse7CwaEscwEfGyR6mzBhQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.64", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.64.tgz", + "integrity": "sha512-Wj1FGK2IxY5EccQCvH+niTYhIvDoDujJf2CpRRgS3NpYNEgiFNVItNbJYQjINRlu7fG7jSsXkKV0UWKriEplrw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/fetch-http-handler": "^5.6.10", + "@smithy/node-http-handler": "^4.9.10", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler": { + "version": "4.9.12", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.12.tgz", + "integrity": "sha512-dWW5KRt4mnEvjNzbGqGeCuAvgum85Y9ZoyuMQqcTEfapndyVJ1k9BEHK7kdXJZ32enyRmmwcFjMwlB/KgLKI3Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.0", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.973.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.7.tgz", + "integrity": "sha512-2CefB8cCxDu52P24B8Ay93/cTT199bcSvNHQ8e2f4BjSCF83yErBnTIZEBo0VeIgCfmw+PJKFUXnlQWxm2dkug==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/credential-provider-env": "^3.972.62", + "@aws-sdk/credential-provider-http": "^3.972.64", + "@aws-sdk/credential-provider-login": "^3.972.69", + "@aws-sdk/credential-provider-process": "^3.972.62", + "@aws-sdk/credential-provider-sso": "^3.973.6", + "@aws-sdk/credential-provider-web-identity": "^3.972.68", + "@aws-sdk/nested-clients": "^3.997.36", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/credential-provider-imds": "^4.4.13", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.69", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.69.tgz", + "integrity": "sha512-gM3j0Ie9+FoLNTYODY+QWbg3vCRBc7mR9cRdntxTMkFYIrwfRmuucfavP6HNBlYSuaYww54TNJGej4GFgoPZAg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/nested-clients": "^3.997.36", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.73", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.73.tgz", + "integrity": "sha512-VTzdbf8Ukjdb9yUubZzRI678CWZvKovhE8Nv3qihwhC187sRMGls+r9N8Wuht5q1xjKx2nmpS48ar8ppupjkCA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.62", + "@aws-sdk/credential-provider-http": "^3.972.64", + "@aws-sdk/credential-provider-ini": "^3.973.7", + "@aws-sdk/credential-provider-process": "^3.972.62", + "@aws-sdk/credential-provider-sso": "^3.973.6", + "@aws-sdk/credential-provider-web-identity": "^3.972.68", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/credential-provider-imds": "^4.4.13", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.62", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.62.tgz", + "integrity": "sha512-zXYU9UWNL66gtMgNLhmxlrvEokuI7r6G2q7FRGu41Bya4iS30JLelUipJX9SV4zhyCPWJhI9Li54R1d9H8Tq6A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.973.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.6.tgz", + "integrity": "sha512-DobZggy3K49xdCpjeyMou0FQhkoYbluVGNydL6D+lcxF8GoAsttFX0xnH5GmiQ89We5dB6TRpW+CD/VowBH6HQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/nested-clients": "^3.997.36", + "@aws-sdk/token-providers": "3.1096.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers": { + "version": "3.1096.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1096.0.tgz", + "integrity": "sha512-hdUS2hDppy3vkWeFl5y86RLNU6OWH2mQB09yOSsRefwhhGTSFPkaZvfLDD/9vFcvMzlr8QFQFw3fw2FtrurVQA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/nested-clients": "^3.997.36", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.68", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.68.tgz", + "integrity": "sha512-bq+yTt+uWJx60VVp/OIAX5xqUAu/K2Uc3eknWnWl+KtfcU2CQe0uNw6lySrn2t5GKHq7jsV0Z63HiBGVtzr/lg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/nested-clients": "^3.997.36", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-handler-node": { + "version": "3.972.30", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.30.tgz", + "integrity": "sha512-hJboPgIpq5+ADc++/B9TBqn65CXV21cZLGB8V5RBQbxkZ/rQ6qMfcxTnW/SvQlasX4jhaSG8B1wsVjhQyDrsnQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-eventstream": { + "version": "3.972.25", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.25.tgz", + "integrity": "sha512-9SFbPzJDHHR5k6Q6KvXVas/veUm/TzNcNTFM2UhdXHZHpyIvI2lS+s4cxljw1BihGpVhsAkQDo/2nW7dHxpf4Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-websocket": { + "version": "3.972.44", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.44.tgz", + "integrity": "sha512-MPjH/vT1UZc7RSdvP/bIZCJqQCOORei84D6a7dwBuvdwOIskTsQ2EczlTRFQu7yWpGMQr1x3xdpDRHjWlTH2Tw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/fetch-http-handler": "^5.6.10", + "@smithy/signature-v4": "^5.6.9", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.997.36", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.36.tgz", + "integrity": "sha512-b71Suv7L+DnhM0MsQHU4WO42I32kxLZi96PbVhZbxMYIoKnEZz3v+LSrG8fupAoA4cBSshCk1Dl/PeRz49qUSg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.1", + "@aws-sdk/signature-v4-multi-region": "^3.996.42", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/fetch-http-handler": "^5.6.10", + "@smithy/node-http-handler": "^4.9.10", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler": { + "version": "4.9.12", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.12.tgz", + "integrity": "sha512-dWW5KRt4mnEvjNzbGqGeCuAvgum85Y9ZoyuMQqcTEfapndyVJ1k9BEHK7kdXJZ32enyRmmwcFjMwlB/KgLKI3Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.0", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.42", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.42.tgz", + "integrity": "sha512-DBV4naZP6HYBlAvPpoQzOP12Wvfou/5rN8yJPXjBTBylU5qwCbh/tXr2MddHoIjgoRkEl/eS+IljiUqvmwey1Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.974.2", + "@smithy/signature-v4": "^5.6.9", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.1048.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1048.0.tgz", + "integrity": "sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/nested-clients": "^3.997.9", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.974.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.2.tgz", + "integrity": "sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.8.tgz", + "integrity": "sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.37.tgz", + "integrity": "sha512-zKq4HQum8JwDyEuyfuI4bbiAcU0KxP6qy+9PR/IsR92IyE/DaBAikzAS50tjxip4bqIIANpCcG+Yyj6CVhXupg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz", + "integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@companion-ai/alpha-hub": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@companion-ai/alpha-hub/-/alpha-hub-0.1.3.tgz", + "integrity": "sha512-g/JoqeGDCoSvkgs1ZSTYJhbTak0zVanQyoYOvf2tDgfqJ09gfkqmSGFDmiP4PkTn1bocPqywZIABgmv25x1uYA==", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.27.1", + "chalk": "^5.3.0", + "commander": "^12.0.0", + "zod": "^3.23.0" + }, + "bin": { + "alpha": "bin/alpha", + "alpha-mcp": "bin/alpha-mcp" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@earendil-works/pi-agent-core": { + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.82.1.tgz", + "integrity": "sha512-Z3kloziJIE2dmrisRckZX8zDca/gIv9/YdFAzeoqpHiLV2wsni6bL4hInNSjVKLbqT+4kqLIkph2JQLKvSepjg==", + "license": "MIT", + "dependencies": { + "@earendil-works/pi-ai": "^0.82.1", + "diff": "8.0.4", + "ignore": "7.0.5", + "typebox": "1.1.38", + "yaml": "2.9.0" + }, + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/@earendil-works/pi-ai": { + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.82.1.tgz", + "integrity": "sha512-3WFYRhEp3lQB3444EhPMBcM7zSaEUE3eJgHOR7s4081NLqbw/FsWilIKWXSua0Gv3sRr7m9xMidR3pPDE7jI/A==", + "license": "MIT", + "dependencies": { + "@anthropic-ai/sdk": "0.91.1", + "@aws-sdk/client-bedrock-runtime": "3.1048.0", + "@google/genai": "1.52.0", + "@mistralai/mistralai": "2.2.6", + "@opentelemetry/api": "1.9.0", + "@smithy/node-http-handler": "4.7.3", + "http-proxy-agent": "7.0.2", + "https-proxy-agent": "7.0.6", + "openai": "6.26.0", + "partial-json": "0.1.7", + "typebox": "1.1.38" + }, + "bin": { + "pi-ai": "dist/cli.js" + }, + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent": { + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.82.1.tgz", + "integrity": "sha512-zbkAhoIuDPMF3pKuja0ajZabrMWU29FUMV9A/XMXT/XC1yXs5xt6t6t13GogQFsDrDqbFP4DkZQO1w8rWRAzYA==", + "hasShrinkwrap": true, + "license": "MIT", + "dependencies": { + "@earendil-works/pi-agent-core": "^0.82.1", + "@earendil-works/pi-ai": "^0.82.1", + "@earendil-works/pi-tui": "^0.82.1", + "@silvia-odwyer/photon-node": "0.3.4", + "chalk": "5.6.2", + "cross-spawn": "7.0.6", + "diff": "8.0.4", + "glob": "13.0.6", + "highlight.js": "10.7.3", + "hosted-git-info": "9.0.3", + "ignore": "7.0.5", + "jiti": "2.7.0", + "minimatch": "10.2.5", + "proper-lockfile": "4.1.2", + "semver": "7.8.0", + "typebox": "1.1.38", + "undici": "8.5.0", + "yaml": "2.9.0" + }, + "bin": { + "pi": "dist/cli.js" + }, + "engines": { + "node": ">=22.19.0" + }, + "optionalDependencies": { + "@mariozechner/clipboard": "0.3.9" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@anthropic-ai/sdk": { + "version": "0.91.1", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.91.1.tgz", + "integrity": "sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==", + "license": "MIT", + "dependencies": { + "json-schema-to-ts": "^3.1.1" + }, + "bin": { + "anthropic-ai-sdk": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/client-bedrock-runtime": { + "version": "3.1048.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1048.0.tgz", + "integrity": "sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/credential-provider-node": "^3.972.42", + "@aws-sdk/eventstream-handler-node": "^3.972.16", + "@aws-sdk/middleware-eventstream": "^3.972.12", + "@aws-sdk/middleware-websocket": "^3.972.19", + "@aws-sdk/token-providers": "3.1048.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/fetch-http-handler": "^5.4.2", + "@smithy/node-http-handler": "^4.7.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/core": { + "version": "3.974.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.11.tgz", + "integrity": "sha512-QpnINq5FZH6EOaDEkmHdT7eUunbvD27pDNQypaWjFyYz7Zl1q3UCMQErBZxpmfGfI7MvI2TlK8KTkgNpv8b1ug==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/xml-builder": "^3.972.24", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/core": "^3.24.2", + "@smithy/signature-v4": "^5.4.2", + "@smithy/types": "^4.14.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.37.tgz", + "integrity": "sha512-/jpPvEh6f7ntmIzf7dNxoNX6Q8vt8UpesCjbW6mFfk4V1NW6bIy9qxcQ6WbA8As5yQhsZOe+xeNd4xHX8kdY2Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.39", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.39.tgz", + "integrity": "sha512-pIgTpisWyWg7X1bUbzSjuUYosYTD0Ghz2M0hkSTmb3a6i3qV3uU+NYJPI/E2XSC0HcsZh5rsLPzeXrkb2DS0Cg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/fetch-http-handler": "^5.4.2", + "@smithy/node-http-handler": "^4.7.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.972.41", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.41.tgz", + "integrity": "sha512-u2tyjaxJJzW8UtW4SM1ZcPMDwO6y+kV+llvou+Adts0FAKyzes5jG4izQN+KX3yE8ZROpS5y1LJ//xL2iSf76w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/credential-provider-env": "^3.972.37", + "@aws-sdk/credential-provider-http": "^3.972.39", + "@aws-sdk/credential-provider-login": "^3.972.41", + "@aws-sdk/credential-provider-process": "^3.972.37", + "@aws-sdk/credential-provider-sso": "^3.972.41", + "@aws-sdk/credential-provider-web-identity": "^3.972.41", + "@aws-sdk/nested-clients": "^3.997.9", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/credential-provider-imds": "^4.3.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.41", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.41.tgz", + "integrity": "sha512-0LBitxXiAiaE5nlFPfpNIww/8FRY/I7WIndWsc9GmNFOM7cE1wNpVNQEGEk9Outg5l8xl+3vybxFyUy4l9q/LQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/nested-clients": "^3.997.9", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.42", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.42.tgz", + "integrity": "sha512-D4oon2zbqqsWOJUM99Gm3/ZyJ0IJvTXVN3PyloGb3kQEyI36fjCZheZj422lAgTWWd6TSHgiImLt3RIaLdv3dQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.37", + "@aws-sdk/credential-provider-http": "^3.972.39", + "@aws-sdk/credential-provider-ini": "^3.972.41", + "@aws-sdk/credential-provider-process": "^3.972.37", + "@aws-sdk/credential-provider-sso": "^3.972.41", + "@aws-sdk/credential-provider-web-identity": "^3.972.41", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/credential-provider-imds": "^4.3.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.37.tgz", + "integrity": "sha512-7nVaHBUaWIddASYfVaA9O4D5ZVjewU3sCol9WqZPGfW0nR+0WqE0xHZnD/U2L33PlOB8KNXGKZ6wOES/QijKzg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.972.41", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.41.tgz", + "integrity": "sha512-IOWAWEHe5LkjSKkkUUX9ciV6Y1scHTsnfEkdt5yyC4Slrc7AGbkLPrpntjqh18ksJAMOaVhoBsO8p2WyTcY2wQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/nested-clients": "^3.997.9", + "@aws-sdk/token-providers": "3.1048.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.41", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.41.tgz", + "integrity": "sha512-mbACk9Yypa8nm4iGZLs0PofOXEcTDOUw6wDnsPXNDNSd2WNXs1tSo+6nc/fh0jLYdfVZThhBL98PHW4aXFsG5A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/nested-clients": "^3.997.9", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/eventstream-handler-node": { + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.16.tgz", + "integrity": "sha512-yedpPgKftqjU5SlPFHfqWpOw6xSCRieWRG1euWOlXn4WJxt2VX92VprCa2PpSOXjVCAeK6dTjW9eJRXVig9yGA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/middleware-eventstream": { + "version": "3.972.12", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.12.tgz", + "integrity": "sha512-tHTHHCHNrq6XklQvlzHBDJG4Iuhh7NVPRdtmvP+nHFA+5sxPlIDzlAHHgfoYHGvT3NXP1yVP/L5c3opUn6T3Qg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/middleware-websocket": { + "version": "3.972.19", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.19.tgz", + "integrity": "sha512-mkEhOGYozqKQkbFaVrjwr0faiwwZza1v5/jSY6Tucm3bD+uKTazIUH/4Yo6aMnQD2ua2W9cMP6s8mvwTcjtqHw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/fetch-http-handler": "^5.4.2", + "@smithy/signature-v4": "^5.4.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/nested-clients": { + "version": "3.997.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.9.tgz", + "integrity": "sha512-jPR3rnmRI4hWYyzfmTGBr7NblMp8QYYeflHXba1H6+7CGrWVqWKQzaXFQ4qbExqPRsXN3T3L3JxFhr6aouXUGQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/signature-v4-multi-region": "^3.996.27", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/fetch-http-handler": "^5.4.2", + "@smithy/node-http-handler": "^4.7.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.27", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.27.tgz", + "integrity": "sha512-0Phbz4t6HI3D3skxvG2uI+VWU034/nSIw1T8d+FPzzQG9EQTrw94o9mOKO2Gv3n3Oc8P7JD7RAUxkoneLWv5Eg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/signature-v4": "^5.4.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/token-providers": { + "version": "3.1048.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1048.0.tgz", + "integrity": "sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.11", + "@aws-sdk/nested-clients": "^3.997.9", + "@aws-sdk/types": "^3.973.8", + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/types": { + "version": "3.973.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", + "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", + "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/xml-builder": { + "version": "3.972.24", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.24.tgz", + "integrity": "sha512-V8z5YcDPfsvzrBlj0xR1vhRtocblhYbqdreCJB/voGd4Sr5zjNAeWxexbnqVtskTJe0vFb5KMqbSL++ePl+zRw==", + "license": "Apache-2.0", + "dependencies": { + "@nodable/entities": "2.1.0", + "@smithy/types": "^4.14.1", + "fast-xml-parser": "5.7.3", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws/lambda-invoke-store": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", + "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-agent-core": { + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.82.1.tgz", + "license": "MIT", + "dependencies": { + "@earendil-works/pi-ai": "^0.82.1", + "diff": "8.0.4", + "ignore": "7.0.5", + "typebox": "1.1.38", + "yaml": "2.9.0" + }, + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-ai": { + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.82.1.tgz", + "license": "MIT", + "dependencies": { + "@anthropic-ai/sdk": "0.91.1", + "@aws-sdk/client-bedrock-runtime": "3.1048.0", + "@google/genai": "1.52.0", + "@mistralai/mistralai": "2.2.6", + "@opentelemetry/api": "1.9.0", + "@smithy/node-http-handler": "4.7.3", + "http-proxy-agent": "7.0.2", + "https-proxy-agent": "7.0.6", + "openai": "6.26.0", + "partial-json": "0.1.7", + "typebox": "1.1.38" + }, + "bin": { + "pi-ai": "dist/cli.js" + }, + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui": { + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.82.1.tgz", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "1.6.0", + "marked": "18.0.5" + }, + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@google/genai": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.52.0.tgz", + "integrity": "sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "google-auth-library": "^10.3.0", + "p-retry": "^4.6.2", + "protobufjs": "^7.5.4", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.25.2" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard/-/clipboard-0.3.9.tgz", + "integrity": "sha512-ABnA53mdfkGZwOFUdZNv2S0CWGO/EIuPj8Vv9xmBFmSYg/qFc7ihO6q5FcQjvoE67kZpWkEc4AhD6B/os04yuA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@mariozechner/clipboard-darwin-arm64": "0.3.9", + "@mariozechner/clipboard-darwin-universal": "0.3.9", + "@mariozechner/clipboard-darwin-x64": "0.3.9", + "@mariozechner/clipboard-linux-arm64-gnu": "0.3.9", + "@mariozechner/clipboard-linux-arm64-musl": "0.3.9", + "@mariozechner/clipboard-linux-riscv64-gnu": "0.3.9", + "@mariozechner/clipboard-linux-x64-gnu": "0.3.9", + "@mariozechner/clipboard-linux-x64-musl": "0.3.9", + "@mariozechner/clipboard-win32-arm64-msvc": "0.3.9", + "@mariozechner/clipboard-win32-x64-msvc": "0.3.9" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-arm64": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-arm64/-/clipboard-darwin-arm64-0.3.9.tgz", + "integrity": "sha512-BfgV7vCEWZwJwZJw03r6bP5+tf0iI/ANuQYCxi9RNn7FrWB3yzGuMKCrNLRl6V761vXRdL8+OqZ0wd4TqlsNOQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-universal": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-universal/-/clipboard-darwin-universal-0.3.9.tgz", + "integrity": "sha512-BGGR4iA9Z2shAjI65eI5xtyb3LYNlDW9X3gxKxDbqtbnREohsrqznov6zpKoIrsRWpzlYVEdKphS7ksJ0/ndSQ==", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-x64": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-x64/-/clipboard-darwin-x64-0.3.9.tgz", + "integrity": "sha512-4kURmCbS6nt8uYhtmWpUcJWyPHfmAr5dTpXD1nO3pIfa+TSQ9DbrGOYCKH+aEFW47XhQ4Vp8ZTszie+wfFvDKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-arm64-gnu": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-arm64-gnu/-/clipboard-linux-arm64-gnu-0.3.9.tgz", + "integrity": "sha512-g59OkUGP2DDfCOIKypHeYgv2M55u/cKvXa5dSxFbEJ34XvIQMdcVmpKCkGUro3ZgefXiGVdwguvTMQGpHWzIXw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-arm64-musl": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-arm64-musl/-/clipboard-linux-arm64-musl-0.3.9.tgz", + "integrity": "sha512-AGuJdgKsmJdm4Pych7kv3sqe591ERRaAHW3xjLooiFzn8J+PxUyof++7YZrB5Y5tpnTO+K18Og3taj2NpluCRQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-riscv64-gnu": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-riscv64-gnu/-/clipboard-linux-riscv64-gnu-0.3.9.tgz", + "integrity": "sha512-DXBEAiuMpk7dhS1a9NzNxVAFi1vaKoPu7rQNgY8LIDLGrK3lnIp3nT10DUum+PKVJoJppIP+NAA8IZe4DMNDPw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-x64-gnu": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-x64-gnu/-/clipboard-linux-x64-gnu-0.3.9.tgz", + "integrity": "sha512-WORrMLd6EpElEME7JRKfSaY34nW1P5LbdgK5YNCS1ncG2LqmITsSMEJ8nh2mpvxb3TxqbOOKgY7k9eMJYlW9Mw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-x64-musl": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-x64-musl/-/clipboard-linux-x64-musl-0.3.9.tgz", + "integrity": "sha512-/DHn+1DrfL6oRaPPWXaOKvonFFrni666fxd+zFqiQEfvBH0tsHVWjq9iqBk0oDp0qaPA72lIMy5BptxISBEhZQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-win32-arm64-msvc": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-win32-arm64-msvc/-/clipboard-win32-arm64-msvc-0.3.9.tgz", + "integrity": "sha512-O5FHD3ErkMwMhNzAfu3ggy0ug4z7btZuoQgwwxlzPrwV2bxlD6WDpqBY4NCgICAgZdDKdp+loUEKVAVt8aYnhQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-win32-x64-msvc": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-win32-x64-msvc/-/clipboard-win32-x64-msvc-0.3.9.tgz", + "integrity": "sha512-ihQC3EufqEY81vhXBgVBtK4prL+wc62zJsSvxrgz7K1hsdt6OObz6v9p3Rn1OG3GJksTTKMJF0u/guMISHPhSA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@mistralai/mistralai": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.6.tgz", + "integrity": "sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.40.0", + "ws": "^8.18.0", + "zod": "^3.25.0 || ^4.0.0", + "zod-to-json-schema": "^3.25.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + } + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.41.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz", + "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/utf8": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", + "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@silvia-odwyer/photon-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@silvia-odwyer/photon-node/-/photon-node-0.3.4.tgz", + "integrity": "sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==", + "license": "Apache-2.0" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/core": { + "version": "3.24.3", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.3.tgz", + "integrity": "sha512-Ep/7tPamGY8mgESE3LyLKtxJyy6U52WWAqr/3wial47Sj4u3PiIF73AOGI27UyLy9duTkhZbgzodOfLV4TduZg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.14.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/credential-provider-imds": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.3.tgz", + "integrity": "sha512-I2Bti0DKFo2IJyN28ijCsx51BAumEYR4/1yZ1FXyBygy9MqbnMqCev4JPth/MbpRfBSRAX35hITSnAdJRo1u5w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.3", + "@smithy/types": "^4.14.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/fetch-http-handler": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.3.tgz", + "integrity": "sha512-F+DRf8IJazRJgYog2A/yJK7eYVc0rqTlRzO+5ZxjJd4WkZoKz0IJRncf7G6t1pdVT3kryJcwuTFhN1c5m6N47A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.3", + "@smithy/types": "^4.14.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/node-http-handler": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.3.tgz", + "integrity": "sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.3", + "@smithy/types": "^4.14.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/signature-v4": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.3.tgz", + "integrity": "sha512-53+75QuPl6DL+ct6vVEB51FDO5oulXr20TPV46VvJZg76lIlXNWfxi8j+G2V/t0I2qxCBOa3vX/8bmjrpFVo9g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.3", + "@smithy/types": "^4.14.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/types": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.2.tgz", + "integrity": "sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/@types/node": { + "version": "22.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", + "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/fast-xml-builder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", + "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "path-expression-matcher": "^1.5.0", + "xml-naming": "^0.1.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/fast-xml-parser": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz", + "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.7", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/gaxios": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", + "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/gcp-metadata": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/google-auth-library": { + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz", + "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^7.1.4", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/hosted-git-info": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/json-schema-to-ts": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", + "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "ts-algebra": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/lru-cache": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.4.0.tgz", + "integrity": "sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/marked": { + "version": "18.0.5", + "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.5.tgz", + "integrity": "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/openai": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz", + "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/p-retry/node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/partial-json": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz", + "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==", + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/path-expression-matcher": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/proper-lockfile/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/protobufjs": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/strnum": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz", + "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/ts-algebra": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", + "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/typebox": { + "version": "1.1.38", + "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz", + "integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==", + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/undici": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz", + "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==", + "license": "MIT", + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/ws": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/xml-naming": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", + "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@earendil-works/pi-coding-agent/node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + }, + "node_modules/@earendil-works/pi-tui": { + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.82.1.tgz", + "integrity": "sha512-9yN8hALfKaxZq7n54EMxqhFCWnMi6LHkraMJ/1YjHiATq75XrI6XDMVppn9EDtiK7Fks8hUe1SDXUTrIvwRWfQ==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "1.6.0", + "marked": "18.0.5" + }, + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/@google/genai": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.52.0.tgz", + "integrity": "sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "google-auth-library": "^10.3.0", + "p-retry": "^4.6.2", + "protobufjs": "^7.5.4", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.25.2" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.4.tgz", + "integrity": "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz", + "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.5.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@hono/node-server": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.0.12.tgz", + "integrity": "sha512-eWpQYr67tqJLeaSUl0Q+TquuYfUdTibpOJlUMV2FfUP7+KqCC5TufnwnlXL6mobZBJbGAYRd7ZvEBDCbLInjhg==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@llamaindex/liteparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@llamaindex/liteparse/-/liteparse-2.0.1.tgz", + "integrity": "sha512-8LGmIflr6AL3zFqy7PU/bRBIgRJtZWLco6XQc9Hsvk6GKpQ4GFsH6GDlk5HTdvuAbdoDb0g4PYLxd/r8SNCENg==", + "license": "Apache-2.0", + "dependencies": { + "commander": "^12.0.0" + }, + "bin": { + "lit": "dist/cli.js", + "liteparse": "dist/cli.js" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "@llamaindex/liteparse-darwin-arm64": "2.0.1", + "@llamaindex/liteparse-linux-arm64-gnu": "2.0.1", + "@llamaindex/liteparse-linux-x64-gnu": "2.0.1", + "@llamaindex/liteparse-win32-x64-msvc": "2.0.1" + } + }, + "node_modules/@llamaindex/liteparse-darwin-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@llamaindex/liteparse-darwin-arm64/-/liteparse-darwin-arm64-2.0.1.tgz", + "integrity": "sha512-/f8hH6R8CEtc5/2QMQvER4gt3RKgvcM4K6OzCvqlEIiJtyob67RkZhkFA8x2h4dAzgAtqMegQCo1vFHs31IPXg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@llamaindex/liteparse-linux-arm64-gnu": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@llamaindex/liteparse-linux-arm64-gnu/-/liteparse-linux-arm64-gnu-2.0.1.tgz", + "integrity": "sha512-oir+ZNsDs9aAPG4BmYHTAhQRb+wBVTXvWgPDY+qn6bAJjY4qMIrlVbUPSzRnKCXZ+4nuuj7PJsRxkXHrmxoQ5A==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@llamaindex/liteparse-linux-x64-gnu": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@llamaindex/liteparse-linux-x64-gnu/-/liteparse-linux-x64-gnu-2.0.1.tgz", + "integrity": "sha512-cMoAkgMMF9V/Mwy7kkeGMBC0q22xVHGTR27ZYpmh56eQdsLTt7YnjcACNLlD9ULJ5ha7DvKIuS0Bmu+agiJvsg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@llamaindex/liteparse-win32-x64-msvc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@llamaindex/liteparse-win32-x64-msvc/-/liteparse-win32-x64-msvc-2.0.1.tgz", + "integrity": "sha512-d/CD/Hidf1GL72pQTyy3gKTeJScElDyRZyPDhFzZYHdFBQY/3zRaUfzzdMZGnjhdwMB10uJeuCYux8pKEcW2Kw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@mistralai/mistralai": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.6.tgz", + "integrity": "sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.40.0", + "ws": "^8.18.0", + "zod": "^3.25.0 || ^4.0.0", + "zod-to-json-schema": "^3.25.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + } + } + }, + "node_modules/@mixmark-io/domino": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", + "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==", + "license": "BSD-2-Clause" + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", + "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9 || ^2.0.5", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@mozilla/readability": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@mozilla/readability/-/readability-0.6.0.tgz", + "integrity": "sha512-juG5VWh4qAivzTAeMzvY9xs9HY5rAcr2E4I7tiSSCokRFi7XIZCAu92ZkSTsIj1OPceCifL3cpfteP3pDT9/QQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.221.0.tgz", + "integrity": "sha512-OlanaW1vv7ufTqQ3/fPLI4arGt5ZoM+P8abOMki6uEYnpRazepSWDwDnnw+la7kE26SHVC18//SMccrDvLKOXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/configuration": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/configuration/-/configuration-0.221.0.tgz", + "integrity": "sha512-uE9y56Zdi9Gt/RdxYnVOo3YmFZkKJJMA0gqtBe8wh8gdtF5Asqe+Oh/TWiDtFb1s+31jNY4CWgnfIB1KOITfFA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "yaml": "^2.8.3" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.10.0.tgz", + "integrity": "sha512-bvyMcgLEkozzSzpEEEo1OMoeQ97bxj6Qs2uN3mPrSdDvObMI1myffD/BPqcLlzZO9//d1SqQA/WPw7Cz2AiqhA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.10.0.tgz", + "integrity": "sha512-/wNZ8twnEQQA4HoHu22+vcsdru6pWPWxW+7w+FlxT6Id7PE/WIbZmVKkte+PF72e0F2dnImFeHD2syyE1Mw6MQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-grpc": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.221.0.tgz", + "integrity": "sha512-txG1G0IrYSsKKMeiWZfj/i5cQmWB+h+hf3HzPpF3RqZVwp+iQQEIsv8Vtmzy6RWVdHdJZfygmVrBI39YTBvWcw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-logs": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.221.0.tgz", + "integrity": "sha512-nKXkr4Tomi6fjYVOf+ytcW3dZAVr4v4Bv5gsT6dr2gvpUPJpKgHB4XbMufMsPotRE3g0XH2GwVVCkN2w6SON+Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-logs": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-proto": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.221.0.tgz", + "integrity": "sha512-AH6EY+47gXFaWYgG3hfeOneGiE9xIZGtDBk+9g0sM8NZWzsQhhmqPbQQXJzS7pyCh5jRRr2nYNXVrkCmoojRvQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-logs": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.221.0.tgz", + "integrity": "sha512-KOgCtO15FC6C1T/xOqBcr7EyUs7B+7yomGNb5Y97d3s38rPbCCk5sewkmE2b0/itOkQ/PptX8CLlD+kn2mEtTg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/exporter-metrics-otlp-http": "0.221.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.221.0.tgz", + "integrity": "sha512-sRfCKbOzgy8xZQV2as0RzIZlnCmCseCKZGLfRcrpo2CBngJDr+rPtX0zkG0+oUCV5kfQPUoW3W3C96Ag3Y/Clg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-metrics": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-proto": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.221.0.tgz", + "integrity": "sha512-YMF4LveY2I3yhw61rn6nmC9FE8U24IZHPeKU1Duc5+sbwjMd8FwZAwba318ImdThCg/HuVQvhm2y6bfgNPnfYg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/exporter-metrics-otlp-http": "0.221.0", + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-prometheus": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.221.0.tgz", + "integrity": "sha512-kW79a20qWESIuAdDrxzg9WKM98twV/NBWBFRAH57ap/+ssZhiCo0hckzKT0zpuwR/gSHrFAQhJL0bYDrnEM34g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-metrics": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.221.0.tgz", + "integrity": "sha512-zXminlZedtq9LvOW64CnNkOqk15zV75k8JgtdTuWFge6+jk2m4GmAUm6L2eIiG1o2a2bZxXw2PDrszm+bps0IA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-trace": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.221.0.tgz", + "integrity": "sha512-AySXiKoC+meiWm6zdVj5T2LnPDZuatveBby1cMOeQteIWsYXAUxs8Sru13G2pVSPrUXz6vF+og7QVBX6GdC/oQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-trace": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.221.0.tgz", + "integrity": "sha512-Z9i2T7vgZbWe9rSLYxXVIbeW+XyzUq4rZanW3ZyVNwVDqCsh0EJKUgBWWQ0CZfeuUA+RQPzKgJQHMuWAUnKqXw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-trace": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-2.10.0.tgz", + "integrity": "sha512-7gsvgf0UDoJ4l9ObrwBmz5G/ZogiPk+lq+g5GpLp24YQF/vPM/BSsnOfcLnfinast5ASUgLo78uSC/ObjlnXgg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.221.0.tgz", + "integrity": "sha512-cCk80Z/iRDf/5gfsKMB4f74LqVA5yKETB/9ojPzVW/6/f70iu89nJvGxsFCxx4XfSohaOofkU19kiYm84AiAlw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.221.0", + "import-in-the-middle": "^3.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.221.0.tgz", + "integrity": "sha512-UFPIq80OH3Ns/oPFHRj14d4DTOxUo+MUFU8hUiCq5jTqFhdeJnfVSANHT+xp92409cA+oxzvlZCe6NM1wvCuBA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/otlp-transformer": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.221.0.tgz", + "integrity": "sha512-rQDmNgyiGCTrescjnzH2ntVyUKVIq6I2UjuK8+stT/Xg0ZOT71FVJqwjFdspQl6Yol/Yqsut9bDo+ame8oTmDQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.14.3", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.221.0.tgz", + "integrity": "sha512-lg6lkOU08Az23jVcn/0Els9HP+V8PnR4Km6p0KgpTggS0n/WuhnmY64rSh83Of9iR9nD+dpWr6adlcX8KzAwjg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-logs": "0.221.0", + "@opentelemetry/sdk-metrics": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-2.10.0.tgz", + "integrity": "sha512-GnA5B24H+1w8BO21J0q+IWNB0z1v+AGbcquTdIt/dufibhnhgxaA8YKvz0I3akRZhB1jHT+/tlzK+qlAjEDybQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-2.10.0.tgz", + "integrity": "sha512-yw/IX8DL470dSMZJoE82ScfYGp7JWZ/G8kFJo35ZILUVTB2jFPTOaioN+8s09pH0RHsWNhweVZb+ZnjJJpCChg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.10.0.tgz", + "integrity": "sha512-q6MMm2zhggzsHVNbabYwut+a6nbuQQe3URUoxaojM/8K1IBfwwPzvxIjNi2/lI1TFe+fMHMW9MWhrtDLEXEnkA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.221.0.tgz", + "integrity": "sha512-FaDcazjyMp7TZZZAsqbo4IkovP0UegoCu0EBkiNt+qCqvUf7FPAsfcrZ3+ZEkKgXZ/jHafop+JoGPDk3A0SmLg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.10.0.tgz", + "integrity": "sha512-t6r1VSvXNtSDnPXU1FbZeetJb7yyovHmgu0wRSoftxtE0g2rSNhQZQUy69sRUCL+iioJpX8SN/S6wq6ZtvLySQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.221.0.tgz", + "integrity": "sha512-UbYuvtBrQQB5Prsh9KOKy4kxzexFxfMs5MkteHeWMoswsEB7kiNhyUVkAOFW/qsEzNHtrkgyghrD2ilZJa+5YA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/configuration": "0.221.0", + "@opentelemetry/context-async-hooks": "2.10.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/exporter-logs-otlp-grpc": "0.221.0", + "@opentelemetry/exporter-logs-otlp-http": "0.221.0", + "@opentelemetry/exporter-logs-otlp-proto": "0.221.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.221.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.221.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.221.0", + "@opentelemetry/exporter-prometheus": "0.221.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.221.0", + "@opentelemetry/exporter-trace-otlp-http": "0.221.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.221.0", + "@opentelemetry/exporter-zipkin": "2.10.0", + "@opentelemetry/instrumentation": "0.221.0", + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.221.0", + "@opentelemetry/propagator-b3": "2.10.0", + "@opentelemetry/propagator-jaeger": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-logs": "0.221.0", + "@opentelemetry/sdk-metrics": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0", + "@opentelemetry/sdk-trace-base": "2.10.0", + "@opentelemetry/sdk-trace-node": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.10.0.tgz", + "integrity": "sha512-MfQGq3GRmTh5fM/y+OjaO0vj6+luCB1XO2gfXCalKCfgKw0eHL++sm75DNweC6ohlp+aFvACqeE0fYayqdRaoQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.10.0.tgz", + "integrity": "sha512-GuYQQT7QD2EeO8lcZLRQzcbOyhqAzL+6WWTKTU9mSUBYBazkEDl+VrQcXQhbB08OWM9anD1aHleVadzulpOaUQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.10.0.tgz", + "integrity": "sha512-GZK/G6oZyBLGlH1pUgeDch7D91KoHd2uotUGIkWCPi9GI5T9X0p4L7nNAMDR1BQjkRYoDqo+ddfVx9t5Uhys+Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "2.10.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/sdk-trace-base": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", + "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", + "license": "BSD-3-Clause" + }, + "node_modules/@smithy/core": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.31.0.tgz", + "integrity": "sha512-sylYk2l9d7CmRv8ts8p0SDQUr3VO+HMeS1nrjL6+UtbO8ktJHTOeQ1McX+aAyvGGccp5aZX9eNtdcXrSwzoZaw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.15.tgz", + "integrity": "sha512-xYVGrisQqTJWhOnScUhbx8s9H63TMtoxzuUoxG6mP8J+B/YbX3vZxVsgV0xDf43abJnJP0fjP7BkQh7OESwuRA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.0", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.6.12", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.12.tgz", + "integrity": "sha512-OpQgP6IGH4j0NJ2zjfYZLjQL85ai+Wi/q51EmZJovXsEwKSvu89qiXUq77Q6EmwZ/hSl7fKpn2Z9mhiDN6OM+Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.0", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.3.tgz", + "integrity": "sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.3", + "@smithy/types": "^4.14.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.6.11", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.11.tgz", + "integrity": "sha512-7HsspeiNCZvZHEJ22vV5L/QYuJdTyJvPJvMrYD3AgkM3IJB0pkln4jkjPvtpTWRMkHXbO8WKwNjoVdVlBFwHmw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.0", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.16.1.tgz", + "integrity": "sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@types/node": { + "version": "26.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.2.tgz", + "integrity": "sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==", + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/body-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", + "on-finished": "^2.4.1", + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "license": "MIT" + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract-get": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", + "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "is-callable": "^1.2.7", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz", + "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==", + "license": "MIT", + "dependencies": { + "es-abstract-get": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "is-callable": "^1.2.7", + "is-date-object": "^1.1.0", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz", + "integrity": "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.6.1.tgz", + "integrity": "sha512-0D493aP61w0TJ2A0wy27riRsO7FMQ7FK+KUHOKCSfPvYo0R55aiC6emCVgFUeShH0fq0ICPVzNcgoS+BsbXQCA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", + "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "is-callable": "^1.2.7", + "is-document.all": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaxios": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.3.0.tgz", + "integrity": "sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gcp-metadata": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/google-auth-library": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.9.1.tgz", + "integrity": "sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^7.1.4", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.12.32", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.32.tgz", + "integrity": "sha512-XcuyW9qE2kJn07PkecMOBd5Vq/hMy7mmGw+idz1yblbg9N17ijJODrvPkn7/dwL3Kulj8LcRJ69DLOWf91dRUg==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-in-the-middle": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.3.2.tgz", + "integrity": "sha512-jTd2FfOgOWOdgjkHuk/1Ms8VKFXkPs15ymYBETw1sAOrO/dY3XeGVRWir9qBbw7pXr0T2eTFwfCZ+N02HmiNGA==", + "license": "Apache-2.0", + "dependencies": { + "cjs-module-lexer": "^2.2.0", + "es-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-address": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.3.1.tgz", + "integrity": "sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-document.all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", + "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jose": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.4.tgz", + "integrity": "sha512-N8acGzVsQy6M/fjFcxtysNc4Q379TcM5dM/qKkNtsHFji88yANnXTr7BLeP75iPnFwBfQzM/jg2BZ9+HZrHCZA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-schema-to-ts": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", + "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "ts-algebra": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/linkedom": { + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.16.11.tgz", + "integrity": "sha512-WgaTVbj7itjyXTsCvgerpneERXShcnNJF5VIV+/4SLtyRLN+HppPre/WDHRofAr2IpEuujSNgJbCBd5lMl6lRw==", + "license": "ISC", + "dependencies": { + "css-select": "^5.1.0", + "cssom": "^0.5.0", + "html-escaper": "^3.0.3", + "htmlparser2": "^9.1.0", + "uhyphen": "^0.2.0" + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/marked": { + "version": "18.0.5", + "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.5.tgz", + "integrity": "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/openai": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz", + "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/own-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.2.tgz", + "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/partial-json": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz", + "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==", + "license": "MIT" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pi-btw": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pi-btw/-/pi-btw-0.4.1.tgz", + "integrity": "sha512-8W5O0Z4yD/teGszo1d5uk8xSQiPQTa+SI0FKv0V3ENggzGzFfL3wze8RTNUDTzN1eRtBhKRoTFgae86ddvy47g==", + "license": "MIT", + "peerDependencies": { + "@earendil-works/pi-ai": ">=0.74.0 <1", + "@earendil-works/pi-coding-agent": ">=0.74.0 <1", + "@earendil-works/pi-tui": ">=0.74.0 <1" + } + }, + "node_modules/pi-docparser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pi-docparser/-/pi-docparser-3.0.1.tgz", + "integrity": "sha512-t08KQlV6jnvXM9usnOWMyxLJL5rlwHjOO/Dy/GXF8x6PIvaFW7FGk4+l3a+HQq+nJJZQ9no9ETQuNg4ZYcN9tg==", + "license": "MIT", + "dependencies": { + "@llamaindex/liteparse": "2.0.1" + }, + "engines": { + "node": ">=20.6.0" + }, + "peerDependencies": { + "@earendil-works/pi-ai": "^0.74.0", + "@earendil-works/pi-coding-agent": "^0.74.0" + } + }, + "node_modules/pi-otel": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/pi-otel/-/pi-otel-0.1.0.tgz", + "integrity": "sha512-MupOgAmL0kYXJs4TuLC6zwyUCPZTNfcR4ZBo3JM/PIHSZMGRPqM42tjbfdNNwC29wWdmyouLg4IrHb4cPdkvoQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.57.0", + "@opentelemetry/exporter-trace-otlp-proto": "^0.57.0", + "@opentelemetry/resources": "^1.30.0", + "@opentelemetry/sdk-node": "^0.57.0", + "@opentelemetry/sdk-trace-base": "^1.30.0", + "@opentelemetry/semantic-conventions": "^1.28.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@earendil-works/pi-coding-agent": "*" + } + }, + "node_modules/pi-subagents": { + "version": "0.37.2", + "resolved": "https://registry.npmjs.org/pi-subagents/-/pi-subagents-0.37.2.tgz", + "integrity": "sha512-pf7DxLBY9pFY3grOFgRfMqoS9QbElWP2ULOCOnmJNrCEvjlA81fiyp0wk1vSaJPJ/rjsP0lA1sAk7S/QD+Olpg==", + "license": "MIT", + "dependencies": { + "jiti": "2.7.0", + "typebox": "1.1.38", + "yaml": "2.8.3" + }, + "bin": { + "pi-subagents": "install.mjs" + }, + "peerDependencies": { + "@earendil-works/pi-agent-core": "*", + "@earendil-works/pi-ai": ">=0.80.0", + "@earendil-works/pi-coding-agent": "*", + "@earendil-works/pi-tui": "*" + }, + "peerDependenciesMeta": { + "@earendil-works/pi-agent-core": { + "optional": true + }, + "@earendil-works/pi-ai": { + "optional": true + }, + "@earendil-works/pi-coding-agent": { + "optional": true + }, + "@earendil-works/pi-tui": { + "optional": true + } + } + }, + "node_modules/pi-subagents/node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/pi-web-access": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/pi-web-access/-/pi-web-access-0.15.0.tgz", + "integrity": "sha512-62ir9Z5K8oCPZVFJRCYeV0uzsTHNEi01p84nn/5NkTYFhVQzxLVooA2DU83hTeWt2DlwaiijYyoPx6yxHrC4LA==", + "license": "MIT", + "dependencies": { + "@mozilla/readability": "^0.6.0", + "linkedom": "^0.16.0", + "p-limit": "^6.1.0", + "promise.try": "^2.0.1", + "turndown": "^7.2.0", + "typebox": "^1.1.38", + "unpdf": "^1.6.2" + }, + "peerDependencies": { + "@earendil-works/pi-ai": "*", + "@earendil-works/pi-coding-agent": "*", + "@earendil-works/pi-tui": "*" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/promise.try": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise.try/-/promise.try-2.0.1.tgz", + "integrity": "sha512-7Lvq1rrywExCch6Uyw8P5G0HrgYs1u2rxY+0HFBMoA5IqndrJrSGc+ybRnPY1N78F8x+j9BaOWNbg7bzTMG9NA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/protobufjs": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-in-the-middle": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", + "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3" + }, + "engines": { + "node": ">=9.3.0 || >=8.10.0 <9.0.0" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-algebra": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", + "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/turndown": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.4.tgz", + "integrity": "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==", + "license": "MIT", + "dependencies": { + "@mixmark-io/domino": "^2.2.0" + }, + "engines": { + "node": ">=18", + "npm": ">=9" + } + }, + "node_modules/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "license": "MIT", + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/typebox": { + "version": "1.1.38", + "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz", + "integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==", + "license": "MIT" + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", + "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "possible-typed-array-names": "^1.1.0", + "reflect.getprototypeof": "^1.0.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uhyphen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", + "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==", + "license": "ISC" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "license": "MIT" + }, + "node_modules/unpdf": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/unpdf/-/unpdf-1.8.0.tgz", + "integrity": "sha512-jQlkckbe5nKxRHQdbvo9IKHlU6Cjq00UlxxB8lrCIxvS2o5IbAL1wM+4a1Yc3+BIohg9p5AsoaftwO+G4Aq/qQ==", + "license": "MIT", + "engines": { + "node": ">=22" + }, + "peerDependencies": { + "@napi-rs/canvas": "^0.1.69 || ^1.0.0" + }, + "peerDependenciesMeta": { + "@napi-rs/canvas": { + "optional": true + } + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + } + } +} diff --git a/.feynman/settings.json b/.feynman/settings.json index dc432565..1c8a24e9 100644 --- a/.feynman/settings.json +++ b/.feynman/settings.json @@ -1,12 +1,12 @@ { "themes": ["-themes/feynman.json"], "packages": [ - "npm:@companion-ai/alpha-hub", - "npm:pi-subagents", - "npm:pi-btw", - "npm:pi-docparser", - "npm:pi-web-access", - "npm:pi-otel" + "npm:@companion-ai/alpha-hub@0.1.3", + "npm:pi-subagents@0.37.2", + "npm:pi-btw@0.4.1", + "npm:pi-docparser@3.0.1", + "npm:pi-web-access@0.15.0", + "npm:pi-otel@0.1.0" ], "quietStartup": true, "collapseChangelog": true diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e3ab2424..6f949ded 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,6 +1,8 @@ name: End-to-End Install Tests on: + pull_request: + branches: [main] workflow_dispatch: inputs: version: @@ -13,6 +15,7 @@ env: jobs: install-e2e: + if: github.event_name == 'workflow_dispatch' name: e2e (${{ matrix.os }}, node ${{ matrix.node }}) strategy: fail-fast: false @@ -37,7 +40,7 @@ jobs: run: shell: bash steps: - - uses: actions/setup-node@v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: ${{ matrix.node }} @@ -181,3 +184,207 @@ jobs: grep -q "RESULT=PONG" subagent.log || { echo "child output not relayed:" >&2; grep -o "RESULT=[A-Za-z_]*" subagent.log >&2; tail -30 subagent.log >&2; exit 1; } grep -o "RESULT=PONG" subagent.log | head -1 echo "subagent smoke ok" + + release-candidate-pr: + if: github.event_name == 'pull_request' + name: Release candidate (PR) + runs-on: ubuntu-latest + timeout-minutes: 60 + permissions: + contents: read + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version-file: .nvmrc + + - name: Validate source and website + shell: bash + run: | + set -euxo pipefail + npm ci + npm test + npm run typecheck + npm run build + npm run architecture:check + npm audit --omit=dev + ( + cd website + npm ci + npm run lint + npm run typecheck + npm run build + npm audit --omit=dev + ) + git diff --check + + - name: Validate packed consumer and runtime + shell: bash + run: | + set -euxo pipefail + npm pack --dry-run --json > "$RUNNER_TEMP/pack-dry-run.json" + npm pack --json --pack-destination "$RUNNER_TEMP" > "$RUNNER_TEMP/pack.json" + tarball="$RUNNER_TEMP/companion-ai-feynman-$(node -p "require('./package.json').version").tgz" + test -s "$tarball" + node scripts/verify-package-budget.mjs "$RUNNER_TEMP/pack.json" "$tarball" + npm audit --omit=dev --prefix .feynman/npm + + consumer="$RUNNER_TEMP/feynman-consumer" + mkdir -p "$consumer" + (cd "$consumer" && npm init -y >/dev/null) + npm install --prefix "$consumer" --omit=dev --no-audit "$tarball" + npm audit --omit=dev --prefix "$consumer" + + bin="$consumer/node_modules/.bin/feynman" + test "$("$bin" --version | tail -1)" = "$(node -p "require('./package.json').version")" + "$bin" --help >/dev/null + HOME="$RUNNER_TEMP/feynman-home" FEYNMAN_HOME="$RUNNER_TEMP/feynman-home" "$bin" packages list + HOME="$RUNNER_TEMP/feynman-home" FEYNMAN_HOME="$RUNNER_TEMP/feynman-home" "$bin" search status + node "$consumer/node_modules/@companion-ai/feynman/scripts/verify-package-artifact.mjs" \ + "$consumer/node_modules/@companion-ai/feynman" + test -z "$(git status --porcelain --untracked-files=all)" + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: pr-npm-package + path: ${{ runner.temp }}/companion-ai-feynman-*.tgz + if-no-files-found: error + + supported-node-consumers-pr: + if: github.event_name == 'pull_request' + needs: release-candidate-pr + name: Candidate consumer (${{ matrix.os }}, Node ${{ matrix.node }}) + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + node: "22.22.0" + - os: ubuntu-latest + node: "24.18.0" + - os: ubuntu-latest + node: "25" + - os: macos-14 + node: "24.18.0" + - os: windows-latest + node: "24.18.0" + - os: windows-latest + node: "25" + runs-on: ${{ matrix.os }} + permissions: + contents: read + steps: + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: ${{ matrix.node }} + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: pr-npm-package + path: npm-package + - name: Verify the exact candidate tarball + shell: bash + run: | + set -euxo pipefail + count=$(find npm-package -type f -name '*.tgz' | wc -l | tr -d ' ') + test "$count" = "1" + tarball=$(find npm-package -type f -name '*.tgz' -print) + tarball=$(node -e 'process.stdout.write(require("node:path").resolve(process.argv[1]))' "$tarball") + tarball_for_tar="$tarball" + if command -v cygpath >/dev/null 2>&1; then + tarball_for_tar=$(cygpath -u "$tarball") + fi + version=$(tar -xOf "$tarball_for_tar" package/package.json | node -e \ + 'let source=""; process.stdin.on("data", chunk => source += chunk).on("end", () => process.stdout.write(JSON.parse(source).version))') + consumer="$RUNNER_TEMP/feynman-consumer" + if command -v cygpath >/dev/null 2>&1; then + consumer=$(cygpath -u "$consumer") + fi + mkdir -p "$consumer" + (cd "$consumer" && npm init -y >/dev/null) + npm install --prefix "$consumer" --omit=dev --no-audit "$tarball" + npm audit --omit=dev --prefix "$consumer" + bin="$consumer/node_modules/.bin/feynman" + test "$("$bin" --version | tail -1)" = "$version" + "$bin" --help >/dev/null + HOME="$RUNNER_TEMP/feynman-home" FEYNMAN_HOME="$RUNNER_TEMP/feynman-home" "$bin" packages list + HOME="$RUNNER_TEMP/feynman-home" FEYNMAN_HOME="$RUNNER_TEMP/feynman-home" "$bin" search status + runtime_audit="$RUNNER_TEMP/feynman-runtime-audit" + mkdir -p "$runtime_audit" + runtime_archive="$consumer/node_modules/@companion-ai/feynman/.feynman/runtime-workspace.tgz" + if command -v cygpath >/dev/null 2>&1; then + runtime_archive=$(cygpath -u "$runtime_archive") + runtime_audit=$(cygpath -u "$runtime_audit") + fi + tar -xzf \ + "$runtime_archive" \ + -C "$runtime_audit" + npm audit --omit=dev --prefix "$runtime_audit/npm" + node "$consumer/node_modules/@companion-ai/feynman/scripts/verify-package-artifact.mjs" \ + "$consumer/node_modules/@companion-ai/feynman" + + windows-native-installer-pr: + if: github.event_name == 'pull_request' + name: Windows native installer (PR) + runs-on: windows-latest + timeout-minutes: 60 + permissions: + contents: read + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version-file: .nvmrc + + - name: Build Windows native ZIP + shell: pwsh + run: | + $ErrorActionPreference = "Stop" + + npm ci --ignore-scripts + if ($LASTEXITCODE -ne 0) { throw "npm ci failed: $LASTEXITCODE" } + + npm run build + if ($LASTEXITCODE -ne 0) { throw "npm run build failed: $LASTEXITCODE" } + + npm run build:native-bundle + if ($LASTEXITCODE -ne 0) { + throw "npm run build:native-bundle failed: $LASTEXITCODE" + } + + $version = node -p "require('./package.json').version" + if ($LASTEXITCODE -ne 0) { throw "Could not read package version" } + + $archive = Join-Path $PWD "dist/release/feynman-$version-win32-x64.zip" + if (-not (Test-Path -LiteralPath $archive)) { + throw "Expected native archive was not produced: $archive" + } + if ((Get-Item -LiteralPath $archive).Length -eq 0) { + throw "Native archive is empty: $archive" + } + + - name: Install candidate with Windows PowerShell 5.1 + shell: powershell + run: | + $ErrorActionPreference = "Stop" + + $version = node -p "require('./package.json').version" + if ($LASTEXITCODE -ne 0) { throw "Could not read package version" } + + $archive = Join-Path $PWD "dist/release/feynman-$version-win32-x64.zip" + & ./scripts/verify-windows-installer.ps1 ` + -ArchivePath $archive ` + -Version $version + + - name: Install candidate with PowerShell Core + shell: pwsh + run: | + $ErrorActionPreference = "Stop" + + $version = node -p "require('./package.json').version" + if ($LASTEXITCODE -ne 0) { throw "Could not read package version" } + + $archive = Join-Path $PWD "dist/release/feynman-$version-win32-x64.zip" + & ./scripts/verify-windows-installer.ps1 ` + -ArchivePath $archive ` + -Version $version diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f84b48e7..83cd5718 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,6 +8,10 @@ on: branches: [main] workflow_dispatch: +concurrency: + group: publish-${{ github.repository }}-${{ github.ref }} + cancel-in-progress: false + jobs: version-check: runs-on: ubuntu-latest @@ -19,30 +23,160 @@ jobs: should_release_github: ${{ steps.version.outputs.should_release_github }} should_run_verify: ${{ steps.version.outputs.should_run_verify }} steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version: 24 + node-version-file: .nvmrc registry-url: "https://registry.npmjs.org" - id: version shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + set -euo pipefail + if [ "$GITHUB_REF" != "refs/heads/main" ]; then + echo "Releases may only run from main; got $GITHUB_REF" >&2 + exit 1 + fi LOCAL=$(node -p "require('./package.json').version") echo "version=$LOCAL" >> "$GITHUB_OUTPUT" - PUBLISHED=$(npm view @companion-ai/feynman version 2>/dev/null || true) + + PUBLISHED_GIT_HEAD="" + npm_error="$RUNNER_TEMP/npm-view-version.err" + if PUBLISHED=$(npm view "@companion-ai/feynman@$LOCAL" version 2>"$npm_error"); then + : + elif grep -q 'E404' "$npm_error"; then + PUBLISHED="" + else + cat "$npm_error" >&2 + exit 1 + fi if [ "$PUBLISHED" = "$LOCAL" ]; then + git_head_error="$RUNNER_TEMP/npm-view-git-head.err" + if ! PUBLISHED_GIT_HEAD=$(npm view "@companion-ai/feynman@$LOCAL" gitHead 2>"$git_head_error"); then + cat "$git_head_error" >&2 + exit 1 + fi + if [ -z "$PUBLISHED_GIT_HEAD" ]; then + echo "npm version $LOCAL has no gitHead" >&2 + exit 1 + fi echo "should_publish_npm=false" >> "$GITHUB_OUTPUT" else + latest_error="$RUNNER_TEMP/npm-view-latest.err" + if LATEST=$(npm view "@companion-ai/feynman@latest" version 2>"$latest_error"); then + LOCAL="$LOCAL" LATEST="$LATEST" node <<'NODE' + const parse = (value) => { + const match = /^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(value); + if (!match) throw new Error(`Release version is not valid SemVer: ${value}`); + return match.slice(1, 4).map(Number); + }; + const local = parse(process.env.LOCAL); + const latest = parse(process.env.LATEST); + const newer = local.some((value, index) => + value > latest[index] && local.slice(0, index).every((part, prior) => part === latest[prior]) + ); + if (!newer) { + throw new Error(`Release version ${process.env.LOCAL} must be newer than npm latest ${process.env.LATEST}`); + } + NODE + elif ! grep -q 'E404' "$latest_error"; then + cat "$latest_error" >&2 + exit 1 + fi echo "should_publish_npm=true" >> "$GITHUB_OUTPUT" fi - if gh release view "v$LOCAL" >/dev/null 2>&1; then + + RELEASE_COMPLETE=false + RELEASE_EXISTS=false + RELEASE_TARGET="" + release_error="$RUNNER_TEMP/gh-release-view.err" + if RELEASE_JSON=$(gh release view "v$LOCAL" --json assets,isDraft,isPrerelease,tagName,targetCommitish 2>"$release_error"); then + RELEASE_EXISTS=true + RELEASE_TARGET=$(RELEASE_JSON="$RELEASE_JSON" node -e \ + 'process.stdout.write(JSON.parse(process.env.RELEASE_JSON).targetCommitish ?? "")') + if [ -z "$RELEASE_TARGET" ]; then + echo "GitHub release v$LOCAL has no target commit" >&2 + exit 1 + fi + RELEASE_COMPLETE=$(RELEASE_JSON="$RELEASE_JSON" VERSION="$LOCAL" node <<'NODE' + const release = JSON.parse(process.env.RELEASE_JSON); + const version = process.env.VERSION; + const expected = new Set([ + `feynman-${version}-linux-x64.tar.gz`, + `feynman-${version}-linux-arm64.tar.gz`, + `feynman-${version}-darwin-x64.tar.gz`, + `feynman-${version}-darwin-arm64.tar.gz`, + `feynman-${version}-win32-x64.zip`, + "SHA256SUMS", + ]); + const assets = Array.isArray(release.assets) ? release.assets : []; + const actual = new Set(assets.map((asset) => asset.name)); + const complete = + release.tagName === `v${version}` && + release.isDraft === false && + release.isPrerelease === false && + assets.length === expected.size && + assets.every((asset) => + expected.has(asset.name) && + Number(asset.size) > 0 && + /^sha256:[a-f0-9]{64}$/.test(asset.digest ?? "") && + typeof asset.url === "string" && + asset.url.length > 0 + ) && + [...expected].every((name) => actual.has(name)); + process.stdout.write(String(complete)); + NODE + ) + elif ! grep -qi 'release not found' "$release_error"; then + cat "$release_error" >&2 + exit 1 + fi + + if [ "$RELEASE_COMPLETE" = "true" ] && [ "$PUBLISHED" = "$LOCAL" ]; then + if [ "$PUBLISHED_GIT_HEAD" != "$RELEASE_TARGET" ]; then + echo "npm version $LOCAL belongs to $PUBLISHED_GIT_HEAD, but GitHub release v$LOCAL targets $RELEASE_TARGET" >&2 + exit 1 + fi + release_relation=$(gh api \ + "repos/$GITHUB_REPOSITORY/compare/$RELEASE_TARGET...$GITHUB_SHA" \ + --jq .status) + case "$release_relation" in + identical | ahead) + ;; + *) + echo "Published release v$LOCAL at $RELEASE_TARGET is not an ancestor of $GITHUB_SHA (status: $release_relation)" >&2 + exit 1 + ;; + esac + elif [ "$PUBLISHED" = "$LOCAL" ] && [ "$PUBLISHED_GIT_HEAD" != "$GITHUB_SHA" ]; then + echo "Incomplete release v$LOCAL belongs to npm commit $PUBLISHED_GIT_HEAD, not $GITHUB_SHA" >&2 + exit 1 + fi + + if \ + [ "$RELEASE_EXISTS" = "true" ] && + [ "$RELEASE_COMPLETE" != "true" ] && + [ "$RELEASE_TARGET" != "$GITHUB_SHA" ] + then + echo "Incomplete GitHub release v$LOCAL targets $RELEASE_TARGET, not $GITHUB_SHA" >&2 + exit 1 + fi + if \ + [ "$RELEASE_COMPLETE" = "true" ] && + [ "$PUBLISHED" != "$LOCAL" ] && + [ "$RELEASE_TARGET" != "$GITHUB_SHA" ] + then + echo "Cannot publish npm $LOCAL from $GITHUB_SHA for an existing GitHub release at $RELEASE_TARGET" >&2 + exit 1 + fi + + if [ "$RELEASE_COMPLETE" = "true" ]; then echo "should_release_github=false" >> "$GITHUB_OUTPUT" else echo "should_release_github=true" >> "$GITHUB_OUTPUT" fi - if [ "$PUBLISHED" = "$LOCAL" ] && gh release view "v$LOCAL" >/dev/null 2>&1; then + if [ "$PUBLISHED" = "$LOCAL" ] && [ "$RELEASE_COMPLETE" = "true" ]; then echo "should_run_verify=false" >> "$GITHUB_OUTPUT" else echo "should_run_verify=true" >> "$GITHUB_OUTPUT" @@ -54,53 +188,227 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + outputs: + package_integrity: ${{ steps.package.outputs.integrity }} steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version: 24 + node-version-file: .nvmrc registry-url: "https://registry.npmjs.org" - - run: npm ci - - run: npm test - - run: npm pack + - id: package + name: Validate source, website, package, and clean consumer + shell: bash + env: + SHOULD_PUBLISH_NPM: ${{ needs.version-check.outputs.should_publish_npm }} + VERSION: ${{ needs.version-check.outputs.version }} + run: | + set -euxo pipefail + npm ci + npm test + npm run typecheck + npm run build + npm run architecture:check + npm audit --omit=dev + ( + cd website + npm ci + npm run lint + npm run typecheck + npm run build + npm audit --omit=dev + ) + git diff --check + + tarball="$RUNNER_TEMP/companion-ai-feynman-$VERSION.tgz" + if [ "$SHOULD_PUBLISH_NPM" = "true" ]; then + npm pack --dry-run --json > "$RUNNER_TEMP/pack-dry-run.json" + npm pack --json --pack-destination "$RUNNER_TEMP" > "$RUNNER_TEMP/pack.json" + node scripts/verify-package-budget.mjs "$RUNNER_TEMP/pack.json" "$tarball" + else + npm_tarball_error="$RUNNER_TEMP/npm-view-tarball.err" + if ! npm_tarball_url=$(npm view "@companion-ai/feynman@$VERSION" dist.tarball 2>"$npm_tarball_error"); then + cat "$npm_tarball_error" >&2 + exit 1 + fi + test -n "$npm_tarball_url" + curl --fail --location --retry 5 --retry-all-errors \ + "$npm_tarball_url" --output "$tarball" + fi + test -s "$tarball" + echo "tarball=$tarball" >> "$GITHUB_OUTPUT" + integrity=$(TARBALL="$tarball" node -e \ + 'const { createHash } = require("node:crypto"); const { readFileSync } = require("node:fs"); process.stdout.write("sha512-" + createHash("sha512").update(readFileSync(process.env.TARBALL)).digest("base64"))') + if [ "$SHOULD_PUBLISH_NPM" = "false" ]; then + published_integrity=$(npm view "@companion-ai/feynman@$VERSION" dist.integrity) + test -n "$published_integrity" + test "$integrity" = "$published_integrity" + fi + echo "integrity=$integrity" >> "$GITHUB_OUTPUT" + if [ "$SHOULD_PUBLISH_NPM" = "true" ]; then + npm audit --omit=dev --prefix .feynman/npm + node scripts/verify-package-artifact.mjs . + fi + + consumer="$RUNNER_TEMP/feynman-consumer" + mkdir -p "$consumer" + (cd "$consumer" && npm init -y >/dev/null) + npm install --prefix "$consumer" --omit=dev --no-audit "$tarball" + npm audit --omit=dev --prefix "$consumer" + bin="$consumer/node_modules/.bin/feynman" + test "$("$bin" --version | tail -1)" = "$(node -p "require('./package.json').version")" + "$bin" --help >/dev/null + HOME="$RUNNER_TEMP/feynman-home" FEYNMAN_HOME="$RUNNER_TEMP/feynman-home" "$bin" packages list + HOME="$RUNNER_TEMP/feynman-home" FEYNMAN_HOME="$RUNNER_TEMP/feynman-home" "$bin" search status + runtime_audit="$RUNNER_TEMP/feynman-runtime-audit" + mkdir -p "$runtime_audit" + tar -xzf \ + "$consumer/node_modules/@companion-ai/feynman/.feynman/runtime-workspace.tgz" \ + -C "$runtime_audit" + npm audit --omit=dev --prefix "$runtime_audit/npm" + node "$consumer/node_modules/@companion-ai/feynman/scripts/verify-package-artifact.mjs" \ + "$consumer/node_modules/@companion-ai/feynman" + test -z "$(git status --porcelain --untracked-files=all)" + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: npm-package + path: ${{ steps.package.outputs.tarball }} + if-no-files-found: error + + verify-package-consumers: + needs: + - version-check + - verify + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + node: "22.22.0" + - os: ubuntu-latest + node: "24.18.0" + - os: ubuntu-latest + node: "25" + - os: macos-14 + node: "24.18.0" + - os: windows-latest + node: "24.18.0" + - os: windows-latest + node: "25" + runs-on: ${{ matrix.os }} + permissions: + contents: read + steps: + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: ${{ matrix.node }} + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: npm-package + path: npm-package + - name: Verify the exact npm tarball on ${{ matrix.os }} with Node ${{ matrix.node }} + shell: bash + env: + VERSION: ${{ needs.version-check.outputs.version }} + run: | + set -euxo pipefail + count=$(find npm-package -type f -name '*.tgz' | wc -l | tr -d ' ') + test "$count" = "1" + tarball=$(find npm-package -type f -name '*.tgz' -print) + tarball=$(node -e 'process.stdout.write(require("node:path").resolve(process.argv[1]))' "$tarball") + consumer="$RUNNER_TEMP/feynman-consumer" + mkdir -p "$consumer" + (cd "$consumer" && npm init -y >/dev/null) + npm install --prefix "$consumer" --omit=dev --no-audit "$tarball" + npm audit --omit=dev --prefix "$consumer" + bin="$consumer/node_modules/.bin/feynman" + test "$("$bin" --version | tail -1)" = "$VERSION" + "$bin" --help >/dev/null + HOME="$RUNNER_TEMP/feynman-home" FEYNMAN_HOME="$RUNNER_TEMP/feynman-home" "$bin" packages list + HOME="$RUNNER_TEMP/feynman-home" FEYNMAN_HOME="$RUNNER_TEMP/feynman-home" "$bin" search status + runtime_audit="$RUNNER_TEMP/feynman-runtime-audit" + mkdir -p "$runtime_audit" + tar -xzf \ + "$consumer/node_modules/@companion-ai/feynman/.feynman/runtime-workspace.tgz" \ + -C "$runtime_audit" + npm audit --omit=dev --prefix "$runtime_audit/npm" + node "$consumer/node_modules/@companion-ai/feynman/scripts/verify-package-artifact.mjs" \ + "$consumer/node_modules/@companion-ai/feynman" publish-npm: needs: - version-check - verify - if: needs.version-check.outputs.should_publish_npm == 'true' && needs.verify.result == 'success' + - verify-package-consumers + - build-native-bundles + if: >- + needs.version-check.outputs.should_publish_npm == 'true' && + needs.verify.result == 'success' && + needs.verify-package-consumers.result == 'success' && + needs.build-native-bundles.result == 'success' runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version: 24 + node-version-file: .nvmrc registry-url: "https://registry.npmjs.org" - - run: npm ci + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + name: npm-package + path: npm-package - shell: bash env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | - LOCAL=$(node -p "require('./package.json').version") - PUBLISHED=$(npm view @companion-ai/feynman version 2>/dev/null || true) + set -euo pipefail + mapfile -t tarballs < <(find npm-package -type f -name '*.tgz' -print) + test "${#tarballs[@]}" -eq 1 + tarball="${tarballs[0]}" + LOCAL=$(tar -xOf "$tarball" package/package.json | node -e \ + 'let source=""; process.stdin.on("data", chunk => source += chunk).on("end", () => process.stdout.write(JSON.parse(source).version))') + test "$LOCAL" = "${{ needs.version-check.outputs.version }}" + npm_error="$RUNNER_TEMP/npm-view-before-publish.err" + if PUBLISHED=$(npm view "@companion-ai/feynman@$LOCAL" version 2>"$npm_error"); then + : + elif grep -q 'E404' "$npm_error"; then + PUBLISHED="" + else + cat "$npm_error" >&2 + exit 1 + fi if [ "$PUBLISHED" = "$LOCAL" ]; then - echo "@companion-ai/feynman@$LOCAL is already published; skipping npm publish." + published_git_head=$(npm view "@companion-ai/feynman@$LOCAL" gitHead) + test -n "$published_git_head" + test "$published_git_head" = "$GITHUB_SHA" + published_integrity=$(npm view "@companion-ai/feynman@$LOCAL" dist.integrity) + test "$published_integrity" = "${{ needs.verify.outputs.package_integrity }}" + echo "@companion-ai/feynman@$LOCAL already matches this verified commit and tarball; skipping npm publish." exit 0 fi - npx npm@latest publish --access public --provenance + npx npm@11.18.0 publish "$tarball" --access public --provenance build-native-bundles: - needs: version-check - if: needs.version-check.outputs.should_release_github == 'true' + needs: + - version-check + - verify + - verify-package-consumers + if: >- + needs.version-check.outputs.should_run_verify == 'true' && + needs.verify.result == 'success' && + needs.verify-package-consumers.result == 'success' strategy: fail-fast: false matrix: include: - id: linux-x64 os: ubuntu-latest + - id: linux-arm64 + os: ubuntu-24.04-arm - id: darwin-x64 os: macos-15-intel - id: darwin-arm64 @@ -111,10 +419,10 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version: 24 + node-version-file: .nvmrc - run: npm ci --ignore-scripts - run: npm run build - run: npm run build:native-bundle @@ -137,7 +445,10 @@ jobs: Expand-Archive -LiteralPath "dist/release/feynman-$version-win32-x64.zip" -DestinationPath $tmp -Force $bundleRoot = Join-Path $tmp "feynman-$version-win32-x64" & (Join-Path $bundleRoot "feynman.cmd") --help | Select-Object -First 20 - - uses: actions/upload-artifact@v7 + if ($LASTEXITCODE -ne 0) { + throw "Windows native launcher failed --help: $LASTEXITCODE" + } + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: native-${{ matrix.id }} path: dist/release/* @@ -145,16 +456,27 @@ jobs: release-github: needs: - version-check + - verify + - publish-npm - build-native-bundles - if: needs.version-check.outputs.should_release_github == 'true' && needs.build-native-bundles.result == 'success' + if: >- + always() && + needs.version-check.outputs.should_release_github == 'true' && + needs.verify.result == 'success' && + needs.build-native-bundles.result == 'success' && + ( + needs.version-check.outputs.should_publish_npm == 'false' || + needs.publish-npm.result == 'success' + ) runs-on: ubuntu-latest permissions: contents: write steps: - - uses: actions/checkout@v6 - - uses: actions/download-artifact@v8 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: path: release-assets + pattern: native-* merge-multiple: true - name: Build release notes shell: bash @@ -162,6 +484,10 @@ jobs: VERSION: ${{ needs.version-check.outputs.version }} run: | node scripts/extract-release-notes.mjs "$VERSION" "$RUNNER_TEMP/release-notes.md" + ( + cd release-assets + sha256sum feynman-* > SHA256SUMS + ) - name: Create GitHub release shell: bash env: @@ -169,16 +495,206 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} VERSION: ${{ needs.version-check.outputs.version }} run: | - if gh release view "v$VERSION" >/dev/null 2>&1; then + set -euo pipefail + release_error="$RUNNER_TEMP/gh-release-before-write.err" + if gh release view "v$VERSION" >/dev/null 2>"$release_error"; then + release_exists=true + elif grep -qi 'release not found' "$release_error"; then + release_exists=false + else + cat "$release_error" >&2 + exit 1 + fi + if [ "$release_exists" = "true" ]; then + gh release edit "v$VERSION" --draft=true --prerelease=false + while IFS= read -r asset; do + case "$asset" in + "feynman-$VERSION-linux-x64.tar.gz" | \ + "feynman-$VERSION-linux-arm64.tar.gz" | \ + "feynman-$VERSION-darwin-x64.tar.gz" | \ + "feynman-$VERSION-darwin-arm64.tar.gz" | \ + "feynman-$VERSION-win32-x64.zip" | \ + "SHA256SUMS") + ;; + *) + gh release delete-asset "v$VERSION" "$asset" --yes + ;; + esac + done < <(gh release view "v$VERSION" --json assets --jq '.assets[].name') gh release upload "v$VERSION" release-assets/* --clobber - gh release edit "v$VERSION" \ - --title "v$VERSION" \ - --notes-file "$RUNNER_TEMP/release-notes.md" \ - --draft=false \ - --latest else gh release create "v$VERSION" release-assets/* \ --title "v$VERSION" \ --notes-file "$RUNNER_TEMP/release-notes.md" \ - --target "$GITHUB_SHA" + --target "$GITHUB_SHA" \ + --draft fi + + staged_dir="$RUNNER_TEMP/staged-release" + mkdir -p "$staged_dir" + gh release download "v$VERSION" --dir "$staged_dir" + RELEASE_DIR="$staged_dir" VERSION="$VERSION" node <<'NODE' + const { readFileSync, readdirSync, statSync } = require("node:fs"); + const version = process.env.VERSION; + const expectedArchives = [ + `feynman-${version}-linux-x64.tar.gz`, + `feynman-${version}-linux-arm64.tar.gz`, + `feynman-${version}-darwin-x64.tar.gz`, + `feynman-${version}-darwin-arm64.tar.gz`, + `feynman-${version}-win32-x64.zip`, + ].sort(); + const expectedFiles = [...expectedArchives, "SHA256SUMS"].sort(); + const actualFiles = readdirSync(process.env.RELEASE_DIR).sort(); + if ( + JSON.stringify(actualFiles) !== JSON.stringify(expectedFiles) || + actualFiles.some((name) => statSync(`${process.env.RELEASE_DIR}/${name}`).size === 0) + ) { + throw new Error(`Staged release asset mismatch: ${actualFiles.join(", ")}`); + } + const checksumEntries = readFileSync( + `${process.env.RELEASE_DIR}/SHA256SUMS`, + "utf8", + ).trim().split(/\r?\n/).map((line) => { + const match = /^([a-f0-9]{64})\s+\*?(.+)$/.exec(line); + if (!match) throw new Error(`Invalid SHA256SUMS line: ${line}`); + return match[2]; + }).sort(); + if (JSON.stringify(checksumEntries) !== JSON.stringify(expectedArchives)) { + throw new Error(`SHA256SUMS entry mismatch: ${checksumEntries.join(", ")}`); + } + NODE + (cd "$staged_dir" && sha256sum -c SHA256SUMS) + gh release edit "v$VERSION" \ + --title "v$VERSION" \ + --notes-file "$RUNNER_TEMP/release-notes.md" \ + --draft=false \ + --prerelease=false \ + --latest + + verify-published-state: + needs: + - version-check + - verify + - publish-npm + - release-github + if: >- + always() && + needs.version-check.outputs.should_run_verify == 'true' && + ( + needs.version-check.outputs.should_publish_npm == 'false' || + needs.publish-npm.result == 'success' + ) && + ( + needs.version-check.outputs.should_release_github == 'false' || + needs.release-github.result == 'success' + ) + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version-file: .nvmrc + registry-url: "https://registry.npmjs.org" + - name: Verify npm package and GitHub release + shell: bash + env: + GH_REPO: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ needs.version-check.outputs.version }} + run: | + set -euxo pipefail + + npm_visibility_error="$RUNNER_TEMP/npm-view-published.err" + for attempt in $(seq 1 18); do + if published_version=$(npm view "@companion-ai/feynman@$VERSION" version 2>"$npm_visibility_error"); then + if [ "$published_version" != "$VERSION" ]; then + echo "npm returned version $published_version for @companion-ai/feynman@$VERSION" >&2 + exit 1 + fi + break + fi + if ! grep -q 'E404' "$npm_visibility_error"; then + cat "$npm_visibility_error" >&2 + exit 1 + fi + if [ "$attempt" -eq 18 ]; then + cat "$npm_visibility_error" >&2 + echo "npm package did not become visible: @companion-ai/feynman@$VERSION" >&2 + exit 1 + fi + sleep 10 + done + + published_git_head=$(npm view "@companion-ai/feynman@$VERSION" gitHead) + if [ -z "$published_git_head" ] || [ "$published_git_head" != "$GITHUB_SHA" ]; then + echo "Published npm package belongs to $published_git_head, not $GITHUB_SHA" >&2 + exit 1 + fi + published_integrity=$(npm view "@companion-ai/feynman@$VERSION" dist.integrity) + test "$published_integrity" = "${{ needs.verify.outputs.package_integrity }}" + + consumer="$RUNNER_TEMP/published-consumer" + mkdir -p "$consumer" + (cd "$consumer" && npm init -y >/dev/null) + npm install --prefix "$consumer" --omit=dev --no-audit "@companion-ai/feynman@$VERSION" + npm audit --omit=dev --prefix "$consumer" + bin="$consumer/node_modules/.bin/feynman" + test "$("$bin" --version | tail -1)" = "$VERSION" + "$bin" --help >/dev/null + node "$consumer/node_modules/@companion-ai/feynman/scripts/verify-package-artifact.mjs" \ + "$consumer/node_modules/@companion-ai/feynman" + + release_dir="$RUNNER_TEMP/published-release" + mkdir -p "$release_dir" + gh release download "v$VERSION" \ + --pattern "feynman-$VERSION-*" \ + --dir "$release_dir" + gh release download "v$VERSION" \ + --pattern "SHA256SUMS" \ + --dir "$release_dir" + release_target=$(gh release view "v$VERSION" --json targetCommitish --jq .targetCommitish) + test "$release_target" = "$GITHUB_SHA" + RELEASE_DIR="$release_dir" VERSION="$VERSION" node <<'NODE' + const { readFileSync, readdirSync, statSync } = require("node:fs"); + const expectedArchives = [ + `feynman-${process.env.VERSION}-linux-x64.tar.gz`, + `feynman-${process.env.VERSION}-linux-arm64.tar.gz`, + `feynman-${process.env.VERSION}-darwin-x64.tar.gz`, + `feynman-${process.env.VERSION}-darwin-arm64.tar.gz`, + `feynman-${process.env.VERSION}-win32-x64.zip`, + ].sort(); + const expectedFiles = [...expectedArchives, "SHA256SUMS"].sort(); + const files = readdirSync(process.env.RELEASE_DIR).sort(); + if ( + JSON.stringify(files) !== JSON.stringify(expectedFiles) || + files.some((name) => statSync(`${process.env.RELEASE_DIR}/${name}`).size === 0) + ) { + throw new Error(`Release asset mismatch: ${files.join(", ")}`); + } + const checksumEntries = readFileSync( + `${process.env.RELEASE_DIR}/SHA256SUMS`, + "utf8", + ).trim().split(/\r?\n/).map((line) => { + const match = /^([a-f0-9]{64})\s+\*?(.+)$/.exec(line); + if (!match) throw new Error(`Invalid SHA256SUMS line: ${line}`); + return match[2]; + }).sort(); + if (JSON.stringify(checksumEntries) !== JSON.stringify(expectedArchives)) { + throw new Error(`SHA256SUMS entry mismatch: ${checksumEntries.join(", ")}`); + } + NODE + + (cd "$release_dir" && sha256sum -c SHA256SUMS) + for archive in "$release_dir"/*.tar.gz; do + tar -tzf "$archive" >/dev/null + done + unzip -t "$release_dir/feynman-$VERSION-win32-x64.zip" >/dev/null + + native_root="$RUNNER_TEMP/published-native" + mkdir -p "$native_root" + tar -xzf "$release_dir/feynman-$VERSION-linux-x64.tar.gz" -C "$native_root" + native="$native_root/feynman-$VERSION-linux-x64/feynman" + test "$("$native" --version | tail -1)" = "$VERSION" + "$native" --help >/dev/null diff --git a/.gitignore b/.gitignore index 1e583c6c..0877c590 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,11 @@ node_modules .feynman/git .feynman/sessions .feynman/workbench +.feynman/cache .feynman/schedule-prompts.json dist *.tgz +.feynman/runtime-workspace.sha256 outputs/* !outputs/.gitkeep papers/* diff --git a/.nvmrc b/.nvmrc index a45fd52c..ca5c3500 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24 +24.18.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index abddc93c..25a7af1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,349 @@ Workspace lab notebook for long-running or resumable research work. Use this file to track chronology, not release notes. Keep entries short, factual, and operational. +### 2026-07-28 01:49 PDT — intake-sweep-pi-web-access-0-15 + +- Objective: Resolve the post-cutoff `pi-web-access@0.15.0` research-search release before publishing Feynman `0.3.6`. +- Changed: Pinned the bundled and seeded web-access package to `0.15.0`, refreshed the committed runtime lock/archive, documented simultaneous all-provider search, TinyFish search/extraction, and configurable OpenAI Responses-compatible gateways, and extended Feynman's package patch so current upstream `utils.ts` continues to honor the exact `FEYNMAN_WEB_SEARCH_CONFIG` file instead of falling back to Pi's agent directory. +- Verified: The exact upstream tag/commit passed its patched test suite (`215/215`), typecheck, runtime production audit, idempotency, and diff check. Focused Feynman package/runtime/settings/integrity regressions passed (`50/50`); full tests passed (`649/649`); typecheck, build, architecture, actionlint, website lint/typecheck/build, root/site/runtime/consumer audits, and diff check passed. Dry and real packs matched at SHA-1 `ae23ce2976abe5a3d5920435ad4f4f9a68a8a395`; the real tarball SHA-256 is `b6d10e01f6bea37984016b7b4a294a8a038ac5e295ccc38c826040583cfa025d`. Clean installed-artifact verification reports Pi `0.82.1`, `pi-web-access@0.15.0`, and runtime SHA-256 `2ec33eae33d1d994b73a6826703200daf0883295b2e52a786ea268f5b94375ef`; isolated RPC loaded `web-results` while ignoring an intentionally invalid agent-directory web config in favor of Feynman's exact config path. +- Next: Commit and push the exact candidate, run the clean Daytona ladder at that SHA, require the final GitHub Windows/Node matrix to pass, then merge and verify npm/GitHub release identity. + +### 2026-07-28 01:24 PDT — intake-sweep-windows-consumer-path + +- Objective: Repair the final exact-head PR `#192` platform failure without weakening the shared candidate-tarball gate. +- Fixed: Run `30341296771` proved that both Windows Node `24.18.0` and Node `25` consumers converted the downloaded tarball to a native `D:\...` path, which GNU tar interpreted as a remote host. The PR consumer gate now retains a native absolute tarball for npm, derives an MSYS path for GNU tar, and normalizes shell-owned consumer and runtime extraction paths under Git Bash. +- Verified: The exact parent candidate passed the GitHub release-candidate source/package job and entered both Windows installer hosts; actionlint, the focused release-workflow suite (`5/5`), and `git diff --check` pass with the path repair. Exact successor CI, final clean Daytona verification, merge, and publication remain pending. +- Next: Commit and push the repair, require every Windows/Node/native job to pass, rerun clean-machine proof at the successor SHA, then merge and verify the `0.3.6` release. + +### 2026-07-28 01:07 PDT — intake-sweep-0-3-6-final-candidate + +- Objective: Finish PR `#192` as the single release path for issues `#182/#185/#186/#187/#188/#190/#193/#196`, including the remaining Windows, supported-Node, packaged-runtime, and live-auth gates. +- Fixed: Raised the Node 22 floor to `22.22.0`; made candidate-tarball paths absolute; kept the PowerShell launcher while validating it under execution-policy bypass; normalized Windows runtime hardlinks; updated MCP to `1.30.0`, Hono to `2.0.12`, and `pi-subagents` to `0.37.2`; made installed-consumer CI audit the extracted runtime archive; made runtime recovery verify every manifest package; and made both alphaXiv status paths refresh and verify credentials against live user-info. +- Verified: Full tests passed (`648/648`); typecheck, build, architecture, actionlint, website lint/typecheck/build (`34` pages), root/site/runtime/consumer audits, and `git diff --check` passed. Final tarball SHA-256 is `06cdfd606a52e5a59d15d7276c68a9e542f3b40dfa120a4fda5a970e2676fa2b` (`111572902` bytes, `327212330` unpacked, `39105` files); source and installed artifact verification passed with Pi `0.82.1` and runtime SHA-256 `7a858a29c51dcf977be07ba6be1c64ba023b4eaad3aacf0f7ed03414c9679056`. Exact-package RPC proved extension/prompt loading, direct bash, and `/thinking` clamping; live OpenAI model, researcher subagent, and refreshed alphaXiv user-info smokes passed. +- Next: Commit and push the exact candidate, run and delete a disposable Daytona sandbox at that SHA, require the full GitHub Windows and Node `22/24/25` matrix to pass, merge, then verify npm/GitHub/native release identity and issue closure. + +### 2026-07-26 17:48 PDT — intake-sweep-windows-runtime-hardlinks + +- Objective: Repair PR `#192` Windows native job `89859997454` at exact head `8bf9f1a2e5af48787c2eb47eae3726b86cacb9c1` without weakening runtime archive integrity. +- Fixed: Windows tar preserved npm-created NTFS hardlinks, while the live workspace hash treated each hardlink as its regular-file contents and the archive hash treated it as a distinct entry type. Runtime archive verification now resolves in-archive hardlinks to their target file or symlink content, rejects targets outside `npm/`, duplicate entries, missing targets, and cycles, and compares the same logical tree on every platform. +- Further fixed: All public Windows PowerShell downloads now use `-UseBasicParsing`, which Microsoft requires after the CVE-2025-54100 PowerShell 5.1 update to avoid an interactive script-execution prompt. PR and publish gates now reuse the exact packed candidate across Node `22.19.0`, `24.18.0`, and `25`, including Windows Node 25 plus macOS and Windows Node 24 consumers, instead of leaving the supported-major matrix manual and post-publication. +- Verified: A minimal hardlink repro failed against the prior archive parser; the focused archive/runtime regression suite passes (`8/8`), the installer/workflow suite passes (`8/8`), actionlint passes, both public Windows installers are byte-identical, and root typecheck/full tests/build/architecture plus `git diff --check` passed at the hardlink commit (`642/642`). Exact Windows native/install and supported-major consumer proof remain pending the next pushed-head CI run. +- Next: Push the remaining gate repairs, require the complete PR matrix to pass, then finish clean-machine, merge, and release verification. + +### 2026-07-26 17:16 PDT — intake-sweep-0-3-6-windows-ci-repair + +- Objective: Repair the first exact-head PR CI failure at `f5974f96ae9b1950ced68093c6ee1abdb9acc5d9` without weakening the release verifier. +- Fixed: Windows native build run `30226243548`, job `89856784343`, proved that the production dependency install replaced the patched MCP manifest before artifact verification. The embedded runtime patch now repairs MCP manifests in the installed package and vendored workspace graphs. The Windows installer also validates downloaded PowerShell launchers through the current host with a process-scoped execution-policy bypass, preserving the public in-memory installer under Windows PowerShell's default Restricted policy. A follow-up adversarial check found that the StrictMode verifier used `$installBinDir` without defining it; the verifier now derives that path explicitly and tests the assignment. +- Verified: Focused archive, installer, MCP, runtime-patch, and release-workflow tests passed (`18/18`) before the StrictMode follow-up; both public Windows installer copies are byte-identical; actionlint and `git diff --check` passed. Exact Windows native/install proof remains pending the next pushed-head CI run. +- Next: Commit and push the repair, require both Windows PowerShell 5.1 and PowerShell Core jobs to pass, then continue clean-machine and release verification. + +### 2026-07-26 16:48 PDT — intake-sweep-0-3-6-release-candidate + +- Objective: Reconcile the inherited 0.3.6 work into PR `#192`, finish the Pi 0.82.1/security/package/installer release blockers, and prove the exact candidate before merge and publication. +- Changes: Migrated Feynman's model/auth/session paths to Pi 0.82.1 `ModelRuntime`; added model-aware `/thinking`; preserved Pi follow-up while adding Option+Enter newline input; pinned and integrity-bound the packaged runtime graph; repaired Pi brace-expansion and MCP/Hono consumer advisories; made runtime/native archives deterministic; made Windows replacement transactional and checksum-ambiguous inputs fail closed; added Windows Desktop/Core, clean-consumer, package-budget, native matrix, exact-tarball publication, and release-reconciliation gates. The publish gate now accepts a complete npm/GitHub release at an ancestor commit while still requiring exact commit identity for incomplete-release recovery, so ordinary later main commits do not false-fail the prior release. +- Intake: PR `#192` is the owning merge path. PR `#200` is superseded by the independently prepared model-aware implementation and should close after the replacement commit is pushed. Issues `#182/#185/#186/#187/#188/#190/#193/#196` are implemented and remain open only until exact-head CI, merge, and release verification. +- Verified locally: Focused regressions passed (`64/64`); full `npm test` passed (`639/639`); typecheck, build, architecture check, website lint/typecheck/build (`34` pages), actionlint, root/site/runtime/consumer production audits, and `git diff --check` passed. Exact tarball `companion-ai-feynman-0.3.6.tgz` is `111547961` bytes with `39088` files, SHA-256 `d95cd2bdce96069653707b85f06a6d1e453113893a354d46a02f676d25503e26`; source and installed artifact verification passed with Pi `0.82.1` and runtime archive SHA-256 `0bb4e8c6049a1a9d3742f36350cd978c46d249d22c4cbf6942fac8ff6d4dd8ae`. An installed Pi session reached the expected missing OpenAI credential only after runtime load and workspace scaffolding. +- Next: Commit and push the exact candidate, run and delete a disposable Daytona proof, repair PR CI to green, merge, then verify npm/GitHub/native release identity and terminally reconcile the eight issues plus PR `#200`. + +### 2026-07-22 20:10 EDT — intake-sweep-package-floor + +- Objective: Finish the `check-new-issues` release-candidate proof after the queue audit, preserve the existing PR branch, and correct package metadata that made supported Node 22 installs noisy or inconsistent. +- Changes: Raised the website engine contract from Node `>=20.19.0 <25` to `>=22.19.0 <26`, matching Astro 7 and the root Feynman runtime. Moved `ketcher-core`, `ketcher-react`, and `ketcher-standalone` from production dependencies to exact `3.15.0` development dependencies because they are build-only inputs already bundled into `dist`. +- Verified: Clean root and website installs passed; the complete suite passed (`595/595`); focused runtime/MCP tests passed (`24/24`); root typecheck/build and architecture checks passed with existing warnings; website lint/typecheck/build passed (`34` pages); website audit found `0 vulnerabilities`; root audit still reports only Pi-shrinkwrapped `brace-expansion@5.0.6` and `protobufjs@7.6.4`; `npm pack --dry-run --json` passed with `402` entries. The exact tarball `/tmp/feynman-pack-release-20260722-2010/companion-ai-feynman-0.3.6.tgz` is `71043279` bytes with SHA-256 `6b9e4150f6b28233345bd99b4f3222371fe3d0e354ec7665740dac6a03cc9732`. +- Installed smoke: A fresh Node `22.22.3` install emitted no Ketcher engine warnings and passed version/help, alpha help, package listing, unknown `--extensions` guidance, `alt+enter`, packaged workspace scaffold creation, launch-before-spawn wiring, alphaXiv OAuth markers, project-local fetch-cache markers, and runtime archive entries for Pi `0.80.6`, `pi-btw` `0.4.1`, and `pi-web-access` `0.13.0`. +- Blocked: A consumer-side tarball audit additionally resolves `@modelcontextprotocol/sdk@1.29.0` to vulnerable `@hono/node-server@1.19.14`. The repository is clean because its root override selects `2.0.11`, but npm package overrides do not propagate to consumers and the latest MCP SDK still declares `@hono/node-server@^1.19.9`; no safe package-local version bump is currently available. +- Next: Keep PR `#192` unmerged and unpublished without explicit authorization; verify issue `#199` on a tool-capable Ubuntu/Ollama model before calling it fully fixed; resolve or explicitly accept the consumer-install MCP/Hono audit blocker before publishing `0.3.6`. + +### 2026-07-22 15:36 EDT — intake-sweep-workspace-scaffold + +- Objective: Re-run `check-new-issues`, preserve existing dirty release-candidate work, refresh live GitHub/release/package/workflow state, classify open issues/PRs/contributor refs, and fix safe repo-local validation or artifact failures without GitHub writes. +- Checked: New issue `#199` reports fresh Ubuntu/Ollama runs printing planned `outputs/.plans` writes without actually creating files because the workspace lacks `outputs/.plans`. Open issues are now `#199`, `#198`, `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#197`, `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains green at `54d08a3`; GitHub release and npm latest remain `v0.3.5` / `0.3.5`; local package remains `0.3.6`; bundled Pi remains `0.80.6`; npm Pi latest remains `0.81.1`. +- Decisions: Ported a smallest root-cause local fix for `#199`: Pi launch now scaffolds `outputs/.plans`, `outputs/.drafts`, `papers`, and `notes` under the selected `--cwd` before the child runtime starts. PR `#192` remains merge/defer pending explicit authorization; PR `#189` remains already ported into `#192`; PR `#191` remains reject/defer as broader extension inventory surface; PR `#197` remains reject/defer as generic provider catalog expansion. Issue `#198` remains outside the AI-researcher product bar; `#196` remains upstream Pi TUI slash-command scope; `#193/#182/#190/#188/#187/#186/#185` remain covered by `#192`; `#184` remains support/content scope. +- Contributor refs: Remote refs were refreshed. `origin/fix/deepresearch-local-model-warning` remains `74` behind / `1` ahead; `pr4fork/main` remains `73` behind / `0` ahead; visible fork refs did not introduce a fresh safe research-loop port target. +- Freshness: Root and website `npm outdated --json` show non-security drift. No dependency edit was made because the actionable defect was workspace artifact scaffolding, not dependency freshness. +- Verified: `npm test` passed (`595/595`); root `npm run typecheck`; root `npm run build` with existing RDKit/3Dmol/direct-eval/chunk warnings; `npm run architecture:check` with existing split-debt warnings; website lint/typecheck/build passed (`34` pages); website audit found `0 vulnerabilities`; root audit remains blocked by Pi-shrinkwrapped `brace-expansion@5.0.6` and `protobufjs@7.6.4`; `git diff --check` passed; `npm pack --dry-run --json` passed with `entryCount: 402`, shasum `ff8c9b527f00bee5588e7fbb43bc3660d97d044b`, size `71041173`; installed-tarball smoke passed for package `0.3.6`, help, and fresh-workspace scaffold creation. +- Next: Review/commit the scaffold fix with the existing `0.3.6` release-candidate work; merge/publish PR `#192` only when authorized; keep dependency freshness drift separate from `#199`. + +### 2026-07-22 07:32 EDT — intake-sweep-copilot-review-rejected + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve the existing dirty release-candidate worktree, refresh live GitHub/release/package/workflow state, classify open issues/PRs/contributor refs, and validate the local `0.3.6` package without GitHub writes. +- Checked: Open issues are `#198`, `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs are `#197`, `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains green at `54d08a3`; GitHub release and npm latest remain `v0.3.5` / `0.3.5`; local package remains `0.3.6`; bundled Pi remains `0.80.6`; npm Pi latest remains `0.81.1`; alpha-hub remains `0.1.3`; `pi-btw` remains `0.4.1`. +- Decisions: Issue `#198` is reject/defer because Microsoft Copilot reviewer/checklist automation is external review/admin workflow rather than a concrete Feynman-owned research-loop defect or smallest research artifact verification improvement. PR `#192` remains merge/defer pending explicit authorization; PR `#189` remains already ported into `#192`; PR `#191` remains reject/defer as broader extension inventory surface; PR `#197` remains reject/defer as generic curated provider expansion. Issue `#196` remains upstream Pi TUI slash-command scope; `#193/#182/#190/#188/#187/#186/#185` remain covered by `#192`; `#184` remains support/content scope. +- Contributor refs: Remote refs were refreshed. `origin/fix/deepresearch-local-model-warning`, `pr4fork/main`, and visible fork refs did not introduce a fresh safe research-loop port target. +- Freshness: Root and website `npm outdated --json` show non-security drift. No dependency edit was made because no queue-specific root-cause failure requires dependency churn and the remaining root audit blocker is still Pi-owned nested shrinkwrap state. +- Verified: Focused runtime test passed (`15/15`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/direct-eval/chunk warnings; `npm run architecture:check` with existing split-debt warnings; `npm test` passed (`594/594`); website lint/typecheck/build passed (`34` pages); website audit found `0 vulnerabilities`; root audit remains blocked only by Pi-shrinkwrapped `brace-expansion@5.0.6` and `protobufjs@7.6.4`; `git diff --check` passed; `npm pack --dry-run --json` passed with `entryCount: 402`, shasum `c698bb6c66c37756ba677c0a45af49c532f6a6d9`, size `71041144`; installed-tarball smoke passed for `0.3.6`, help, alpha help, `packages list` including `pi-btw` and `pi-web-access`, `update --extensions` help hint, `alt+enter`, runtime archive markers, alpha auth patch, and project-local fetch cache patch. +- Next: Merge/publish PR `#192` only when authorized; keep `#198`, `#197`, and `#191` out unless product scope explicitly changes. + +### 2026-07-13 23:35 PDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve existing dirty local work, refresh GitHub issue/PR/workflow/release/package/branch state, classify the queue against the AI-researcher product bar, and validate the local package without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues`; open issues remain `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi remains `0.80.6`; `@companion-ai/alpha-hub` remains `^0.1.3`. +- Decisions: No new code changes. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, `#190`, and `#193`; it already includes PR `#189` as cherry-pick `79aa7b2`. Reject/defer PR `#191` because `feynman extensions` is still a broader extension-inventory surface than the reported update/help failure requires and its Vercel status remains failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: Remote refs were refreshed. `origin/fix/deepresearch-local-model-warning` remains stale local-model warning work; visible fork refs were prompt/Overleaf/admin surfaces, provider/platform changes, fork docs, broad Windows rewrites, or already-covered installer/runtime/auth work. No new safe port target was found. +- Freshness: Root and website `npm outdated --json` show dependency drift only; root and website `npm audit --omit=dev` found `0 vulnerabilities`. No dependency change was made. +- Verified: Focused runtime test passed (`15/15`); `npm test` passed (`594/594`); root `npm run typecheck`; root `npm run build` with existing Vite/RDKit/3Dmol/chunk warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev`; `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `f0b50e989c04095e9a4b3b65628bcf6def9921aa`); installed-tarball smoke proved package `0.3.6`, CLI help, `feynman alpha --help`, `feynman packages list` including `npm:pi-btw` and `npm:pi-web-access`, runtime archive presence, and the hoisted alpha CLI resolver. +- Note: The installed tarball emitted dependency deprecation warnings during `npm install`, but completed successfully. No GitHub write was made. +- Next: Commit the hoisted alpha CLI resolver and merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-13 11:34 PDT — intake-sweep-alpha-193-covered + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve existing dirty local work, refresh GitHub issue/PR/workflow/release/package state, classify the queue against the AI-researcher product bar, and validate the local package without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; `origin/main` remains `54d08a3`. Open issues are now `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest/current remains `0.80.6`; `@companion-ai/alpha-hub` latest/current remains `0.1.3`. +- Decisions: No GitHub writes. Treat new issue `#193` as covered by the `#192` alphaXiv auth patch plus the current local hoisted-alpha CLI resolver in `src/cli.ts`; `clerk.alphaxiv.org` still fails with `ENOTFOUND`, while local patched alpha-hub uses `https://api.alphaxiv.org/auth`. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, `#190`, and `#193`; it already includes contributor PR `#189` as cherry-pick `79aa7b2`. Reject/defer PR `#191` because `feynman extensions` remains broader than the update/help failure requires and its Vercel status remains failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: Remote refs were refreshed. No new safe port target was found beyond `#189`, already included in `#192`; visible fork refs remain stale, broader provider/platform/admin work, docs/export material, or already-covered installer/runtime/auth work. +- Freshness: Root and website `npm outdated --json` show non-security drift only. No dependency change was made. +- Verified: Focused alpha/runtime tests passed (`20/20`); `npm test` passed (`594/594`); root `npm run typecheck`; root `npm run build` with existing Vite/RDKit/3Dmol/chunk warnings; `npm run architecture:check` with existing split-debt warnings; root and website `npm audit --omit=dev` (`0 vulnerabilities`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `f0b50e989c04095e9a4b3b65628bcf6def9921aa`); installed-tarball smoke proved package `0.3.6`, CLI help, `feynman alpha --help`, hoisted alpha resolver presence, and installed alpha-hub auth issuer `https://api.alphaxiv.org/auth`. +- Note: Early focused and pack probes failed only from invocation/parser assumptions: raw `node --test` on TS files without `tsx`, then mixed `npm pack --json` output containing prepack `[feynman]` logs. Corrected commands passed. +- Next: Commit the hoisted alpha CLI resolver and merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-13 03:37 PDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve existing dirty local work, refresh GitHub/package/release/branch state, classify open issues/PRs/contributor refs, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; `origin/main` remains `54d08a3`. Open issues remain `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest/current remains `0.80.6`; `@companion-ai/alpha-hub` latest/current remains `0.1.3`. +- Decisions: No new code changes. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it includes contributor PR `#189` as cherry-pick `79aa7b2`, has green Vercel status, and the latest PR comment still reports the alpha auth patch worked for another user. Reject/defer PR `#191` because `feynman extensions` is broader than the update/help failure requires and its Vercel status is still failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: Remote refs and recent public forks were refreshed/spot-checked. No new safe port target was found beyond `#189`, already included in `#192`; recent visible forks were either at `54d08a3`, behind, broader provider/platform work, docs/export material, or already-covered Windows/install/auth work. +- Freshness: `npm outdated --json` shows non-security drift only in root and website packages. No dependency change was made. +- Verified: Focused runtime/auth/web/install regressions passed (`51/51`); `npm test` passed (`594/594`); root `npm run typecheck`; root `npm run build` with existing Vite/RDKit/3Dmol/chunk warnings; `npm run architecture:check` with existing split-debt warnings; root and website `npm audit --omit=dev` (`0 vulnerabilities`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `f0b50e989c04095e9a4b3b65628bcf6def9921aa`); corrected installed-tarball smoke proved package/CLI `0.3.6`, CLI help, package listing, `alpha status`, bundled `alt+enter`, runtime archive, alphaXiv OAuth2 patch, project-local fetch cache patch, and archive entries for `pi-btw`, `pi-web-access`, and `@earendil-works/pi-coding-agent`. +- Note: Early smoke wrappers failed only from probe assumptions: mixed `npm pack --json` parsing, stale alpha-hub archive path, and stale pi-web-access source path. The corrected smoke used actual archive paths and passed; temp artifacts were cleaned. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-12 06:15 EDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve unrelated local work, refresh GitHub/package/release/branch state, classify open issues/PRs/contributor refs, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; `origin/main` remains `54d08a3`. Open issues remain `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest/current remains `0.80.6`; `@companion-ai/alpha-hub` latest/current remains `0.1.3`. +- Decisions: No new code changes. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it includes contributor PR `#189` as cherry-pick `79aa7b2`, has green Vercel status, and the latest PR comment still reports the alpha auth patch worked for another user. Reject/defer PR `#191` because `feynman extensions` is broader than the update/help failure requires and its Vercel status is still failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: Remote refs were refreshed. No new safe port target was found beyond `#189`, already included in `#192`; older visible refs remain stale, broader provider/platform work, docs/export material, or already-covered Windows/install/auth work. +- Freshness: `npm outdated --json` shows non-security drift only in root and website packages. No dependency change was made. +- Verified: `npm run architecture:check` with existing split-debt warnings; `npm test` passed (`593/593`); root `npm run typecheck`; root `npm run build` with existing Vite/RDKit/3Dmol/chunk warnings; root and website `npm audit --omit=dev` (`0 vulnerabilities`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); corrected installed-tarball smoke proved package `0.3.6`, CLI `--version`, CLI `--help` exit, `packages list`, `alpha status`, runtime archive entries for `pi-btw` and `pi-web-access`, and the alphaXiv OAuth2 patch in the runtime archive. +- Note: One early smoke wrapper failed only from a mixed `npm pack --json` parser grabbing an inner `files` array. The corrected parser and smoke passed; temp installs and tarballs were cleaned. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-12 02:15 EDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve unrelated local work, refresh GitHub/package/release/branch state, classify open issues/PRs/contributor refs, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; `origin/main` remains `54d08a3`. Open issues remain `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest/current remains `0.80.6`; `@companion-ai/alpha-hub` latest/current remains `0.1.3`. +- Decisions: No new code changes. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it includes contributor PR `#189` as cherry-pick `79aa7b2`, has green Vercel status, and the latest PR comment still reports the alpha auth patch worked for another user. Reject/defer PR `#191` because `feynman extensions` is broader than the update/help failure requires and its Vercel status is still failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: Remote refs were refreshed. No new safe port target was found beyond `#189`, already included in `#192`; older visible refs remain stale, broader provider/platform work, docs/export material, or already-covered Windows/install/auth work. +- Freshness: `npm outdated --json` shows non-security drift only in root and website packages. No dependency change was made. +- Verified: `npm test` passed (`593/593`); root `npm run typecheck`; root `npm run build` with existing Vite/RDKit/3Dmol/chunk warnings; root and website `npm audit --omit=dev` (`0 vulnerabilities`); `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); corrected installed-tarball smoke proved package `0.3.6`, CLI `--version`, `packages list`, `alpha status`, bundled `alt+enter`, runtime archive entries for `pi-btw` and `pi-web-access`, and the alphaXiv OAuth2 patch in the runtime archive. +- Note: Two early smoke wrappers failed only from probe assumptions: first parsing the `[feynman]` prepack log prefix as JSON, then sampling archive paths under `pipefail`/a stale alpha-hub path. The corrected checks passed and temp artifacts were cleaned. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-11 22:11 EDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve unrelated local work, refresh GitHub/package/release/branch state, classify open issues/PRs/contributor refs, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; `origin/main` remains `54d08a3`. Open issues remain `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest/current remains `0.80.6`; `@companion-ai/alpha-hub` latest/current remains `0.1.3`. +- Decisions: No new code changes. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it includes contributor PR `#189` as cherry-pick `79aa7b2`, and the latest PR comment still reports the alpha auth patch worked for another user. Reject/defer PR `#191` because `feynman extensions` is broader than the update/help failure requires and its Vercel status is still failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: Remote refs were refreshed. No new safe port target was found beyond `#189`, already included in `#192`; older visible refs remain stale, broader provider/platform work, docs/export material, or already-covered Windows/install/auth work. +- Freshness: `npm outdated --json` shows non-security drift only in root and website packages. No dependency change was made. +- Verified: `npm test` passed (`593/593`); root `npm run typecheck`; root and website `npm audit --omit=dev` (`0 vulnerabilities`); root `npm run build` with existing Vite/RDKit/3Dmol/chunk warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); `npm run architecture:check` with existing split-debt warnings; `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); corrected installed-tarball smoke proved package `0.3.6`, CLI `--version`, `--help`, `packages list`, `alpha status`, bundled `alt+enter`, runtime archive, and archive entries for `pi-btw`, `pi-web-access`, and `@earendil-works/pi-coding-agent`. +- Note: One installed-smoke wrapper failed from a bad mixed-log JSON parser; the corrected strict smoke passed and temp artifacts were cleaned. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-11 18:09 EDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve unrelated local work, refresh GitHub/package/release/branch state, classify open issues/PRs/contributor refs, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; `origin/main` remains `54d08a3`. Open issues remain `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest/current remains `0.80.6`; alpha-hub latest/current remains `0.1.3`. +- Decisions: No new code changes. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it includes contributor PR `#189` as cherry-pick `79aa7b2`, and the latest PR comment reports the alpha auth patch worked for another user. Reject/defer PR `#191` because `feynman extensions` is broader than the update/help failure requires and its Vercel status is still failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: Remote refs were refreshed. No new safe port target was found beyond `#189`, already included in `#192`; older visible refs remain stale, broader provider/platform work, docs/export material, or already-covered Windows/install/auth work. +- Freshness: `npm outdated --json` shows non-security drift only in root and website packages. No dependency change was made. +- Verified: `npm test` passed (`593/593`); root `npm run typecheck`; website `npm run lint` and `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `npm run architecture:check` with existing split-debt warnings; root `npm run build` with existing Vite/RDKit/3Dmol/chunk warnings; website `npm run build` (`34` pages); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); strict installed-tarball smoke proved package `0.3.6`, CLI `--version`, `--help`, `packages list`, `alpha status`, bundled `alt+enter`, runtime archive, and archive entries for `pi-btw`, `pi-web-access`, and `@earendil-works/pi-coding-agent`. +- Note: One installed-smoke wrapper failed from a bad mixed-log JSON parser and missing `set -e`; the corrected strict smoke passed and temp artifacts were cleaned. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-11 09:16 EDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve the existing dirty `CHANGELOG.md`, refresh GitHub/package/release/branch state, classify open issues/PRs/contributor refs, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; `origin/main` remains `54d08a3`. Open issues remain `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest/current remains `0.80.6`; alpha-hub latest/current remains `0.1.3`. +- Decisions: No new code changes. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it includes contributor PR `#189` as cherry-pick `79aa7b2`. Reject/defer PR `#191` because `feynman extensions` is broader than the update/help failure requires and its Vercel status is failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: `origin/fix/deepresearch-local-model-warning`, `pr4fork/main`, and fork refs were checked. No new safe port target was found: visible refs were either already represented in `#192`, broader platform/provider/admin work, docs-only walkthrough/export material, fork-specific changes, or stale Windows/install work already covered by the current branch. +- Freshness: `npm outdated --long` shows non-security drift only (`@clack/prompts`, OpenTelemetry packages, TypeBox, Node types, fast-xml-parser, lucide-react, patristic, posthog-node, radix-ui, tsx, TypeScript, undici, vite). No dependency change was made. +- Verified: `npm test` passed (`593/593`); `npm run typecheck`; `npm run architecture:check` with existing split-debt warnings; root `npm run build` with existing Vite/RDKit/3Dmol warnings; root and website `npm audit --omit=dev` (`0 vulnerabilities`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); installed-tarball smoke proved package `0.3.6`, CLI `--version`, `--help`, `packages list`, `alpha status`, bundled `alt+enter`, and runtime archive entries for `pi-btw`, `pi-web-access`, and `@earendil-works/pi-coding-agent`. +- Note: Two initial smoke wrappers failed only from probe assumptions: first reading hoisted dependencies under the package-local `node_modules`, then resolving non-exported dependency `package.json` files. The final smoke used CLI/archive checks and passed; generated temp installs and tarballs were removed. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-11 05:15 EDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve the existing dirty `CHANGELOG.md`, refresh live GitHub/package/release/branch state, classify open issues/PRs, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; `origin/main` remains `54d08a3`. Live queue remains issues `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, `#182` and PRs `#192`, `#191`, `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local candidate remains `0.3.6`; Pi remains latest/current at `0.80.6`; alpha-hub remains latest/current at `0.1.3`. +- Decisions: No new code changes. Keep draft PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it already includes contributor PR `#189` as cherry-pick `79aa7b2` with original authorship. Reject/defer PR `#191` because a new `feynman extensions` inventory command is broader than the `update --extensions` help/update failure requires and its Vercel check is failing. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: `origin/fix/deepresearch-local-model-warning`, `pr4fork/main`, and older fork refs were checked as remote branch state; none introduced a current safe port target beyond `#189`, already included in `#192`. +- Freshness: `npm outdated --long` shows non-security drift only (`@clack/prompts`, OpenTelemetry packages, TypeBox, Node types, fast-xml-parser, lucide-react, patristic, posthog-node, radix-ui, tsx, TypeScript, undici, vite). No dependency change was made. +- Verified: `npm test` passed (`593/593`); `npm run typecheck`; `npm run architecture:check` with existing split-debt warnings; root `npm run build` with existing Vite/RDKit/3Dmol warnings; root and website `npm audit --omit=dev` (`0 vulnerabilities`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); corrected installed-tarball smoke proved `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, package `0.3.6`, Pi `0.80.6`, alpha-hub `^0.1.3`, bundled `alt+enter`, and runtime archive entries for `pi-btw`, `pi-web-access`, and `@earendil-works/pi-coding-agent`. +- Note: An initial installed-smoke wrapper hit the known mixed `npm pack --json` log parser issue; it was rerun with a stricter extractor and passed. Generated temp installs and tarballs were removed. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-11 01:29 EDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve existing local work, refresh live GitHub/package/release/branch state, classify every open issue/PR, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; pre-existing dirty state was `CHANGELOG.md` only. Live queue remains issues `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, `#182` and PRs `#192`, `#191`, `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local candidate remains `0.3.6`; Pi remains latest/current at `0.80.6`; alpha-hub remains latest/current at `0.1.3`. +- Decisions: No new code changes. Keep PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it already includes contributor PR `#189` as cherry-pick `79aa7b2`. Reject/defer PR `#191` because `feynman extensions` is broader extension-inventory surface than the reported update/help failure needs and has a failing Vercel status. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: `origin/fix/deepresearch-local-model-warning`, `pr4fork/main`, and older fork refs were observed; none introduced a current safe port target beyond `#189`, already included in `#192`. +- Verified: `npm test` passed (`593/593`); `npm run typecheck`; `npm run architecture:check` with existing split-debt warnings; root `npm run build` with existing Vite/RDKit/3Dmol warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); installed tarball smoke proved `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, package `0.3.6`, Pi `0.80.6`, alpha-hub `0.1.3`, bundled `alt+enter`, staged Windows installer extraction, fetch cache patch, and alphaXiv OAuth2 patch. Direct archive listing proved bundled `pi-btw` and `pi-web-access`. +- Note: Earlier smoke wrappers failed only from parser/probe mistakes: mixed `npm pack --json` logs, package export restrictions on direct `package.json` requires, and a stale runtime archive prefix. Corrected checks passed and temp artifacts were removed. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-10 21:13 EDT — intake-sweep-pr-192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve existing local work, refresh live GitHub/package/release state, classify every open issue/PR, and run repo-local validation without GitHub writes. +- Checked: Current branch is `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; pre-existing dirty state was `CHANGELOG.md` only. Live queue remains issues `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, `#182` and PRs `#192`, `#191`, `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local candidate remains `0.3.6`; Pi remains latest/current at `0.80.6`; alpha-hub remains latest/current at `0.1.3`. +- Decisions: No new code changes. Keep PR `#192` as the merge path for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`; it already includes contributor PR `#189` as cherry-pick `79aa7b2`. Reject/defer PR `#191` because `feynman extensions` is broader extension-inventory surface than the reported update/help failure needs. Issue `#184` remains outside Feynman's AI-researcher product bar. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` and `pr4fork/main` were the only non-main refs observed; neither introduced a current safe port target for this queue. +- Verified: `npm test` passed (`593/593`); `npm run typecheck`; `npm run architecture:check` with existing split-debt warnings; root `npm run build` with existing Vite/RDKit/3Dmol warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); installed tarball smoke proved `feynman --version`, `feynman --help`, `feynman packages list`, package `0.3.6`, Pi `0.80.6`, bundled `alt+enter`, staged Windows installer extraction, fetch cache patch, alphaXiv OAuth2 patch, runtime archive, and bundled `pi-btw`/`pi-web-access` archive entries. +- Note: The smoke command exited `141` only after successful checks because `tar | grep | head` hit SIGPIPE under `pipefail`; temp install and tarball artifacts were removed. +- Next: Review/merge/publish PR `#192` when authorized; keep PR `#191` out unless product scope explicitly expands to extension inventory. + +### 2026-07-10 17:12 EDT — intake-sweep-pr-192-validated + +- Objective: Re-run `check-new-issues` from the current `codex/fix-feynman-user-issues` checkout, preserve local branch state, and classify the now-open issues/PRs without GitHub writes. +- Checked: Current branch tracks `origin/codex/fix-feynman-user-issues` at `8ad8d55` with no dirty files. Open issues are `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`. Open PRs are `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest remains `0.3.5`; local candidate is `0.3.6`; Pi latest/current is `0.80.6`; alpha-hub latest/current is `0.1.3`. +- Decisions: PR `#192` is the preferred merge path after review because it bundles the smallest research-loop reliability fixes for `#182`, `#185`, `#186`, `#187`, `#188`, and `#190`, includes contributor PR `#189` as a cherry-pick, and leaves `#191` out. PR `#189` should be ported via `#192` rather than merged separately. PR `#191` should be rejected/deferred because a new `feynman extensions` management/discovery surface is broader than the issue requires; update guidance is enough for `#187`. Issue `#184` remains outside the AI-researcher product bar as support/advice. +- Contributor refs: Existing fork refs remain stale or broad provider/admin/platform churn. No additional contributor branch was ported beyond `#189`, which is already included in local PR `#192` as commit `79aa7b2`. +- Freshness: `npm outdated --long` shows non-security dependency drift only (`@clack/prompts`, OpenTelemetry packages, TypeBox, Node types, fast-xml-parser, lucide-react, patristic, posthog-node, radix-ui, tsx, TypeScript, undici, vite). No queue-specific freshness patch was needed. +- Verified: Focused regressions passed (`88/88`); full `npm test` passed (`593/593`), including the two workbench tests that failed in the prior run; `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `167a902ecc8b2ea71e6b3402052f3a45c7ab2b11`); installed tarball smoke passed for `feynman --version`, `feynman --help`, `feynman packages list`, package `0.3.6`, Pi `0.80.6`, bundled `alt+enter` keybinding, staged Windows installer extraction, runtime archive presence, fetch cache patch, and alphaXiv OAuth2 patch. +- Note: A first installed-smoke helper failed only because it parsed mixed `npm pack --json` logs and then used overly literal probe strings. The corrected smoke passed and temp tarball artifacts were removed. +- Next: Review and merge/publish PR `#192` when authorized; leave `#191` out unless the product scope explicitly expands to extension inventory. + +### 2026-07-10 13:14 EDT — intake-sweep-current-queue-flaky-workbench + +- Objective: Re-run `check-new-issues` against the current dirty checkout, preserve pending Pi `0.80.6`, alpha OAuth, and Windows installer work, and verify whether the live queue or local validation requires another local fix. +- Checked: Local `main` remains aligned with `origin/main` at `54d08a3`. Live GitHub queue still has open issues `#186`, `#185`, `#184`, and `#182`, with zero open PRs. Latest `main` `Publish and Release` run `28835967900` is green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; `@earendil-works/pi-coding-agent` latest/current is `0.80.6`; `@companion-ai/alpha-hub` latest/current is `0.1.3`. +- Decisions: No new code changes were needed. Issue `#186` remains covered by the pending staged Windows installer extraction fix; issue `#185` remains covered by bundled `pi-btw`; issue `#184` remains outside the AI-researcher product bar as support/advice; issue `#182` remains covered by the pending alphaXiv OAuth2 endpoint patch. No PRs were available to merge, port, reject, or defer. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` is behind current `main` with one already-covered ahead commit. Sampled fork refs were behind by 91-142 commits with Bedrock/provider setup, Overleaf/export/admin prompts, Claude CLI bypass, architecture notes, fork-specific search tooling, or broad Windows/platform churn; no clean core-research patch was ported. +- Freshness: Root `npm outdated --json` shows non-security dependency drift only, with Pi already current at `0.80.6`. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Root `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `78cbe7bc2a43ce7aec95c42c10077b4754a9afe1`); installed tarball smoke reached `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, packaged `scripts/install/install.ps1` staged-extraction checks, and runtime archive inspection showing `api.alphaxiv.org/auth`, `oauth2/authorize`, and `openid profile email offline_access`. +- Validation note: The full `npm test` run failed `2/589` in `tests/workbench.test.ts` (`notebook Python session kernel persists variables across cells` saw one execution record instead of two; `workbench server streams chat messages through the authenticated API` saw missing final message status). The same two tests passed when rerun in isolation with `node --import tsx --test --test-concurrency=1 --test-name-pattern='notebook Python session kernel persists variables across cells|workbench server streams chat messages through the authenticated API' tests/workbench.test.ts`, so this remains a repo-local full-suite flake/failure to investigate. +- Note: The first real-pack smoke parser failed on mixed `npm pack --json` logs, and the corrected smoke later failed only because it expected `website/public/install.ps1` inside the npm package. The shipped package includes `scripts/install/install.ps1`, which was verified; temp smoke artifacts and the root tarball were removed. +- Next: Investigate the two full-suite workbench flakes before claiming a fully green local validation ladder; commit or push only when explicitly authorized. + +### 2026-07-10 09:09 EDT — intake-sweep-windows-installer-staging + +- Objective: Re-run `check-new-issues` against the current dirty checkout, preserve the pending Pi `0.80.6` and alpha OAuth work, and evaluate the new Windows installer issue. +- Checked: Local `main` remains aligned with `origin/main` at `54d08a3`. Live GitHub queue has open issues `#186`, `#185`, `#184`, and `#182`, with zero open PRs. Latest `main` `Publish and Release` run `28835967900` is green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; `@companion-ai/alpha-hub` latest/current remains `0.1.3`; `@earendil-works/pi-*` remains `0.80.6`; root and website have non-security dependency drift only. +- Decisions: Ported the smallest safe fix for issue `#186` because install reliability supports Feynman's research-loop reliability. The Windows installer now extracts the release zip into temp staging, validates the expected bundle directory, then swaps that bundle into `%LOCALAPPDATA%\Programs\feynman`, avoiding `Expand-Archive -Force` cleanup against the live install root. Issue `#185` remains covered by bundled `pi-btw`; issue `#184` remains outside the AI-researcher product bar; issue `#182` remains covered by the pending alphaXiv OAuth2 endpoint patch. No PRs to merge, port, reject, or defer. +- Contributor refs: Configured refs remain stale or non-actionable. `origin/fix/deepresearch-local-model-warning` is behind current `main` with one already-covered ahead commit; `pr4fork/main` is behind with zero ahead. Sampled fork refs remain older provider/setup/platform/admin or broad fork work rather than a fresh core research-loop fix. +- Changed: Updated `scripts/install/install.ps1`, synced `website/public/install.ps1`, and added `tests/install-windows.test.ts`. Existing dirty changes in `package.json`, `package-lock.json`, `scripts/lib/alpha-hub-auth-patch.mjs`, `scripts/prepare-runtime-workspace.mjs`, `src/pi/package-ops.ts`, and `tests/alpha-hub-auth-patch.test.ts` were preserved. +- Verified: Focused installer tests passed (`6/6`); full `npm test` passed (`588/588`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `53c8090ca3fb238122d5f0942b0fee5c99b692b0`); real installed tarball smoke passed for `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, and packaged `install.ps1` staged-extraction checks. No local PowerShell runtime was available for a live Windows script execution. +- Next: Commit or push only when explicitly authorized; otherwise keep the Windows installer staging fix, Pi `0.80.6` refresh, and alpha OAuth patch local-only. + +### 2026-07-09 21:15 EDT — intake-sweep-pi-0806-refresh + +- Objective: Re-run the `check-new-issues` intake sweep against the current dirty checkout, preserve unrelated local work, and port only safe core-research/runtime fixes. +- Checked: Local `main` remains aligned with `origin/main` at `54d08a3`. Live GitHub queue still has open issues `#185`, `#184`, and `#182`, with zero open PRs. Latest `main` `Publish and Release` run `28835967900` is green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; `@companion-ai/alpha-hub` latest/current remains `0.1.3`; `pi-btw` latest/current remains `0.4.1`; `@earendil-works/pi-*` latest is now `0.80.6`. +- Decisions: Ported the smallest safe runtime freshness fix by bumping Feynman's pinned Pi runtime packages from the pending `0.80.5` refresh to `0.80.6`. The upstream package diff directly affects the research loop: post-compaction output-token budgeting, GPT-5.6/GPT-5.5 long-context cost accounting, OpenAI cache-write usage accounting, GPT-5.6 Codex metadata, `max` thinking-level support, Claude thinking-block preservation, and `shellPath` home expansion. Issue `#182` remains locally covered by the pending alphaXiv OAuth2 endpoint patch; issue `#185` remains covered by bundled `pi-btw`; issue `#184` remains outside Feynman's AI-researcher product bar as support/advice. No PRs to merge, port, reject, or defer. +- Contributor refs: Configured refs remain stale or non-actionable. `origin/fix/deepresearch-local-model-warning` is behind current `main` with one already-covered ahead commit; `pr4fork/main` is behind with zero ahead. Sampled fork refs are still behind current `main` with small ahead diffs in old provider/setup/platform/fork-specific lanes rather than fresh core research-loop fixes. +- Changed: Updated `package.json` and `package-lock.json` to `@earendil-works/pi-agent-core`, `pi-ai`, `pi-coding-agent`, and `pi-tui` `0.80.6`; updated Pi runtime fallback constants in `src/pi/package-ops.ts` and `scripts/prepare-runtime-workspace.mjs`. +- Freshness: Root `npm outdated --long --json` now shows non-Pi dependency drift only; website drift remains non-security dependency drift. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused package/runtime/alpha tests passed (`27/27`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `35c88e81b93f395c695cab93e46bbde1f6f27bd6`); real tarball smoke passed for `feynman --version`, current help, `feynman packages list` showing `npm:pi-btw`, `feynman alpha status`, installed Pi `0.80.6`, runtime archive Pi `0.80.6`, runtime `pi-btw` `0.4.1`, and alpha OAuth2 runtime archive inspection. +- Note: The real-pack metadata parser again hit mixed prepack logs/JSON after the tarball was created; the produced tarball was used directly. A first installed-smoke assertion looked for Pi under a nested dependency path and failed after npm hoisted Pi to top-level; the corrected direct package metadata check passed. Temp smoke artifacts and the root tarball were removed. +- Next: Commit or push only when explicitly authorized; otherwise keep the local Pi `0.80.6` refresh plus existing alpha OAuth patch local-only. + +### 2026-07-08 21:03 EDT — intake-sweep-no-new-action + +- Objective: Re-run the `check-new-issues` intake sweep against the current Feynman checkout, preserving the pending alpha-auth patch while checking live GitHub issues/PRs, contributor refs, main workflows, release/package state, freshness, and local validation. +- Checked: Local `main` and `origin/main` both resolve to `54d08a3` after fetch. Open issues remain `#185`, `#184`, and `#182`; open PR list is empty. Latest `main` `Publish and Release` run remains `28835967900`, succeeded at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest remains `0.3.5`; Pi latest/current remains `0.80.3`; alpha-hub latest/current remains `0.1.3`; `pi-btw` latest/current remains `0.4.1`. +- Decisions: No new queue-driven code changes were needed. `#182` remains locally actionable but already covered by the pending local alpha-hub auth compatibility patch that rewrites bundled auth to `https://api.alphaxiv.org/auth/oauth2/*` with `openid profile email offline_access`. `#185` remains covered by bundled `pi-btw`, which directly improves long-running research-loop steering. `#184` remains outside Feynman's AI-researcher product bar as support/advice rather than a repo feature. There were no PRs to merge, port, reject, or defer. +- Contributor state: Configured contributor refs are stale, behind, or non-actionable. `origin/fix/deepresearch-local-model-warning` is behind by 74 commits with one ahead local-model-warning commit; `pr4fork/main` is behind by 73 with zero ahead. Sampled fork refs were behind by 91-142 commits with small ahead diffs focused on provider setup, Overleaf/export/admin prompts, Claude CLI bypass, architecture notes, fork-specific search tooling, broad platform churn, or runtime/setup churn; none was a clean core-research patch to port in this run. +- Freshness: Root and website have dependency drift only. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused alpha/runtime tests passed (`16/16`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); real installed tarball smoke passed for `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, alpha OAuth2 runtime archive inspection, and bundled `pi-btw` archive files. The first installed-smoke wrapper failed before install because it parsed `[feynman]` prepack logs as JSON; the corrected parser succeeded, and temp smoke artifacts were removed. +- Next: Commit or push only if explicitly authorized; otherwise keep the local alpha auth compatibility patch pending review. + +### 2026-07-08 16:58 EDT — intake-sweep-no-new-action + +- Objective: Re-run the `check-new-issues` intake sweep against the current Feynman checkout, preserving existing local alpha-auth patch work while checking live GitHub issues/PRs, contributor branches, main workflows, release/package state, freshness, and validation. +- Checked: Local `main` and `origin/main` both resolve to `54d08a3`. Open issues are `#185`, `#184`, and `#182`; open PR list is empty. Latest `main` `Publish and Release` run remains `28835967900`, succeeded at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest remains `0.3.5`; Pi latest/current remains `0.80.3`; alpha-hub latest/current remains `0.1.3`; `pi-btw` latest/current remains `0.4.1`. +- Decisions: No new queue-driven code changes were needed. `#182` remains locally actionable but already covered by the pending local alpha-hub auth compatibility patch. `#185` remains covered by bundled `pi-btw`, which directly improves long-running research-loop steering. `#184` remains outside Feynman's AI-researcher product bar as support/advice rather than a repo feature. There were no PRs to merge, port, reject, or defer. +- Contributor state: Configured contributor refs are stale, behind, or non-actionable. `origin/fix/deepresearch-local-model-warning` is behind by 74 commits with one local-model-warning commit ahead; `pr4fork/main` is behind by 73 with zero ahead. Sampled fork refs were behind by 91-142 commits with small ahead diffs focused on Overleaf/export/admin prompts, broad platform churn, provider setup, Claude CLI bypass, architecture notes, or fork-specific search tooling; none was a clean core-research patch to port in this run. +- Freshness: Root and website have dependency drift only. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused alpha/runtime tests passed (`16/16`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); real installed tarball smoke from `/tmp/feynman-pack-smoke-lcIijJ/` passed for `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, alpha OAuth2 runtime archive inspection, and bundled `pi-btw` archive files. The temp smoke directory and root tarball were removed. +- Next: Commit or push only if explicitly authorized; otherwise keep the local alpha auth compatibility patch pending review. + +### 2026-07-08 12:56 EDT — intake-sweep-no-new-action + +- Objective: Re-run the `check-new-issues` intake sweep against the current Feynman checkout, preserving existing local work while checking live GitHub issues/PRs, contributor branches/forks, main workflows, release/package state, freshness, and local validation. +- Checked: Local `main` is aligned with `origin/main` at `54d08a3` after fetch. Open issues remain `#185`, `#184`, and `#182`; open PR list is empty. Issue `#182`'s newest comment still matches the already-pending alphaXiv OAuth2 endpoint/scope patch. Latest `main` `Publish and Release` run is `28835967900`, succeeded at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; Pi latest/current remains `0.80.3`; alpha-hub latest/current remains `0.1.3`; `pi-btw` latest/current remains `0.4.1`. +- Decisions: No new queue-driven code changes were needed. `#182` remains the only locally actionable issue and is already covered by the pending local alpha-hub auth compatibility patch that rewrites bundled auth to `https://api.alphaxiv.org/auth/oauth2/*` with `openid profile email offline_access`. `#185` remains covered by bundled `pi-btw`, which directly improves long-running research-loop steering. `#184` remains outside Feynman's AI-researcher product bar as support/advice rather than a repo feature. There were no PRs to merge, port, reject, or defer. +- Contributor/fork state: Configured contributor refs are behind, stale, or old already-reviewed changes. `origin/fix/deepresearch-local-model-warning` is behind by 74 commits with one ahead local-model warning commit; `pr4fork/main` is behind by 73 commits with zero ahead commits. Recent public fork heads checked: `QuantumKuba/feynman`, `ivnvalex/feynman`, and `colindomoney/feynman` match `54d08a3`; `ussdeveloper/feynman` is behind at `fa26693`; `advaitpaliwal/feynman` is behind at `cb5fa56`. +- Freshness: Root and website have dependency drift only. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused alpha/runtime tests passed (`16/16`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); real installed tarball smoke from `/tmp/feynman-pack-smoke-OqsQM0/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, and runtime archive inspection for `api.alphaxiv.org/auth`, `oauth2/authorize`, `oauth2/token`, `oauth2/register`, `oauth2/userinfo`, `openid profile email offline_access`, and bundled `pi-btw`. +- Next: Commit or push only if explicitly authorized; otherwise keep the local alpha auth compatibility patch pending review. + +### 2026-07-08 08:54 EDT — intake-sweep-no-new-action + +- Objective: Re-run the `check-new-issues` intake sweep against the current Feynman checkout, preserving existing local work while checking live GitHub issues/PRs, contributor refs/forks, workflows, release/package state, freshness, and local validation. +- Checked: Local `main` is aligned with `origin/main` at `54d08a3` after fetch. Open issues remain `#185`, `#184`, and `#182`; open PR list is empty. Issue `#182` has a new comment suggesting the same alphaXiv OAuth2 endpoint/scope rewrite already present in the pending local patch. Latest `main` `Publish and Release` run is `28835967900`, succeeded at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; Pi latest/current remains `0.80.3`; alpha-hub latest/current remains `0.1.3`; `pi-btw` latest/current remains `0.4.1`. +- Decisions: No new queue-driven code changes were needed. `#182` remains the only locally actionable issue and is already covered by the pending local alpha-hub auth compatibility patch that rewrites bundled auth to `https://api.alphaxiv.org/auth/oauth2/*` with `openid profile email offline_access`. `#185` remains covered by bundled `pi-btw`, which directly improves long-running research-loop steering. `#184` remains outside Feynman's AI-researcher product bar as support/advice rather than a repo feature. There were no PRs to merge, port, reject, or defer. +- Contributor/fork state: Configured contributor refs are behind, stale, or old already-reviewed changes. `origin/fix/deepresearch-local-model-warning` is behind by 74 commits with one ahead local-model warning commit; `pr4fork/main` is behind by 73 commits with zero ahead commits. Recent public fork discovery showed `colindomoney/feynman` identical to `main`; `ussdeveloper/feynman` and `advaitpaliwal/feynman` are behind with zero ahead commits. +- Freshness: Root and website have dependency drift only. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused alpha/runtime tests passed (`16/16`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); real installed tarball smoke from `/tmp/feynman-pack-smoke-x31nAy/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, and runtime archive inspection for `api.alphaxiv.org/auth`, `oauth2/authorize`, `oauth2/token`, `oauth2/register`, `oauth2/userinfo`, `openid profile email offline_access`, and bundled `pi-btw`. +- Note: The first installed-smoke wrapper exited nonzero after successful CLI checks because it looked for `package/npm/...` inside the nested runtime archive; the correct nested path is `npm/node_modules/...`, and the follow-up archive inspection passed. The temp smoke directory was removed. +- Next: Commit or push only if explicitly authorized; otherwise keep the local alpha auth compatibility patch pending review. + +### 2026-07-08 04:53 EDT — intake-sweep-no-new-action + +- Objective: Re-run the `check-new-issues` intake sweep against the current Feynman checkout, preserving existing local work while checking live GitHub issues/PRs, contributor refs/forks, workflows, release/package state, freshness, and local validation. +- Checked: Local `main` is aligned with `origin/main` at `54d08a3` after fetch. Open issues remain `#185`, `#184`, and `#182`; open PR list is empty. Latest `main` `Publish and Release` run is `28835967900`, succeeded at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; Pi latest/current remains `0.80.3`; alpha-hub latest/current remains `0.1.3`; `pi-btw` latest/current remains `0.4.1` with Pi peer range `>=0.74.0 <1`. +- Decisions: No new queue-driven code changes were needed. `#182` remains the only locally actionable issue and is already covered by the pending local alpha-hub auth compatibility patch that rewrites bundled auth to `https://api.alphaxiv.org/auth/oauth2/*` with `openid profile email offline_access`. `#185` remains covered by bundled `pi-btw`, which directly improves long-running research-loop steering. `#184` remains outside Feynman's AI-researcher product bar as support/advice rather than a repo feature. There were no PRs to merge, port, reject, or defer. +- Contributor/fork state: Configured contributor refs are behind, stale, or broad fork-specific churn. `pr4fork/main` is behind by 73 commits with zero ahead commits; `origin/fix/deepresearch-local-model-warning` is behind by 74 commits with one already-considered ahead commit. Public fork discovery showed only `advaitpaliwal/feynman` as recently pushed, still behind current `origin/main` at `cb5fa56`. +- Freshness: Root and website have dependency drift only. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused alpha/runtime tests passed (`16/16`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); real installed tarball smoke from `/tmp/feynman-pack-smoke-nGtsGm/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, and runtime archive inspection for `api.alphaxiv.org/auth`, `oauth2/authorize`, `openid profile email offline_access`, and bundled `pi-btw`. +- Next: Commit or push only if explicitly authorized; otherwise keep the local alpha auth compatibility patch pending review. + +### 2026-07-08 00:52 EDT — intake-sweep-alpha-auth-patch-validated + +- Objective: Re-run the `check-new-issues` intake sweep against the current Feynman checkout, preserve existing local work, and verify whether fresh GitHub, release, package, contributor, or validation state requires another change. +- Checked: Live GitHub queue still has open issues `#185`, `#184`, and `#182`, with zero open PRs. Latest `main` publish run is `Publish and Release` `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; Pi latest/current is `0.80.3`; alpha-hub latest/current is `0.1.3`; `pi-btw` latest/current is `0.4.1` with Pi peer range `>=0.74.0 <1`. The newest public forks checked, `founderqiang/feynman` and `colindomoney/feynman`, are identical to `main`; `ussdeveloper/feynman`, `Sourabhsubhasish/feynman`, and `advaitpaliwal/feynman` are behind with zero ahead commits. Configured contributor remotes remain stale or behind. +- Decisions: No new code changes were needed beyond the existing local `#182` alpha auth compatibility patch. Issue `#182` remains the only locally actionable queue item because its newest comment points at alphaXiv's migrated OAuth endpoints and the local package patch already rewrites bundled alpha-hub auth to `https://api.alphaxiv.org/auth/oauth2/*` with `openid profile email offline_access`. Issue `#185` remains covered by bundled `pi-btw`, which directly improves long-running research-loop steering. Issue `#184` remains outside Feynman's AI-researcher product bar as support/advice, not a repo feature. No PRs to merge, port, reject, or defer. +- Freshness: Root and website have dependency drift only. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); real tarball smoke from `/tmp/feynman-pack-smoke-8S4oAQ/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list`, `feynman alpha status`, and runtime archive inspection for `api.alphaxiv.org/auth`, `oauth2/authorize`, `openid profile email offline_access`, and bundled `pi-btw`. +- Next: Commit or push only when explicitly authorized; otherwise keep the local alpha auth compatibility patch pending review. + +### 2026-07-07 21:07 EDT — check-new-issues-alpha-auth-endpoint + +- Objective: Run the recurring Feynman intake sweep against live GitHub issues, PRs, contributor branches/forks, recent main workflows, release/npm state, package freshness, and local validation while preserving unrelated worktree changes. +- Checked: Live open issues stayed `#185`, `#184`, and `#182`; open PR list was empty; local `main` is aligned with `origin/main` at `54d08a3`; latest `main` `Publish and Release` run `28835967900` succeeded at `54d08a3`; latest GitHub release and npm package remain `v0.3.5` / `@companion-ai/feynman@0.3.5`; runtime/package versions remain `@earendil-works/pi-coding-agent@0.80.3`, `@companion-ai/alpha-hub@0.1.3`, and `pi-btw@0.4.1`. New public fork `colindomoney/feynman` is identical to `main`; recent forks `ussdeveloper`, `advaitpaliwal`, `skandanyal`, and `gaurav-g-alva` are behind with zero ahead commits; configured contributor refs are old/behind or non-actionable. +- Decisions: Ported the safe core of the new `#182` evidence by updating Feynman's alpha-hub runtime patch to use alphaXiv's current `https://api.alphaxiv.org/auth/oauth2/*` endpoints and `openid profile email offline_access` scope. This directly restores a research-source login path without taking the fork's broader search-mode collapse or manual-token workflow. `#185` remains covered on `main` by bundled `pi-btw`; `#184` remains outside the AI-researcher product bar as support/advice. No open PRs needed merge/port/reject/defer action. +- Changed: `scripts/lib/alpha-hub-auth-patch.mjs` rewrites legacy Clerk endpoint constants to the current alphaXiv OAuth2 host; `scripts/prepare-runtime-workspace.mjs` now hashes/imports/applies the auth patch when building `.feynman/runtime-workspace.tgz`; `tests/alpha-hub-auth-patch.test.ts` covers the endpoint rewrite. +- Verified: `node --import tsx --test --test-concurrency=1 tests/alpha-hub-auth-patch.test.ts tests/package-seeding.test.ts` (`16/16`); full `npm test` twice after the endpoint patch (`586/586`, final run `586/586` after the runtime-archive fix); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` with `entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`; actual temp tarball smoke from `/tmp/feynman-pack-smoke-e3qffD/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:@companion-ai/alpha-hub` and `npm:pi-btw`, `feynman alpha status`, and nested runtime archive inspection showing `api.alphaxiv.org/auth`, `oauth2/authorize`, and `openid profile email offline_access`. +- Next: Keep the patch local until explicitly authorized to commit/push; issue `#182` can be rechecked with a fresh logged-out login flow when an affected user or release test environment is available. + +### 2026-07-07 12:50 EDT — check-new-issues-clean-main + +- Objective: Run the recurring Feynman intake sweep against live GitHub issues, PRs, contributor branches/forks, recent main workflows, release/npm state, package freshness, and local validation while preserving unrelated worktree changes. +- Checked: Live open issues stayed `#185`, `#184`, and `#182`; open PR list was empty; local `main` is aligned with `origin/main` at `54d08a3`; latest `main` `Publish and Release` run `28835967900` succeeded at `54d08a3`; latest GitHub release and npm package remain `v0.3.5` / `@companion-ai/feynman@0.3.5`; runtime/package versions remain `@earendil-works/pi-coding-agent@0.80.3`, `@companion-ai/alpha-hub@0.1.3`, and `pi-btw@0.4.1`; recent public forks checked (`nagyist/feynman`, `TheTechOddBug/feynman`, and `dubbypanda/feynman`) are identical to `main`, while `founderqiang/feynman`, `gaadha1985/feynman`, and `ussdeveloper/feynman` are behind by three commits with zero ahead commits. Configured contributor refs are old/behind or non-actionable. +- Decisions: No queue-driven code changes were needed. `#185` remains covered on `main` by bundling existing `pi-btw` in the core Pi package stack because it improves long-running research-loop steering without inventing a Feynman-owned interrupt protocol. `#184` remains outside the AI-researcher product bar because it is a thesis-planning/support request, not a repo feature or defect. `#182` has one new affected-user comment but no new Feynman-owned repro or diagnostic; it remains deferred/external because Feynman delegates alpha auth to `@companion-ai/alpha-hub`, the installed alpha-hub source owns Clerk registration, localhost callback, token exchange, and auth storage, issue diagnostics still point at alphaXiv/Clerk redirect/token handoff outside Feynman, and the current installed-tarball `alpha status` succeeds. No open PRs needed merge/port/reject/defer action. +- Freshness: Root and website have dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: `npm test` (`585/585`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` with `entryCount: 401`, shasum `dff26e588536c8184e30f2e39e208a47bea011c3`; actual temp tarball smoke from `/tmp/feynman-pack-smoke-I0Ypru/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:pi-btw` in Core, `feynman alpha status`, and runtime archive inspection for `npm/node_modules/pi-btw/package.json` plus `npm/node_modules/pi-btw/extensions/btw.ts`. +- Next: Keep sweeps read-only unless a fresh Feynman-owned repro or core-research PR appears; current main contains unreleased workbench commits after `v0.3.5`. + +### 2026-07-07 08:49 EDT — check-new-issues-clean-main + +- Objective: Run the recurring Feynman intake sweep against live GitHub issues, PRs, contributor branches/forks, recent main workflows, release/npm state, package freshness, and local validation while preserving unrelated worktree changes. +- Checked: Live open issues stayed `#185`, `#184`, and `#182`; open PR list was empty; local `main` is aligned with `origin/main` at `54d08a3`; latest `main` `Publish and Release` run `28835967900` succeeded at `54d08a3`; latest GitHub release and npm package remain `v0.3.5` / `@companion-ai/feynman@0.3.5`; runtime/package versions remain `@earendil-works/pi-coding-agent@0.80.3`, `@companion-ai/alpha-hub@0.1.3`, and `pi-btw@0.4.1`; the newest public forks checked (`nagyist/feynman`, `TheTechOddBug/feynman`, and `dubbypanda/feynman`) are identical to `main`, while `founderqiang/feynman`, `gaadha1985/feynman`, and `ussdeveloper/feynman` are behind by three commits with zero ahead commits. Configured contributor refs are old/behind or non-actionable. +- Decisions: No queue-driven code changes were needed. `#185` remains covered on `main` by bundling existing `pi-btw` in the core Pi package stack because it improves long-running research-loop steering without inventing a Feynman-owned interrupt protocol. `#184` remains outside the AI-researcher product bar because it is a thesis-planning/support request, not a repo feature or defect. `#182` remains deferred/external because Feynman delegates alpha auth to `@companion-ai/alpha-hub`, issue diagnostics point at alphaXiv/Clerk redirect/token handoff outside Feynman, and the current installed-tarball `alpha status` succeeds. No open PRs needed merge/port/reject/defer action. +- Freshness: Root and website have dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: `npm test` (`585/585`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` with `entryCount: 401`, shasum `dff26e588536c8184e30f2e39e208a47bea011c3`; actual temp tarball smoke from `/tmp/feynman-pack-smoke-C38rex/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:pi-btw` in Core, `feynman alpha status`, and runtime archive inspection for `npm/node_modules/pi-btw/package.json` plus `npm/node_modules/pi-btw/extensions/btw.ts`. +- Note: one real-pack metadata parser attempt failed after successful tarball creation because mixed prepack logs preceded/embedded JSON; the produced tarball was used directly for archive inspection and installed smoke. +- Next: Keep sweeps read-only unless a fresh Feynman-owned repro or core-research PR appears; current main contains unreleased workbench commits after `v0.3.5`. + +### 2026-07-07 04:48 EDT — check-new-issues-clean-main + +- Objective: Run the recurring Feynman intake sweep against live GitHub issues, PRs, contributor branches/forks, recent main workflows, release/npm state, package freshness, and local validation while preserving unrelated worktree changes. +- Checked: Live open issues stayed `#185`, `#184`, and `#182`; open PR list was empty; local `main` is aligned with `origin/main` at `54d08a3`; latest `main` `Publish and Release` run `28835967900` succeeded at `54d08a3`; latest GitHub release and npm package remain `v0.3.5` / `@companion-ai/feynman@0.3.5`; runtime/package versions remain `@earendil-works/pi-coding-agent@0.80.3`, `@companion-ai/alpha-hub@0.1.3`, and `pi-btw@0.4.1`; the newest public fork checked (`ussdeveloper/feynman`) is behind main by three commits with zero ahead commits, and configured contributor refs are old/behind or non-actionable. +- Decisions: No queue-driven code changes were needed. `#185` remains covered on `main` by bundling existing `pi-btw` in the core Pi package stack because it improves long-running research-loop steering without inventing a Feynman-owned interrupt protocol. `#184` remains outside the AI-researcher product bar because it is a thesis-planning/support request, not a repo feature or defect. `#182` remains deferred/external because Feynman delegates alpha auth to `@companion-ai/alpha-hub`, issue diagnostics point at alphaXiv/Clerk redirect/token handoff outside Feynman, and the current installed-tarball `alpha status` succeeds. No open PRs needed merge/port/reject/defer action. +- Freshness: Root and website have dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: `npm test` (`585/585`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` with `entryCount: 401`, shasum `dff26e588536c8184e30f2e39e208a47bea011c3`; actual temp tarball smoke from `/tmp/feynman-pack-smoke-T0C0Hw/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:pi-btw` in Core, `feynman alpha status`, and runtime archive inspection for `npm/node_modules/pi-btw/package.json` plus `npm/node_modules/pi-btw/extensions/btw.ts`. +- Next: Keep sweeps read-only unless a fresh Feynman-owned repro or core-research PR appears; current main contains unreleased workbench commits after `v0.3.5`. + +### 2026-07-07 00:53 EDT — check-new-issues-clean-main + +- Objective: Run the recurring Feynman intake sweep against live GitHub issues, PRs, contributor branches/forks, recent main workflows, release/npm state, package freshness, and local validation while preserving unrelated worktree changes. +- Checked: Live open issues stayed `#185`, `#184`, and `#182`; open PR list was empty; local `main` is aligned with `origin/main` at `54d08a3`; latest `main` `Publish and Release` run `28835967900` succeeded at `54d08a3`; latest GitHub release and npm package remain `v0.3.5` / `@companion-ai/feynman@0.3.5`; runtime/package versions remain `@earendil-works/pi-coding-agent@0.80.3`, `@companion-ai/alpha-hub@0.1.3`, and `pi-btw@0.4.1`; the two most recently pushed public forks (`founderqiang/feynman`, `ussdeveloper/feynman`) are both behind main by three commits with zero ahead commits, and configured contributor refs are old/behind or non-actionable. +- Decisions: No queue-driven code changes were needed. `#185` remains covered on `main` by bundling existing `pi-btw` in the core Pi package stack because it improves long-running research-loop steering without inventing a Feynman-owned interrupt protocol. `#184` remains outside the AI-researcher product bar because it is a thesis-planning/support request, not a repo feature or defect. `#182` remains deferred/external because Feynman delegates alpha auth to `@companion-ai/alpha-hub`, issue diagnostics point at alphaXiv/Clerk redirect/token handoff outside Feynman, and the current installed-tarball `alpha status` succeeds. No open PRs needed merge/port/reject/defer action. +- Freshness: Root and website have dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: `npm test` (`585/585`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34 pages`); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` with `entryCount: 401`, shasum `dff26e588536c8184e30f2e39e208a47bea011c3`; actual temp tarball smoke from `/tmp/feynman-pack-smoke-PknUYQ/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:pi-btw` in Core, `feynman alpha status`, and runtime archive inspection for `npm/node_modules/pi-btw/package.json` plus `npm/node_modules/pi-btw/extensions/btw.ts`. +- Next: Keep sweeps read-only unless a fresh Feynman-owned repro or core-research PR appears; current main contains unreleased workbench commits after `v0.3.5`. + ### 2026-07-06 EDT — workbench-light-theme-parity - Objective: Close the biggest visual 1:1 gap. Drove the installed Claude Science app live (authenticated via `claude-science url`) and captured its real project frame: it is a clean LIGHT UI (`rgb(253,253,252)` background, near-black text, blue accent), not the dark-green theme the workbench had. Owner decision: match Claude's light layout with Feynman green as the single accent, and simplify the frame chrome. @@ -3483,3 +3826,205 @@ Use this file to track chronology, not release notes. Keep entries short, factua - Verified: Full `npm test` passed (`585/585`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/patristic warnings; `npm run architecture:check` with existing split-debt warnings; root `npm audit --omit=dev` (`0 vulnerabilities`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), `npm run build` (`34 pages`), and `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `cc7a11600c6ebf36481195626203769be3c52dcb`); real tarball smoke from `/tmp/feynman-pack-smoke-uvbzpV/companion-ai-feynman-0.3.5.tgz` found bundled `pi-btw` files and passed `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:pi-btw` in Core, and `feynman alpha status`. - Note: The first real-pack metadata parser hit the known mixed-log JSON shape after the tarball was created; the produced tarball was used directly for archive inspection and installed-package smoke. - Next: Commit or push only when explicitly authorized; otherwise keep the local `#185` fix plus unrelated workbench edits intact. + +### 2026-07-09 00:59 EDT — intake-sweep-alpha-oauth-current + +- Objective: Re-run the `check-new-issues` intake sweep against the current dirty checkout, preserve unrelated local work, and verify whether fresh GitHub, release, package, contributor, or validation state requires another safe local fix. +- Checked: Live GitHub queue still has open issues `#185`, `#184`, and `#182`, with zero open PRs. Latest `main` `Publish and Release` run is `28835967900`, green at `54d08a3`; local `main` is aligned with `origin/main` at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; Pi latest/current is `0.80.3`; alpha-hub latest/current is `0.1.3`; `pi-btw` latest/current is `0.4.1`. +- Decisions: No new code changes were needed. Issue `#182` is locally covered by the existing pending alphaXiv OAuth2 endpoint patch in `scripts/lib/alpha-hub-auth-patch.mjs`, `scripts/prepare-runtime-workspace.mjs`, and `tests/alpha-hub-auth-patch.test.ts`; installed-tarball archive inspection verified the patched `@companion-ai/alpha-hub/src/lib/auth.js` uses `https://api.alphaxiv.org/auth`, `oauth2/authorize`, and `openid profile email offline_access`. Issue `#185` remains covered by bundled `pi-btw`. Issue `#184` remains outside Feynman's AI-researcher product bar as support/advice. No PRs to merge, port, reject, or defer. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` is stale behind `origin/main` and its useful local-model warning behavior is already present in current source/tests. Other sampled fork refs are behind `origin/main` with provider setup, Overleaf/export/admin prompts, Claude CLI bypass, architecture notes, fork-specific search tooling, broad platform churn, or runtime/setup churn; no clean core-research patch was ported. +- Freshness: Root and website `npm outdated --json` show dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused alpha/runtime tests passed (`27/27`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); installed tarball smoke from `/tmp/feynman-pack-smoke-QRXTHd/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:pi-btw`, `feynman alpha status`, bundled `pi-btw` files, and alpha OAuth2 runtime archive inspection. +- Note: The first archive-inspection path in the smoke used a stale `package/npm/...` prefix and failed after install; the corrected archive path `npm/node_modules/@companion-ai/alpha-hub/src/lib/auth.js` passed. +- Next: Commit or push only when explicitly authorized; otherwise keep the local alpha OAuth patch and lab notebook entry local-only. + +### 2026-07-09 10:22 EDT — intake-sweep-alpha-oauth-still-current + +- Objective: Re-run the `check-new-issues` intake sweep against the current dirty checkout, preserve unrelated local work, and verify whether fresh GitHub, release, package, contributor, or validation state requires another local fix. +- Checked: Live GitHub queue still has open issues `#185`, `#184`, and `#182`, with zero open PRs. Local `main` is aligned with `origin/main` at `54d08a3`; latest main `Publish and Release` run `28835967900` is green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; Pi latest/current is `0.80.3`; alpha-hub latest/current is `0.1.3`; `pi-btw` bundled runtime package is `0.4.1`. +- Decisions: No new code changes were needed. Issue `#182` remains locally covered by the pending alphaXiv OAuth2 endpoint patch in `scripts/lib/alpha-hub-auth-patch.mjs`, `scripts/prepare-runtime-workspace.mjs`, and `tests/alpha-hub-auth-patch.test.ts`; direct source and installed-tarball archive checks verified the patched `@companion-ai/alpha-hub/src/lib/auth.js` uses `https://api.alphaxiv.org/auth`, `oauth2/authorize`, and `openid profile email offline_access`. Issue `#185` remains covered by bundled `pi-btw`. Issue `#184` remains outside Feynman's AI-researcher product bar as support/advice. No PRs to merge, port, reject, or defer. +- Contributor refs: Configured remote refs remain stale or non-actionable: `origin/fix/deepresearch-local-model-warning` is behind current `main`, `pr4fork/main` contains old runtime/telemetry churn, and sampled fork refs contain old provider/export/admin/prompt/platform changes rather than a fresh core research-loop fix. +- Freshness: Root and website `npm outdated --long` show dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); installed tarball smoke from `/tmp/feynman-pack-smoke-ljaPtX/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:pi-btw`, `feynman alpha status`, bundled `pi-btw` files, and alpha OAuth2 runtime archive inspection. +- Next: Commit or push only when explicitly authorized; otherwise keep the local alpha OAuth patch and lab notebook entry local-only. + +### 2026-07-09 13:09 EDT — intake-sweep-alpha-oauth-still-current + +- Objective: Re-run the `check-new-issues` intake sweep against the current dirty checkout, preserve unrelated local work, and verify whether fresh GitHub, release, package, contributor, or validation state requires another local fix. +- Checked: Local `main` is aligned with `origin/main` at `54d08a3`. Live GitHub queue still has open issues `#185`, `#184`, and `#182`, with zero open PRs. Latest main `Publish and Release` run `28835967900` is green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; `@earendil-works/pi-coding-agent` latest/current remains `0.80.3`; alpha-hub latest/current remains `0.1.3`; `pi-btw` latest/current remains `0.4.1`. +- Decisions: No new code changes were needed. Issue `#182` remains locally covered by the pending alphaXiv OAuth2 endpoint patch in `scripts/lib/alpha-hub-auth-patch.mjs`, `scripts/prepare-runtime-workspace.mjs`, and `tests/alpha-hub-auth-patch.test.ts`; installed-tarball archive checks verified the patched `@companion-ai/alpha-hub/src/lib/auth.js` uses `https://api.alphaxiv.org/auth`, `oauth2/authorize`, `oauth2/token`, `oauth2/register`, `oauth2/userinfo`, and `openid profile email offline_access`. Issue `#185` remains covered by bundled `pi-btw`. Issue `#184` remains outside Feynman's AI-researcher product bar as support/advice. No PRs to merge, port, reject, or defer. +- Contributor refs: No checked contributor branch or fork was ahead of `origin/main`. Recent public forks `ifr1m`, `QuantumKuba`, `ivnvalex`, and `colindomoney` match `54d08a3`; `ussdeveloper` is behind by 3 commits; `advaitpaliwal`, `skandanyal`, and `gaurav-g-alva` are behind by 18 commits. Configured remote refs remain stale or non-actionable: `origin/fix/deepresearch-local-model-warning` is behind by 74 with one already-covered ahead commit, and `pr4fork/main` is behind by 73 with zero ahead. +- Freshness: Root and website `npm outdated --long --json` show dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused alpha/runtime/settings tests passed (`31/31`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `01d621ba42cd8d159489a18aef58778887ade7e9`); real installed tarball smoke from `/tmp/feynman-pack-smoke-CUZfeY/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, current styled help, `feynman packages list` showing `npm:pi-btw`, `feynman alpha status`, bundled `pi-btw` files, and alpha OAuth2 runtime archive inspection. +- Note: The first installed-smoke archive inspection hit the known `tar -tzf` `ENOBUFS` failure from buffer-based archive listing, and a stale help assertion expected `Usage: feynman`; the streamed archive check plus current-help assertion passed. Temp smoke artifacts were removed. +- Next: Commit or push only when explicitly authorized; otherwise keep the local alpha OAuth patch and lab notebook entry local-only. + +### 2026-07-09 17:17 EDT — intake-sweep-pi-0805-refresh + +- Objective: Re-run the `check-new-issues` intake sweep against the current dirty checkout, preserve unrelated local work, and port only safe core-research fixes. +- Checked: Local `main` is aligned with `origin/main` at `54d08a3`. Live GitHub queue still has open issues `#185`, `#184`, and `#182`, with zero open PRs. Latest main `Publish and Release` run `28835967900` is green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; `@companion-ai/alpha-hub` latest/current remains `0.1.3`; `pi-btw` latest/current remains `0.4.1`; `@earendil-works/pi-*` latest is now `0.80.5`. +- Decisions: Ported the smallest safe package freshness fix by bumping Feynman's pinned Pi runtime packages from `0.80.3` to `0.80.5`, because upstream `0.80.5` includes research-loop reliability fixes around provider retries/errors, truncated tool calls, session/context handling, extension lifecycle, and cache visibility. Issue `#182` remains locally covered by the pending alphaXiv OAuth2 endpoint patch; issue `#185` remains covered by bundled `pi-btw`; issue `#184` remains outside Feynman's AI-researcher product bar as support/advice. No PRs to merge, port, reject, or defer. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` is behind current `main` with one already-covered ahead commit; `pr4fork/main` is behind with zero ahead. Sampled fork refs contain old Overleaf/export, provider setup, Claude bypass, platform churn, architecture notes, or fork-specific search changes rather than a fresh core research-loop fix. +- Changed: Updated `package.json` and `package-lock.json` to `@earendil-works/pi-agent-core`, `pi-ai`, `pi-coding-agent`, and `pi-tui` `0.80.5`; updated Pi runtime fallback constants in `src/pi/package-ops.ts` and `scripts/prepare-runtime-workspace.mjs`. +- Freshness: Root `npm outdated --long --json` now shows only non-Pi dependency drift; website drift remains non-security dependency drift. Root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Focused package/runtime tests passed (`39/39`); full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `3ac05c3ab4e19620ea6ad8946c91809e7ba47a70`); real tarball smoke from `/tmp/feynman-pack-smoke-XpXZOs/companion-ai-feynman-0.3.5.tgz` passed for `feynman --version`, current styled help, `feynman packages list` showing `npm:pi-btw`, `feynman alpha status`, installed Pi `0.80.5`, runtime archive Pi `0.80.5`, and alpha OAuth2 runtime archive inspection. +- Note: The first tarball install attempt failed because a stale `/tmp/feynman-pack-smoke-*` directory plus npm cache left only `175M` free; cleared only Feynman smoke temp directories and npm cache, then reran the smoke successfully. The initial corrected smoke used a stale alpha-hub `cli/src` archive path; the actual packaged path is `npm/node_modules/@companion-ai/alpha-hub/src/lib/auth.js` and passed. +- Next: Commit or push only when explicitly authorized; otherwise keep the local Pi `0.80.5` refresh plus existing alpha OAuth patch local-only. + +### 2026-07-10 01:12 EDT — intake-sweep-pi-0806-still-current + +- Objective: Re-run the `check-new-issues` intake sweep against the current dirty checkout, preserve unrelated local work, and verify whether fresh GitHub, release, package, contributor, or validation state requires another local fix. +- Checked: Local `main` is aligned with `origin/main` at `54d08a3`. Live GitHub queue still has open issues `#185`, `#184`, and `#182`, with zero open PRs. Latest main `Publish and Release` run `28835967900` is green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; `@companion-ai/alpha-hub` remains `0.1.3`; `pi-btw` remains `0.4.1`; `@earendil-works/pi-*` remains `0.80.6`. +- Decisions: No new code changes were needed. Issue `#182` remains locally covered by the pending alphaXiv OAuth2 endpoint patch; issue `#185` remains covered by bundled `pi-btw`; issue `#184` remains outside Feynman's AI-researcher product bar as support/advice. No PRs to merge, port, reject, or defer. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` is behind current `main` with one already-covered ahead commit; `pr4fork/main` is behind with zero ahead. Sampled fork refs contain old Bedrock/provider/export/admin/prompt/platform/search changes rather than a fresh core research-loop fix. +- Freshness: Root and website `npm outdated --long --json` show dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `35c88e81b93f395c695cab93e46bbde1f6f27bd6`); real installed tarball smoke passed for `feynman --version`, `feynman packages list` showing `npm:pi-btw`, `feynman alpha status`, installed Pi `0.80.6`, bundled runtime `pi-btw`, and alpha OAuth2 runtime archive inspection. +- Note: The first installed-smoke metadata assertion used a package-local Pi path and failed after npm hoisted Pi top-level; the corrected filesystem metadata and runtime archive checks passed. Temp smoke artifacts and the root tarball were removed. +- Next: Commit or push only when explicitly authorized; otherwise keep the local Pi `0.80.6` refresh plus existing alpha OAuth patch local-only. + +### 2026-07-10 05:08 EDT — intake-sweep-pi-0806-still-current + +- Objective: Re-run the `check-new-issues` intake sweep against the current dirty checkout, preserve unrelated local work, and verify whether fresh GitHub, release, package, contributor, or validation state requires another local fix. +- Checked: Local `main` is aligned with `origin/main` at `54d08a3`. Live GitHub queue still has open issues `#185`, `#184`, and `#182`, with zero open PRs. Latest main `Publish and Release` run `28835967900` is green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` latest/current remains `0.3.5`; `@companion-ai/alpha-hub` remains `0.1.3`; `pi-btw` remains `0.4.1`; `@earendil-works/pi-*` remains `0.80.6`. +- Decisions: No new code changes were needed. Issue `#182` remains locally covered by the pending alphaXiv OAuth2 endpoint patch; issue `#185` remains covered by bundled `pi-btw`; issue `#184` remains outside Feynman's AI-researcher product bar as support/advice. No PRs to merge, port, reject, or defer. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` is behind current `main` with one already-covered ahead commit; `pr4fork/main` is behind with zero ahead. Sampled fork refs contain old Overleaf/export, MiniMax/provider setup, Claude bypass, Bedrock setup, architecture notes, fork-specific search tooling, or Windows/platform churn rather than a fresh core research-loop fix. +- Freshness: Root and website `npm outdated --long --json` show dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: Full `npm test` passed (`586/586`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk/patristic warnings; `npm run architecture:check` with existing split-debt warnings; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 401`, shasum `35c88e81b93f395c695cab93e46bbde1f6f27bd6`); real installed tarball smoke passed for `feynman --version`, `feynman --help`, `feynman packages list` showing `npm:pi-btw`, `feynman alpha status`, installed Pi `0.80.6`, runtime archive Pi `0.80.6`, bundled runtime `pi-btw`, and alpha OAuth2 runtime archive inspection. +- Next: Commit or push only when explicitly authorized; otherwise keep the local Pi `0.80.6` refresh plus existing alpha OAuth patch local-only. + +### 2026-07-10 13:24 EDT — feynman-e2e-oauth-mcp-repair + +- Objective: Reproduce the current user-reported failures and verify Feynman across source, real OAuth/provider flows, MCP transports, cloud clean-room execution, research output, and the packed npm artifact. +- Live queue: Classified issues `#182`, `#184`, `#185`, and `#186`; there are zero open PRs. `#182` and `#186` have local fixes, `#185` is implemented on `main` but unreleased, and `#184` is support rather than a product defect. Public npm/GitHub release remains `0.3.5`. +- Fixed: Extended the alpha-hub runtime patch to reject missing or mismatched OAuth callback state. Fixed a separate workbench data-loss race discovered by the full suite: valid `active-org.json` manifests are no longer rewritten on every lookup, creation and required upgrades are atomic, and concurrent readers no longer mint new org UUIDs after observing a truncated file. +- State recovery: The race had redirected the live pointer to a test-only org created during the suite. Restored it to the most recent org containing the real Feynman workspace, backed up the prior pointer at `~/.feynman/.state/active-org-pre-recovery-20260710-1324.json`, and deleted or merged no org data. Twenty repeated lookups preserved the same mode-`0600` manifest; the recovered workbench exposed 6 projects, 60 runs, and 445 artifacts. +- Live verification: Fresh alphaXiv browser OAuth, authenticated keyword/semantic search, and paper retrieval passed; OpenAI model execution returned the required sentinel; custom MCP Streamable HTTP, SSE, stdio, bearer OAuth, grants, and callback/disconnect passed; `/btw` returned `BTW_E2E_OK` during a rate-limited `/lit` run. Anthropic OAuth reached the real provider page but remained blocked by the logged-out external account. +- Compute and artifacts: Authenticated Daytona CLI created a clean sandbox, cloned and tested the checkout, and deleted the sandbox. `/lit` produced `outputs/loopback-oauth-pkce.md`, its provenance sidecar, and a verification record. No E2B credential was promoted or tested. +- Verified: Full tests passed (`590/590`); typecheck, root build, architecture check, website lint/typecheck/build, root and website production audits (`0 vulnerabilities`), and `git diff --check` passed. `npm pack --dry-run` and a real clean-home tarball install passed; the shipped runtime contains Pi `^0.80.6`, `pi-btw` `^0.4.1`, current alphaXiv endpoints, and loopback state validation. +- Security: The inherited Daytona key is usable but remains as a literal in a mode-`0644` shell file and entered an internal tool transcript during discovery. Rotate it and move the replacement into a user-only secret store; do not reuse the exposed value. +- Persistence: Local-only and uncommitted. Next: run the installer on Windows 11, complete any required Anthropic OAuth from a signed-in account, bump the version, and publish before describing the fixes as user-visible. + +### 2026-07-10 15:41 EDT — feynman-e2e-user-issue-release + +- Objective: Finish the live issue sweep, repair every actionable user-facing failure, verify the release artifact, and publish the work for review. +- Fixed: Added the packaged Option+Enter newline binding without overwriting user keybindings; moved `fetch_content` PDF scratch output from `~/Downloads` to project-local `.feynman/cache/fetch-content` with an environment override; added actionable help for unknown CLI flags; documented that package updates already include extensions; retained the alphaXiv OAuth, Windows staged-installer, active-org atomicity, Pi `0.80.6`, and bundled `pi-btw` fixes from the preceding repair. +- GitHub: Ported contributor PR `#189` with its original attribution. Left PR `#191` unported because it adds a broader extensions-management surface while issue `#187` only requires clear update behavior and error guidance. Issue `#184` remains a support request rather than a Feynman product defect. +- Verified: Focused regression suites passed (`98/98`); the complete suite passed (`593/593`); typecheck, production build, architecture guard, website lint/typecheck/build (`34` pages), root and website production audits (`0 vulnerabilities`), `git diff --check`, and a gitleaks diff scan passed. A clean installed `0.3.6` tarball passed version, main help, alpha help, package listing, unknown `--extensions` guidance, packaged keybindings, Windows installer equality, Pi `^0.80.6`, `pi-btw` `^0.4.1`, current alphaXiv OAuth endpoints, and project-local PDF-cache inspection. +- Security: Moved the Daytona API key from plaintext `~/.zshrc` into macOS Keychain, verified a fresh shell loads the same credential, and passed an authenticated `daytona list`. The existing key was not revoked because Daytona deletion is immediate and this machine has neither a manager JWT nor an account-wide consumer inventory; rotate it after identifying every consumer. +- Environment: The first full-suite attempt failed only with `ENOSPC` across 112 temp-directory creations; removed 5,394 stale Feynman test workspaces and reran cleanly. Tarball verification also required clearing reproducible npm/Bun/Homebrew/module/updater caches because the data volume remained effectively full. +- Persistence: Published for review on `codex/fix-feynman-user-issues`. Next: merge only after review, let the main-branch publish workflow validate the package on Ubuntu, then dispatch the published-package macOS/Linux/Windows install matrix before calling the Win11 fix live-verified. + +### 2026-07-14 03:39 PDT — intake-sweep-pr192-plus-thinking-request + +- Objective: Re-run the `check-new-issues` intake sweep against the current dirty checkout, preserve unrelated local work, and classify new issue/PR/release/package state against the AI-researcher product bar. +- Checked: Live GitHub queue now has open issues `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`. Open PRs remain `#192`, `#191`, and `#189`. Latest main `Publish and Release` run remains green at `54d08a3`; GitHub release and npm latest remain `v0.3.5` / `0.3.5`; local package remains `0.3.6`; bundled Pi remains `0.80.6`; alpha-hub remains `0.1.3`. +- Decisions: No new code changes were needed. Issue `#196` is relevant to research-loop TUI ergonomics but defers upstream to Pi's interactive slash-command layer because Feynman already exposes CLI `--thinking`, model picker, persisted thinking state, and docs/keybinding coverage while Pi owns builtin slash-command dispatch. Issues `#193` and `#182` remain covered by pending `#192` alphaXiv OAuth/hoisted alpha CLI work; `#190`, `#188`, `#187`, `#186`, and `#185` remain covered by PR `#192`; `#184` remains outside the AI-researcher product bar. +- PR decisions: `#192` remains the merge path with green Vercel and four commits. `#189` remains already ported into `#192` as cherry-pick `79aa7b2`. `#191` remains reject/defer because it adds a broader `feynman extensions` inventory surface and still has failing Vercel while `#187` only requires update/help guidance. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` is `74` behind / `1` ahead; `pr4fork/main` is `73` behind / `0` ahead. Visible fork refs ahead of `origin/main` are Overleaf/admin prompts, MiniMax/provider/platform changes, Claude bypass, Bedrock setup, fork docs/search tooling, architecture notes, or broad Windows rewrites already covered by `#192`; no new safe port target was found. +- Freshness: Root and website `npm outdated --json` show dependency drift only; root and website `npm audit --omit=dev` both found `0 vulnerabilities`. +- Verified: `npm run typecheck`; `npm run build` with existing Vite/RDKit/3Dmol/chunk warnings; `npm run architecture:check` with existing split-debt warnings; `npm test` passed (`594/594`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev`; `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `f0b50e989c04095e9a4b3b65628bcf6def9921aa`); real installed-tarball smoke passed for version/help, alpha help/status, packages list including `npm:pi-btw` and `npm:pi-web-access`, hoisted alpha resolver, unknown `--extensions` help hint, and packaged `alt+enter` newline binding. +- Probe caveat: An initial string probe expected old built-output/keybinding shapes and reported false negatives; the corrected installed CLI behavior and packaged JSON checks passed. No GitHub writes were made. +- Next: Merge/publish PR `#192` when authorized; treat `#196` as a Pi upstream slash-command request unless a Feynman-owned packaging or docs defect is reproduced. + +### 2026-07-14 18:43 PDT — intake-sweep-pr192-still-clean + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve pre-existing dirty files, refresh GitHub/package/release/branch state, classify open issues/PRs/contributor refs, and run repo-local validation without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; pre-existing dirty files remained `CHANGELOG.md`, `src/cli.ts`, and `tests/pi-runtime.test.ts`. Open issues remain `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest is `0.80.7` while the local release candidate remains pinned to `0.80.6`; alpha-hub remains `0.1.3`; `pi-btw` remains `0.4.1`. +- Decisions: No new code changes were needed. PR `#192` remains the merge/defer path for the local `0.3.6` fix set covering `#182`, `#193`, `#190`, `#188`, `#187`, `#186`, and `#185`; it is still draft, merge-clean, and Vercel green. PR `#189` remains already ported into `#192` as cherry-pick `79aa7b2`. PR `#191` remains reject/defer because it adds a broader `feynman extensions` inventory command while `#187` only requires accurate update/help guidance and the PR's Vercel status remains failing. Issue `#196` remains defer/reject for this sweep because slash-command dispatch belongs to Pi's TUI layer; `#184` remains outside the AI-researcher product bar as a support/content request. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` remains `74` behind / `1` ahead; `pr4fork/main` remains `73` behind / `0` ahead. Visible fork refs are stale or broad provider/platform/docs/admin/search changes rather than a current safe research-loop port target. +- Freshness: Root and website `npm outdated --json` show non-security drift only, including Pi `0.80.7`, OpenTelemetry, Ketcher, Vite, TypeBox, Astro, Tailwind, and other minor/package updates. No dependency edit was made because no queue-specific root-cause failure required it and the branch is already a validated release candidate. +- Verified: `npm run typecheck`; `npm run build` with existing Vite/RDKit/3Dmol/direct-eval/chunk warnings; `npm run architecture:check` with existing split-debt warnings; `npm test` passed (`594/594`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `f0b50e989c04095e9a4b3b65628bcf6def9921aa`, size about `71.9 MB`); corrected installed-tarball smoke passed for package/CLI `0.3.6`, CLI help, alpha help/status, packages list including `npm:pi-btw` and `npm:pi-web-access`, unknown `--extensions` help hint, bundled `alt+enter`, runtime archive entries for `pi-btw`, `pi-web-access`, and Pi, alphaXiv OAuth2 patch, and project-local fetch cache patch. +- Probe caveat: Early smoke wrappers failed only from harness assumptions: mixed `npm pack --json` lifecycle output and a stale inner runtime archive `package/` prefix. The corrected smoke used the deterministic tarball filename plus actual inner archive paths and passed; generated tarballs and temp installs were removed. +- Next: Merge/publish PR `#192` only when authorized; keep `#191` out unless product scope explicitly expands to extension inventory, and treat Pi `0.80.7` as freshness drift until a research-loop fix justifies changing the validated release candidate. + +### 2026-07-16 05:44 PDT — intake-sweep-atlascloud-pr197 + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve pre-existing dirty files, refresh GitHub/package/release/branch state, classify the new queue item, and validate the local release candidate without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` at `8ad8d55` tracking `origin/codex/fix-feynman-user-issues`; pre-existing dirty files remained `CHANGELOG.md`, `src/cli.ts`, and `tests/pi-runtime.test.ts`. Open issues remain `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`. Open PRs are now `#197`, `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3`; GitHub release remains `v0.3.5`; npm `@companion-ai/feynman` remains `0.3.5`; local package remains `0.3.6`; Pi latest remains `0.80.7`; alpha-hub remains `0.1.3`; `pi-btw` remains `0.4.1`. +- Decisions: No functional repo edits were made. PR `#197` is reject/defer for this sweep: it hard-codes a new Atlas Cloud setup lane and model IDs even though the existing custom OpenAI-compatible provider flow already covers this class of provider, it is not tied to a current Feynman research-loop defect, and its only status check is a Vercel authorization failure. PR `#192` remains the merge/defer path for the local `0.3.6` fix set covering `#182`, `#193`, `#190`, `#188`, `#187`, `#186`, and `#185`. PR `#189` remains already ported into `#192` as cherry-pick `79aa7b2`. PR `#191` remains reject/defer because it adds a broader `feynman extensions` inventory command while `#187` only requires accurate update/help guidance. Issue `#196` remains defer/reject to Pi's TUI slash-command layer; `#184` remains outside the AI-researcher product bar. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` remains `74` behind / `1` ahead; `pr4fork/main` remains `73` behind / `0` ahead. Visible fork refs remain stale or broad provider/platform/docs/admin/search work rather than a current safe research-loop port target. +- Freshness: Root and website `npm outdated --json` show non-security drift only, including Pi `0.80.7`, OpenTelemetry, Ketcher, Vite, TypeBox, Astro, Tailwind, shadcn, and related minor/package updates. No dependency edit was made because no queue-specific root-cause failure required it and the branch is already a validated release candidate. +- Verified: Focused runtime test passed (`15/15`); `npm run typecheck`; `npm run build` with existing Vite/RDKit/3Dmol/direct-eval/chunk warnings; `npm run architecture:check` with existing split-debt warnings; `npm test` passed (`594/594`); website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages); root and website `npm audit --omit=dev` (`0 vulnerabilities`); `git diff --check`; `npm pack --dry-run --json` (`entryCount: 402`, shasum `f0b50e989c04095e9a4b3b65628bcf6def9921aa`, size about `71.9 MB`); installed-tarball smoke passed for package/CLI `0.3.6`, CLI help, alpha help, packages list including `npm:pi-btw` and `npm:pi-web-access`, unknown `--extensions` help hint, bundled `alt+enter`, runtime archive entries for Pi, `pi-btw`, and `pi-web-access`, alphaXiv OAuth2 patch, and project-local fetch cache patch. +- Next: Merge/publish PR `#192` only when authorized; do not port `#197` unless Feynman intentionally expands curated provider setup and verifies Atlas Cloud from trusted docs plus current runtime behavior. + +### 2026-07-17 05:35 PDT — intake-sweep-pr197-still-deferred + +- Objective: Re-run `check-new-issues` from `/Users/advaitpaliwal/Companion/Code/feynman`, preserve pre-existing dirty files, refresh live GitHub/release/package/workflow state, classify open issues and PRs, and validate the local `0.3.6` candidate without GitHub writes. +- Checked: Current branch remains `codex/fix-feynman-user-issues` tracking `origin/codex/fix-feynman-user-issues`; pre-existing dirty files remained `CHANGELOG.md`, `src/cli.ts`, and `tests/pi-runtime.test.ts`. Open issues remain `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`. Open PRs remain `#197`, `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains `28835967900`, green at `54d08a3` on 2026-07-07. GitHub release remains `v0.3.5`; npm latest remains `0.3.5`; local package remains `0.3.6`; bundled Pi remains `0.80.6`; alpha-hub remains `0.1.3`. +- Decisions: No new functional edits were made. PR `#197` remains reject/defer because it hard-codes Atlas Cloud as a curated provider and model list while the existing custom OpenAI-compatible provider path covers that class and no current Feynman-owned research-loop defect requires the vendor lane; its Vercel check still fails on authorization. PR `#192` remains the merge/defer path for the coherent `0.3.6` fix set covering `#182`, `#193`, `#190`, `#188`, `#187`, `#186`, and `#185`. PR `#189` remains already ported into `#192` as cherry-pick `79aa7b2`. PR `#191` remains reject/defer because it adds a broader `feynman extensions` inventory command while `#187` only needs accurate update/help guidance. Issue `#196` remains upstream to Pi's TUI slash-command layer; issue `#184` remains outside the AI-researcher product bar. +- Contributor refs: `origin/fix/deepresearch-local-model-warning` remains `74` behind / `1` ahead; `pr4fork/main` remains `73` behind / `0` ahead. No contributor branch introduced a fresh safe research-loop port target. +- Freshness: Root `npm outdated --json` shows non-security drift including Pi `0.80.10`, OpenTelemetry, Ketcher, Vite, TypeBox, and related package updates; website drift includes Astro, Tailwind, shadcn, and related packages. No dependency edit was made because dependency churn alone is not a queue-specific root-cause fix and the local release candidate remains validated. +- Verified: Focused runtime test passed (`15/15`); `npm run typecheck`; `npm run build` with existing Vite/RDKit/3Dmol/direct-eval/chunk warnings; `npm run architecture:check` with existing split-debt warnings; `npm test` passed (`594/594`); root and website `npm audit --omit=dev` found `0 vulnerabilities`; website `npm run lint`, `npm run typecheck` (`0 errors`, `0 warnings`, `0 hints`), and `npm run build` (`34` pages) passed; `git diff --check` passed; `npm pack --dry-run --json` passed with `entryCount: 402`, shasum `f0b50e989c04095e9a4b3b65628bcf6def9921aa`, and size about `71.9 MB`; real installed-tarball smoke passed for installed `0.3.6`, CLI help, alpha help, packages list containing `npm:pi-btw` and `npm:pi-web-access`, `update --extensions` exiting `1` with the help hint, runtime archive entries for `pi-btw` and `pi-web-access`, alphaXiv OAuth2 markers, and project-local fetch cache markers. +- Next: Merge/publish PR `#192` only when authorized; leave `#197` out unless curated Atlas Cloud setup becomes an explicit product decision backed by trusted docs and live runtime verification. + +### 2026-07-20 22:06 EDT — intake-sweep-security-freshness + +- Objective: Re-run `check-new-issues`, preserve existing dirty work, refresh live issue/PR/workflow/release/package state, classify the queue, and repair repo-local validation failures where safe. +- Checked: Open issues remain `#198`, `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#197`, `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains green at `54d08a3`; GitHub release and npm latest remain `v0.3.5` / `0.3.5`; local package remains `0.3.6`; bundled Pi remains `0.80.6`; npm Pi latest remains `0.80.10`. +- Decisions: PR `#192` remains merge/defer pending explicit authorization; PR `#189` remains already ported into `#192`; PR `#191` remains reject/defer as broader extension inventory surface; PR `#197` remains reject/defer as generic provider catalog expansion. Issue `#198` remains outside the AI-researcher product bar; `#196` remains upstream Pi TUI slash-command scope; `#193/#182/#190/#188/#187/#186/#185` remain covered by `#192`; `#184` remains support/content scope. +- Fixed: Root `body-parser` and hoisted `protobufjs` audit resolutions were refreshed; website dependencies moved to Astro `7.1.3`, `@astrojs/react` `6.0.1`, Vite `8.1.5`, and `body-parser` `2.3.0`; the stricter Astro 7 compiler exposed and fixed one missing nav `` in `website/src/layouts/main.astro`. +- Blocked: Root `npm audit --omit=dev` still reports Pi-shrinkwrapped `@earendil-works/pi-coding-agent/node_modules/brace-expansion@5.0.6` and `protobufjs@7.6.4`. Latest Pi `0.80.10` still ships the same nested versions, and npm overrides do not penetrate Pi's package shrinkwrap, so no safe Feynman-local fix remains without an upstream Pi package update or replacing the Pi artifact. +- Verified: Focused runtime test passed (`15/15`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk warnings; `npm run architecture:check`; `npm test` passed (`594/594`); website lint/typecheck/build passed (`34` pages); website audit found `0 vulnerabilities`; `git diff --check` passed; `npm pack --dry-run --json` passed with `entryCount: 402`, shasum `9fffb39c1002616276e0c7f860bae5533ac91c2d`, size `71025824`; installed-tarball smoke passed for `0.3.6`, help, alpha help, `update --extensions` help hint, `pi-btw`, `pi-web-access`, alpha resolver, `alt+enter`, and runtime archive. +- Next: Keep the dependency/security patch local for review; merge/publish `#192` only when authorized; track the remaining root audit blocker to a Pi package release that updates its shrinkwrapped nested dependencies. + +### 2026-07-21 19:32 EDT — intake-sweep-website-audit-refresh + +- Objective: Re-run `check-new-issues`, preserve the existing dirty release-candidate worktree, refresh live GitHub/release/package/workflow state, classify open issues/PRs, and repair any safe repo-local validation failures without GitHub writes. +- Checked: Open issues remain `#198`, `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#197`, `#192`, `#191`, and `#189`. Latest `main` `Publish and Release` run remains green at `54d08a3`; GitHub release and npm latest remain `v0.3.5` / `0.3.5`; local package remains `0.3.6`; bundled Pi remains `0.80.6`; npm Pi latest remains `0.81.1`. +- Decisions: PR `#192` remains merge/defer pending explicit authorization; PR `#189` remains already ported into `#192`; PR `#191` remains reject/defer as broader extension inventory surface; PR `#197` remains reject/defer as generic provider catalog expansion. Issue `#198` remains outside the AI-researcher product bar; `#196` remains upstream Pi TUI slash-command scope; `#193/#182/#190/#188/#187/#186/#185` remain covered by `#192`; `#184` remains support/content scope. +- Fixed: Website audit newly reported `sharp <0.35.0` and `svgo 4.0.0 - 4.0.1`; added website overrides for `sharp@0.35.3` and `svgo@4.0.2` and refreshed `website/package-lock.json`. +- Blocked: Root `npm audit --omit=dev` still reports Pi-shrinkwrapped `@earendil-works/pi-coding-agent/node_modules/brace-expansion@5.0.6` and `protobufjs@7.6.4`. Latest Pi `0.81.1` ships `brace-expansion@5.0.7` but still shrinkwraps `protobufjs@7.6.4`, so a Pi bump would be a runtime upgrade and would not fully clear the audit blocker. +- Verified: Focused runtime test passed (`15/15`); `npm run typecheck`; `npm run build` with existing RDKit/3Dmol/chunk warnings; `npm run architecture:check`; `npm test` passed (`594/594`); website lint/typecheck/build passed (`34` pages); website audit found `0 vulnerabilities`; root audit remains blocked only by Pi shrinkwrap; `git diff --check` passed; `npm pack --dry-run --json` passed with `entryCount: 402`, shasum `c698bb6c66c37756ba677c0a45af49c532f6a6d9`, size `71041144`; installed-tarball smoke passed for `0.3.6`, help, alpha help, `update --extensions` help hint, `pi-btw`, `pi-web-access`, alpha resolver, `alt+enter`, and runtime archive entries. +- Next: Keep the website audit patch local for review; merge/publish `#192` only when authorized; track the remaining root audit blocker to an upstream Pi release that also updates nested `protobufjs`. + +### 2026-07-23 04:22 EDT — intake-sweep-model-spec-package-runtime + +- Objective: Re-run `check-new-issues`, preserve the existing release-candidate worktree, classify the live issue/PR/branch/release queue, and port only safe research-loop reliability fixes. +- Checked: Open issues are `#199`, `#198`, `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs are `#197`, `#192`, `#191`, and `#189`. GitHub/npm latest remain `v0.3.5` / `0.3.5`, the local candidate remains `0.3.6`, and bundled Pi remains `0.80.6` versus latest `0.81.1`. +- Decisions: PR `#192` remains defer pending complete release proof and explicit merge authorization; `#197` is rejected as redundant hard-coded provider catalog work; `#191` is rejected as generic extension inventory; `#189` was already ported in `79aa7b2`. Issue `#199` remains unresolved: the scaffold exists, but a real Ollama run changed the requested relative artifact path to `/outputs/...`, failed both write tools, and falsely replied `DONE`. Issues `#193/#190/#188/#187/#186/#182` remain covered by `#192`; `#185` is implemented but unpublished; `#196` remains Pi TUI ownership; `#198/#184` remain outside the reusable AI-researcher product bar. +- Fixed: Model overrides now resolve slash and colon candidates against Pi's registry and forward the canonical `provider/model-id` form, preserving model IDs such as `qwen3:0.6b`. The package manifest now includes four TypeScript source modules imported by source-loaded packaged extensions, preventing installed-package extension load failures. +- Verified: Focused model/runtime tests passed (`53/53`); final full `npm test` passed (`597/597`); typecheck, build, architecture check, and `git diff --check` passed with existing warnings. Final pack dry-run and real pack contain `406` entries; the tarball is `71,011,267` bytes with SHA-256 `b45e3d94cc55cd6104ae9c3b96ad4f17a5f5bb164c69feb62b995476a8aa4038`. A clean installed-tarball smoke passed version/help, confirmed all four source modules, loaded the Pi extensions, canonicalized `ollama:qwen3:0.6b`, reached Ollama as `provider=ollama` and `model=qwen3:0.6b`, and failed only with the expected missing-model `404`. +- Blocked: Root release audit still has Pi-shrinkwrapped `brace-expansion@5.0.6` and `protobufjs@7.6.4`; a fresh consumer install also resolves vulnerable `@hono/node-server@1.19.14` through MCP SDK `1.29.0`. Package-level overrides do not propagate, and Pi `0.81.1` does not clear all findings. +- Persistence: Local-only at `1ab61217`; no commit, push, merge, close, comment, release, or other GitHub write was made. Next: fix and verify `#199` with a tool-capable model, resolve or explicitly accept the release-audit blockers, then review `#192` before any merge or publish. + +### 2026-07-24 00:10 EDT — intake-sweep-issue199-validation + +- Objective: Refresh the live intake queue and release state, challenge issue `#199` with clean local-model probes, and revalidate the unchanged `0.3.6` candidate without disturbing inherited worktree changes. +- Checked: The open issue and PR sets are unchanged. PR decisions remain `#192` defer, `#197` reject, `#191` reject, and `#189` port complete in `79aa7b2`; no contributor branch contains a fresh research-loop port target. The latest `main` workflow run `28835967900` only passed `version-check`, while verify, native, npm publish, and GitHub release jobs were skipped; the last real publication remains run `28343027426` for `v0.3.5`. +- Issue `#199`: Workspace scaffolding and Pi's relative-path write behavior are present, but fresh isolated Ollama runs with `qwen3:4b` and `qwen3:0.6b` either remained in repetitive reasoning or timed out without tool execution or an artifact. Keep the issue open; local-model artifact reliability is not verified. +- Fixed: The local-model probes exposed a Feynman-owned `pi-otel` startup failure because the runtime can resolve either OpenTelemetry Resources 1.x or 2.x while the patch assumed one API. The patch now chooses `resourceFromAttributes` when available and falls back to `Resource`, repairs both previously patched forms, and has focused regression coverage. +- Freshness and audits: GitHub/npm latest remain `v0.3.5` / `0.3.5`; local is `0.3.6`; bundled Pi is `0.80.6` versus `0.81.1`. Root audit still reports Pi-shrinkwrapped `brace-expansion@5.0.6` and `protobufjs@7.6.4`; Pi `0.81.1` fixes only the first. A clean consumer install additionally resolves vulnerable `@hono/node-server@1.19.15` through MCP SDK `1.29.0`; package overrides do not propagate to consumers. Website audit is clean. +- Verified: Focused model/runtime tests passed (`53/53`), focused `pi-otel`/runtime tests passed (`21/21`), full tests passed (`598/598`), and root typecheck, build, architecture check, website lint/typecheck/build (`34` pages), and `git diff --check` passed with only existing build and split-debt warnings. Direct runtime probes initialized and shut down `pi-otel` against both OpenTelemetry API generations. Pack dry-run and real pack contain `406` entries at `71,044,856` bytes; a clean installed-tarball launch loaded all extensions without error, canonicalized a colon-bearing Ollama model id, reached Ollama with the exact model id, and failed only with the expected missing-model `404`. The real tarball SHA-256 is `9e17ec9a2f05a2b08b6ed34cda254bd2ab83174c95226e598608174f8e7ac474`. +- Persistence: The `pi-otel` compatibility patch, its focused test, and this lab-notebook entry are local-only and uncommitted. No push, merge, close, comment, release, or other GitHub write was made. Next: prove issue `#199` with a reliably tool-capable local model and resolve or explicitly accept consumer audit blockers before treating PR `#192` as release-ready. + +### 2026-07-24 03:50 EDT — intake-sweep-pi-082-deferred + +- Objective: Refresh the complete issue, PR, contributor-ref, workflow, release, package, and validation state while preserving the inherited `0.3.6` release-candidate worktree. +- Checked: Open issues remain `#199`, `#198`, `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; open PRs remain `#197`, `#192`, `#191`, and `#189`. No Feynman queue, branch, workflow, or release item changed after the prior sweep. PR decisions remain `#192` defer, `#189` port complete in `79aa7b2`, and `#191/#197` reject. +- Freshness: Pi `0.82.0` is newly published and its packed shrinkwrap updates `brace-expansion` to `5.0.7` and `protobufjs` to `7.6.5`, clearing Pi's two nested audit findings. The upgrade is not a safe pin-only change: Feynman's `AuthStorage`, `ModelRegistry.create(...)`, and `createAgentSession({ authStorage, modelRegistry })` integration must migrate to Pi's async `ModelRuntime` contract and all local runtime patches must be revalidated. +- Blocked: The current root audit still reports the two Pi `0.80.6` findings. A clean installed-Feynman consumer reports ten affected package nodes representing the two Pi advisories plus the MCP SDK / `@hono/node-server <2.0.5` path-traversal advisory; package overrides still do not propagate to consumers. Issue `#199` remains only partially covered by workspace scaffolding because reliable local-model tool execution and artifact creation are still unverified. +- Verified: Focused model, runtime, and `pi-otel` tests passed (`57/57`); full tests passed (`598/598`); root typecheck, build, architecture check, and `git diff --check` passed with existing warnings; website lint, typecheck, build (`34` pages), and production audit passed; package dry-run and real pack contain `406` entries at `71,044,856` bytes. The clean installed-tarball smoke passed `0.3.6` version/help, package inventory, required source modules, unknown-flag guidance, and packaged `pi-otel` compatibility markers; SHA-256 is `9e17ec9a2f05a2b08b6ed34cda254bd2ab83174c95226e598608174f8e7ac474`. +- Persistence: No product code, dependency, commit, branch, PR, release, or GitHub state changed in this sweep; only this lab-notebook entry was added. Next: migrate and validate Pi `0.82.0` as a dedicated runtime change, then reconcile the remaining local `0.3.6` work into PR `#192` before any merge or release decision. + +### 2026-07-25 20:04 EDT — intake-sweep-runtime-freshness-audit + +- Objective: Refresh the issue, PR, contributor-ref, workflow, release, package, and validation state for the local `0.3.6` candidate while preserving the inherited dirty release worktree and keeping GitHub read-only. +- Queue: Open issues are `#198`, `#196`, `#193`, `#190`, `#188`, `#187`, `#186`, `#185`, `#184`, and `#182`; `#199` is closed after the reporter attributed the missing artifacts to an Ollama context window of `4096` and reported success at `65536`. Open PR decisions remain `#192` defer, `#189` port complete in `79aa7b2`, and `#191/#197` reject. No issue or PR changed after the automation cutoff, and contributor branches/forks exposed no new safe research-loop port target. +- Fixed: Website production audit newly reported three high findings. Added website-only overrides for `brace-expansion@5.0.8` and `postcss@8.5.23`, refreshed `website/package-lock.json`, and returned the website production audit to zero findings without touching inherited product changes. +- Freshness: A clean runtime rebuild picked up `pi-web-access@0.14.0` and `pi-subagents@0.37.0`; the shipped archive still uses Pi `0.80.6`, `pi-btw@0.4.1`, `pi-docparser@3.0.1`, `pi-otel@0.1.0`, and `typebox@1.1.38`. Pi `0.82.1` remains a coordinated `ModelRuntime` migration rather than a safe pin-only update because Feynman still uses the removed `AuthStorage`, synchronous `ModelRegistry.create(...)`, and legacy `createAgentSession` service inputs. +- Release truth: GitHub/npm latest remain `v0.3.5` / `0.3.5`; local is `0.3.6`. Main run `28835967900` is green only for `version-check`, with verify, native bundle, npm publish, and GitHub release jobs skipped; the last actual publication remains run `28343027426`. +- Verified: Fresh `pi-web-access@0.14.0` passed `201/201` upstream tests, typecheck, and production audit; focused Feynman runtime/model/package tests passed `97/97`; full `npm test` passed `598/598`; root typecheck, build, architecture check, website lint/typecheck/build, website production audit, and `git diff --check` passed. Root production audit remains blocked by Pi-shrinkwrapped `brace-expansion@5.0.6` (high) and `protobufjs@7.6.4` (moderate). A fresh installed-tarball consumer audit reports `10` affected nodes: the same Pi advisories plus the MCP SDK / `@hono/node-server <2.0.5` path, with no compatible consumer fix for that chain. Package dry-run and real pack contain `406` entries at `72,176,110` bytes; the real tarball SHA-256 is `4786f4eb92339c1395e5f1e1ed7082d670f1c8a8892cac7d47a3e9c8d71138bd`. +- Installed-tarball proof: A clean install returned `0.3.6`, rendered help and package inventory, extracted Pi `0.80.6`, `pi-web-access@0.14.0`, and `pi-subagents@0.37.0`, loaded Feynman's research tools plus `pi-web-access` and `pi-otel` with zero extension errors, registered `source_check`, preserved `ollama:qwen3:0.6b` canonicalization, and initialized/shut down the patched `pi-otel` SDK. +- Persistence: Only the website audit override/lock refresh and this lab entry were added by this sweep; all other dirty files were inherited and preserved. No commit, push, merge, close, comment, release, or other GitHub write was made. Next: reconcile the local fixes into PR `#192`, migrate Pi deliberately, and resolve or explicitly accept the Pi shrinkwrap plus consumer MCP/Hono release-audit blockers before publish. + +### 2026-07-28 02:33 PDT — 0.3.6-windows-node25-archive-verifier + +- Objective: Finish PR `#192` at exact release-candidate SHA `8415be8eef305ecb0d564b025ec88bac47302329`, including clean Daytona proof, all supported-node consumers, merge, and `0.3.6` publication. +- Verified: A fresh Linux Daytona sandbox passed all `649` tests at `8415be8`, typecheck, build, architecture check, website lint/typecheck/build, all production audits, dry and real pack, clean installed-consumer/runtime audits, artifact verification, and installed RPC extension loading. Its 112,175,141-byte tarball matched the GitHub PR artifact byte-for-byte at SHA-256 `34ae1c9d053d724c6eadc9781beb2f865a2c372fe0255dd1fbe93a360a167f4c`. +- Failed: GitHub run `30344883546` exposed one exact Windows/Node `25.9.0` portability defect after otherwise successful install, version/help, package/search, and audits: `readArchiveEntry` delegated to the host `tar`, which failed to read `npm/package-lock.json` from the valid runtime archive. +- Fixed: Runtime archive entry reads now use Feynman's in-process gzip/tar parser instead of an external executable, with a regression that removes `PATH` before reading the deterministic archive. +- Verified: The repaired tree passed the focused regression (`8/8`), full `npm test` (`650/650`), typecheck, build, architecture check, root and website production audits, website lint/typecheck/build, package freshness review, and `git diff --check`. Dry and real pack were byte-identical at 111,577,262 bytes / 39,105 entries with SHA-256 `fc1d5913f2e3435e3377af883771aac2e8013f63259185dd7e54edb49002e4f9`; clean source/runtime/consumer audits, installed artifact verification, and installed Pi RPC loading (`112` commands, including `web-results`) passed. +- Verified: Exact `1433b387913b84e4f2281f3fc5dba2bfe6ef5cb4` passed the same full ladder in a fresh Daytona sandbox on Node `24.18.0`; its 112,175,500-byte tarball matched the GitHub PR artifact at SHA-256 `f1973a38b017cec3df023260bd7d14be9d1e438624cafd2c9ed0025b86cf8ee0`. Installed verification also passed on Node `25.9.0` with `PATH` empty. GitHub run `30347794537` passed every Linux/macOS/Windows Node consumer, including the original Windows artifact failure, but its native installer job exhausted the 60-minute budget during the second exact Windows PowerShell 5.1 extraction; `Expand-Archive` spent over 25 minutes on the 52,956-file candidate. +- Fixed: The public Windows installer now uses the supported .NET `System.IO.Compression.ZipFile.ExtractToDirectory` API instead of the pathologically slow `Expand-Archive` cmdlet, preserving the exact staging and transactional replacement boundary while making repeated Windows PowerShell 5.1/Core verification practical. +- Measured: Exact successor `b098c3809b9b148a4bea2829c16faa07bf464015` passed all six supported-node consumers, but the Windows PowerShell 5.1 verifier still spent over 30 minutes repeating the 530 MiB download for independent checksum and rollback cases. The verifier now uses the exact native candidate for clean-install and replacement proof in each PowerShell host, then runs the same checksum and rollback paths against a compact valid bundle. +- State: `verified` through the exact package/consumer matrix and Daytona ladder; exact successor-SHA Windows PowerShell 5.1/Core installer completion remains required before merge. Next: require the bounded Windows verifier and all CI jobs green, then merge and verify the GitHub/npm release. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e9101694..633fb080 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ If you need to change how bundled subagents behave, edit `.feynman/agents/*.md`. ## Before You Open a PR 1. Start from the latest `main`. -2. Use Node.js `24.x` for local development. The supported runtime range is Node.js `22.19.0` through `25.x`; `.nvmrc` pins the preferred local version while `package.json`, `website/package.json`, and the runtime version guard define the broader supported range. The optional session-search package remains limited to Node.js `22.x` because its sqlite dependency does not reliably install on newer Node majors. +2. Use Node.js `24.x` for local development. The supported runtime range is Node.js `22.22.0` through `25.x`; `.nvmrc` pins the preferred local version while `package.json`, `website/package.json`, and the runtime version guard define the broader supported range. The optional session-search package remains limited to Node.js `22.x` because its sqlite dependency does not reliably install on newer Node majors. 3. Install dependencies from the repo root: ```bash diff --git a/README.md b/README.md index 7d0209ff..1a4bd3b9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ irm https://feynman.is/install.ps1 | iex The one-line installer fetches the latest tagged release. To pin a version, pass it explicitly, for example `curl -fsSL https://feynman.is/install | bash -s -- 0.2.35`. -The installer downloads a standalone native bundle with its own Node.js runtime. +The installer downloads a standalone native bundle with its own pinned Node.js runtime and verifies the release SHA-256 before replacing an existing installation. To upgrade the standalone app later, rerun the installer. `feynman update` only refreshes installed Pi packages inside Feynman's environment; it does not replace the standalone runtime bundle itself. @@ -169,6 +169,7 @@ Ask naturally or use slash commands as shortcuts. | `/autoresearch ` | Bounded experiment loop with benchmark evidence | | `/watch ` | Research watch baseline with optional scheduled follow-up | | `/btw ` | Side conversation while the main research agent is busy, with optional handoff back into the main thread | +| `/thinking [level]` | View or set model reasoning effort (`off` through `max`, model permitting) without leaving the REPL | | `/outputs` | Browse all research artifacts | --- diff --git a/RELEASES.md b/RELEASES.md index ac4bd182..8eb4a331 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,9 +6,32 @@ GitHub release notes are generated from the matching `## vX.Y.Z` section in this ## Unreleased +## v0.3.6 - 2026-07-28 + +- Raised the npm-install Node 22 floor to `22.22.0`, matching the direct telemetry runtime's actual engine contract; standalone installers continue to bundle Node `24.18.0`. + +### Reliability + +- Fixed alphaXiv login after its OAuth migration by shipping the current OAuth2 endpoints and validating the loopback callback state before exchanging authorization codes. `feynman alpha status` now refreshes expired credentials and verifies them against the live user-info endpoint instead of treating any cached token as logged in. +- Fixed Windows one-line installs by extracting release archives into temporary staging before replacing the installed bundle. +- Fixed workbench state switching between newly minted local organizations when concurrent processes read `active-org.json` during a rewrite. Valid manifests are no longer rewritten, and required writes are atomic. +- Option+Enter now inserts a newline in Feynman's REPL input. Shift+Enter preserves Pi's follow-up action in terminals that report modified Enter keys, Ctrl+J remains a portable newline alternative, and existing user-modified keybindings remain untouched. +- Added `/thinking [level]` so reasoning effort is discoverable and directly adjustable inside the REPL while Shift+Tab remains available. The picker follows the active model's supported levels, including `max` where Pi exposes it. +- `fetch_content` now writes extracted PDF scratch Markdown under the active project's `.feynman/cache/fetch-content` instead of `~/Downloads`. Set `FEYNMAN_FETCH_CACHE_DIR` to override the location. +- Unknown CLI flags now point to `feynman help`, and `feynman update` help clarifies that extensions update with their packages rather than through a separate `--extensions` flag. + ### Package Stack - Added `pi-btw` to Feynman's default Pi package stack so `/btw` side conversations are available during long-running research turns without requiring a separate package install. +- Updated `pi-subagents` to `0.37.2` so child runs that disable inherited project context follow Pi's current context-file contract, while reducing repeated TUI and skill-file scans. +- Updated `pi-web-access` to `0.15.0`, adding simultaneous all-provider search with partial-failure diagnostics, TinyFish search and extraction, and configurable OpenAI Responses-compatible search gateways. +- Refreshed the bundled Pi runtime packages from `0.80.3` to `0.82.1`, migrated Feynman's model/auth integration to Pi's asynchronous `ModelRuntime`, and kept the runtime fallback pins aligned with the installed package set. +- Repaired the current Pi and MCP production dependency advisories in the packaged runtime by replacing Pi's vulnerable nested `brace-expansion` copy with `5.0.8`, updating MCP SDK to `1.30.0`, and pinning its compatible Hono server dependency to `2.0.12`. The Pi repair can be removed after upstream updates its shrinkwrap; the Hono pin can be removed after MCP no longer permits the vulnerable v1 range. +- Pinned the bundled runtime's complete dependency graph in a committed lockfile, upgraded its coordinated OpenTelemetry train to `2.10.0`/`0.221.0`, and made pruning changes and archive digests invalidate stale runtime artifacts. Startup now verifies every package named by the bundled runtime manifest, so a stale Pi copy is restored even when it is not itself a user-configured extension. +- Runtime and standalone archives now bind relative build inputs and the complete patched tree, reject stale or transplanted manifests, normalize archive metadata, and omit macOS AppleDouble metadata that previously doubled package size. +- Added pre-merge Linux package/consumer plus Windows PowerShell installer replacement gates. Release publication now promotes the exact verified tarball only after native bundles pass. +- Added explicit release-package budgets of 125 MiB compressed, 360 MiB unpacked, and 42,000 files around the current bundled research runtime so accidental package growth fails before publication. +- Pinned release executors and the bundled Node `24.18.0` archives, added Linux arm64 release builds, and made every standalone installer verify the published `SHA256SUMS` entry before replacing a working installation. ### Science Workbench diff --git a/bin/feynman.js b/bin/feynman.js index 76202f74..efccd734 100755 --- a/bin/feynman.js +++ b/bin/feynman.js @@ -2,7 +2,7 @@ import { resolve } from "node:path"; import { pathToFileURL } from "node:url"; -const MIN_NODE_VERSION = "22.19.0"; +const MIN_NODE_VERSION = "22.22.0"; const MAX_NODE_MAJOR = 25; const PREFERRED_NODE_MAJOR = 24; diff --git a/extensions/research-tools.ts b/extensions/research-tools.ts index 41cc4894..36d3e054 100644 --- a/extensions/research-tools.ts +++ b/extensions/research-tools.ts @@ -11,6 +11,7 @@ import { registerInitCommand, registerOutputsCommand } from "./research-tools/pr import { registerServiceTierControls } from "./research-tools/service-tier.js"; import { registerScienceDatabaseTools } from "./research-tools/science-databases.js"; import { registerModelEndpointTools } from "./research-tools/model-endpoints.js"; +import { registerThinkingCommand } from "./research-tools/thinking.js"; import { registerWorkbenchConnectorTools } from "./research-tools/workbench-connectors.js"; import { registerWorkbenchContextTool } from "./research-tools/workbench-context.js"; @@ -33,6 +34,7 @@ export default function researchTools(pi: ExtensionAPI): void { registerServiceTierControls(pi); registerScienceDatabaseTools(pi); registerModelEndpointTools(pi); + registerThinkingCommand(pi); registerWorkbenchConnectorTools(pi); registerWorkbenchContextTool(pi); } diff --git a/extensions/research-tools/discovery.ts b/extensions/research-tools/discovery.ts index 5fa27917..34ba63b0 100644 --- a/extensions/research-tools/discovery.ts +++ b/extensions/research-tools/discovery.ts @@ -149,6 +149,7 @@ export function registerDiscoveryCommands(pi: ExtensionAPI): void { "/tools — inspect callable tools", "/hotkeys — view keyboard shortcuts", "/service-tier — set request tier for supported providers", + "/thinking — view or set the active model thinking level", "--- Installed Packages ---", ...packages.map((pkg) => pkg), ]; diff --git a/extensions/research-tools/thinking.ts b/extensions/research-tools/thinking.ts new file mode 100644 index 00000000..2033f368 --- /dev/null +++ b/extensions/research-tools/thinking.ts @@ -0,0 +1,67 @@ +import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; +import type { ThinkingLevel } from "@earendil-works/pi-agent-core"; +import { getSupportedThinkingLevels } from "@earendil-works/pi-ai"; + +const THINKING_LEVELS = [ + "off", + "minimal", + "low", + "medium", + "high", + "xhigh", + "max", +] as const satisfies readonly ThinkingLevel[]; + +const THINKING_LEVEL_SET = new Set(THINKING_LEVELS); + +function normalizeThinkingLevel(value: string): ThinkingLevel | undefined { + const normalized = value.trim().toLowerCase(); + return THINKING_LEVEL_SET.has(normalized) ? (normalized as ThinkingLevel) : undefined; +} + +export function registerThinkingCommand(pi: ExtensionAPI): void { + pi.registerCommand("thinking", { + description: "View or set the active model thinking level.", + getArgumentCompletions: (prefix) => { + const normalizedPrefix = prefix.trim().toLowerCase(); + return THINKING_LEVELS + .filter((level) => level.startsWith(normalizedPrefix)) + .map((level) => ({ value: level, label: level })); + }, + handler: async (args, ctx) => { + const requested = normalizeThinkingLevel(args); + if (args.trim() && !requested) { + ctx.ui.notify("Use off, minimal, low, medium, high, xhigh, or max.", "error"); + return; + } + + let selected = requested; + if (!selected && ctx.hasUI) { + const current = pi.getThinkingLevel(); + const availableLevels = ctx.model + ? getSupportedThinkingLevels(ctx.model) + : [...THINKING_LEVELS]; + const choice = await ctx.ui.select( + `Thinking level (current: ${current})`, + availableLevels.map((level) => level === current ? `${level} (current)` : level), + ); + if (!choice) return; + selected = normalizeThinkingLevel(choice.replace(/ \(current\)$/, "")); + } + + if (!selected) { + ctx.ui.notify(`Thinking level: ${pi.getThinkingLevel()}`, "info"); + return; + } + + pi.setThinkingLevel(selected); + const active = pi.getThinkingLevel(); + ctx.ui.notify( + active === selected + ? `Thinking level set to ${active}.` + : `Thinking level set to ${active} (clamped from ${selected} for the active model).`, + "info", + ); + }, + }); +} diff --git a/metadata/commands.mjs b/metadata/commands.mjs index 975c38d3..bad8adc2 100644 --- a/metadata/commands.mjs +++ b/metadata/commands.mjs @@ -42,6 +42,7 @@ export const extensionCommandSpecs = [ { name: "init", args: "", section: "Project & Session", description: "Bootstrap AGENTS.md and session-log folders for a research project.", publicDocs: true }, { name: "outputs", args: "", section: "Project & Session", description: "Browse all research artifacts (papers, outputs, experiments, notes).", publicDocs: true }, { name: "service-tier", args: "", section: "Project & Session", description: "View or set the provider service tier override for supported models.", publicDocs: true }, + { name: "thinking", args: "[level]", section: "Project & Session", description: "View or set the active model thinking level.", publicDocs: true }, { name: "tools", args: "", section: "Project & Session", description: "Browse public research tools with their source and parameter summary.", publicDocs: true }, ]; @@ -149,7 +150,7 @@ export const cliCommandSections = [ { usage: "feynman search status", description: "Show Pi web-access status and config path." }, { usage: "feynman search set [api-key]", description: "Set the web search provider and optionally save its API key." }, { usage: "feynman search clear", description: "Reset web search provider to auto while preserving API keys." }, - { usage: "feynman update [package]", description: "Update installed packages, or a specific package." }, + { usage: "feynman update [package]", description: "Update installed packages, or one package. Extensions update with their packages; there is no separate --extensions flag." }, ], }, ]; @@ -161,7 +162,7 @@ export const legacyFlags = [ { usage: "--alpha-status", description: "Show alphaXiv auth status and exit." }, { usage: "--model ", description: "Force a specific non-Pro model." }, { usage: "--service-tier ", description: "Override request service tier for this run." }, - { usage: "--thinking ", description: "Set thinking level: off | minimal | low | medium | high | xhigh." }, + { usage: "--thinking ", description: "Set thinking level: off | minimal | low | medium | high | xhigh | max." }, { usage: "--cwd ", description: "Set the working directory for tools." }, { usage: "--session-dir ", description: "Set the session storage directory." }, { usage: "--new-session", description: "Start a new persisted session." }, diff --git a/package-lock.json b/package-lock.json index 35081e10..62403ef5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,41 +1,46 @@ { "name": "@companion-ai/feynman", - "version": "0.3.5", + "version": "0.3.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@companion-ai/feynman", - "version": "0.3.5", + "version": "0.3.6", + "bundleDependencies": [ + "@companion-ai/alpha-hub", + "@earendil-works/pi-agent-core", + "@earendil-works/pi-ai", + "@earendil-works/pi-coding-agent", + "@earendil-works/pi-tui" + ], "hasInstallScript": true, "license": "MIT", "dependencies": { "@clack/prompts": "^1.5.1", "@companion-ai/alpha-hub": "^0.1.3", - "@earendil-works/pi-agent-core": "0.80.3", - "@earendil-works/pi-ai": "0.80.3", - "@earendil-works/pi-coding-agent": "0.80.3", - "@earendil-works/pi-tui": "0.80.3", + "@earendil-works/pi-agent-core": "0.82.1", + "@earendil-works/pi-ai": "0.82.1", + "@earendil-works/pi-coding-agent": "0.82.1", + "@earendil-works/pi-tui": "0.82.1", "@nightingale-elements/nightingale-msa": "^5.6.0", "@opentelemetry/api": "^1.9.1", - "@opentelemetry/api-logs": "^0.219.0", - "@opentelemetry/exporter-logs-otlp-http": "^0.219.0", - "@opentelemetry/exporter-trace-otlp-proto": "^0.219.0", - "@opentelemetry/resources": "^2.8.0", - "@opentelemetry/sdk-logs": "^0.219.0", - "@opentelemetry/sdk-trace-base": "^2.8.0", - "@opentelemetry/sdk-trace-node": "^2.8.0", + "@opentelemetry/api-logs": "^0.221.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.221.0", + "@opentelemetry/exporter-trace-otlp-proto": "^0.221.0", + "@opentelemetry/resources": "^2.10.0", + "@opentelemetry/sdk-logs": "^0.221.0", + "@opentelemetry/sdk-trace-base": "^2.10.0", + "@opentelemetry/sdk-trace-node": "^2.10.0", "@opentelemetry/semantic-conventions": "^1.41.1", "@rdkit/rdkit": "^2025.3.4-1.0.0", "@sinclair/typebox": "^0.34.49", "3dmol": "^2.5.5", + "brace-expansion": "5.0.8", "d3": "^7.9.0", "fast-xml-parser": "5.7.3", "igv": "^3.8.4", "jszip": "^3.10.1", - "ketcher-core": "^3.15.0", - "ketcher-react": "^3.15.0", - "ketcher-standalone": "^3.15.0", "npyjs": "^1.1.0", "patristic": "^0.5.7", "pdfjs-dist": "^6.1.200", @@ -52,22 +57,27 @@ "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.3", + "ketcher-core": "3.15.0", + "ketcher-react": "3.15.0", + "ketcher-standalone": "3.15.0", "lucide-react": "^1.23.0", "radix-ui": "^1.6.1", "react": "^19.2.7", "react-dom": "^19.2.7", "tsx": "^4.22.4", "typescript": "^6.0.3", - "vite": "^8.1.3" + "vite": "^8.1.3", + "yaml": "2.9.0" }, "engines": { - "node": ">=22.19.0 <26" + "node": ">=22.22.0 <26" } }, "node_modules/@anthropic-ai/sdk": { "version": "0.91.1", "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.91.1.tgz", "integrity": "sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==", + "inBundle": true, "license": "MIT", "dependencies": { "json-schema-to-ts": "^3.1.1" @@ -88,6 +98,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", @@ -103,6 +114,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", @@ -117,6 +129,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -126,6 +139,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.222.0", @@ -137,6 +151,7 @@ "version": "3.1048.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1048.0.tgz", "integrity": "sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -159,17 +174,18 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.974.25", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.25.tgz", - "integrity": "sha512-fJFkx6u6wCqGMV/v6EAxiwa2UzEukbvr1hNPv4MrD3yj4IFz011jZg42/eSTOP/u5kJ0tlILqEjCWtT8GiKZvA==", + "version": "3.977.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.977.1.tgz", + "integrity": "sha512-KVtQRtc00ES/y+Sc3vYXeP6pCIcNlBJCZOwvqSy8ZpVGmbM5+IG+AfhuTKQ2oXmIVqZJewaGMMpzPkywC6xg0w==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.14", - "@aws-sdk/xml-builder": "^3.972.32", - "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/core": "^3.28.0", - "@smithy/signature-v4": "^5.6.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/types": "^3.974.2", + "@aws-sdk/xml-builder": "^3.972.37", + "@aws/lambda-invoke-store": "^0.3.0", + "@smithy/core": "^3.29.8", + "@smithy/signature-v4": "^5.6.9", + "@smithy/types": "^4.16.1", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -178,15 +194,16 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.51", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.51.tgz", - "integrity": "sha512-Xo+/zf5k5pZdo53X8aVXN4MJGfU/M1P7yMM/GbNY/x9fyRZGEzjhKqW38GA0FSQQ9TYKs+bfPyz5ja4bi6pjTQ==", + "version": "3.972.61", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.61.tgz", + "integrity": "sha512-qihs2ekMb89Nxd2JenCgVFhjbkb3EIo7HEBCBzyZACKVJdrLUZBLOmAE3xr0Sayml8n/jZSzwO/IufIiIzO7PQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -194,17 +211,18 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.53", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.53.tgz", - "integrity": "sha512-7E9oFUcf9YWe+ttGiWhe/cCSI+pswwelzgQMoKXgPJi1AIfS27TK6et5ZULqEqHu30zbN+jh1RqlwcXqY/aXyg==", + "version": "3.972.63", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.63.tgz", + "integrity": "sha512-yfozsS8wkWZEi/n6IsrodcFKBWZ0iNAezhJbTReMNc0z1Px17qdeAeuL1/wziCAmCZyXiW7QzP75ggJkBQv8jQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/fetch-http-handler": "^5.6.1", - "@smithy/node-http-handler": "^4.9.1", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/fetch-http-handler": "^5.6.10", + "@smithy/node-http-handler": "^4.9.10", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -212,13 +230,14 @@ } }, "node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.1.tgz", - "integrity": "sha512-m/f15di58P6NtLQ7eVEb5N19NdJWn+4c7zfkFHMT/i3JH7U8UtknpPoy8o2tm2R3OdliYvsvQhZHIfACQDqT+Q==", + "version": "4.9.11", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.11.tgz", + "integrity": "sha512-slbzbz8taEOzoXv/9y34YNBoE+ZHmddLykCgjDAjvMAsu2nM5s2Gzwa5OGF721tD8s+CKeFUBds5lSj9lcbuDg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@smithy/core": "^3.30.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -226,23 +245,24 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.58", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.58.tgz", - "integrity": "sha512-MPr0hD8pyDGfF3dWXvFOILhcKTB9ptqJOJK9JEuDQzpc2HgKisY16eR7IrKUXxSbz8LZj+LHz/CS8Y5G1ai7yw==", + "version": "3.973.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.6.tgz", + "integrity": "sha512-jGLTW1bj148GL/6/IMlfY2fMYS9FtHOG+NahkFD4y0qkzYudNUahelxryY68/HGMslYuHClk1XaS/3b3eJzEkg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/credential-provider-env": "^3.972.51", - "@aws-sdk/credential-provider-http": "^3.972.53", - "@aws-sdk/credential-provider-login": "^3.972.57", - "@aws-sdk/credential-provider-process": "^3.972.51", - "@aws-sdk/credential-provider-sso": "^3.972.57", - "@aws-sdk/credential-provider-web-identity": "^3.972.57", - "@aws-sdk/nested-clients": "^3.997.25", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/credential-provider-imds": "^4.4.4", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/credential-provider-env": "^3.972.61", + "@aws-sdk/credential-provider-http": "^3.972.63", + "@aws-sdk/credential-provider-login": "^3.972.68", + "@aws-sdk/credential-provider-process": "^3.972.61", + "@aws-sdk/credential-provider-sso": "^3.973.5", + "@aws-sdk/credential-provider-web-identity": "^3.972.67", + "@aws-sdk/nested-clients": "^3.997.35", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/credential-provider-imds": "^4.4.13", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -250,16 +270,17 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.57", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.57.tgz", - "integrity": "sha512-kPWc/SCrl9agKeywxKwPEoQHanWag0LcNQrcZpEQpjNifkxq6tQENhgrrS9al317CF6yytyihlX+FhPHlk0QjA==", + "version": "3.972.68", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.68.tgz", + "integrity": "sha512-w6tNci6g7RqFpLhj1f5xseBvaNojb4Pkgp5Jp5apl9hrJtaf2AA+rX9+qlhlWUK6kcyAFYPA7emO+55zj+S98Q==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/nested-clients": "^3.997.25", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/nested-clients": "^3.997.35", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -267,21 +288,22 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.60", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.60.tgz", - "integrity": "sha512-hE2hIBJQjCDRx8TbSqpVQ+/o2mIrJZQZbQ3LlwE2bJf7z47x5GmhcvGwZPqJH7Oq//SzTXEBGSZ4qSpK3yPbhw==", + "version": "3.972.72", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.72.tgz", + "integrity": "sha512-blQ7F5QGzylnzeh5549zQLoCAiMHkXFLjFovEMaVy4b2X8JhUu+u9NXro1hyK95YHdVFNmBHKs2hIHtZchxKlQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.51", - "@aws-sdk/credential-provider-http": "^3.972.53", - "@aws-sdk/credential-provider-ini": "^3.972.58", - "@aws-sdk/credential-provider-process": "^3.972.51", - "@aws-sdk/credential-provider-sso": "^3.972.57", - "@aws-sdk/credential-provider-web-identity": "^3.972.57", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/credential-provider-imds": "^4.4.4", - "@smithy/types": "^4.15.0", + "@aws-sdk/credential-provider-env": "^3.972.61", + "@aws-sdk/credential-provider-http": "^3.972.63", + "@aws-sdk/credential-provider-ini": "^3.973.6", + "@aws-sdk/credential-provider-process": "^3.972.61", + "@aws-sdk/credential-provider-sso": "^3.973.5", + "@aws-sdk/credential-provider-web-identity": "^3.972.67", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/credential-provider-imds": "^4.4.13", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -289,15 +311,16 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.51", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.51.tgz", - "integrity": "sha512-081dD2RlnmY+G05v6E73KfACvDjPjnttrLjGHE2SSglbID25UcuijbWpL4g+XR5T2Kl4oIJoVBXi64s+2f009Q==", + "version": "3.972.61", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.61.tgz", + "integrity": "sha512-xzRuj+fUVO4nkafKQJVKAF97kGpeQbfjuwmRrtGZNf42/1dkmcz6o7dswBy7alY0htQn5sCL1GWQYEykviWZkA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -305,17 +328,18 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.57", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.57.tgz", - "integrity": "sha512-dC7ZyX3EHKHLOeVUEDzzGvk0L1s6N06YDrau7P0rGXL/j1cO+DzN2w1x9vcEh7zljVCR3019f5mi1Th+GGTURw==", + "version": "3.973.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.5.tgz", + "integrity": "sha512-fZRjjWhLFelsDoOYjqShQTrIGYC3Pf9Mx9Czf+1ikfQDgktxjze33dVo1q1/ZQ+T0qbtejVoHNHrfD5aJVpv/w==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/nested-clients": "^3.997.25", - "@aws-sdk/token-providers": "3.1077.0", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/nested-clients": "^3.997.35", + "@aws-sdk/token-providers": "3.1095.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -323,16 +347,17 @@ } }, "node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers": { - "version": "3.1077.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1077.0.tgz", - "integrity": "sha512-sRUkfZ3fpOco95jZHsQUQiXvuIVLvCmWVclFg6dRFDyfsYs6Pdr/NuZ2+yJxeHN+6WAfDh2aZ8nlZntnvuhZUQ==", + "version": "3.1095.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1095.0.tgz", + "integrity": "sha512-65SudS6y4nzaYHybtqcpm3sHe5jLhdMn68HRKS1nUx690BtQeaAQOoujQ+dpOjBATIVGVgKKjEP8tR+U06QJQA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/nested-clients": "^3.997.25", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/nested-clients": "^3.997.35", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -340,16 +365,17 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.57", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.57.tgz", - "integrity": "sha512-HtWM3FV2o7NJFJSUqFLBlxmV9RxQRHpzCvQaP1n1Qo4CxQSvwpJ8ERWHiLqXMFDgDXyELt+EZNFcpG6XQRcJbQ==", + "version": "3.972.67", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.67.tgz", + "integrity": "sha512-FTNZ05gkPBA6CKbU3N4zPgybV+stdazwMOya75CmGdcJL7p8Fw/BdHP8WVxJd0mvzyPK2cg/C3gli58Ir4HgCw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/nested-clients": "^3.997.25", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/nested-clients": "^3.997.35", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -357,14 +383,15 @@ } }, "node_modules/@aws-sdk/eventstream-handler-node": { - "version": "3.972.24", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.24.tgz", - "integrity": "sha512-O2tFBFQnP68GRNahxYJYZ4NVlGZ/hBe2oH58EKPPjbf7Yc04ZhKFdzAMblRrzeGdun9pBwE+CyLjFH/tr4pYNw==", + "version": "3.972.30", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.30.tgz", + "integrity": "sha512-hJboPgIpq5+ADc++/B9TBqn65CXV21cZLGB8V5RBQbxkZ/rQ6qMfcxTnW/SvQlasX4jhaSG8B1wsVjhQyDrsnQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -372,14 +399,15 @@ } }, "node_modules/@aws-sdk/middleware-eventstream": { - "version": "3.972.20", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.20.tgz", - "integrity": "sha512-VAI4wBVWOg5h1pZVmSEKe8kAW/7odKfbzO9uB23e1AICQh2pp/ROUhFacDXmwgJZZt49dIF6nEvzPTvHiO1cUA==", + "version": "3.972.25", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.25.tgz", + "integrity": "sha512-9SFbPzJDHHR5k6Q6KvXVas/veUm/TzNcNTFM2UhdXHZHpyIvI2lS+s4cxljw1BihGpVhsAkQDo/2nW7dHxpf4Q==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -387,17 +415,18 @@ } }, "node_modules/@aws-sdk/middleware-websocket": { - "version": "3.972.33", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.33.tgz", - "integrity": "sha512-e24VZXVZjpfVxpQ4ghf4LYV/i/x0znERdVcSzPU0+ktjmnd0k1fdPlcYsImDqIDaLZilbbwMLhuQY8d/dBzrGA==", + "version": "3.972.43", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.43.tgz", + "integrity": "sha512-n29++15Vma64Kd0enp9Bo8a6LTm8TvUoMbJEwqXtIksv0oEs+SUCRMm3gozDfPD1Ly0k/sSBughxarlLlRF6Xw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/fetch-http-handler": "^5.6.1", - "@smithy/signature-v4": "^5.6.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/fetch-http-handler": "^5.6.10", + "@smithy/signature-v4": "^5.6.9", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -405,18 +434,19 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.997.25", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.25.tgz", - "integrity": "sha512-VpRQ3wR6l+fwRHV5veJL2ehtyQFrGyH/2CJG9DVtb8H3xyqqnZWSTSrq/CJJ7DvDlDgrPRiW2SkYA8pN6VWCFQ==", + "version": "3.997.35", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.35.tgz", + "integrity": "sha512-2MJfseVG/aXvIyOIBlYA/Oaf6qFDdsu4D8RKsEUdOQpVuLaor0BdxIBBtJLBNQQEe6Ku3YMvLljwb1MwVUpzRw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.974.25", - "@aws-sdk/signature-v4-multi-region": "^3.996.37", - "@aws-sdk/types": "^3.973.14", - "@smithy/core": "^3.28.0", - "@smithy/fetch-http-handler": "^5.6.1", - "@smithy/node-http-handler": "^4.9.1", - "@smithy/types": "^4.15.0", + "@aws-sdk/core": "^3.977.0", + "@aws-sdk/signature-v4-multi-region": "^3.996.42", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.29.8", + "@smithy/fetch-http-handler": "^5.6.10", + "@smithy/node-http-handler": "^4.9.10", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -424,13 +454,14 @@ } }, "node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.1.tgz", - "integrity": "sha512-m/f15di58P6NtLQ7eVEb5N19NdJWn+4c7zfkFHMT/i3JH7U8UtknpPoy8o2tm2R3OdliYvsvQhZHIfACQDqT+Q==", + "version": "4.9.11", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.11.tgz", + "integrity": "sha512-slbzbz8taEOzoXv/9y34YNBoE+ZHmddLykCgjDAjvMAsu2nM5s2Gzwa5OGF721tD8s+CKeFUBds5lSj9lcbuDg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@smithy/core": "^3.30.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -438,14 +469,15 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.996.37", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.37.tgz", - "integrity": "sha512-u8qd064XsHzM0Mk+yH4IPKn/ZC9rdniEKs+neBHNlsPZirw3rcLvmrH4ImoKC4yF7A0I/MbcC3dseARnJLiAhg==", + "version": "3.996.42", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.42.tgz", + "integrity": "sha512-DBV4naZP6HYBlAvPpoQzOP12Wvfou/5rN8yJPXjBTBylU5qwCbh/tXr2MddHoIjgoRkEl/eS+IljiUqvmwey1Q==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.14", - "@smithy/signature-v4": "^5.6.0", - "@smithy/types": "^4.15.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/signature-v4": "^5.6.9", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -456,6 +488,7 @@ "version": "3.1048.0", "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1048.0.tgz", "integrity": "sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -470,12 +503,13 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.973.14", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.14.tgz", - "integrity": "sha512-vH4pEu9YBEwr67yT+GVcmKX0GzfIrIYUn+MF5vXg9OspouVnAekuyVyawFvZHEK7WlcwVDwNrqI3ZBDUAiyu9A==", + "version": "3.974.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.2.tgz", + "integrity": "sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.15.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -486,6 +520,7 @@ "version": "3.965.8", "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.8.tgz", "integrity": "sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -495,12 +530,13 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.32", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.32.tgz", - "integrity": "sha512-2loKuOMRFDg1nwdni5AtJ9S5juVbRNPNsPC7tWTfkHyycPwACMhxepspUHi8GhvfNlL2cQo3sPMod1uib+KZ0w==", + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.37.tgz", + "integrity": "sha512-zKq4HQum8JwDyEuyfuI4bbiAcU0KxP6qy+9PR/IsR92IyE/DaBAikzAS50tjxip4bqIIANpCcG+Yyj6CVhXupg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.15.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -508,9 +544,10 @@ } }, "node_modules/@aws/lambda-invoke-store": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", - "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz", + "integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=18.0.0" @@ -520,6 +557,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", @@ -534,6 +572,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.29.7", @@ -550,6 +589,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -559,6 +599,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.29.7", @@ -572,6 +613,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -581,6 +623,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -590,6 +633,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.29.7" @@ -605,6 +649,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -614,6 +659,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", @@ -628,6 +674,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", @@ -646,6 +693,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.29.7", @@ -687,6 +735,7 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@companion-ai/alpha-hub/-/alpha-hub-0.1.3.tgz", "integrity": "sha512-g/JoqeGDCoSvkgs1ZSTYJhbTak0zVanQyoYOvf2tDgfqJ09gfkqmSGFDmiP4PkTn1bocPqywZIABgmv25x1uYA==", + "inBundle": true, "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.27.1", @@ -703,12 +752,14 @@ } }, "node_modules/@earendil-works/pi-agent-core": { - "version": "0.80.3", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.80.3.tgz", - "integrity": "sha512-3qw0/GeRQBU/nlGjDe5Yb7ePKTmoxefx2YxyKMFAviFUMXpFexBG/hS7mBtwFahFvzrrTPPoRT6sFIDjwoDWPQ==", + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.82.1.tgz", + "integrity": "sha512-Z3kloziJIE2dmrisRckZX8zDca/gIv9/YdFAzeoqpHiLV2wsni6bL4hInNSjVKLbqT+4kqLIkph2JQLKvSepjg==", + "inBundle": true, "license": "MIT", "dependencies": { - "@earendil-works/pi-ai": "^0.80.3", + "@earendil-works/pi-ai": "^0.82.1", + "diff": "8.0.4", "ignore": "7.0.5", "typebox": "1.1.38", "yaml": "2.9.0" @@ -718,9 +769,10 @@ } }, "node_modules/@earendil-works/pi-ai": { - "version": "0.80.3", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.3.tgz", - "integrity": "sha512-jPZLMeGL5kkMSEAwAklfXTMHqZvfhsJtCCpKGIr5Duk7mc0n4skjB1dugk7y0z3z8ZHIUCmPAWHdyDqgUz5vdA==", + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.82.1.tgz", + "integrity": "sha512-3WFYRhEp3lQB3444EhPMBcM7zSaEUE3eJgHOR7s4081NLqbw/FsWilIKWXSua0Gv3sRr7m9xMidR3pPDE7jI/A==", + "inBundle": true, "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "0.91.1", @@ -746,21 +798,23 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=8.0.0" } }, "node_modules/@earendil-works/pi-coding-agent": { - "version": "0.80.3", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.80.3.tgz", - "integrity": "sha512-TIggw9gCXpA+Ph7OjdTA7ka2NPwTVuPmy39KDSyUzaKq8VvHfMGR7vtRz4JB7Um/RMRblmzhu4p9tUCk6MTgGA==", + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.82.1.tgz", + "integrity": "sha512-zbkAhoIuDPMF3pKuja0ajZabrMWU29FUMV9A/XMXT/XC1yXs5xt6t6t13GogQFsDrDqbFP4DkZQO1w8rWRAzYA==", "hasShrinkwrap": true, + "inBundle": true, "license": "MIT", "dependencies": { - "@earendil-works/pi-agent-core": "^0.80.3", - "@earendil-works/pi-ai": "^0.80.3", - "@earendil-works/pi-tui": "^0.80.3", + "@earendil-works/pi-agent-core": "^0.82.1", + "@earendil-works/pi-ai": "^0.82.1", + "@earendil-works/pi-tui": "^0.82.1", "@silvia-odwyer/photon-node": "0.3.4", "chalk": "5.6.2", "cross-spawn": "7.0.6", @@ -791,6 +845,7 @@ "version": "0.91.1", "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.91.1.tgz", "integrity": "sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==", + "inBundle": true, "license": "MIT", "dependencies": { "json-schema-to-ts": "^3.1.1" @@ -811,6 +866,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", @@ -825,6 +881,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", @@ -840,6 +897,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", @@ -854,6 +912,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -863,6 +922,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.222.0", @@ -874,6 +934,7 @@ "version": "3.1048.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1048.0.tgz", "integrity": "sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -899,6 +960,7 @@ "version": "3.974.11", "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.11.tgz", "integrity": "sha512-QpnINq5FZH6EOaDEkmHdT7eUunbvD27pDNQypaWjFyYz7Zl1q3UCMQErBZxpmfGfI7MvI2TlK8KTkgNpv8b1ug==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.8", @@ -918,6 +980,7 @@ "version": "3.972.37", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.37.tgz", "integrity": "sha512-/jpPvEh6f7ntmIzf7dNxoNX6Q8vt8UpesCjbW6mFfk4V1NW6bIy9qxcQ6WbA8As5yQhsZOe+xeNd4xHX8kdY2Q==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -934,6 +997,7 @@ "version": "3.972.39", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.39.tgz", "integrity": "sha512-pIgTpisWyWg7X1bUbzSjuUYosYTD0Ghz2M0hkSTmb3a6i3qV3uU+NYJPI/E2XSC0HcsZh5rsLPzeXrkb2DS0Cg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -952,6 +1016,7 @@ "version": "3.972.41", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.41.tgz", "integrity": "sha512-u2tyjaxJJzW8UtW4SM1ZcPMDwO6y+kV+llvou+Adts0FAKyzes5jG4izQN+KX3yE8ZROpS5y1LJ//xL2iSf76w==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -976,6 +1041,7 @@ "version": "3.972.41", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.41.tgz", "integrity": "sha512-0LBitxXiAiaE5nlFPfpNIww/8FRY/I7WIndWsc9GmNFOM7cE1wNpVNQEGEk9Outg5l8xl+3vybxFyUy4l9q/LQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -993,6 +1059,7 @@ "version": "3.972.42", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.42.tgz", "integrity": "sha512-D4oon2zbqqsWOJUM99Gm3/ZyJ0IJvTXVN3PyloGb3kQEyI36fjCZheZj422lAgTWWd6TSHgiImLt3RIaLdv3dQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.37", @@ -1015,6 +1082,7 @@ "version": "3.972.37", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.37.tgz", "integrity": "sha512-7nVaHBUaWIddASYfVaA9O4D5ZVjewU3sCol9WqZPGfW0nR+0WqE0xHZnD/U2L33PlOB8KNXGKZ6wOES/QijKzg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -1031,6 +1099,7 @@ "version": "3.972.41", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.41.tgz", "integrity": "sha512-IOWAWEHe5LkjSKkkUUX9ciV6Y1scHTsnfEkdt5yyC4Slrc7AGbkLPrpntjqh18ksJAMOaVhoBsO8p2WyTcY2wQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -1049,6 +1118,7 @@ "version": "3.972.41", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.41.tgz", "integrity": "sha512-mbACk9Yypa8nm4iGZLs0PofOXEcTDOUw6wDnsPXNDNSd2WNXs1tSo+6nc/fh0jLYdfVZThhBL98PHW4aXFsG5A==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -1066,6 +1136,7 @@ "version": "3.972.16", "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.16.tgz", "integrity": "sha512-yedpPgKftqjU5SlPFHfqWpOw6xSCRieWRG1euWOlXn4WJxt2VX92VprCa2PpSOXjVCAeK6dTjW9eJRXVig9yGA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.8", @@ -1081,6 +1152,7 @@ "version": "3.972.12", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.12.tgz", "integrity": "sha512-tHTHHCHNrq6XklQvlzHBDJG4Iuhh7NVPRdtmvP+nHFA+5sxPlIDzlAHHgfoYHGvT3NXP1yVP/L5c3opUn6T3Qg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.8", @@ -1096,6 +1168,7 @@ "version": "3.972.19", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.19.tgz", "integrity": "sha512-mkEhOGYozqKQkbFaVrjwr0faiwwZza1v5/jSY6Tucm3bD+uKTazIUH/4Yo6aMnQD2ua2W9cMP6s8mvwTcjtqHw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -1114,6 +1187,7 @@ "version": "3.997.9", "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.9.tgz", "integrity": "sha512-jPR3rnmRI4hWYyzfmTGBr7NblMp8QYYeflHXba1H6+7CGrWVqWKQzaXFQ4qbExqPRsXN3T3L3JxFhr6aouXUGQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -1135,6 +1209,7 @@ "version": "3.996.27", "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.27.tgz", "integrity": "sha512-0Phbz4t6HI3D3skxvG2uI+VWU034/nSIw1T8d+FPzzQG9EQTrw94o9mOKO2Gv3n3Oc8P7JD7RAUxkoneLWv5Eg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.8", @@ -1151,6 +1226,7 @@ "version": "3.1048.0", "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1048.0.tgz", "integrity": "sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.11", @@ -1168,6 +1244,7 @@ "version": "3.973.8", "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.14.1", @@ -1181,6 +1258,7 @@ "version": "3.965.5", "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -1193,6 +1271,7 @@ "version": "3.972.24", "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.24.tgz", "integrity": "sha512-V8z5YcDPfsvzrBlj0xR1vhRtocblhYbqdreCJB/voGd4Sr5zjNAeWxexbnqVtskTJe0vFb5KMqbSL++ePl+zRw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@nodable/entities": "2.1.0", @@ -1208,6 +1287,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=18.0.0" @@ -1217,17 +1297,20 @@ "version": "7.29.2", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-agent-core": { - "version": "0.80.3", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.80.3.tgz", + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.82.1.tgz", + "inBundle": true, "license": "MIT", "dependencies": { - "@earendil-works/pi-ai": "^0.80.3", + "@earendil-works/pi-ai": "^0.82.1", + "diff": "8.0.4", "ignore": "7.0.5", "typebox": "1.1.38", "yaml": "2.9.0" @@ -1237,8 +1320,9 @@ } }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-ai": { - "version": "0.80.3", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.3.tgz", + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.82.1.tgz", + "inBundle": true, "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "0.91.1", @@ -1254,15 +1338,16 @@ "typebox": "1.1.38" }, "bin": { - "pi-ai": "./dist/cli.js" + "pi-ai": "dist/cli.js" }, "engines": { "node": ">=22.19.0" } }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui": { - "version": "0.80.3", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.80.3.tgz", + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.82.1.tgz", + "inBundle": true, "license": "MIT", "dependencies": { "get-east-asian-width": "1.6.0", @@ -1277,6 +1362,7 @@ "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.52.0.tgz", "integrity": "sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==", "hasInstallScript": true, + "inBundle": true, "license": "Apache-2.0", "dependencies": { "google-auth-library": "^10.3.0", @@ -1300,6 +1386,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@mariozechner/clipboard/-/clipboard-0.3.9.tgz", "integrity": "sha512-ABnA53mdfkGZwOFUdZNv2S0CWGO/EIuPj8Vv9xmBFmSYg/qFc7ihO6q5FcQjvoE67kZpWkEc4AhD6B/os04yuA==", + "inBundle": true, "license": "MIT", "optional": true, "engines": { @@ -1325,6 +1412,7 @@ "cpu": [ "arm64" ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1338,6 +1426,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-universal/-/clipboard-darwin-universal-0.3.9.tgz", "integrity": "sha512-BGGR4iA9Z2shAjI65eI5xtyb3LYNlDW9X3gxKxDbqtbnREohsrqznov6zpKoIrsRWpzlYVEdKphS7ksJ0/ndSQ==", + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1354,6 +1443,7 @@ "cpu": [ "x64" ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1370,9 +1460,7 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1389,9 +1477,7 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1408,9 +1494,7 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1427,9 +1511,7 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1446,9 +1528,7 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1465,6 +1545,7 @@ "cpu": [ "arm64" ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1481,6 +1562,7 @@ "cpu": [ "x64" ], + "inBundle": true, "license": "MIT", "optional": true, "os": [ @@ -1494,6 +1576,7 @@ "version": "2.2.6", "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.6.tgz", "integrity": "sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.40.0", @@ -1520,12 +1603,14 @@ "url": "https://github.com/sponsors/nodable" } ], + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@opentelemetry/api": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=8.0.0" @@ -1535,6 +1620,7 @@ "version": "1.41.1", "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz", "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=14" @@ -1544,30 +1630,35 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/codegen": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/eventemitter": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/fetch": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "inBundle": true, "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1" @@ -1577,36 +1668,42 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/utf8": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@silvia-odwyer/photon-node": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/@silvia-odwyer/photon-node/-/photon-node-0.3.4.tgz", "integrity": "sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==", + "inBundle": true, "license": "Apache-2.0" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/core": { "version": "3.24.3", "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.3.tgz", "integrity": "sha512-Ep/7tPamGY8mgESE3LyLKtxJyy6U52WWAqr/3wial47Sj4u3PiIF73AOGI27UyLy9duTkhZbgzodOfLV4TduZg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", @@ -1621,6 +1718,7 @@ "version": "4.3.3", "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.3.tgz", "integrity": "sha512-I2Bti0DKFo2IJyN28ijCsx51BAumEYR4/1yZ1FXyBygy9MqbnMqCev4JPth/MbpRfBSRAX35hITSnAdJRo1u5w==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.24.3", @@ -1635,6 +1733,7 @@ "version": "5.4.3", "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.3.tgz", "integrity": "sha512-F+DRf8IJazRJgYog2A/yJK7eYVc0rqTlRzO+5ZxjJd4WkZoKz0IJRncf7G6t1pdVT3kryJcwuTFhN1c5m6N47A==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.24.3", @@ -1649,6 +1748,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -1661,6 +1761,7 @@ "version": "4.7.3", "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.3.tgz", "integrity": "sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.24.3", @@ -1675,6 +1776,7 @@ "version": "5.4.3", "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.3.tgz", "integrity": "sha512-53+75QuPl6DL+ct6vVEB51FDO5oulXr20TPV46VvJZg76lIlXNWfxi8j+G2V/t0I2qxCBOa3vX/8bmjrpFVo9g==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.24.3", @@ -1689,6 +1791,7 @@ "version": "4.14.2", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.2.tgz", "integrity": "sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -1701,6 +1804,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", @@ -1714,6 +1818,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", @@ -1727,6 +1832,7 @@ "version": "22.19.19", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "inBundle": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -1736,6 +1842,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 14" @@ -1745,6 +1852,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "inBundle": true, "license": "MIT", "engines": { "node": "18 || 20 || >=22" @@ -1768,12 +1876,14 @@ "url": "https://feross.org/support" } ], + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/bignumber.js": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "inBundle": true, "license": "MIT", "engines": { "node": "*" @@ -1783,30 +1893,34 @@ "version": "2.14.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + "inBundle": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/@earendil-works/pi-coding-agent/node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "inBundle": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -1819,6 +1933,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "inBundle": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -1833,6 +1948,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 12" @@ -1842,6 +1958,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "inBundle": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1859,6 +1976,7 @@ "version": "8.0.4", "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "inBundle": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -1868,6 +1986,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -1877,6 +1996,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/fast-xml-builder": { @@ -1889,6 +2009,7 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], + "inBundle": true, "license": "MIT", "dependencies": { "path-expression-matcher": "^1.5.0", @@ -1905,6 +2026,7 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], + "inBundle": true, "license": "MIT", "dependencies": { "@nodable/entities": "^2.1.0", @@ -1930,6 +2052,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "inBundle": true, "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", @@ -1943,6 +2066,7 @@ "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "inBundle": true, "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" @@ -1955,6 +2079,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -1969,6 +2094,7 @@ "version": "8.1.2", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "gaxios": "^7.0.0", @@ -1983,6 +2109,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=18" @@ -1995,6 +2122,7 @@ "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { "minimatch": "^10.2.2", @@ -2012,6 +2140,7 @@ "version": "10.6.2", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz", "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -2029,6 +2158,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=14" @@ -2038,12 +2168,14 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "inBundle": true, "license": "ISC" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "inBundle": true, "license": "BSD-3-Clause", "engines": { "node": "*" @@ -2053,6 +2185,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", + "inBundle": true, "license": "ISC", "dependencies": { "lru-cache": "^11.1.0" @@ -2065,6 +2198,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "inBundle": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.0", @@ -2078,6 +2212,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "inBundle": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -2091,6 +2226,7 @@ "version": "7.0.5", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 4" @@ -2100,12 +2236,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "inBundle": true, "license": "ISC" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/jiti": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "inBundle": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -2115,6 +2253,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "inBundle": true, "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" @@ -2124,6 +2263,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", + "inBundle": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", @@ -2137,6 +2277,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "inBundle": true, "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", @@ -2148,6 +2289,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "inBundle": true, "license": "MIT", "dependencies": { "jwa": "^2.0.1", @@ -2158,12 +2300,14 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "inBundle": true, "license": "Apache-2.0" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/lru-cache": { "version": "11.4.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.4.0.tgz", "integrity": "sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==", + "inBundle": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" @@ -2173,6 +2317,7 @@ "version": "18.0.5", "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.5.tgz", "integrity": "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==", + "inBundle": true, "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -2185,6 +2330,7 @@ "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.5" @@ -2200,6 +2346,7 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "inBundle": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" @@ -2209,6 +2356,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/node-domexception": { @@ -2226,6 +2374,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "inBundle": true, "license": "MIT", "engines": { "node": ">=10.5.0" @@ -2235,6 +2384,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "inBundle": true, "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", @@ -2253,6 +2403,7 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz", "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==", + "inBundle": true, "license": "Apache-2.0", "bin": { "openai": "bin/cli" @@ -2274,6 +2425,7 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "inBundle": true, "license": "MIT", "dependencies": { "@types/retry": "0.12.0", @@ -2287,12 +2439,14 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/partial-json": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz", "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==", + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/path-expression-matcher": { @@ -2305,6 +2459,7 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], + "inBundle": true, "license": "MIT", "engines": { "node": ">=14.0.0" @@ -2314,6 +2469,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=8" @@ -2323,6 +2479,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", @@ -2339,6 +2496,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "inBundle": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -2350,16 +2508,18 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/@earendil-works/pi-coding-agent/node_modules/protobufjs": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.4.tgz", - "integrity": "sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==", + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", "hasInstallScript": true, + "inBundle": true, "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -2382,6 +2542,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 4" @@ -2405,12 +2566,14 @@ "url": "https://feross.org/support" } ], + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/semver": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "inBundle": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -2423,6 +2586,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "inBundle": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -2435,6 +2599,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=8" @@ -2444,6 +2609,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "inBundle": true, "license": "ISC" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/strnum": { @@ -2456,30 +2622,35 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/ts-algebra": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "inBundle": true, "license": "0BSD" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/typebox": { "version": "1.1.38", "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz", "integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==", + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/undici": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz", "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=22.19.0" @@ -2489,12 +2660,14 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "inBundle": true, "license": "MIT" }, "node_modules/@earendil-works/pi-coding-agent/node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 8" @@ -2504,6 +2677,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "inBundle": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -2519,6 +2693,7 @@ "version": "8.21.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -2546,6 +2721,7 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], + "inBundle": true, "license": "MIT", "engines": { "node": ">=16.0.0" @@ -2555,6 +2731,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "inBundle": true, "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -2570,6 +2747,7 @@ "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "inBundle": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -2579,15 +2757,17 @@ "version": "3.25.2", "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "inBundle": true, "license": "ISC", "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "node_modules/@earendil-works/pi-tui": { - "version": "0.80.3", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.80.3.tgz", - "integrity": "sha512-2BJI6qwRQfnM0Q7seL1+SbacU/jRRjBnN7Hu3n9BjAn7/s5FaBNnvdD1qBQYRsFTHfjqMaDsjYqanPyqwXj99w==", + "version": "0.82.1", + "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.82.1.tgz", + "integrity": "sha512-9yN8hALfKaxZq7n54EMxqhFCWnMi6LHkraMJ/1YjHiATq75XrI6XDMVppn9EDtiK7Fks8hUe1SDXUTrIvwRWfQ==", + "inBundle": true, "license": "MIT", "dependencies": { "get-east-asian-width": "1.6.0", @@ -2635,6 +2815,7 @@ "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.16.7", @@ -2654,6 +2835,7 @@ "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "dev": true, "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0", @@ -2667,12 +2849,14 @@ "version": "0.9.2", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "dev": true, "license": "MIT" }, "node_modules/@emotion/is-prop-valid": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", + "dev": true, "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0" @@ -2682,12 +2866,14 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "dev": true, "license": "MIT" }, "node_modules/@emotion/react": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", @@ -2712,6 +2898,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "dev": true, "license": "MIT", "dependencies": { "@emotion/hash": "^0.9.2", @@ -2725,12 +2912,14 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "dev": true, "license": "MIT" }, "node_modules/@emotion/styled": { "version": "11.14.1", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", @@ -2754,12 +2943,14 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "dev": true, "license": "MIT" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "dev": true, "license": "MIT", "peerDependencies": { "react": ">=16.8.0" @@ -2769,12 +2960,14 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "dev": true, "license": "MIT" }, "node_modules/@emotion/weak-memoize": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "dev": true, "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { @@ -3223,6 +3416,7 @@ "version": "1.7.5", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "dev": true, "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.11" @@ -3232,6 +3426,7 @@ "version": "1.7.6", "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "dev": true, "license": "MIT", "dependencies": { "@floating-ui/core": "^1.7.5", @@ -3242,6 +3437,7 @@ "version": "0.27.19", "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.19.tgz", "integrity": "sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog==", + "dev": true, "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.1.8", @@ -3257,6 +3453,7 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "dev": true, "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.7.6" @@ -3270,6 +3467,7 @@ "version": "0.2.11", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "dev": true, "license": "MIT" }, "node_modules/@google/genai": { @@ -3277,6 +3475,7 @@ "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.52.0.tgz", "integrity": "sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==", "hasInstallScript": true, + "inBundle": true, "license": "Apache-2.0", "dependencies": { "google-auth-library": "^10.3.0", @@ -3296,13 +3495,38 @@ } } }, + "node_modules/@google/genai/node_modules/protobufjs": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", + "hasInstallScript": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.0.12.tgz", + "integrity": "sha512-eWpQYr67tqJLeaSUl0Q+TquuYfUdTibpOJlUMV2FfUP7+KqCC5TufnwnlXL6mobZBJbGAYRd7ZvEBDCbLInjhg==", + "inBundle": true, "license": "MIT", "engines": { - "node": ">=18.14.1" + "node": ">=20" }, "peerDependencies": { "hono": "^4" @@ -3312,6 +3536,7 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -3322,6 +3547,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -3331,12 +3557,14 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3347,6 +3575,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.40.0.tgz", "integrity": "sha512-FWyAKwbGbmwLbG6biyxB/MQkELzcbd6E89Xufarbx/1VZ2pX/BMaeVD4J7ojHgIZ4omTNI6nKH26K4wWySCIGQ==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/html": "0.40.0", @@ -3360,6 +3589,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/code/-/code-0.40.0.tgz", "integrity": "sha512-xbo3lW3OC7sz0UnoME0tXQcgnekmuvsGAb1HZpFHAF0ZUCquB6/yK0+9QzknrTBH9y3Urqx0vM54xAqNQISOtg==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/utils": "0.40.0", @@ -3371,6 +3601,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.40.0.tgz", "integrity": "sha512-qOlN4CYXHkdVxAzrZ1Cdu7bAYf1se+R3y7MfjWa6WFFukf7n6+RAoNIWTzpTLM7h7fOrsJLyP0Goi5IZI9wAOQ==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/html": "0.40.0", @@ -3389,6 +3620,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.40.0.tgz", "integrity": "sha512-QWBZw89CAkw2b3Fl942DxJ7M8/XxFFvVubw9Z7Ac6wgUkGgtF2wrK9F0H8cPZ3pzbUqL1v1EtwW1/XhlLfmQqw==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/extension": "0.40.0", @@ -3399,6 +3631,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/extension/-/extension-0.40.0.tgz", "integrity": "sha512-kipdm0f+xe8ctxHt9S3NPZazMX3ILqIk5xMWxX2svdsRc7qIeMkl+5SLWnBqQA+e5ztLJqa7GSA4WMqu/dBZDQ==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/utils": "0.40.0", @@ -3410,6 +3643,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.40.0.tgz", "integrity": "sha512-k4PKWa8xyMHnnh+ewUboeFr8wKemk1GoMZ6LKN4qnqNKGCHANyJKeHRVUzyLjbiSwcXTrBqtUTV4ZrJXGRIkEw==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/text": "0.40.0", @@ -3421,6 +3655,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.40.0.tgz", "integrity": "sha512-Jo/9Z1fPlv+IpBkUaVstyKminXWjM1A1yR9UPZv4a3B3e8Rn0gqa+EaY5CXSvscnmh2EHSD8I4s59D4rirUy8Q==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/extension": "0.40.0", @@ -3432,6 +3667,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.40.0.tgz", "integrity": "sha512-5EZeHbp9Q3Op2KRoVfFvX4QyMizYW5SJkrWkGG6h6g/Z9EDNjb3C7Wjqx7ZosCHcFze6Pgic/0yEaCc2fSUcEg==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/selection": "0.40.0", @@ -3443,6 +3679,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.40.0.tgz", "integrity": "sha512-4EVMJQ6tKJR+1+YAJ2mhVsRR6Edk6b81hWKjnMZITKhEOKjylxO7bwuXYVYPEckBzL2mXkEhYX5aFnig5+HkMQ==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/extension": "0.40.0", @@ -3454,6 +3691,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.40.0.tgz", "integrity": "sha512-YHStiN56DOc6tDu/3LwalPtHH8/1R+peiDF+/ePpla9aSDJclAqhxRBYsqSZhO6Hu5QhAEIi2Me7Gi+uZdmCTw==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/extension": "0.40.0", @@ -3466,6 +3704,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.40.0.tgz", "integrity": "sha512-9XJ0PQmeq5tDSgathAQs1ePMM5zaCBCbD4ShMXJf3fW1udI7e/Swn0Loxw9/VnER9fnVkyejGMC2oMWDQ80FVw==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/utils": "0.40.0", @@ -3476,6 +3715,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.40.0.tgz", "integrity": "sha512-J0vO4jSPZaazBgFafJhLYaJPBxSMk1nhGnNiu6+TojqOe3tx/0vukCafowNxBDruZFns+r7HsSs+vkmGJtGsrA==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/code": "0.40.0", @@ -3491,6 +3731,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/offset/-/offset-0.40.0.tgz", "integrity": "sha512-USytxiqB/mU6tKy2nXs4jhgCES90l8N5lCYxVbho2L/cVXAzBCp1epG///B6Vgm+twSj+jQjhGZioktILnG+FQ==", + "dev": true, "license": "MIT", "dependencies": { "lexical": "0.40.0" @@ -3500,6 +3741,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.40.0.tgz", "integrity": "sha512-T1LE8R7LloV9t8m+5IQ7Djkqcbd4mOoX85Jh8cKQ58TFHbkwi8nSe+FJUi3fucOI2atDq9QZCJnpRUCHw4eEwQ==", + "dev": true, "license": "MIT", "dependencies": { "lexical": "0.40.0" @@ -3509,6 +3751,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.40.0.tgz", "integrity": "sha512-mr6J1Fu34MwUNOPkzn3l/fZBpD91HLAxs6RBAQ6mfSW7jLXBVDlvhiB4ez9ud/jZ0bgLaY8EG7ooT7htdlkBUQ==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/clipboard": "0.40.0", @@ -3522,6 +3765,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/react/-/react-0.40.0.tgz", "integrity": "sha512-+J73I21LNT659f1IMTbxe055mKnt4H2SkHp3UDxrmWmkWmDaPcq7XG07i8/xCPtYz15aEXUQycqaWQc5pAqF5g==", + "dev": true, "license": "MIT", "dependencies": { "@floating-ui/react": "^0.27.16", @@ -3553,6 +3797,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.40.0.tgz", "integrity": "sha512-aHW9gSYGzEfZNxx14j2xJhihrnKaWA1aoudteP4r7TkNlbfJ3xG9dxp7ItwrAKJlfvI0gkMc1/aZOUIqESbAkw==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/clipboard": "0.40.0", @@ -3566,6 +3811,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.40.0.tgz", "integrity": "sha512-iFwZufMlIx9fZ+K3NQip9oxoHzuP+V9rVdkLnfUWC7aO4HNxVPSryEfUnbAs+F5xlOzyVHsu7Xa+CMHfIL8/gQ==", + "dev": true, "license": "MIT", "dependencies": { "lexical": "0.40.0" @@ -3575,6 +3821,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.40.0.tgz", "integrity": "sha512-pn5T7Uc80dH8LR2d/sepKc8SjiKKir40AF+5hW0MJAOYfoizd10x72AxPcM6iBYvI0rdW7rD7Lhko1qLmZ0pOw==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/clipboard": "0.40.0", @@ -3587,6 +3834,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/text/-/text-0.40.0.tgz", "integrity": "sha512-cTMBrHPzlIRQUkopIUhPwSzcqQDGsCEdjpStylJficwMav9vG+/sJNSG4PFO+4ss5BZ/x7AoM3KH/P2SOzqdbw==", + "dev": true, "license": "MIT", "dependencies": { "lexical": "0.40.0" @@ -3596,6 +3844,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.40.0.tgz", "integrity": "sha512-3wkzgQxeb137GtaGWZI23XYB+omGjfYlrvAPJOqcb5z8yS7iAiuHwWULdmi1/jPBClS7z9N8pkNzq06BP8QlZA==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/selection": "0.40.0", @@ -3606,6 +3855,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.40.0.tgz", "integrity": "sha512-wpasbrlfzBnHhyuUunxZcGwOH+bqfxUuavGgwxDlTTlHJMnyF5bUG7ADcuqd3gFLB+dpABL0lWo6VxdSOo7fdg==", + "dev": true, "license": "MIT", "dependencies": { "@lexical/offset": "0.40.0", @@ -3635,6 +3885,7 @@ "version": "2.2.6", "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.6.tgz", "integrity": "sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.40.0", @@ -3652,12 +3903,13 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz", - "integrity": "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", + "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", + "inBundle": true, "license": "MIT", "dependencies": { - "@hono/node-server": "^1.19.9", + "@hono/node-server": "^1.19.9 || ^2.0.5", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", @@ -3695,6 +3947,7 @@ "version": "5.18.0", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz", "integrity": "sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -3705,6 +3958,7 @@ "version": "5.18.0", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz", "integrity": "sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.9", @@ -3750,6 +4004,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3759,6 +4014,7 @@ "version": "5.17.1", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.17.1.tgz", "integrity": "sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.9", @@ -3786,6 +4042,7 @@ "version": "5.18.0", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz", "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.9", @@ -3819,6 +4076,7 @@ "version": "5.18.0", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz", "integrity": "sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.9", @@ -3859,6 +4117,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3868,6 +4127,7 @@ "version": "7.2.24", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -3882,6 +4142,7 @@ "version": "5.17.1", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.17.1.tgz", "integrity": "sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.9", @@ -3912,6 +4173,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4236,15 +4498,16 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=8.0.0" } }, "node_modules/@opentelemetry/api-logs": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.219.0.tgz", - "integrity": "sha512-FFx7YnaYJlIjqWW/AG/yAZ0L/NEY724PipXXXQLdtZPbLwBGbUMTGL1i/esI56TWfTUXxhLfpgrnWJCG8aUJyg==", + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.221.0.tgz", + "integrity": "sha512-OlanaW1vv7ufTqQ3/fPLI4arGt5ZoM+P8abOMki6uEYnpRazepSWDwDnnw+la7kE26SHVC18//SMccrDvLKOXQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.3.0" @@ -4254,9 +4517,9 @@ } }, "node_modules/@opentelemetry/context-async-hooks": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.8.0.tgz", - "integrity": "sha512-/3FIraneMcng67SUJCxvyInk/oxzwsxyadufk0wwfOBLf5wqtAGX4MoQASwSbndBPeARzBryUM9Azr5kHIdWLw==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.10.0.tgz", + "integrity": "sha512-bvyMcgLEkozzSzpEEEo1OMoeQ97bxj6Qs2uN3mPrSdDvObMI1myffD/BPqcLlzZO9//d1SqQA/WPw7Cz2AiqhA==", "license": "Apache-2.0", "engines": { "node": "^18.19.0 || >=20.6.0" @@ -4266,9 +4529,9 @@ } }, "node_modules/@opentelemetry/core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.8.0.tgz", - "integrity": "sha512-hd1Lfh8p545nNz+jq1Ejfz+Mn1hyLuxYn1YzTfFNrxr8urEWMNQLPf1Th8kjOH+HxwawCrtgBp8JpBUR4ZSgww==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.10.0.tgz", + "integrity": "sha512-/wNZ8twnEQQA4HoHu22+vcsdru6pWPWxW+7w+FlxT6Id7PE/WIbZmVKkte+PF72e0F2dnImFeHD2syyE1Mw6MQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" @@ -4281,16 +4544,14 @@ } }, "node_modules/@opentelemetry/exporter-logs-otlp-http": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.219.0.tgz", - "integrity": "sha512-mhl2HL6GmZI8b8PwPfqMws/5ovJfbRTxwc9Y5agVVHiQ+e5SL1btsFr/kJDgt7YCexDtsUn5HAreHQO9szFS0A==", + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.221.0.tgz", + "integrity": "sha512-nKXkr4Tomi6fjYVOf+ytcW3dZAVr4v4Bv5gsT6dr2gvpUPJpKgHB4XbMufMsPotRE3g0XH2GwVVCkN2w6SON+Q==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api-logs": "0.219.0", - "@opentelemetry/core": "2.8.0", - "@opentelemetry/otlp-exporter-base": "0.219.0", - "@opentelemetry/otlp-transformer": "0.219.0", - "@opentelemetry/sdk-logs": "0.219.0" + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-logs": "0.221.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -4300,16 +4561,14 @@ } }, "node_modules/@opentelemetry/exporter-trace-otlp-proto": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.219.0.tgz", - "integrity": "sha512-lF/LUBfhOFmxJa+SQsLN7ziV4MHa2pyKgOM6JNehSOfU+npjM4gwm9oIKEJrzrWcexMcqydiyoFy0XCb1Ql3wQ==", + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.221.0.tgz", + "integrity": "sha512-Z9i2T7vgZbWe9rSLYxXVIbeW+XyzUq4rZanW3ZyVNwVDqCsh0EJKUgBWWQ0CZfeuUA+RQPzKgJQHMuWAUnKqXw==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/otlp-exporter-base": "0.219.0", - "@opentelemetry/otlp-transformer": "0.219.0", - "@opentelemetry/resources": "2.8.0", - "@opentelemetry/sdk-trace-base": "2.8.0" + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-trace": "2.10.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -4319,13 +4578,13 @@ } }, "node_modules/@opentelemetry/otlp-exporter-base": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.219.0.tgz", - "integrity": "sha512-zvIxQX/AZUVKDU+hCuYx+7UkiP7GRdnk1ZbFQRYzHvYp47cAWR4j3IhoPhV9KaeXEv2xdGq3IA6PnpzDmLcmSA==", + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.221.0.tgz", + "integrity": "sha512-UFPIq80OH3Ns/oPFHRj14d4DTOxUo+MUFU8hUiCq5jTqFhdeJnfVSANHT+xp92409cA+oxzvlZCe6NM1wvCuBA==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/otlp-transformer": "0.219.0" + "@opentelemetry/core": "2.10.0", + "@opentelemetry/otlp-transformer": "0.221.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -4335,17 +4594,17 @@ } }, "node_modules/@opentelemetry/otlp-transformer": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.219.0.tgz", - "integrity": "sha512-aaYKAyXhw9VchKZVGOopD3Gw/kPsyrX2c6IQ0AW32mTjqmZOh5Y6Gf5OYqTNqVktAeBjmFinhyFaCwW6GYK9YQ==", + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.221.0.tgz", + "integrity": "sha512-lg6lkOU08Az23jVcn/0Els9HP+V8PnR4Km6p0KgpTggS0n/WuhnmY64rSh83Of9iR9nD+dpWr6adlcX8KzAwjg==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api-logs": "0.219.0", - "@opentelemetry/core": "2.8.0", - "@opentelemetry/resources": "2.8.0", - "@opentelemetry/sdk-logs": "0.219.0", - "@opentelemetry/sdk-metrics": "2.8.0", - "@opentelemetry/sdk-trace-base": "2.8.0" + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-logs": "0.221.0", + "@opentelemetry/sdk-metrics": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -4355,12 +4614,12 @@ } }, "node_modules/@opentelemetry/resources": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.8.0.tgz", - "integrity": "sha512-qmXQ27ilDbUK/vGMqwL8D4/rhn76C+sherM4wTbjlfknR8Nvfc/hCxjRJPhkzZzUsPiNg16SA31NxMabwttRjg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.10.0.tgz", + "integrity": "sha512-q6MMm2zhggzsHVNbabYwut+a6nbuQQe3URUoxaojM/8K1IBfwwPzvxIjNi2/lI1TFe+fMHMW9MWhrtDLEXEnkA==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.8.0", + "@opentelemetry/core": "2.10.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { @@ -4371,14 +4630,14 @@ } }, "node_modules/@opentelemetry/sdk-logs": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.219.0.tgz", - "integrity": "sha512-s6lTKRakaPClvKoWHRChxnXjDMkM/TQ30ff78jN6EBGf7MI7VzANE5PU3f4z9qDUudWjvZjOLHG0rBnBKYvoXA==", + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.221.0.tgz", + "integrity": "sha512-FaDcazjyMp7TZZZAsqbo4IkovP0UegoCu0EBkiNt+qCqvUf7FPAsfcrZ3+ZEkKgXZ/jHafop+JoGPDk3A0SmLg==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api-logs": "0.219.0", - "@opentelemetry/core": "2.8.0", - "@opentelemetry/resources": "2.8.0", + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { @@ -4389,13 +4648,13 @@ } }, "node_modules/@opentelemetry/sdk-metrics": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.8.0.tgz", - "integrity": "sha512-UDBGaj6W0Rgy5rTTaoxs8gVGF/aGkAKyjurJv7se6wjRxJu7FoquTLT/vt54DZfo4crbprYfhX/SOK9+BPw1qg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.10.0.tgz", + "integrity": "sha512-t6r1VSvXNtSDnPXU1FbZeetJb7yyovHmgu0wRSoftxtE0g2rSNhQZQUy69sRUCL+iioJpX8SN/S6wq6ZtvLySQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/resources": "2.8.0" + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -4404,14 +4663,32 @@ "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, + "node_modules/@opentelemetry/sdk-trace": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.10.0.tgz", + "integrity": "sha512-MfQGq3GRmTh5fM/y+OjaO0vj6+luCB1XO2gfXCalKCfgKw0eHL++sm75DNweC6ohlp+aFvACqeE0fYayqdRaoQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, "node_modules/@opentelemetry/sdk-trace-base": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.8.0.tgz", - "integrity": "sha512-mhU4jp+vW0mGbFRd+GeXHvmfA4aDqWjBjLC3pE5XMpLs0IE2ryYb019Ts2AQrOq67gaTF25D91+fgvEHDZEnuQ==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.10.0.tgz", + "integrity": "sha512-GuYQQT7QD2EeO8lcZLRQzcbOyhqAzL+6WWTKTU9mSUBYBazkEDl+VrQcXQhbB08OWM9anD1aHleVadzulpOaUQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/resources": "2.8.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { @@ -4422,14 +4699,14 @@ } }, "node_modules/@opentelemetry/sdk-trace-node": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.8.0.tgz", - "integrity": "sha512-nZt9OGufioAc3AfoLTqA9bsAeaMJAictYDdI2VcNQ+PmT+3rfKjAZDZvgPfd8VPX0O5Bw1hdQF6kDK8VSpZiWg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.10.0.tgz", + "integrity": "sha512-GZK/G6oZyBLGlH1pUgeDch7D91KoHd2uotUGIkWCPi9GI5T9X0p4L7nNAMDR1BQjkRYoDqo+ddfVx9t5Uhys+Q==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/context-async-hooks": "2.8.0", - "@opentelemetry/core": "2.8.0", - "@opentelemetry/sdk-trace-base": "2.8.0" + "@opentelemetry/context-async-hooks": "2.10.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/sdk-trace-base": "2.10.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -4442,6 +4719,7 @@ "version": "1.41.1", "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz", "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=14" @@ -4461,6 +4739,7 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -4486,6 +4765,7 @@ "version": "1.14.3", "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.3.tgz", "integrity": "sha512-m0K3vnbSLC5rHs2ZVfeAMvBtT1zIyq4mxx5OlNncSgMj5Iz6W5Rn3kPrDxAC+iIKmiVe0lSl6U37t5ZkEWoVAw==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -4496,30 +4776,35 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "inBundle": true, "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1" @@ -4529,24 +4814,28 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", - "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/@radix-ui/number": { @@ -6405,12 +6694,13 @@ "license": "MIT" }, "node_modules/@smithy/core": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.28.0.tgz", - "integrity": "sha512-N/LoLG8pZ1zv5cIWpdF6vmSjtZtXKK9G0OqT5yYCOZU+CzPq1+nYA95VoKJBGWRScs7YbMugZ7lZx8Fj1vdHoA==", + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.30.0.tgz", + "integrity": "sha512-dl2yRglDxfzH9uJ4fSo4zTaAHa0zH7+V7BZMRWy8hEYIKT1BiqMUK/CN6T3ADQ3kbA5N1tmUulroJ2UtONS7Kw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.15.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -6418,13 +6708,14 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.4.tgz", - "integrity": "sha512-jT0WrDaM88L5na9FX1xRNywCS3B1n75wPY5Ksasjo0PHUtuI7d8FclksN1BbOSYTiaiKxUDqU23nUymH/V+AaQ==", + "version": "4.4.14", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.14.tgz", + "integrity": "sha512-QgbuahIb2qxQeZQvNK0sw3aF3JH5zwH8j2lLp5DUasVXexGGMWULAR+7z0omPXFolCP/m5wN9M5lm9EGdSviTQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@smithy/core": "^3.30.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -6432,13 +6723,14 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.1.tgz", - "integrity": "sha512-fW6l9rWoyk1iyzfuZaERnZLNjB6WIojgGm6Bo9Hpfpy3RUpltjLikNlxTsS/YtxVobcfbCGBuAncREYqT4hvqQ==", + "version": "5.6.11", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.11.tgz", + "integrity": "sha512-o0Zkj1nKqJAoq+a+BrkhU39tRftMNjLwpc/z06Frfl43wpbHrJMaSAVZE4vTqlxtVkNaGaT0bIDxOp7tkFTuQQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@smithy/core": "^3.30.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -6449,6 +6741,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6461,6 +6754,7 @@ "version": "4.7.3", "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.3.tgz", "integrity": "sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.24.3", @@ -6472,13 +6766,14 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.0.tgz", - "integrity": "sha512-IkPHQdbyoebSwBCuMTzJ/2oIhKVqiZZAZxQYSlpDZqq/WhJUpmdgbHvP7ItddxsPzcDUJeI0V4PNMSNtlZ0aqA==", + "version": "5.6.10", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.10.tgz", + "integrity": "sha512-EXhWePm3SXJAX38npIy4TXL2Aex/OVgCClTjelN2QHw/U+8CQUH8C7AaxsVzQcYieYPseywn48s89DmvuGjiAg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.28.0", - "@smithy/types": "^4.15.0", + "@smithy/core": "^3.30.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -6486,9 +6781,10 @@ } }, "node_modules/@smithy/types": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.15.0.tgz", - "integrity": "sha512-Z5TAOxygoFvybJV3igo5SloFflSokHx2hu1eFA+DxDTcn+FtKxUSui+rbTRG1pAafMA888Z3MVvCWUuvCrTXjg==", + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.16.1.tgz", + "integrity": "sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6501,6 +6797,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", @@ -6514,6 +6811,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", @@ -6538,6 +6836,7 @@ "version": "3.0.15", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^2" @@ -6547,6 +6846,7 @@ "version": "25.9.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz", "integrity": "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==", + "inBundle": true, "license": "MIT", "dependencies": { "undici-types": ">=7.24.0 <7.24.7" @@ -6556,18 +6856,21 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true, "license": "MIT" }, "node_modules/@types/prop-types": { "version": "15.7.15", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, "license": "MIT" }, "node_modules/@types/react": { "version": "19.2.17", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -6587,6 +6890,7 @@ "version": "4.4.12", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "*" @@ -6596,6 +6900,7 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "inBundle": true, "license": "MIT" }, "node_modules/@types/trusted-types": { @@ -6608,12 +6913,14 @@ "version": "2.0.11", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, "license": "MIT" }, "node_modules/@types/use-sync-external-store": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "dev": true, "license": "MIT" }, "node_modules/@vitejs/plugin-react": { @@ -6662,6 +6969,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "inBundle": true, "license": "MIT", "dependencies": { "mime-types": "^3.0.0", @@ -6675,6 +6983,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=0.8" @@ -6684,6 +6993,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 14" @@ -6693,6 +7003,7 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "inBundle": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -6709,6 +7020,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "inBundle": true, "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -6750,12 +7062,14 @@ "node_modules/asap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", - "integrity": "sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==" + "integrity": "sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==", + "dev": true }, "node_modules/assert": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.2", @@ -6769,6 +7083,7 @@ "version": "2.2.5", "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -6778,6 +7093,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -6793,6 +7109,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", @@ -6804,6 +7121,15 @@ "npm": ">=6" } }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -6822,32 +7148,35 @@ "url": "https://feross.org/support" } ], + "inBundle": true, "license": "MIT" }, "node_modules/bignumber.js": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "inBundle": true, "license": "MIT", "engines": { "node": "*" } }, "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "inBundle": true, "license": "MIT", "dependencies": { "bytes": "^3.1.2", - "content-type": "^1.0.5", + "content-type": "^2.0.0", "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" }, "engines": { "node": ">=18" @@ -6857,22 +7186,51 @@ "url": "https://opencollective.com/express" } }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/bowser": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "inBundle": true, "license": "MIT" }, + "node_modules/brace-expansion": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -6882,6 +7240,7 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -6900,6 +7259,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "inBundle": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -6913,6 +7273,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "inBundle": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -6929,6 +7290,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -6938,6 +7300,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -6948,6 +7311,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "dev": true, "license": "Apache-2.0", "dependencies": { "adler-32": "~1.3.0", @@ -6961,6 +7325,7 @@ "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "inBundle": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -6973,6 +7338,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -6983,6 +7349,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -6993,6 +7360,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -7003,6 +7371,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -7012,6 +7381,7 @@ "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=18" @@ -7021,6 +7391,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=18" @@ -7034,6 +7405,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -7043,12 +7415,14 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, "license": "MIT" }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -7058,6 +7432,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=6.6.0" @@ -7073,6 +7448,7 @@ "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "inBundle": true, "license": "MIT", "dependencies": { "object-assign": "^4", @@ -7090,6 +7466,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", @@ -7106,6 +7483,7 @@ "version": "1.10.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", + "dev": true, "license": "ISC", "engines": { "node": ">= 6" @@ -7115,6 +7493,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" @@ -7156,6 +7535,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "inBundle": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -7170,6 +7550,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, "license": "MIT" }, "node_modules/d3": { @@ -7598,6 +7979,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 12" @@ -7607,6 +7989,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "inBundle": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -7625,12 +8008,14 @@ "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", "integrity": "sha512-yVn6RZmHiGnxRKR9sJb3iVV2XTF1Ghh2DiWRZ3dMnGc43yUdWWF/kX6lQyk3+P84iprfWKU/8zFTrlkvtFm1ug==", "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, "license": "MIT" }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -7648,6 +8033,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", @@ -7674,6 +8060,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -7696,10 +8083,21 @@ "dev": true, "license": "MIT" }, + "node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.7", @@ -7710,6 +8108,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "inBundle": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -7724,6 +8123,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -7733,18 +8133,21 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "inBundle": true, "license": "MIT" }, "node_modules/element-closest-polyfill": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/element-closest-polyfill/-/element-closest-polyfill-1.0.7.tgz", "integrity": "sha512-SX7RrUUEybUllkGjVf5XJR5I0Fl2L0iawK/caX/yJu94xW/WoRRD8Fky65gKpvqhU9PLBKOliIy4Ly2rDRzdUQ==", + "dev": true, "license": "ISC" }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -7754,6 +8157,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -7763,6 +8167,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -7772,6 +8177,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -7781,6 +8187,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "inBundle": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -7835,12 +8242,14 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "inBundle": true, "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -7853,6 +8262,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -7861,12 +8271,14 @@ "node_modules/eve-raphael": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/eve-raphael/-/eve-raphael-0.5.0.tgz", - "integrity": "sha512-jrxnPsCGqng1UZuEp9DecX/AuSyAszATSjf4oEcRxvfxa1Oux4KkIPKBAAWWnpdwfARtr+Q0o9aPYWjsROD7ug==" + "integrity": "sha512-jrxnPsCGqng1UZuEp9DecX/AuSyAszATSjf4oEcRxvfxa1Oux4KkIPKBAAWWnpdwfARtr+Q0o9aPYWjsROD7ug==", + "dev": true }, "node_modules/eventsource": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "inBundle": true, "license": "MIT", "dependencies": { "eventsource-parser": "^3.0.1" @@ -7879,6 +8291,7 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=18.0.0" @@ -7888,6 +8301,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "inBundle": true, "license": "MIT", "dependencies": { "accepts": "^2.0.0", @@ -7931,6 +8345,7 @@ "version": "8.5.1", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.1.tgz", "integrity": "sha512-5O6KYmyJEpuPJV5hNTXKbAHWRqrzyu+OI3vUnSd2kXFubIVpG7ezpgxQy76Zo5GQZtrQBg86hF+CM/NX+cioiQ==", + "inBundle": true, "license": "MIT", "dependencies": { "ip-address": "^10.2.0" @@ -7949,12 +8364,14 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "inBundle": true, "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "inBundle": true, "license": "MIT" }, "node_modules/fast-string-truncated-width": { @@ -7973,9 +8390,9 @@ } }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", "funding": [ { "type": "github", @@ -7986,6 +8403,7 @@ "url": "https://opencollective.com/fastify" } ], + "inBundle": true, "license": "BSD-3-Clause" }, "node_modules/fast-wrap-ansi": { @@ -8066,6 +8484,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "inBundle": true, "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", @@ -8079,12 +8498,14 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", + "dev": true, "license": "MIT" }, "node_modules/file-selector": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz", "integrity": "sha512-iACCiXeMYOvZqlF1kTiYINzgepRBymz1wwjiuup9u9nayhb6g4fSwiyJ/6adli+EPwrWtpgQAh2PoS7HukEGEg==", + "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.0.3" @@ -8097,6 +8518,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "inBundle": true, "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -8118,12 +8540,14 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true, "license": "MIT" }, "node_modules/font-face-observer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/font-face-observer/-/font-face-observer-1.0.0.tgz", "integrity": "sha512-GHeQVlm05gBswpLECTYd3vnsGMyTPkkOSu1dRjfF3VGjCZ1omtjWjVaJw2WjgqegBFKWZOAfj50YEou/WlcmAg==", + "dev": true, "license": "BSD", "dependencies": { "promise": "^6.1.0" @@ -8133,6 +8557,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.2.7" @@ -8148,6 +8573,7 @@ "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "inBundle": true, "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" @@ -8160,6 +8586,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -8169,6 +8596,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -8193,15 +8621,17 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "inBundle": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gaxios": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.5.tgz", - "integrity": "sha512-5FZy72Rh8LhtjmvDrKkI+lVhrsQrVKVsItxMoDm5mNQE+xR0WVIIs+jzPSJgBvKVsLi24fZhXJIsNI0bihDzFg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.3.0.tgz", + "integrity": "sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -8216,6 +8646,7 @@ "version": "8.1.2", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "gaxios": "^7.0.0", @@ -8230,6 +8661,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8239,6 +8671,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=18" @@ -8251,6 +8684,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "inBundle": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -8285,6 +8719,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "inBundle": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -8295,9 +8730,10 @@ } }, "node_modules/google-auth-library": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.9.0.tgz", - "integrity": "sha512-xtvUqvINPhTaBm7nXqlYPcrMHJPm1lCNdSovxnKKhTm+4JsvQ+KGVYJViLoH9Yxu8w+T0Qv5HubzYT9BLrppJg==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.9.1.tgz", + "integrity": "sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -8315,6 +8751,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">=14" @@ -8324,6 +8761,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8336,6 +8774,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -8348,6 +8787,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8360,6 +8800,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -8375,6 +8816,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "inBundle": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -8387,6 +8829,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" @@ -8396,12 +8839,14 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, "license": "MIT" }, "node_modules/hono": { - "version": "4.12.26", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.26.tgz", - "integrity": "sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw==", + "version": "4.12.31", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.31.tgz", + "integrity": "sha512-zJIHFrl6bq3RDd2YusFNCDlM8qUprxKswyi/OPzPyzKDdyBXDqWx8bZlZ7R+saTdSTatUmb3O7K4SspGPaEOQg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=16.9.0" @@ -8411,6 +8856,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "inBundle": true, "license": "MIT", "dependencies": { "depd": "~2.0.0", @@ -8431,6 +8877,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "inBundle": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.0", @@ -8444,6 +8891,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "inBundle": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -8457,6 +8905,7 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "inBundle": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -8473,6 +8922,7 @@ "version": "7.0.5", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 4" @@ -8494,6 +8944,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -8510,12 +8961,14 @@ "version": "1.43.0", "resolved": "https://registry.npmjs.org/indigo-ketcher/-/indigo-ketcher-1.43.0.tgz", "integrity": "sha512-kscIeTsXFxfucNwbqRWSjV1FOMOtOo1ly6Vw5ZyQ8yRLBsn4YvpI/twXMxj8M8wlf1xEc3Eh+umnA4oGZKFjRA==", + "dev": true, "license": "Apache-2.0" }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "inBundle": true, "license": "ISC" }, "node_modules/internmap": { @@ -8532,6 +8985,7 @@ "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz", "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==", "deprecated": "The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019.", + "dev": true, "license": "Apache-2.0" }, "node_modules/iobuffer": { @@ -8544,6 +8998,7 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 12" @@ -8553,6 +9008,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -8562,6 +9018,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -8572,6 +9029,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, "license": "MIT", "dependencies": { "is-alphabetical": "^1.0.0", @@ -8586,6 +9044,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -8602,12 +9061,14 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, "license": "MIT" }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8620,6 +9081,7 @@ "version": "2.16.2", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.3" @@ -8635,6 +9097,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -8647,6 +9110,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -8657,6 +9121,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.4", @@ -8676,6 +9141,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -8686,6 +9152,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.0", @@ -8702,12 +9169,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "inBundle": true, "license": "MIT" }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -8726,6 +9195,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" @@ -8747,12 +9217,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "inBundle": true, "license": "ISC" }, "node_modules/isomorphic.js": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz", "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==", + "dev": true, "license": "MIT", "peer": true, "funding": { @@ -8764,6 +9236,7 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz", "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==", + "inBundle": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -8773,12 +9246,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, "license": "MIT" }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -8791,6 +9266,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "inBundle": true, "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" @@ -8800,12 +9276,14 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, "license": "MIT" }, "node_modules/json-schema-to-ts": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", + "inBundle": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", @@ -8819,12 +9297,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "inBundle": true, "license": "MIT" }, "node_modules/json-schema-typed": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "inBundle": true, "license": "BSD-2-Clause" }, "node_modules/jszip": { @@ -8849,6 +9329,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "inBundle": true, "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", @@ -8860,6 +9341,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "inBundle": true, "license": "MIT", "dependencies": { "jwa": "^2.0.1", @@ -8870,6 +9352,7 @@ "version": "3.15.0", "resolved": "https://registry.npmjs.org/ketcher-core/-/ketcher-core-3.15.0.tgz", "integrity": "sha512-Z2ngiRd+IzGItUIJcc90laqS5L2CYtjAiUOB3xB2X0sqOegdYmP5KBoVT09SP+B0o5Pc1teb1JB6w3t8g4hflg==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.26.10", @@ -8890,6 +9373,7 @@ "version": "3.15.0", "resolved": "https://registry.npmjs.org/ketcher-react/-/ketcher-react-3.15.0.tgz", "integrity": "sha512-Sr1KZCrkBxlIwlLdV6R9Pij2cdyNl6e0AFPlkeN5ejB17y8q6rw0ZTRQuLXP6IoQI5xUHTuZHe6I/dDsu8HG+g==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.26.10", @@ -8943,6 +9427,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/miew-react/-/miew-react-0.11.0.tgz", "integrity": "sha512-IdJYzrbkpotS4Hx0JYg7KyOcpwyTdGRS1hnc504Y//Xvdl24Ft6uahuf9mbCEI2PNVPDARLc+hqzMTbpDWD88A==", + "dev": true, "license": "MIT", "dependencies": { "miew": "^0.11.0" @@ -8956,6 +9441,7 @@ "version": "3.15.0", "resolved": "https://registry.npmjs.org/ketcher-standalone/-/ketcher-standalone-3.15.0.tgz", "integrity": "sha512-as+FmPz7HmDR159+L980ePcOzlzUOnPS8KHB6mSFU4rHrLCQEciudszRnpvaR7/OGwQUSUVSXndwyVeWZHv89w==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.26.10", @@ -8970,12 +9456,14 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.40.0.tgz", "integrity": "sha512-wNvd/AY13h/QJYvx565M/FSdRjy0l99W5/MFA2x+mbK3KnKa5BifZbHZ1J4/YssCkdyZhSlLwFkyDaYi7l2Dsw==", + "dev": true, "license": "MIT" }, "node_modules/lib0": { "version": "0.2.117", "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.117.tgz", "integrity": "sha512-DeXj9X5xDCjgKLU/7RR+/HQEVzuuEUiwldwOGsHK/sfAfELGWEyTcf0x+uOvCvK3O2zPmZePXWL85vtia6GyZw==", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -9280,6 +9768,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, "license": "MIT" }, "node_modules/lit": { @@ -9317,18 +9806,21 @@ "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, "license": "MIT" }, "node_modules/long": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "inBundle": true, "license": "Apache-2.0" }, "node_modules/longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -9339,6 +9831,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -9361,6 +9854,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, "license": "MIT", "dependencies": { "repeat-string": "^1.0.0" @@ -9374,6 +9868,7 @@ "version": "18.0.5", "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.5.tgz", "integrity": "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==", + "inBundle": true, "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -9386,6 +9881,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -9395,6 +9891,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", + "dev": true, "license": "MIT", "dependencies": { "escape-string-regexp": "^4.0.0", @@ -9410,6 +9907,7 @@ "version": "0.8.5", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^3.0.0", @@ -9427,6 +9925,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", + "dev": true, "license": "MIT", "dependencies": { "mdast-util-gfm-autolink-literal": "^0.1.0", @@ -9444,6 +9943,7 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", + "dev": true, "license": "MIT", "dependencies": { "ccount": "^1.0.0", @@ -9459,6 +9959,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", + "dev": true, "license": "MIT", "dependencies": { "mdast-util-to-markdown": "^0.6.0" @@ -9472,6 +9973,7 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", + "dev": true, "license": "MIT", "dependencies": { "markdown-table": "^2.0.0", @@ -9486,6 +9988,7 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", + "dev": true, "license": "MIT", "dependencies": { "mdast-util-to-markdown": "~0.6.0" @@ -9499,6 +10002,7 @@ "version": "0.6.5", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", @@ -9517,6 +10021,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -9527,6 +10032,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -9536,6 +10042,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=18" @@ -9548,6 +10055,7 @@ "version": "2.11.4", "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9568,6 +10076,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", + "dev": true, "license": "MIT", "dependencies": { "micromark": "~2.11.0", @@ -9586,6 +10095,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", + "dev": true, "license": "MIT", "dependencies": { "micromark": "~2.11.3" @@ -9599,6 +10109,7 @@ "version": "0.6.5", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", + "dev": true, "license": "MIT", "dependencies": { "micromark": "~2.11.0" @@ -9612,6 +10123,7 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", + "dev": true, "license": "MIT", "dependencies": { "micromark": "~2.11.0" @@ -9625,6 +10137,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -9635,6 +10148,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", + "dev": true, "license": "MIT", "dependencies": { "micromark": "~2.11.0" @@ -9648,6 +10162,7 @@ "version": "0.11.1", "resolved": "https://registry.npmjs.org/miew/-/miew-0.11.1.tgz", "integrity": "sha512-CIhZfI9eB0P/covNrst45Y8Xd+MUncyxjNLkZULr+dcyS1ALxjtb+W2icbZEHEsn7zZJJ4ybIMIwQGnzS25IbQ==", + "dev": true, "license": "MIT", "dependencies": { "lodash": "^4.17.21", @@ -9658,6 +10173,7 @@ "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -9667,6 +10183,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "inBundle": true, "license": "MIT", "dependencies": { "mime-db": "^1.54.0" @@ -9683,6 +10200,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "inBundle": true, "license": "MIT" }, "node_modules/nanoid": { @@ -9708,6 +10226,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -9737,6 +10256,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "inBundle": true, "license": "MIT", "engines": { "node": ">=10.5.0" @@ -9746,6 +10266,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "inBundle": true, "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", @@ -9776,6 +10297,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9785,6 +10307,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -9797,6 +10320,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -9813,6 +10337,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -9822,6 +10347,7 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9842,6 +10368,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "inBundle": true, "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -9854,6 +10381,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "inBundle": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -9863,6 +10391,7 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz", "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==", + "inBundle": true, "license": "Apache-2.0", "bin": { "openai": "bin/cli" @@ -9884,6 +10413,7 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "inBundle": true, "license": "MIT", "dependencies": { "@types/retry": "0.12.0", @@ -9913,6 +10443,7 @@ "version": "0.12.18", "resolved": "https://registry.npmjs.org/paper/-/paper-0.12.18.tgz", "integrity": "sha512-ZSLIEejQTJZuYHhSSqAf4jXOnii0kPhCJGAnYAANtdS72aNwXJ9cP95tZHgq1tnNpvEwgQhggy+4OarviqTCGw==", + "dev": true, "license": "MIT", "workspaces": [ "packages/*" @@ -9925,6 +10456,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -9937,6 +10469,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, "license": "MIT", "dependencies": { "character-entities": "^1.0.0", @@ -9955,6 +10488,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -9973,6 +10507,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -9982,6 +10517,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz", "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==", + "inBundle": true, "license": "MIT" }, "node_modules/path-expression-matcher": { @@ -10003,6 +10539,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=8" @@ -10012,12 +10549,14 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, "license": "MIT" }, "node_modules/path-to-regexp": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "inBundle": true, "license": "MIT", "funding": { "type": "opencollective", @@ -10028,6 +10567,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10055,6 +10595,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -10074,6 +10615,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=16.20.0" @@ -10083,6 +10625,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -10141,6 +10684,7 @@ "version": "1.30.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -10156,6 +10700,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz", "integrity": "sha512-O+uwGKreKNKkshzZv2P7N64lk6EP17iXBn0PbUnNQhk+Q0AHLstiTrjkx3v5YBd3cxUe7Sq6KyRhl/A0xUjk7Q==", + "dev": true, "license": "MIT", "dependencies": { "asap": "~1.0.0" @@ -10165,6 +10710,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -10176,35 +10722,14 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, "license": "MIT" }, - "node_modules/protobufjs": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.4.tgz", - "integrity": "sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.5", - "@protobufjs/eventemitter": "^1.1.1", - "@protobufjs/fetch": "^1.1.1", - "@protobufjs/float": "^1.0.2", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.1", - "@types/node": ">=13.7.0", - "long": "^5.3.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "inBundle": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -10218,6 +10743,7 @@ "version": "6.15.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", + "inBundle": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -10311,6 +10837,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -10320,6 +10847,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/raphael/-/raphael-2.3.0.tgz", "integrity": "sha512-w2yIenZAQnp257XUWGni4bLMVxpUpcIl7qgxEgDIXtmSypYtlNxfXWpOBxs7LBTps5sDwhRnrToJrMUrivqNTQ==", + "dev": true, "license": "MIT", "dependencies": { "eve-raphael": "0.5.0" @@ -10329,6 +10857,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "inBundle": true, "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -10353,6 +10882,7 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.7.0.tgz", "integrity": "sha512-fuesYIemttah97XmsIHmz4OORDHiSFzyc9HMAIrCHJou2jaRQmL8cFJ76K4zQhhj8jzwOBlOi4BaGTjjOZCfTg==", + "dev": true, "license": "MIT", "peerDependencies": { "react": ">=16.8.0", @@ -10363,6 +10893,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/react-contexify/-/react-contexify-6.0.0.tgz", "integrity": "sha512-jMhz6yZI81Jv3UDj7TXqCkhdkCFEEmvwGCPXsQuA2ZUC8EbCuVQ6Cy8FzKMXa0y454XTDClBN2YFvvmoFlrFkg==", + "dev": true, "license": "MIT", "dependencies": { "clsx": "^1.2.1" @@ -10376,6 +10907,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/react-device-detect/-/react-device-detect-2.2.3.tgz", "integrity": "sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==", + "dev": true, "license": "MIT", "dependencies": { "ua-parser-js": "^1.0.33" @@ -10389,6 +10921,7 @@ "version": "19.2.7", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "dev": true, "license": "MIT", "dependencies": { "scheduler": "^0.27.0" @@ -10401,6 +10934,7 @@ "version": "11.7.1", "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.7.1.tgz", "integrity": "sha512-zxCMwhfPy1olUEbw3FLNPLhAm/HnaYH5aELIEglRbqabizKAdHs0h+WuyOpmA+v1JXn0++fpQDdNfUagWt5hJQ==", + "dev": true, "license": "MIT", "dependencies": { "attr-accept": "^2.2.2", @@ -10418,6 +10952,7 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.2.tgz", "integrity": "sha512-3DpCr5HVdZ0caUjYE/kIHBEJN0mNP3ZCgf16c48uJ5TbWjorKVp+YG8W3XqlJ7vJAVNw6wNIImyPXmFydwmyng==", + "dev": true, "license": "MIT", "peerDependencies": { "react": "^18.0.0 || ^19.0.0" @@ -10427,6 +10962,7 @@ "version": "9.16.0", "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz", "integrity": "sha512-w9nJSEp+DrW9KmQmeWHQyfaP6b03v+TdXynaoA964Wxt7mdR3An11z4NNCQgL4gKSK7y1ver2Fq+JKH6CWEzUA==", + "dev": true, "license": "MIT", "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0", @@ -10442,6 +10978,7 @@ "version": "19.2.7", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", + "dev": true, "license": "MIT" }, "node_modules/react-json-view-lite": { @@ -10460,12 +10997,14 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "dev": true, "license": "MIT" }, "node_modules/react-redux": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.3.0.tgz", "integrity": "sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==", + "dev": true, "license": "MIT", "dependencies": { "@types/use-sync-external-store": "^0.0.6", @@ -10561,6 +11100,7 @@ "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/runtime": "^7.5.5", @@ -10577,6 +11117,7 @@ "version": "9.22.6", "resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.6.tgz", "integrity": "sha512-U5j7KuUQt3AaMatlMJ0UJddqSiX+Km0YJxSqbAzIiGw5EmNz0khMyqP2hzgu4+QUtm+QPIrxzUX4raJxmVJnHg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.7.2", @@ -10616,12 +11157,14 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "dev": true, "license": "MIT" }, "node_modules/redux-logger": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz", "integrity": "sha512-JoCIok7bg/XpqA1JqCqXFypuqBbQzGQySrhFzewB7ThcnysTO30l4VCst86AuB9T9tuT03MAA56Jw2PNhRSNCg==", + "dev": true, "license": "MIT", "dependencies": { "deep-diff": "^0.3.5" @@ -10631,6 +11174,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "dev": true, "license": "MIT", "peerDependencies": { "redux": "^5.0.0" @@ -10640,12 +11184,14 @@ "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true, "license": "MIT" }, "node_modules/remark-gfm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", + "dev": true, "license": "MIT", "dependencies": { "mdast-util-gfm": "^0.1.0", @@ -10660,6 +11206,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dev": true, "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^0.8.0" @@ -10673,6 +11220,7 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10" @@ -10682,6 +11230,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10691,18 +11240,21 @@ "version": "4.1.8", "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", + "dev": true, "license": "MIT" }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "dev": true, "license": "MIT" }, "node_modules/resolve": { "version": "1.22.12", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -10724,6 +11276,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -10733,6 +11286,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 4" @@ -10782,6 +11336,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "inBundle": true, "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -10818,12 +11373,14 @@ "url": "https://feross.org/support" } ], + "inBundle": true, "license": "MIT" }, "node_modules/safe-regex-test": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -10841,18 +11398,21 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "inBundle": true, "license": "MIT" }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "dev": true, "license": "MIT" }, "node_modules/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "inBundle": true, "license": "MIT", "dependencies": { "debug": "^4.4.3", @@ -10879,6 +11439,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "inBundle": true, "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", @@ -10898,6 +11459,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -10921,12 +11483,14 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "inBundle": true, "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "inBundle": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -10939,6 +11503,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=8" @@ -10948,6 +11513,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "inBundle": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -10967,6 +11533,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "inBundle": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -10983,6 +11550,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "inBundle": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -11001,6 +11569,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "inBundle": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -11026,6 +11595,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -11045,6 +11615,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -11084,18 +11655,21 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "dev": true, "license": "MIT" }, "node_modules/subscription": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/subscription/-/subscription-3.0.0.tgz", "integrity": "sha512-W0xDn7QYcDo9HhHqsmoj4U8pJVqYqnggBUoJixAQXc2MoX71Ef551Np9tyTMX+9Ta6br9MdTbvdpQ/+JP31uPQ==", + "dev": true, "license": "MIT" }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11108,6 +11682,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.6.0.tgz", "integrity": "sha512-OIWR6bKzXvdXYyO4DK/UWa1VA1JeKq8E+0ug2DG98Y/vOmMpfZNj+TIG988HjfYSqtcy/hFOtZq/n/j5GSESNg==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/fontello/svg2ttf?sponsor=1" @@ -11117,12 +11692,14 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.5.0.tgz", "integrity": "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==", + "dev": true, "license": "MIT" }, "node_modules/three": { "version": "0.153.0", "resolved": "https://registry.npmjs.org/three/-/three-0.153.0.tgz", "integrity": "sha512-OCP2/uQR6GcDpSLnJt/3a4mdS0kNWcbfUXIwLoEMgLzEUIVIYsSDwskpmOii/AkDM+BBwrl6+CKgrjX9+E2aWg==", + "dev": true, "license": "MIT" }, "node_modules/tidytree": { @@ -11156,6 +11733,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=0.6" @@ -11171,12 +11749,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", + "inBundle": true, "license": "MIT" }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "inBundle": true, "license": "0BSD" }, "node_modules/tsx": { @@ -11199,23 +11779,43 @@ } }, "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "inBundle": true, "license": "MIT", "dependencies": { - "content-type": "^1.0.5", + "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/typebox": { "version": "1.1.38", "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz", "integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==", + "inBundle": true, "license": "MIT" }, "node_modules/typescript": { @@ -11236,6 +11836,7 @@ "version": "1.0.41", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz", "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==", + "dev": true, "funding": [ { "type": "opencollective", @@ -11271,12 +11872,14 @@ "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "inBundle": true, "license": "MIT" }, "node_modules/unist-util-is": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -11287,6 +11890,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^2.0.2" @@ -11300,6 +11904,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", @@ -11314,6 +11919,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -11338,6 +11944,7 @@ "version": "8.2.5", "resolved": "https://registry.npmjs.org/url-search-params-polyfill/-/url-search-params-polyfill-8.2.5.tgz", "integrity": "sha512-FOEojW4XReTmtZOB7xqSHmJZhrNTmClhBriwLTmle4iA7bwuCo6ldSfbtsFSb8bTf3E0a3XpfonAdaur9vqq8A==", + "dev": true, "license": "MIT" }, "node_modules/use-callback-ref": { @@ -11366,6 +11973,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-7.0.1.tgz", "integrity": "sha512-tJESENDoVXfzkv1Cl9dJ13ySgENcKjvEKSU7QwjckjxjXg/MV2zW1CjEUtLpmXY084womIxJROUR3L1SuqlvOw==", + "dev": true, "license": "MIT", "dependencies": { "resize-observer-polyfill": "^1.5.1" @@ -11402,6 +12010,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "dev": true, "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -11411,6 +12020,7 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -11430,6 +12040,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -11517,6 +12128,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">= 8" @@ -11532,6 +12144,7 @@ "version": "3.6.20", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "dev": true, "license": "MIT" }, "node_modules/whatwg-url": { @@ -11548,6 +12161,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "inBundle": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -11563,6 +12177,7 @@ "version": "1.1.22", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", + "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -11584,12 +12199,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "inBundle": true, "license": "ISC" }, "node_modules/ws": { "version": "8.21.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -11626,6 +12243,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "inBundle": true, "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -11641,6 +12259,7 @@ "version": "13.6.31", "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.31.tgz", "integrity": "sha512-Eq+5BRfbeGyqGVrTJL3bEcr8gKkxPuyuoHmAwpk52fDb8kOVMrfVSTRPd6yiGgX5Fskb96qCRjzjbRjrL4YEnw==", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -11659,6 +12278,7 @@ "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "inBundle": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -11668,6 +12288,7 @@ "version": "3.25.1", "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "inBundle": true, "license": "ISC", "peerDependencies": { "zod": "^3.25 || ^4" @@ -11677,6 +12298,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true, "license": "MIT", "funding": { "type": "github", diff --git a/package.json b/package.json index 12bca2ee..87a16216 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "@companion-ai/feynman", - "version": "0.3.5", + "version": "0.3.6", "description": "Research-first CLI agent built on Pi and alphaXiv", "license": "MIT", "type": "module", "engines": { - "node": ">=22.19.0 <26" + "node": ">=22.22.0 <26" }, "bin": { "feynman": "bin/feynman.js" @@ -15,7 +15,10 @@ "dist/", "metadata/", ".feynman/agents/", + ".feynman/config/", + ".feynman/runtime-package-lock.json", ".feynman/runtime-workspace.tgz", + ".feynman/runtime-workspace.sha256", ".feynman/settings.json", ".feynman/SYSTEM.md", ".feynman/themes/", @@ -35,20 +38,35 @@ "scripts/prepare-runtime-workspace.mjs", "scripts/prune-runtime-deps.mjs", "scripts/sync-website-installers.mjs", + "scripts/verify-package-artifact.mjs", + "scripts/verify-package-budget.mjs", "skills/", + "src/config/paths.ts", + "src/workbench/data-root.ts", + "src/workbench/oauth-store.ts", + "src/workbench/settings-store.ts", + ".nvmrc", "AGENTS.md", "CONTRIBUTING.md", "RELEASES.md", "README.md", ".env.example" ], + "bundleDependencies": [ + "@companion-ai/alpha-hub", + "@earendil-works/pi-agent-core", + "@earendil-works/pi-ai", + "@earendil-works/pi-coding-agent", + "@earendil-works/pi-tui" + ], "scripts": { "preinstall": "node ./scripts/check-node-version.mjs", "build": "npm run build:workbench-web && tsc -p tsconfig.build.json", "build:workbench-web": "vite build --config workbench.vite.config.ts", "build:native-bundle": "node ./scripts/build-native-bundle.mjs", "dev": "tsx src/index.ts", - "prepack": "node ./scripts/clean-publish-artifacts.mjs && npm run build && node ./scripts/prepare-runtime-workspace.mjs", + "prepack": "node ./scripts/clean-publish-artifacts.mjs && npm run build && node ./scripts/patch-embedded-pi.mjs && node ./scripts/prepare-runtime-workspace.mjs --rebuild", + "runtime:lock": "node ./scripts/prepare-runtime-workspace.mjs --refresh-lock", "start": "tsx src/index.ts", "start:dist": "node ./bin/feynman.js", "test": "node ./scripts/patch-embedded-pi.mjs && node --import tsx --test --test-concurrency=1 tests/*.test.ts", @@ -62,6 +80,11 @@ "literature-review", "experiments" ], + "feynmanReleaseBudget": { + "maxTarballBytes": 131072000, + "maxUnpackedBytes": 377487360, + "maxFileCount": 42000 + }, "pi": { "extensions": [ "./extensions" @@ -76,30 +99,28 @@ "dependencies": { "@clack/prompts": "^1.5.1", "@companion-ai/alpha-hub": "^0.1.3", - "@earendil-works/pi-agent-core": "0.80.3", - "@earendil-works/pi-ai": "0.80.3", - "@earendil-works/pi-coding-agent": "0.80.3", - "@earendil-works/pi-tui": "0.80.3", + "@earendil-works/pi-agent-core": "0.82.1", + "@earendil-works/pi-ai": "0.82.1", + "@earendil-works/pi-coding-agent": "0.82.1", + "@earendil-works/pi-tui": "0.82.1", "@nightingale-elements/nightingale-msa": "^5.6.0", "@opentelemetry/api": "^1.9.1", - "@opentelemetry/api-logs": "^0.219.0", - "@opentelemetry/exporter-logs-otlp-http": "^0.219.0", - "@opentelemetry/exporter-trace-otlp-proto": "^0.219.0", - "@opentelemetry/resources": "^2.8.0", - "@opentelemetry/sdk-logs": "^0.219.0", - "@opentelemetry/sdk-trace-base": "^2.8.0", - "@opentelemetry/sdk-trace-node": "^2.8.0", + "@opentelemetry/api-logs": "^0.221.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.221.0", + "@opentelemetry/exporter-trace-otlp-proto": "^0.221.0", + "@opentelemetry/resources": "^2.10.0", + "@opentelemetry/sdk-logs": "^0.221.0", + "@opentelemetry/sdk-trace-base": "^2.10.0", + "@opentelemetry/sdk-trace-node": "^2.10.0", "@opentelemetry/semantic-conventions": "^1.41.1", "@rdkit/rdkit": "^2025.3.4-1.0.0", "@sinclair/typebox": "^0.34.49", "3dmol": "^2.5.5", + "brace-expansion": "5.0.8", "d3": "^7.9.0", "fast-xml-parser": "5.7.3", "igv": "^3.8.4", "jszip": "^3.10.1", - "ketcher-core": "^3.15.0", - "ketcher-react": "^3.15.0", - "ketcher-standalone": "^3.15.0", "npyjs": "^1.1.0", "patristic": "^0.5.7", "pdfjs-dist": "^6.1.200", @@ -110,12 +131,13 @@ }, "overrides": { "basic-ftp": "5.3.1", - "hono": "4.12.26", + "brace-expansion": "5.0.8", + "hono": "4.12.31", "qs": "6.15.2", "ws": "8.21.0", "@modelcontextprotocol/sdk": { - "@hono/node-server": "1.19.14", - "hono": "4.12.26" + "@hono/node-server": "2.0.12", + "hono": "4.12.31" }, "express-rate-limit": "8.5.1", "ip-address": "10.2.0", @@ -131,26 +153,27 @@ } } }, - "fast-uri": "3.1.2", + "fast-uri": "3.1.4", "esbuild": "0.28.1", "fast-xml-builder": "1.2.0", - "protobufjs": "7.6.4", - "minimatch": { - "brace-expansion": "5.0.6" - } + "protobufjs": "7.6.5" }, "devDependencies": { "@types/node": "^25.9.3", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.3", + "ketcher-core": "3.15.0", + "ketcher-react": "3.15.0", + "ketcher-standalone": "3.15.0", "lucide-react": "^1.23.0", "radix-ui": "^1.6.1", "react": "^19.2.7", "react-dom": "^19.2.7", "tsx": "^4.22.4", "typescript": "^6.0.3", - "vite": "^8.1.3" + "vite": "^8.1.3", + "yaml": "2.9.0" }, "repository": { "type": "git", diff --git a/scripts/build-native-bundle.mjs b/scripts/build-native-bundle.mjs index fd470bd9..81c995ad 100644 --- a/scripts/build-native-bundle.mjs +++ b/scripts/build-native-bundle.mjs @@ -1,12 +1,27 @@ import { chmodSync, cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs"; +import { createHash } from "node:crypto"; import { tmpdir } from "node:os"; import { basename, dirname, join, resolve } from "node:path"; import { spawnSync } from "node:child_process"; +import { verifyFileSha256 } from "./lib/runtime-workspace-integrity.mjs"; +import { + createDeterministicTarGz, + createDeterministicZip, +} from "./lib/deterministic-archive.mjs"; const appRoot = resolve(import.meta.dirname, ".."); const packageJson = JSON.parse(readFileSync(resolve(appRoot, "package.json"), "utf8")); const packageLockPath = resolve(appRoot, "package-lock.json"); const minBundledNodeVersion = packageJson.engines?.node?.match(/>=\s*([0-9]+\.[0-9]+\.[0-9]+)/)?.[1] || process.version.slice(1); +const releaseNodeVersion = readFileSync(resolve(appRoot, ".nvmrc"), "utf8").trim().replace(/^v/, ""); +const PINNED_NODE_ARCHIVE_SHA256 = { + "node-v24.18.0-darwin-arm64.tar.xz": "4477b9f78efb77744cf5eb57a0e9594dba66466b38b4e93fa9f35cb907a095a6", + "node-v24.18.0-darwin-x64.tar.xz": "4a3b6bc81542154430825128d9a279e8b364e8d90581544e506ef7579fd1ab6f", + "node-v24.18.0-linux-arm64.tar.xz": "58c9520501f6ae2b52d5b210444e24b9d0c029a58c5011b797bc1fe7105886f6", + "node-v24.18.0-linux-x64.tar.xz": "55aa7153f9d88f28d765fcdad5ae6945b5c0f98a36881703817e4c450fa76742", + "node-v24.18.0-win-arm64.zip": "f274669adb93b1fd0fbf8f21fd078609e9dcc84333d4f2718d2dde3f9a161a01", + "node-v24.18.0-win-x64.zip": "0ae68406b42d7725661da979b1403ec9926da205c6770827f33aac9d8f26e821", +}; function parseSemver(version) { const [major = "0", minor = "0", patch = "0"] = version.split("."); @@ -41,10 +56,9 @@ function resolveBundledNodeVersion() { return requestedNodeVersion; } - const currentNodeVersion = process.version.slice(1); - return compareSemver(parseSemver(currentNodeVersion), parseSemver(minBundledNodeVersion)) < 0 + return compareSemver(parseSemver(releaseNodeVersion), parseSemver(minBundledNodeVersion)) < 0 ? minBundledNodeVersion - : currentNodeVersion; + : releaseNodeVersion; } const bundledNodeVersion = resolveBundledNodeVersion(); @@ -251,9 +265,21 @@ function installBundledNode(bundleRoot, target, stagingRoot) { const archiveName = nodeArchiveName(target); const archivePath = resolve(stagingRoot, archiveName); const url = `https://nodejs.org/dist/v${bundledNodeVersion}/${archiveName}`; + const expectedSha256 = + process.env.FEYNMAN_BUNDLED_NODE_SHA256?.trim() || + PINNED_NODE_ARCHIVE_SHA256[archiveName]; + if (!expectedSha256) { + fail( + `no trusted SHA-256 is configured for ${archiveName}; set FEYNMAN_BUNDLED_NODE_SHA256 for an intentional override`, + ); + } logStep(`downloading Node.js ${bundledNodeVersion} for ${target.id}...`); run("curl", ["-fsSL", url, "-o", archivePath]); + const actualSha256 = createHash("sha256").update(readFileSync(archivePath)).digest("hex"); + if (actualSha256 !== expectedSha256) { + fail(`Node.js archive SHA-256 mismatch for ${archiveName}: expected ${expectedSha256}, found ${actualSha256}`); + } logStep("extracting bundled Node.js..."); const extractRoot = resolve(stagingRoot, "node-dist"); @@ -320,72 +346,103 @@ function validateBundle(bundleRoot, target) { const betterSqlitePackageJson = resolve(bundleRoot, "app", ".feynman", "npm", "node_modules", "better-sqlite3", "package.json"); if (!existsSync(betterSqlitePackageJson)) { logStep("skipping better-sqlite3 validation; sqlite-backed packages are not bundled for this Node runtime"); - return; + } else { + run(nodeExecutable, ["-e", "require('./app/.feynman/npm/node_modules/better-sqlite3'); console.log('better-sqlite3 ok')"], { + cwd: bundleRoot, + }); } - run(nodeExecutable, ["-e", "require('./app/.feynman/npm/node_modules/better-sqlite3'); console.log('better-sqlite3 ok')"], { - cwd: bundleRoot, - }); + const launchers = target.launcher === "windows" + ? [ + { command: resolve(bundleRoot, "feynman.cmd"), prefix: [] }, + { + command: "powershell", + prefix: [ + "-NoProfile", + "-ExecutionPolicy", + "Bypass", + "-File", + resolve(bundleRoot, "feynman.ps1"), + ], + }, + ] + : [{ command: resolve(bundleRoot, "feynman"), prefix: [] }]; + + for (const launcher of launchers) { + const versionOutput = runCapture( + launcher.command, + [...launcher.prefix, "--version"], + { cwd: bundleRoot }, + ); + if (versionOutput.split(/\r?\n/).at(-1)?.trim() !== packageJson.version) { + fail(`native launcher version mismatch for ${launcher.command}: ${versionOutput}`); + } + const helpOutput = runCapture( + launcher.command, + [...launcher.prefix, "--help"], + { cwd: bundleRoot }, + ); + if (!helpOutput.trim()) { + fail(`native launcher returned empty help: ${launcher.command}`); + } + } } -function packBundle(bundleRoot, target, outDir) { +async function packBundle(bundleRoot, target, outDir) { logStep("packing native bundle..."); const archiveName = `${basename(bundleRoot)}.${target.bundleExtension}`; const archivePath = resolve(outDir, archiveName); rmSync(archivePath, { force: true }); if (target.bundleExtension === "zip") { - if (process.platform === "win32" && commandExists("7z")) { - run("7z", ["a", "-tzip", archivePath, basename(bundleRoot), "-mx=1", "-bb0", "-bd"], { - cwd: resolve(bundleRoot, ".."), - }); - return archivePath; - } - if (process.platform === "win32") { - const bundleDir = dirname(bundleRoot).replace(/'/g, "''"); - const bundleName = basename(bundleRoot).replace(/'/g, "''"); - run("powershell", [ - "-NoProfile", - "-Command", - `Push-Location '${bundleDir}'; Compress-Archive -Path '${bundleName}' -DestinationPath '${archivePath.replace(/'/g, "''")}' -Force; Pop-Location`, - ]); - } else { - run("zip", ["-qr", archivePath, basename(bundleRoot)], { cwd: resolve(bundleRoot, "..") }); + if (process.platform === "win32" && !commandExists("7z")) { + fail("7z is required to create deterministic Windows release archives"); } - return archivePath; + return createDeterministicZip(bundleRoot, archivePath); } - run("tar", ["-czf", archivePath, basename(bundleRoot)], { cwd: resolve(bundleRoot, "..") }); - return archivePath; + return await createDeterministicTarGz(bundleRoot, archivePath); } -function main() { +async function main() { const target = detectTarget(); const stagingRoot = mkdtempSync(join(tmpdir(), "feynman-native-")); const outDir = resolve(appRoot, "dist", "release"); const bundleRoot = resolve(stagingRoot, `feynman-${packageJson.version}-${target.id}`); const appDir = resolve(bundleRoot, "app"); - mkdirSync(outDir, { recursive: true }); - mkdirSync(appDir, { recursive: true }); + try { + mkdirSync(outDir, { recursive: true }); + mkdirSync(appDir, { recursive: true }); - ensureBundledWorkspace(); - copyPackageFiles(appDir); - installAppDependencies(appDir, stagingRoot); + ensureBundledWorkspace(); + copyPackageFiles(appDir); + installAppDependencies(appDir, stagingRoot); - const appFeynmanDir = resolve(appDir, ".feynman"); - logStep("extracting runtime workspace..."); - extractTarball(resolve(appFeynmanDir, "runtime-workspace.tgz"), appFeynmanDir, "-xzf"); - rmSync(resolve(appFeynmanDir, "runtime-workspace.tgz"), { force: true }); - logStep("patching embedded Pi runtime..."); - run(process.execPath, [resolve(appDir, "scripts", "patch-embedded-pi.mjs")], { cwd: appDir }); - - installBundledNode(bundleRoot, target, stagingRoot); - writeLauncher(bundleRoot, target); - validateBundle(bundleRoot, target); - - const archivePath = packBundle(bundleRoot, target, outDir); - console.log(`[feynman] native bundle ready: ${archivePath}`); + const appFeynmanDir = resolve(appDir, ".feynman"); + logStep("extracting runtime workspace..."); + const runtimeArchivePath = resolve(appFeynmanDir, "runtime-workspace.tgz"); + const runtimeArchiveDigestPath = resolve(appFeynmanDir, "runtime-workspace.sha256"); + if (!verifyFileSha256(runtimeArchivePath, runtimeArchiveDigestPath)) { + fail("runtime workspace archive failed its SHA-256 integrity check"); + } + extractTarball(runtimeArchivePath, appFeynmanDir, "-xzf"); + logStep("patching embedded Pi runtime..."); + run(process.execPath, [resolve(appDir, "scripts", "patch-embedded-pi.mjs")], { cwd: appDir }); + run(process.execPath, [resolve(appDir, "scripts", "verify-package-artifact.mjs"), appDir], { cwd: appDir }); + run("npm", ["audit", "--omit=dev", "--no-fund"], { cwd: appDir }); + rmSync(runtimeArchivePath, { force: true }); + rmSync(runtimeArchiveDigestPath, { force: true }); + + installBundledNode(bundleRoot, target, stagingRoot); + writeLauncher(bundleRoot, target); + validateBundle(bundleRoot, target); + + const archivePath = await packBundle(bundleRoot, target, outDir); + console.log(`[feynman] native bundle ready: ${archivePath}`); + } finally { + rmSync(stagingRoot, { recursive: true, force: true }); + } } -main(); +await main(); diff --git a/scripts/check-node-version.mjs b/scripts/check-node-version.mjs index 33da11de..b1bddd56 100644 --- a/scripts/check-node-version.mjs +++ b/scripts/check-node-version.mjs @@ -1,4 +1,4 @@ -const MIN_NODE_VERSION = "22.19.0"; +const MIN_NODE_VERSION = "22.22.0"; const MAX_NODE_MAJOR = 25; const PREFERRED_NODE_MAJOR = 24; diff --git a/scripts/extract-release-notes.mjs b/scripts/extract-release-notes.mjs index 6a16328c..442e04c0 100644 --- a/scripts/extract-release-notes.mjs +++ b/scripts/extract-release-notes.mjs @@ -13,15 +13,11 @@ if (!normalizedVersion) { const releasesPath = resolve(process.cwd(), "RELEASES.md"); const source = readFileSync(releasesPath, "utf8"); -const notes = - extractReleaseNotes(source, normalizedVersion) || - [ - `## ${normalizedVersion}`, - "", - "- See RELEASES.md for the current release history.", - "- Standalone native bundles are attached below for macOS, Linux, and Windows.", - "", - ].join("\n"); +const notes = extractReleaseNotes(source, normalizedVersion); +if (!notes) { + console.error(`RELEASES.md has no section for ${normalizedVersion}`); + process.exit(1); +} if (outputPath) { writeFileSync(outputPath, `${notes.trim()}\n`, "utf8"); diff --git a/scripts/install/install.ps1 b/scripts/install/install.ps1 index e7145d6e..ac92ce25 100644 --- a/scripts/install/install.ps1 +++ b/scripts/install/install.ps1 @@ -20,7 +20,9 @@ function Normalize-Version { } function Resolve-LatestReleaseVersion { - $page = Invoke-WebRequest -Uri "https://github.com/companion-inc/feynman/releases/latest" + $page = Invoke-WebRequest ` + -Uri "https://github.com/companion-inc/feynman/releases/latest" ` + -UseBasicParsing $match = [regex]::Match($page.Content, 'releases/tag/v([0-9][^"''<>\s]*)') if (-not $match.Success) { throw "Failed to resolve the latest Feynman release version." @@ -53,6 +55,7 @@ function Resolve-ReleaseMetadata { BundleName = $bundleName ArchiveName = $archiveName DownloadUrl = "$baseUrl/$archiveName" + ChecksumsUrl = "$baseUrl/SHA256SUMS" } } @@ -64,7 +67,9 @@ function Get-ArchSuffix { if ($envArch) { switch ($envArch) { "AMD64" { return "x64" } - "ARM64" { return "arm64" } + # The release currently ships the Windows x64 bundle. Windows 11 on Arm + # runs that bundle through its supported x64 emulation layer. + "ARM64" { return "x64" } } } @@ -72,7 +77,7 @@ function Get-ArchSuffix { $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture switch ($arch.ToString()) { "X64" { return "x64" } - "Arm64" { return "arm64" } + "Arm64" { return "x64" } } } catch {} @@ -86,6 +91,7 @@ $resolvedVersion = $release.ResolvedVersion $bundleName = $release.BundleName $archiveName = $release.ArchiveName $downloadUrl = $release.DownloadUrl +$checksumsUrl = $release.ChecksumsUrl $installRoot = Join-Path $env:LOCALAPPDATA "Programs\feynman" $installBinDir = Join-Path $installRoot "bin" @@ -96,9 +102,15 @@ New-Item -ItemType Directory -Path $tmpDir | Out-Null try { $archivePath = Join-Path $tmpDir $archiveName + $checksumsPath = Join-Path $tmpDir "SHA256SUMS" + $extractRoot = Join-Path $tmpDir "extract" + $extractedBundleDir = Join-Path $extractRoot $bundleName Write-Host "==> Downloading $archiveName" try { - Invoke-WebRequest -Uri $downloadUrl -OutFile $archivePath + Invoke-WebRequest ` + -Uri $downloadUrl ` + -OutFile $archivePath ` + -UseBasicParsing } catch { throw @" Failed to download $archiveName from: @@ -114,28 +126,139 @@ Workarounds: "@ } - New-Item -ItemType Directory -Path $installRoot -Force | Out-Null - if (Test-Path $bundleDir) { - Remove-Item -Recurse -Force $bundleDir + Write-Host "==> Verifying $archiveName" + Invoke-WebRequest ` + -Uri $checksumsUrl ` + -OutFile $checksumsPath ` + -UseBasicParsing + $escapedArchiveName = [regex]::Escape($archiveName) + $checksumMatches = @( + Select-String ` + -LiteralPath $checksumsPath ` + -Pattern "^([0-9a-fA-F]{64})\s+\*?$escapedArchiveName$" + ) + if ($checksumMatches.Count -eq 0) { + throw "SHA256SUMS does not contain a valid checksum for $archiveName." + } + if ($checksumMatches.Count -ne 1) { + throw "SHA256SUMS contains multiple checksum entries for $archiveName." + } + $expectedChecksum = $checksumMatches[0].Matches[0].Groups[1].Value.ToLowerInvariant() + $actualChecksum = (Get-FileHash -LiteralPath $archivePath -Algorithm SHA256).Hash.ToLowerInvariant() + if ($actualChecksum -ne $expectedChecksum) { + throw "SHA-256 mismatch for ${archiveName}: expected $expectedChecksum, found $actualChecksum." } Write-Host "==> Extracting $archiveName" - Expand-Archive -LiteralPath $archivePath -DestinationPath $installRoot -Force + New-Item -ItemType Directory -Path $extractRoot -Force | Out-Null + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($archivePath, $extractRoot) + if (-not (Test-Path $extractedBundleDir)) { + throw "Downloaded archive did not contain the expected $bundleName directory." + } + $candidateCmd = Join-Path $extractedBundleDir "feynman.cmd" + $candidatePs1 = Join-Path $extractedBundleDir "feynman.ps1" + foreach ($candidate in @($candidateCmd, $candidatePs1)) { + if (-not (Test-Path -LiteralPath $candidate)) { + throw "Downloaded archive did not contain the expected launcher: $candidate" + } + } + $candidateVersionOutput = @(& $candidateCmd --version 2>&1) + if ($LASTEXITCODE -ne 0) { + throw "Downloaded launcher failed --version: $candidateCmd" + } + $candidateVersion = ($candidateVersionOutput | Select-Object -Last 1).ToString().Trim() + if ($candidateVersion -ne $resolvedVersion) { + throw "Downloaded bundle version mismatch: expected=$resolvedVersion actual=$candidateVersion" + } + $candidateHelp = @(& $candidateCmd --help 2>&1) + if ($LASTEXITCODE -ne 0 -or $candidateHelp.Count -eq 0) { + throw "Downloaded launcher failed --help: $candidateCmd" + } - New-Item -ItemType Directory -Path $installBinDir -Force | Out-Null + # The public one-line installer can run under Windows PowerShell's default + # Restricted policy because it executes an in-memory scriptblock. Validate + # the packaged PowerShell launcher in a child host with an explicit process- + # scoped bypass rather than invoking the downloaded .ps1 file directly. + $powerShellExecutable = (Get-Process -Id $PID).Path + $candidateVersionOutput = @( + & $powerShellExecutable -NoProfile -ExecutionPolicy Bypass -File $candidatePs1 --version 2>&1 + ) + if ($LASTEXITCODE -ne 0) { + throw "Downloaded launcher failed --version: $candidatePs1" + } + $candidateVersion = ($candidateVersionOutput | Select-Object -Last 1).ToString().Trim() + if ($candidateVersion -ne $resolvedVersion) { + throw "Downloaded bundle version mismatch: expected=$resolvedVersion actual=$candidateVersion" + } + $candidateHelp = @( + & $powerShellExecutable -NoProfile -ExecutionPolicy Bypass -File $candidatePs1 --help 2>&1 + ) + if ($LASTEXITCODE -ne 0 -or $candidateHelp.Count -eq 0) { + throw "Downloaded launcher failed --help: $candidatePs1" + } - $shimPath = Join-Path $installBinDir "feynman.cmd" - $shimPs1Path = Join-Path $installBinDir "feynman.ps1" - Write-Host "==> Linking feynman into $installBinDir" + New-Item -ItemType Directory -Path $installRoot -Force | Out-Null + $stagedBinDir = Join-Path $tmpDir "bin" + New-Item -ItemType Directory -Path $stagedBinDir -Force | Out-Null + $shimCandidate = Join-Path $stagedBinDir "feynman.cmd" @" @echo off CALL "$bundleDir\feynman.cmd" %* -"@ | Set-Content -Path $shimPath -Encoding ASCII +"@ | Set-Content -Path $shimCandidate -Encoding ASCII - @" -`$BundleDir = "$bundleDir" -& "`$BundleDir\node\node.exe" "`$BundleDir\app\bin\feynman.js" @args -"@ | Set-Content -Path $shimPs1Path -Encoding UTF8 + $backupBundleDir = Join-Path $tmpDir "previous-bundle" + $backupBinDir = Join-Path $tmpDir "previous-bin" + $hadPreviousBundle = Test-Path -LiteralPath $bundleDir + $hadPreviousBin = Test-Path -LiteralPath $installBinDir + $backupBundleMoved = $false + $backupBinMoved = $false + $candidateBundleInstalled = $false + $candidateBinInstalled = $false + try { + if ($hadPreviousBundle) { + Move-Item -LiteralPath $bundleDir -Destination $backupBundleDir + $backupBundleMoved = $true + } + if ($env:FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_BACKUP -eq "1") { + throw "Injected installer failure after bundle backup." + } + if ($hadPreviousBin) { + Move-Item -LiteralPath $installBinDir -Destination $backupBinDir + $backupBinMoved = $true + } + Move-Item -LiteralPath $extractedBundleDir -Destination $bundleDir + $candidateBundleInstalled = $true + Write-Host "==> Linking feynman into $installBinDir" + if ($env:FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_SWAP -eq "1") { + throw "Injected installer failure after bundle swap." + } + Move-Item -LiteralPath $stagedBinDir -Destination $installBinDir + $candidateBinInstalled = $true + } catch { + if ($candidateBundleInstalled -and (Test-Path -LiteralPath $bundleDir)) { + Remove-Item -LiteralPath $bundleDir -Recurse -Force + } + if ($candidateBinInstalled -and (Test-Path -LiteralPath $installBinDir)) { + Remove-Item -LiteralPath $installBinDir -Recurse -Force + } + if ($backupBundleMoved -and (Test-Path -LiteralPath $backupBundleDir)) { + Move-Item -LiteralPath $backupBundleDir -Destination $bundleDir + } + if ($backupBinMoved -and (Test-Path -LiteralPath $backupBinDir)) { + Move-Item -LiteralPath $backupBinDir -Destination $installBinDir + } + throw + } + if (Test-Path -LiteralPath $backupBundleDir) { + Remove-Item -LiteralPath $backupBundleDir -Recurse -Force + } + if (Test-Path -LiteralPath $backupBinDir) { + Remove-Item -LiteralPath $backupBinDir -Recurse -Force + } + Get-ChildItem -LiteralPath $installRoot -Directory -Filter "feynman-*" | + Where-Object { $_.FullName -ne $bundleDir } | + Remove-Item -Recurse -Force $currentUserPath = [Environment]::GetEnvironmentVariable("Path", "User") $alreadyOnPath = $false @@ -155,7 +278,24 @@ CALL "$bundleDir\feynman.cmd" %* } $resolvedCommand = Get-Command feynman -ErrorAction SilentlyContinue - if ($resolvedCommand -and $resolvedCommand.Source -ne $shimPath) { + # Install only the CMD shim on PATH. Windows PowerShell resolves .ps1 before + # PATHEXT launchers, so a same-name PowerShell shim is blocked by the default + # Restricted policy before the working CMD launcher can be selected. + $expectedShimPaths = @( + [System.IO.Path]::GetFullPath((Join-Path $installBinDir "feynman.cmd")) + ) + $resolvedSource = if ($resolvedCommand) { $resolvedCommand.Source } else { $null } + $resolvedToInstalledShim = $false + if ($resolvedSource) { + $resolvedFullPath = [System.IO.Path]::GetFullPath($resolvedSource) + foreach ($expectedShimPath in $expectedShimPaths) { + if ([string]::Equals($resolvedFullPath, $expectedShimPath, [System.StringComparison]::OrdinalIgnoreCase)) { + $resolvedToInstalledShim = $true + break + } + } + } + if ($resolvedCommand -and -not $resolvedToInstalledShim) { Write-Warning "Current shell resolves feynman to $($resolvedCommand.Source)" Write-Host "Run in a new shell, or run: `$env:Path = '$installBinDir;' + `$env:Path" Write-Host "Then run: feynman" diff --git a/scripts/install/install.sh b/scripts/install/install.sh index 3f651d61..e1bcdce3 100644 --- a/scripts/install/install.sh +++ b/scripts/install/install.sh @@ -164,6 +164,19 @@ require_command() { fi } +sha256_file() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | awk '{print $1}' + return + fi + if command -v shasum >/dev/null 2>&1; then + shasum -a 256 "$1" | awk '{print $1}' + return + fi + echo "sha256sum or shasum is required to verify the Feynman download." >&2 + exit 1 +} + warn_command_conflict() { expected_path="$INSTALL_BIN_DIR/feynman" resolved_path="$(command -v feynman 2>/dev/null || true)" @@ -198,9 +211,11 @@ resolve_release_metadata() { bundle_name="feynman-${resolved_version}-${asset_target}" archive_name="${bundle_name}.${archive_extension}" - download_url="${FEYNMAN_INSTALL_BASE_URL:-https://github.com/companion-inc/feynman/releases/download/v${resolved_version}}/${archive_name}" + release_base_url="${FEYNMAN_INSTALL_BASE_URL:-https://github.com/companion-inc/feynman/releases/download/v${resolved_version}}" + download_url="${release_base_url}/${archive_name}" + checksums_url="${release_base_url}/SHA256SUMS" - printf '%s\n%s\n%s\n%s\n' "$resolved_version" "$bundle_name" "$archive_name" "$download_url" + printf '%s\n%s\n%s\n%s\n%s\n' "$resolved_version" "$bundle_name" "$archive_name" "$download_url" "$checksums_url" } case "$(uname -s)" in @@ -239,6 +254,7 @@ resolved_version="$(printf '%s\n' "$release_metadata" | sed -n '1p')" bundle_name="$(printf '%s\n' "$release_metadata" | sed -n '2p')" archive_name="$(printf '%s\n' "$release_metadata" | sed -n '3p')" download_url="$(printf '%s\n' "$release_metadata" | sed -n '4p')" +checksums_url="$(printf '%s\n' "$release_metadata" | sed -n '5p')" step "Installing Feynman ${resolved_version} for ${asset_target}" @@ -266,18 +282,97 @@ EOF exit 1 fi -mkdir -p "$INSTALL_APP_DIR" -rm -rf "$INSTALL_APP_DIR/$bundle_name" -run_with_spinner "Extracting ${archive_name}" tar -xzf "$archive_path" -C "$INSTALL_APP_DIR" +checksums_path="$tmp_dir/SHA256SUMS" +step "Verifying ${archive_name}" +download_file "$checksums_url" "$checksums_path" +checksum_matches="$(awk -v name="$archive_name" '$2 == name || $2 == "*" name { print $1 }' "$checksums_path")" +checksum_count="$(printf '%s\n' "$checksum_matches" | awk 'NF { count += 1 } END { print count + 0 }')" +if [ "$checksum_count" -ne 1 ]; then + if [ "$checksum_count" -eq 0 ]; then + echo "SHA256SUMS does not contain a valid checksum for ${archive_name}." >&2 + else + echo "SHA256SUMS contains multiple checksum entries for ${archive_name}." >&2 + fi + exit 1 +fi +expected_checksum="$(printf '%s\n' "$checksum_matches" | sed -n '1p')" +case "$expected_checksum" in + "" | *[!0-9a-fA-F]*) + echo "SHA256SUMS does not contain a valid checksum for ${archive_name}." >&2 + exit 1 + ;; +esac +if [ "${#expected_checksum}" -ne 64 ]; then + echo "SHA256SUMS contains a malformed checksum for ${archive_name}." >&2 + exit 1 +fi +actual_checksum="$(sha256_file "$archive_path")" +if [ "$actual_checksum" != "$expected_checksum" ]; then + echo "SHA-256 mismatch for ${archive_name}: expected ${expected_checksum}, found ${actual_checksum}." >&2 + exit 1 +fi +extract_root="$tmp_dir/extract" +mkdir -p "$extract_root" +run_with_spinner "Extracting ${archive_name}" tar -xzf "$archive_path" -C "$extract_root" +candidate_bundle="$extract_root/$bundle_name" +if [ ! -x "$candidate_bundle/feynman" ]; then + echo "Downloaded archive did not contain the expected executable: ${bundle_name}/feynman" >&2 + exit 1 +fi +candidate_version="$("$candidate_bundle/feynman" --version | tail -n 1)" +if [ "$candidate_version" != "$resolved_version" ]; then + echo "Downloaded bundle version mismatch: expected ${resolved_version}, found ${candidate_version}." >&2 + exit 1 +fi +"$candidate_bundle/feynman" --help >/dev/null + +mkdir -p "$INSTALL_APP_DIR" mkdir -p "$INSTALL_BIN_DIR" +bundle_dir="$INSTALL_APP_DIR/$bundle_name" +backup_dir="$tmp_dir/previous-bundle" +had_previous=0 +if [ -e "$bundle_dir" ]; then + mv "$bundle_dir" "$backup_dir" + had_previous=1 +fi +if ! mv "$candidate_bundle" "$bundle_dir"; then + if [ "$had_previous" -eq 1 ]; then + mv "$backup_dir" "$bundle_dir" + fi + echo "Failed to install the validated Feynman bundle." >&2 + exit 1 +fi + step "Linking feynman into $INSTALL_BIN_DIR" -cat >"$INSTALL_BIN_DIR/feynman" <"$shim_candidate" <; + +export function createDeterministicZip( + rootPath: string, + archivePath: string, +): string; diff --git a/scripts/lib/deterministic-archive.mjs b/scripts/lib/deterministic-archive.mjs new file mode 100644 index 00000000..e126126a --- /dev/null +++ b/scripts/lib/deterministic-archive.mjs @@ -0,0 +1,194 @@ +import { + createReadStream, + createWriteStream, + lstatSync, + lutimesSync, + mkdtempSync, + readdirSync, + rmSync, + utimesSync, + writeFileSync, +} from "node:fs"; +import { tmpdir } from "node:os"; +import { basename, dirname, join, relative, resolve, sep } from "node:path"; +import { spawnSync } from "node:child_process"; +import { createGzip } from "node:zlib"; +import { pipeline } from "node:stream/promises"; + +export const ARCHIVE_EPOCH_MS = Date.UTC(2000, 0, 1, 0, 0, 0); + +function normalizeLabel(path) { + return path.split(sep).join("/"); +} + +function walkArchiveTree(rootPath, currentPath, entries) { + const stat = lstatSync(currentPath); + entries.push(normalizeLabel(relative(dirname(rootPath), currentPath))); + if (!stat.isDirectory()) return; + for (const entry of readdirSync(currentPath, { withFileTypes: true }) + .sort((left, right) => left.name.localeCompare(right.name, "en"))) { + walkArchiveTree(rootPath, resolve(currentPath, entry.name), entries); + } +} + +export function collectArchiveEntries(rootPath) { + const resolvedRoot = resolve(rootPath); + const entries = []; + walkArchiveTree(resolvedRoot, resolvedRoot, entries); + for (const entry of entries) { + if (entry.includes("\n") || entry.includes("\r")) { + throw new Error(`Archive paths may not contain newlines: ${entry}`); + } + } + return entries; +} + +function normalizeTreeTimestamp(path, date) { + const stat = lstatSync(path); + if (stat.isDirectory()) { + for (const entry of readdirSync(path, { withFileTypes: true }) + .sort((left, right) => left.name.localeCompare(right.name, "en"))) { + normalizeTreeTimestamp(resolve(path, entry.name), date); + } + } + if (stat.isSymbolicLink()) { + try { + lutimesSync(path, date, date); + } catch { + // Some Windows filesystems do not expose symlink timestamp updates. + } + return; + } + utimesSync(path, date, date); +} + +export function normalizeArchiveTreeTimestamps(rootPath, epochMs = ARCHIVE_EPOCH_MS) { + normalizeTreeTimestamp(resolve(rootPath), new Date(epochMs)); +} + +function tarFlavor() { + const result = spawnSync("tar", ["--version"], { + encoding: "utf8", + stdio: ["ignore", "pipe", "pipe"], + }); + if (result.status !== 0) { + throw new Error(`tar --version failed: ${result.stderr?.trim() || result.status}`); + } + return /bsdtar|libarchive/i.test(`${result.stdout}\n${result.stderr}`) ? "bsd" : "gnu"; +} + +function runArchiveCommand(command, args, options = {}) { + const result = spawnSync(command, args, { + stdio: "inherit", + ...options, + }); + if (result.error) { + throw new Error(`${command} failed: ${result.error.message}`); + } + if (result.status !== 0) { + throw new Error(`${command} ${args.join(" ")} failed with code ${result.status ?? 1}`); + } +} + +function writeEntryList(rootPath, listPath) { + const entries = collectArchiveEntries(rootPath); + writeFileSync(listPath, `${entries.join("\n")}\n`, "utf8"); + return entries; +} + +export async function createDeterministicTarGz(rootPath, archivePath) { + const resolvedRoot = resolve(rootPath); + const resolvedArchive = resolve(archivePath); + normalizeArchiveTreeTimestamps(resolvedRoot); + + const tempRoot = mkdtempSync(join(tmpdir(), "feynman-tar-")); + const listPath = resolve(tempRoot, "entries.txt"); + const tarPath = resolve(tempRoot, `${basename(resolvedArchive)}.tar`); + writeEntryList(resolvedRoot, listPath); + + try { + const common = [ + "--no-recursion", + "-cf", + tarPath, + "-C", + dirname(resolvedRoot), + "-T", + listPath, + ]; + const ownership = tarFlavor() === "bsd" + ? ["--uid", "0", "--gid", "0", "--uname", "root", "--gname", "root"] + : [ + "--owner=0", + "--group=0", + "--numeric-owner", + `--mtime=@${Math.floor(ARCHIVE_EPOCH_MS / 1000)}`, + "--sort=name", + "--pax-option=delete=atime,delete=ctime", + ]; + runArchiveCommand("tar", [...ownership, ...common], { + env: { + ...process.env, + COPYFILE_DISABLE: "1", + TZ: "UTC", + }, + }); + await pipeline( + createReadStream(tarPath), + createGzip({ level: 9, mtime: 0 }), + createWriteStream(resolvedArchive, { mode: 0o644 }), + ); + } finally { + rmSync(tempRoot, { recursive: true, force: true }); + } + return resolvedArchive; +} + +export function createDeterministicZip(rootPath, archivePath) { + const resolvedRoot = resolve(rootPath); + const resolvedArchive = resolve(archivePath); + normalizeArchiveTreeTimestamps(resolvedRoot); + + const tempRoot = mkdtempSync(join(tmpdir(), "feynman-zip-")); + const listPath = resolve(tempRoot, "entries.txt"); + writeEntryList(resolvedRoot, listPath); + const cwd = dirname(resolvedRoot); + const env = { ...process.env, COPYFILE_DISABLE: "1", TZ: "UTC" }; + + try { + if (process.platform === "win32") { + runArchiveCommand( + "7z", + [ + "a", + "-tzip", + resolvedArchive, + `@${listPath}`, + "-mx=1", + "-bb0", + "-bd", + "-mtc=off", + "-mta=off", + "-mtm=off", + ], + { cwd, env }, + ); + } else { + const entries = collectArchiveEntries(resolvedRoot); + const result = spawnSync("zip", ["-X", "-q", "-y", resolvedArchive, "-@"], { + cwd, + env, + input: `${entries.join("\n")}\n`, + encoding: "utf8", + stdio: ["pipe", "inherit", "inherit"], + }); + if (result.error) throw new Error(`zip failed: ${result.error.message}`); + if (result.status !== 0) { + throw new Error(`zip failed with code ${result.status ?? 1}`); + } + } + } finally { + rmSync(tempRoot, { recursive: true, force: true }); + } + return resolvedArchive; +} diff --git a/scripts/lib/mcp-sdk-package-patch.d.mts b/scripts/lib/mcp-sdk-package-patch.d.mts new file mode 100644 index 00000000..7293765d --- /dev/null +++ b/scripts/lib/mcp-sdk-package-patch.d.mts @@ -0,0 +1 @@ +export declare function patchMcpSdkPackageJsonSource(source: string): string; diff --git a/scripts/lib/mcp-sdk-package-patch.mjs b/scripts/lib/mcp-sdk-package-patch.mjs new file mode 100644 index 00000000..2d3e5c60 --- /dev/null +++ b/scripts/lib/mcp-sdk-package-patch.mjs @@ -0,0 +1,37 @@ +const SAFE_HONO_NODE_SERVER_VERSION = "2.0.12"; + +/** + * MCP SDK 1.30.0 allows the security-fixed @hono/node-server v2 line, but also + * retains the vulnerable v1 line for compatibility. Feynman bundles this + * dependency tree, so pin the exact tested v2 release in the shipped manifest. + * Remove this patch once MCP no longer permits the vulnerable v1 range. + */ +export function patchMcpSdkPackageJsonSource(source) { + const manifest = JSON.parse(source); + if (!manifest.dependencies || typeof manifest.dependencies !== "object") { + throw new Error("@modelcontextprotocol/sdk package.json has no dependencies object"); + } + + const current = manifest.dependencies["@hono/node-server"]; + if (current === SAFE_HONO_NODE_SERVER_VERSION) { + return source; + } + if (typeof current !== "string") { + throw new Error("@modelcontextprotocol/sdk package.json has no @hono/node-server dependency"); + } + const knownUnsafeRange = + current === "^1.19.9" || + current === "^1.19.9 || ^2.0.5" || + (() => { + const match = /^[~^]?2\.0\.(\d+)$/.exec(current); + return match !== null && Number.parseInt(match[1], 10) < 12; + })(); + if (!knownUnsafeRange) { + throw new Error( + `Unsupported @modelcontextprotocol/sdk @hono/node-server dependency: ${current}`, + ); + } + + manifest.dependencies["@hono/node-server"] = SAFE_HONO_NODE_SERVER_VERSION; + return JSON.stringify(manifest, null, 2) + "\n"; +} diff --git a/scripts/lib/pi-model-registry-patch.mjs b/scripts/lib/pi-model-registry-patch.mjs index 8e20a238..af9dfcb8 100644 --- a/scripts/lib/pi-model-registry-patch.mjs +++ b/scripts/lib/pi-model-registry-patch.mjs @@ -44,16 +44,66 @@ const RETURN_PATCHED = [ ].join("\n"); const HELPER_ANCHOR = "function formatValidationPath(error) {"; +const CURRENT_REGISTRY_HELPER_ANCHOR = "export class ModelRegistry {"; +const CURRENT_COMPATIBILITY_RETURN_ORIGINAL = " return { ok: true, headers };"; +const CURRENT_COMPATIBILITY_RETURN_PATCHED = [ + " assertHeaderSafeRequestConfig(model.provider, undefined, headers);", + CURRENT_COMPATIBILITY_RETURN_ORIGINAL, +].join("\n"); +const CURRENT_RESOLVED_RETURN_ORIGINAL = + " return { ok: true, apiKey: resolution.auth.apiKey, headers, env: resolution.env };"; +const CURRENT_RESOLVED_RETURN_PATCHED = [ + " assertHeaderSafeRequestConfig(model.provider, resolution.auth.apiKey, headers);", + CURRENT_RESOLVED_RETURN_ORIGINAL, +].join("\n"); +const RUNTIME_HELPER_ANCHOR = "function mergeHeaders(base, override) {"; +const RUNTIME_REQUEST_AUTH = [ + " if (transformHeaders)", + " headers = await transformHeaders(headers ?? {});", +].join("\n"); +const RUNTIME_REQUEST_AUTH_PATCHED = [ + RUNTIME_REQUEST_AUTH, + " assertHeaderSafeRequestConfig(model.provider, providerOptions.apiKey ?? resolution.auth.apiKey, headers);", +].join("\n"); export function patchPiModelRegistrySource(source) { if (source.includes("function assertHeaderSafeRequestConfig(")) { return source; } - if (!source.includes(RETURN_ORIGINAL) || !source.includes(HELPER_ANCHOR)) { - return source; + if (source.includes(RETURN_ORIGINAL) && source.includes(HELPER_ANCHOR)) { + let patched = source.replace(RETURN_ORIGINAL, RETURN_PATCHED); + patched = patched.replace(HELPER_ANCHOR, `${LATIN1_GUARD_HELPER}\n${HELPER_ANCHOR}`); + return patched; } - - let patched = source.replace(RETURN_ORIGINAL, RETURN_PATCHED); - patched = patched.replace(HELPER_ANCHOR, `${LATIN1_GUARD_HELPER}\n${HELPER_ANCHOR}`); - return patched; + if ( + source.includes(CURRENT_COMPATIBILITY_RETURN_ORIGINAL) && + source.includes(CURRENT_RESOLVED_RETURN_ORIGINAL) && + source.includes(CURRENT_REGISTRY_HELPER_ANCHOR) + ) { + let patched = source.replace( + CURRENT_COMPATIBILITY_RETURN_ORIGINAL, + CURRENT_COMPATIBILITY_RETURN_PATCHED, + ); + patched = patched.replace( + CURRENT_RESOLVED_RETURN_ORIGINAL, + CURRENT_RESOLVED_RETURN_PATCHED, + ); + patched = patched.replace( + CURRENT_REGISTRY_HELPER_ANCHOR, + `${LATIN1_GUARD_HELPER}\n${CURRENT_REGISTRY_HELPER_ANCHOR}`, + ); + return patched; + } + if (source.includes(RUNTIME_REQUEST_AUTH) && source.includes(RUNTIME_HELPER_ANCHOR)) { + let patched = source.replace(RUNTIME_REQUEST_AUTH, RUNTIME_REQUEST_AUTH_PATCHED); + patched = patched.replace(RUNTIME_HELPER_ANCHOR, `${LATIN1_GUARD_HELPER}\n${RUNTIME_HELPER_ANCHOR}`); + return patched; + } + if (source.includes("class ModelRuntime")) { + throw new Error("Unsupported Pi ModelRuntime layout: required request-auth patch anchor was not found"); + } + if (source.includes("class ModelRegistry")) { + throw new Error("Unsupported Pi ModelRegistry layout: required request-auth patch anchors were not found"); + } + return source; } diff --git a/scripts/lib/pi-otel-patch.mjs b/scripts/lib/pi-otel-patch.mjs index 0e4dab9f..9713a82b 100644 --- a/scripts/lib/pi-otel-patch.mjs +++ b/scripts/lib/pi-otel-patch.mjs @@ -17,11 +17,19 @@ export function patchPiOtelSource(relativePath, source) { } if (relativePath === "dist/otel/sdk.js") { + const compatibleResourceImport = `import * as otelResources from "@opentelemetry/resources"; +const createFeynmanResource = (attributes) => typeof otelResources.resourceFromAttributes === "function" + ? otelResources.resourceFromAttributes(attributes) + : new otelResources.Resource(attributes);`; patched = patched - .replace('import { Resource } from "@opentelemetry/resources";', 'import { resourceFromAttributes } from "@opentelemetry/resources";') + // pi-otel can resolve its declared OpenTelemetry 1.x dependency in + // the agent workspace or Feynman's hoisted 2.x runtime dependency. + .replace('import { Resource } from "@opentelemetry/resources";', compatibleResourceImport) + .replace('import { resourceFromAttributes } from "@opentelemetry/resources";', compatibleResourceImport) .replace('import { ATTR_PI_CWD } from "../attrs.js";\n', "") .replace("\n [ATTR_PI_CWD]: cfg.cwd,", "") - .replace("const resource = new Resource({", "const resource = resourceFromAttributes({") + .replace("const resource = new Resource({", "const resource = createFeynmanResource({") + .replace("const resource = resourceFromAttributes({", "const resource = createFeynmanResource({") .replace( " // OTLP endpoints always carry an explicit port; refuse to fall back to\n // 80/443, which could silently green-light an unrelated service.\n if (!u.port)\n return Promise.resolve(false);\n return probeTcp(u.hostname || \"127.0.0.1\", Number(u.port), timeoutMs);", " const defaultPort = u.protocol === \"https:\" ? 443 : u.protocol === \"http:\" ? 80 : undefined;\n const port = u.port ? Number(u.port) : defaultPort;\n if (!port)\n return Promise.resolve(false);\n return probeTcp(u.hostname || \"127.0.0.1\", port, timeoutMs);", diff --git a/scripts/lib/pi-shrinkwrap-security-patch.d.mts b/scripts/lib/pi-shrinkwrap-security-patch.d.mts new file mode 100644 index 00000000..50495576 --- /dev/null +++ b/scripts/lib/pi-shrinkwrap-security-patch.d.mts @@ -0,0 +1,3 @@ +export declare function patchPiCodingAgentShrinkwrapSource(source: string): string; +export declare function patchPiPackageLockSource(source: string): string; +export declare function patchPiBraceExpansionTree(nodeModulesPath: string, fallbackSafePackagePath?: string): boolean; diff --git a/scripts/lib/pi-shrinkwrap-security-patch.mjs b/scripts/lib/pi-shrinkwrap-security-patch.mjs new file mode 100644 index 00000000..e0b33b30 --- /dev/null +++ b/scripts/lib/pi-shrinkwrap-security-patch.mjs @@ -0,0 +1,121 @@ +import { cpSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs"; +import { createRequire } from "node:module"; +import { dirname, resolve } from "node:path"; + +const require = createRequire(import.meta.url); + +const SAFE_BRACE_EXPANSION = { + version: "5.0.8", + resolved: "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + integrity: "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + license: "MIT", + dependencies: { "balanced-match": "^4.0.2" }, + engines: { node: "20 || >=22" }, +}; + +function readPackageVersion(packageRoot) { + try { + return JSON.parse(readFileSync(resolve(packageRoot, "package.json"), "utf8")).version; + } catch { + return undefined; + } +} + +function resolveSafePackagePath(nodeModulesPath, fallbackSafePackagePath) { + const candidates = [ + resolve(nodeModulesPath, "brace-expansion"), + fallbackSafePackagePath, + ]; + try { + candidates.push(dirname(require.resolve("brace-expansion/package.json"))); + } catch {} + return candidates.find((candidate) => + candidate && readPackageVersion(candidate) === SAFE_BRACE_EXPANSION.version + ); +} + +export function patchPiCodingAgentShrinkwrapSource(source) { + const shrinkwrap = JSON.parse(source); + const entry = shrinkwrap.packages?.["node_modules/brace-expansion"]; + if (entry?.version === SAFE_BRACE_EXPANSION.version) { + return source; + } + if (!entry || !["5.0.6", "5.0.7"].includes(entry.version)) { + throw new Error(`Unsupported Pi brace-expansion shrinkwrap entry: ${entry?.version ?? "missing"}`); + } + shrinkwrap.packages["node_modules/brace-expansion"] = SAFE_BRACE_EXPANSION; + return JSON.stringify(shrinkwrap, null, 2) + "\n"; +} + +export function patchPiPackageLockSource(source) { + const lockfile = JSON.parse(source); + let changed = false; + for (const [packagePath, entry] of Object.entries(lockfile.packages ?? {})) { + if (!packagePath.endsWith("/pi-coding-agent/node_modules/brace-expansion")) { + continue; + } + if (entry?.version === SAFE_BRACE_EXPANSION.version) { + continue; + } + if (!entry || !["5.0.6", "5.0.7"].includes(entry.version)) { + throw new Error(`Unsupported Pi brace-expansion package-lock entry: ${entry?.version ?? "missing"}`); + } + lockfile.packages[packagePath] = SAFE_BRACE_EXPANSION; + changed = true; + } + return changed ? JSON.stringify(lockfile, null, 2) + "\n" : source; +} + +/** + * Pi 0.82.1 still shrinkwraps vulnerable brace-expansion 5.0.7. Replace only + * that nested package with the verified 5.0.8 tree and update Pi's published + * shrinkwrap metadata. Remove this patch after Pi ships brace-expansion >=5.0.8. + */ +export function patchPiBraceExpansionTree(nodeModulesPath, fallbackSafePackagePath) { + const piRoots = ["@earendil-works", "@mariozechner"] + .map((scope) => resolve(nodeModulesPath, scope, "pi-coding-agent")) + .filter((piRoot) => existsSync(resolve(piRoot, "npm-shrinkwrap.json"))); + if (piRoots.length === 0) { + return false; + } + + let changed = false; + for (const piRoot of piRoots) { + const shrinkwrapPath = resolve(piRoot, "npm-shrinkwrap.json"); + + const shrinkwrapSource = readFileSync(shrinkwrapPath, "utf8"); + const patchedShrinkwrap = patchPiCodingAgentShrinkwrapSource(shrinkwrapSource); + const nestedPackagePath = resolve(piRoot, "node_modules", "brace-expansion"); + const nestedVersion = readPackageVersion(nestedPackagePath); + if (nestedVersion !== SAFE_BRACE_EXPANSION.version) { + if (nestedVersion && !["5.0.6", "5.0.7"].includes(nestedVersion)) { + throw new Error(`Unsupported installed Pi brace-expansion version: ${nestedVersion}`); + } + const safePackagePath = resolveSafePackagePath(nodeModulesPath, fallbackSafePackagePath); + if (!safePackagePath) { + throw new Error(`Safe brace-expansion ${SAFE_BRACE_EXPANSION.version} package tree is unavailable`); + } + const temporaryPath = `${nestedPackagePath}.feynman-safe-${process.pid}`; + rmSync(temporaryPath, { recursive: true, force: true }); + mkdirSync(dirname(temporaryPath), { recursive: true }); + cpSync(safePackagePath, temporaryPath, { recursive: true }); + rmSync(nestedPackagePath, { recursive: true, force: true }); + renameSync(temporaryPath, nestedPackagePath); + changed = true; + } + if (patchedShrinkwrap !== shrinkwrapSource) { + writeFileSync(shrinkwrapPath, patchedShrinkwrap, "utf8"); + changed = true; + } + } + const packageLockPath = resolve(nodeModulesPath, "..", "package-lock.json"); + if (existsSync(packageLockPath)) { + const packageLockSource = readFileSync(packageLockPath, "utf8"); + const patchedPackageLock = patchPiPackageLockSource(packageLockSource); + if (patchedPackageLock !== packageLockSource) { + writeFileSync(packageLockPath, patchedPackageLock, "utf8"); + changed = true; + } + } + return changed; +} diff --git a/scripts/lib/pi-subagents-patch.mjs b/scripts/lib/pi-subagents-patch.mjs index 2e910e6f..f9a35a26 100644 --- a/scripts/lib/pi-subagents-patch.mjs +++ b/scripts/lib/pi-subagents-patch.mjs @@ -159,6 +159,27 @@ function patchTaskSchemaOutputParam(source) { ); } +function patchCurrentPiSpawnResolver(source) { + if ( + !source.includes('export const PI_CODING_AGENT_PACKAGE = "@earendil-works/pi-coding-agent";') || + source.includes("FEYNMAN_PI_CLI_PATH") + ) { + return source; + } + return source.replace( + "\tconst argv1 = deps.argv1 ?? process.argv[1];", + [ + "\tconst env = deps.env ?? process.env;", + "\tconst feynmanPiCliPath = env.FEYNMAN_PI_CLI_PATH?.trim();", + "\tif (feynmanPiCliPath) {", + "\t\tconst cliPath = normalizePath(feynmanPiCliPath);", + "\t\tif (isRunnableNodeScript(cliPath, existsSync)) return cliPath;", + "\t}", + "\tconst argv1 = deps.argv1 ?? process.argv[1];", + ].join("\n"), + ); +} + const OLD_AGENT_DIR_DECLS = [ '\tconst userDirOld = path.join(os.homedir(), ".pi", "agent", "agents");', '\tconst userDirNew = path.join(os.homedir(), ".agents");', @@ -312,6 +333,7 @@ export function patchPiSubagentsSource(relativePath, source) { "\texecPath?: string;\n\targv1?: string;\n\targv2?: string;", ], ]); + patched = patchCurrentPiSpawnResolver(patched); break; case "subagent-executor.ts": { diff --git a/scripts/lib/pi-tui-patch.mjs b/scripts/lib/pi-tui-patch.mjs index d867c611..30621494 100644 --- a/scripts/lib/pi-tui-patch.mjs +++ b/scripts/lib/pi-tui-patch.mjs @@ -110,6 +110,14 @@ const OVERFLOW_TRUNCATE_BLOCK_AFTER_CLEAR = ` let line = newLines[i]; } buffer += line;`; +const OVERFLOW_THROW_BLOCK_AFTER_CLEAR_CURRENT = OVERFLOW_THROW_BLOCK_AFTER_CLEAR.replace( + 'path.join(os.homedir(), ".pi", "agent", "pi-crash.log")', + 'path.join(this.logDirectory, "pi-crash.log")', +); + +const CURRENT_EDITOR_IMPORT = 'import { cjkBreakRegex, getGraphemeSegmenter, getWordSegmenter, isWhitespaceChar, sliceByColumn, visibleWidth, } from "../utils.js";'; +const CURRENT_EDITOR_IMPORT_PATCHED = 'import { applyBackgroundToLine, cjkBreakRegex, getGraphemeSegmenter, getWordSegmenter, isWhitespaceChar, sliceByColumn, visibleWidth, } from "../utils.js";'; + // Two known upstream layouts: pi-tui <=0.75 and the 0.76+ Unicode // word-navigation rework. Both need applyBackgroundToLine added for the // background-fill render below. @@ -271,6 +279,125 @@ const EDITOR_THEME_BLOCK = [ "}", ].join("\n"); +function patchCurrentEditorSource(source) { + const replacements = [ + [ + CURRENT_EDITOR_IMPORT, + CURRENT_EDITOR_IMPORT_PATCHED, + ], + [ + ' const horizontal = this.borderColor("─");\n // Layout the text', + ' const horizontal = this.borderColor("─");\n const bgColor = this.theme.bgColor;\n const styleInput = typeof this.theme.input === "function" ? this.theme.input : (text) => text;\n // Layout the text', + ], + [ + ` // Render top border (with scroll indicator if scrolled down) + if (this.scrollOffset > 0) { + const border = createScrollBorder("↑", this.scrollOffset, width); + result.push(this.borderColor(border)); + } + else { + result.push(horizontal.repeat(width)); + }`, + ` // Render top border (with scroll indicator if scrolled down) + if (this.scrollOffset > 0) { + const border = createScrollBorder("↑", this.scrollOffset, width); + result.push(bgColor ? applyBackgroundToLine(\` ↑ \${this.scrollOffset} more\`, width, bgColor) : this.borderColor(border)); + } + else { + result.push(bgColor ? applyBackgroundToLine("", width, bgColor) : horizontal.repeat(width)); + }`, + ], + [ + " const emitCursorMarker = this.focused;\n for (const layoutLine of visibleLines) {", + ` const emitCursorMarker = this.focused; + const showPlaceholder = this.state.lines.length === 1 && + this.state.lines[0] === "" && + typeof this.theme.placeholderText === "string" && + this.theme.placeholderText.length > 0; + for (const layoutLine of visibleLines) {`, + ], + [ + ` let cursorInPadding = false; + // Add cursor if this line has it + if (layoutLine.hasCursor && layoutLine.cursorPos !== undefined) {`, + ` let cursorInPadding = false; + const isPlaceholderLine = showPlaceholder && this.scrollOffset === 0 && layoutLine === visibleLines[0]; + if (isPlaceholderLine) { + const marker = emitCursorMarker ? CURSOR_MARKER : ""; + const placeholder = typeof this.theme.placeholder === "function" + ? this.theme.placeholder(this.theme.placeholderText) + : this.theme.placeholderText; + displayText = marker + placeholder; + lineVisibleWidth = visibleWidth(this.theme.placeholderText); + } + // Add cursor if this line has it + else if (layoutLine.hasCursor && layoutLine.cursorPos !== undefined) {`, + ], + [ + " displayText = before + marker + cursor + restAfter;", + " displayText = styleInput(before) + marker + cursor + styleInput(restAfter);", + ], + [ + ' const cursor = `\\x1b[7m${firstGrapheme}\\x1b[0m`;', + ' const cursor = `\\x1b[7m${firstGrapheme}\\x1b[27m`;', + ], + [ + ' const cursor = "\\x1b[7m \\x1b[0m";', + ' const cursor = "\\x1b[7m \\x1b[27m";', + ], + [ + " displayText = before + marker + cursor;", + " displayText = styleInput(before) + marker + cursor;", + ], + [ + ` } + } + // Calculate padding based on actual visible width`, + ` } + } + else { + displayText = styleInput(displayText); + } + // Calculate padding based on actual visible width`, + ], + [ + ' result.push(`${leftPadding}${displayText}${padding}${lineRightPadding}`);', + ' const renderedLine = `${leftPadding}${displayText}${padding}${lineRightPadding}`;\n result.push(bgColor ? applyBackgroundToLine(renderedLine, width, bgColor) : renderedLine);', + ], + [ + ` // Render bottom border (with scroll indicator if more content below) + const linesBelow = layoutLines.length - (this.scrollOffset + visibleLines.length); + if (linesBelow > 0) { + const border = createScrollBorder("↓", linesBelow, width); + result.push(this.borderColor(border)); + } + else { + result.push(horizontal.repeat(width)); + }`, + ` // Render bottom border (with scroll indicator if more content below) + const linesBelow = layoutLines.length - (this.scrollOffset + visibleLines.length); + if (linesBelow > 0) { + const border = createScrollBorder("↓", linesBelow, width); + result.push(bgColor ? applyBackgroundToLine(\` ↓ \${linesBelow} more\`, width, bgColor) : this.borderColor(border)); + } + else { + result.push(bgColor ? applyBackgroundToLine("", width, bgColor) : horizontal.repeat(width)); + }`, + ], + [ + ' result.push(`${leftPadding}${line}${linePadding}${rightPadding}`);', + ' const renderedLine = `${leftPadding}${line}${linePadding}${rightPadding}`;\n result.push(bgColor ? applyBackgroundToLine(renderedLine, width, bgColor) : renderedLine);', + ], + ]; + const missing = replacements + .map(([original], index) => source.includes(original) ? undefined : index + 1) + .filter(Boolean); + if (missing.length > 0) { + throw new Error(`Unsupported Pi editor layout: missing required 0.82 patch anchors ${missing.join(", ")}`); + } + return replacements.reduce((patched, [original, replacement]) => patched.replace(original, replacement), source); +} + export function patchPiTuiSource(source) { if (source.includes("line = sliceByColumn(line, 0, width, true);")) { return source; @@ -281,10 +408,27 @@ export function patchPiTuiSource(source) { if (source.includes(OVERFLOW_THROW_BLOCK_AFTER_CLEAR)) { return source.replace(OVERFLOW_THROW_BLOCK_AFTER_CLEAR, OVERFLOW_TRUNCATE_BLOCK_AFTER_CLEAR); } - return source; + if (source.includes(OVERFLOW_THROW_BLOCK_AFTER_CLEAR_CURRENT)) { + return source.replace(OVERFLOW_THROW_BLOCK_AFTER_CLEAR_CURRENT, OVERFLOW_TRUNCATE_BLOCK_AFTER_CLEAR); + } + throw new Error("Unsupported Pi TUI layout: required overflow patch anchor was not found"); } export function patchPiEditorSource(source) { + if (source.includes(CURRENT_EDITOR_IMPORT) && !source.includes("const styleInput = typeof this.theme.input")) { + return patchCurrentEditorSource(source); + } + if (source.includes("const styleInput = typeof this.theme.input")) { + return source + .replace( + ' const cursor = `\\x1b[7m${firstGrapheme}\\x1b[0m`;', + ' const cursor = `\\x1b[7m${firstGrapheme}\\x1b[27m`;', + ) + .replace( + ' const cursor = "\\x1b[7m \\x1b[0m";', + ' const cursor = "\\x1b[7m \\x1b[27m";', + ); + } let patched = source; let importsPatched = patched.includes("applyBackgroundToLine,"); for (const [original, replacement] of EDITOR_IMPORT_PAIRS) { @@ -293,18 +437,17 @@ export function patchPiEditorSource(source) { importsPatched = true; } } - if (patched.includes("const styleInput = typeof this.theme.input")) { - return patched; - } if (!importsPatched) { - // Unknown upstream layout: leave render() untouched rather than emit a - // body that references applyBackgroundToLine without importing it. - return source; + throw new Error("Unsupported Pi editor layout: required import patch anchor was not found"); } - return patched.replace( + const rendered = patched.replace( / render\(width\) \{[\s\S]*?\n handleInput\(data\) \{/m, `${EDITOR_RENDER_BLOCK}\n handleInput(data) {`, ); + if (rendered === patched || !rendered.includes("const styleInput = typeof this.theme.input")) { + throw new Error("Unsupported Pi editor layout: required render patch anchor was not found"); + } + return rendered; } export function patchPiInteractiveThemeSource(source) { @@ -314,8 +457,16 @@ export function patchPiInteractiveThemeSource(source) { ) { return source; } - return source.replace( + const patched = source.replace( /export function getEditorTheme\(\) \{[\s\S]*?\n\}\nexport function getSettingsListTheme\(\) \{/m, `${EDITOR_THEME_BLOCK}\nexport function getSettingsListTheme() {`, ); + if ( + patched === source || + !patched.includes('bgColor: (text) => theme.bg("userMessageBg", text),') || + !patched.includes('input: (text) => theme.fg("text", text),') + ) { + throw new Error("Unsupported Pi interactive theme layout: required editor-theme patch anchor was not found"); + } + return patched; } diff --git a/scripts/lib/pi-web-access-patch.mjs b/scripts/lib/pi-web-access-patch.mjs index 4adb9c63..652c1bba 100644 --- a/scripts/lib/pi-web-access-patch.mjs +++ b/scripts/lib/pi-web-access-patch.mjs @@ -8,13 +8,31 @@ export const PI_WEB_ACCESS_PATCH_TARGETS = [ "gemini-web.ts", "github-extract.ts", "perplexity.ts", + "pdf-extract.ts", "video-extract.ts", "youtube-extract.ts", + "utils.ts", ]; const LEGACY_CONFIG_EXPR = 'join(homedir(), ".pi", "web-search.json")'; const PATCHED_CONFIG_EXPR = 'process.env.FEYNMAN_WEB_SEARCH_CONFIG ?? process.env.PI_WEB_SEARCH_CONFIG ?? join(homedir(), ".pi", "web-search.json")'; +const LEGACY_PDF_OUTPUT_DIR = 'const DEFAULT_OUTPUT_DIR = join(homedir(), "Downloads");'; +const PATCHED_PDF_OUTPUT_DIR = [ + "const DEFAULT_OUTPUT_DIR =", + ' process.env.FEYNMAN_FETCH_CACHE_DIR?.trim() || join(process.cwd(), ".feynman", "cache", "fetch-content");', +].join("\n"); +const CONFIG_PATH_HELPER = [ + "export function getWebSearchConfigPath(): string {", + '\treturn join(getWebSearchConfigDir(), "web-search.json");', + "}", +].join("\n"); +const PATCHED_CONFIG_PATH_HELPER = [ + "export function getWebSearchConfigPath(): string {", + "\tconst configuredPath = process.env.FEYNMAN_WEB_SEARCH_CONFIG?.trim() || process.env.PI_WEB_SEARCH_CONFIG?.trim();", + '\treturn configuredPath || join(getWebSearchConfigDir(), "web-search.json");', + "}", +].join("\n"); function patchGeminiWebSource(source) { let patched = source; @@ -381,5 +399,20 @@ export function patchPiWebAccessSource(relativePath, source) { } } + if (relativePath === "pdf-extract.ts") { + if (patched.includes(LEGACY_PDF_OUTPUT_DIR)) { + patched = patched.replace(LEGACY_PDF_OUTPUT_DIR, PATCHED_PDF_OUTPUT_DIR); + changed = true; + } + if (patched.includes('import { homedir } from "node:os";') && patched.includes(PATCHED_PDF_OUTPUT_DIR)) { + patched = patched.replace('import { homedir } from "node:os";\n', ""); + changed = true; + } + } + + if (relativePath === "utils.ts" && patched.includes(CONFIG_PATH_HELPER)) { + patched = patched.replace(CONFIG_PATH_HELPER, PATCHED_CONFIG_PATH_HELPER); + } + return patched; } diff --git a/scripts/lib/runtime-workspace-integrity.d.mts b/scripts/lib/runtime-workspace-integrity.d.mts new file mode 100644 index 00000000..ae8e1ea2 --- /dev/null +++ b/scripts/lib/runtime-workspace-integrity.d.mts @@ -0,0 +1,40 @@ +export declare const RUNTIME_INPUT_FILES: readonly string[]; + +export declare function parseExactRuntimePackageSpec(spec: string): { + name: string; + version: string; +}; + +export declare function workspacePackagesMatch( + nodeModulesPath: string, + packageSpecs: string[], +): boolean; +export declare function runtimeManifestPackagesMatch( + nodeModulesPath: string, + manifestPackageSpecs: string[], + configuredPackageSpecs?: string[], +): boolean; + +export declare function computeFileSha256(path: string): string; +export declare function computeRuntimeInputHash( + rootPath: string, + inputFiles?: readonly string[], +): string; +export declare function computeRuntimeTreeHash(rootPath: string): string; +export declare function computeRuntimeArchiveTreeHash(archivePath: string): string; +export declare function writeFileSha256(path: string, digestPath: string): string; +export declare function verifyFileSha256(path: string, digestPath: string): boolean; +export declare function filesMatch(leftPath: string, rightPath: string): boolean; +export declare function readArchiveEntry( + archivePath: string, + entryPath: string, +): string | undefined; + +export declare function runtimeArchiveMatches(options: { + archivePath: string; + digestPath: string; + lockPath: string; + manifestPath: string; + packageSpecs: string[]; + runtimeInputHash: string; +}): boolean; diff --git a/scripts/lib/runtime-workspace-integrity.mjs b/scripts/lib/runtime-workspace-integrity.mjs new file mode 100644 index 00000000..755a990d --- /dev/null +++ b/scripts/lib/runtime-workspace-integrity.mjs @@ -0,0 +1,464 @@ +import { createHash } from "node:crypto"; +import { + existsSync, + lstatSync, + readFileSync, + readdirSync, + readlinkSync, + writeFileSync, +} from "node:fs"; +import { dirname, relative, resolve, sep } from "node:path"; +import { gunzipSync } from "node:zlib"; + +export const RUNTIME_INPUT_FILES = Object.freeze([ + "scripts/prepare-runtime-workspace.mjs", + "scripts/prune-runtime-deps.mjs", + "package.json", + ".feynman/runtime-package-lock.json", + ".feynman/settings.json", + "scripts/lib/pi-agent-core-patch.mjs", + "scripts/lib/pi-extension-loader-patch.mjs", + "scripts/lib/pi-tui-patch.mjs", + "scripts/lib/pi-web-access-patch.mjs", + "scripts/lib/pi-subagents-patch.mjs", + "scripts/lib/pi-otel-patch.mjs", + "scripts/lib/pi-session-search-patch.mjs", + "scripts/lib/pi-model-registry-patch.mjs", + "scripts/lib/pi-shrinkwrap-security-patch.mjs", + "scripts/lib/alpha-hub-auth-patch.mjs", + "scripts/lib/alpha-hub-search-patch.mjs", + "scripts/lib/mcp-sdk-package-patch.mjs", + "scripts/lib/deterministic-archive.mjs", + "scripts/lib/runtime-workspace-integrity.mjs", +]); + +const RUNTIME_TREE_EXCLUDES = new Set([".runtime-manifest.json"]); + +export function parseExactRuntimePackageSpec(spec) { + const separator = spec.lastIndexOf("@"); + if (separator <= 0 || separator === spec.length - 1) { + throw new Error(`Runtime package must use an exact spec: ${spec}`); + } + return { + name: spec.slice(0, separator), + version: spec.slice(separator + 1), + }; +} + +function readPackageVersion(packageJsonPath) { + try { + const manifest = JSON.parse(readFileSync(packageJsonPath, "utf8")); + return typeof manifest.version === "string" ? manifest.version : undefined; + } catch { + return undefined; + } +} + +export function workspacePackagesMatch(nodeModulesPath, packageSpecs) { + return packageSpecs.every((spec) => { + const { name, version } = parseExactRuntimePackageSpec(spec); + return readPackageVersion(resolve(nodeModulesPath, ...name.split("/"), "package.json")) === version; + }); +} + +export function runtimeManifestPackagesMatch( + nodeModulesPath, + manifestPackageSpecs, + configuredPackageSpecs = manifestPackageSpecs, +) { + if (!configuredPackageSpecs.every((spec) => manifestPackageSpecs.includes(spec))) { + return false; + } + return workspacePackagesMatch(nodeModulesPath, manifestPackageSpecs); +} + +export function computeFileSha256(path) { + return createHash("sha256").update(readFileSync(path)).digest("hex"); +} + +function normalizeRelativePath(path) { + const normalized = path.split(sep).join("/").replace(/^\.\//, ""); + if ( + !normalized || + normalized.startsWith("/") || + normalized === ".." || + normalized.startsWith("../") || + normalized.includes("/../") + ) { + throw new Error(`Expected a normalized relative path, received: ${path}`); + } + return normalized; +} + +export function computeRuntimeInputHash(rootPath, inputFiles = RUNTIME_INPUT_FILES) { + const hash = createHash("sha256"); + for (const label of [...new Set(inputFiles.map(normalizeRelativePath))].sort()) { + const path = resolve(rootPath, ...label.split("/")); + hash.update(label); + hash.update("\0"); + hash.update(existsSync(path) ? computeFileSha256(path) : "missing"); + hash.update("\0"); + } + return hash.digest("hex"); +} + +function collectRuntimeTreeEntries(rootPath, currentPath, entries) { + for (const entry of readdirSync(currentPath, { withFileTypes: true })) { + const path = resolve(currentPath, entry.name); + const label = normalizeRelativePath(relative(rootPath, path)); + if (RUNTIME_TREE_EXCLUDES.has(label)) continue; + + const stat = lstatSync(path); + if (stat.isDirectory()) { + collectRuntimeTreeEntries(rootPath, path, entries); + continue; + } + if (stat.isSymbolicLink()) { + entries.push({ + label, + type: "symlink", + value: readlinkSync(path).split(sep).join("/"), + }); + continue; + } + if (stat.isFile()) { + entries.push({ + label, + type: "file", + value: computeFileSha256(path), + }); + continue; + } + throw new Error(`Unsupported runtime workspace entry: ${path}`); + } +} + +export function computeRuntimeTreeHash(rootPath) { + if (!existsSync(rootPath)) { + throw new Error(`Runtime workspace does not exist: ${rootPath}`); + } + const entries = []; + collectRuntimeTreeEntries(rootPath, rootPath, entries); + entries.sort((left, right) => left.label.localeCompare(right.label)); + + const hash = createHash("sha256"); + for (const entry of entries) { + hash.update(entry.label); + hash.update("\0"); + hash.update(entry.type); + hash.update("\0"); + hash.update(entry.value); + hash.update("\0"); + } + return hash.digest("hex"); +} + +export function computeRuntimeArchiveTreeHash(archivePath) { + const tarball = gunzipSync(readFileSync(archivePath)); + const entries = []; + let offset = 0; + let nextPax = {}; + let nextLongPath; + let sawWorkspace = false; + + while (offset + 512 <= tarball.length) { + const header = tarball.subarray(offset, offset + 512); + if (header.every((byte) => byte === 0)) break; + + const readField = (start, length) => + header.subarray(start, start + length).toString("utf8").replace(/\0.*$/s, ""); + const sizeSource = readField(124, 12).trim(); + const size = sizeSource ? Number.parseInt(sizeSource, 8) : 0; + if (!Number.isSafeInteger(size) || size < 0) { + throw new Error(`Invalid runtime archive entry size at byte ${offset}`); + } + const type = String.fromCharCode(header[156] || 48); + const contentStart = offset + 512; + const contentEnd = contentStart + size; + if (contentEnd > tarball.length) { + throw new Error(`Truncated runtime archive entry at byte ${offset}`); + } + const content = tarball.subarray(contentStart, contentEnd); + const prefix = readField(345, 155); + const headerPath = [prefix, readField(0, 100)].filter(Boolean).join("/"); + const headerLink = readField(157, 100); + + if (type === "x" || type === "g") { + const pax = {}; + let paxOffset = 0; + while (paxOffset < content.length) { + const space = content.indexOf(0x20, paxOffset); + if (space === -1) throw new Error("Invalid PAX record length"); + const recordLength = Number.parseInt( + content.subarray(paxOffset, space).toString("ascii"), + 10, + ); + if (!Number.isSafeInteger(recordLength) || recordLength <= 0) { + throw new Error("Invalid PAX record size"); + } + const recordEnd = paxOffset + recordLength; + const record = content.subarray(space + 1, recordEnd - 1).toString("utf8"); + const equals = record.indexOf("="); + if (equals > 0) pax[record.slice(0, equals)] = record.slice(equals + 1); + paxOffset = recordEnd; + } + nextPax = type === "g" ? { ...nextPax, ...pax } : pax; + } else if (type === "L") { + nextLongPath = content.toString("utf8").replace(/\0.*$/s, ""); + } else { + const archivePath = nextPax.path ?? nextLongPath ?? headerPath; + const linkPath = nextPax.linkpath ?? headerLink; + nextPax = {}; + nextLongPath = undefined; + if (archivePath === "npm" || archivePath === "npm/") { + sawWorkspace = true; + } else if (archivePath.startsWith("npm/")) { + sawWorkspace = true; + const label = normalizeRelativePath(archivePath.slice("npm/".length)); + if (!RUNTIME_TREE_EXCLUDES.has(label)) { + if (type === "0" || type === "\0") { + entries.push({ + label, + type: "file", + value: createHash("sha256").update(content).digest("hex"), + }); + } else if (type === "2") { + entries.push({ label, type: "symlink", value: linkPath }); + } else if (type === "1") { + const targetPath = linkPath.replace(/^\.\//, ""); + if (!targetPath.startsWith("npm/")) { + throw new Error( + `Runtime archive hardlink target is outside npm/: ${linkPath}`, + ); + } + entries.push({ + label, + type: "hardlink", + value: normalizeRelativePath(targetPath.slice("npm/".length)), + }); + } else if (type !== "5") { + throw new Error(`Unsupported runtime archive entry type ${type}: ${archivePath}`); + } + } + } else { + throw new Error(`Runtime archive entry is outside npm/: ${archivePath}`); + } + } + + offset = contentStart + Math.ceil(size / 512) * 512; + } + if (!sawWorkspace) throw new Error("Runtime archive does not contain the npm workspace"); + const entriesByLabel = new Map(); + for (const entry of entries) { + if (entriesByLabel.has(entry.label)) { + throw new Error(`Duplicate runtime archive entry: ${entry.label}`); + } + entriesByLabel.set(entry.label, entry); + } + const resolveHardlink = (entry, seen = new Set()) => { + if (entry.type !== "hardlink") return entry; + if (seen.has(entry.label)) { + throw new Error(`Runtime archive hardlink cycle: ${[...seen, entry.label].join(" -> ")}`); + } + const target = entriesByLabel.get(entry.value); + if (!target) { + throw new Error( + `Runtime archive hardlink target is missing: ${entry.label} -> ${entry.value}`, + ); + } + return resolveHardlink(target, new Set([...seen, entry.label])); + }; + const normalizedEntries = entries.map((entry) => { + const resolved = resolveHardlink(entry); + return { + label: entry.label, + type: resolved.type, + value: resolved.value, + }; + }); + normalizedEntries.sort((left, right) => left.label.localeCompare(right.label)); + const hash = createHash("sha256"); + for (const entry of normalizedEntries) { + hash.update(entry.label); + hash.update("\0"); + hash.update(entry.type); + hash.update("\0"); + hash.update(entry.value); + hash.update("\0"); + } + return hash.digest("hex"); +} + +export function writeFileSha256(path, digestPath) { + const digest = computeFileSha256(path); + writeFileSync(digestPath, `${digest} ${path.split(/[\\/]/).at(-1)}\n`, "utf8"); + return digest; +} + +export function verifyFileSha256(path, digestPath) { + if (!existsSync(path) || !existsSync(digestPath)) { + return false; + } + const expected = readFileSync(digestPath, "utf8").trim().split(/\s+/, 1)[0]; + return /^[a-f0-9]{64}$/.test(expected) && computeFileSha256(path) === expected; +} + +export function filesMatch(leftPath, rightPath) { + if (!existsSync(leftPath) || !existsSync(rightPath)) { + return false; + } + return readFileSync(leftPath).equals(readFileSync(rightPath)); +} + +export function readArchiveEntry(archivePath, entryPath) { + const tarball = gunzipSync(readFileSync(archivePath)); + const requestedPath = entryPath.replace(/^\.\//, "").replace(/\/$/, ""); + const entries = new Map(); + let offset = 0; + let globalPax = {}; + let nextPax = {}; + let nextLongPath; + + while (offset + 512 <= tarball.length) { + const header = tarball.subarray(offset, offset + 512); + if (header.every((byte) => byte === 0)) break; + + const readField = (start, length) => + header.subarray(start, start + length).toString("utf8").replace(/\0.*$/s, ""); + const sizeSource = readField(124, 12).trim(); + const size = sizeSource ? Number.parseInt(sizeSource, 8) : 0; + if (!Number.isSafeInteger(size) || size < 0) { + throw new Error(`Invalid runtime archive entry size at byte ${offset}`); + } + const type = String.fromCharCode(header[156] || 48); + const contentStart = offset + 512; + const contentEnd = contentStart + size; + if (contentEnd > tarball.length) { + throw new Error(`Truncated runtime archive entry at byte ${offset}`); + } + const content = tarball.subarray(contentStart, contentEnd); + const prefix = readField(345, 155); + const headerPath = [prefix, readField(0, 100)].filter(Boolean).join("/"); + const headerLink = readField(157, 100); + + if (type === "x" || type === "g") { + const pax = {}; + let paxOffset = 0; + while (paxOffset < content.length) { + const space = content.indexOf(0x20, paxOffset); + if (space === -1) throw new Error("Invalid PAX record length"); + const recordLength = Number.parseInt( + content.subarray(paxOffset, space).toString("ascii"), + 10, + ); + if (!Number.isSafeInteger(recordLength) || recordLength <= 0) { + throw new Error("Invalid PAX record size"); + } + const recordEnd = paxOffset + recordLength; + const record = content.subarray(space + 1, recordEnd - 1).toString("utf8"); + const equals = record.indexOf("="); + if (equals > 0) pax[record.slice(0, equals)] = record.slice(equals + 1); + paxOffset = recordEnd; + } + if (type === "g") globalPax = { ...globalPax, ...pax }; + else nextPax = pax; + } else if (type === "L") { + nextLongPath = content.toString("utf8").replace(/\0.*$/s, ""); + } else { + const pax = { ...globalPax, ...nextPax }; + const archiveEntryPath = (pax.path ?? nextLongPath ?? headerPath) + .replace(/^\.\//, "") + .replace(/\/$/, ""); + const linkPath = (pax.linkpath ?? headerLink).replace(/^\.\//, ""); + nextPax = {}; + nextLongPath = undefined; + + if (type === "0" || type === "\0") { + if (archiveEntryPath === requestedPath) return content.toString("utf8"); + entries.set(archiveEntryPath, { type: "file", content }); + } else if (type === "1") { + entries.set(archiveEntryPath, { type: "hardlink", target: linkPath }); + } + } + + offset = contentStart + Math.ceil(size / 512) * 512; + } + + const resolveEntry = (path, seen = new Set()) => { + const entry = entries.get(path); + if (!entry) return undefined; + if (entry.type === "file") return entry.content; + if (seen.has(path)) { + throw new Error(`Runtime archive hardlink cycle: ${[...seen, path].join(" -> ")}`); + } + return resolveEntry(entry.target, new Set([...seen, path])); + }; + return resolveEntry(requestedPath)?.toString("utf8"); +} + +export function runtimeArchiveMatches({ + archivePath, + digestPath, + lockPath, + manifestPath, + packageSpecs, + runtimeInputHash, +}) { + if ( + !verifyFileSha256(archivePath, digestPath) || + !existsSync(lockPath) || + !existsSync(manifestPath) + ) { + return false; + } + const archivedLock = readArchiveEntry(archivePath, "npm/package-lock.json"); + if (archivedLock === undefined || archivedLock !== readFileSync(lockPath, "utf8")) { + return false; + } + const manifestSource = readFileSync(manifestPath, "utf8"); + if (readArchiveEntry(archivePath, "npm/.runtime-manifest.json") !== manifestSource) { + return false; + } + let manifest; + try { + manifest = JSON.parse(manifestSource); + } catch { + return false; + } + if ( + typeof runtimeInputHash !== "string" || + manifest.runtimeInputHash !== runtimeInputHash || + typeof manifest.runtimeTreeHash !== "string" || + !/^[a-f0-9]{64}$/.test(manifest.runtimeTreeHash) || + (typeof manifest.workspaceTreeHash !== "undefined" && + (typeof manifest.workspaceTreeHash !== "string" || + !/^[a-f0-9]{64}$/.test(manifest.workspaceTreeHash))) + ) { + return false; + } + try { + const workspacePath = dirname(manifestPath); + if ( + computeRuntimeTreeHash(workspacePath) !== + (manifest.workspaceTreeHash ?? manifest.runtimeTreeHash) || + computeRuntimeArchiveTreeHash(archivePath) !== manifest.runtimeTreeHash + ) { + return false; + } + } catch { + return false; + } + return packageSpecs.every((spec) => { + const { name, version } = parseExactRuntimePackageSpec(spec); + const source = readArchiveEntry( + archivePath, + `npm/node_modules/${name}/package.json`, + ); + if (!source) return false; + try { + return JSON.parse(source).version === version; + } catch { + return false; + } + }); +} diff --git a/scripts/patch-embedded-pi.mjs b/scripts/patch-embedded-pi.mjs index c95ec7ff..4b8425b6 100644 --- a/scripts/patch-embedded-pi.mjs +++ b/scripts/patch-embedded-pi.mjs @@ -7,11 +7,17 @@ import { fileURLToPath } from "node:url"; import { FEYNMAN_LOGO_HTML } from "../logo.mjs"; import { patchAlphaHubAuthSource } from "./lib/alpha-hub-auth-patch.mjs"; import { patchAlphaHubSearchResultsSource, patchAlphaHubSearchSource } from "./lib/alpha-hub-search-patch.mjs"; +import { patchMcpSdkPackageJsonSource } from "./lib/mcp-sdk-package-patch.mjs"; import { patchPiAgentCoreSource } from "./lib/pi-agent-core-patch.mjs"; import { patchPiExtensionLoaderSource } from "./lib/pi-extension-loader-patch.mjs"; import { resolveAdjacentNpmCommand } from "./lib/npm-command.mjs"; import { patchPiModelRegistrySource } from "./lib/pi-model-registry-patch.mjs"; +import { patchPiBraceExpansionTree } from "./lib/pi-shrinkwrap-security-patch.mjs"; import { patchPiEditorSource, patchPiInteractiveThemeSource, patchPiTuiSource } from "./lib/pi-tui-patch.mjs"; +import { + runtimeManifestPackagesMatch, + verifyFileSha256, +} from "./lib/runtime-workspace-integrity.mjs"; import { PI_WEB_ACCESS_PATCH_TARGETS, patchPiWebAccessSource } from "./lib/pi-web-access-patch.mjs"; import { PI_SUBAGENTS_PATCH_TARGETS, patchPiSubagentsSource, stripPiSubagentBuiltinModelSource } from "./lib/pi-subagents-patch.mjs"; import { PI_OTEL_PATCH_TARGETS, patchPiOtelSource } from "./lib/pi-otel-patch.mjs"; @@ -75,6 +81,7 @@ const interactiveModePath = piPackageRoot ? resolve(piPackageRoot, "dist", "mode const interactiveThemePath = piPackageRoot ? resolve(piPackageRoot, "dist", "modes", "interactive", "theme", "theme.js") : null; const extensionLoaderPath = piPackageRoot ? resolve(piPackageRoot, "dist", "core", "extensions", "loader.js") : null; const modelRegistryPath = piPackageRoot ? resolve(piPackageRoot, "dist", "core", "model-registry.js") : null; +const modelRuntimePath = piPackageRoot ? resolve(piPackageRoot, "dist", "core", "model-runtime.js") : null; const agentLoopPath = piAgentCoreRoot ? resolve(piAgentCoreRoot, "dist", "agent-loop.js") : null; const tuiPath = piTuiRoot ? resolve(piTuiRoot, "dist", "tui.js") : null; const terminalPath = piTuiRoot ? resolve(piTuiRoot, "dist", "terminal.js") : null; @@ -121,14 +128,30 @@ const workspaceDir = resolve(appRoot, ".feynman", "npm"); const workspacePackageJsonPath = resolve(workspaceDir, "package.json"); const workspaceManifestPath = resolve(workspaceDir, ".runtime-manifest.json"); const workspaceArchivePath = resolve(appRoot, ".feynman", "runtime-workspace.tgz"); +const workspaceArchiveDigestPath = resolve(appRoot, ".feynman", "runtime-workspace.sha256"); const workspaceNpmConfigPath = resolve(workspaceDir, ".npmrc"); const workspaceSetupLockDir = resolve(appRoot, ".feynman", ".workspace-setup.lock"); const globalNodeModulesRoot = resolve(feynmanNpmPrefix, "lib", "node_modules"); -const PRUNE_VERSION = 6; +const PRUNE_VERSION = 8; const WORKSPACE_SETUP_LOCK_STALE_MS = 300000; const NATIVE_PACKAGE_SPECS = new Set([ "@kaiserlich-dev/pi-session-search", ]); + +function patchMcpSdkManifest(nodeModulesRoot) { + const manifestPath = resolve( + nodeModulesRoot, + "@modelcontextprotocol", + "sdk", + "package.json", + ); + if (!existsSync(manifestPath)) return; + const source = readFileSync(manifestPath, "utf8"); + const patched = patchMcpSdkPackageJsonSource(source); + if (patched !== source) { + writeFileSync(manifestPath, patched, "utf8"); + } +} const FILTERED_INSTALL_OUTPUT_PATTERNS = [ /npm warn deprecated node-domexception@1\.0\.0/i, /npm notice/i, @@ -137,10 +160,6 @@ const FILTERED_INSTALL_OUTPUT_PATTERNS = [ /^run `npm fund` for details$/i, ]; -function arraysMatch(left, right) { - return left.length === right.length && left.every((value, index) => value === right[index]); -} - function supportsNativePackageSources(version = process.versions.node) { const [major = "0"] = version.replace(/^v/, "").split("."); return (Number.parseInt(major, 10) || 0) <= 22; @@ -254,10 +273,6 @@ function filterUnsupportedPackageSpecs(packageSpecs) { return packageSpecs.filter((spec) => !NATIVE_PACKAGE_SPECS.has(parsePackageName(spec))); } -function workspaceContainsPackages(packageSpecs) { - return packageSpecs.every((spec) => existsSync(resolve(workspaceRoot, parsePackageName(spec)))); -} - function workspaceMatchesRuntime(packageSpecs) { if (!existsSync(workspaceManifestPath)) return false; @@ -266,12 +281,11 @@ function workspaceMatchesRuntime(packageSpecs) { if (!Array.isArray(manifest.packageSpecs)) { return false; } - if (!arraysMatch(manifest.packageSpecs, packageSpecs)) { - if (!(workspaceContainsPackages(packageSpecs) && packageSpecs.every((spec) => manifest.packageSpecs.includes(spec)))) { - return false; - } + const manifestPackageSpecs = filterUnsupportedPackageSpecs(manifest.packageSpecs); + if (!runtimeManifestPackagesMatch(workspaceRoot, manifestPackageSpecs, packageSpecs)) { + return false; } - if (!supportsNativePackageSources() && workspaceContainsPackages(packageSpecs)) { + if (!supportsNativePackageSources()) { return true; } if ( @@ -283,7 +297,7 @@ function workspaceMatchesRuntime(packageSpecs) { return false; } - return packageSpecs.every((spec) => existsSync(resolve(workspaceRoot, parsePackageName(spec)))); + return true; } catch { return false; } @@ -429,6 +443,9 @@ function ensureBundledPackageLinks(packageSpecs) { function restorePackagedWorkspace(packageSpecs) { if (!existsSync(workspaceArchivePath)) return false; + if (!verifyFileSha256(workspaceArchivePath, workspaceArchiveDigestPath)) { + throw new Error("Bundled runtime archive failed its SHA-256 integrity check"); + } rmSync(workspaceDir, { recursive: true, force: true }); mkdirSync(resolve(appRoot, ".feynman"), { recursive: true }); @@ -774,7 +791,8 @@ for (const loaderPath of [extensionLoaderPath, workspaceExtensionLoaderPath].fil const workspaceModelRegistryPath = resolveWorkspacePiFile("pi-coding-agent", "dist", "core", "model-registry.js"); -for (const entryPath of [modelRegistryPath, workspaceModelRegistryPath].filter(Boolean)) { +const workspaceModelRuntimePath = resolveWorkspacePiFile("pi-coding-agent", "dist", "core", "model-runtime.js"); +for (const entryPath of [modelRegistryPath, modelRuntimePath, workspaceModelRegistryPath, workspaceModelRuntimePath].filter(Boolean)) { if (!existsSync(entryPath)) continue; const source = readFileSync(entryPath, "utf8"); const patched = patchPiModelRegistrySource(source); @@ -783,6 +801,18 @@ for (const entryPath of [modelRegistryPath, workspaceModelRegistryPath].filter(B } } +const safeBraceExpansionPath = resolve(appRoot, "node_modules", "brace-expansion"); +patchPiBraceExpansionTree(resolve(appRoot, "node_modules"), safeBraceExpansionPath); +patchPiBraceExpansionTree(workspaceRoot, safeBraceExpansionPath); +for (const nodeModulesRoot of [ + resolve(appRoot, "node_modules"), + resolve(appRoot, "node_modules", "@companion-ai", "alpha-hub", "node_modules"), + workspaceRoot, + resolve(workspaceRoot, "@companion-ai", "alpha-hub", "node_modules"), +]) { + patchMcpSdkManifest(nodeModulesRoot); +} + for (const entryPath of [agentLoopPath, workspaceAgentLoopPath].filter(Boolean)) { if (!existsSync(entryPath)) { continue; diff --git a/scripts/prepare-runtime-workspace.mjs b/scripts/prepare-runtime-workspace.mjs index 41a92617..e65c604c 100644 --- a/scripts/prepare-runtime-workspace.mjs +++ b/scripts/prepare-runtime-workspace.mjs @@ -1,62 +1,82 @@ -import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs"; -import { createHash } from "node:crypto"; +import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from "node:fs"; import { dirname, relative, resolve } from "node:path"; import { spawnSync } from "node:child_process"; import { patchPiAgentCoreSource } from "./lib/pi-agent-core-patch.mjs"; import { patchPiExtensionLoaderSource } from "./lib/pi-extension-loader-patch.mjs"; +import { patchPiModelRegistrySource } from "./lib/pi-model-registry-patch.mjs"; +import { patchPiBraceExpansionTree } from "./lib/pi-shrinkwrap-security-patch.mjs"; import { patchPiEditorSource, patchPiInteractiveThemeSource, patchPiTuiSource } from "./lib/pi-tui-patch.mjs"; import { PI_WEB_ACCESS_PATCH_TARGETS, patchPiWebAccessSource } from "./lib/pi-web-access-patch.mjs"; import { PI_SUBAGENTS_PATCH_TARGETS, patchPiSubagentsSource, stripPiSubagentBuiltinModelSource } from "./lib/pi-subagents-patch.mjs"; import { PI_OTEL_PATCH_TARGETS, patchPiOtelSource } from "./lib/pi-otel-patch.mjs"; import { PI_SESSION_SEARCH_PATCH_TARGETS, patchPiSessionSearchSource } from "./lib/pi-session-search-patch.mjs"; +import { patchAlphaHubAuthSource } from "./lib/alpha-hub-auth-patch.mjs"; import { patchAlphaHubSearchSource } from "./lib/alpha-hub-search-patch.mjs"; +import { patchMcpSdkPackageJsonSource } from "./lib/mcp-sdk-package-patch.mjs"; +import { createDeterministicTarGz } from "./lib/deterministic-archive.mjs"; +import { + computeRuntimeArchiveTreeHash, + computeRuntimeInputHash, + computeRuntimeTreeHash, + filesMatch, + runtimeArchiveMatches, + workspacePackagesMatch, + writeFileSha256, +} from "./lib/runtime-workspace-integrity.mjs"; const appRoot = resolve(import.meta.dirname, ".."); const settingsPath = resolve(appRoot, ".feynman", "settings.json"); const packageJsonPath = resolve(appRoot, "package.json"); const packageLockPath = resolve(appRoot, "package-lock.json"); const feynmanDir = resolve(appRoot, ".feynman"); +const runtimePackageLockPath = resolve(feynmanDir, "runtime-package-lock.json"); const workspaceDir = resolve(appRoot, ".feynman", "npm"); const workspaceNodeModulesDir = resolve(workspaceDir, "node_modules"); const manifestPath = resolve(workspaceDir, ".runtime-manifest.json"); const workspacePackageJsonPath = resolve(workspaceDir, "package.json"); const workspaceNpmConfigPath = resolve(workspaceDir, ".npmrc"); const workspaceArchivePath = resolve(feynmanDir, "runtime-workspace.tgz"); +const workspaceArchiveDigestPath = resolve(feynmanDir, "runtime-workspace.sha256"); const PRUNE_VERSION = 8; -const PI_RUNTIME_FALLBACK_VERSION = "0.80.3"; +const PI_RUNTIME_FALLBACK_VERSION = "0.82.1"; const RUNTIME_PACKAGE_OVERRIDES = { "@mozilla/readability": "0.6.0", - "@opentelemetry/core": "2.8.0", - "@opentelemetry/exporter-logs-otlp-grpc": "0.219.0", - "@opentelemetry/exporter-logs-otlp-http": "0.219.0", - "@opentelemetry/exporter-logs-otlp-proto": "0.219.0", - "@opentelemetry/exporter-metrics-otlp-grpc": "0.219.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.219.0", - "@opentelemetry/exporter-metrics-otlp-proto": "0.219.0", - "@opentelemetry/exporter-prometheus": "0.219.0", - "@opentelemetry/exporter-trace-otlp-grpc": "0.219.0", - "@opentelemetry/exporter-trace-otlp-http": "0.219.0", - "@opentelemetry/exporter-trace-otlp-proto": "0.219.0", - "@opentelemetry/exporter-zipkin": "2.8.0", - "@opentelemetry/instrumentation": "0.219.0", - "@opentelemetry/otlp-exporter-base": "0.219.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.219.0", - "@opentelemetry/otlp-transformer": "0.219.0", - "@opentelemetry/propagator-b3": "2.8.0", - "@opentelemetry/propagator-jaeger": "2.8.0", - "@opentelemetry/resources": "2.8.0", - "@opentelemetry/sdk-logs": "0.219.0", - "@opentelemetry/sdk-metrics": "2.8.0", - "@opentelemetry/sdk-node": "0.219.0", - "@opentelemetry/sdk-trace-base": "2.8.0", - "@opentelemetry/sdk-trace-node": "2.8.0", + "@modelcontextprotocol/sdk": { + "@hono/node-server": "2.0.12", + }, + "@opentelemetry/core": "2.10.0", + "@opentelemetry/exporter-logs-otlp-grpc": "0.221.0", + "@opentelemetry/exporter-logs-otlp-http": "0.221.0", + "@opentelemetry/exporter-logs-otlp-proto": "0.221.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.221.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.221.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.221.0", + "@opentelemetry/exporter-prometheus": "0.221.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.221.0", + "@opentelemetry/exporter-trace-otlp-http": "0.221.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.221.0", + "@opentelemetry/exporter-zipkin": "2.10.0", + "@opentelemetry/instrumentation": "0.221.0", + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/propagator-b3": "2.10.0", + "@opentelemetry/propagator-jaeger": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-logs": "0.221.0", + "@opentelemetry/sdk-metrics": "2.10.0", + "@opentelemetry/sdk-node": "0.221.0", + "@opentelemetry/sdk-trace-base": "2.10.0", + "@opentelemetry/sdk-trace-node": "2.10.0", + "brace-expansion": "5.0.8", }; const PINNED_RUNTIME_PACKAGES = [ "@earendil-works/pi-agent-core", "@earendil-works/pi-ai", "@earendil-works/pi-coding-agent", "@earendil-works/pi-tui", + "brace-expansion", "typebox", ]; const LEGACY_PI_RUNTIME_PACKAGE_ALIASES = { @@ -79,6 +99,17 @@ function parsePackageName(spec) { return match?.[1] ?? spec; } +function runtimeDependencies(packageSpecs) { + return Object.fromEntries(packageSpecs.map((spec) => { + const name = parsePackageName(spec); + const version = spec.startsWith(`${name}@`) ? spec.slice(name.length + 1) : ""; + if (!version) { + throw new Error(`Runtime package must use an exact spec: ${spec}`); + } + return [name, version]; + })); +} + function filterUnsupportedPackageSpecs(packageSpecs) { if (supportsNativePackageSources()) return packageSpecs; return packageSpecs.filter((spec) => !NATIVE_PACKAGE_SPECS.has(parsePackageName(spec))); @@ -118,41 +149,17 @@ function arraysMatch(left, right) { return left.length === right.length && left.every((value, index) => value === right[index]); } -function hashFile(path) { - if (!existsSync(path)) { - return null; - } - return createHash("sha256").update(readFileSync(path)).digest("hex"); -} - function getRuntimeInputHash() { - const hash = createHash("sha256"); - for (const path of [ - resolve(appRoot, "scripts", "prepare-runtime-workspace.mjs"), - packageJsonPath, - packageLockPath, - settingsPath, - resolve(appRoot, "scripts", "lib", "pi-agent-core-patch.mjs"), - resolve(appRoot, "scripts", "lib", "pi-extension-loader-patch.mjs"), - resolve(appRoot, "scripts", "lib", "pi-tui-patch.mjs"), - resolve(appRoot, "scripts", "lib", "pi-web-access-patch.mjs"), - resolve(appRoot, "scripts", "lib", "pi-subagents-patch.mjs"), - resolve(appRoot, "scripts", "lib", "pi-otel-patch.mjs"), - resolve(appRoot, "scripts", "lib", "pi-session-search-patch.mjs"), - resolve(appRoot, "scripts", "lib", "alpha-hub-search-patch.mjs"), - ]) { - hash.update(path); - hash.update("\0"); - hash.update(hashFile(path) ?? "missing"); - hash.update("\0"); - } - return hash.digest("hex"); + return computeRuntimeInputHash(appRoot); } function workspaceIsCurrent(packageSpecs) { if (!existsSync(manifestPath) || !existsSync(workspaceNodeModulesDir)) { return false; } + if (!filesMatch(resolve(workspaceDir, "package-lock.json"), runtimePackageLockPath)) { + return false; + } try { const manifest = JSON.parse(readFileSync(manifestPath, "utf8")); @@ -162,6 +169,14 @@ function workspaceIsCurrent(packageSpecs) { if (manifest.runtimeInputHash !== getRuntimeInputHash()) { return false; } + if ( + typeof manifest.runtimeTreeHash !== "string" || + typeof (manifest.workspaceTreeHash ?? manifest.runtimeTreeHash) !== "string" || + computeRuntimeTreeHash(workspaceDir) !== + (manifest.workspaceTreeHash ?? manifest.runtimeTreeHash) + ) { + return false; + } if ( manifest.nodeAbi !== process.versions.modules || manifest.platform !== process.platform || @@ -171,13 +186,13 @@ function workspaceIsCurrent(packageSpecs) { return false; } - return packageSpecs.every((spec) => existsSync(resolve(workspaceNodeModulesDir, parsePackageName(spec)))); + return workspacePackagesMatch(workspaceNodeModulesDir, packageSpecs); } catch { return false; } } -function writeWorkspacePackageJson() { +function writeWorkspacePackageJson(packageSpecs) { writeFileSync( workspacePackageJsonPath, JSON.stringify( @@ -185,6 +200,7 @@ function writeWorkspacePackageJson() { name: "feynman-runtime", private: true, overrides: RUNTIME_PACKAGE_OVERRIDES, + dependencies: runtimeDependencies(packageSpecs), }, null, 2, @@ -207,20 +223,12 @@ function childNpmInstallEnv() { }; } -function prepareWorkspace(packageSpecs) { - rmSync(workspaceDir, { recursive: true, force: true }); - mkdirSync(workspaceDir, { recursive: true }); - writeWorkspacePackageJson(); - - if (packageSpecs.length === 0) { - return; - } - +function runWorkspaceNpm(args) { const result = spawnSync( process.env.npm_execpath ? process.execPath : "npm", process.env.npm_execpath - ? [process.env.npm_execpath, "install", "--prefer-online", "--no-audit", "--no-fund", "--no-dry-run", "--legacy-peer-deps", "--loglevel", "error", "--prefix", workspaceDir, ...packageSpecs] - : ["install", "--prefer-online", "--no-audit", "--no-fund", "--no-dry-run", "--legacy-peer-deps", "--loglevel", "error", "--prefix", workspaceDir, ...packageSpecs], + ? [process.env.npm_execpath, ...args] + : args, { stdio: "inherit", env: childNpmInstallEnv() }, ); if (result.status !== 0) { @@ -228,14 +236,62 @@ function prepareWorkspace(packageSpecs) { } } -function writeManifest(packageSpecs) { +function prepareWorkspace(packageSpecs, refreshRuntimeLock) { + rmSync(workspaceDir, { recursive: true, force: true }); + mkdirSync(workspaceDir, { recursive: true }); + writeWorkspacePackageJson(packageSpecs); + + if (packageSpecs.length === 0) { + return; + } + + if (refreshRuntimeLock) { + runWorkspaceNpm([ + "install", + "--save-exact", + "--prefer-online", + "--no-audit", + "--no-fund", + "--no-dry-run", + "--legacy-peer-deps", + "--loglevel", + "error", + "--prefix", + workspaceDir, + ...packageSpecs, + ]); + return; + } + + if (!existsSync(runtimePackageLockPath)) { + throw new Error( + "Missing .feynman/runtime-package-lock.json. Run npm run runtime:lock to create it.", + ); + } + cpSync(runtimePackageLockPath, resolve(workspaceDir, "package-lock.json")); + runWorkspaceNpm([ + "ci", + "--no-audit", + "--no-fund", + "--no-dry-run", + "--legacy-peer-deps", + "--loglevel", + "error", + "--prefix", + workspaceDir, + ]); +} + +function writeManifest(packageSpecs, runtimeTreeHash = computeRuntimeTreeHash(workspaceDir)) { + const workspaceTreeHash = computeRuntimeTreeHash(workspaceDir); writeFileSync( manifestPath, JSON.stringify( { packageSpecs, runtimeInputHash: getRuntimeInputHash(), - generatedAt: new Date().toISOString(), + runtimeTreeHash, + workspaceTreeHash, nodeAbi: process.versions.modules, nodeVersion: process.version, platform: process.platform, @@ -374,6 +430,13 @@ function patchBundledPiExtensionLoader() { return patchScopedPiWorkspaceFile("pi-coding-agent", "dist/core/extensions/loader.js", patchPiExtensionLoaderSource); } +function patchBundledPiModelRuntime() { + let changed = false; + changed = patchScopedPiWorkspaceFile("pi-coding-agent", "dist/core/model-registry.js", patchPiModelRegistrySource) || changed; + changed = patchScopedPiWorkspaceFile("pi-coding-agent", "dist/core/model-runtime.js", patchPiModelRegistrySource) || changed; + return changed; +} + function patchBundledPiInteractiveTheme() { return patchScopedPiWorkspaceFile("pi-coding-agent", "dist/modes/interactive/theme/theme.js", patchPiInteractiveThemeSource); } @@ -439,17 +502,43 @@ function patchBundledPiSessionSearch() { } function patchBundledAlphaHub() { + const authPath = resolve(workspaceNodeModulesDir, "@companion-ai", "alpha-hub", "src", "lib", "auth.js"); const alphaxivPath = resolve(workspaceNodeModulesDir, "@companion-ai", "alpha-hub", "src", "lib", "alphaxiv.js"); - if (!existsSync(alphaxivPath)) { + if (!existsSync(authPath) && !existsSync(alphaxivPath)) { return false; } - const source = readFileSync(alphaxivPath, "utf8"); - const patched = patchAlphaHubSearchSource(source); + let changed = false; + if (existsSync(authPath)) { + const source = readFileSync(authPath, "utf8"); + const patched = patchAlphaHubAuthSource(source); + if (patched !== source) { + writeFileSync(authPath, patched, "utf8"); + changed = true; + } + } + if (existsSync(alphaxivPath)) { + const source = readFileSync(alphaxivPath, "utf8"); + const patched = patchAlphaHubSearchSource(source); + if (patched !== source) { + writeFileSync(alphaxivPath, patched, "utf8"); + changed = true; + } + } + return changed; +} + +function patchMcpSdkManifest(nodeModulesDir) { + const manifestPath = resolve(nodeModulesDir, "@modelcontextprotocol", "sdk", "package.json"); + if (!existsSync(manifestPath)) { + throw new Error(`Required @modelcontextprotocol/sdk manifest not found: ${manifestPath}`); + } + const source = readFileSync(manifestPath, "utf8"); + const patched = patchMcpSdkPackageJsonSource(source); if (patched === source) { return false; } - writeFileSync(alphaxivPath, patched, "utf8"); + writeFileSync(manifestPath, patched, "utf8"); return true; } @@ -458,6 +547,11 @@ function patchBundledRuntime() { changed = patchBundledPiCodingAgentPackageJson() || changed; changed = patchBundledPiAgentCore() || changed; changed = patchBundledPiExtensionLoader() || changed; + changed = patchBundledPiModelRuntime() || changed; + changed = patchPiBraceExpansionTree( + workspaceNodeModulesDir, + resolve(appRoot, "node_modules", "brace-expansion"), + ) || changed; changed = patchBundledPiInteractiveTheme() || changed; changed = patchBundledPiTui() || changed; changed = patchBundledPiWebAccess() || changed; @@ -465,51 +559,78 @@ function patchBundledRuntime() { changed = patchBundledPiOtel() || changed; changed = patchBundledPiSessionSearch() || changed; changed = patchBundledAlphaHub() || changed; + changed = patchMcpSdkManifest(workspaceNodeModulesDir) || changed; return changed; } -function archiveIsCurrent() { - if (!existsSync(workspaceArchivePath) || !existsSync(manifestPath)) { - return false; - } - - return statSync(workspaceArchivePath).mtimeMs >= statSync(manifestPath).mtimeMs; +function archiveIsCurrent(packageSpecs) { + return runtimeArchiveMatches({ + archivePath: workspaceArchivePath, + digestPath: workspaceArchiveDigestPath, + lockPath: runtimePackageLockPath, + manifestPath, + packageSpecs, + runtimeInputHash: getRuntimeInputHash(), + }); } -function createWorkspaceArchive() { +async function createWorkspaceArchive(packageSpecs) { rmSync(workspaceArchivePath, { force: true }); - - const result = spawnSync("tar", ["-czf", workspaceArchivePath, "-C", feynmanDir, "npm"], { - stdio: "inherit", - }); - if (result.status !== 0) { - process.exit(result.status ?? 1); + const workspaceTreeHash = computeRuntimeTreeHash(workspaceDir); + writeManifest(packageSpecs, workspaceTreeHash); + await createDeterministicTarGz(workspaceDir, workspaceArchivePath); + const archiveTreeHash = computeRuntimeArchiveTreeHash(workspaceArchivePath); + if (archiveTreeHash !== workspaceTreeHash) { + // Windows tar can encode NTFS links differently from lstat(). Keep both + // logical hashes so source freshness and the shipped archive are each + // verified against the representation that users actually consume. + writeManifest(packageSpecs, archiveTreeHash); + rmSync(workspaceArchivePath, { force: true }); + await createDeterministicTarGz(workspaceDir, workspaceArchivePath); + const rebuiltArchiveTreeHash = computeRuntimeArchiveTreeHash(workspaceArchivePath); + if (rebuiltArchiveTreeHash !== archiveTreeHash) { + throw new Error( + `Runtime archive tree changed while recording its manifest: ${archiveTreeHash} -> ${rebuiltArchiveTreeHash}`, + ); + } } + writeFileSha256(workspaceArchivePath, workspaceArchiveDigestPath); } +patchMcpSdkManifest(resolve(appRoot, "node_modules")); +patchPiBraceExpansionTree( + resolve(appRoot, "node_modules"), + resolve(appRoot, "node_modules", "brace-expansion"), +); const packageSpecs = readPackageSpecs(); +const refreshRuntimeLock = process.argv.includes("--refresh-lock"); +const rebuildWorkspace = process.argv.includes("--rebuild"); -if (workspaceIsCurrent(packageSpecs)) { +if (!refreshRuntimeLock && !rebuildWorkspace && workspaceIsCurrent(packageSpecs)) { console.log("[feynman] vendored runtime workspace already up to date"); linkLegacyPiRuntimeAliases(); if (patchBundledRuntime()) { writeManifest(packageSpecs); console.log("[feynman] patched bundled Pi runtime"); } - if (archiveIsCurrent()) { + if (archiveIsCurrent(packageSpecs)) { process.exit(0); } console.log("[feynman] refreshing runtime workspace archive..."); - createWorkspaceArchive(); + await createWorkspaceArchive(packageSpecs); console.log("[feynman] runtime workspace archive ready"); process.exit(0); } - console.log("[feynman] preparing vendored runtime workspace..."); - prepareWorkspace(packageSpecs); - pruneWorkspace(); - linkLegacyPiRuntimeAliases(); - patchBundledRuntime(); - writeManifest(packageSpecs); -createWorkspaceArchive(); +console.log("[feynman] preparing vendored runtime workspace..."); +prepareWorkspace(packageSpecs, refreshRuntimeLock); +pruneWorkspace(); +linkLegacyPiRuntimeAliases(); +patchBundledRuntime(); +if (refreshRuntimeLock) { + cpSync(resolve(workspaceDir, "package-lock.json"), runtimePackageLockPath); + console.log("[feynman] refreshed committed runtime lock"); +} +writeManifest(packageSpecs); +await createWorkspaceArchive(packageSpecs); console.log("[feynman] vendored runtime workspace ready"); diff --git a/scripts/verify-package-artifact.mjs b/scripts/verify-package-artifact.mjs new file mode 100644 index 00000000..df65458e --- /dev/null +++ b/scripts/verify-package-artifact.mjs @@ -0,0 +1,331 @@ +import { existsSync, readFileSync } from "node:fs"; +import { resolve } from "node:path"; + +import { + computeFileSha256, + computeRuntimeArchiveTreeHash, + computeRuntimeInputHash, + parseExactRuntimePackageSpec, + readArchiveEntry, + verifyFileSha256, +} from "./lib/runtime-workspace-integrity.mjs"; + +const packageRoot = resolve(process.argv[2] ?? resolve(import.meta.dirname, "..")); + +function fail(message) { + throw new Error(`[feynman artifact] ${message}`); +} + +function readJson(path, label) { + if (!existsSync(path)) fail(`${label} is missing`); + try { + return JSON.parse(readFileSync(path, "utf8")); + } catch { + fail(`${label} is not valid JSON`); + } +} + +function readText(path, label) { + if (!existsSync(path)) fail(`${label} is missing`); + return readFileSync(path, "utf8"); +} + +function requireMarkers(source, label, markers) { + for (const marker of markers) { + if (!source.includes(marker)) { + fail(`${label} is missing required marker: ${marker}`); + } + } +} + +function readArchivedJson(archivePath, entryPath) { + const source = readArchiveEntry(archivePath, entryPath); + if (!source) fail(`runtime archive entry is missing: ${entryPath}`); + try { + return JSON.parse(source); + } catch { + fail(`runtime archive entry is not valid JSON: ${entryPath}`); + } +} + +function readArchivedText(archivePath, entryPath) { + const source = readArchiveEntry(archivePath, entryPath); + if (source === undefined) fail(`runtime archive entry is missing: ${entryPath}`); + return source; +} + +const manifest = readJson(resolve(packageRoot, "package.json"), "package.json"); +const expectedPiVersion = manifest.dependencies?.["@earendil-works/pi-coding-agent"]; +if (typeof expectedPiVersion !== "string") fail("package.json has no exact Pi runtime version"); + +for (const name of [ + "@earendil-works/pi-agent-core", + "@earendil-works/pi-ai", + "@earendil-works/pi-coding-agent", + "@earendil-works/pi-tui", +]) { + const expected = manifest.dependencies?.[name]; + const installed = readJson( + resolve(packageRoot, "node_modules", ...name.split("/"), "package.json"), + `${name} package manifest`, + ).version; + if (installed !== expected) { + fail(`${name} version mismatch: expected ${expected}, found ${installed}`); + } +} + +requireMarkers( + readText( + resolve(packageRoot, "node_modules", "@earendil-works", "pi-coding-agent", "dist", "core", "model-runtime.js"), + "bundled Pi ModelRuntime", + ), + "bundled Pi ModelRuntime", + ["function assertHeaderSafeRequestConfig(", "providerOptions.apiKey ?? resolution.auth.apiKey"], +); +requireMarkers( + readText( + resolve(packageRoot, "node_modules", "@earendil-works", "pi-coding-agent", "dist", "core", "model-registry.js"), + "bundled Pi ModelRegistry", + ), + "bundled Pi ModelRegistry", + [ + "function assertHeaderSafeRequestConfig(", + "assertHeaderSafeRequestConfig(model.provider, undefined, headers);", + "assertHeaderSafeRequestConfig(model.provider, resolution.auth.apiKey, headers);", + ], +); +requireMarkers( + readText( + resolve(packageRoot, "node_modules", "@earendil-works", "pi-tui", "dist", "tui.js"), + "bundled Pi TUI", + ), + "bundled Pi TUI", + ["line = sliceByColumn(line, 0, width, true);"], +); +requireMarkers( + readText( + resolve(packageRoot, "node_modules", "@earendil-works", "pi-tui", "dist", "components", "editor.js"), + "bundled Pi editor", + ), + "bundled Pi editor", + [ + "applyBackgroundToLine", + "const styleInput = typeof this.theme.input", + 'const cursor = `\\x1b[7m${firstGrapheme}\\x1b[27m`', + 'const cursor = "\\x1b[7m \\x1b[27m"', + ], +); + +const alphaLib = resolve(packageRoot, "node_modules", "@companion-ai", "alpha-hub", "src", "lib"); +requireMarkers( + readText(resolve(alphaLib, "auth.js"), "bundled alpha-hub auth"), + "bundled alpha-hub auth", + [ + "https://api.alphaxiv.org/auth", + "/oauth2/authorize", + "waitForCallback(server, state)", + "OAuth state mismatch", + ], +); +requireMarkers( + readText(resolve(alphaLib, "alphaxiv.js"), "bundled alpha-hub search"), + "bundled alpha-hub search", + ["async function searchRestFast(", "return await fallbackSearch("], +); +requireMarkers( + readText(resolve(alphaLib, "index.js"), "bundled alpha-hub parser"), + "bundled alpha-hub parser", + ["function parseStructuredSearchResults("], +); + +const mcpManifest = readJson( + resolve(packageRoot, "node_modules", "@modelcontextprotocol", "sdk", "package.json"), + "bundled MCP SDK manifest", +); +if (mcpManifest.dependencies?.["@hono/node-server"] !== "2.0.12") { + fail("bundled MCP SDK does not pin @hono/node-server 2.0.12"); +} +if ( + readJson( + resolve(packageRoot, "node_modules", "@hono", "node-server", "package.json"), + "bundled Hono node server manifest", + ).version !== "2.0.12" +) { + fail("bundled Hono node server is not 2.0.12"); +} +if ( + readJson( + resolve( + packageRoot, + "node_modules", + "@earendil-works", + "pi-coding-agent", + "node_modules", + "brace-expansion", + "package.json", + ), + "bundled Pi brace-expansion manifest", + ).version !== "5.0.8" +) { + fail("bundled Pi brace-expansion is not 5.0.8"); +} + +const archivePath = resolve(packageRoot, ".feynman", "runtime-workspace.tgz"); +const digestPath = resolve(packageRoot, ".feynman", "runtime-workspace.sha256"); +const runtimeLockPath = resolve(packageRoot, ".feynman", "runtime-package-lock.json"); +if (!verifyFileSha256(archivePath, digestPath)) { + fail("runtime workspace archive SHA-256 does not match its sidecar"); +} +const runtimeLockSource = readText(runtimeLockPath, "committed runtime package lock"); +const runtimeLock = JSON.parse(runtimeLockSource); +const expectedPiWebAccessVersion = runtimeLock.packages?.[""]?.dependencies?.["pi-web-access"]; +if (typeof expectedPiWebAccessVersion !== "string") { + fail("committed runtime lock does not pin pi-web-access"); +} +if ( + runtimeLock.packages?.["node_modules/@hono/node-server"]?.version !== "2.0.12" +) { + fail("committed runtime lock does not pin @hono/node-server 2.0.12"); +} +for (const [packagePath, entry] of Object.entries(runtimeLock.packages ?? {})) { + if ( + packagePath.endsWith("/pi-coding-agent/node_modules/brace-expansion") && + entry?.version !== "5.0.8" + ) { + fail("committed runtime lock does not pin Pi brace-expansion 5.0.8"); + } +} +if (readArchivedText(archivePath, "npm/package-lock.json") !== runtimeLockSource) { + fail("runtime archive package lock differs from the committed runtime lock"); +} +const runtimeManifest = readArchivedJson(archivePath, "npm/.runtime-manifest.json"); +if (!Array.isArray(runtimeManifest.packageSpecs)) { + fail("runtime archive manifest has no packageSpecs"); +} +const currentRuntimeInputHash = computeRuntimeInputHash(packageRoot); +if (runtimeManifest.runtimeInputHash !== currentRuntimeInputHash) { + fail( + `runtime archive inputs are stale: expected ${currentRuntimeInputHash}, found ${runtimeManifest.runtimeInputHash ?? "missing"}`, + ); +} +if ( + typeof runtimeManifest.runtimeTreeHash !== "string" || + !/^[a-f0-9]{64}$/.test(runtimeManifest.runtimeTreeHash) +) { + fail("runtime archive manifest has no valid runtimeTreeHash"); +} +const archivedRuntimeTreeHash = computeRuntimeArchiveTreeHash(archivePath); +if (archivedRuntimeTreeHash !== runtimeManifest.runtimeTreeHash) { + fail( + `runtime archive tree mismatch: expected ${runtimeManifest.runtimeTreeHash}, found ${archivedRuntimeTreeHash}`, + ); +} +for (const spec of runtimeManifest.packageSpecs) { + const { name, version } = parseExactRuntimePackageSpec(spec); + const archived = readArchivedJson( + archivePath, + `npm/node_modules/${name}/package.json`, + ); + if (archived.version !== version) { + fail(`runtime archive ${name} version mismatch: expected ${version}, found ${archived.version}`); + } +} + +requireMarkers( + readArchivedText( + archivePath, + "npm/node_modules/@earendil-works/pi-coding-agent/dist/core/model-runtime.js", + ), + "runtime Pi ModelRuntime", + ["function assertHeaderSafeRequestConfig(", "providerOptions.apiKey ?? resolution.auth.apiKey"], +); +requireMarkers( + readArchivedText( + archivePath, + "npm/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js", + ), + "runtime Pi ModelRegistry", + [ + "function assertHeaderSafeRequestConfig(", + "assertHeaderSafeRequestConfig(model.provider, undefined, headers);", + "assertHeaderSafeRequestConfig(model.provider, resolution.auth.apiKey, headers);", + ], +); +requireMarkers( + readArchivedText( + archivePath, + "npm/node_modules/@earendil-works/pi-tui/dist/components/editor.js", + ), + "runtime Pi editor", + [ + "applyBackgroundToLine", + "const styleInput = typeof this.theme.input", + 'const cursor = `\\x1b[7m${firstGrapheme}\\x1b[27m`', + 'const cursor = "\\x1b[7m \\x1b[27m"', + ], +); +requireMarkers( + readArchivedText( + archivePath, + "npm/node_modules/@companion-ai/alpha-hub/src/lib/auth.js", + ), + "runtime alpha-hub auth", + ["https://api.alphaxiv.org/auth", "waitForCallback(server, state)", "OAuth state mismatch"], +); +requireMarkers( + readArchivedText( + archivePath, + "npm/node_modules/pi-otel/dist/otel/sdk.js", + ), + "runtime pi-otel SDK", + ["createFeynmanResource", "resourceFromAttributes"], +); +if ( + readArchivedJson( + archivePath, + "npm/node_modules/pi-web-access/package.json", + ).version !== expectedPiWebAccessVersion +) { + fail(`runtime pi-web-access is not ${expectedPiWebAccessVersion}`); +} +requireMarkers( + readArchivedText( + archivePath, + "npm/node_modules/pi-web-access/utils.ts", + ), + "runtime pi-web-access config helper", + ["FEYNMAN_WEB_SEARCH_CONFIG", "PI_WEB_SEARCH_CONFIG", "configuredPath || join(getWebSearchConfigDir()"], +); +if ( + readArchivedJson( + archivePath, + "npm/node_modules/@modelcontextprotocol/sdk/package.json", + ).dependencies?.["@hono/node-server"] !== "2.0.12" +) { + fail("runtime MCP SDK does not pin @hono/node-server 2.0.12"); +} +if ( + readArchivedJson( + archivePath, + "npm/node_modules/@hono/node-server/package.json", + ).version !== "2.0.12" +) { + fail("runtime Hono node server is not 2.0.12"); +} +if ( + readArchivedJson( + archivePath, + "npm/node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion/package.json", + ).version !== "5.0.8" +) { + fail("runtime Pi brace-expansion is not 5.0.8"); +} + +console.log(JSON.stringify({ + ok: true, + package: `${manifest.name}@${manifest.version}`, + piVersion: expectedPiVersion, + piWebAccessVersion: expectedPiWebAccessVersion, + runtimePackages: runtimeManifest.packageSpecs.length, + runtimeArchiveSha256: computeFileSha256(archivePath), +})); diff --git a/scripts/verify-package-budget.mjs b/scripts/verify-package-budget.mjs new file mode 100644 index 00000000..53f309a6 --- /dev/null +++ b/scripts/verify-package-budget.mjs @@ -0,0 +1,86 @@ +import { statSync, readFileSync } from "node:fs"; +import { basename, resolve } from "node:path"; + +function fail(message) { + throw new Error(`[feynman package budget] ${message}`); +} + +function parseJsonSuffix(source) { + for (let index = source.length - 1; index >= 0; index -= 1) { + if (source[index] !== "[" && source[index] !== "{") continue; + try { + return JSON.parse(source.slice(index).trim()); + } catch { + continue; + } + } + fail("pack output does not end with valid JSON"); +} + +const appRoot = resolve(import.meta.dirname, ".."); +const packOutputPath = resolve(process.argv[2] ?? ""); +const tarballPath = process.argv[3] ? resolve(process.argv[3]) : undefined; +if (!process.argv[2]) { + fail("usage: node scripts/verify-package-budget.mjs [tarball]"); +} + +const packageManifest = JSON.parse(readFileSync(resolve(appRoot, "package.json"), "utf8")); +const budget = packageManifest.feynmanReleaseBudget; +if ( + !Number.isSafeInteger(budget?.maxTarballBytes) || + !Number.isSafeInteger(budget?.maxUnpackedBytes) || + !Number.isSafeInteger(budget?.maxFileCount) +) { + fail("package.json must declare integer feynmanReleaseBudget limits"); +} + +const parsed = parseJsonSuffix(readFileSync(packOutputPath, "utf8")); +const entries = Array.isArray(parsed) ? parsed : [parsed]; +if (entries.length !== 1 || typeof entries[0] !== "object" || entries[0] === null) { + fail(`expected exactly one packed artifact, found ${entries.length}`); +} +const packed = entries[0]; +for (const field of ["size", "unpackedSize"]) { + if (!Number.isSafeInteger(packed[field]) || packed[field] <= 0) { + fail(`pack metadata has no positive integer ${field}`); + } +} +const fileCount = + Number.isSafeInteger(packed.entryCount) && packed.entryCount > 0 + ? packed.entryCount + : Number.isSafeInteger(packed.totalFiles) && packed.totalFiles > 0 + ? packed.totalFiles + : Array.isArray(packed.files) && packed.files.length > 0 + ? packed.files.length + : undefined; +if (!Number.isSafeInteger(fileCount)) { + fail("pack metadata has no positive integer entryCount or totalFiles"); +} +if (packed.size > budget.maxTarballBytes) { + fail(`tarball size ${packed.size} exceeds ${budget.maxTarballBytes} bytes`); +} +if (packed.unpackedSize > budget.maxUnpackedBytes) { + fail(`unpacked size ${packed.unpackedSize} exceeds ${budget.maxUnpackedBytes} bytes`); +} +if (fileCount > budget.maxFileCount) { + fail(`file count ${fileCount} exceeds ${budget.maxFileCount}`); +} + +if (tarballPath) { + const actualSize = statSync(tarballPath).size; + if (actualSize !== packed.size) { + fail(`tarball size differs from pack metadata: expected ${packed.size}, found ${actualSize}`); + } + if (basename(tarballPath) !== packed.filename) { + fail(`tarball filename differs from pack metadata: expected ${packed.filename}, found ${basename(tarballPath)}`); + } +} + +console.log(JSON.stringify({ + ok: true, + filename: packed.filename, + size: packed.size, + unpackedSize: packed.unpackedSize, + fileCount, + budget, +})); diff --git a/scripts/verify-windows-installer.ps1 b/scripts/verify-windows-installer.ps1 new file mode 100644 index 00000000..3616ce27 --- /dev/null +++ b/scripts/verify-windows-installer.ps1 @@ -0,0 +1,394 @@ +param( + [Parameter(Mandatory = $true)] + [string]$ArchivePath, + + [Parameter(Mandatory = $true)] + [string]$Version +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 + +$archive = (Resolve-Path -LiteralPath $ArchivePath).Path +if ((Get-Item -LiteralPath $archive).Length -eq 0) { + throw "Native archive is empty: $archive" +} + +$baseTemp = if ($env:RUNNER_TEMP) { + $env:RUNNER_TEMP +} else { + [System.IO.Path]::GetTempPath() +} +$testRoot = Join-Path $baseTemp ("feynman-installer-" + [guid]::NewGuid().ToString("N")) +$serverScript = Join-Path $testRoot "serve-feynman-archive.mjs" +$portFile = Join-Path $testRoot "archive-port.txt" +$checksumFile = Join-Path $testRoot "SHA256SUMS" +$serverJob = $null + +New-Item -ItemType Directory -Path $testRoot -Force | Out-Null +$archiveName = Split-Path -Leaf $archive +$servedArchive = Join-Path $testRoot $archiveName +Copy-Item -LiteralPath $archive -Destination $servedArchive +$activeArchiveSha256 = (Get-FileHash -LiteralPath $servedArchive -Algorithm SHA256).Hash.ToLowerInvariant() +"$activeArchiveSha256 $archiveName" | Set-Content -LiteralPath $checksumFile -Encoding ASCII + +try { + @' +import { createReadStream, statSync, writeFileSync } from "node:fs"; +import { createServer } from "node:http"; +import { basename } from "node:path"; + +const archive = process.env.ARCHIVE_PATH; +const checksumFile = process.env.CHECKSUM_PATH; +const portFile = process.env.ARCHIVE_PORT_FILE; +const archiveName = basename(archive); +const checksumName = basename(checksumFile); +const server = createServer((request, response) => { + const pathname = new URL( + request.url ?? "/", + "http://127.0.0.1", + ).pathname; + + if (pathname === "/healthz") { + response.writeHead(204); + response.end(); + return; + } + + const source = pathname === `/${archiveName}` + ? archive + : pathname === `/${checksumName}` + ? checksumFile + : undefined; + if (!source) { + response.writeHead(404); + response.end("not found"); + return; + } + + const size = statSync(source).size; + response.writeHead(200, { + "Content-Type": source === archive ? "application/zip" : "text/plain", + "Content-Length": size, + }); + + if (request.method === "HEAD") { + response.end(); + return; + } + + createReadStream(source).pipe(response); +}); + +server.listen(0, "127.0.0.1", () => { + const address = server.address(); + if (!address || typeof address === "string") { + throw new Error("Could not determine local archive server port"); + } + writeFileSync(portFile, String(address.port)); +}); +'@ | Set-Content -LiteralPath $serverScript -Encoding utf8 + + $serverJob = Start-Job -ScriptBlock { + param($script, $archivePath, $checksumsPath, $serverPortFile) + $env:ARCHIVE_PATH = $archivePath + $env:CHECKSUM_PATH = $checksumsPath + $env:ARCHIVE_PORT_FILE = $serverPortFile + & node $script + if ($LASTEXITCODE -ne 0) { + throw "Local archive server failed: $LASTEXITCODE" + } + } -ArgumentList $serverScript, $servedArchive, $checksumFile, $portFile + + $baseUrl = $null + for ($attempt = 0; $attempt -lt 30; $attempt += 1) { + if (Test-Path -LiteralPath $portFile) { + $port = (Get-Content -LiteralPath $portFile -Raw).Trim() + if ($port -match "^\d+$") { + $baseUrl = "http://127.0.0.1:$port" + break + } + } + + if ($serverJob.State -eq "Failed" -or $serverJob.State -eq "Completed") { + Receive-Job -Job $serverJob + throw "Local archive server exited before becoming ready" + } + Start-Sleep -Seconds 1 + } + + if (-not $baseUrl) { + Receive-Job -Job $serverJob + throw "Local archive server did not publish a listening port" + } + + $ready = $false + for ($attempt = 0; $attempt -lt 30; $attempt += 1) { + try { + $response = Invoke-WebRequest ` + -Uri "$baseUrl/healthz" ` + -UseBasicParsing ` + -TimeoutSec 2 + if ($response.StatusCode -eq 204) { + $ready = $true + break + } + } catch {} + Start-Sleep -Seconds 1 + } + if (-not $ready) { + throw "Local archive server did not become ready" + } + + $env:LOCALAPPDATA = Join-Path $testRoot "LocalAppData" + $env:FEYNMAN_HOME = Join-Path $testRoot "FeynmanHome" + $env:FEYNMAN_INSTALL_BASE_URL = $baseUrl + $env:NO_PROXY = "127.0.0.1,localhost" + + $installerSource = Get-Content ` + -LiteralPath "scripts/install/install.ps1" ` + -Raw + $installer = [scriptblock]::Create($installerSource) + + $installRoot = Join-Path $env:LOCALAPPDATA "Programs\feynman" + $installBinDir = Join-Path $installRoot "bin" + $bundleDir = Join-Path $installRoot "feynman-$Version-win32-x64" + $shim = Join-Path $installRoot "bin\feynman.cmd" + $shimPs1 = Join-Path $installRoot "bin\feynman.ps1" + $bundleCmd = Join-Path $bundleDir "feynman.cmd" + $bundlePs1 = Join-Path $bundleDir "feynman.ps1" + + function Assert-InstalledCandidate { + if (Test-Path -LiteralPath $shimPs1) { + throw "PATH bin must not contain a policy-blocked feynman.ps1 shim: $shimPs1" + } + + $launchers = @($shim, $bundleCmd) + foreach ($launcher in $launchers) { + if (-not (Test-Path -LiteralPath $launcher)) { + throw "Installed launcher is missing: $launcher" + } + + $versionOutput = @(& $launcher --version 2>&1) + $versionExit = $LASTEXITCODE + if ($versionExit -ne 0) { + throw "Installed feynman --version failed for ${launcher}: $versionExit" + } + $actualVersion = ($versionOutput | Select-Object -Last 1).ToString().Trim() + if ($actualVersion -ne $Version) { + throw "Version mismatch for ${launcher}: expected=$Version actual=$actualVersion" + } + + $helpOutput = @(& $launcher --help 2>&1) + $helpExit = $LASTEXITCODE + if ($helpExit -ne 0) { + throw "Installed feynman --help failed for ${launcher}: $helpExit" + } + if ($helpOutput.Count -eq 0) { + throw "Installed feynman --help returned no output for $launcher" + } + $helpOutput | Select-Object -First 20 + } + + if (-not (Test-Path -LiteralPath $bundlePs1)) { + throw "Installed bundle PowerShell launcher is missing: $bundlePs1" + } + $powerShellExecutable = (Get-Process -Id $PID).Path + $ps1VersionOutput = @( + & $powerShellExecutable -NoProfile -ExecutionPolicy Bypass -File $bundlePs1 --version 2>&1 + ) + if ($LASTEXITCODE -ne 0) { + throw "Installed bundle PowerShell launcher failed --version: $bundlePs1" + } + $actualPs1Version = ($ps1VersionOutput | Select-Object -Last 1).ToString().Trim() + if ($actualPs1Version -ne $Version) { + throw "Version mismatch for ${bundlePs1}: expected=$Version actual=$actualPs1Version" + } + } + + function Assert-BareRestrictedLauncher { + foreach ($hostName in @("powershell.exe", "pwsh")) { + $hostCommand = Get-Command $hostName -ErrorAction SilentlyContinue + if (-not $hostCommand) { + continue + } + $versionOutput = @( + & $hostCommand.Source ` + -NoProfile ` + -ExecutionPolicy Restricted ` + -Command "feynman --version; exit `$LASTEXITCODE" ` + 2>&1 + ) + if ($LASTEXITCODE -ne 0) { + throw "Bare feynman failed under Restricted policy in ${hostName}: $LASTEXITCODE" + } + $actualVersion = ($versionOutput | Select-Object -Last 1).ToString().Trim() + if ($actualVersion -ne $Version) { + throw "Bare feynman version mismatch under Restricted policy in ${hostName}: expected=$Version actual=$actualVersion" + } + } + } + + & $installer -Version $Version + Assert-InstalledCandidate + $env:PATH = "$installBinDir;$env:PATH" + Assert-BareRestrictedLauncher + + $replacementSentinel = Join-Path $bundleDir "stale-replacement.sentinel" + "must be removed" | Set-Content -LiteralPath $replacementSentinel + + & $installer -Version $Version + + if (Test-Path -LiteralPath $replacementSentinel) { + throw "Exact-candidate replacement retained the old bundle" + } + Assert-InstalledCandidate + Assert-BareRestrictedLauncher + + # The exact release ZIP is large enough that repeatedly downloading and + # extracting it can consume the entire hosted-runner timeout. The clean and + # replacement passes above prove the real candidate in both PowerShell + # hosts. Exercise checksum and rollback branches with a compact, valid bundle + # so those same installer paths remain covered without ten redundant 530 MiB + # transfers across the two hosts. + $fixtureRoot = Join-Path $testRoot "compact-fixture" + $fixtureBundleDir = Join-Path $fixtureRoot "feynman-$Version-win32-x64" + $fixtureArchive = Join-Path $testRoot "compact-fixture.zip" + New-Item -ItemType Directory -Path $fixtureBundleDir -Force | Out-Null + @" +@echo off +if "%~1"=="--version" ( + echo $Version + exit /b 0 +) +if "%~1"=="--help" ( + echo Feynman installer verifier fixture + exit /b 0 +) +exit /b 0 +"@ | Set-Content -LiteralPath (Join-Path $fixtureBundleDir "feynman.cmd") -Encoding ASCII + @" +if (`$args[0] -eq "--version") { + Write-Output "$Version" + exit 0 +} +if (`$args[0] -eq "--help") { + Write-Output "Feynman installer verifier fixture" + exit 0 +} +exit 0 +"@ | Set-Content -LiteralPath (Join-Path $fixtureBundleDir "feynman.ps1") -Encoding UTF8 + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::CreateFromDirectory($fixtureRoot, $fixtureArchive) + Copy-Item -LiteralPath $fixtureArchive -Destination $servedArchive -Force + $activeArchiveSha256 = ( + Get-FileHash -LiteralPath $servedArchive -Algorithm SHA256 + ).Hash.ToLowerInvariant() + "$activeArchiveSha256 $archiveName" | + Set-Content -LiteralPath $checksumFile -Encoding ASCII + + $duplicateSentinel = Join-Path $bundleDir "duplicate-checksum-must-preserve.sentinel" + "must remain" | Set-Content -LiteralPath $duplicateSentinel + $conflictingChecksum = "0" * 64 + foreach ($checksumLines in @( + @("$activeArchiveSha256 $archiveName", "$conflictingChecksum $archiveName"), + @("$conflictingChecksum $archiveName", "$activeArchiveSha256 $archiveName") + )) { + $checksumLines | Set-Content -LiteralPath $checksumFile -Encoding ASCII + $duplicateRejected = $false + try { + & $installer -Version $Version + } catch { + $duplicateRejected = $_.Exception.Message -match "multiple checksum entries" + } + if (-not $duplicateRejected) { + throw "Installer did not reject duplicate checksum entries" + } + if (-not (Test-Path -LiteralPath $duplicateSentinel)) { + throw "Duplicate checksum entries replaced the prior installed bundle" + } + } + + "$activeArchiveSha256 $archiveName" | Set-Content -LiteralPath $checksumFile -Encoding ASCII + $backupFailureSentinel = Join-Path $bundleDir "backup-failure-must-preserve.sentinel" + "must remain" | Set-Content -LiteralPath $backupFailureSentinel + $env:FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_BACKUP = "1" + $backupFailureRejected = $false + try { + & $installer -Version $Version + } catch { + $backupFailureRejected = $_.Exception.Message -match "Injected installer failure after bundle backup" + } finally { + Remove-Item Env:FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_BACKUP -ErrorAction SilentlyContinue + } + if (-not $backupFailureRejected) { + throw "Installer did not surface the injected bundle-backup failure" + } + if (-not (Test-Path -LiteralPath $backupFailureSentinel)) { + throw "Failed bundle backup removed the previous bundle" + } + Assert-InstalledCandidate + + $preservedSentinel = Join-Path $bundleDir "checksum-failure-must-preserve.sentinel" + "must remain" | Set-Content -LiteralPath $preservedSentinel + ("0" * 64) + " $archiveName" | Set-Content -LiteralPath $checksumFile -Encoding ASCII + $checksumRejected = $false + try { + & $installer -Version $Version + } catch { + $checksumRejected = $_.Exception.Message -match "SHA-256 mismatch" + } + if (-not $checksumRejected) { + throw "Installer did not reject a corrupted archive checksum" + } + if (-not (Test-Path -LiteralPath $preservedSentinel)) { + throw "Checksum failure replaced the prior installed bundle" + } + + $previousBundleDir = Join-Path $installRoot "feynman-previous-win32-x64" + Move-Item -LiteralPath $bundleDir -Destination $previousBundleDir + @" +@echo off +CALL "$previousBundleDir\feynman.cmd" %* +"@ | Set-Content -LiteralPath $shim -Encoding ASCII + $upgradeSentinel = Join-Path $previousBundleDir "upgrade-failure-must-preserve.sentinel" + "must remain" | Set-Content -LiteralPath $upgradeSentinel + "$activeArchiveSha256 $archiveName" | Set-Content -LiteralPath $checksumFile -Encoding ASCII + + $env:FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_SWAP = "1" + $upgradeFailureRejected = $false + try { + & $installer -Version $Version + } catch { + $upgradeFailureRejected = $_.Exception.Message -match "Injected installer failure" + } finally { + Remove-Item Env:FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_SWAP -ErrorAction SilentlyContinue + } + if (-not $upgradeFailureRejected) { + throw "Installer did not surface the injected upgrade failure" + } + if (Test-Path -LiteralPath $bundleDir) { + throw "Failed upgrade retained the replacement bundle" + } + if (-not (Test-Path -LiteralPath $upgradeSentinel)) { + throw "Failed upgrade removed the previous bundle" + } + foreach ($launcher in @($shim)) { + $versionOutput = @(& $launcher --version 2>&1) + $versionExit = $LASTEXITCODE + if ($versionExit -ne 0) { + throw "Restored launcher failed after injected upgrade failure: $launcher" + } + $actualVersion = ($versionOutput | Select-Object -Last 1).ToString().Trim() + if ($actualVersion -ne $Version) { + throw "Restored launcher version mismatch after injected failure: $launcher" + } + } +} finally { + if ($serverJob) { + Stop-Job -Job $serverJob -ErrorAction SilentlyContinue + Receive-Job -Job $serverJob -ErrorAction SilentlyContinue + Remove-Job -Job $serverJob -Force -ErrorAction SilentlyContinue + } + Remove-Item -LiteralPath $testRoot -Recurse -Force -ErrorAction SilentlyContinue +} diff --git a/src/alpha-auth-status.ts b/src/alpha-auth-status.ts new file mode 100644 index 00000000..610251e2 --- /dev/null +++ b/src/alpha-auth-status.ts @@ -0,0 +1,41 @@ +export const ALPHAXIV_USERINFO_ENDPOINT = "https://api.alphaxiv.org/auth/oauth2/userinfo"; + +export type AlphaAuthStatus = { + authenticated: boolean; + name?: string; +}; + +type AlphaAuthStatusOptions = { + getValidToken: () => Promise; + fetchImpl?: typeof fetch; +}; + +export async function verifyAlphaAuthStatus({ + getValidToken, + fetchImpl = fetch, +}: AlphaAuthStatusOptions): Promise { + const token = await getValidToken(); + if (!token) return { authenticated: false }; + + const response = await fetchImpl(ALPHAXIV_USERINFO_ENDPOINT, { + headers: { Authorization: `Bearer ${token}` }, + signal: AbortSignal.timeout(15_000), + }); + if ([400, 401, 403].includes(response.status)) { + return { authenticated: false }; + } + if (!response.ok) { + throw new Error(`alphaXiv auth verification failed: ${response.status} ${response.statusText}`); + } + + const userInfo = await response.json() as Record; + if (typeof userInfo.sub !== "string" || !userInfo.sub) { + throw new Error("alphaXiv auth verification returned no user subject."); + } + const name = typeof userInfo.name === "string" && userInfo.name.trim() + ? userInfo.name.trim() + : typeof userInfo.preferred_username === "string" && userInfo.preferred_username.trim() + ? userInfo.preferred_username.trim() + : undefined; + return { authenticated: true, name }; +} diff --git a/src/bootstrap/sync.ts b/src/bootstrap/sync.ts index b4e0f86b..e115214c 100644 --- a/src/bootstrap/sync.ts +++ b/src/bootstrap/sync.ts @@ -181,6 +181,7 @@ export function syncBundledAssets(appRoot: string, agentDir: string): BootstrapS syncManagedFiles(resolve(appRoot, ".feynman", "themes"), resolve(agentDir, "themes"), "themes", state, result); syncManagedFiles(resolve(appRoot, ".feynman", "agents"), resolve(agentDir, "agents"), "agents", state, result); + syncManagedFiles(resolve(appRoot, ".feynman", "config"), agentDir, "config", state, result); syncManagedFiles(resolve(appRoot, "skills"), resolve(agentDir, "skills"), "skills", state, result); writeBootstrapState(statePath, state); diff --git a/src/cli.ts b/src/cli.ts index ac357416..da86f4e5 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -9,18 +9,20 @@ try { import { spawn } from "node:child_process"; import { existsSync, readFileSync } from "node:fs"; +import { createRequire } from "node:module"; import { dirname, resolve } from "node:path"; import { parseArgs } from "node:util"; import { fileURLToPath } from "node:url"; import { getUserName as getAlphaUserName, - isLoggedIn as isAlphaLoggedIn, login as loginAlpha, logout as logoutAlpha, } from "@companion-ai/alpha-hub/lib"; +import { getValidToken as getValidAlphaToken } from "@companion-ai/alpha-hub/lib/auth"; import { createAgentSession, SessionManager, SettingsManager, type AgentSessionEvent } from "@earendil-works/pi-coding-agent"; +import { verifyAlphaAuthStatus } from "./alpha-auth-status.js"; import { syncBundledAssets } from "./bootstrap/sync.js"; import { ensureFeynmanHome, getDefaultSessionDir, getFeynmanAgentDir, getFeynmanHome } from "./config/paths.js"; import { launchPiChat } from "./pi/launch.js"; @@ -35,7 +37,13 @@ import { normalizeOptionalPackagePresetName, resolvePackageUpdateSources, } from "./pi/package-presets.js"; -import { normalizeFeynmanSettings, normalizeThinkingLevel, parseModelSpec, type ThinkingLevel } from "./pi/settings.js"; +import { + canonicalizeModelSpec, + normalizeFeynmanSettings, + normalizeThinkingLevel, + parseModelSpec, + type ThinkingLevel, +} from "./pi/settings.js"; import { applyFeynmanPackageManagerEnv } from "./pi/runtime.js"; import { parseCitationExpansion, @@ -85,7 +93,7 @@ import { telemetryErrorProperties, } from "./telemetry/posthog.js"; import { ASH, printAsciiHeader, printInfo, printPanel, printSection, RESET, SAGE } from "./ui/terminal.js"; -import { createModelRegistry } from "./model/registry.js"; +import { createModelRuntime } from "./model/registry.js"; import { parseWorkbenchPort, serveWorkbench } from "./workbench/server.js"; import { cliCommandSections, @@ -143,10 +151,19 @@ function printHelp(appRoot: string): void { } export function resolveBundledAlphaCliPath(appRoot: string): string { + let resolvedPackageAlpha: string | undefined; + try { + const requireFromApp = createRequire(resolve(appRoot, "package.json")); + const packageEntryPath = requireFromApp.resolve("@companion-ai/alpha-hub"); + resolvedPackageAlpha = resolve(dirname(packageEntryPath), "..", "bin", "alpha"); + } catch { + resolvedPackageAlpha = undefined; + } const candidates = [ + resolvedPackageAlpha, resolve(appRoot, "node_modules", ...ALPHA_HUB_PACKAGE_PATH, "bin", "alpha"), resolve(appRoot, ".feynman", "npm", "node_modules", ...ALPHA_HUB_PACKAGE_PATH, "bin", "alpha"), - ]; + ].filter((candidate): candidate is string => Boolean(candidate)); const found = candidates.find((candidate) => existsSync(candidate)); if (!found) { throw new Error(`Bundled alphaXiv CLI not found. Checked: ${candidates.join(", ")}`); @@ -228,11 +245,13 @@ async function handleAlphaCommand(action: string | undefined): Promise { } if (!action || action === "status") { - if (isAlphaLoggedIn()) { - const name = getAlphaUserName(); + const status = await verifyAlphaAuthStatus({ getValidToken: getValidAlphaToken }); + if (status.authenticated) { + const name = status.name ?? getAlphaUserName(); console.log(name ? `alphaXiv logged in as ${name}` : "alphaXiv logged in"); } else { console.log("alphaXiv not logged in"); + process.exitCode = 1; } return; } @@ -242,7 +261,7 @@ async function handleAlphaCommand(action: string | undefined): Promise { async function handleModelCommand(subcommand: string | undefined, args: string[], feynmanSettingsPath: string, feynmanAuthPath: string): Promise { if (!subcommand || subcommand === "list") { - printModelList(feynmanSettingsPath, feynmanAuthPath); + await printModelList(feynmanSettingsPath, feynmanAuthPath); return; } @@ -267,7 +286,7 @@ async function handleModelCommand(subcommand: string | undefined, args: string[] if (!spec) { throw new Error("Usage: feynman model set "); } - setDefaultModelSpec(feynmanSettingsPath, feynmanAuthPath, spec); + await setDefaultModelSpec(feynmanSettingsPath, feynmanAuthPath, spec); return; } @@ -564,19 +583,19 @@ export function resolveThinkingConfig(rawValue: string | undefined): { }; } -export function shouldRunInteractiveSetup( +export async function shouldRunInteractiveSetup( explicitModelSpec: string | undefined, currentModelSpec: string | undefined, isInteractiveTerminal: boolean, authPath: string, -): boolean { +): Promise { if (explicitModelSpec || !isInteractiveTerminal) { return false; } const status = buildModelStatusSnapshotFromRecords( - getSupportedModelRecords(authPath), - getAuthenticatedModelRecords(authPath), + await getSupportedModelRecords(authPath), + await getAuthenticatedModelRecords(authPath), currentModelSpec, ); return !status.currentValid; @@ -595,7 +614,7 @@ export function resolveWorkspaceInputPath(workingDir: string, value: string | un return trimmed ? resolve(workingDir, trimmed) : undefined; } -export function resolveRankSynthesisModelSpec(authPath: string, explicitModelSpec: string | undefined): string | undefined { +export async function resolveRankSynthesisModelSpec(authPath: string, explicitModelSpec: string | undefined): Promise { const trimmed = explicitModelSpec?.trim(); if (trimmed) { if (isProClassModelSpec(trimmed)) { @@ -603,7 +622,7 @@ export function resolveRankSynthesisModelSpec(authPath: string, explicitModelSpe } return trimmed; } - return chooseRecommendedModel(authPath)?.spec; + return (await chooseRecommendedModel(authPath))?.spec; } function createRankModelSynthesizer(options: { @@ -613,12 +632,12 @@ function createRankModelSynthesizer(options: { modelSpec?: string; }): ModelSynthesizer { return async ({ prompt }) => { - const modelRegistry = createModelRegistry(options.authPath); + const modelRuntime = await createModelRuntime(options.authPath); const requestedModel = options.modelSpec?.trim(); if (requestedModel && isProClassModelSpec(requestedModel)) { throw new Error(`Pro-class synthesis model disabled: ${requestedModel}. Choose a non-Pro model.`); } - const recommendation = requestedModel ? undefined : chooseRecommendedModel(options.authPath); + const recommendation = requestedModel ? undefined : await chooseRecommendedModel(options.authPath); const resolvedModelSpec = requestedModel || recommendation?.spec; if (!resolvedModelSpec) { throw new Error("No non-Pro model is available for PaperRank synthesis. Run `feynman model login` for a non-Pro model or pass `--synthesis-model provider/model` with a non-Pro model."); @@ -626,7 +645,7 @@ function createRankModelSynthesizer(options: { if (isProClassModelSpec(resolvedModelSpec)) { throw new Error(`Pro-class synthesis model disabled: ${resolvedModelSpec}. Choose a non-Pro model.`); } - const model = parseModelSpec(resolvedModelSpec, modelRegistry); + const model = parseModelSpec(resolvedModelSpec, modelRuntime); if (!model) { throw new Error(`Unknown synthesis model: ${resolvedModelSpec}`); } @@ -650,8 +669,7 @@ function createRankModelSynthesizer(options: { const { session } = await createAgentSession({ cwd: options.cwd, agentDir: options.agentDir, - authStorage: modelRegistry.authStorage, - modelRegistry, + modelRuntime, model, sessionManager: SessionManager.inMemory(options.cwd), settingsManager, @@ -862,53 +880,66 @@ async function runMain(input: { here: string; appRoot: string; feynmanVersion: s const rawArgs = process.argv.slice(2); const alphaPassthrough = resolveAlphaPassthroughArgs(rawArgs); - if (alphaPassthrough) { + if (alphaPassthrough && alphaPassthrough.args[0] !== "status") { await runBundledAlphaCli(appRoot, alphaPassthrough.args, { cwd: alphaPassthrough.cwd }); return; } - const { values, positionals } = parseArgs({ - args: process.argv.slice(2), - allowPositionals: true, - options: { - cwd: { type: "string" }, - doctor: { type: "boolean" }, - help: { type: "boolean" }, - version: { type: "boolean" }, - "alpha-login": { type: "boolean" }, - "alpha-logout": { type: "boolean" }, - "alpha-status": { type: "boolean" }, - mode: { type: "string" }, - model: { type: "string" }, - "new-session": { type: "boolean" }, - json: { type: "boolean" }, - host: { type: "string" }, - limit: { type: "string" }, - "no-auth": { type: "boolean" }, - "no-open": { type: "boolean" }, - "expand-citations": { type: "string" }, - "full-text-top": { type: "string" }, - port: { type: "string" }, - "critique-top": { type: "string" }, - synthesize: { type: "boolean" }, - "synthesis-top": { type: "string" }, - "synthesis-model": { type: "string" }, - "output-dir": { type: "string" }, - "fetch-full-text": { type: "boolean" }, - "preference-file": { type: "string" }, - "reproduction-notes": { type: "string" }, - prompt: { type: "string" }, - "service-tier": { type: "string" }, - "session-dir": { type: "string" }, - "source-fixture": { type: "string" }, - "setup-preview": { type: "boolean" }, - "tier1-threshold": { type: "string" }, - "tier2-threshold": { type: "string" }, - thinking: { type: "string" }, - overlap: { type: "string" }, - "window-size": { type: "string" }, - }, - }); + const parseCliArgs = () => + parseArgs({ + args: process.argv.slice(2), + allowPositionals: true, + options: { + cwd: { type: "string" }, + doctor: { type: "boolean" }, + help: { type: "boolean" }, + version: { type: "boolean" }, + "alpha-login": { type: "boolean" }, + "alpha-logout": { type: "boolean" }, + "alpha-status": { type: "boolean" }, + mode: { type: "string" }, + model: { type: "string" }, + "new-session": { type: "boolean" }, + json: { type: "boolean" }, + host: { type: "string" }, + limit: { type: "string" }, + "no-auth": { type: "boolean" }, + "no-open": { type: "boolean" }, + "expand-citations": { type: "string" }, + "full-text-top": { type: "string" }, + port: { type: "string" }, + "critique-top": { type: "string" }, + synthesize: { type: "boolean" }, + "synthesis-top": { type: "string" }, + "synthesis-model": { type: "string" }, + "output-dir": { type: "string" }, + "fetch-full-text": { type: "boolean" }, + "preference-file": { type: "string" }, + "reproduction-notes": { type: "string" }, + prompt: { type: "string" }, + "service-tier": { type: "string" }, + "session-dir": { type: "string" }, + "source-fixture": { type: "string" }, + "setup-preview": { type: "boolean" }, + "tier1-threshold": { type: "string" }, + "tier2-threshold": { type: "string" }, + thinking: { type: "string" }, + overlap: { type: "string" }, + "window-size": { type: "string" }, + }, + }); + + let parsedArgs: ReturnType; + try { + parsedArgs = parseCliArgs(); + } catch (error) { + if (error && typeof error === "object" && "code" in error && error.code === "ERR_PARSE_ARGS_UNKNOWN_OPTION") { + const message = error instanceof Error ? error.message : String(error); + throw new Error(`${message}\nRun \`feynman help\` to see available commands and flags.`); + } + throw error; + } + const { values, positionals } = parsedArgs; if (values.help) { printHelp(appRoot); @@ -929,10 +960,10 @@ async function runMain(input: { here: string; appRoot: string; feynmanVersion: s const feynmanAuthPath = resolve(feynmanAgentDir, "auth.json"); const { defaultThinkingLevel, launchThinkingLevel } = resolveThinkingConfig(values.thinking ?? process.env.FEYNMAN_THINKING); - normalizeFeynmanSettings(feynmanSettingsPath, bundledSettingsPath, defaultThinkingLevel, feynmanAuthPath); + await normalizeFeynmanSettings(feynmanSettingsPath, bundledSettingsPath, defaultThinkingLevel, feynmanAuthPath); if (values.doctor) { - runDoctor({ + await runDoctor({ settingsPath: feynmanSettingsPath, authPath: feynmanAuthPath, sessionDir, @@ -991,7 +1022,7 @@ async function runMain(input: { here: string; appRoot: string; feynmanVersion: s } if (command === "doctor") { - runDoctor({ + await runDoctor({ settingsPath: feynmanSettingsPath, authPath: feynmanAuthPath, sessionDir, @@ -1002,7 +1033,7 @@ async function runMain(input: { here: string; appRoot: string; feynmanVersion: s } if (command === "status") { - runStatus({ + await runStatus({ settingsPath: feynmanSettingsPath, authPath: feynmanAuthPath, sessionDir, @@ -1050,6 +1081,10 @@ async function runMain(input: { here: string; appRoot: string; feynmanVersion: s } if (command === "alpha") { + if (rest[0] === "status") { + await handleAlphaCommand("status"); + return; + } await runBundledAlphaCli(appRoot, rest, { cwd: workingDir }); return; } @@ -1265,7 +1300,8 @@ async function runMain(input: { here: string; appRoot: string; feynmanVersion: s return; } - const explicitModelSpec = values.model ?? process.env.FEYNMAN_MODEL; + const requestedExplicitModelSpec = values.model ?? process.env.FEYNMAN_MODEL; + let explicitModelSpec = requestedExplicitModelSpec; const explicitServiceTier = normalizeServiceTier(values["service-tier"] ?? process.env.FEYNMAN_SERVICE_TIER); const mode = values.mode; if (mode !== undefined && mode !== "text" && mode !== "json" && mode !== "rpc") { @@ -1277,19 +1313,20 @@ async function runMain(input: { here: string; appRoot: string; feynmanVersion: s if (explicitServiceTier) { process.env.FEYNMAN_SERVICE_TIER = explicitServiceTier; } - if (explicitModelSpec) { - if (isProClassModelSpec(explicitModelSpec)) { - throw new Error(`Pro-class model disabled: ${explicitModelSpec}. Choose a non-Pro model.`); + if (requestedExplicitModelSpec) { + if (isProClassModelSpec(requestedExplicitModelSpec)) { + throw new Error(`Pro-class model disabled: ${requestedExplicitModelSpec}. Choose a non-Pro model.`); } - const modelRegistry = createModelRegistry(feynmanAuthPath); - const explicitModel = parseModelSpec(explicitModelSpec, modelRegistry); - if (!explicitModel) { - throw new Error(`Unknown model: ${explicitModelSpec}`); + const modelRuntime = await createModelRuntime(feynmanAuthPath); + const canonicalModelSpec = canonicalizeModelSpec(requestedExplicitModelSpec, modelRuntime); + if (!canonicalModelSpec) { + throw new Error(`Unknown model: ${requestedExplicitModelSpec}`); } + explicitModelSpec = canonicalModelSpec; } const currentModelSpec = getCurrentModelSpec(feynmanSettingsPath); - if (shouldRunInteractiveSetup( + if (await shouldRunInteractiveSetup( explicitModelSpec, currentModelSpec, Boolean(process.stdin.isTTY && process.stdout.isTTY), @@ -1307,7 +1344,7 @@ async function runMain(input: { here: string; appRoot: string; feynmanVersion: s if (!getCurrentModelSpec(feynmanSettingsPath)) { return; } - normalizeFeynmanSettings(feynmanSettingsPath, bundledSettingsPath, defaultThinkingLevel, feynmanAuthPath); + await normalizeFeynmanSettings(feynmanSettingsPath, bundledSettingsPath, defaultThinkingLevel, feynmanAuthPath); } const workflowCommandNames = new Set(readPromptSpecs(appRoot).filter((s) => s.topLevelCli).map((s) => s.name)); diff --git a/src/config/paths.ts b/src/config/paths.ts index cc322ab4..03e60ca5 100644 --- a/src/config/paths.ts +++ b/src/config/paths.ts @@ -1,5 +1,5 @@ import { randomUUID } from "node:crypto"; -import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { existsSync, linkSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs"; import { homedir } from "node:os"; import { resolve } from "node:path"; @@ -68,8 +68,34 @@ function normalizeActiveOrg(home: string, value: unknown): FeynmanActiveOrg | un }; } -function writeActiveOrg(path: string, org: FeynmanActiveOrg): void { - writeFileSync(path, `${JSON.stringify(org, null, 2)}\n`, { encoding: "utf8", mode: 0o600 }); +function activeOrgJson(org: FeynmanActiveOrg): string { + return `${JSON.stringify(org, null, 2)}\n`; +} + +function writeActiveOrgAtomic(path: string, org: FeynmanActiveOrg): void { + const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`; + try { + writeFileSync(temporaryPath, activeOrgJson(org), { encoding: "utf8", mode: 0o600, flag: "wx" }); + renameSync(temporaryPath, path); + } finally { + rmSync(temporaryPath, { force: true }); + } +} + +function createActiveOrg(path: string, org: FeynmanActiveOrg): boolean { + const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`; + try { + writeFileSync(temporaryPath, activeOrgJson(org), { encoding: "utf8", mode: 0o600, flag: "wx" }); + try { + linkSync(temporaryPath, path); + return true; + } catch (error) { + if ((error as NodeJS.ErrnoException).code === "EEXIST") return false; + throw error; + } + } finally { + rmSync(temporaryPath, { force: true }); + } } export function ensureFeynmanActiveOrg(home = getFeynmanHome()): FeynmanActiveOrg { @@ -78,9 +104,12 @@ export function ensureFeynmanActiveOrg(home = getFeynmanHome()): FeynmanActiveOr const path = getFeynmanActiveOrgPath(home); if (existsSync(path)) { try { - const normalized = normalizeActiveOrg(home, JSON.parse(readFileSync(path, "utf8"))); + const parsed = JSON.parse(readFileSync(path, "utf8")) as unknown; + const normalized = normalizeActiveOrg(home, parsed); if (normalized) { - writeActiveOrg(path, normalized); + if (JSON.stringify(parsed) !== JSON.stringify(normalized)) { + writeActiveOrgAtomic(path, normalized); + } mkdirSync(resolve(getFeynmanOrgsDir(home), normalized.org_uuid), { recursive: true }); return normalized; } @@ -95,7 +124,18 @@ export function ensureFeynmanActiveOrg(home = getFeynmanHome()): FeynmanActiveOr account_uuid: randomUUID(), login_owner_data_dir: home, }; - writeActiveOrg(path, org); + if (!createActiveOrg(path, org)) { + try { + const existing = normalizeActiveOrg(home, JSON.parse(readFileSync(path, "utf8"))); + if (existing) { + mkdirSync(resolve(getFeynmanOrgsDir(home), existing.org_uuid), { recursive: true }); + return existing; + } + } catch { + // An existing invalid manifest is replaced atomically below. + } + writeActiveOrgAtomic(path, org); + } mkdirSync(resolve(getFeynmanOrgsDir(home), org.org_uuid), { recursive: true }); return org; } diff --git a/src/model/catalog.ts b/src/model/catalog.ts index 4d06fcd5..70b4f011 100644 --- a/src/model/catalog.ts +++ b/src/model/catalog.ts @@ -2,7 +2,7 @@ import { readFileSync } from "node:fs"; import { getEnvApiKey } from "@earendil-works/pi-ai/compat"; -import { createModelRegistry } from "./registry.js"; +import { createModelRuntime } from "./registry.js"; type ModelRecord = { provider: string; @@ -346,21 +346,22 @@ function sortProviders(left: ProviderStatus, right: ProviderStatus): number { return left.label.localeCompare(right.label); } -export function getAuthenticatedModelRecords(authPath: string): ModelRecord[] { +export async function getAuthenticatedModelRecords(authPath: string): Promise { const expiredOAuthProviders = readExpiredOAuthProviders(authPath); - return createModelRegistry(authPath) - .getAvailable() + const modelRuntime = await createModelRuntime(authPath); + return (await modelRuntime.getAvailable()) .filter((model) => !expiredOAuthProviders.has(model.provider)) .map((model) => ({ provider: model.provider, id: model.id, name: model.name })); } -export function getAvailableModelRecords(authPath: string): ModelRecord[] { - return getAuthenticatedModelRecords(authPath).filter((model) => !isProClassModel(model)); +export async function getAvailableModelRecords(authPath: string): Promise { + return (await getAuthenticatedModelRecords(authPath)).filter((model) => !isProClassModel(model)); } -export function getSupportedModelRecords(authPath: string): ModelRecord[] { - return createModelRegistry(authPath) - .getAll() +export async function getSupportedModelRecords(authPath: string): Promise { + const modelRuntime = await createModelRuntime(authPath); + return modelRuntime + .getModels() .map((model) => ({ provider: model.provider, id: model.id, name: model.name })); } @@ -380,8 +381,8 @@ function readExpiredOAuthProviders(authPath: string): Set { return expired; } -export function chooseRecommendedModel(authPath: string): { spec: string; reason: string } | undefined { - const preferred = choosePreferredModelRecord(getAvailableModelRecords(authPath)); +export async function chooseRecommendedModel(authPath: string): Promise<{ spec: string; reason: string } | undefined> { + const preferred = choosePreferredModelRecord(await getAvailableModelRecords(authPath)); if (!preferred) { return undefined; } diff --git a/src/model/commands.ts b/src/model/commands.ts index b052716c..bc241ed5 100644 --- a/src/model/commands.ts +++ b/src/model/commands.ts @@ -1,4 +1,4 @@ -import { AuthStorage } from "@earendil-works/pi-coding-agent"; +import type { AuthEvent, AuthPrompt } from "@earendil-works/pi-ai"; import { readFileSync, writeFileSync } from "node:fs"; import { exec as execCallback } from "node:child_process"; import { promisify } from "node:util"; @@ -16,15 +16,15 @@ import { type ModelStatusSnapshot, } from "./catalog.js"; import { MODEL_API_KEY_PROVIDERS, type ApiKeyProviderInfo } from "./api-key-providers.js"; -import { createModelRegistry, getModelsJsonPath } from "./registry.js"; +import { createModelRegistry, createModelRuntime, getModelsJsonPath } from "./registry.js"; import { upsertProviderBaseUrl, upsertProviderConfig } from "./models-json.js"; const exec = promisify(execCallback); -function collectModelStatus(settingsPath: string, authPath: string): ModelStatusSnapshot { +async function collectModelStatus(settingsPath: string, authPath: string): Promise { return buildModelStatusSnapshotFromRecords( - getSupportedModelRecords(authPath), - getAuthenticatedModelRecords(authPath), + await getSupportedModelRecords(authPath), + await getAuthenticatedModelRecords(authPath), getCurrentModelSpec(settingsPath), ); } @@ -35,20 +35,27 @@ type OAuthProviderInfo = { usesCallbackServer?: boolean; }; -function getOAuthProviders(authPath: string): OAuthProviderInfo[] { - return AuthStorage.create(authPath).getOAuthProviders() as OAuthProviderInfo[]; +async function getOAuthProviders(authPath: string): Promise { + const modelRuntime = await createModelRuntime(authPath); + return modelRuntime + .getProviders() + .filter((provider) => Boolean(provider.auth.oauth)) + .map((provider) => ({ + id: provider.id, + name: provider.auth.oauth?.name ?? provider.name, + })); } -function resolveOAuthProvider(authPath: string, input: string): OAuthProviderInfo | undefined { +async function resolveOAuthProvider(authPath: string, input: string): Promise { const normalizedInput = input.trim().toLowerCase(); if (!normalizedInput) { return undefined; } - return getOAuthProviders(authPath).find((provider) => provider.id.toLowerCase() === normalizedInput); + return (await getOAuthProviders(authPath)).find((provider) => provider.id.toLowerCase() === normalizedInput); } async function selectOAuthProvider(authPath: string, action: "login" | "logout"): Promise { - const providers = getOAuthProviders(authPath); + const providers = await getOAuthProviders(authPath); if (providers.length === 0) { printWarning("No Pi OAuth model providers are available."); return undefined; @@ -83,11 +90,11 @@ function resolveApiKeyProvider(input: string): ApiKeyProviderInfo | undefined { return MODEL_API_KEY_PROVIDERS.find((provider) => provider.id === normalizedInput); } -export function resolveModelProviderForCommand( +export async function resolveModelProviderForCommand( authPath: string, input: string, -): { kind: "oauth" | "api-key"; id: string } | undefined { - const oauthProvider = resolveOAuthProvider(authPath, input); +): Promise<{ kind: "oauth" | "api-key"; id: string } | undefined> { + const oauthProvider = await resolveOAuthProvider(authPath, input); if (oauthProvider) { return { kind: "oauth", id: oauthProvider.id }; } @@ -465,7 +472,7 @@ async function promptLiteLlmProviderSetup(): Promise { - const registry = createModelRegistry(authPath); + const registry = await createModelRegistry(authPath); const modelsError = registry.getError(); if (modelsError) { printWarning("Verification: models.json failed to load."); @@ -605,8 +612,11 @@ async function configureBedrockProvider(authPath: string): Promise { try { await verifyBedrockCredentialChain(); - AuthStorage.create(authPath).set("amazon-bedrock", { type: "api_key", key: "" }); - printSuccess("Verified AWS credential chain and marked Amazon Bedrock as configured."); + const modelRuntime = await createModelRuntime(authPath); + if (!(await modelRuntime.checkAuth("amazon-bedrock"))) { + throw new Error("Pi could not resolve the verified AWS credential chain for Amazon Bedrock."); + } + printSuccess("Verified the AWS credential chain used by Amazon Bedrock."); printInfo("Use `feynman model list` to see available Bedrock models."); return true; } catch (error) { @@ -619,19 +629,19 @@ async function configureBedrockProvider(authPath: string): Promise { } } -function maybeSetRecommendedDefaultModel(settingsPath: string | undefined, authPath: string): void { +async function maybeSetRecommendedDefaultModel(settingsPath: string | undefined, authPath: string): Promise { if (!settingsPath) { return; } const currentSpec = getCurrentModelSpec(settingsPath); - const available = getAvailableModelRecords(authPath); + const available = await getAvailableModelRecords(authPath); const currentValid = currentSpec ? available.some((m) => `${m.provider}/${m.id}` === currentSpec) : false; if ((!currentSpec || !currentValid) && available.length > 0) { - const recommended = chooseRecommendedModel(authPath); + const recommended = await chooseRecommendedModel(authPath); if (recommended) { - setDefaultModelSpec(settingsPath, authPath, recommended.spec); + await setDefaultModelSpec(settingsPath, authPath, recommended.spec); } } } @@ -740,7 +750,11 @@ async function configureApiKeyProvider(authPath: string, providerId?: string): P return false; } - AuthStorage.create(authPath).set(provider.id, { type: "api_key", key: apiKey }); + const modelRuntime = await createModelRuntime(authPath); + await modelRuntime.login(provider.id, "api_key", { + prompt: async () => apiKey, + notify: () => undefined, + }); printSuccess(`Saved API key for ${provider.id} in auth storage.`); const baseUrl = await promptText("Base URL override (optional, include /v1 for OpenAI-compatible endpoints)", ""); @@ -757,13 +771,13 @@ async function configureApiKeyProvider(authPath: string, providerId?: string): P return true; } -function resolveAvailableModelSpec(authPath: string, input: string): string | undefined { +async function resolveAvailableModelSpec(authPath: string, input: string): Promise { const normalizedInput = input.trim().replace(/^([^/:]+):(.+)$/, "$1/$2").toLowerCase(); if (!normalizedInput) { return undefined; } - const available = getAvailableModelRecords(authPath); + const available = await getAvailableModelRecords(authPath); const fullSpecMatch = available.find((model) => `${model.provider}/${model.id}`.toLowerCase() === normalizedInput); if (fullSpecMatch) { return `${fullSpecMatch.provider}/${fullSpecMatch.id}`; @@ -796,8 +810,8 @@ export function getCurrentModelSpec(settingsPath: string): string | undefined { return undefined; } -export function printModelList(settingsPath: string, authPath: string): void { - const status = collectModelStatus(settingsPath, authPath); +export async function printModelList(settingsPath: string, authPath: string): Promise { + const status = await collectModelStatus(settingsPath, authPath); if (status.availableModels.length === 0) { printWarning("No authenticated Pi models are currently available."); for (const line of status.guidance) { @@ -836,7 +850,7 @@ export async function authenticateModelProvider(authPath: string, settingsPath?: if (selection === 1) { const configured = await configureApiKeyProvider(authPath); if (configured) { - maybeSetRecommendedDefaultModel(settingsPath, authPath); + await maybeSetRecommendedDefaultModel(settingsPath, authPath); } return configured; } @@ -847,20 +861,20 @@ export async function authenticateModelProvider(authPath: string, settingsPath?: export async function loginModelProvider(authPath: string, providerId?: string, settingsPath?: string): Promise { if (providerId) { - const resolvedProvider = resolveModelProviderForCommand(authPath, providerId); + const resolvedProvider = await resolveModelProviderForCommand(authPath, providerId); if (!resolvedProvider) { throw new Error(`Unknown model provider: ${providerId}`); } if (resolvedProvider.kind === "api-key") { const configured = await configureApiKeyProvider(authPath, resolvedProvider.id); if (configured) { - maybeSetRecommendedDefaultModel(settingsPath, authPath); + await maybeSetRecommendedDefaultModel(settingsPath, authPath); } return configured; } } - const provider = providerId ? resolveOAuthProvider(authPath, providerId) : await selectOAuthProvider(authPath, "login"); + const provider = providerId ? await resolveOAuthProvider(authPath, providerId) : await selectOAuthProvider(authPath, "login"); if (!provider) { if (providerId) { throw new Error(`Unknown model provider: ${providerId}`); @@ -869,66 +883,73 @@ export async function loginModelProvider(authPath: string, providerId?: string, return false; } - const authStorage = AuthStorage.create(authPath); + const modelRuntime = await createModelRuntime(authPath); const abortController = new AbortController(); - await authStorage.login(provider.id, { - onAuth: (info: { url: string; instructions?: string }) => { - printSection(`Login: ${provider.name ?? provider.id}`); - const opened = openUrl(info.url); - if (opened) { - printInfo("Opened the login URL in your browser."); - } else { - printWarning("Couldn't open your browser automatically."); + await modelRuntime.login(provider.id, "oauth", { + prompt: async (prompt: AuthPrompt) => { + if (prompt.type === "select") { + return promptSelect( + prompt.message, + prompt.options.map((option) => ({ + value: option.id, + label: option.label, + hint: option.description, + })), + undefined, + prompt.signal, + ); } - printInfo(`Auth URL: ${info.url}`); - if (info.instructions) { - printInfo(info.instructions); - } - }, - onPrompt: async (prompt: { message: string; placeholder?: string }) => { - return promptText(prompt.message, prompt.placeholder ?? ""); - }, - onProgress: (message: string) => { - printInfo(message); - }, - onManualCodeInput: async () => { - return promptText("Paste redirect URL or auth code"); - }, - onDeviceCode: (info: { userCode: string; verificationUri: string }) => { - printSection(`Login: ${provider.name ?? provider.id}`); - printInfo(`Visit ${info.verificationUri} and enter code: ${info.userCode}`); - openUrl(info.verificationUri); + return promptText(prompt.message, "", prompt.placeholder, prompt.signal); }, - onSelect: async (prompt: { message: string; options: Array<{ id: string; label: string }> }) => { - return promptSelect( - prompt.message, - prompt.options.map((option) => ({ value: option.id, label: option.label })), - ); + notify: (event: AuthEvent) => { + if (event.type === "auth_url") { + printSection(`Login: ${provider.name ?? provider.id}`); + if (openUrl(event.url)) { + printInfo("Opened the login URL in your browser."); + } else { + printWarning("Couldn't open your browser automatically."); + } + printInfo(`Auth URL: ${event.url}`); + if (event.instructions) { + printInfo(event.instructions); + } + return; + } + if (event.type === "device_code") { + printSection(`Login: ${provider.name ?? provider.id}`); + printInfo(`Visit ${event.verificationUri} and enter code: ${event.userCode}`); + openUrl(event.verificationUri); + return; + } + if (event.type === "progress" || event.type === "info") { + printInfo(event.message); + } }, signal: abortController.signal, }); printSuccess(`Model provider login complete: ${provider.id}`); - maybeSetRecommendedDefaultModel(settingsPath, authPath); + await maybeSetRecommendedDefaultModel(settingsPath, authPath); return true; } export async function logoutModelProvider(authPath: string, providerId?: string): Promise { - const authStorage = AuthStorage.create(authPath); + const modelRuntime = await createModelRuntime(authPath); if (providerId) { - const resolvedProvider = resolveModelProviderForCommand(authPath, providerId); + const resolvedProvider = await resolveModelProviderForCommand(authPath, providerId); if (resolvedProvider) { - authStorage.logout(resolvedProvider.id); + await modelRuntime.logout(resolvedProvider.id); printSuccess(`Model provider logout complete: ${resolvedProvider.id}`); return; } const normalizedProviderId = normalizeProviderId(providerId); - if (authStorage.has(normalizedProviderId)) { - authStorage.logout(normalizedProviderId); + const credentials = await modelRuntime.listCredentials(); + if (credentials.some((credential) => credential.providerId === normalizedProviderId)) { + await modelRuntime.logout(normalizedProviderId); printSuccess(`Model provider logout complete: ${normalizedProviderId}`); return; } @@ -942,12 +963,12 @@ export async function logoutModelProvider(authPath: string, providerId?: string) return; } - authStorage.logout(provider.id); + await modelRuntime.logout(provider.id); printSuccess(`Model provider logout complete: ${provider.id}`); } -export function setDefaultModelSpec(settingsPath: string, authPath: string, spec: string): void { - const resolvedSpec = resolveAvailableModelSpec(authPath, spec); +export async function setDefaultModelSpec(settingsPath: string, authPath: string, spec: string): Promise { + const resolvedSpec = await resolveAvailableModelSpec(authPath, spec); if (!resolvedSpec) { throw new Error(`Model not available in Pi auth storage: ${spec}. Run \`feynman model list\` first.`); } @@ -962,7 +983,7 @@ export function setDefaultModelSpec(settingsPath: string, authPath: string, spec } export async function runModelSetup(settingsPath: string, authPath: string): Promise { - let status = collectModelStatus(settingsPath, authPath); + let status = await collectModelStatus(settingsPath, authPath); while (status.availableModels.length === 0) { const choices = [ @@ -974,20 +995,20 @@ export async function runModelSetup(settingsPath: string, authPath: string): Pro if (selection === 0) { const loggedIn = await loginModelProvider(authPath, undefined, settingsPath); if (!loggedIn) { - status = collectModelStatus(settingsPath, authPath); + status = await collectModelStatus(settingsPath, authPath); continue; } } else if (selection === 1) { const configured = await configureApiKeyProvider(authPath); if (!configured) { - status = collectModelStatus(settingsPath, authPath); + status = await collectModelStatus(settingsPath, authPath); continue; } } else { printInfo("Setup cancelled."); return; } - status = collectModelStatus(settingsPath, authPath); + status = await collectModelStatus(settingsPath, authPath); if (status.availableModels.length === 0) { printWarning("No authenticated models are available yet."); printInfo("If you configured a custom provider, ensure it has `apiKey` set in models.json."); @@ -1002,6 +1023,6 @@ export async function runModelSetup(settingsPath: string, authPath: string): Pro const recommended = status.recommended ?? status.availableModels[0]; if (recommended) { - setDefaultModelSpec(settingsPath, authPath, recommended); + await setDefaultModelSpec(settingsPath, authPath, recommended); } } diff --git a/src/model/registry.ts b/src/model/registry.ts index dd4e9453..7dff1c9d 100644 --- a/src/model/registry.ts +++ b/src/model/registry.ts @@ -1,11 +1,19 @@ import { dirname, resolve } from "node:path"; -import { AuthStorage, ModelRegistry } from "@earendil-works/pi-coding-agent"; +import { ModelRegistry, ModelRuntime } from "@earendil-works/pi-coding-agent"; export function getModelsJsonPath(authPath: string): string { return resolve(dirname(authPath), "models.json"); } -export function createModelRegistry(authPath: string): ModelRegistry { - return ModelRegistry.create(AuthStorage.create(authPath), getModelsJsonPath(authPath)); +export async function createModelRuntime(authPath: string): Promise { + return ModelRuntime.create({ + authPath, + modelsPath: getModelsJsonPath(authPath), + allowModelNetwork: false, + }); +} + +export async function createModelRegistry(authPath: string): Promise { + return new ModelRegistry(await createModelRuntime(authPath)); } diff --git a/src/pi/launch.ts b/src/pi/launch.ts index a9eddf68..65b07fe8 100644 --- a/src/pi/launch.ts +++ b/src/pi/launch.ts @@ -6,6 +6,7 @@ import { buildPiArgs, buildPiEnv, ensureFeynmanCommandShim, + ensureFeynmanWorkspaceScaffold, type PiRuntimeOptions, resolvePiPaths, toNodeImportSpecifier, @@ -66,6 +67,7 @@ export async function launchPiChat(options: PiRuntimeOptions): Promise { : ["--import", toNodeImportSpecifier(promisePolyfillPath)]; const executables = await resolveAllExecutables(); ensureFeynmanCommandShim(options.appRoot, options.feynmanAgentDir); + ensureFeynmanWorkspaceScaffold(options.workingDir); const child = spawn(process.execPath, [...importArgs, wrapperPath, piMainPath, ...buildPiArgs(options, paths)], { cwd: options.workingDir, diff --git a/src/pi/package-ops.ts b/src/pi/package-ops.ts index fc33decd..9552d9e3 100644 --- a/src/pi/package-ops.ts +++ b/src/pi/package-ops.ts @@ -58,7 +58,7 @@ const FILTERED_INSTALL_OUTPUT_PATTERNS = [ /^run `npm fund` for details$/i, ]; const APP_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..", ".."); -const PI_RUNTIME_FALLBACK_VERSION = "0.80.3"; +const PI_RUNTIME_FALLBACK_VERSION = "0.82.1"; const LEGACY_PI_RUNTIME_PACKAGE_ALIASES = { "@mariozechner/pi-agent-core": "@earendil-works/pi-agent-core", "@mariozechner/pi-ai": "@earendil-works/pi-ai", diff --git a/src/pi/package-presets.ts b/src/pi/package-presets.ts index 5b6ecc8f..e43deb16 100644 --- a/src/pi/package-presets.ts +++ b/src/pi/package-presets.ts @@ -1,6 +1,6 @@ import type { PackageSource } from "@earendil-works/pi-coding-agent"; -export const CORE_PACKAGE_SOURCES = [ +const UNPINNED_CORE_PACKAGE_SOURCES = [ "npm:@companion-ai/alpha-hub", "npm:pi-subagents", "npm:pi-btw", @@ -9,6 +9,15 @@ export const CORE_PACKAGE_SOURCES = [ "npm:pi-otel", ] as const; +export const CORE_PACKAGE_SOURCES = [ + "npm:@companion-ai/alpha-hub@0.1.3", + "npm:pi-subagents@0.37.2", + "npm:pi-btw@0.4.1", + "npm:pi-docparser@3.0.1", + "npm:pi-web-access@0.15.0", + "npm:pi-otel@0.1.0", +] as const; + const LEGACY_CORE_PACKAGE_SOURCES = [ "npm:@companion-ai/alpha-hub", "npm:pi-subagents", @@ -36,6 +45,19 @@ const LEGACY_CORE_WITH_PI_OTEL_PACKAGE_SOURCES = [ "npm:pi-otel", ] as const; +const LEGACY_PINNED_CORE_PACKAGE_SOURCES = [ + ...CORE_PACKAGE_SOURCES, + "npm:pi-markdown-preview", + "npm:@walterra/pi-charts", + "npm:pi-mermaid", + "npm:@aliou/pi-processes", + "npm:pi-zotero", + "npm:@kaiserlich-dev/pi-session-search", + "npm:pi-schedule-prompt", + "npm:@samfp/pi-memory", + "npm:@tmustier/pi-ralph-wiggum", +] as const; + const LEGACY_TELEMETRY_WITH_PI_OTEL_PACKAGE_SOURCES = [ ...LEGACY_CORE_WITH_PI_OTEL_PACKAGE_SOURCES, "npm:@devkade/pi-opentelemetry", @@ -90,6 +112,25 @@ export type OptionalPackagePresetName = keyof typeof OPTIONAL_PACKAGE_PRESETS; export type OptionalPackagePresetAlias = OptionalPackagePresetName; const LEGACY_DEFAULT_PACKAGE_SETS = [ + [ + ...UNPINNED_CORE_PACKAGE_SOURCES, + ], + [ + ...UNPINNED_CORE_PACKAGE_SOURCES, + "npm:pi-generative-ui", + ], + [ + ...UNPINNED_CORE_PACKAGE_SOURCES, + "npm:@devkade/pi-opentelemetry", + ], + [ + ...UNPINNED_CORE_PACKAGE_SOURCES, + "npm:@devkade/pi-opentelemetry", + "npm:pi-generative-ui", + ], + [ + ...LEGACY_PINNED_CORE_PACKAGE_SOURCES, + ], [ ...CORE_PACKAGE_SOURCES, "npm:pi-generative-ui", diff --git a/src/pi/runtime-patches.ts b/src/pi/runtime-patches.ts index c0972168..355eeba4 100644 --- a/src/pi/runtime-patches.ts +++ b/src/pi/runtime-patches.ts @@ -3,8 +3,10 @@ import { dirname, resolve } from "node:path"; import { patchAlphaHubAuthSource } from "../../scripts/lib/alpha-hub-auth-patch.mjs"; import { patchAlphaHubSearchResultsSource, patchAlphaHubSearchSource } from "../../scripts/lib/alpha-hub-search-patch.mjs"; +import { patchMcpSdkPackageJsonSource } from "../../scripts/lib/mcp-sdk-package-patch.mjs"; import { patchPiAgentCoreSource } from "../../scripts/lib/pi-agent-core-patch.mjs"; import { patchPiModelRegistrySource } from "../../scripts/lib/pi-model-registry-patch.mjs"; +import { patchPiBraceExpansionTree } from "../../scripts/lib/pi-shrinkwrap-security-patch.mjs"; import { PI_OTEL_PATCH_TARGETS, patchPiOtelSource } from "../../scripts/lib/pi-otel-patch.mjs"; import { PI_SESSION_SEARCH_PATCH_TARGETS, patchPiSessionSearchSource } from "../../scripts/lib/pi-session-search-patch.mjs"; import { PI_SUBAGENTS_PATCH_TARGETS, patchPiSubagentsSource } from "../../scripts/lib/pi-subagents-patch.mjs"; @@ -89,7 +91,9 @@ export function patchPiRuntimeNodeModules(appRoot: string, feynmanAgentDir?: str nodeModuleRoots.push(resolve(feynmanAgentDir, "npm", "node_modules")); } let changed = false; + const safeBraceExpansionPath = resolve(appRoot, "node_modules", "brace-expansion"); for (const nodeModulesPath of nodeModuleRoots) { + changed = patchPiBraceExpansionTree(nodeModulesPath, safeBraceExpansionPath) || changed; changed = patchScopedPiPackageFileIfPresent( nodeModulesPath, "pi-coding-agent", @@ -126,6 +130,20 @@ export function patchPiRuntimeNodeModules(appRoot: string, feynmanAgentDir?: str "dist/core/model-registry.js", patchPiModelRegistrySource, ) || changed; + changed = patchScopedPiPackageFileIfPresent( + nodeModulesPath, + "pi-coding-agent", + "dist/core/model-runtime.js", + patchPiModelRegistrySource, + ) || changed; + changed = patchFileIfPresent( + resolve(nodeModulesPath, "@modelcontextprotocol", "sdk", "package.json"), + patchMcpSdkPackageJsonSource, + ) || changed; + changed = patchFileIfPresent( + resolve(nodeModulesPath, "@companion-ai", "alpha-hub", "node_modules", "@modelcontextprotocol", "sdk", "package.json"), + patchMcpSdkPackageJsonSource, + ) || changed; changed = patchFileIfPresent( resolve(nodeModulesPath, "@companion-ai", "alpha-hub", "src", "lib", "auth.js"), patchAlphaHubAuthSource, diff --git a/src/pi/runtime.ts b/src/pi/runtime.ts index 1c2472f2..d09c7057 100644 --- a/src/pi/runtime.ts +++ b/src/pi/runtime.ts @@ -64,6 +64,29 @@ export function ensureFeynmanCommandShim(appRoot: string, feynmanAgentDir: strin return shimPath; } +export function ensureFeynmanWorkspaceScaffold( + workingDir: string, + createDirectory: typeof mkdirSync = mkdirSync, +): boolean { + for (const relPath of [ + "outputs/.plans", + "outputs/.drafts", + "papers", + "notes", + ]) { + try { + createDirectory(resolve(workingDir, relPath), { recursive: true }); + } catch (error) { + const code = (error as NodeJS.ErrnoException).code; + if (code === "EACCES" || code === "EPERM" || code === "EROFS") { + return false; + } + throw error; + } + } + return true; +} + export function applyFeynmanPackageManagerEnv(feynmanAgentDir: string): string { const feynmanNpmPrefixPath = getFeynmanNpmPrefixPath(feynmanAgentDir); process.env.FEYNMAN_NPM_PREFIX = feynmanNpmPrefixPath; diff --git a/src/pi/settings.ts b/src/pi/settings.ts index 631d3e30..6c0f531a 100644 --- a/src/pi/settings.ts +++ b/src/pi/settings.ts @@ -1,27 +1,43 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; import { dirname } from "node:path"; -import { ModelRegistry, type PackageSource } from "@earendil-works/pi-coding-agent"; +import type { ModelRegistry, ModelRuntime, PackageSource } from "@earendil-works/pi-coding-agent"; import { CORE_PACKAGE_SOURCES, filterPackageSourcesForCurrentNode, shouldPruneLegacyDefaultPackages } from "./package-presets.js"; import { choosePreferredModelRecord, getAvailableModelRecords, isProClassModelSpec } from "../model/catalog.js"; -export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh"; +export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max"; -export function parseModelSpec(spec: string, modelRegistry: ModelRegistry) { +type ModelLookup = Pick | Pick; + +function findModel(modelLookup: ModelLookup, provider: string, id: string) { + return "find" in modelLookup + ? modelLookup.find(provider, id) + : modelLookup.getModel(provider, id); +} + +export function parseModelSpec(spec: string, modelLookup: ModelLookup) { const trimmed = spec.trim(); - const separator = trimmed.includes(":") ? ":" : trimmed.includes("/") ? "/" : null; - if (!separator) { - return undefined; - } + for (const separator of ["/", ":"] as const) { + const separatorIndex = trimmed.indexOf(separator); + if (separatorIndex <= 0 || separatorIndex === trimmed.length - 1) { + continue; + } - const [provider, ...rest] = trimmed.split(separator); - const id = rest.join(separator); - if (!provider || !id) { - return undefined; + const provider = trimmed.slice(0, separatorIndex); + const id = trimmed.slice(separatorIndex + 1); + const model = findModel(modelLookup, provider, id); + if (model) { + return model; + } } - return modelRegistry.find(provider, id); + return undefined; +} + +export function canonicalizeModelSpec(spec: string, modelLookup: ModelLookup): string | undefined { + const model = parseModelSpec(spec, modelLookup); + return model ? `${model.provider}/${model.id}` : undefined; } export function normalizeThinkingLevel(value: string | undefined): ThinkingLevel | undefined { @@ -36,7 +52,8 @@ export function normalizeThinkingLevel(value: string | undefined): ThinkingLevel normalized === "low" || normalized === "medium" || normalized === "high" || - normalized === "xhigh" + normalized === "xhigh" || + normalized === "max" ) { return normalized; } @@ -78,12 +95,12 @@ export function readJson(path: string): Record { } } -export function normalizeFeynmanSettings( +export async function normalizeFeynmanSettings( settingsPath: string, bundledSettingsPath: string, defaultThinkingLevel: ThinkingLevel, authPath: string, -): void { +): Promise { let settings: Record = {}; if (existsSync(settingsPath)) { @@ -118,7 +135,7 @@ export function normalizeFeynmanSettings( settings.packages = filterConfiguredPackagesForCurrentNode(settings.packages as PackageSource[]); } - const availableModels = getAvailableModelRecords(authPath).map((model) => ({ + const availableModels = (await getAvailableModelRecords(authPath)).map((model) => ({ provider: model.provider, id: model.id, })); diff --git a/src/setup/doctor.ts b/src/setup/doctor.ts index e0c28b97..4df53eb6 100644 --- a/src/setup/doctor.ts +++ b/src/setup/doctor.ts @@ -63,14 +63,14 @@ export type FeynmanStatusSnapshot = { missingPiBits: string[]; }; -export function collectStatusSnapshot(options: DoctorOptions): FeynmanStatusSnapshot { +export async function collectStatusSnapshot(options: DoctorOptions): Promise { const pandocPath = resolveExecutable("pandoc", PANDOC_FALLBACK_PATHS); const browserPath = process.env.PUPPETEER_EXECUTABLE_PATH ?? resolveExecutable("google-chrome", BROWSER_FALLBACK_PATHS); const missingPiBits = validatePiInstallation(options.appRoot); const webStatus = getPiWebAccessStatus(); const modelStatus = buildModelStatusSnapshotFromRecords( - getSupportedModelRecords(options.authPath), - getAvailableModelRecords(options.authPath), + await getSupportedModelRecords(options.authPath), + await getAvailableModelRecords(options.authPath), getCurrentModelSpec(options.settingsPath), ); @@ -95,8 +95,8 @@ export function collectStatusSnapshot(options: DoctorOptions): FeynmanStatusSnap }; } -export function runStatus(options: DoctorOptions): void { - const snapshot = collectStatusSnapshot(options); +export async function runStatus(options: DoctorOptions): Promise { + const snapshot = await collectStatusSnapshot(options); printPanel("Feynman Status", [ "Current setup summary for the research shell.", ]); @@ -131,11 +131,11 @@ export function runStatus(options: DoctorOptions): void { } } -export function runDoctor(options: DoctorOptions): void { +export async function runDoctor(options: DoctorOptions): Promise { const settings = readJson(options.settingsPath); - const modelRegistry = createModelRegistry(options.authPath); - const supportedModels = getSupportedModelRecords(options.authPath); - const modelStatus = collectStatusSnapshot(options); + const modelRegistry = await createModelRegistry(options.authPath); + const supportedModels = await getSupportedModelRecords(options.authPath); + const modelStatus = await collectStatusSnapshot(options); const pandocPath = resolveExecutable("pandoc", PANDOC_FALLBACK_PATHS); const browserPath = process.env.PUPPETEER_EXECUTABLE_PATH ?? resolveExecutable("google-chrome", BROWSER_FALLBACK_PATHS); const missingPiBits = validatePiInstallation(options.appRoot); diff --git a/src/setup/prompts.ts b/src/setup/prompts.ts index 6c217bf9..7f3b3768 100644 --- a/src/setup/prompts.ts +++ b/src/setup/prompts.ts @@ -50,7 +50,12 @@ export async function promptOutro(message: string): Promise { clackOutro(message); } -export async function promptText(question: string, defaultValue = "", placeholder?: string): Promise { +export async function promptText( + question: string, + defaultValue = "", + placeholder?: string, + signal?: AbortSignal, +): Promise { ensureInteractiveTerminal(); const value = guardCancelled( @@ -58,6 +63,7 @@ export async function promptText(question: string, defaultValue = "", placeholde message: question, initialValue: defaultValue || undefined, placeholder: placeholder ?? (defaultValue || undefined), + signal, }), ); @@ -69,6 +75,7 @@ export async function promptSelect( question: string, options: PromptSelectOption[], initialValue?: T, + signal?: AbortSignal, ): Promise { ensureInteractiveTerminal(); @@ -81,6 +88,7 @@ export async function promptSelect( hint: option.hint, })) as Option[], initialValue, + signal, }), ); diff --git a/src/setup/setup.ts b/src/setup/setup.ts index f773698f..a8ed1d7c 100644 --- a/src/setup/setup.ts +++ b/src/setup/setup.ts @@ -186,7 +186,7 @@ export async function runSetup(options: SetupOptions): Promise { await maybeLoginAlpha(); await maybeInstallPreviewDependencies(); - normalizeFeynmanSettings( + await normalizeFeynmanSettings( options.settingsPath, options.bundledSettingsPath, options.defaultThinkingLevel ?? "medium", @@ -194,8 +194,8 @@ export async function runSetup(options: SetupOptions): Promise { ); const modelStatus = buildModelStatusSnapshotFromRecords( - getSupportedModelRecords(options.authPath), - getAvailableModelRecords(options.authPath), + await getSupportedModelRecords(options.authPath), + await getAvailableModelRecords(options.authPath), getCurrentModelSpec(options.settingsPath), ); printSection("Ready"); diff --git a/src/system/node-version.ts b/src/system/node-version.ts index 354b855f..d6d34ce1 100644 --- a/src/system/node-version.ts +++ b/src/system/node-version.ts @@ -1,4 +1,4 @@ -export const MIN_NODE_VERSION = "22.19.0"; +export const MIN_NODE_VERSION = "22.22.0"; export const MAX_NODE_MAJOR = 25; export const PREFERRED_NODE_MAJOR = 24; diff --git a/src/telemetry/posthog.ts b/src/telemetry/posthog.ts index 78bceaac..d54d4305 100644 --- a/src/telemetry/posthog.ts +++ b/src/telemetry/posthog.ts @@ -280,13 +280,14 @@ export function initializePostHogTelemetry(options: { loggerProvider = new LoggerProvider({ resource, processors: [ - new BatchLogRecordProcessor( - new OTLPLogExporter({ + new BatchLogRecordProcessor({ + exporter: new OTLPLogExporter({ url: `${config.host}/i/v1/logs`, headers: { Authorization: `Bearer ${config.projectToken}` }, }), - { scheduledDelayMillis: 250, exportTimeoutMillis: 3000 }, - ), + scheduledDelayMillis: 250, + exportTimeoutMillis: 3000, + }), ], }); logs.setGlobalLoggerProvider(loggerProvider); diff --git a/src/workbench/package-resources.ts b/src/workbench/package-resources.ts index 4366c134..dbb43b34 100644 --- a/src/workbench/package-resources.ts +++ b/src/workbench/package-resources.ts @@ -104,6 +104,18 @@ function packageLabel(source: string): string { .replace(/@latest$/, ""); } +function packageSourceIdentity(source: string): string { + return source.startsWith("npm:") ? `npm:${packageNameFromSource(source)}` : source; +} + +const CORE_PACKAGE_IDENTITIES = new Set( + (CORE_PACKAGE_SOURCES as readonly string[]).map(packageSourceIdentity), +); + +function isCorePackageSource(source: string): boolean { + return CORE_PACKAGE_IDENTITIES.has(packageSourceIdentity(source)); +} + function installedPackageRoot(workingDir: string, source: string): string | undefined { if (!source.startsWith("npm:")) return undefined; const packageName = packageNameFromSource(source); @@ -158,7 +170,7 @@ function packageResourceCounts(summary: PackageManifestSummary | undefined): str function packageKindTags(source: string, optionalPresetName: string | undefined): string[] { const tags = ["package"]; - if ((CORE_PACKAGE_SOURCES as readonly string[]).includes(source)) tags.push("core"); + if (isCorePackageSource(source)) tags.push("core"); if (optionalPresetName) tags.push("optional", optionalPresetName); if (source.includes("web")) tags.push("web"); if (source.includes("doc")) tags.push("documents"); @@ -204,28 +216,29 @@ export function buildConnectorResources(workingDir: string): WorkbenchResource[] const configuredEntries = Array.isArray(settings?.packages) ? settings.packages.map(packageSettingsEntry).filter((entry): entry is PackageSettingsEntry => Boolean(entry)) : []; - const configuredSources = new Set(configuredEntries.map((entry) => entry.source)); + const configuredSources = new Set(configuredEntries.map((entry) => packageSourceIdentity(entry.source))); const optionalPresets = listOptionalPackagePresets(); - const optionalBySource = new Map(optionalPresets.flatMap((preset) => preset.sources.map((source) => [source, preset.name] as const))); + const optionalBySource = new Map(optionalPresets.flatMap((preset) => preset.sources.map((source) => [packageSourceIdentity(source), preset.name] as const))); const packageEntries = [ ...configuredEntries, - ...filterPackageSourcesForCurrentNode(CORE_PACKAGE_SOURCES).filter((source) => !configuredSources.has(source)).map((source) => ({ + ...filterPackageSourcesForCurrentNode(CORE_PACKAGE_SOURCES).filter((source) => !configuredSources.has(packageSourceIdentity(source))).map((source) => ({ source, filters: [], })), ...optionalPresets.flatMap((preset) => preset.sources - .filter((source) => !configuredSources.has(source)) + .filter((source) => !configuredSources.has(packageSourceIdentity(source))) .map((source) => ({ source, filters: [] }))), ]; const seenPackageSources = new Set(); const packages = packageEntries.flatMap((entry) => { - if (seenPackageSources.has(entry.source)) return []; - seenPackageSources.add(entry.source); + const sourceIdentity = packageSourceIdentity(entry.source); + if (seenPackageSources.has(sourceIdentity)) return []; + seenPackageSources.add(sourceIdentity); const manifest = readPackageManifest(workingDir, entry.source); const resourceCounts = packageResourceCounts(manifest); - const optionalPreset = optionalBySource.get(entry.source); - const configured = configuredSources.has(entry.source); - const core = (CORE_PACKAGE_SOURCES as readonly string[]).includes(entry.source); + const optionalPreset = optionalBySource.get(sourceIdentity); + const configured = configuredSources.has(sourceIdentity); + const core = isCorePackageSource(entry.source); const installed = Boolean(manifest); const details = [ entry.source, diff --git a/src/workbench/scan.ts b/src/workbench/scan.ts index a57ffd8f..490da712 100644 --- a/src/workbench/scan.ts +++ b/src/workbench/scan.ts @@ -81,11 +81,12 @@ const PLAN_STEP_STATUSES = new Set([ "running", ]); -type BuildWorkbenchStateOptions = { +export type BuildWorkbenchStateOptions = { workingDir: string; version?: string; settingsPath?: string; authPath?: string; + modelStatus?: ModelStatusSnapshot; maxArtifacts?: number; maxRuns?: number; }; @@ -111,11 +112,11 @@ function readCurrentModelSpec(settingsPath: string | undefined): string | undefi return undefined; } -function buildWorkbenchModelStatus(options: BuildWorkbenchStateOptions): ModelStatusSnapshot | undefined { +export async function loadWorkbenchModelStatus(options: Pick): Promise { if (!options.authPath) return undefined; return buildModelStatusSnapshotFromRecords( - getSupportedModelRecords(options.authPath), - getAvailableModelRecords(options.authPath), + await getSupportedModelRecords(options.authPath), + await getAvailableModelRecords(options.authPath), readCurrentModelSpec(options.settingsPath), ); } @@ -1099,7 +1100,7 @@ export function buildWorkbenchState(options: BuildWorkbenchStateOptions): Workbe workspaceName: basename(workingDir), ...(options.version ? { version: options.version } : {}), generatedAt: new Date().toISOString(), - ...(options.authPath ? { modelStatus: buildWorkbenchModelStatus(options) } : {}), + ...(options.modelStatus ? { modelStatus: options.modelStatus } : {}), summary: buildWorkbenchSummary(artifacts, projects.length, runs.length, memory.notes.length, claims.length, sessionActivity, transcriptAnnotations.length), onboarding: readWorkbenchOnboardingProfile(workingDir), projects, diff --git a/src/workbench/server.ts b/src/workbench/server.ts index a75bd440..f5a03e5b 100644 --- a/src/workbench/server.ts +++ b/src/workbench/server.ts @@ -36,7 +36,7 @@ import { createWorkbenchProject } from "./projects.js"; import { upsertWorkbenchFrameReadCursor } from "./read-cursors.js"; import { requestWorkbenchReview } from "./review.js"; import { readWorkbenchPdfText } from "./pdf-text.js"; -import { buildWorkbenchState, readWorkbenchFile, readWorkbenchFileDownload } from "./scan.js"; +import { buildWorkbenchState, loadWorkbenchModelStatus, readWorkbenchFile, readWorkbenchFileDownload, type BuildWorkbenchStateOptions } from "./scan.js"; import { ensureOpenScienceSeedFixtures } from "./seed-fixtures.js"; import { readWorkbenchSettings, removeWorkbenchSettingsRecord, upsertWorkbenchSettingsRecord, type WorkbenchSettingsCollection, type WorkbenchCustomConnector } from "./settings-store.js"; import { diffArtifactVersionSnapshot, restoreArtifactVersionSnapshot } from "./artifact-snapshot-actions.js"; @@ -312,11 +312,11 @@ function contentDispositionFilename(name: string): string { return name.replace(/["\r\n\\]/g, "_"); } -function stateOptions(options: { authPath?: string; settingsPath?: string; version?: string; workingDir: string }) { - return { workingDir: options.workingDir, ...(options.version ? { version: options.version } : {}), ...(options.settingsPath ? { settingsPath: options.settingsPath } : {}), ...(options.authPath ? { authPath: options.authPath } : {}) }; +function stateOptions(options: BuildWorkbenchStateOptions) { + return { workingDir: options.workingDir, ...(options.version ? { version: options.version } : {}), ...(options.settingsPath ? { settingsPath: options.settingsPath } : {}), ...(options.authPath ? { authPath: options.authPath } : {}), ...(options.modelStatus ? { modelStatus: options.modelStatus } : {}) }; } -function buildServedWorkbenchState(options: { authPath?: string; settingsPath?: string; version?: string; workingDir: string }) { +function buildServedWorkbenchState(options: BuildWorkbenchStateOptions) { const state = buildWorkbenchState(stateOptions(options)); materializeWorkbenchOrgDatabase(state); return state; @@ -333,7 +333,7 @@ function findArtifactVersion(options: WorkbenchRequestHandlerOptions, body: Reco return version; } -type WorkbenchRequestHandlerOptions = Required> & { +type WorkbenchRequestHandlerOptions = Required> & BuildWorkbenchStateOptions & { appRoot?: string; settingsPath?: string; authPath?: string; @@ -414,7 +414,7 @@ async function handleWorkbenchRequest( if (sendWorkbenchWeb(response, options, url, headers)) { return; } - + options = { ...options, modelStatus: await loadWorkbenchModelStatus(options) }; if (url.pathname === "/api/state") { sendJson(response, 200, buildServedWorkbenchState(options), headers); return; diff --git a/tests/alpha-auth-status.test.ts b/tests/alpha-auth-status.test.ts new file mode 100644 index 00000000..00213b0e --- /dev/null +++ b/tests/alpha-auth-status.test.ts @@ -0,0 +1,73 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { + ALPHAXIV_USERINFO_ENDPOINT, + verifyAlphaAuthStatus, +} from "../src/alpha-auth-status.js"; + +test("alpha auth status rejects missing and expired credentials", async () => { + let fetchCalls = 0; + const missing = await verifyAlphaAuthStatus({ + getValidToken: async () => null, + fetchImpl: async () => { + fetchCalls += 1; + return new Response(); + }, + }); + assert.deepEqual(missing, { authenticated: false }); + assert.equal(fetchCalls, 0); + + const expired = await verifyAlphaAuthStatus({ + getValidToken: async () => "expired-token", + fetchImpl: async (input, init) => { + fetchCalls += 1; + assert.equal(String(input), ALPHAXIV_USERINFO_ENDPOINT); + assert.equal((init?.headers as Record).Authorization, "Bearer expired-token"); + return new Response('{"error":"invalid_token"}', { status: 400 }); + }, + }); + assert.deepEqual(expired, { authenticated: false }); + assert.equal(fetchCalls, 1); +}); + +test("alpha auth status requires a live user subject", async () => { + const authenticated = await verifyAlphaAuthStatus({ + getValidToken: async () => "current-token", + fetchImpl: async () => new Response(JSON.stringify({ + sub: "user-1", + name: "Researcher", + }), { + status: 200, + headers: { "content-type": "application/json" }, + }), + }); + assert.deepEqual(authenticated, { + authenticated: true, + name: "Researcher", + }); + + await assert.rejects( + verifyAlphaAuthStatus({ + getValidToken: async () => "current-token", + fetchImpl: async () => new Response("{}", { + status: 200, + headers: { "content-type": "application/json" }, + }), + }), + /no user subject/, + ); +}); + +test("alpha auth status surfaces provider failures", async () => { + await assert.rejects( + verifyAlphaAuthStatus({ + getValidToken: async () => "current-token", + fetchImpl: async () => new Response("unavailable", { + status: 503, + statusText: "Service Unavailable", + }), + }), + /503 Service Unavailable/, + ); +}); diff --git a/tests/alpha-hub-auth-patch.test.ts b/tests/alpha-hub-auth-patch.test.ts index 2e90bd39..93884b8e 100644 --- a/tests/alpha-hub-auth-patch.test.ts +++ b/tests/alpha-hub-auth-patch.test.ts @@ -3,6 +3,29 @@ import assert from "node:assert/strict"; import { patchAlphaHubAuthSource } from "../scripts/lib/alpha-hub-auth-patch.mjs"; +const LEGACY_ENDPOINTS = [ + "const CLERK_ISSUER = 'https://clerk.alphaxiv.org';", + "const AUTH_ENDPOINT = `${CLERK_ISSUER}/oauth/authorize`;", + "const TOKEN_ENDPOINT = `${CLERK_ISSUER}/oauth/token`;", + "const REGISTER_ENDPOINT = `${CLERK_ISSUER}/oauth/register`;", + "const CALLBACK_PORT = 9876;", + "const REDIRECT_URI = `http://127.0.0.1:${CALLBACK_PORT}/callback`;", + "const USERINFO_ENDPOINT = `${CLERK_ISSUER}/oauth/userinfo`;", + "const SCOPES = 'profile email offline_access';", +].join("\n"); + +test("patchAlphaHubAuthSource uses alphaXiv's current OAuth endpoints", () => { + const patched = patchAlphaHubAuthSource(LEGACY_ENDPOINTS); + + assert.match(patched, /https:\/\/api\.alphaxiv\.org\/auth/); + assert.match(patched, /oauth2\/authorize/); + assert.match(patched, /oauth2\/token/); + assert.match(patched, /oauth2\/register/); + assert.match(patched, /oauth2\/userinfo/); + assert.match(patched, /openid profile email offline_access/); + assert.doesNotMatch(patched, /clerk\.alphaxiv\.org/); +}); + test("patchAlphaHubAuthSource fixes browser open logic for WSL and Windows", () => { const input = [ "function openBrowser(url) {", @@ -31,6 +54,27 @@ test("patchAlphaHubAuthSource includes the auth URL in login output", () => { assert.match(patched, /Auth URL: \$\{authUrl\.toString\(\)\}/); }); +test("patchAlphaHubAuthSource validates OAuth state on the loopback callback", () => { + const input = [ + "function waitForCallback(server) {", + " const code = url.searchParams.get('code');", + " const error = url.searchParams.get('error');", + "", + " if (error) {", + " const code = await waitForCallback(server);", + ].join("\n"); + + const patched = patchAlphaHubAuthSource(input); + + assert.match(patched, /function waitForCallback\(server, expectedState\)/); + assert.match(patched, /const returnedState = url\.searchParams\.get\('state'\)/); + assert.match(patched, /returnedState !== expectedState/); + assert.match(patched, /OAuth state mismatch/); + assert.match(patched, /waitForCallback\(server, state\)/); + assert.doesNotMatch(patched, /waitForCallback\(server\);/); + assert.equal(patchAlphaHubAuthSource(patched), patched); +}); + test("patchAlphaHubAuthSource is idempotent", () => { const input = [ "function openBrowser(url) {", diff --git a/tests/archive-reproducibility.test.ts b/tests/archive-reproducibility.test.ts new file mode 100644 index 00000000..a0f8dcc4 --- /dev/null +++ b/tests/archive-reproducibility.test.ts @@ -0,0 +1,60 @@ +import assert from "node:assert/strict"; +import { appendFileSync, mkdirSync, mkdtempSync, utimesSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import test from "node:test"; + +import { + createDeterministicTarGz, + createDeterministicZip, +} from "../scripts/lib/deterministic-archive.mjs"; +import { computeFileSha256 } from "../scripts/lib/runtime-workspace-integrity.mjs"; + +function fixture() { + const root = mkdtempSync(join(tmpdir(), "feynman-archive-repro-")); + const tree = join(root, "bundle"); + mkdirSync(join(tree, "nested"), { recursive: true }); + writeFileSync(join(tree, "README.md"), "same bytes\n"); + writeFileSync(join(tree, "nested", "data.json"), '{"same":true}\n'); + return { root, tree }; +} + +function perturbTimestamps(tree: string) { + const now = new Date(); + utimesSync(tree, now, now); + utimesSync(join(tree, "README.md"), now, now); + utimesSync(join(tree, "nested"), now, now); + utimesSync(join(tree, "nested", "data.json"), now, now); +} + +test("deterministic tar.gz output ignores source mtimes and repeated builds", async () => { + const { root, tree } = fixture(); + const first = join(root, "first.tar.gz"); + const second = join(root, "second.tar.gz"); + await createDeterministicTarGz(tree, first); + perturbTimestamps(tree); + await createDeterministicTarGz(tree, second); + assert.equal(computeFileSha256(first), computeFileSha256(second)); +}); + +test("deterministic ZIP output ignores source mtimes and repeated builds", { + skip: process.platform === "win32", +}, () => { + const { root, tree } = fixture(); + const first = join(root, "first.zip"); + const second = join(root, "second.zip"); + createDeterministicZip(tree, first); + perturbTimestamps(tree); + createDeterministicZip(tree, second); + assert.equal(computeFileSha256(first), computeFileSha256(second)); +}); + +test("archive inputs remain content-sensitive", async () => { + const { root, tree } = fixture(); + const first = join(root, "first.tar.gz"); + const second = join(root, "second.tar.gz"); + await createDeterministicTarGz(tree, first); + appendFileSync(join(tree, "README.md"), "changed\n"); + await createDeterministicTarGz(tree, second); + assert.notEqual(computeFileSha256(first), computeFileSha256(second)); +}); diff --git a/tests/bootstrap-sync.test.ts b/tests/bootstrap-sync.test.ts index 132c90df..8e5003a1 100644 --- a/tests/bootstrap-sync.test.ts +++ b/tests/bootstrap-sync.test.ts @@ -80,3 +80,35 @@ test("syncBundledAssets removes deleted managed files but preserves user-modifie assert.deepEqual(secondResult.skipped, ["legacy/SKILL.md"]); assert.equal(readFileSync(join(agentDir, "skills", "legacy", "SKILL.md"), "utf8"), "# user legacy override\n"); }); + +test("syncBundledAssets installs Feynman's Option+Enter newline binding without overriding user config", async () => { + const appRoot = createAppRoot(); + const home = mkdtempSync(join(tmpdir(), "feynman-home-")); + process.env.FEYNMAN_HOME = home; + const agentDir = join(home, "agent"); + const bundledConfigDir = join(appRoot, ".feynman", "config"); + mkdirSync(bundledConfigDir, { recursive: true }); + writeFileSync(join(bundledConfigDir, "keybindings.json"), JSON.stringify({ + "tui.input.newLine": ["ctrl+j", "alt+enter"], + "app.message.followUp": ["shift+enter"], + }, null, 2) + "\n"); + + const result = syncBundledAssets(appRoot, agentDir); + const keybindingsPath = join(agentDir, "keybindings.json"); + const { KeybindingsManager } = await import("../node_modules/@earendil-works/pi-coding-agent/dist/core/keybindings.js"); + const keybindings = KeybindingsManager.create(agentDir); + + assert.ok(result.copied.includes("keybindings.json")); + assert.deepEqual(keybindings.getKeys("tui.input.newLine"), ["ctrl+j", "alt+enter"]); + assert.deepEqual(keybindings.getKeys("app.message.followUp"), ["shift+enter"]); + assert.equal(keybindings.matches("\u001b\r", "tui.input.newLine"), true); + assert.equal(keybindings.matches("\u001b[13;3u", "tui.input.newLine"), true); + assert.equal(keybindings.matches("\u001b\r", "app.message.followUp"), false); + assert.equal(keybindings.matches("\u001b[13;2u", "app.message.followUp"), true); + + writeFileSync(keybindingsPath, '{"tui.input.newLine":["ctrl+j"]}\n'); + writeFileSync(join(bundledConfigDir, "keybindings.json"), '{"tui.input.newLine":["alt+enter"]}\n'); + const updateResult = syncBundledAssets(appRoot, agentDir); + assert.ok(updateResult.skipped.includes("keybindings.json")); + assert.equal(readFileSync(keybindingsPath, "utf8"), '{"tui.input.newLine":["ctrl+j"]}\n'); +}); diff --git a/tests/config-paths.test.ts b/tests/config-paths.test.ts index a2e3ef83..6217d458 100644 --- a/tests/config-paths.test.ts +++ b/tests/config-paths.test.ts @@ -1,6 +1,6 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; @@ -148,3 +148,24 @@ test("ensureFeynmanActiveOrg preserves a reference-shaped existing active org", rmSync(root, { recursive: true, force: true }); } }); + +test("ensureFeynmanActiveOrg does not rewrite a valid manifest", () => { + const root = mkdtempSync(join(tmpdir(), "feynman-paths-")); + try { + const home = join(root, "home"); + const activeOrg = ensureFeynmanActiveOrg(home); + const path = getFeynmanActiveOrgPath(home); + const before = statSync(path, { bigint: true }); + + for (let index = 0; index < 20; index += 1) { + assert.equal(ensureFeynmanActiveOrg(home).org_uuid, activeOrg.org_uuid); + } + + const after = statSync(path, { bigint: true }); + assert.equal(after.mtimeNs, before.mtimeNs); + assert.equal(after.ino, before.ino); + assert.deepEqual(JSON.parse(readFileSync(path, "utf8")), activeOrg); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); diff --git a/tests/install-native.test.ts b/tests/install-native.test.ts new file mode 100644 index 00000000..58f5698c --- /dev/null +++ b/tests/install-native.test.ts @@ -0,0 +1,106 @@ +import assert from "node:assert/strict"; +import { createHash } from "node:crypto"; +import { + appendFileSync, + chmodSync, + existsSync, + mkdirSync, + mkdtempSync, + readFileSync, + writeFileSync, +} from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { pathToFileURL } from "node:url"; +import { spawnSync } from "node:child_process"; +import test from "node:test"; + +const appRoot = process.cwd(); + +function sha256(path: string): string { + return createHash("sha256").update(readFileSync(path)).digest("hex"); +} + +test("native installer verifies checksums and preserves a working install on failure", { + skip: process.platform === "win32", +}, () => { + const root = mkdtempSync(join(tmpdir(), "feynman-native-installer-")); + const releaseRoot = join(root, "release"); + const installRoot = join(root, "install"); + const binRoot = join(root, "bin"); + const home = join(root, "home"); + const version = "9.8.7"; + const platform = process.platform === "darwin" ? "darwin" : "linux"; + const architecture = process.arch === "arm64" ? "arm64" : "x64"; + const bundleName = `feynman-${version}-${platform}-${architecture}`; + const bundleRoot = join(root, bundleName); + const archiveName = `${bundleName}.tar.gz`; + const archivePath = join(releaseRoot, archiveName); + const installedBundle = join(installRoot, bundleName); + + mkdirSync(bundleRoot, { recursive: true }); + mkdirSync(releaseRoot, { recursive: true }); + mkdirSync(home, { recursive: true }); + const launcher = join(bundleRoot, "feynman"); + writeFileSync(launcher, `#!/bin/sh +case "\${1:-}" in + --version) printf '%s\\n' "${version}" ;; + --help) printf '%s\\n' "Feynman test help" ;; + *) printf '%s\\n' "Feynman test" ;; +esac +`); + chmodSync(launcher, 0o755); + assert.equal(spawnSync("tar", ["-czf", archivePath, "-C", root, bundleName]).status, 0); + writeFileSync(join(releaseRoot, "SHA256SUMS"), `${sha256(archivePath)} ${archiveName}\n`); + + const env = { + ...process.env, + HOME: home, + FEYNMAN_INSTALL_APP_DIR: installRoot, + FEYNMAN_INSTALL_BIN_DIR: binRoot, + FEYNMAN_INSTALL_BASE_URL: pathToFileURL(releaseRoot).href.replace(/\/$/, ""), + FEYNMAN_INSTALL_SKIP_PATH_UPDATE: "1", + }; + const install = () => spawnSync( + "sh", + [join(appRoot, "scripts", "install", "install.sh"), version], + { cwd: appRoot, env, encoding: "utf8" }, + ); + + const first = install(); + assert.equal(first.status, 0, first.stderr); + assert.equal(existsSync(join(binRoot, "feynman")), true); + assert.equal(existsSync(installedBundle), true); + + const replacementSentinel = join(installedBundle, "replace-me.sentinel"); + writeFileSync(replacementSentinel, "remove me\n"); + const obsoleteBundle = join(installRoot, "feynman-1.0.0-old"); + mkdirSync(obsoleteBundle, { recursive: true }); + const replacement = install(); + assert.equal(replacement.status, 0, replacement.stderr); + assert.equal(existsSync(replacementSentinel), false); + assert.equal(existsSync(obsoleteBundle), false); + + const duplicateSentinel = join(installedBundle, "duplicate-checksum-must-preserve.sentinel"); + writeFileSync(duplicateSentinel, "keep me\n"); + const validChecksum = sha256(archivePath); + for (const checksumLines of [ + `${validChecksum} ${archiveName}\n${"0".repeat(64)} ${archiveName}\n`, + `${"0".repeat(64)} ${archiveName}\n${validChecksum} ${archiveName}\n`, + ]) { + writeFileSync(join(releaseRoot, "SHA256SUMS"), checksumLines); + const duplicateRejected = install(); + assert.notEqual(duplicateRejected.status, 0); + assert.match(duplicateRejected.stderr, /multiple checksum entries/); + assert.equal(existsSync(duplicateSentinel), true); + } + + const preservedSentinel = join(installedBundle, "preserve-me.sentinel"); + writeFileSync(preservedSentinel, "keep me\n"); + writeFileSync(join(releaseRoot, "SHA256SUMS"), `${validChecksum} ${archiveName}\n`); + appendFileSync(archivePath, "corrupt"); + const rejected = install(); + assert.notEqual(rejected.status, 0); + assert.match(rejected.stderr, /SHA-256 mismatch/); + assert.equal(existsSync(preservedSentinel), true); +}); diff --git a/tests/install-windows.test.ts b/tests/install-windows.test.ts new file mode 100644 index 00000000..a695883f --- /dev/null +++ b/tests/install-windows.test.ts @@ -0,0 +1,72 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const appRoot = resolve(dirname(fileURLToPath(import.meta.url)), ".."); + +test("Windows installer extracts into staging before replacing installed bundle", () => { + const installer = readFileSync(resolve(appRoot, "scripts", "install", "install.ps1"), "utf8"); + + assert.match(installer, /\$extractRoot = Join-Path \$tmpDir "extract"/); + assert.match(installer, /\$extractedBundleDir = Join-Path \$extractRoot \$bundleName/); + assert.match(installer, /Add-Type -AssemblyName System\.IO\.Compression\.FileSystem/); + assert.match( + installer, + /\[System\.IO\.Compression\.ZipFile\]::ExtractToDirectory\(\$archivePath, \$extractRoot\)/, + ); + assert.match(installer, /Downloaded archive did not contain the expected \$bundleName directory/); + assert.match(installer, /Get-FileHash -LiteralPath \$archivePath -Algorithm SHA256/); + assert.match(installer, /SHA-256 mismatch/); + assert.match(installer, /SHA256SUMS contains multiple checksum entries/); + assert.equal((installer.match(/Invoke-WebRequest/g) ?? []).length, 3); + assert.equal((installer.match(/-UseBasicParsing/g) ?? []).length, 3); + assert.match(installer, /\$backupBundleDir = Join-Path \$tmpDir "previous-bundle"/); + assert.match(installer, /\$backupBinDir = Join-Path \$tmpDir "previous-bin"/); + assert.match(installer, /FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_BACKUP/); + assert.match(installer, /Move-Item -LiteralPath \$installBinDir -Destination \$backupBinDir/); + assert.match(installer, /Move-Item -LiteralPath \$stagedBinDir -Destination \$installBinDir/); + assert.match(installer, /FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_SWAP/); + assert.match(installer, /Move-Item -LiteralPath \$extractedBundleDir -Destination \$bundleDir/); + assert.match(installer, /\$candidatePs1 = Join-Path \$extractedBundleDir "feynman\.ps1"/); + assert.match( + installer, + /& \$powerShellExecutable -NoProfile -ExecutionPolicy Bypass -File \$candidatePs1 --version/, + ); + assert.doesNotMatch(installer, /@\(& \$candidate --version 2>&1\)/); + assert.match(installer, /"ARM64" \{ return "x64" \}/); + assert.match(installer, /"Arm64" \{ return "x64" \}/); + assert.doesNotMatch(installer, /\$shimPs1Candidate/); + assert.doesNotMatch(installer, /Join-Path \$stagedBinDir "feynman\.ps1"/); + assert.match(installer, /Install only the CMD shim on PATH/); + assert.doesNotMatch(installer, /\$resolvedCommand\.Source -ne \$shimPath/); + assert.doesNotMatch(installer, /Move-Item -LiteralPath \$shimCandidate -Destination \$shimPath/); + assert.doesNotMatch(installer, /Expand-Archive/); +}); + +test("website Windows installer stays synced with the packaged installer", () => { + const installer = readFileSync(resolve(appRoot, "scripts", "install", "install.ps1"), "utf8"); + const websiteInstaller = readFileSync(resolve(appRoot, "website", "public", "install.ps1"), "utf8"); + + assert.equal(websiteInstaller, installer); +}); + +test("Windows installer verifier defines every strict-mode install path", () => { + const verifier = readFileSync(resolve(appRoot, "scripts", "verify-windows-installer.ps1"), "utf8"); + + assert.match(verifier, /Set-StrictMode -Version 2\.0/); + assert.match(verifier, /\$installBinDir = Join-Path \$installRoot "bin"/); + assert.match(verifier, /\$env:PATH = "\$installBinDir;\$env:PATH"/); + assert.match(verifier, /-ExecutionPolicy Restricted/); + assert.match(verifier, /PATH bin must not contain a policy-blocked feynman\.ps1 shim/); + assert.match(verifier, /\$servedArchive = Join-Path \$testRoot \$archiveName/); + assert.match(verifier, /Exact-candidate replacement retained the old bundle/); + assert.match(verifier, /\$fixtureRoot = Join-Path \$testRoot "compact-fixture"/); + assert.match( + verifier, + /\[System\.IO\.Compression\.ZipFile\]::CreateFromDirectory\(\$fixtureRoot, \$fixtureArchive\)/, + ); + assert.match(verifier, /Copy-Item -LiteralPath \$fixtureArchive -Destination \$servedArchive -Force/); + assert.doesNotMatch(verifier, /for \(\$pass = 1; \$pass -le 2;/); +}); diff --git a/tests/mcp-sdk-package-patch.test.ts b/tests/mcp-sdk-package-patch.test.ts new file mode 100644 index 00000000..b34b9596 --- /dev/null +++ b/tests/mcp-sdk-package-patch.test.ts @@ -0,0 +1,67 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; +import test from "node:test"; + +import { patchMcpSdkPackageJsonSource } from "../scripts/lib/mcp-sdk-package-patch.mjs"; + +test("MCP SDK package patch carries the safe Hono node server into bundled consumers", () => { + for (const [version, range] of [ + ["1.29.0", "^1.19.9"], + ["1.30.0", "^1.19.9 || ^2.0.5"], + ]) { + const source = JSON.stringify({ + name: "@modelcontextprotocol/sdk", + version, + dependencies: { + "@hono/node-server": range, + }, + }); + + const patched = JSON.parse(patchMcpSdkPackageJsonSource(source)) as { + dependencies: Record; + }; + assert.equal(patched.dependencies["@hono/node-server"], "2.0.12"); + } +}); + +test("MCP SDK package patch is idempotent and replaces unsafe lower 2.x ranges", () => { + const safe = JSON.stringify({ + dependencies: { + "@hono/node-server": "2.0.12", + }, + }); + assert.equal(patchMcpSdkPackageJsonSource(safe), safe); + for (const unsafe of ["2.0.0", "^2.0.0", "~2.0.4"]) { + const patched = JSON.parse(patchMcpSdkPackageJsonSource(JSON.stringify({ + dependencies: { "@hono/node-server": unsafe }, + }))) as { dependencies: Record }; + assert.equal(patched.dependencies["@hono/node-server"], "2.0.12"); + } +}); + +test("MCP SDK package patch fails closed on incompatible manifests", () => { + assert.throws( + () => patchMcpSdkPackageJsonSource(JSON.stringify({ dependencies: {} })), + /no @hono\/node-server dependency/, + ); + for (const unsupported of ["^1.20.0", "^2.1.0", "3.0.0", "workspace:*"]) { + assert.throws( + () => patchMcpSdkPackageJsonSource(JSON.stringify({ + dependencies: { "@hono/node-server": unsupported }, + })), + /Unsupported .* @hono\/node-server dependency/, + ); + } +}); + +test("embedded runtime patch wires the MCP manifest repair into installed package graphs", () => { + const source = readFileSync(resolve("scripts", "patch-embedded-pi.mjs"), "utf8"); + assert.match( + source, + /import \{ patchMcpSdkPackageJsonSource \} from "\.\/lib\/mcp-sdk-package-patch\.mjs";/, + ); + assert.match(source, /function patchMcpSdkManifest\(nodeModulesRoot\)/); + assert.match(source, /resolve\(appRoot, "node_modules"\)/); + assert.match(source, /patchMcpSdkManifest\(nodeModulesRoot\)/); +}); diff --git a/tests/model-harness.test.ts b/tests/model-harness.test.ts index eb2b575a..784840d7 100644 --- a/tests/model-harness.test.ts +++ b/tests/model-harness.test.ts @@ -3,7 +3,7 @@ import assert from "node:assert/strict"; import { spawnSync } from "node:child_process"; import { mkdtempSync, readFileSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; -import { join } from "node:path"; +import { dirname, join } from "node:path"; import { appendWorkflowFlagPositionals, @@ -19,7 +19,9 @@ import { } from "../src/cli.js"; import { buildModelStatusSnapshotFromRecords, chooseRecommendedModel, getAvailableModelRecords } from "../src/model/catalog.js"; import { isLocalModelProvider, resolveModelProviderForCommand, setDefaultModelSpec } from "../src/model/commands.js"; +import { createModelRegistry } from "../src/model/registry.js"; import { supportsNativePackageSources } from "../src/pi/package-presets.js"; +import { canonicalizeModelSpec, parseModelSpec } from "../src/pi/settings.js"; function createAuthPath(contents: Record): string { const root = mkdtempSync(join(tmpdir(), "feynman-auth-")); @@ -40,13 +42,13 @@ const MODEL_ENV_KEYS = [ "KIMI_API_KEY", ]; -function withoutModelEnv(callback: () => T): T { +async function withoutModelEnv(callback: () => T | Promise): Promise { const savedEnv = Object.fromEntries(MODEL_ENV_KEYS.map((key) => [key, process.env[key]])); for (const key of MODEL_ENV_KEYS) { delete process.env[key]; } try { - return callback(); + return await callback(); } finally { for (const [key, value] of Object.entries(savedEnv)) { if (value === undefined) { @@ -58,8 +60,8 @@ function withoutModelEnv(callback: () => T): T { } } -function getOpenAiGptModel(authPath: string): { provider: string; id: string } { - const recommendation = chooseRecommendedModel(authPath); +async function getOpenAiGptModel(authPath: string): Promise<{ provider: string; id: string }> { + const recommendation = await chooseRecommendedModel(authPath); assert.ok(recommendation); const [provider, ...idParts] = recommendation.spec.split("/"); const id = idParts.join("/"); @@ -72,38 +74,67 @@ function asModelSpec(model: { provider: string; id: string }): string { return `${model.provider}/${model.id}`; } -test("chooseRecommendedModel prefers the strongest authenticated research model", () => { +test("chooseRecommendedModel prefers the strongest authenticated research model", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, anthropic: { type: "api_key", key: "anthropic-test-key" }, }); - const recommendation = chooseRecommendedModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); - assert.equal(recommendation?.spec, "anthropic/claude-opus-4-8"); + assert.equal(recommendation?.spec, "anthropic/claude-opus-5"); }); -test("chooseRecommendedModel prefers the newest OpenAI GPT exposed by Pi", () => { +test("chooseRecommendedModel prefers the newest OpenAI GPT exposed by Pi", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, }); - const recommendation = chooseRecommendedModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); assert.match(recommendation?.spec ?? "", /^openai\/gpt-\d/); assert.match(recommendation?.reason ?? "", /newest authenticated OpenAI GPT model/); }); -test("resolveRankSynthesisModelSpec uses the recommended research model instead of a stale default", () => { +test("resolveRankSynthesisModelSpec uses the recommended research model instead of a stale default", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, }); - const recommendation = chooseRecommendedModel(authPath); - const explicitOpenAiModel = getOpenAiGptModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); + const explicitOpenAiModel = await getOpenAiGptModel(authPath); const explicitOpenAiSpec = asModelSpec(explicitOpenAiModel); - assert.equal(resolveRankSynthesisModelSpec(authPath, undefined), recommendation?.spec); - assert.equal(resolveRankSynthesisModelSpec(authPath, explicitOpenAiSpec), explicitOpenAiSpec); + assert.equal(await resolveRankSynthesisModelSpec(authPath, undefined), recommendation?.spec); + assert.equal(await resolveRankSynthesisModelSpec(authPath, explicitOpenAiSpec), explicitOpenAiSpec); +}); + +test("model specs preserve colon-bearing custom model ids and canonicalize Pi launch syntax", async () => { + const authPath = createAuthPath({ + ollama: { type: "api_key", key: "ollama" }, + }); + const modelsPath = join(dirname(authPath), "models.json"); + writeFileSync( + modelsPath, + JSON.stringify({ + providers: { + ollama: { + baseUrl: "http://localhost:11434/v1", + api: "openai-completions", + apiKey: "ollama", + models: [{ id: "qwen3:0.6b" }], + }, + }, + }) + "\n", + "utf8", + ); + const registry = await createModelRegistry(authPath); + + for (const spec of ["ollama/qwen3:0.6b", "ollama:qwen3:0.6b"]) { + const model = parseModelSpec(spec, registry); + assert.equal(model?.provider, "ollama"); + assert.equal(model?.id, "qwen3:0.6b"); + assert.equal(canonicalizeModelSpec(spec, registry), "ollama/qwen3:0.6b"); + } }); test("parsePositiveInteger rejects partial numeric strings", () => { @@ -151,6 +182,25 @@ test("feynman alpha reaches Alpha Hub help when cwd is supplied before alpha", ( assert.doesNotMatch(result.stdout, /Research-first agent shell built on Pi/); }); +test("unknown CLI flags point users to Feynman help", () => { + const workingDir = mkdtempSync(join(tmpdir(), "feynman-unknown-option-cwd-")); + const homeDir = mkdtempSync(join(tmpdir(), "feynman-unknown-option-home-")); + const result = spawnSync(process.execPath, ["--import", "tsx", "src/index.ts", "--cwd", workingDir, "update", "--extensions"], { + cwd: process.cwd(), + encoding: "utf8", + env: { + ...process.env, + FEYNMAN_HOME: homeDir, + FEYNMAN_TELEMETRY: "0", + }, + maxBuffer: 1024 * 1024, + }); + + assert.equal(result.status, 1); + assert.match(`${result.stdout}\n${result.stderr}`, /Unknown option '--extensions'/); + assert.match(`${result.stdout}\n${result.stderr}`, /Run `feynman help` to see available commands and flags/); +}); + test("packages CLI hides removed UI and bulk extras", () => { const workingDir = mkdtempSync(join(tmpdir(), "feynman-packages-cwd-")); const homeDir = mkdtempSync(join(tmpdir(), "feynman-packages-home-")); @@ -231,31 +281,31 @@ test("PaperRank synthesis CLI line labels explicit models as overrides", () => { ); }); -test("chooseRecommendedModel prefers OpenCode Zen Claude when OpenCode is the authenticated provider", () => { - withoutModelEnv(() => { +test("chooseRecommendedModel prefers OpenCode Zen Claude when OpenCode is the authenticated provider", async () => { + await withoutModelEnv(async () => { const authPath = createAuthPath({ opencode: { type: "api_key", key: "opencode-test-key" }, }); - const recommendation = chooseRecommendedModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); - assert.equal(recommendation?.spec, "opencode/claude-opus-4-8"); + assert.equal(recommendation?.spec, "opencode/claude-opus-5"); }); }); -test("chooseRecommendedModel prefers OpenCode Go Kimi when OpenCode Go is the authenticated provider", () => { - withoutModelEnv(() => { +test("chooseRecommendedModel prefers OpenCode Go Kimi when OpenCode Go is the authenticated provider", async () => { + await withoutModelEnv(async () => { const authPath = createAuthPath({ "opencode-go": { type: "api_key", key: "opencode-test-key" }, }); - const recommendation = chooseRecommendedModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); assert.equal(recommendation?.spec, "opencode-go/kimi-k2.6"); }); }); -test("getAvailableModelRecords excludes expired OAuth credentials without an env fallback", () => { +test("getAvailableModelRecords excludes expired OAuth credentials without an env fallback", async () => { const authPath = createAuthPath({ anthropic: { type: "oauth", @@ -265,12 +315,12 @@ test("getAvailableModelRecords excludes expired OAuth credentials without an env }, }); - const available = getAvailableModelRecords(authPath); + const available = await getAvailableModelRecords(authPath); assert.equal(available.some((model) => model.provider === "anthropic"), false); }); -test("getAvailableModelRecords keeps unexpired OAuth credentials available", () => { +test("getAvailableModelRecords keeps unexpired OAuth credentials available", async () => { const authPath = createAuthPath({ anthropic: { type: "oauth", @@ -280,17 +330,17 @@ test("getAvailableModelRecords keeps unexpired OAuth credentials available", () }, }); - const available = getAvailableModelRecords(authPath); + const available = await getAvailableModelRecords(authPath); assert.equal(available.some((model) => model.provider === "anthropic"), true); }); -test("setDefaultModelSpec accepts a unique bare model id from authenticated models", () => { +test("setDefaultModelSpec accepts a unique bare model id from authenticated models", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, }); const settingsPath = join(mkdtempSync(join(tmpdir(), "feynman-settings-")), "settings.json"); - const openAiModel = getOpenAiGptModel(authPath); + const openAiModel = await getOpenAiGptModel(authPath); const logs: string[] = []; const originalLog = console.log; @@ -298,7 +348,7 @@ test("setDefaultModelSpec accepts a unique bare model id from authenticated mode logs.push([message, ...optionalParams].map(String).join(" ")); }; try { - setDefaultModelSpec(settingsPath, authPath, openAiModel.id); + await setDefaultModelSpec(settingsPath, authPath, openAiModel.id); } finally { console.log = originalLog; } @@ -312,15 +362,15 @@ test("setDefaultModelSpec accepts a unique bare model id from authenticated mode assert.match(logs.join("\n"), /Non-Pro default model set to openai\//); }); -test("setDefaultModelSpec accepts provider:model syntax for authenticated models", () => { +test("setDefaultModelSpec accepts provider:model syntax for authenticated models", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, }); const settingsPath = join(mkdtempSync(join(tmpdir(), "feynman-settings-")), "settings.json"); - const openAiModel = getOpenAiGptModel(authPath); + const openAiModel = await getOpenAiGptModel(authPath); - setDefaultModelSpec(settingsPath, authPath, `openai:${openAiModel.id}`); + await setDefaultModelSpec(settingsPath, authPath, `openai:${openAiModel.id}`); const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { defaultProvider?: string; @@ -330,50 +380,50 @@ test("setDefaultModelSpec accepts provider:model syntax for authenticated models assert.equal(settings.defaultModel, openAiModel.id); }); -test("resolveModelProviderForCommand falls back to API-key providers when OAuth is unavailable", () => { +test("resolveModelProviderForCommand falls back to API-key providers when OAuth is unavailable", async () => { const authPath = createAuthPath({}); - const resolved = resolveModelProviderForCommand(authPath, "google"); + const resolved = await resolveModelProviderForCommand(authPath, "google"); assert.equal(resolved?.kind, "api-key"); assert.equal(resolved?.id, "google"); }); -test("resolveModelProviderForCommand supports LM Studio as a first-class local provider", () => { +test("resolveModelProviderForCommand supports LM Studio as a first-class local provider", async () => { const authPath = createAuthPath({}); - const resolved = resolveModelProviderForCommand(authPath, "lm-studio"); + const resolved = await resolveModelProviderForCommand(authPath, "lm-studio"); assert.equal(resolved?.kind, "api-key"); assert.equal(resolved?.id, "lm-studio"); }); -test("resolveModelProviderForCommand supports LiteLLM as a first-class proxy provider", () => { +test("resolveModelProviderForCommand supports LiteLLM as a first-class proxy provider", async () => { const authPath = createAuthPath({}); - const resolved = resolveModelProviderForCommand(authPath, "litellm"); + const resolved = await resolveModelProviderForCommand(authPath, "litellm"); assert.equal(resolved?.kind, "api-key"); assert.equal(resolved?.id, "litellm"); }); -test("resolveModelProviderForCommand prefers OAuth when a provider supports both auth modes", () => { +test("resolveModelProviderForCommand prefers OAuth when a provider supports both auth modes", async () => { const authPath = createAuthPath({}); - const resolved = resolveModelProviderForCommand(authPath, "anthropic"); + const resolved = await resolveModelProviderForCommand(authPath, "anthropic"); assert.equal(resolved?.kind, "oauth"); assert.equal(resolved?.id, "anthropic"); }); -test("setDefaultModelSpec prefers the explicitly configured provider when a bare model id is ambiguous", () => { +test("setDefaultModelSpec prefers the explicitly configured provider when a bare model id is ambiguous", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, }); const settingsPath = join(mkdtempSync(join(tmpdir(), "feynman-settings-")), "settings.json"); - const openAiModel = getOpenAiGptModel(authPath); + const openAiModel = await getOpenAiGptModel(authPath); - setDefaultModelSpec(settingsPath, authPath, openAiModel.id); + await setDefaultModelSpec(settingsPath, authPath, openAiModel.id); const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { defaultProvider?: string; @@ -398,25 +448,25 @@ test("buildModelStatusSnapshotFromRecords flags an invalid current model and sug assert.ok(snapshot.guidance.some((line) => line.includes("Configured default model is unavailable"))); }); -test("chooseRecommendedModel prefers the newest MiniMax over highspeed when that is the authenticated provider", () => { - withoutModelEnv(() => { +test("chooseRecommendedModel prefers the newest MiniMax over highspeed when that is the authenticated provider", async () => { + await withoutModelEnv(async () => { const authPath = createAuthPath({ minimax: { type: "api_key", key: "minimax-test-key" }, }); - const recommendation = chooseRecommendedModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); assert.equal(recommendation?.spec, "minimax/MiniMax-M3"); }); }); -test("chooseRecommendedModel prefers kimi-for-coding when Kimi Coding is the authenticated provider", () => { - withoutModelEnv(() => { +test("chooseRecommendedModel prefers kimi-for-coding when Kimi Coding is the authenticated provider", async () => { + await withoutModelEnv(async () => { const authPath = createAuthPath({ "kimi-coding": { type: "api_key", key: "kimi-test-key" }, }); - const recommendation = chooseRecommendedModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); assert.equal(recommendation?.spec, "kimi-coding/kimi-for-coding"); }); @@ -499,37 +549,37 @@ test("resolvePiPromptOptions keeps top-level workflows interactive when stdin is assert.deepEqual(resolvePiPromptOptions(undefined, [], undefined, workflows), {}); }); -test("shouldRunInteractiveSetup triggers on first run when no default model is configured", () => { +test("shouldRunInteractiveSetup triggers on first run when no default model is configured", async () => { const authPath = createAuthPath({}); - assert.equal(shouldRunInteractiveSetup(undefined, undefined, true, authPath), true); + assert.equal(await shouldRunInteractiveSetup(undefined, undefined, true, authPath), true); }); -test("shouldRunInteractiveSetup triggers when the configured default model is unavailable", () => { +test("shouldRunInteractiveSetup triggers when the configured default model is unavailable", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, }); - assert.equal(shouldRunInteractiveSetup(undefined, "anthropic/claude-opus-4-6", true, authPath), true); + assert.equal(await shouldRunInteractiveSetup(undefined, "anthropic/claude-opus-4-6", true, authPath), true); }); -test("shouldRunInteractiveSetup skips onboarding when the configured default model is available", () => { +test("shouldRunInteractiveSetup skips onboarding when the configured default model is available", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, }); - const openAiModel = getOpenAiGptModel(authPath); + const openAiModel = await getOpenAiGptModel(authPath); - assert.equal(shouldRunInteractiveSetup(undefined, asModelSpec(openAiModel), true, authPath), false); + assert.equal(await shouldRunInteractiveSetup(undefined, asModelSpec(openAiModel), true, authPath), false); }); -test("shouldRunInteractiveSetup skips onboarding for explicit model overrides or non-interactive terminals", () => { +test("shouldRunInteractiveSetup skips onboarding for explicit model overrides or non-interactive terminals", async () => { const authPath = createAuthPath({ openai: { type: "api_key", key: "openai-test-key" }, }); - const openAiModel = getOpenAiGptModel(authPath); + const openAiModel = await getOpenAiGptModel(authPath); - assert.equal(shouldRunInteractiveSetup(asModelSpec(openAiModel), undefined, true, authPath), false); - assert.equal(shouldRunInteractiveSetup(undefined, undefined, false, authPath), false); + assert.equal(await shouldRunInteractiveSetup(asModelSpec(openAiModel), undefined, true, authPath), false); + assert.equal(await shouldRunInteractiveSetup(undefined, undefined, false, authPath), false); }); test("isLocalModelProvider flags known local provider ids without consulting models.json", () => { diff --git a/tests/node-version.test.ts b/tests/node-version.test.ts index 174f9b08..49ef4142 100644 --- a/tests/node-version.test.ts +++ b/tests/node-version.test.ts @@ -14,6 +14,7 @@ test("isSupportedNodeVersion enforces the exact minimum floor", () => { assert.equal(isSupportedNodeVersion("23.0.0"), true); assert.equal(isSupportedNodeVersion(`${MAX_NODE_MAJOR}.9.9`), true); assert.equal(isSupportedNodeVersion(`${MAX_NODE_MAJOR + 1}.0.0`), false); + assert.equal(isSupportedNodeVersion("22.21.1"), false); assert.equal(isSupportedNodeVersion("22.18.0"), false); assert.equal(isSupportedNodeVersion("20.19.0"), false); assert.equal(isSupportedNodeVersion("18.17.0"), false); diff --git a/tests/package-budget.test.ts b/tests/package-budget.test.ts new file mode 100644 index 00000000..81227f97 --- /dev/null +++ b/tests/package-budget.test.ts @@ -0,0 +1,76 @@ +import assert from "node:assert/strict"; +import { mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join, resolve } from "node:path"; +import { spawnSync } from "node:child_process"; +import test from "node:test"; + +const root = process.cwd(); +const verifier = resolve(root, "scripts", "verify-package-budget.mjs"); + +function runBudget(packMetadata: Record) { + const tempRoot = mkdtempSync(join(tmpdir(), "feynman-package-budget-")); + const packOutput = join(tempRoot, "pack.json"); + writeFileSync( + packOutput, + `prepack lifecycle output\n${JSON.stringify([packMetadata])}\n`, + "utf8", + ); + return spawnSync(process.execPath, [verifier, packOutput], { + encoding: "utf8", + }); +} + +test("package release budget is documented and accepts the measured candidate shape", () => { + const manifest = JSON.parse(readFileSync(resolve(root, "package.json"), "utf8")) as { + feynmanReleaseBudget: { + maxTarballBytes: number; + maxUnpackedBytes: number; + maxFileCount: number; + }; + }; + assert.deepEqual(manifest.feynmanReleaseBudget, { + maxTarballBytes: 131_072_000, + maxUnpackedBytes: 377_487_360, + maxFileCount: 42_000, + }); + + const result = runBudget({ + filename: "companion-ai-feynman-0.3.6.tgz", + size: 113_321_310, + unpackedSize: 328_980_000, + entryCount: 39_085, + }); + assert.equal(result.status, 0, result.stderr); +}); + +test("package release budget accepts npm pack totalFiles metadata from older npm releases", () => { + const result = runBudget({ + filename: "companion-ai-feynman-0.3.6.tgz", + size: 113_321_310, + unpackedSize: 328_980_000, + totalFiles: 39_085, + }); + assert.equal(result.status, 0, result.stderr); +}); + +test("package release budget rejects compressed size and file-count regressions", () => { + for (const packMetadata of [ + { + filename: "companion-ai-feynman-0.3.6.tgz", + size: 131_072_001, + unpackedSize: 328_980_000, + entryCount: 39_085, + }, + { + filename: "companion-ai-feynman-0.3.6.tgz", + size: 113_321_310, + unpackedSize: 328_980_000, + entryCount: 42_001, + }, + ]) { + const result = runBudget(packMetadata); + assert.notEqual(result.status, 0); + assert.match(result.stderr, /feynman package budget/); + } +}); diff --git a/tests/package-seeding.test.ts b/tests/package-seeding.test.ts index aada5070..6542dccf 100644 --- a/tests/package-seeding.test.ts +++ b/tests/package-seeding.test.ts @@ -9,6 +9,7 @@ import { resolveAdjacentNpmCommand, seedBundledWorkspacePackages, } from "../src/pi/package-ops.js"; +import { RUNTIME_INPUT_FILES } from "../scripts/lib/runtime-workspace-integrity.mjs"; function createBundledWorkspace( appRoot: string, @@ -45,15 +46,18 @@ test("Pi runtime fallback version follows the bundled Pi runtime version", async test("prepare runtime workspace hash tracks every imported patch file", async () => { const runtimeWorkspaceSource = readFileSync(resolve(process.cwd(), "scripts", "prepare-runtime-workspace.mjs"), "utf8"); const importedPatchFiles = [...runtimeWorkspaceSource.matchAll(/from "\.\/lib\/([^"]+\.mjs)"/g)].map((match) => match[1]); - const hashedPatchFiles = [...runtimeWorkspaceSource.matchAll(/resolve\(appRoot, "scripts", "lib", "([^"]+\.mjs)"\)/g)].map((match) => match[1]); - assert.match(runtimeWorkspaceSource, /resolve\(appRoot, "scripts", "prepare-runtime-workspace\.mjs"\)/); + assert.ok(RUNTIME_INPUT_FILES.includes("scripts/prepare-runtime-workspace.mjs")); + assert.ok(RUNTIME_INPUT_FILES.includes("scripts/prune-runtime-deps.mjs")); assert.ok(importedPatchFiles.length > 0); for (const patchFile of importedPatchFiles) { - assert.ok(hashedPatchFiles.includes(patchFile), `${patchFile} must be included in the runtime input hash`); + assert.ok( + RUNTIME_INPUT_FILES.includes(`scripts/lib/${patchFile}`), + `${patchFile} must be included in the runtime input hash`, + ); } - for (const patchFile of hashedPatchFiles) { - assert.equal(existsSync(resolve(process.cwd(), "scripts", "lib", patchFile)), true, `${patchFile} must exist`); + for (const inputFile of RUNTIME_INPUT_FILES) { + assert.equal(existsSync(resolve(process.cwd(), inputFile)), true, `${inputFile} must exist`); } }); @@ -61,8 +65,8 @@ test("prepare runtime workspace pins audited transitive runtime overrides", asyn const runtimeWorkspaceSource = readFileSync(resolve(process.cwd(), "scripts", "prepare-runtime-workspace.mjs"), "utf8"); assert.match(runtimeWorkspaceSource, /"@mozilla\/readability": "0\.6\.0"/); - assert.match(runtimeWorkspaceSource, /"@opentelemetry\/sdk-node": "0\.219\.0"/); - assert.match(runtimeWorkspaceSource, /"@opentelemetry\/resources": "2\.8\.0"/); + assert.match(runtimeWorkspaceSource, /"@opentelemetry\/sdk-node": "0\.221\.0"/); + assert.match(runtimeWorkspaceSource, /"@opentelemetry\/resources": "2\.10\.0"/); assert.match(runtimeWorkspaceSource, /overrides: RUNTIME_PACKAGE_OVERRIDES/); }); diff --git a/tests/pi-model-registry-patch.test.ts b/tests/pi-model-registry-patch.test.ts index 0fcabfc5..038cb6aa 100644 --- a/tests/pi-model-registry-patch.test.ts +++ b/tests/pi-model-registry-patch.test.ts @@ -1,5 +1,7 @@ import test from "node:test"; import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; import { patchPiModelRegistrySource } from "../scripts/lib/pi-model-registry-patch.mjs"; @@ -26,6 +28,49 @@ const SOURCE = [ "", ].join("\n"); +const MODEL_RUNTIME_SOURCE = [ + "function mergeHeaders(base, override) {", + " return { ...base, ...override };", + "}", + "class ModelRuntime {", + " async prepareRequest(model, options) {", + " const resolution = await this.getAuth(model);", + " const { transformHeaders, ...providerOptions } = options ?? {};", + " let headers = mergeHeaders(resolution.auth.headers, providerOptions.headers);", + " if (transformHeaders)", + " headers = await transformHeaders(headers ?? {});", + " return { providerOptions, headers };", + " }", + "}", + "", +].join("\n"); + +const CURRENT_MODEL_REGISTRY_SOURCE = [ + 'export { clearApiKeyCache } from "./provider-composer.js";', + "export class ModelRegistry {", + " async getApiKeyAndHeaders(model) {", + " try {", + " const resolution = await this.runtime.getAuth(model);", + " if (!resolution) {", + " const compatibility = this.runtime.getCompatibilityRequestConfig(model);", + " const headers = compatibility.headers", + " ? Object.fromEntries(Object.entries(compatibility.headers).filter((entry) => entry[1] !== null))", + " : undefined;", + " return { ok: true, headers };", + " }", + " const headers = resolution.auth.headers", + " ? Object.fromEntries(Object.entries(resolution.auth.headers).filter((entry) => entry[1] !== null))", + " : undefined;", + " return { ok: true, apiKey: resolution.auth.apiKey, headers, env: resolution.env };", + " }", + " catch (error) {", + " return { ok: false, error: String(error) };", + " }", + " }", + "}", + "", +].join("\n"); + test("patchPiModelRegistrySource guards request headers against non-Latin-1 values", () => { const patched = patchPiModelRegistrySource(SOURCE); @@ -36,6 +81,68 @@ test("patchPiModelRegistrySource guards request headers against non-Latin-1 valu assert.equal(twice, patched); }); +test("patchPiModelRegistrySource guards final ModelRuntime request authentication", () => { + const patched = patchPiModelRegistrySource(MODEL_RUNTIME_SOURCE); + + assert.match(patched, /function assertHeaderSafeRequestConfig\(/); + assert.match( + patched, + /assertHeaderSafeRequestConfig\(model\.provider, providerOptions\.apiKey \?\? resolution\.auth\.apiKey, headers\);/, + ); + assert.equal(patchPiModelRegistrySource(patched), patched); +}); + +test("patchPiModelRegistrySource guards the Pi 0.82 compatibility facade", () => { + const patched = patchPiModelRegistrySource(CURRENT_MODEL_REGISTRY_SOURCE); + + assert.match(patched, /function assertHeaderSafeRequestConfig\(/); + assert.match(patched, /assertHeaderSafeRequestConfig\(model\.provider, undefined, headers\);/); + assert.match( + patched, + /assertHeaderSafeRequestConfig\(model\.provider, resolution\.auth\.apiKey, headers\);/, + ); + assert.equal(patchPiModelRegistrySource(patched), patched); +}); + +test("patchPiModelRegistrySource fails closed on an unknown ModelRuntime layout", () => { + assert.throws( + () => patchPiModelRegistrySource("class ModelRuntime { async prepareRequest() {} }\n"), + /Unsupported Pi ModelRuntime layout/, + ); +}); + +test("patchPiModelRegistrySource fails closed on an unknown ModelRegistry layout", () => { + assert.throws( + () => patchPiModelRegistrySource("export class ModelRegistry { async getApiKeyAndHeaders() {} }\n"), + /Unsupported Pi ModelRegistry layout/, + ); +}); + +test("embedded Pi ModelRuntime carries the final request header guard", () => { + const source = readFileSync( + join(process.cwd(), "node_modules", "@earendil-works", "pi-coding-agent", "dist", "core", "model-runtime.js"), + "utf8", + ); + assert.match(source, /function assertHeaderSafeRequestConfig\(/); + assert.match( + source, + /assertHeaderSafeRequestConfig\(model\.provider, providerOptions\.apiKey \?\? resolution\.auth\.apiKey, headers\);/, + ); +}); + +test("embedded Pi ModelRegistry compatibility facade carries both request guards", () => { + const source = readFileSync( + join(process.cwd(), "node_modules", "@earendil-works", "pi-coding-agent", "dist", "core", "model-registry.js"), + "utf8", + ); + assert.match(source, /function assertHeaderSafeRequestConfig\(/); + assert.match(source, /assertHeaderSafeRequestConfig\(model\.provider, undefined, headers\);/); + assert.match( + source, + /assertHeaderSafeRequestConfig\(model\.provider, resolution\.auth\.apiKey, headers\);/, + ); +}); + test("injected Latin-1 guard names the offending provider and header", async () => { const patched = patchPiModelRegistrySource(SOURCE); const helper = patched.slice(0, patched.indexOf("function formatValidationPath")); diff --git a/tests/pi-otel-patch.test.ts b/tests/pi-otel-patch.test.ts index 9b328dd6..8f952cb5 100644 --- a/tests/pi-otel-patch.test.ts +++ b/tests/pi-otel-patch.test.ts @@ -14,11 +14,26 @@ test("patchPiOtelSource strips cwd attributes from pi-otel spans and resources", assert.doesNotMatch(patchPiOtelSource("dist/otel/sdk.js", sdk), /ATTR_PI_CWD|cfg\.cwd/); assert.doesNotMatch(patchPiOtelSource("dist/index.js", index), /ATTR_PI_CWD|cfg\.cwd/); assert.match(patchPiOtelSource("dist/index.js", index), /if \(await probeEndpoint\(cfg\.endpoint\)\)/); - assert.match(patchPiOtelSource("dist/otel/sdk.js", sdk), /import \{ resourceFromAttributes \} from "@opentelemetry\/resources"/); - assert.match(patchPiOtelSource("dist/otel/sdk.js", sdk), /const resource = resourceFromAttributes\(\{/); + assert.match(patchPiOtelSource("dist/otel/sdk.js", sdk), /import \* as otelResources from "@opentelemetry\/resources"/); + assert.match(patchPiOtelSource("dist/otel/sdk.js", sdk), /const resource = createFeynmanResource\(\{/); assert.match(patchPiOtelSource("dist/otel/sdk.js", sdk), /u\.protocol === "https:" \? 443/); }); +test("patchPiOtelSource supports both OpenTelemetry 1.x and 2.x resource APIs", () => { + for (const source of [ + `import { Resource } from "@opentelemetry/resources"; +const resource = new Resource({});`, + `import { resourceFromAttributes } from "@opentelemetry/resources"; +const resource = resourceFromAttributes({});`, + ]) { + const patched = patchPiOtelSource("dist/otel/sdk.js", source); + + assert.match(patched, /typeof otelResources\.resourceFromAttributes === "function"/); + assert.match(patched, /new otelResources\.Resource\(attributes\)/); + assert.match(patched, /const resource = createFeynmanResource\(\{\}\)/); + } +}); + test("patchPiOtelSource makes pi-otel honor trace-specific OTLP env vars", () => { const config = ` const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? merged?.endpoint ?? diff --git a/tests/pi-runtime-patches.test.ts b/tests/pi-runtime-patches.test.ts index 3f03224c..36f83eac 100644 --- a/tests/pi-runtime-patches.test.ts +++ b/tests/pi-runtime-patches.test.ts @@ -165,6 +165,12 @@ async function execute(params, configWorkflow, ctx) { pi.registerCommand("search", { description: "Browse stored web search results" }); `; +const WEB_ACCESS_PDF_SOURCE = ` +import { join, basename } from "node:path"; +import { homedir } from "node:os"; +const DEFAULT_OUTPUT_DIR = join(homedir(), "Downloads"); +`; + const SUBAGENT_PI_SPAWN_SOURCE = ` export interface PiSpawnDeps { execPath?: string; @@ -184,6 +190,53 @@ export function resolveWindowsPiCliScript(deps: PiSpawnDeps = {}): string | unde } `; +const MODEL_REGISTRY_SOURCE = ` +export { clearApiKeyCache } from "./provider-composer.js"; +export class ModelRegistry { + async getApiKeyAndHeaders(model) { + try { + const resolution = await this.runtime.getAuth(model); + if (!resolution) { + const compatibility = this.runtime.getCompatibilityRequestConfig(model); + const headers = compatibility.headers + ? Object.fromEntries(Object.entries(compatibility.headers).filter((entry) => entry[1] !== null)) + : undefined; + return { ok: true, headers }; + } + const headers = resolution.auth.headers + ? Object.fromEntries(Object.entries(resolution.auth.headers).filter((entry) => entry[1] !== null)) + : undefined; + return { ok: true, apiKey: resolution.auth.apiKey, headers, env: resolution.env }; + } + catch (error) { + return { ok: false, error: String(error) }; + } + } +} +`; + +const MODEL_RUNTIME_SOURCE = ` +function mergeHeaders(base, override) { + return { ...base, ...override }; +} +export class ModelRuntime { + async prepareRequest(model, options) { + const resolution = await this.getAuth(model, { apiKey: options?.apiKey, env: options?.env }); + const { transformHeaders, ...providerOptions } = options ?? {}; + let headers = mergeHeaders(resolution.auth.headers, providerOptions.headers); + if (transformHeaders) + headers = await transformHeaders(headers ?? {}); + return { + options: { + ...providerOptions, + apiKey: providerOptions.apiKey ?? resolution.auth.apiKey, + headers, + }, + }; + } +} +`; + test("patchPiRuntimeNodeModules patches installed Pi runtime files", async () => { const appRoot = mkdtempSync(join(tmpdir(), "feynman-runtime-patches-")); const agentLoopPath = join(appRoot, "node_modules", "@earendil-works", "pi-agent-core", "dist", "agent-loop.js"); @@ -191,6 +244,9 @@ test("patchPiRuntimeNodeModules patches installed Pi runtime files", async () => const editorPath = join(appRoot, "node_modules", "@earendil-works", "pi-tui", "dist", "components", "editor.js"); const themePath = join(appRoot, "node_modules", "@earendil-works", "pi-coding-agent", "dist", "modes", "interactive", "theme", "theme.js"); const packageJsonPath = join(appRoot, "node_modules", "@earendil-works", "pi-coding-agent", "package.json"); + const modelRegistryPath = join(appRoot, "node_modules", "@earendil-works", "pi-coding-agent", "dist", "core", "model-registry.js"); + const modelRuntimePath = join(appRoot, "node_modules", "@earendil-works", "pi-coding-agent", "dist", "core", "model-runtime.js"); + const mcpManifestPath = join(appRoot, "node_modules", "@modelcontextprotocol", "sdk", "package.json"); const alphaSearchPath = join(appRoot, "node_modules", "@companion-ai", "alpha-hub", "src", "lib", "alphaxiv.js"); const sessionSearchPath = join(appRoot, "node_modules", "@kaiserlich-dev", "pi-session-search", "extensions", "indexer.ts"); await mkdir(dirname(agentLoopPath), { recursive: true }); @@ -198,6 +254,9 @@ test("patchPiRuntimeNodeModules patches installed Pi runtime files", async () => await mkdir(dirname(editorPath), { recursive: true }); await mkdir(dirname(themePath), { recursive: true }); await mkdir(dirname(packageJsonPath), { recursive: true }); + await mkdir(dirname(modelRegistryPath), { recursive: true }); + await mkdir(dirname(modelRuntimePath), { recursive: true }); + await mkdir(dirname(mcpManifestPath), { recursive: true }); await mkdir(dirname(alphaSearchPath), { recursive: true }); await mkdir(dirname(sessionSearchPath), { recursive: true }); writeFileSync(agentLoopPath, SOURCE, "utf8"); @@ -209,6 +268,12 @@ test("patchPiRuntimeNodeModules patches installed Pi runtime files", async () => JSON.stringify({ name: "@earendil-works/pi-coding-agent", piConfig: { configDir: ".pi" } }, null, 2) + "\n", "utf8", ); + writeFileSync(modelRegistryPath, MODEL_REGISTRY_SOURCE, "utf8"); + writeFileSync(modelRuntimePath, MODEL_RUNTIME_SOURCE, "utf8"); + writeFileSync(mcpManifestPath, JSON.stringify({ + name: "@modelcontextprotocol/sdk", + dependencies: { "@hono/node-server": "^1.19.9" }, + }) + "\n", "utf8"); writeFileSync(alphaSearchPath, ALPHA_SEARCH_SOURCE, "utf8"); writeFileSync(sessionSearchPath, SESSION_SEARCH_INDEXER_SOURCE, "utf8"); @@ -228,6 +293,23 @@ test("patchPiRuntimeNodeModules patches installed Pi runtime files", async () => const patchedPackageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { piConfig?: Record }; assert.equal(patchedPackageJson.piConfig?.name, "feynman"); assert.equal(patchedPackageJson.piConfig?.configDir, ".feynman"); + assert.match( + readFileSync(modelRuntimePath, "utf8"), + /assertHeaderSafeRequestConfig\(model\.provider, providerOptions\.apiKey \?\? resolution\.auth\.apiKey, headers\)/, + ); + const patchedRegistry = readFileSync(modelRegistryPath, "utf8"); + assert.match( + patchedRegistry, + /assertHeaderSafeRequestConfig\(model\.provider, undefined, headers\)/, + ); + assert.match( + patchedRegistry, + /assertHeaderSafeRequestConfig\(model\.provider, resolution\.auth\.apiKey, headers\)/, + ); + assert.equal( + JSON.parse(readFileSync(mcpManifestPath, "utf8")).dependencies["@hono/node-server"], + "2.0.12", + ); assert.match(readFileSync(alphaSearchPath, "utf8"), /async function searchRestFast/); assert.match(readFileSync(sessionSearchPath, "utf8"), /process\.env\.FEYNMAN_SESSION_DIR/); assert.equal(patchPiRuntimeNodeModules(appRoot), false); @@ -241,6 +323,7 @@ test("patchPiRuntimeNodeModules patches the vendored runtime workspace", async ( const themePath = join(appRoot, ".feynman", "npm", "node_modules", "@mariozechner", "pi-coding-agent", "dist", "modes", "interactive", "theme", "theme.js"); const packageJsonPath = join(appRoot, ".feynman", "npm", "node_modules", "@mariozechner", "pi-coding-agent", "package.json"); const webAccessPath = join(appRoot, ".feynman", "npm", "node_modules", "pi-web-access", "index.ts"); + const webAccessPdfPath = join(appRoot, ".feynman", "npm", "node_modules", "pi-web-access", "pdf-extract.ts"); const subagentSpawnPath = join(appRoot, ".feynman", "npm", "node_modules", "pi-subagents", "src", "runs", "shared", "pi-spawn.ts"); const piOtelConfigPath = join(appRoot, ".feynman", "npm", "node_modules", "pi-otel", "dist", "config.js"); const sessionSearchPath = join(appRoot, ".feynman", "npm", "node_modules", "@kaiserlich-dev", "pi-session-search", "extensions", "indexer.ts"); @@ -250,6 +333,7 @@ test("patchPiRuntimeNodeModules patches the vendored runtime workspace", async ( await mkdir(dirname(themePath), { recursive: true }); await mkdir(dirname(packageJsonPath), { recursive: true }); await mkdir(dirname(webAccessPath), { recursive: true }); + await mkdir(dirname(webAccessPdfPath), { recursive: true }); await mkdir(dirname(subagentSpawnPath), { recursive: true }); await mkdir(dirname(piOtelConfigPath), { recursive: true }); await mkdir(dirname(sessionSearchPath), { recursive: true }); @@ -263,6 +347,7 @@ test("patchPiRuntimeNodeModules patches the vendored runtime workspace", async ( "utf8", ); writeFileSync(webAccessPath, WEB_ACCESS_INDEX_SOURCE, "utf8"); + writeFileSync(webAccessPdfPath, WEB_ACCESS_PDF_SOURCE, "utf8"); writeFileSync(subagentSpawnPath, SUBAGENT_PI_SPAWN_SOURCE, "utf8"); writeFileSync(piOtelConfigPath, PI_OTEL_CONFIG_SOURCE, "utf8"); writeFileSync(sessionSearchPath, SESSION_SEARCH_INDEXER_SOURCE, "utf8"); @@ -278,6 +363,9 @@ test("patchPiRuntimeNodeModules patches the vendored runtime workspace", async ( assert.equal(patchedPackageJson.piConfig?.configDir, ".feynman"); assert.match(readFileSync(webAccessPath, "utf8"), /params\.workflow \?\? configWorkflow \?\? "none"/); assert.match(readFileSync(webAccessPath, "utf8"), /pi\.registerCommand\("web-results"/); + assert.match(readFileSync(webAccessPdfPath, "utf8"), /FEYNMAN_FETCH_CACHE_DIR/); + assert.match(readFileSync(webAccessPdfPath, "utf8"), /\.feynman.*cache.*fetch-content/); + assert.doesNotMatch(readFileSync(webAccessPdfPath, "utf8"), /Downloads|homedir/); assert.match(readFileSync(subagentSpawnPath, "utf8"), /process\.env\.FEYNMAN_PI_CLI_PATH/); assert.match(readFileSync(subagentSpawnPath, "utf8"), /\targv2\?: string;/); assert.match(readFileSync(subagentSpawnPath, "utf8"), /path\.basename\(argvPath\) !== "pi-cli-wrapper\.js"/); diff --git a/tests/pi-runtime.test.ts b/tests/pi-runtime.test.ts index f7bb843e..77508626 100644 --- a/tests/pi-runtime.test.ts +++ b/tests/pi-runtime.test.ts @@ -1,6 +1,6 @@ import assert from "node:assert/strict"; import { spawnSync } from "node:child_process"; -import { mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import test from "node:test"; @@ -11,6 +11,7 @@ import { buildPiArgs, buildPiEnv, ensureFeynmanCommandShim, + ensureFeynmanWorkspaceScaffold, getFeynmanCommandShimDir, resolvePiPaths, toNodeImportSpecifier, @@ -384,6 +385,25 @@ test("ensureFeynmanCommandShim creates a repo-local feynman launcher", () => { assert.deepEqual(JSON.parse(result.stdout), { argv: ["alpha", "status"], bin: feynmanBinPath }); }); +test("ensureFeynmanWorkspaceScaffold creates default artifact directories", () => { + const workingDir = mkdtempSync(join(tmpdir(), "feynman-workspace-scaffold-")); + + assert.equal(ensureFeynmanWorkspaceScaffold(workingDir), true); + + for (const relPath of ["outputs/.plans", "outputs/.drafts", "papers", "notes"]) { + assert.equal(existsSync(join(workingDir, relPath)), true, relPath); + } +}); + +test("ensureFeynmanWorkspaceScaffold does not block read-only research sessions", () => { + const workingDir = mkdtempSync(join(tmpdir(), "feynman-workspace-readonly-")); + const permissionError = Object.assign(new Error("read-only filesystem"), { code: "EROFS" }); + + assert.equal(ensureFeynmanWorkspaceScaffold(workingDir, () => { + throw permissionError; + }), false); +}); + test("buildPiEnv uses pre-resolved executable paths when provided", () => { const paths = resolvePiPaths("/repo/feynman"); const env = buildPiEnv( @@ -464,6 +484,39 @@ test("resolvePiPaths falls back to the vendored runtime workspace in packed inst assert.deepEqual(validatePiInstallation(appRoot), []); }); +test("package ships source modules required by source-loaded research extensions", () => { + const manifest = JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf8")) as { files?: string[] }; + const packagedFiles = new Set(manifest.files ?? []); + + for (const path of [ + "src/config/paths.ts", + "src/workbench/data-root.ts", + "src/workbench/oauth-store.ts", + "src/workbench/settings-store.ts", + ]) { + assert.equal(packagedFiles.has(path), true, `${path} must ship with the source-loaded research extension`); + } +}); + +test("resolveBundledAlphaCliPath resolves hoisted package installs before bundled fallbacks", () => { + const root = mkdtempSync(join(tmpdir(), "feynman-alpha-cli-hoisted-")); + const appRoot = join(root, "node_modules", "@companion-ai", "feynman"); + const hoistedAlpha = join(root, "node_modules", "@companion-ai", "alpha-hub", "bin", "alpha"); + + mkdirSync(join(appRoot), { recursive: true }); + writeFileSync(join(appRoot, "package.json"), JSON.stringify({ name: "@companion-ai/feynman" })); + mkdirSync(dirname(hoistedAlpha), { recursive: true }); + mkdirSync(join(root, "node_modules", "@companion-ai", "alpha-hub", "src"), { recursive: true }); + writeFileSync( + join(root, "node_modules", "@companion-ai", "alpha-hub", "package.json"), + JSON.stringify({ name: "@companion-ai/alpha-hub", type: "module", exports: { ".": "./src/index.js" } }), + ); + writeFileSync(join(root, "node_modules", "@companion-ai", "alpha-hub", "src", "index.js"), "", "utf8"); + writeFileSync(hoistedAlpha, "", "utf8"); + + assert.equal(resolveBundledAlphaCliPath(appRoot), realpathSync(hoistedAlpha)); +}); + test("resolveBundledAlphaCliPath prefers package-local alpha and falls back to the bundled workspace", () => { const appRoot = mkdtempSync(join(tmpdir(), "feynman-alpha-cli-")); const packageLocalAlpha = join(appRoot, "node_modules", "@companion-ai", "alpha-hub", "bin", "alpha"); diff --git a/tests/pi-settings.test.ts b/tests/pi-settings.test.ts index 48f26d1b..bf2d322f 100644 --- a/tests/pi-settings.test.ts +++ b/tests/pi-settings.test.ts @@ -68,6 +68,7 @@ test("normalizeThinkingLevel accepts the latest Pi thinking levels", () => { assert.equal(normalizeThinkingLevel("medium"), "medium"); assert.equal(normalizeThinkingLevel("high"), "high"); assert.equal(normalizeThinkingLevel("xhigh"), "xhigh"); + assert.equal(normalizeThinkingLevel("max"), "max"); }); test("normalizeThinkingLevel rejects unknown values", () => { @@ -75,7 +76,7 @@ test("normalizeThinkingLevel rejects unknown values", () => { assert.equal(normalizeThinkingLevel(undefined), undefined); }); -test("normalizeFeynmanSettings seeds the fast core package set", () => { +test("normalizeFeynmanSettings seeds the fast core package set", async () => { const root = mkdtempSync(join(tmpdir(), "feynman-settings-")); const settingsPath = join(root, "settings.json"); const bundledSettingsPath = join(root, "bundled-settings.json"); @@ -84,13 +85,13 @@ test("normalizeFeynmanSettings seeds the fast core package set", () => { writeFileSync(bundledSettingsPath, "{}\n", "utf8"); writeFileSync(authPath, "{}\n", "utf8"); - normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); + await normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { packages?: string[] }; assert.deepEqual(settings.packages, [...CORE_PACKAGE_SOURCES]); }); -test("normalizeFeynmanSettings prunes the legacy slow default package set", () => { +test("normalizeFeynmanSettings prunes the legacy slow default package set", async () => { const root = mkdtempSync(join(tmpdir(), "feynman-settings-")); const settingsPath = join(root, "settings.json"); const bundledSettingsPath = join(root, "bundled-settings.json"); @@ -99,9 +100,14 @@ test("normalizeFeynmanSettings prunes the legacy slow default package set", () = writeFileSync( settingsPath, JSON.stringify( - { - packages: [ - ...CORE_PACKAGE_SOURCES, + { + packages: [ + "npm:@companion-ai/alpha-hub", + "npm:pi-subagents", + "npm:pi-btw", + "npm:pi-docparser", + "npm:pi-web-access", + "npm:pi-otel", "npm:pi-generative-ui", ], }, @@ -113,13 +119,13 @@ test("normalizeFeynmanSettings prunes the legacy slow default package set", () = writeFileSync(bundledSettingsPath, "{}\n", "utf8"); writeFileSync(authPath, "{}\n", "utf8"); - normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); + await normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { packages?: string[] }; assert.deepEqual(settings.packages, [...CORE_PACKAGE_SOURCES]); }); -test("normalizeFeynmanSettings prunes the legacy Devkade telemetry default package", () => { +test("normalizeFeynmanSettings prunes the legacy Devkade telemetry default package", async () => { const root = mkdtempSync(join(tmpdir(), "feynman-settings-")); const settingsPath = join(root, "settings.json"); const bundledSettingsPath = join(root, "bundled-settings.json"); @@ -142,13 +148,13 @@ test("normalizeFeynmanSettings prunes the legacy Devkade telemetry default packa writeFileSync(bundledSettingsPath, "{}\n", "utf8"); writeFileSync(authPath, "{}\n", "utf8"); - normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); + await normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { packages?: string[] }; assert.deepEqual(settings.packages, [...CORE_PACKAGE_SOURCES]); }); -test("normalizeFeynmanSettings seeds the newest OpenAI GPT default exposed by Pi", () => { +test("normalizeFeynmanSettings seeds the newest OpenAI GPT default exposed by Pi", async () => { const root = mkdtempSync(join(tmpdir(), "feynman-settings-")); const settingsPath = join(root, "settings.json"); const bundledSettingsPath = join(root, "bundled-settings.json"); @@ -156,9 +162,9 @@ test("normalizeFeynmanSettings seeds the newest OpenAI GPT default exposed by Pi writeFileSync(bundledSettingsPath, "{}\n", "utf8"); writeFileSync(authPath, JSON.stringify({ openai: { type: "api_key", key: "openai-test-key" } }) + "\n", "utf8"); - const recommendation = chooseRecommendedModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); - normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); + await normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { defaultProvider?: string; @@ -167,7 +173,7 @@ test("normalizeFeynmanSettings seeds the newest OpenAI GPT default exposed by Pi assert.equal(`${settings.defaultProvider}/${settings.defaultModel}`, recommendation?.spec); }); -test("normalizeFeynmanSettings replaces an unavailable stale default with the current default", () => { +test("normalizeFeynmanSettings replaces an unavailable stale default with the current default", async () => { const root = mkdtempSync(join(tmpdir(), "feynman-settings-")); const settingsPath = join(root, "settings.json"); const bundledSettingsPath = join(root, "bundled-settings.json"); @@ -180,9 +186,9 @@ test("normalizeFeynmanSettings replaces an unavailable stale default with the cu ); writeFileSync(bundledSettingsPath, "{}\n", "utf8"); writeFileSync(authPath, JSON.stringify({ openai: { type: "api_key", key: "openai-test-key" } }) + "\n", "utf8"); - const recommendation = chooseRecommendedModel(authPath); + const recommendation = await chooseRecommendedModel(authPath); - normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); + await normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { defaultProvider?: string; @@ -191,7 +197,7 @@ test("normalizeFeynmanSettings replaces an unavailable stale default with the cu assert.equal(`${settings.defaultProvider}/${settings.defaultModel}`, recommendation?.spec); }); -test("normalizeFeynmanSettings seeds OpenCode Go Kimi as the preferred OpenCode Go default", () => { +test("normalizeFeynmanSettings seeds OpenCode Go Kimi as the preferred OpenCode Go default", async () => { const root = mkdtempSync(join(tmpdir(), "feynman-settings-")); const settingsPath = join(root, "settings.json"); const bundledSettingsPath = join(root, "bundled-settings.json"); @@ -200,7 +206,7 @@ test("normalizeFeynmanSettings seeds OpenCode Go Kimi as the preferred OpenCode writeFileSync(bundledSettingsPath, "{}\n", "utf8"); writeFileSync(authPath, JSON.stringify({ "opencode-go": { type: "api_key", key: "opencode-test-key" } }) + "\n", "utf8"); - normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); + await normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { defaultProvider?: string; @@ -250,7 +256,7 @@ test("supportsNativePackageSources disables sqlite-backed packages on Node 23+", assert.equal(supportsNativePackageSources("24.8.0"), false); }); -test("normalizeFeynmanSettings prunes legacy package defaults to the lean research core", () => { +test("normalizeFeynmanSettings prunes legacy package defaults to the lean research core", async () => { const root = mkdtempSync(join(tmpdir(), "feynman-settings-")); const settingsPath = join(root, "settings.json"); const bundledSettingsPath = join(root, "bundled-settings.json"); @@ -284,14 +290,14 @@ test("normalizeFeynmanSettings prunes legacy package defaults to the lean resear const originalVersion = process.versions.node; Object.defineProperty(process.versions, "node", { value: "24.0.0", configurable: true }); try { - normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); + await normalizeFeynmanSettings(settingsPath, bundledSettingsPath, "medium", authPath); } finally { Object.defineProperty(process.versions, "node", { value: originalVersion, configurable: true }); } const settings = JSON.parse(readFileSync(settingsPath, "utf8")) as { packages?: string[] }; assert.deepEqual(settings.packages, [...CORE_PACKAGE_SOURCES]); - assert.equal((settings.packages as string[] | undefined)?.includes("npm:pi-btw"), true); + assert.equal((settings.packages as string[] | undefined)?.some((source) => source.startsWith("npm:pi-btw@")), true); for (const source of NATIVE_PACKAGE_SOURCES) { assert.equal((settings.packages as string[] | undefined)?.includes(source), false); } diff --git a/tests/pi-shrinkwrap-security-patch.test.ts b/tests/pi-shrinkwrap-security-patch.test.ts new file mode 100644 index 00000000..8470112b --- /dev/null +++ b/tests/pi-shrinkwrap-security-patch.test.ts @@ -0,0 +1,114 @@ +import assert from "node:assert/strict"; +import { mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import test from "node:test"; + +import { + patchPiBraceExpansionTree, + patchPiCodingAgentShrinkwrapSource, + patchPiPackageLockSource, +} from "../scripts/lib/pi-shrinkwrap-security-patch.mjs"; + +test("Pi shrinkwrap security patch upgrades only vulnerable brace-expansion entries", () => { + const source = JSON.stringify({ + packages: { + "node_modules/brace-expansion": { + version: "5.0.7", + resolved: "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + }, + }, + }); + const patched = JSON.parse(patchPiCodingAgentShrinkwrapSource(source)); + assert.equal(patched.packages["node_modules/brace-expansion"].version, "5.0.8"); + assert.throws( + () => patchPiCodingAgentShrinkwrapSource(JSON.stringify({ + packages: { "node_modules/brace-expansion": { version: "4.0.0" } }, + })), + /Unsupported Pi brace-expansion shrinkwrap entry/, + ); +}); + +test("Pi shrinkwrap security patch upgrades the owning package lock", () => { + const source = JSON.stringify({ + packages: { + "node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion": { + version: "5.0.7", + resolved: "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + }, + }, + }); + const patched = JSON.parse(patchPiPackageLockSource(source)); + assert.equal( + patched.packages["node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion"].version, + "5.0.8", + ); +}); + +test("Pi shrinkwrap security patch replaces the nested package tree and is idempotent", () => { + const root = mkdtempSync(join(tmpdir(), "feynman-pi-security-")); + const nodeModules = join(root, "node_modules"); + const safePackage = join(nodeModules, "brace-expansion"); + const piRoot = join(nodeModules, "@earendil-works", "pi-coding-agent"); + const nestedPackage = join(piRoot, "node_modules", "brace-expansion"); + mkdirSync(safePackage, { recursive: true }); + mkdirSync(nestedPackage, { recursive: true }); + writeFileSync(join(safePackage, "package.json"), JSON.stringify({ name: "brace-expansion", version: "5.0.8" })); + writeFileSync(join(safePackage, "index.js"), "export const safe = true;\n"); + writeFileSync(join(nestedPackage, "package.json"), JSON.stringify({ name: "brace-expansion", version: "5.0.7" })); + writeFileSync(join(piRoot, "npm-shrinkwrap.json"), JSON.stringify({ + packages: { "node_modules/brace-expansion": { version: "5.0.7" } }, + })); + writeFileSync(join(root, "package-lock.json"), JSON.stringify({ + packages: { + "node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion": { + version: "5.0.7", + }, + }, + })); + + assert.equal(patchPiBraceExpansionTree(nodeModules), true); + assert.equal(JSON.parse(readFileSync(join(nestedPackage, "package.json"), "utf8")).version, "5.0.8"); + assert.equal(JSON.parse(readFileSync(join(piRoot, "npm-shrinkwrap.json"), "utf8")).packages["node_modules/brace-expansion"].version, "5.0.8"); + assert.equal( + JSON.parse(readFileSync(join(root, "package-lock.json"), "utf8")) + .packages["node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion"].version, + "5.0.8", + ); + assert.equal(patchPiBraceExpansionTree(nodeModules), false); +}); + +test("Pi shrinkwrap security patch accepts a safe nested tree when npm hoists the fallback", () => { + const root = mkdtempSync(join(tmpdir(), "feynman-pi-security-hoisted-")); + const nodeModules = join(root, "node_modules", "@companion-ai", "feynman", "node_modules"); + const piRoot = join(nodeModules, "@earendil-works", "pi-coding-agent"); + const nestedPackage = join(piRoot, "node_modules", "brace-expansion"); + mkdirSync(nestedPackage, { recursive: true }); + writeFileSync(join(nestedPackage, "package.json"), JSON.stringify({ name: "brace-expansion", version: "5.0.8" })); + writeFileSync(join(piRoot, "npm-shrinkwrap.json"), JSON.stringify({ + packages: { "node_modules/brace-expansion": { version: "5.0.8" } }, + })); + + assert.equal(patchPiBraceExpansionTree(nodeModules), false); +}); + +test("embedded Pi dependency tree uses patched brace-expansion", () => { + const piRoot = join( + process.cwd(), + "node_modules", + "@earendil-works", + "pi-coding-agent", + ); + const nestedPackage = join( + piRoot, + "node_modules", + "brace-expansion", + "package.json", + ); + assert.equal(JSON.parse(readFileSync(nestedPackage, "utf8")).version, "5.0.8"); + const shrinkwrap = JSON.parse(readFileSync(join(piRoot, "npm-shrinkwrap.json"), "utf8")); + assert.equal( + shrinkwrap.packages["node_modules/brace-expansion"].version, + "5.0.8", + ); +}); diff --git a/tests/pi-subagents-patch.test.ts b/tests/pi-subagents-patch.test.ts index 01aaea52..f17e7411 100644 --- a/tests/pi-subagents-patch.test.ts +++ b/tests/pi-subagents-patch.test.ts @@ -432,6 +432,34 @@ test("patchPiSubagentsSource makes pi-spawn prefer the real Pi CLI over Feynman assert.doesNotMatch(patched, /resolvePiAgentDir/); }); +test("patchPiSubagentsSource preserves the exact Feynman Pi path in the current package resolver", () => { + const input = [ + 'import * as fs from "node:fs";', + 'import * as path from "node:path";', + 'export const PI_CODING_AGENT_PACKAGE = "@earendil-works/pi-coding-agent";', + "interface PiSpawnDeps {", + "\targv1?: string;", + "\tenv?: NodeJS.ProcessEnv;", + "}", + "function isRunnableNodeScript(filePath: string, existsSync: (filePath: string) => boolean): boolean {", + "\treturn existsSync(filePath);", + "}", + "function normalizePath(filePath: string): string { return path.resolve(filePath); }", + "export function resolvePiCliScript(deps: PiSpawnDeps = {}): string | undefined {", + "\tconst existsSync = fs.existsSync;", + "\tconst argv1 = deps.argv1 ?? process.argv[1];", + "\treturn argv1;", + "}", + ].join("\n"); + + const patched = patchPiSubagentsSource("src/runs/shared/pi-spawn.ts", input); + + assert.match(patched, /const env = deps\.env \?\? process\.env;/); + assert.match(patched, /env\.FEYNMAN_PI_CLI_PATH\?\.trim\(\)/); + assert.match(patched, /isRunnableNodeScript\(cliPath, existsSync\)/); + assert.equal(patchPiSubagentsSource("src/runs/shared/pi-spawn.ts", patched), patched); +}); + test("patchPiSubagentsSource upgrades old Feynman pi-spawn patch to derive cli.js from wrapper main arg", () => { const input = [ "export interface PiSpawnDeps {", diff --git a/tests/pi-tui-patch.test.ts b/tests/pi-tui-patch.test.ts index 64d61382..c2ed0fa5 100644 --- a/tests/pi-tui-patch.test.ts +++ b/tests/pi-tui-patch.test.ts @@ -1,5 +1,7 @@ import test from "node:test"; import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; import { patchPiEditorSource, patchPiInteractiveThemeSource, patchPiTuiSource } from "../scripts/lib/pi-tui-patch.mjs"; @@ -118,12 +120,43 @@ test("patchPiTuiSource truncates the current upstream overflow check after clear assert.doesNotMatch(patched, /throw new Error\(errorMsg\)/); }); +test("embedded Pi 0.82 TUI and editor patches apply without dropping Unicode behavior", () => { + const tui = readFileSync(join(process.cwd(), "node_modules", "@earendil-works", "pi-tui", "dist", "tui.js"), "utf8"); + const editor = readFileSync(join(process.cwd(), "node_modules", "@earendil-works", "pi-tui", "dist", "components", "editor.js"), "utf8"); + + assert.match(tui, /line = sliceByColumn\(line, 0, width, true\)/); + assert.doesNotMatch(tui, /Rendered line .* exceeds terminal width/); + assert.match(editor, /applyBackgroundToLine, cjkBreakRegex/); + assert.match(editor, /const styleInput = typeof this\.theme\.input === "function"/); + assert.match(editor, /createScrollBorder/); + assert.match(editor, /firstGrapheme/); + assert.match(editor, /const cursor = `\\x1b\[7m\$\{firstGrapheme\}\\x1b\[27m`/); + assert.match(editor, /const cursor = "\\x1b\[7m \\x1b\[27m"/); + assert.doesNotMatch(editor, /const cursor = .*\\x1b\[0m/); + assert.match(editor, /sliceByColumn/); +}); + test("patchPiTuiSource is idempotent", () => { const once = patchPiTuiSource(SOURCE); const twice = patchPiTuiSource(once); assert.equal(twice, once); }); +test("Pi TUI patchers fail closed on unknown upstream layouts", () => { + assert.throws( + () => patchPiTuiSource("export class TUI {}"), + /Unsupported Pi TUI layout/, + ); + assert.throws( + () => patchPiEditorSource("export class Editor {}"), + /Unsupported Pi editor layout/, + ); + assert.throws( + () => patchPiInteractiveThemeSource("export function getEditorTheme() { return {}; }"), + /Unsupported Pi interactive theme layout/, + ); +}); + const EDITOR_SOURCE = ` import { getSegmenter, isPunctuationChar, isWhitespaceChar, truncateToWidth, visibleWidth } from "../utils.js"; @@ -166,6 +199,19 @@ test("patchPiEditorSource is idempotent", () => { assert.equal(twice, once); }); +test("patchPiEditorSource upgrades full fake-cursor resets without clearing the background", () => { + const source = [ + 'const styleInput = typeof this.theme.input === "function" ? this.theme.input : (text) => text;', + ' const cursor = `\\x1b[7m${firstGrapheme}\\x1b[0m`;', + ' const cursor = "\\x1b[7m \\x1b[0m";', + ].join("\n"); + const patched = patchPiEditorSource(source); + + assert.match(patched, /\\x1b\[27m/); + assert.doesNotMatch(patched, /\\x1b\[0m/); + assert.equal(patchPiEditorSource(patched), patched); +}); + test("patchPiInteractiveThemeSource gives editor input an explicit foreground", () => { const patched = patchPiInteractiveThemeSource(THEME_SOURCE); diff --git a/tests/pi-web-access-patch.test.ts b/tests/pi-web-access-patch.test.ts index e12b4911..88ae9648 100644 --- a/tests/pi-web-access-patch.test.ts +++ b/tests/pi-web-access-patch.test.ts @@ -17,6 +17,27 @@ test("patchPiWebAccessSource rewrites legacy Pi web-search config paths", () => assert.match(patched, /PI_WEB_SEARCH_CONFIG/); }); +test("patchPiWebAccessSource keeps current upstream config helpers on Feynman's exact config file", () => { + const input = [ + 'import { join } from "node:path";', + "export function getWebSearchConfigDir(): string {", + "\tif (process.env.PI_CODING_AGENT_DIR) return process.env.PI_CODING_AGENT_DIR;", + '\treturn "/tmp/.pi";', + "}", + "export function getWebSearchConfigPath(): string {", + '\treturn join(getWebSearchConfigDir(), "web-search.json");', + "}", + "", + ].join("\n"); + + const patched = patchPiWebAccessSource("utils.ts", input); + + assert.match(patched, /process\.env\.FEYNMAN_WEB_SEARCH_CONFIG\?\.trim\(\)/); + assert.match(patched, /process\.env\.PI_WEB_SEARCH_CONFIG\?\.trim\(\)/); + assert.match(patched, /configuredPath \|\| join\(getWebSearchConfigDir\(\), "web-search\.json"\)/); + assert.equal(patchPiWebAccessSource("utils.ts", patched), patched); +}); + test("patchPiWebAccessSource updates index.ts directory handling", () => { const input = [ 'import { existsSync, mkdirSync } from "node:fs";', @@ -234,3 +255,18 @@ test("patchPiWebAccessSource enforces a curator browser-connect deadline in cura const twice = patchPiWebAccessSource("curator-server.ts", patched); assert.equal(twice, patched); }); + +test("patchPiWebAccessSource keeps fetched PDF scratch files inside the project", () => { + const source = [ + 'import { join, basename } from "node:path";', + 'import { homedir } from "node:os";', + 'const DEFAULT_OUTPUT_DIR = join(homedir(), "Downloads");', + ].join("\n"); + + const patched = patchPiWebAccessSource("pdf-extract.ts", source); + + assert.match(patched, /FEYNMAN_FETCH_CACHE_DIR/); + assert.match(patched, /process\.cwd\(\).*\.feynman.*cache.*fetch-content/); + assert.doesNotMatch(patched, /homedir|Downloads/); + assert.equal(patchPiWebAccessSource("pdf-extract.ts", patched), patched); +}); diff --git a/tests/release-notes.test.ts b/tests/release-notes.test.ts index cbe74a53..ffb7dadf 100644 --- a/tests/release-notes.test.ts +++ b/tests/release-notes.test.ts @@ -1,4 +1,5 @@ import assert from "node:assert/strict"; +import { spawnSync } from "node:child_process"; import test from "node:test"; import { extractReleaseNotes, normalizeReleaseVersion } from "../scripts/lib/release-notes.mjs"; @@ -35,3 +36,13 @@ test("extractReleaseNotes returns only the requested release section", () => { test("extractReleaseNotes returns empty string for missing versions", () => { assert.equal(extractReleaseNotes("## v0.2.33\n\n- Existing.", "0.2.34"), ""); }); + +test("release-note extraction fails closed when the version section is missing", () => { + const result = spawnSync( + process.execPath, + ["scripts/extract-release-notes.mjs", "99.99.99"], + { cwd: process.cwd(), encoding: "utf8" }, + ); + assert.notEqual(result.status, 0); + assert.match(result.stderr, /RELEASES\.md has no section for v99\.99\.99/); +}); diff --git a/tests/release-workflows.test.ts b/tests/release-workflows.test.ts new file mode 100644 index 00000000..4bd69b55 --- /dev/null +++ b/tests/release-workflows.test.ts @@ -0,0 +1,132 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; + +const e2eWorkflow = readFileSync(".github/workflows/e2e.yml", "utf8"); +const publishWorkflow = readFileSync(".github/workflows/publish.yml", "utf8"); + +test("pull-request release gates validate the merge candidate", () => { + assert.match(e2eWorkflow, /pull_request:\s*\n\s+branches: \[main\]/); + assert.doesNotMatch(e2eWorkflow, /github\.event\.pull_request\.head\.sha/); + assert.match(e2eWorkflow, /name: Release candidate \(PR\)/); + assert.match(e2eWorkflow, /name: Candidate consumer \(\$\{\{ matrix\.os \}\}, Node \$\{\{ matrix\.node \}\}\)/); + assert.match(e2eWorkflow, /name: pr-npm-package/); + assert.match(e2eWorkflow, /node: "22\.22\.0"/); + assert.match(e2eWorkflow, /node: "25"/); + assert.match(e2eWorkflow, /name: Windows native installer \(PR\)/); + assert.match(e2eWorkflow, /shell: powershell/); + assert.match(e2eWorkflow, /shell: pwsh/); + assert.match(e2eWorkflow, /tarball_for_tar=\$\(cygpath -u "\$tarball"\)/); + assert.match(e2eWorkflow, /consumer=\$\(cygpath -u "\$consumer"\)/); + assert.match(e2eWorkflow, /runtime_archive=\$\(cygpath -u "\$runtime_archive"\)/); + assert.equal( + (e2eWorkflow.match(/scripts\/verify-windows-installer\.ps1/g) ?? []).length, + 2, + ); +}); + +test("PR and publish workflows require clean package and consumer audits", () => { + for (const workflow of [e2eWorkflow, publishWorkflow]) { + assert.match(workflow, /npm audit --omit=dev --prefix \.feynman\/npm/); + assert.match(workflow, /npm audit --omit=dev --prefix "\$consumer"/); + assert.match(workflow, /\.feynman\/runtime-workspace\.tgz/); + assert.match(workflow, /npm audit --omit=dev --prefix "\$runtime_audit\/npm"/); + assert.doesNotMatch( + workflow, + /npm audit --omit=dev --prefix\s+\\?\s*"\$consumer\/node_modules\/@companion-ai\/feynman\/\.feynman\/npm"/, + ); + assert.match(workflow, /npm pack --dry-run --json/); + assert.match(workflow, /verify-package-artifact\.mjs/); + assert.match(workflow, /verify-package-budget\.mjs/); + assert.match(workflow, /git status --porcelain --untracked-files=all/); + } +}); + +test("publish uses the exact verified tarball after native bundles pass", () => { + assert.match(publishWorkflow, /concurrency:\s*\n\s+group: publish-/); + assert.match(publishWorkflow, /name: npm-package/); + assert.match(publishWorkflow, /name: npm-package\s*\n\s+path: npm-package/); + assert.match(publishWorkflow, /npx npm@11\.18\.0 publish "\$tarball" --access public --provenance/); + assert.match( + publishWorkflow, + /publish-npm:\s*\n\s+needs:\s*\n\s+- version-check\s*\n\s+- verify\s*\n\s+- verify-package-consumers\s*\n\s+- build-native-bundles/, + ); + assert.match( + publishWorkflow, + /build-native-bundles:\s*\n\s+needs:\s*\n\s+- version-check\s*\n\s+- verify\s*\n\s+- verify-package-consumers/, + ); + assert.match(publishWorkflow, /verify-package-consumers:/); + for (const os of ["ubuntu-latest", "macos-14", "windows-latest"]) { + assert.match(publishWorkflow, new RegExp(`- os: ${os}`)); + } + for (const nodeVersion of ["22.22.0", "24.18.0", "25"]) { + assert.match(publishWorkflow, new RegExp(`node: "${nodeVersion.replace(/\./g, "\\.")}"`)); + } + assert.match(publishWorkflow, /needs\.build-native-bundles\.result == 'success'/); + assert.match(publishWorkflow, /needs\.verify-package-consumers\.result == 'success'/); + assert.match(publishWorkflow, /dist\.integrity/); + assert.match(publishWorkflow, /dist\.tarball/); + assert.match(publishWorkflow, /SHOULD_PUBLISH_NPM/); + assert.match(publishWorkflow, /needs\.verify\.outputs\.package_integrity/); + assert.doesNotMatch( + publishWorkflow, + /if \[ "\$\{\{ needs\.version-check\.outputs\.should_publish_npm \}\}" = "true" \]/, + ); +}); + +test("GitHub release waits for verification, native bundles, and npm publication", () => { + assert.match( + publishWorkflow, + /release-github:\s*\n\s+needs:\s*\n\s+- version-check\s*\n\s+- verify\s*\n\s+- publish-npm\s*\n\s+- build-native-bundles/, + ); + assert.match(publishWorkflow, /needs\.verify\.result == 'success'/); + assert.match(publishWorkflow, /needs\.publish-npm\.result == 'success'/); + assert.match(publishWorkflow, /always\(\)/); + assert.match(publishWorkflow, /pattern: native-\*/); + assert.doesNotMatch(publishWorkflow, /gh release view "v\$VERSION" >\/dev\/null 2>&1/); + assert.match(publishWorkflow, /release_exists=true/); + assert.match(publishWorkflow, /release_exists=false/); + assert.match(publishWorkflow, /--draft/); + assert.match(publishWorkflow, /Staged release asset mismatch/); +}); + +test("version reconciliation and post-publish verification cover all release surfaces", () => { + for (const id of ["linux-x64", "linux-arm64", "darwin-x64", "darwin-arm64", "win32-x64"]) { + assert.match(publishWorkflow, new RegExp(`feynman-.*-${id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`)); + } + assert.match(publishWorkflow, /SHA256SUMS/); + assert.match(publishWorkflow, /sha256sum -c SHA256SUMS/); + assert.match(publishWorkflow, /SHA256SUMS entry mismatch/); + assert.match(publishWorkflow, /assets\.length === expected\.size/); + assert.match(publishWorkflow, /Number\(asset\.size\) > 0/); + assert.match(publishWorkflow, /verify-published-state:/); + assert.match(publishWorkflow, /gh release download "v\$VERSION"/); + assert.match(publishWorkflow, /npm install --prefix "\$consumer".*"@companion-ai\/feynman@\$VERSION"/); + assert.match(publishWorkflow, /unzip -t/); + assert.match(publishWorkflow, /targetCommitish/); + assert.match(publishWorkflow, /asset\.digest/); + assert.match( + publishWorkflow, + /repos\/\$GITHUB_REPOSITORY\/compare\/\$RELEASE_TARGET\.\.\.\$GITHUB_SHA/, + ); + assert.match(publishWorkflow, /identical \| ahead/); + assert.match( + publishWorkflow, + /npm version \$LOCAL belongs to \$PUBLISHED_GIT_HEAD, but GitHub release v\$LOCAL targets \$RELEASE_TARGET/, + ); + assert.doesNotMatch( + publishWorkflow, + /\[ -z "\$PUBLISHED_GIT_HEAD" \] \|\| \[ "\$PUBLISHED_GIT_HEAD" != "\$GITHUB_SHA" \]/, + ); + assert.doesNotMatch( + publishWorkflow, + /npm view "@companion-ai\/feynman@\$VERSION" version 2>\/dev\/null \|\| true/, + ); + assert.match(publishWorkflow, /node-version-file: \.nvmrc/); + assert.match(publishWorkflow, /npx npm@11\.18\.0 publish/); + assert.match(publishWorkflow, /Windows native launcher failed --help/); + assert.doesNotMatch(publishWorkflow, /npm@latest/); + for (const workflow of [e2eWorkflow, publishWorkflow]) { + assert.doesNotMatch(workflow, /uses: actions\/[^@\s]+@v\d/); + } +}); diff --git a/tests/runtime-workspace-integrity.test.ts b/tests/runtime-workspace-integrity.test.ts new file mode 100644 index 00000000..a9e1439a --- /dev/null +++ b/tests/runtime-workspace-integrity.test.ts @@ -0,0 +1,239 @@ +import assert from "node:assert/strict"; +import { appendFileSync, linkSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { spawnSync } from "node:child_process"; +import test from "node:test"; + +import { + computeRuntimeArchiveTreeHash, + computeRuntimeInputHash, + computeRuntimeTreeHash, + readArchiveEntry, + RUNTIME_INPUT_FILES, + runtimeArchiveMatches, + runtimeManifestPackagesMatch, + workspacePackagesMatch, + writeFileSha256, +} from "../scripts/lib/runtime-workspace-integrity.mjs"; +import { createDeterministicTarGz } from "../scripts/lib/deterministic-archive.mjs"; + +test("runtime workspace integrity checks installed versions and the exact archive digest", () => { + const root = mkdtempSync(join(tmpdir(), "feynman-runtime-integrity-")); + const feynmanDir = join(root, ".feynman"); + const workspace = join(feynmanDir, "npm"); + const nodeModules = join(workspace, "node_modules"); + const packageRoot = join(nodeModules, "@scope", "runtime"); + const manifestPath = join(workspace, ".runtime-manifest.json"); + const lockPath = join(feynmanDir, "runtime-package-lock.json"); + const archivePath = join(feynmanDir, "runtime-workspace.tgz"); + const digestPath = join(feynmanDir, "runtime-workspace.sha256"); + const inputPath = join(root, "runtime-input.txt"); + const inputFiles = ["runtime-input.txt"]; + const specs = ["@scope/runtime@1.2.3"]; + + mkdirSync(packageRoot, { recursive: true }); + writeFileSync(join(packageRoot, "package.json"), JSON.stringify({ + name: "@scope/runtime", + version: "1.2.3", + })); + const lockSource = JSON.stringify({ + lockfileVersion: 3, + packages: { + "": { dependencies: { "@scope/runtime": "1.2.3" } }, + "node_modules/@scope/runtime": { version: "1.2.3" }, + }, + }) + "\n"; + writeFileSync(join(workspace, "package-lock.json"), lockSource); + writeFileSync(lockPath, lockSource); + writeFileSync(inputPath, "runtime input\n"); + const runtimeInputHash = computeRuntimeInputHash(root, inputFiles); + writeFileSync(manifestPath, JSON.stringify({ + packageSpecs: specs, + runtimeInputHash, + runtimeTreeHash: computeRuntimeTreeHash(workspace), + workspaceTreeHash: computeRuntimeTreeHash(workspace), + }) + "\n"); + + const packed = spawnSync("tar", ["-czf", archivePath, "-C", feynmanDir, "npm"], { + env: { ...process.env, COPYFILE_DISABLE: "1" }, + }); + assert.equal(packed.status, 0); + writeFileSha256(archivePath, digestPath); + + assert.equal(workspacePackagesMatch(nodeModules, specs), true); + assert.equal(runtimeArchiveMatches({ + archivePath, + digestPath, + lockPath, + manifestPath, + packageSpecs: specs, + runtimeInputHash, + }), true); + + appendFileSync(inputPath, "changed\n"); + assert.equal(runtimeArchiveMatches({ + archivePath, + digestPath, + lockPath, + manifestPath, + packageSpecs: specs, + runtimeInputHash: computeRuntimeInputHash(root, inputFiles), + }), false); + + appendFileSync(archivePath, "tampered"); + assert.equal(runtimeArchiveMatches({ + archivePath, + digestPath, + lockPath, + manifestPath, + packageSpecs: specs, + runtimeInputHash, + }), false); + assert.equal(workspacePackagesMatch(nodeModules, ["@scope/runtime@9.9.9"]), false); +}); + +test("runtime manifest verification checks bundled packages beyond configured extensions", () => { + const root = mkdtempSync(join(tmpdir(), "feynman-runtime-manifest-")); + const writePackage = (name: string, version: string) => { + const packagePath = join(root, ...name.split("/")); + mkdirSync(packagePath, { recursive: true }); + writeFileSync( + join(packagePath, "package.json"), + `${JSON.stringify({ name, version })}\n`, + "utf8", + ); + }; + writePackage("pi-subagents", "0.37.2"); + writePackage("@earendil-works/pi-coding-agent", "0.79.1"); + + const manifestSpecs = [ + "pi-subagents@0.37.2", + "@earendil-works/pi-coding-agent@0.82.1", + ]; + assert.equal( + runtimeManifestPackagesMatch(root, manifestSpecs, ["pi-subagents@0.37.2"]), + false, + ); + + writePackage("@earendil-works/pi-coding-agent", "0.82.1"); + assert.equal( + runtimeManifestPackagesMatch(root, manifestSpecs, ["pi-subagents@0.37.2"]), + true, + ); + assert.equal( + runtimeManifestPackagesMatch(root, manifestSpecs, ["missing-package@1.0.0"]), + false, + ); +}); + +test("runtime archive integrity rejects a lock that differs from the committed graph", () => { + const root = mkdtempSync(join(tmpdir(), "feynman-runtime-lock-integrity-")); + const feynmanDir = join(root, ".feynman"); + const workspace = join(feynmanDir, "npm"); + const packageRoot = join(workspace, "node_modules", "runtime"); + const manifestPath = join(workspace, ".runtime-manifest.json"); + const lockPath = join(feynmanDir, "runtime-package-lock.json"); + const archivePath = join(feynmanDir, "runtime-workspace.tgz"); + const digestPath = join(feynmanDir, "runtime-workspace.sha256"); + const inputPath = join(root, "runtime-input.txt"); + const specs = ["runtime@1.0.0"]; + + mkdirSync(packageRoot, { recursive: true }); + writeFileSync(join(packageRoot, "package.json"), JSON.stringify({ version: "1.0.0" })); + writeFileSync(join(workspace, "package-lock.json"), '{"lockfileVersion":3}\n'); + writeFileSync(lockPath, '{"lockfileVersion":3,"packages":{}}\n'); + writeFileSync(inputPath, "runtime input\n"); + const runtimeInputHash = computeRuntimeInputHash(root, ["runtime-input.txt"]); + writeFileSync(manifestPath, JSON.stringify({ + packageSpecs: specs, + runtimeInputHash, + runtimeTreeHash: computeRuntimeTreeHash(workspace), + workspaceTreeHash: computeRuntimeTreeHash(workspace), + }) + "\n"); + assert.equal(spawnSync("tar", ["-czf", archivePath, "-C", feynmanDir, "npm"], { + env: { ...process.env, COPYFILE_DISABLE: "1" }, + }).status, 0); + writeFileSha256(archivePath, digestPath); + + assert.equal(runtimeArchiveMatches({ + archivePath, + digestPath, + lockPath, + manifestPath, + packageSpecs: specs, + runtimeInputHash, + }), false); +}); + +test("runtime archive tree hashes normalize tar hardlinks to file contents", async () => { + const root = mkdtempSync(join(tmpdir(), "feynman-runtime-hardlink-integrity-")); + const workspace = join(root, "npm"); + const original = join(workspace, "original.txt"); + const hardlink = join(workspace, "hardlink.txt"); + const archivePath = join(root, "runtime-workspace.tgz"); + + mkdirSync(workspace, { recursive: true }); + writeFileSync(original, "shared bytes\n"); + linkSync(original, hardlink); + await createDeterministicTarGz(workspace, archivePath); + + assert.equal( + computeRuntimeArchiveTreeHash(archivePath), + computeRuntimeTreeHash(workspace), + ); +}); + +test("runtime archive entries are read without an external tar executable", async () => { + const root = mkdtempSync(join(tmpdir(), "feynman-runtime-entry-")); + const workspace = join(root, "npm"); + const archivePath = join(root, "runtime-workspace.tgz"); + + mkdirSync(workspace, { recursive: true }); + writeFileSync(join(workspace, "package-lock.json"), '{"lockfileVersion":3}\n'); + await createDeterministicTarGz(workspace, archivePath); + + const originalPath = process.env.PATH; + process.env.PATH = ""; + try { + assert.equal( + readArchiveEntry(archivePath, "npm/package-lock.json"), + '{"lockfileVersion":3}\n', + ); + } finally { + process.env.PATH = originalPath; + } +}); + +test("runtime input hashes are independent of the checkout root", () => { + const left = mkdtempSync(join(tmpdir(), "feynman-runtime-input-left-")); + const right = mkdtempSync(join(tmpdir(), "feynman-runtime-input-right-")); + const inputFiles = ["scripts/prepare-runtime-workspace.mjs", ".feynman/settings.json"]; + for (const root of [left, right]) { + mkdirSync(join(root, "scripts"), { recursive: true }); + mkdirSync(join(root, ".feynman"), { recursive: true }); + writeFileSync(join(root, "scripts", "prepare-runtime-workspace.mjs"), "same source\n"); + writeFileSync(join(root, ".feynman", "settings.json"), '{"same":true}\n'); + } + + assert.equal( + computeRuntimeInputHash(left, inputFiles), + computeRuntimeInputHash(right, inputFiles), + ); +}); + +test("runtime manifests preserve separate workspace and archive tree hashes", () => { + const source = readFileSync( + join(process.cwd(), "scripts", "prepare-runtime-workspace.mjs"), + "utf8", + ); + assert.match(source, /workspaceTreeHash/); + assert.match(source, /computeRuntimeArchiveTreeHash\(workspaceArchivePath\)/); + assert.match(source, /writeManifest\(packageSpecs, archiveTreeHash\)/); +}); + +test("runtime input hashes use only files shipped in installed packages", () => { + assert.equal(RUNTIME_INPUT_FILES.includes("package-lock.json"), false); + assert.equal(RUNTIME_INPUT_FILES.includes(".feynman/runtime-package-lock.json"), true); + assert.equal(RUNTIME_INPUT_FILES.includes("package.json"), true); +}); diff --git a/tests/runtime-workspace-lock.test.ts b/tests/runtime-workspace-lock.test.ts new file mode 100644 index 00000000..6ebbfee5 --- /dev/null +++ b/tests/runtime-workspace-lock.test.ts @@ -0,0 +1,71 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; +import test from "node:test"; + +const root = process.cwd(); + +test("vendored runtime uses a committed exact dependency lock", () => { + const settings = JSON.parse( + readFileSync(join(root, ".feynman", "settings.json"), "utf8"), + ) as { packages: string[] }; + const rootLock = JSON.parse( + readFileSync(join(root, "package-lock.json"), "utf8"), + ) as { packages: Record }; + const runtimeLock = JSON.parse( + readFileSync(join(root, ".feynman", "runtime-package-lock.json"), "utf8"), + ) as { + lockfileVersion: number; + packages: Record; version?: string }>; + }; + + const expected = Object.fromEntries(settings.packages.map((source) => { + const spec = source.slice("npm:".length); + const match = spec.match(/^(@?[^@]+(?:\/[^@]+)?)@(.+)$/); + assert.ok(match, `runtime package is not exact: ${source}`); + return [match[1], match[2]]; + })); + for (const packageName of [ + "@earendil-works/pi-agent-core", + "@earendil-works/pi-ai", + "@earendil-works/pi-coding-agent", + "@earendil-works/pi-tui", + "brace-expansion", + "typebox", + ]) { + const version = rootLock.packages[`node_modules/${packageName}`]?.version; + if (version) expected[packageName] = version; + } + + assert.equal(runtimeLock.lockfileVersion, 3); + assert.deepEqual(runtimeLock.packages[""].dependencies, expected); + assert.equal( + runtimeLock.packages["node_modules/@hono/node-server"]?.version, + "2.0.12", + ); + for (const [packagePath, entry] of Object.entries(runtimeLock.packages)) { + if (packagePath.endsWith("/pi-coding-agent/node_modules/brace-expansion")) { + assert.equal(entry.version, "5.0.8"); + } + } +}); + +test("runtime build hashes its lock and pruning logic and installs with npm ci", () => { + const source = readFileSync( + join(root, "scripts", "prepare-runtime-workspace.mjs"), + "utf8", + ); + assert.match(source, /runtime-package-lock\.json/); + assert.match(source, /prune-runtime-deps\.mjs/); + assert.match(source, /"ci"/); + assert.match(source, /--refresh-lock/); + assert.match(source, /--save-exact/); + assert.match(source, /workspacePackagesMatch/); + assert.match(source, /runtimeArchiveMatches/); + assert.match(source, /computeRuntimeInputHash/); + assert.match(source, /computeRuntimeTreeHash/); + assert.match(source, /filesMatch/); + assert.match(source, /runtime-workspace\.sha256/); + assert.match(source, /createDeterministicTarGz/); + assert.match(source, /--rebuild/); +}); diff --git a/tests/thinking-command.test.ts b/tests/thinking-command.test.ts new file mode 100644 index 00000000..ffd46b58 --- /dev/null +++ b/tests/thinking-command.test.ts @@ -0,0 +1,100 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { registerThinkingCommand } from "../extensions/research-tools/thinking.js"; + +type RegisteredCommand = { + getArgumentCompletions?: (prefix: string) => Array<{ value: string; label: string }> | null; + handler: (args: string, ctx: any) => Promise; +}; + +function createHarness(initial = "medium", thinkingLevelMap?: Record) { + let active = initial; + const registered = new Map(); + const notifications: Array<{ message: string; level: string }> = []; + const selections: Array<{ title: string; options: string[] }> = []; + let selection: string | undefined; + const pi = { + getThinkingLevel: () => active, + setThinkingLevel: (level: string) => { + active = level; + }, + registerCommand: (name: string, command: RegisteredCommand) => { + registered.set(name, command); + }, + }; + const ctx = { + hasUI: true, + model: { + reasoning: true, + thinkingLevelMap, + }, + ui: { + notify: (message: string, level: string) => notifications.push({ message, level }), + select: async (title: string, options: string[]) => { + selections.push({ title, options }); + return selection; + }, + }, + }; + + registerThinkingCommand(pi as any); + return { + command: registered.get("thinking")!, + ctx, + getActive: () => active, + notifications, + selections, + setSelection: (value: string | undefined) => { + selection = value; + }, + }; +} + +test("/thinking sets an explicit supported level and offers completions", async () => { + const harness = createHarness(); + + await harness.command.handler("high", harness.ctx); + + assert.equal(harness.getActive(), "high"); + assert.deepEqual(harness.notifications, [{ message: "Thinking level set to high.", level: "info" }]); + assert.deepEqual(harness.command.getArgumentCompletions?.("m"), [ + { value: "minimal", label: "minimal" }, + { value: "medium", label: "medium" }, + { value: "max", label: "max" }, + ]); +}); + +test("/thinking without an argument opens a current-aware picker", async () => { + const harness = createHarness("low", { xhigh: "xhigh", max: "max" }); + harness.setSelection("max"); + + await harness.command.handler("", harness.ctx); + + assert.equal(harness.getActive(), "max"); + assert.equal(harness.selections[0]?.title, "Thinking level (current: low)"); + assert.ok(harness.selections[0]?.options.includes("low (current)")); + assert.ok(harness.selections[0]?.options.includes("max")); +}); + +test("/thinking picker only shows levels supported by the active model", async () => { + const harness = createHarness("high"); + + await harness.command.handler("", harness.ctx); + + assert.deepEqual(harness.selections[0]?.options, ["off", "minimal", "low", "medium", "high (current)"]); +}); + +test("/thinking reports current state without UI and rejects invalid levels", async () => { + const harness = createHarness("medium"); + harness.ctx.hasUI = false; + + await harness.command.handler("", harness.ctx); + await harness.command.handler("extreme", harness.ctx); + + assert.deepEqual(harness.notifications, [ + { message: "Thinking level: medium", level: "info" }, + { message: "Use off, minimal, low, medium, high, xhigh, or max.", level: "error" }, + ]); + assert.equal(harness.getActive(), "medium"); +}); diff --git a/tests/workbench-new-sessions.test.ts b/tests/workbench-new-sessions.test.ts index 39bfd508..34834dc7 100644 --- a/tests/workbench-new-sessions.test.ts +++ b/tests/workbench-new-sessions.test.ts @@ -118,6 +118,19 @@ test("workbench state exposes Feynman model status for the model menu", async () assert.equal(payload.modelStatus?.current, "openai/gpt-5.5"); assert.ok(Array.isArray(payload.modelStatus?.availableModels)); assert.ok(Array.isArray(payload.modelStatus?.guidance)); + + writeFileSync(authPath, JSON.stringify({ openai: { type: "api_key", key: "openai-test-key" } }, null, 2) + "\n", "utf8"); + const refreshedResponse = await fetch(`${handle.url}api/state`, { + headers: { cookie: "feynman_workbench=test-token" }, + }); + assert.equal(refreshedResponse.status, 200); + const refreshedPayload = await refreshedResponse.json() as { + modelStatus?: { availableModels: string[] }; + }; + assert.ok( + refreshedPayload.modelStatus?.availableModels.some((spec) => spec.startsWith("openai/")), + "model status must refresh after auth changes without restarting the workbench", + ); } finally { await handle.close(); rmSync(root, { recursive: true, force: true }); diff --git a/website/.astro/content.d.ts b/website/.astro/content.d.ts index 93c5f35f..d6bc4c06 100644 --- a/website/.astro/content.d.ts +++ b/website/.astro/content.d.ts @@ -85,6 +85,10 @@ declare module 'astro:content' { entry: DataEntryMap[C][string], ): Promise; + export function render( + entry: import('astro').LiveDataEntry>, + ): Promise; + export function reference< C extends | keyof DataEntryMap diff --git a/website/package-lock.json b/website/package-lock.json index 745ae89c..eab535db 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -8,12 +8,12 @@ "name": "website", "version": "0.0.1", "dependencies": { - "@astrojs/react": "^5.0.7", + "@astrojs/react": "^6.0.1", "@fontsource-variable/ibm-plex-sans": "^5.2.8", "@tailwindcss/vite": "^4.3.1", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "astro": "^6.4.4", + "astro": "^7.1.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^1.18.0", @@ -39,7 +39,7 @@ "typescript-eslint": "^8.60.1" }, "engines": { - "node": ">=20.19.0 <25" + "node": ">=22.22.0 <26" } }, "node_modules/@astrojs/check": { @@ -68,10 +68,198 @@ "dev": true, "license": "MIT" }, + "node_modules/@astrojs/compiler-binding": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding/-/compiler-binding-0.3.1.tgz", + "integrity": "sha512-DaAUj29AIBU2XdJ8uwcab8lW5O2pk9pY8AXkcMw0sw77nVa3oeTYRcO+Dvbbpoexf6ThMc0FMWYCQ/wN1/T7oQ==", + "license": "MIT", + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@astrojs/compiler-binding-darwin-arm64": "0.3.1", + "@astrojs/compiler-binding-darwin-x64": "0.3.1", + "@astrojs/compiler-binding-linux-arm64-gnu": "0.3.1", + "@astrojs/compiler-binding-linux-arm64-musl": "0.3.1", + "@astrojs/compiler-binding-linux-x64-gnu": "0.3.1", + "@astrojs/compiler-binding-linux-x64-musl": "0.3.1", + "@astrojs/compiler-binding-wasm32-wasi": "0.3.1", + "@astrojs/compiler-binding-win32-arm64-msvc": "0.3.1", + "@astrojs/compiler-binding-win32-x64-msvc": "0.3.1" + } + }, + "node_modules/@astrojs/compiler-binding-darwin-arm64": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-darwin-arm64/-/compiler-binding-darwin-arm64-0.3.1.tgz", + "integrity": "sha512-IEmEF2fUIlTHtpeE/isyEGVOB14cEyh/LZOFYt6wn3jNyVpdC8aR5OZ+RzFUR/f+8ZDM1LaMwZKvoA7eMyJeFw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-darwin-x64": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-darwin-x64/-/compiler-binding-darwin-x64-0.3.1.tgz", + "integrity": "sha512-GF2kIxjpPDLsn94zbZNMsxEmkU828QqnmM7kiQJnaooS3jmI+I7kk6+oI6EpwOsK3femCMdcm+wmOsEqtGrmjQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-linux-arm64-gnu": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-arm64-gnu/-/compiler-binding-linux-arm64-gnu-0.3.1.tgz", + "integrity": "sha512-XJL3SDmOtVrqFhCirNcHwE91+IesJqlgNo23I4qW9QUYfwzm/TBZuH61fgqsb1ttgR1mMYz6ooPWs0JDhwMqpQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-linux-arm64-musl": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-arm64-musl/-/compiler-binding-linux-arm64-musl-0.3.1.tgz", + "integrity": "sha512-xqE8BVbDoBueK/B47w30PtkVofUWJKGkwoMVE+EOMLf11rnoANxIAdA9FPqY+rng4oNI5ndHGsri1yPj2k8vZQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-linux-x64-gnu": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-x64-gnu/-/compiler-binding-linux-x64-gnu-0.3.1.tgz", + "integrity": "sha512-1y0StU1qiCuDFH3rmbRJXcxdfHxFPrES1Rd+RLffosvUR7I2cH5SF5SFnBN9vXpzpkmyElZm3Yr47iJBPN7vVA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-linux-x64-musl": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-x64-musl/-/compiler-binding-linux-x64-musl-0.3.1.tgz", + "integrity": "sha512-16q0fYf7kpbmdObZEeZJEup8hQv/whgNwVjrSvT8umrKwLDSnNIWiQpm09lQQu6bweZB0XyIvHwlPitvJhC+hg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-wasm32-wasi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-wasm32-wasi/-/compiler-binding-wasm32-wasi-0.3.1.tgz", + "integrity": "sha512-cB456shIwDv/PrVT+2QG7LFndpHkVge5HjqADKZgGaAc9JHVktCtjSrcdkRQ+3tbkPazNKaTLRjXLIiz2NIx9g==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@astrojs/compiler-binding-win32-arm64-msvc": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-win32-arm64-msvc/-/compiler-binding-win32-arm64-msvc-0.3.1.tgz", + "integrity": "sha512-ur/9+If/yTE69mmeX5MqSZndL0HOyx67GeNZUy3N7wVdWpLz9UTJXwyWS4UR2PUQHitghjsM5xoX0Ge56WRVQQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-win32-x64-msvc": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-win32-x64-msvc/-/compiler-binding-win32-x64-msvc-0.3.1.tgz", + "integrity": "sha512-k0W+kDBzDkNZOqu4kElDvCOIbKw5Ut9S1WZ1Krj3KTgNuBERNKXsMMsRLLcbgfdMdbe7bTekQLshZrrvmYpmwA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-rs": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-rs/-/compiler-rs-0.3.1.tgz", + "integrity": "sha512-aT7xkgsbNoS6nriY5qKpbihK43slFHO41iqgHCTdOvn1ifaQxLCc5yXy+6GzAtiafoaC1zA7OwVXCXMsvUZOkg==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler-binding": "0.3.1" + }, + "engines": { + "node": ">=22.12.0" + } + }, "node_modules/@astrojs/internal-helpers": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.10.0.tgz", - "integrity": "sha512-Ry2R3VPeIN4uPCSA4xQc+e+vsJXkalKpEbDc07hV+a/o5Bs2N/s/uDcPJH/05L19DKh9tAy7e6JM3YZ6Cxfezw==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.10.1.tgz", + "integrity": "sha512-5phcroT/vmOOrYuuAxtkbPixy5hePtlz9i8K4OeDv3dNK6/UQRuXPOSRTxIOBbUY5Sonw2UaxjbuVc43Mcir6Q==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.4", @@ -126,29 +314,17 @@ } } }, - "node_modules/@astrojs/markdown-remark": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-7.2.0.tgz", - "integrity": "sha512-+YxmVQu1Bd+MFfSzjq1rOJvD9+nIOJzz5YIIhdIH01RrxRkKbyKoEgyIqP3yv51MhzMDgd79QaPv+kCVPT8vHw==", + "node_modules/@astrojs/markdown-satteri": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-satteri/-/markdown-satteri-0.3.4.tgz", + "integrity": "sha512-6Lvt/bQZEBW+zzdhPblvfZEy5PGEYJaUsUqaCgwHeRPxZJL1gc9I+DRLKWJjjYTWDzVUTzXlMq4WwSK+X34CVw==", "license": "MIT", "dependencies": { - "@astrojs/internal-helpers": "0.10.0", + "@astrojs/internal-helpers": "0.10.1", "@astrojs/prism": "4.0.2", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", - "hast-util-to-text": "^4.0.2", - "mdast-util-definitions": "^6.0.0", - "rehype-raw": "^7.0.0", - "rehype-stringify": "^10.0.1", - "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.1.2", - "remark-smartypants": "^3.0.2", - "unified": "^11.0.5", - "unist-util-remove-position": "^5.0.0", - "unist-util-visit": "^5.1.0", - "unist-util-visit-parents": "^6.0.2", - "vfile": "^6.0.3" + "satteri": "^0.9.1" } }, "node_modules/@astrojs/prism": { @@ -164,16 +340,16 @@ } }, "node_modules/@astrojs/react": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@astrojs/react/-/react-5.0.7.tgz", - "integrity": "sha512-N9cCoxvnLWaP+AK1Fv4e5Mc7ktnVTpSo2nWLwvD9Ohr1dJKygwrTSm9yatqoahgb1A5Kwjg/rT2shRiIVdn3aw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@astrojs/react/-/react-6.0.1.tgz", + "integrity": "sha512-Afs1sEm72P2plDnrOGxmIteJ7bjx/VqxlcaQLNip5eHJ5tIvKUORQetC9UKcvgwKnj51t60HWl5mOANkOsWs4w==", "license": "MIT", "dependencies": { - "@astrojs/internal-helpers": "0.10.0", + "@astrojs/internal-helpers": "0.10.1", "@vitejs/plugin-react": "^5.2.0", "devalue": "^5.8.1", "ultrahtml": "^1.6.0", - "vite": "^7.3.2" + "vite": "^8.0.13" }, "engines": { "node": ">=22.12.0" @@ -186,16 +362,15 @@ } }, "node_modules/@astrojs/telemetry": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.2.tgz", - "integrity": "sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.3.tgz", + "integrity": "sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ==", "license": "MIT", "dependencies": { "ci-info": "^4.4.0", "dset": "^3.1.4", "is-docker": "^4.0.0", - "is-wsl": "^3.1.1", - "which-pm-runs": "^1.1.0" + "package-manager-detector": "^1.6.0" }, "engines": { "node": "18.20.8 || ^20.3.0 || >=22.0.0" @@ -646,6 +821,151 @@ "node": ">=6.9.0" } }, + "node_modules/@bruits/satteri-darwin-arm64": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-darwin-arm64/-/satteri-darwin-arm64-0.9.5.tgz", + "integrity": "sha512-iw4nZgx9v30lWo/MTngQqi1pI78KI0DnkSm+lVJGYdmPLgAyDNJigVhpG42/Iq55A6c1Ll8q66ljyyRiQUxwow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@bruits/satteri-darwin-x64": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-darwin-x64/-/satteri-darwin-x64-0.9.5.tgz", + "integrity": "sha512-6T26Z5Kf3cFW2PSlk9p7zT7yVxvuBSiJvYyz9u8KjYwMTqZyIDOj2wDyNpxKV4+6yUVG7rddq2QwvG/8LJA2+Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@bruits/satteri-linux-arm64-gnu": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-linux-arm64-gnu/-/satteri-linux-arm64-gnu-0.9.5.tgz", + "integrity": "sha512-u51id17uJwNEMK9nBlICsq6U31c+XVqQueVBkwRIzZG+gMpS8TOJctt5h5Wz33Z8xnMdTd+adtACVz0yHgGuOA==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@bruits/satteri-linux-arm64-musl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-linux-arm64-musl/-/satteri-linux-arm64-musl-0.9.5.tgz", + "integrity": "sha512-v39HxiwGC5Rqm01HksP6+5Y+xKLPlsuVFgIgpEAo+SiQ22c+mJVhS3u7Z6ePAKdhL5NJoK1xq70kLz3L13AhpQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@bruits/satteri-linux-x64-gnu": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-linux-x64-gnu/-/satteri-linux-x64-gnu-0.9.5.tgz", + "integrity": "sha512-F3uO8uFp3pAP5ZGXttwvh57GS7s0lL953tnNdyI2gRyP4kOOkp6pyGojNJzCjkDvWI2Cvb9iNrKok3aqQPauAw==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@bruits/satteri-linux-x64-musl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-linux-x64-musl/-/satteri-linux-x64-musl-0.9.5.tgz", + "integrity": "sha512-bicEqglLlz++mWyADaZoP0JY20s4vDfLjaPYgQqC+NI4zZLTOOg1T4GB8aqtc822Pqji8SQBmSrTb7CrP8i08Q==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@bruits/satteri-wasm32-wasi": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-wasm32-wasi/-/satteri-wasm32-wasi-0.9.5.tgz", + "integrity": "sha512-zauAuMwfPnKPUkd4AFixRFpXdgKwP2mKgxrIIo2gJzW0/ZneF9dbHnLkojSpaBnCCp7VUL1hIi5WWZvB1CqmAQ==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@bruits/satteri-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@bruits/satteri-win32-arm64-msvc": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-win32-arm64-msvc/-/satteri-win32-arm64-msvc-0.9.5.tgz", + "integrity": "sha512-SrfE7NEsgZjBvU3c+RR6oQRu0ToXY5uVJEbieXEF0YTctIV2zAVlbaMjWLts074QCgh3a+XHWkR/lWh2VH2LUg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@bruits/satteri-win32-x64-msvc": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-win32-x64-msvc/-/satteri-win32-x64-msvc-0.9.5.tgz", + "integrity": "sha512-5Kw9ZAtTGS8WHizyn+CJhjjfIQrw+7jcZodpmpXJjefnO15M8UexIi6JR2E5thyvsmHyhL6ZDDMUNR4bKJPd4g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@capsizecss/unpack": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.0.tgz", @@ -918,10 +1238,32 @@ "dev": true, "license": "MIT" }, + "node_modules/@emnapi/core": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", + "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, "node_modules/@emnapi/runtime": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.0.tgz", - "integrity": "sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "license": "MIT", "optional": true, "dependencies": { @@ -1520,12 +1862,12 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.0.12.tgz", + "integrity": "sha512-eWpQYr67tqJLeaSUl0Q+TquuYfUdTibpOJlUMV2FfUP7+KqCC5TufnwnlXL6mobZBJbGAYRd7ZvEBDCbLInjhg==", "license": "MIT", "engines": { - "node": ">=18.14.1" + "node": ">=20" }, "peerDependencies": { "hono": "^4" @@ -1608,9 +1950,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz", + "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==", "cpu": [ "arm64" ], @@ -1620,19 +1962,19 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" + "@img/sharp-libvips-darwin-arm64": "1.3.2" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz", + "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==", "cpu": [ "x64" ], @@ -1642,35 +1984,54 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" + "@img/sharp-libvips-darwin-x64": "1.3.2" } }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz", + "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==", + "license": "Apache-2.0", "optional": true, "os": [ - "darwin" + "freebsd" ], - "funding": { - "url": "https://opencollective.com/libvips" + "dependencies": { + "@img/sharp-wasm32": "0.35.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz", + "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz", + "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==", "cpu": [ "x64" ], @@ -1684,12 +2045,15 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz", + "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==", "cpu": [ "arm" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1700,12 +2064,15 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz", + "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1716,12 +2083,15 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz", + "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==", "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1732,12 +2102,15 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz", + "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==", "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1748,12 +2121,15 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz", + "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1764,12 +2140,15 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz", + "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1780,12 +2159,15 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz", + "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1796,12 +2178,15 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz", + "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1812,204 +2197,244 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz", + "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==", "cpu": [ "arm" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" + "@img/sharp-libvips-linux-arm": "1.3.2" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz", + "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" + "@img/sharp-libvips-linux-arm64": "1.3.2" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz", + "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==", "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" + "@img/sharp-libvips-linux-ppc64": "1.3.2" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz", + "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==", "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" + "@img/sharp-libvips-linux-riscv64": "1.3.2" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz", + "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" + "@img/sharp-libvips-linux-s390x": "1.3.2" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz", + "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" + "@img/sharp-libvips-linux-x64": "1.3.2" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz", + "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.2" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz", + "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + "@img/sharp-libvips-linuxmusl-x64": "1.3.2" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz", + "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz", + "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==", "cpu": [ "wasm32" ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "license": "Apache-2.0", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.7.0" + "@img/sharp-wasm32": "0.35.3" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz", + "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==", "cpu": [ "arm64" ], @@ -2019,16 +2444,16 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz", + "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==", "cpu": [ "ia32" ], @@ -2038,16 +2463,16 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": "^20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz", + "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==", "cpu": [ "x64" ], @@ -2057,7 +2482,7 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" @@ -2170,6 +2595,24 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, "node_modules/@noble/ciphers": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", @@ -2250,6 +2693,15 @@ "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", "license": "MIT" }, + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@radix-ui/number": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.2.tgz", @@ -3744,51 +4196,10 @@ "integrity": "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==", "license": "MIT" }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", - "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", - "license": "MIT" - }, - "node_modules/@rollup/pluginutils": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz", - "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", - "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", - "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", "cpu": [ "arm64" ], @@ -3796,12 +4207,15 @@ "optional": true, "os": [ "android" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", - "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", "cpu": [ "arm64" ], @@ -3809,12 +4223,15 @@ "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", - "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", "cpu": [ "x64" ], @@ -3822,25 +4239,15 @@ "optional": true, "os": [ "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", - "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", - "cpu": [ - "arm64" ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", - "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", "cpu": [ "x64" ], @@ -3848,25 +4255,15 @@ "optional": true, "os": [ "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", - "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", - "cpu": [ - "arm" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", - "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", "cpu": [ "arm" ], @@ -3874,168 +4271,129 @@ "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", - "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", - "cpu": [ - "arm64" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", - "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", "cpu": [ "arm64" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", - "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", - "cpu": [ - "loong64" + "libc": [ + "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", - "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", - "cpu": [ - "loong64" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", - "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", "cpu": [ - "ppc64" + "arm64" + ], + "libc": [ + "musl" ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", - "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", "cpu": [ "ppc64" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", - "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", - "cpu": [ - "riscv64" + "libc": [ + "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", - "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", - "cpu": [ - "riscv64" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", - "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", - "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", - "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", - "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", - "cpu": [ - "x64" ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", - "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", "cpu": [ "arm64" ], @@ -4043,38 +4401,60 @@ "optional": true, "os": [ "openharmony" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", - "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", "cpu": [ - "arm64" + "wasm32" ], "license": "MIT", "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", - "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", "cpu": [ - "ia32" + "arm64" ], "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", - "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", "cpu": [ "x64" ], @@ -4082,20 +4462,38 @@ "optional": true, "os": [ "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", - "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", - "cpu": [ - "x64" ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz", + "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } }, "node_modules/@sec-ant/readable-stream": { "version": "0.4.1", @@ -4104,13 +4502,13 @@ "license": "MIT" }, "node_modules/@shikijs/core": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.2.0.tgz", - "integrity": "sha512-Hc87Ab1Ld/vEbZRCbwx344I5v+4RU8CVToUTRkqXL1+TjbuOp9U5Xa0M23V4GEWHxVn+yO5otb+HkQVm3ptWQQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.3.1.tgz", + "integrity": "sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA==", "license": "MIT", "dependencies": { - "@shikijs/primitive": "4.2.0", - "@shikijs/types": "4.2.0", + "@shikijs/primitive": "4.3.1", + "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" @@ -4120,12 +4518,12 @@ } }, "node_modules/@shikijs/engine-javascript": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.2.0.tgz", - "integrity": "sha512-fjETeq1k5ffyXqRgS6+3hpvqseLalp1kjNfRbXpUgWR8FpZ1CmQfiNHovc5lncYjt/Vg5JK/WJEmLahjwMa0og==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.3.1.tgz", + "integrity": "sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.2.0", + "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.6" }, @@ -4134,12 +4532,12 @@ } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.2.0.tgz", - "integrity": "sha512-hTorK1dffPkpbMUk6Z+828PgRo7d07HbnizoP0hNPFjhxMHctj0Px/qoHeGMYafc6ju+u9iMldN4JbVzNQM++g==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.3.1.tgz", + "integrity": "sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.2.0", + "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2" }, "engines": { @@ -4147,24 +4545,24 @@ } }, "node_modules/@shikijs/langs": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.2.0.tgz", - "integrity": "sha512-bwrVRlJ0wUhZxAbVdvBbv2TTC9yLsh4C/IO5Ofz0T8MQntgDvyVnkbjw9vi50r1kx7RCIJdnJnjZAwmAsXFLZQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.3.1.tgz", + "integrity": "sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.2.0" + "@shikijs/types": "4.3.1" }, "engines": { "node": ">=20" } }, "node_modules/@shikijs/primitive": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.2.0.tgz", - "integrity": "sha512-NOq+DtUkVBJtZMVXL5A0vI0Xk8nvDYaXetFHSJFlOqjDZIVhIPRYFdGkSoElDqNuegikcc3A76SNUa8dTqtAYA==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.3.1.tgz", + "integrity": "sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.2.0", + "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" }, @@ -4173,21 +4571,21 @@ } }, "node_modules/@shikijs/themes": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.2.0.tgz", - "integrity": "sha512-RX8IHYeLv8Cu2W6ruc3RxUqWn0IYCqSrMBzi/uRGAmfyDNOnNO5BF/Px7o97n4XTpmFTo5GbRaazuOWj+2ak2w==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.3.1.tgz", + "integrity": "sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.2.0" + "@shikijs/types": "4.3.1" }, "engines": { "node": ">=20" } }, "node_modules/@shikijs/types": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.2.0.tgz", - "integrity": "sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.3.1.tgz", + "integrity": "sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g==", "license": "MIT", "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", @@ -4426,6 +4824,66 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.1.tgz", @@ -4483,6 +4941,16 @@ "path-browserify": "^1.0.1" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -4524,15 +4992,6 @@ "@babel/types": "^7.28.2" } }, - "node_modules/@types/debug": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", - "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -4546,10 +5005,19 @@ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "license": "MIT" }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -4571,12 +5039,6 @@ "@types/unist": "*" } }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, "node_modules/@types/nlcst": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", @@ -4860,9 +5322,9 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", - "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", "license": "ISC" }, "node_modules/@vitejs/plugin-react": { @@ -5091,6 +5553,18 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/am-i-vibing": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/am-i-vibing/-/am-i-vibing-0.4.0.tgz", + "integrity": "sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==", + "license": "MIT", + "dependencies": { + "process-ancestry": "^0.1.0" + }, + "bin": { + "am-i-vibing": "dist/cli.mjs" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -5177,16 +5651,6 @@ "node": ">= 0.4" } }, - "node_modules/array-iterate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", - "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/ast-types": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", @@ -5200,30 +5664,31 @@ } }, "node_modules/astro": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/astro/-/astro-6.4.6.tgz", - "integrity": "sha512-48OBTBKR9ctbf+DQxpOuxGl8ebfn59zTuNQMBzptmG/Mi/H8IdfMSbJgGuX1I/4U6g9yazG1p4BHlf4+2hWU4Q==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/astro/-/astro-7.1.3.tgz", + "integrity": "sha512-4dhPyAAXthf3xLEYnG8SeL7yr/nTPPABfY7e9YF0yuO+vK9Xp+8Q5j4xzsmL3GueukQv4oNwGNTBepLOiDGeJA==", "license": "MIT", "dependencies": { - "@astrojs/compiler": "^4.0.0", - "@astrojs/internal-helpers": "0.10.0", - "@astrojs/markdown-remark": "7.2.0", - "@astrojs/telemetry": "3.3.2", + "@astrojs/compiler-rs": "^0.3.1", + "@astrojs/internal-helpers": "0.10.1", + "@astrojs/markdown-satteri": "0.3.4", + "@astrojs/telemetry": "3.3.3", "@capsizecss/unpack": "^4.0.0", "@clack/prompts": "^1.1.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", + "am-i-vibing": "^0.4.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "ci-info": "^4.4.0", "clsx": "^2.1.1", "common-ancestor-path": "^2.0.0", - "cookie": "^1.1.1", + "cookie": "^2.0.1", "devalue": "^5.8.1", "diff": "^8.0.3", "dset": "^3.1.4", "es-module-lexer": "^2.0.0", - "esbuild": "^0.27.3", + "esbuild": "^0.28.0", "flattie": "^1.1.1", "fontace": "~0.4.1", "get-tsconfig": "5.0.0-beta.4", @@ -5235,14 +5700,13 @@ "magic-string": "^0.30.21", "magicast": "^0.5.2", "mrmime": "^2.0.1", - "neotraverse": "^0.6.18", + "neotraverse": "^1.0.1", "obug": "^2.1.1", "p-limit": "^7.3.0", "p-queue": "^9.1.0", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.4", - "rehype": "^13.0.2", "semver": "^7.7.4", "shiki": "^4.0.2", "smol-toml": "^1.6.0", @@ -5252,10 +5716,8 @@ "tinyglobby": "^0.2.15", "ultrahtml": "^1.6.0", "unifont": "~0.7.4", - "unist-util-visit": "^5.1.0", "unstorage": "^1.17.5", - "vfile": "^6.0.3", - "vite": "^7.3.2", + "vite": "^8.0.13", "vitefu": "^1.1.2", "xxhash-wasm": "^1.1.0", "yargs-parser": "^22.0.0", @@ -5274,15 +5736,17 @@ "url": "https://opencollective.com/astrodotbuild" }, "optionalDependencies": { - "sharp": "^0.34.0" + "sharp": "^0.34.0 || ^0.35.0" + }, + "peerDependencies": { + "@astrojs/markdown-remark": "7.2.1" + }, + "peerDependenciesMeta": { + "@astrojs/markdown-remark": { + "optional": true + } } }, - "node_modules/astro/node_modules/@astrojs/compiler": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-4.0.0.tgz", - "integrity": "sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==", - "license": "MIT" - }, "node_modules/astro/node_modules/semver": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", @@ -5336,21 +5800,34 @@ } }, "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", - "content-type": "^1.0.5", + "content-type": "^2.0.0", "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", "engines": { "node": ">=18" }, @@ -5366,15 +5843,15 @@ "license": "ISC" }, "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/braces": { @@ -5514,16 +5991,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/character-entities-html4": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", @@ -5743,12 +6210,12 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==", "license": "MIT", "engines": { - "node": ">=18" + "node": ">=22" }, "funding": { "type": "opencollective", @@ -5954,19 +6421,6 @@ } } }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/dedent": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", @@ -6840,9 +7294,9 @@ } }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", "funding": [ { "type": "github", @@ -7364,19 +7818,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-parse-selector": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", @@ -7390,31 +7831,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-to-html": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", @@ -7438,41 +7854,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", - "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-text": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", - "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -7521,9 +7902,9 @@ } }, "node_modules/hono": { - "version": "4.12.26", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.26.tgz", - "integrity": "sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw==", + "version": "4.12.31", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.31.tgz", + "integrity": "sha512-zJIHFrl6bq3RDd2YusFNCDlM8qUprxKswyi/OPzPyzKDdyBXDqWx8bZlZ7R+saTdSTatUmb3O7K4SspGPaEOQg==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -7907,9 +8288,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "funding": [ { "type": "github", @@ -8347,16 +8728,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -8395,16 +8766,6 @@ "source-map-js": "^1.2.1" } }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -8414,237 +8775,21 @@ "node": ">= 0.4" } }, - "node_modules/mdast-util-definitions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", - "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", "license": "MIT", "dependencies": { + "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", - "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", - "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", @@ -8693,460 +8838,10 @@ "node": ">= 8" } }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, "node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -9159,13 +8854,14 @@ ], "license": "MIT", "dependencies": { - "micromark-util-symbol": "^2.0.0" + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-util-resolve-all": { + "node_modules/micromark-util-encode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "funding": [ { "type": "GitHub Sponsors", @@ -9176,10 +8872,7 @@ "url": "https://opencollective.com/unified" } ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } + "license": "MIT" }, "node_modules/micromark-util-sanitize-uri": { "version": "2.0.1", @@ -9202,28 +8895,6 @@ "micromark-util-symbol": "^2.0.0" } }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, "node_modules/micromark-util-symbol": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", @@ -9374,9 +9045,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -9408,9 +9079,9 @@ } }, "node_modules/neotraverse": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", - "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-1.0.1.tgz", + "integrity": "sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w==", "license": "MIT", "engines": { "node": ">= 10" @@ -9874,24 +9545,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-latin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", - "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "@types/unist": "^3.0.0", - "nlcst-to-string": "^4.0.0", - "unist-util-modify-children": "^4.0.0", - "unist-util-visit-children": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/parse-ms": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", @@ -9973,9 +9626,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "license": "MIT", "engines": { "node": ">=12" @@ -9994,9 +9647,9 @@ } }, "node_modules/postcss": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", - "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "funding": [ { "type": "opencollective", @@ -10013,7 +9666,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -10190,6 +9843,15 @@ "node": ">=6" } }, + "node_modules/process-ancestry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/process-ancestry/-/process-ancestry-0.1.0.tgz", + "integrity": "sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -10540,148 +10202,6 @@ "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", "license": "MIT" }, - "node_modules/rehype": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", - "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "rehype-parse": "^9.0.0", - "rehype-stringify": "^10.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", - "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-from-html": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-stringify": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", - "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-to-html": "^9.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-smartypants": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", - "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", - "license": "MIT", - "dependencies": { - "retext": "^9.0.0", - "retext-smartypants": "^6.0.0", - "unified": "^11.0.4", - "unist-util-visit": "^5.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/request-light": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.7.0.tgz", @@ -10742,37 +10262,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/retext": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", - "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "retext-latin": "^4.0.0", - "retext-stringify": "^4.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-latin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", - "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "parse-latin": "^7.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/retext-smartypants": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", @@ -10788,21 +10277,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/retext-stringify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", - "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "nlcst-to-string": "^4.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -10813,49 +10287,44 @@ "node": ">=0.10.0" } }, - "node_modules/rollup": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", - "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", "license": "MIT", "dependencies": { - "@types/estree": "1.0.9" + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.61.1", - "@rollup/rollup-android-arm64": "4.61.1", - "@rollup/rollup-darwin-arm64": "4.61.1", - "@rollup/rollup-darwin-x64": "4.61.1", - "@rollup/rollup-freebsd-arm64": "4.61.1", - "@rollup/rollup-freebsd-x64": "4.61.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", - "@rollup/rollup-linux-arm-musleabihf": "4.61.1", - "@rollup/rollup-linux-arm64-gnu": "4.61.1", - "@rollup/rollup-linux-arm64-musl": "4.61.1", - "@rollup/rollup-linux-loong64-gnu": "4.61.1", - "@rollup/rollup-linux-loong64-musl": "4.61.1", - "@rollup/rollup-linux-ppc64-gnu": "4.61.1", - "@rollup/rollup-linux-ppc64-musl": "4.61.1", - "@rollup/rollup-linux-riscv64-gnu": "4.61.1", - "@rollup/rollup-linux-riscv64-musl": "4.61.1", - "@rollup/rollup-linux-s390x-gnu": "4.61.1", - "@rollup/rollup-linux-x64-gnu": "4.61.1", - "@rollup/rollup-linux-x64-musl": "4.61.1", - "@rollup/rollup-openbsd-x64": "4.61.1", - "@rollup/rollup-openharmony-arm64": "4.61.1", - "@rollup/rollup-win32-arm64-msvc": "4.61.1", - "@rollup/rollup-win32-ia32-msvc": "4.61.1", - "@rollup/rollup-win32-x64-gnu": "4.61.1", - "@rollup/rollup-win32-x64-msvc": "4.61.1", - "fsevents": "~2.3.2" - } + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "license": "MIT" }, "node_modules/router": { "version": "2.2.0", @@ -10931,6 +10400,29 @@ "suf-log": "^2.5.3" } }, + "node_modules/satteri": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/satteri/-/satteri-0.9.5.tgz", + "integrity": "sha512-ZuWVl+vnM64y+/TtX8Kosv2c00W+hLQiiwnEL6H0UKVVrxFqMw4D2CJHHQaouVd89OAhtBBfjWLqhKi3TVUV4w==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.5", + "@types/hast": "^3.0.4", + "@types/mdast": "^4.0.4", + "@types/unist": "^3.0.3" + }, + "optionalDependencies": { + "@bruits/satteri-darwin-arm64": "0.9.5", + "@bruits/satteri-darwin-x64": "0.9.5", + "@bruits/satteri-linux-arm64-gnu": "0.9.5", + "@bruits/satteri-linux-arm64-musl": "0.9.5", + "@bruits/satteri-linux-x64-gnu": "0.9.5", + "@bruits/satteri-linux-x64-musl": "0.9.5", + "@bruits/satteri-wasm32-wasi": "0.9.5", + "@bruits/satteri-win32-arm64-msvc": "0.9.5", + "@bruits/satteri-win32-x64-msvc": "0.9.5" + } + }, "node_modules/sax": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", @@ -11060,54 +10552,59 @@ } }, "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "hasInstallScript": true, + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz", + "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@img/colour": "^1.0.0", + "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", - "semver": "^7.7.3" + "semver": "^7.8.5" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.5", - "@img/sharp-darwin-x64": "0.34.5", - "@img/sharp-libvips-darwin-arm64": "1.2.4", - "@img/sharp-libvips-darwin-x64": "1.2.4", - "@img/sharp-libvips-linux-arm": "1.2.4", - "@img/sharp-libvips-linux-arm64": "1.2.4", - "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" + "@img/sharp-darwin-arm64": "0.35.3", + "@img/sharp-darwin-x64": "0.35.3", + "@img/sharp-freebsd-wasm32": "0.35.3", + "@img/sharp-libvips-darwin-arm64": "1.3.2", + "@img/sharp-libvips-darwin-x64": "1.3.2", + "@img/sharp-libvips-linux-arm": "1.3.2", + "@img/sharp-libvips-linux-arm64": "1.3.2", + "@img/sharp-libvips-linux-ppc64": "1.3.2", + "@img/sharp-libvips-linux-riscv64": "1.3.2", + "@img/sharp-libvips-linux-s390x": "1.3.2", + "@img/sharp-libvips-linux-x64": "1.3.2", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.2", + "@img/sharp-libvips-linuxmusl-x64": "1.3.2", + "@img/sharp-linux-arm": "0.35.3", + "@img/sharp-linux-arm64": "0.35.3", + "@img/sharp-linux-ppc64": "0.35.3", + "@img/sharp-linux-riscv64": "0.35.3", + "@img/sharp-linux-s390x": "0.35.3", + "@img/sharp-linux-x64": "0.35.3", + "@img/sharp-linuxmusl-arm64": "0.35.3", + "@img/sharp-linuxmusl-x64": "0.35.3", + "@img/sharp-webcontainers-wasm32": "0.35.3", + "@img/sharp-win32-arm64": "0.35.3", + "@img/sharp-win32-ia32": "0.35.3", + "@img/sharp-win32-x64": "0.35.3" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/sharp/node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "optional": true, "bin": { @@ -11139,17 +10636,17 @@ } }, "node_modules/shiki": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.2.0.tgz", - "integrity": "sha512-hjNax6o/ylDy9lefQEaSDtzaT3iVNtZ3WmpQnbuQNoG4xvnSKf2kSKbihZVO4JRG1TTMejs7CmNRYlWgAL66pQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.3.1.tgz", + "integrity": "sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw==", "license": "MIT", "dependencies": { - "@shikijs/core": "4.2.0", - "@shikijs/engine-javascript": "4.2.0", - "@shikijs/engine-oniguruma": "4.2.0", - "@shikijs/langs": "4.2.0", - "@shikijs/themes": "4.2.0", - "@shikijs/types": "4.2.0", + "@shikijs/core": "4.3.1", + "@shikijs/engine-javascript": "4.3.1", + "@shikijs/engine-oniguruma": "4.3.1", + "@shikijs/langs": "4.3.1", + "@shikijs/themes": "4.3.1", + "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" }, @@ -11248,9 +10745,9 @@ "license": "MIT" }, "node_modules/smol-toml": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", - "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.0.tgz", + "integrity": "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 18" @@ -11427,9 +10924,9 @@ } }, "node_modules/svgo": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", - "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.2.tgz", + "integrity": "sha512-ekx94z1rRc5LDi6oSUaeRnYhd0UOJxdtQCL2rF8xpWxD3TPAsISWOrxezqGovqS38GRZOdpDfvQe3ts6F7nsng==", "license": "MIT", "dependencies": { "commander": "^11.1.0", @@ -11800,20 +11297,6 @@ "ohash": "^2.0.11" } }, - "node_modules/unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-is": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", @@ -11827,20 +11310,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-modify-children": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", - "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "array-iterate": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-position": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", @@ -11854,20 +11323,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -11896,19 +11351,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-children": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", - "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-visit-parents": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", @@ -12224,17 +11666,16 @@ } }, "node_modules/vite": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", - "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz", + "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.17", + "rolldown": "~1.1.5", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" @@ -12250,9 +11691,10 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", - "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", @@ -12265,13 +11707,16 @@ "@types/node": { "optional": true }, - "jiti": { + "@vitejs/devtools": { "optional": true }, - "less": { + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { @@ -12646,15 +12091,6 @@ "node": ">= 8" } }, - "node_modules/which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/website/package.json b/website/package.json index 1fd8d039..bdda68fb 100644 --- a/website/package.json +++ b/website/package.json @@ -4,7 +4,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=20.19.0 <25" + "node": ">=22.22.0 <26" }, "scripts": { "dev": "astro dev", @@ -16,12 +16,12 @@ "typecheck": "astro check" }, "dependencies": { - "@astrojs/react": "^5.0.7", + "@astrojs/react": "^6.0.1", "@fontsource-variable/ibm-plex-sans": "^5.2.8", "@tailwindcss/vite": "^4.3.1", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "astro": "^6.4.4", + "astro": "^7.1.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^1.18.0", @@ -35,22 +35,26 @@ }, "overrides": { "@modelcontextprotocol/sdk": { - "@hono/node-server": "1.19.14", - "hono": "4.12.26" + "@hono/node-server": "2.0.12", + "hono": "4.12.31" }, - "hono": "4.12.26", + "hono": "4.12.31", "qs": "6.15.2", "express-rate-limit": "8.5.1", "ip-address": "10.2.0", - "postcss": "8.5.14", + "brace-expansion": "5.0.8", + "postcss": "8.5.23", "router": { "path-to-regexp": "8.4.2" }, "defu": "6.1.7", "esbuild": "0.28.1", - "vite": "7.3.5", + "vite": "8.1.5", + "body-parser": "2.3.0", "yaml": "2.8.3", - "fast-uri": "3.1.2" + "fast-uri": "3.1.4", + "sharp": "0.35.3", + "svgo": "4.0.2" }, "devDependencies": { "@astrojs/check": "^0.9.9", diff --git a/website/public/install b/website/public/install index 3f651d61..e1bcdce3 100644 --- a/website/public/install +++ b/website/public/install @@ -164,6 +164,19 @@ require_command() { fi } +sha256_file() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | awk '{print $1}' + return + fi + if command -v shasum >/dev/null 2>&1; then + shasum -a 256 "$1" | awk '{print $1}' + return + fi + echo "sha256sum or shasum is required to verify the Feynman download." >&2 + exit 1 +} + warn_command_conflict() { expected_path="$INSTALL_BIN_DIR/feynman" resolved_path="$(command -v feynman 2>/dev/null || true)" @@ -198,9 +211,11 @@ resolve_release_metadata() { bundle_name="feynman-${resolved_version}-${asset_target}" archive_name="${bundle_name}.${archive_extension}" - download_url="${FEYNMAN_INSTALL_BASE_URL:-https://github.com/companion-inc/feynman/releases/download/v${resolved_version}}/${archive_name}" + release_base_url="${FEYNMAN_INSTALL_BASE_URL:-https://github.com/companion-inc/feynman/releases/download/v${resolved_version}}" + download_url="${release_base_url}/${archive_name}" + checksums_url="${release_base_url}/SHA256SUMS" - printf '%s\n%s\n%s\n%s\n' "$resolved_version" "$bundle_name" "$archive_name" "$download_url" + printf '%s\n%s\n%s\n%s\n%s\n' "$resolved_version" "$bundle_name" "$archive_name" "$download_url" "$checksums_url" } case "$(uname -s)" in @@ -239,6 +254,7 @@ resolved_version="$(printf '%s\n' "$release_metadata" | sed -n '1p')" bundle_name="$(printf '%s\n' "$release_metadata" | sed -n '2p')" archive_name="$(printf '%s\n' "$release_metadata" | sed -n '3p')" download_url="$(printf '%s\n' "$release_metadata" | sed -n '4p')" +checksums_url="$(printf '%s\n' "$release_metadata" | sed -n '5p')" step "Installing Feynman ${resolved_version} for ${asset_target}" @@ -266,18 +282,97 @@ EOF exit 1 fi -mkdir -p "$INSTALL_APP_DIR" -rm -rf "$INSTALL_APP_DIR/$bundle_name" -run_with_spinner "Extracting ${archive_name}" tar -xzf "$archive_path" -C "$INSTALL_APP_DIR" +checksums_path="$tmp_dir/SHA256SUMS" +step "Verifying ${archive_name}" +download_file "$checksums_url" "$checksums_path" +checksum_matches="$(awk -v name="$archive_name" '$2 == name || $2 == "*" name { print $1 }' "$checksums_path")" +checksum_count="$(printf '%s\n' "$checksum_matches" | awk 'NF { count += 1 } END { print count + 0 }')" +if [ "$checksum_count" -ne 1 ]; then + if [ "$checksum_count" -eq 0 ]; then + echo "SHA256SUMS does not contain a valid checksum for ${archive_name}." >&2 + else + echo "SHA256SUMS contains multiple checksum entries for ${archive_name}." >&2 + fi + exit 1 +fi +expected_checksum="$(printf '%s\n' "$checksum_matches" | sed -n '1p')" +case "$expected_checksum" in + "" | *[!0-9a-fA-F]*) + echo "SHA256SUMS does not contain a valid checksum for ${archive_name}." >&2 + exit 1 + ;; +esac +if [ "${#expected_checksum}" -ne 64 ]; then + echo "SHA256SUMS contains a malformed checksum for ${archive_name}." >&2 + exit 1 +fi +actual_checksum="$(sha256_file "$archive_path")" +if [ "$actual_checksum" != "$expected_checksum" ]; then + echo "SHA-256 mismatch for ${archive_name}: expected ${expected_checksum}, found ${actual_checksum}." >&2 + exit 1 +fi +extract_root="$tmp_dir/extract" +mkdir -p "$extract_root" +run_with_spinner "Extracting ${archive_name}" tar -xzf "$archive_path" -C "$extract_root" +candidate_bundle="$extract_root/$bundle_name" +if [ ! -x "$candidate_bundle/feynman" ]; then + echo "Downloaded archive did not contain the expected executable: ${bundle_name}/feynman" >&2 + exit 1 +fi +candidate_version="$("$candidate_bundle/feynman" --version | tail -n 1)" +if [ "$candidate_version" != "$resolved_version" ]; then + echo "Downloaded bundle version mismatch: expected ${resolved_version}, found ${candidate_version}." >&2 + exit 1 +fi +"$candidate_bundle/feynman" --help >/dev/null + +mkdir -p "$INSTALL_APP_DIR" mkdir -p "$INSTALL_BIN_DIR" +bundle_dir="$INSTALL_APP_DIR/$bundle_name" +backup_dir="$tmp_dir/previous-bundle" +had_previous=0 +if [ -e "$bundle_dir" ]; then + mv "$bundle_dir" "$backup_dir" + had_previous=1 +fi +if ! mv "$candidate_bundle" "$bundle_dir"; then + if [ "$had_previous" -eq 1 ]; then + mv "$backup_dir" "$bundle_dir" + fi + echo "Failed to install the validated Feynman bundle." >&2 + exit 1 +fi + step "Linking feynman into $INSTALL_BIN_DIR" -cat >"$INSTALL_BIN_DIR/feynman" <"$shim_candidate" <\s]*)') if (-not $match.Success) { throw "Failed to resolve the latest Feynman release version." @@ -53,6 +55,7 @@ function Resolve-ReleaseMetadata { BundleName = $bundleName ArchiveName = $archiveName DownloadUrl = "$baseUrl/$archiveName" + ChecksumsUrl = "$baseUrl/SHA256SUMS" } } @@ -64,7 +67,9 @@ function Get-ArchSuffix { if ($envArch) { switch ($envArch) { "AMD64" { return "x64" } - "ARM64" { return "arm64" } + # The release currently ships the Windows x64 bundle. Windows 11 on Arm + # runs that bundle through its supported x64 emulation layer. + "ARM64" { return "x64" } } } @@ -72,7 +77,7 @@ function Get-ArchSuffix { $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture switch ($arch.ToString()) { "X64" { return "x64" } - "Arm64" { return "arm64" } + "Arm64" { return "x64" } } } catch {} @@ -86,6 +91,7 @@ $resolvedVersion = $release.ResolvedVersion $bundleName = $release.BundleName $archiveName = $release.ArchiveName $downloadUrl = $release.DownloadUrl +$checksumsUrl = $release.ChecksumsUrl $installRoot = Join-Path $env:LOCALAPPDATA "Programs\feynman" $installBinDir = Join-Path $installRoot "bin" @@ -96,9 +102,15 @@ New-Item -ItemType Directory -Path $tmpDir | Out-Null try { $archivePath = Join-Path $tmpDir $archiveName + $checksumsPath = Join-Path $tmpDir "SHA256SUMS" + $extractRoot = Join-Path $tmpDir "extract" + $extractedBundleDir = Join-Path $extractRoot $bundleName Write-Host "==> Downloading $archiveName" try { - Invoke-WebRequest -Uri $downloadUrl -OutFile $archivePath + Invoke-WebRequest ` + -Uri $downloadUrl ` + -OutFile $archivePath ` + -UseBasicParsing } catch { throw @" Failed to download $archiveName from: @@ -114,28 +126,139 @@ Workarounds: "@ } - New-Item -ItemType Directory -Path $installRoot -Force | Out-Null - if (Test-Path $bundleDir) { - Remove-Item -Recurse -Force $bundleDir + Write-Host "==> Verifying $archiveName" + Invoke-WebRequest ` + -Uri $checksumsUrl ` + -OutFile $checksumsPath ` + -UseBasicParsing + $escapedArchiveName = [regex]::Escape($archiveName) + $checksumMatches = @( + Select-String ` + -LiteralPath $checksumsPath ` + -Pattern "^([0-9a-fA-F]{64})\s+\*?$escapedArchiveName$" + ) + if ($checksumMatches.Count -eq 0) { + throw "SHA256SUMS does not contain a valid checksum for $archiveName." + } + if ($checksumMatches.Count -ne 1) { + throw "SHA256SUMS contains multiple checksum entries for $archiveName." + } + $expectedChecksum = $checksumMatches[0].Matches[0].Groups[1].Value.ToLowerInvariant() + $actualChecksum = (Get-FileHash -LiteralPath $archivePath -Algorithm SHA256).Hash.ToLowerInvariant() + if ($actualChecksum -ne $expectedChecksum) { + throw "SHA-256 mismatch for ${archiveName}: expected $expectedChecksum, found $actualChecksum." } Write-Host "==> Extracting $archiveName" - Expand-Archive -LiteralPath $archivePath -DestinationPath $installRoot -Force + New-Item -ItemType Directory -Path $extractRoot -Force | Out-Null + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($archivePath, $extractRoot) + if (-not (Test-Path $extractedBundleDir)) { + throw "Downloaded archive did not contain the expected $bundleName directory." + } + $candidateCmd = Join-Path $extractedBundleDir "feynman.cmd" + $candidatePs1 = Join-Path $extractedBundleDir "feynman.ps1" + foreach ($candidate in @($candidateCmd, $candidatePs1)) { + if (-not (Test-Path -LiteralPath $candidate)) { + throw "Downloaded archive did not contain the expected launcher: $candidate" + } + } + $candidateVersionOutput = @(& $candidateCmd --version 2>&1) + if ($LASTEXITCODE -ne 0) { + throw "Downloaded launcher failed --version: $candidateCmd" + } + $candidateVersion = ($candidateVersionOutput | Select-Object -Last 1).ToString().Trim() + if ($candidateVersion -ne $resolvedVersion) { + throw "Downloaded bundle version mismatch: expected=$resolvedVersion actual=$candidateVersion" + } + $candidateHelp = @(& $candidateCmd --help 2>&1) + if ($LASTEXITCODE -ne 0 -or $candidateHelp.Count -eq 0) { + throw "Downloaded launcher failed --help: $candidateCmd" + } - New-Item -ItemType Directory -Path $installBinDir -Force | Out-Null + # The public one-line installer can run under Windows PowerShell's default + # Restricted policy because it executes an in-memory scriptblock. Validate + # the packaged PowerShell launcher in a child host with an explicit process- + # scoped bypass rather than invoking the downloaded .ps1 file directly. + $powerShellExecutable = (Get-Process -Id $PID).Path + $candidateVersionOutput = @( + & $powerShellExecutable -NoProfile -ExecutionPolicy Bypass -File $candidatePs1 --version 2>&1 + ) + if ($LASTEXITCODE -ne 0) { + throw "Downloaded launcher failed --version: $candidatePs1" + } + $candidateVersion = ($candidateVersionOutput | Select-Object -Last 1).ToString().Trim() + if ($candidateVersion -ne $resolvedVersion) { + throw "Downloaded bundle version mismatch: expected=$resolvedVersion actual=$candidateVersion" + } + $candidateHelp = @( + & $powerShellExecutable -NoProfile -ExecutionPolicy Bypass -File $candidatePs1 --help 2>&1 + ) + if ($LASTEXITCODE -ne 0 -or $candidateHelp.Count -eq 0) { + throw "Downloaded launcher failed --help: $candidatePs1" + } - $shimPath = Join-Path $installBinDir "feynman.cmd" - $shimPs1Path = Join-Path $installBinDir "feynman.ps1" - Write-Host "==> Linking feynman into $installBinDir" + New-Item -ItemType Directory -Path $installRoot -Force | Out-Null + $stagedBinDir = Join-Path $tmpDir "bin" + New-Item -ItemType Directory -Path $stagedBinDir -Force | Out-Null + $shimCandidate = Join-Path $stagedBinDir "feynman.cmd" @" @echo off CALL "$bundleDir\feynman.cmd" %* -"@ | Set-Content -Path $shimPath -Encoding ASCII +"@ | Set-Content -Path $shimCandidate -Encoding ASCII - @" -`$BundleDir = "$bundleDir" -& "`$BundleDir\node\node.exe" "`$BundleDir\app\bin\feynman.js" @args -"@ | Set-Content -Path $shimPs1Path -Encoding UTF8 + $backupBundleDir = Join-Path $tmpDir "previous-bundle" + $backupBinDir = Join-Path $tmpDir "previous-bin" + $hadPreviousBundle = Test-Path -LiteralPath $bundleDir + $hadPreviousBin = Test-Path -LiteralPath $installBinDir + $backupBundleMoved = $false + $backupBinMoved = $false + $candidateBundleInstalled = $false + $candidateBinInstalled = $false + try { + if ($hadPreviousBundle) { + Move-Item -LiteralPath $bundleDir -Destination $backupBundleDir + $backupBundleMoved = $true + } + if ($env:FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_BACKUP -eq "1") { + throw "Injected installer failure after bundle backup." + } + if ($hadPreviousBin) { + Move-Item -LiteralPath $installBinDir -Destination $backupBinDir + $backupBinMoved = $true + } + Move-Item -LiteralPath $extractedBundleDir -Destination $bundleDir + $candidateBundleInstalled = $true + Write-Host "==> Linking feynman into $installBinDir" + if ($env:FEYNMAN_INSTALL_TEST_FAIL_AFTER_BUNDLE_SWAP -eq "1") { + throw "Injected installer failure after bundle swap." + } + Move-Item -LiteralPath $stagedBinDir -Destination $installBinDir + $candidateBinInstalled = $true + } catch { + if ($candidateBundleInstalled -and (Test-Path -LiteralPath $bundleDir)) { + Remove-Item -LiteralPath $bundleDir -Recurse -Force + } + if ($candidateBinInstalled -and (Test-Path -LiteralPath $installBinDir)) { + Remove-Item -LiteralPath $installBinDir -Recurse -Force + } + if ($backupBundleMoved -and (Test-Path -LiteralPath $backupBundleDir)) { + Move-Item -LiteralPath $backupBundleDir -Destination $bundleDir + } + if ($backupBinMoved -and (Test-Path -LiteralPath $backupBinDir)) { + Move-Item -LiteralPath $backupBinDir -Destination $installBinDir + } + throw + } + if (Test-Path -LiteralPath $backupBundleDir) { + Remove-Item -LiteralPath $backupBundleDir -Recurse -Force + } + if (Test-Path -LiteralPath $backupBinDir) { + Remove-Item -LiteralPath $backupBinDir -Recurse -Force + } + Get-ChildItem -LiteralPath $installRoot -Directory -Filter "feynman-*" | + Where-Object { $_.FullName -ne $bundleDir } | + Remove-Item -Recurse -Force $currentUserPath = [Environment]::GetEnvironmentVariable("Path", "User") $alreadyOnPath = $false @@ -155,7 +278,24 @@ CALL "$bundleDir\feynman.cmd" %* } $resolvedCommand = Get-Command feynman -ErrorAction SilentlyContinue - if ($resolvedCommand -and $resolvedCommand.Source -ne $shimPath) { + # Install only the CMD shim on PATH. Windows PowerShell resolves .ps1 before + # PATHEXT launchers, so a same-name PowerShell shim is blocked by the default + # Restricted policy before the working CMD launcher can be selected. + $expectedShimPaths = @( + [System.IO.Path]::GetFullPath((Join-Path $installBinDir "feynman.cmd")) + ) + $resolvedSource = if ($resolvedCommand) { $resolvedCommand.Source } else { $null } + $resolvedToInstalledShim = $false + if ($resolvedSource) { + $resolvedFullPath = [System.IO.Path]::GetFullPath($resolvedSource) + foreach ($expectedShimPath in $expectedShimPaths) { + if ([string]::Equals($resolvedFullPath, $expectedShimPath, [System.StringComparison]::OrdinalIgnoreCase)) { + $resolvedToInstalledShim = $true + break + } + } + } + if ($resolvedCommand -and -not $resolvedToInstalledShim) { Write-Warning "Current shell resolves feynman to $($resolvedCommand.Source)" Write-Host "Run in a new shell, or run: `$env:Path = '$installBinDir;' + `$env:Path" Write-Host "Then run: feynman" diff --git a/website/src/content/docs/getting-started/configuration.md b/website/src/content/docs/getting-started/configuration.md index 48ac47da..8adc5952 100644 --- a/website/src/content/docs/getting-started/configuration.md +++ b/website/src/content/docs/getting-started/configuration.md @@ -112,7 +112,7 @@ Per-subagent overrides are persisted in the synced agent files under `~/.feynman ## Thinking levels -The `thinkingLevel` field controls how much reasoning the model does before responding. Available levels are `off`, `minimal`, `low`, `medium`, `high`, and `xhigh`. Higher levels produce more thorough analysis at the cost of latency and token usage. You can override per-session: +The `thinkingLevel` field controls how much reasoning the model does before responding. Available levels are `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`, subject to the active model's capabilities. Higher levels produce more thorough analysis at the cost of latency and token usage. You can override per-session: ```bash feynman --thinking high @@ -127,6 +127,7 @@ Feynman respects the following environment variables, which take precedence over | `FEYNMAN_MODEL` | Override the default model with a non-Pro model | | `FEYNMAN_HOME` | Override the parent directory used to create `.feynman` (default parent: `~`) | | `FEYNMAN_WORKBENCH_HOME` | Override the workbench app-data root; otherwise Feynman uses `~/.feynman/orgs//workbench` | +| `FEYNMAN_FETCH_CACHE_DIR` | Override the project-local directory used for `fetch_content` PDF scratch Markdown | | `FEYNMAN_THINKING` | Override the thinking level | | `ANTHROPIC_API_KEY` | Anthropic API key | | `OPENAI_API_KEY` | OpenAI API key | diff --git a/website/src/content/docs/getting-started/installation.md b/website/src/content/docs/getting-started/installation.md index e7f5bdc1..a248209f 100644 --- a/website/src/content/docs/getting-started/installation.md +++ b/website/src/content/docs/getting-started/installation.md @@ -5,7 +5,7 @@ section: Getting Started order: 1 --- -Feynman can be installed either as a standalone runtime bundle or as an npm package. For most users, the standalone installer is the simplest path because it downloads a prebuilt native bundle with zero external runtime dependencies. +Feynman can be installed either as a standalone runtime bundle or as an npm package. For most users, the standalone installer is the simplest path because it downloads a prebuilt native bundle with zero external runtime dependencies and verifies its published SHA-256 before replacing an existing installation. ## One-line installer (recommended) @@ -25,7 +25,7 @@ On **Windows**, open PowerShell as Administrator and run: irm https://feynman.is/install.ps1 | iex ``` -This installs the Windows runtime bundle under `%LOCALAPPDATA%\Programs\feynman`, adds its launcher to your user `PATH`, and lets you re-run the installer at any time to update. +This installs the Windows x64 runtime bundle under `%LOCALAPPDATA%\Programs\feynman`, adds its launcher to your user `PATH`, and lets you re-run the installer at any time to update. Windows 11 on Arm uses the same bundle through its x64 compatibility layer. ## Alternative: npm install @@ -35,7 +35,7 @@ If you prefer installing Feynman into an existing Node.js environment, use npm i npm install -g @companion-ai/feynman ``` -This path uses your local Node.js runtime instead of the bundled standalone runtime. It requires a compatible Node.js version that satisfies Feynman's current engine range: `>=22.19.0 <26`. +This path uses your local Node.js runtime instead of the bundled standalone runtime. It requires a compatible Node.js version that satisfies Feynman's current engine range: `>=22.22.0 <26`. ## Updating the standalone app diff --git a/website/src/content/docs/reference/cli-commands.md b/website/src/content/docs/reference/cli-commands.md index a96df093..cfca46bc 100644 --- a/website/src/content/docs/reference/cli-commands.md +++ b/website/src/content/docs/reference/cli-commands.md @@ -78,7 +78,7 @@ These commands manage your model provider configuration. The `model set` command | --- | --- | | `feynman alpha login` | Sign in to alphaXiv | | `feynman alpha logout` | Clear alphaXiv auth | -| `feynman alpha status` | Check alphaXiv auth status | +| `feynman alpha status` | Refresh expired alphaXiv credentials when possible and verify live auth status | | `feynman alpha search "query"` | Search papers through Feynman's bundled alphaXiv client | | `feynman alpha get ` | Fetch paper content and local annotations | | `feynman alpha ask "question"` | Ask a question about a paper | @@ -135,7 +135,7 @@ These are equivalent to launching the REPL and typing the corresponding slash co | --- | --- | | `--prompt ""` | Run one prompt and exit (one-shot mode) | | `--model ` | Force a specific non-Pro model for this session | -| `--thinking ` | Set thinking level: `off`, `minimal`, `low`, `medium`, `high`, `xhigh` | +| `--thinking ` | Set thinking level: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` | | `--cwd ` | Set the working directory for all file operations | | `--session-dir ` | Set the session storage directory | | `--new-session` | Start a new persisted session | diff --git a/website/src/content/docs/reference/package-stack.md b/website/src/content/docs/reference/package-stack.md index bfa46107..c9406e43 100644 --- a/website/src/content/docs/reference/package-stack.md +++ b/website/src/content/docs/reference/package-stack.md @@ -21,7 +21,7 @@ These are installed by default with every Feynman installation. They provide the | `pi-subagents` | Parallel agent spawning for literature gathering and task decomposition. Powers the multi-agent workflows | | `pi-btw` | Side conversations while the main research agent is busy, including `/btw` follow-ups and handoff back into the main thread | | `pi-docparser` | Parse PDFs, Office documents, spreadsheets, and images for content extraction | -| `pi-web-access` | Web browsing, GitHub access, PDF fetching, and media retrieval | +| `pi-web-access` | Web browsing, simultaneous multi-provider search, GitHub access, PDF fetching, and media retrieval | | `pi-otel` | OpenTelemetry spans for Pi sessions, model calls, turns, and tool usage, exported without prompt or tool payload content | These packages are updated together when you run `feynman update`. You do not need to install them individually. @@ -32,7 +32,7 @@ These packages are updated together when you run `feynman update`. You do not ne | --- | --- | | AlphaXiv tools | Search papers, fetch paper reports, ask paper questions, read linked code, and manage annotations | | Hugging Face Hub tools | Inspect dataset metadata, features, splits, access status, and small files from model, dataset, and Space repos | -| Feynman commands | `/help`, `/outputs`, `/init`, `/feynman-model`, `/service-tier`, and discovery helpers | +| Feynman commands | `/help`, `/outputs`, `/init`, `/feynman-model`, `/service-tier`, `/thinking`, and discovery helpers | ## Optional packages diff --git a/website/src/content/docs/reference/releases.md b/website/src/content/docs/reference/releases.md index 9275dd7b..cb88031f 100644 --- a/website/src/content/docs/reference/releases.md +++ b/website/src/content/docs/reference/releases.md @@ -9,9 +9,32 @@ This page summarizes what changed in recent Feynman releases. GitHub releases us ## Unreleased +## v0.3.6 - 2026-07-28 + +- Raised the npm-install Node 22 floor to `22.22.0`, matching the direct telemetry runtime's actual engine contract; standalone installers continue to bundle Node `24.18.0`. + +### Reliability + +- Fixed alphaXiv login after its OAuth migration by shipping the current OAuth2 endpoints and validating the loopback callback state before exchanging authorization codes. `feynman alpha status` now refreshes expired credentials and verifies them against the live user-info endpoint instead of treating any cached token as logged in. +- Fixed Windows one-line installs by extracting release archives into temporary staging before replacing the installed bundle. +- Fixed workbench state switching between newly minted local organizations when concurrent processes read `active-org.json` during a rewrite. Valid manifests are no longer rewritten, and required writes are atomic. +- Option+Enter now inserts a newline in Feynman's REPL input. Shift+Enter preserves Pi's follow-up action in terminals that report modified Enter keys, Ctrl+J remains a portable newline alternative, and existing user-modified keybindings remain untouched. +- Added `/thinking [level]` so reasoning effort is discoverable and directly adjustable inside the REPL while Shift+Tab remains available. The picker follows the active model's supported levels, including `max` where Pi exposes it. +- `fetch_content` now writes extracted PDF scratch Markdown under the active project's `.feynman/cache/fetch-content` instead of `~/Downloads`. Set `FEYNMAN_FETCH_CACHE_DIR` to override the location. +- Unknown CLI flags now point to `feynman help`, and `feynman update` help clarifies that extensions update with their packages rather than through a separate `--extensions` flag. + ### Package Stack - Added `pi-btw` to Feynman's default Pi package stack so `/btw` side conversations are available during long-running research turns without requiring a separate package install. +- Updated `pi-subagents` to `0.37.2` so child runs that disable inherited project context follow Pi's current context-file contract, while reducing repeated TUI and skill-file scans. +- Updated `pi-web-access` to `0.15.0`, adding simultaneous all-provider search with partial-failure diagnostics, TinyFish search and extraction, and configurable OpenAI Responses-compatible search gateways. +- Refreshed the bundled Pi runtime packages from `0.80.3` to `0.82.1`, migrated Feynman's model/auth integration to Pi's asynchronous `ModelRuntime`, and kept the runtime fallback pins aligned with the installed package set. +- Repaired the current Pi and MCP production dependency advisories in the packaged runtime by replacing Pi's vulnerable nested `brace-expansion` copy with `5.0.8`, updating MCP SDK to `1.30.0`, and pinning its compatible Hono server dependency to `2.0.12`. The Pi repair can be removed after upstream updates its shrinkwrap; the Hono pin can be removed after MCP no longer permits the vulnerable v1 range. +- Pinned the bundled runtime's complete dependency graph in a committed lockfile, upgraded its coordinated OpenTelemetry train to `2.10.0`/`0.221.0`, and made pruning changes and archive digests invalidate stale runtime artifacts. Startup now verifies every package named by the bundled runtime manifest, so a stale Pi copy is restored even when it is not itself a user-configured extension. +- Runtime and standalone archives now bind relative build inputs and the complete patched tree, reject stale or transplanted manifests, normalize archive metadata, and omit macOS AppleDouble metadata that previously doubled package size. +- Added pre-merge Linux package/consumer plus Windows PowerShell installer replacement gates. Release publication now promotes the exact verified tarball only after native bundles pass. +- Added explicit release-package budgets of 125 MiB compressed, 360 MiB unpacked, and 42,000 files around the current bundled research runtime so accidental package growth fails before publication. +- Pinned release executors and the bundled Node `24.18.0` archives, added Linux arm64 release builds, and made every standalone installer verify the published `SHA256SUMS` entry before replacing a working installation. ### Science Workbench diff --git a/website/src/content/docs/reference/slash-commands.md b/website/src/content/docs/reference/slash-commands.md index 904c29e7..5fca3950 100644 --- a/website/src/content/docs/reference/slash-commands.md +++ b/website/src/content/docs/reference/slash-commands.md @@ -35,6 +35,7 @@ These are the primary commands you use during research runs. Workflow prompts ca | `/init` | Bootstrap `AGENTS.md` and session-log folders for a new research project | | `/outputs` | Browse all research artifacts (papers, outputs, experiments, notes) | | `/btw ` | Ask a side question while the main research agent is busy and hand the result back when needed | +| `/thinking [level]` | View the current model thinking level, open a model-aware picker, or set `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max` directly | | `/search` | Search prior research-session transcripts for past research and findings | Session management commands help you organize ongoing work. The `/log` command is particularly useful at the end of a research session to capture what was accomplished and what remains. diff --git a/website/src/content/docs/tools/web-search.md b/website/src/content/docs/tools/web-search.md index 22262c5c..9b026a6d 100644 --- a/website/src/content/docs/tools/web-search.md +++ b/website/src/content/docs/tools/web-search.md @@ -5,15 +5,17 @@ section: Tools order: 2 --- -Feynman's web search tool retrieves current information from the web during research workflows. It supports multiple simultaneous queries, domain filtering, recency filtering, and optional provider-available page-text retrieval. The researcher agent uses web search alongside AlphaXiv to gather evidence from non-academic sources like blog posts, documentation, news, and code repositories. +Feynman's web search tool retrieves current information from the web during research workflows. It supports multiple simultaneous queries, simultaneous all-provider search, domain filtering, recency filtering, and optional provider-available page-text retrieval. The researcher agent uses web search alongside AlphaXiv to gather evidence from non-academic sources like blog posts, documentation, news, and code repositories. ## Routing modes -Feynman supports three web search backends. You can configure which one to use or let Feynman choose automatically: +The bundled `pi-web-access` package can choose one provider, follow a configured fallback route, or query every eligible provider simultaneously: | Mode | Description | | --- | --- | -| `auto` | Prefer Exa when configured, then Perplexity, then Gemini API | +| `auto` | Follow the available-provider fallback route | +| `all` | Query every eligible provider except explicit-only AnySearch, preserve partial successes, and deduplicate sources | +| `tinyfish` | Force TinyFish Search; also enables TinyFish Fetch as a hosted extraction fallback | | `perplexity` | Force Perplexity Sonar for all web searches | | `exa` | Force Exa for all web searches | | `gemini` | Force Gemini API grounding | @@ -22,7 +24,7 @@ Feynman supports three web search backends. You can configure which one to use o The default path does not read Chromium or Chrome cookies and does not request macOS Keychain access. In `auto` mode, Feynman uses API-backed search providers when they are configured: Exa first, then Perplexity, then Gemini API. -Configure an explicit API key for Exa, Perplexity, or Gemini in `~/.feynman/web-search.json` before running source-heavy workflows like `/deepresearch`. +Configure an explicit API key for Exa, Perplexity, TinyFish, or Gemini in `~/.feynman/web-search.json` before running source-heavy workflows like `/deepresearch`. Exa's zero-config MCP fallback remains available without a key. ## Configuration @@ -40,11 +42,14 @@ Edit `~/.feynman/web-search.json` to configure the backend: "searchProvider": "auto", "exaApiKey": "exa_...", "perplexityApiKey": "pplx-...", + "tinyfishApiKey": "sk-tinyfish-...", "geminiApiKey": "AIza..." } ``` -Set `provider` and `searchProvider` to `auto`, `exa`, `perplexity`, or `gemini`. When using `auto`, Feynman prefers Exa if a key is present, then Perplexity, then Gemini API. You can also run `feynman search set [api-key]` to write this file. +Set `provider` and `searchProvider` to `all` to query every eligible provider concurrently, or to a specific `pi-web-access` provider such as `tinyfish`, `exa`, `perplexity`, or `gemini`. `searchRouting` instead defines an ordered fallback route; `all` is not valid inside that sequential list. The `feynman search set [api-key]` convenience command supports `auto`, `exa`, `perplexity`, and `gemini`; edit the JSON directly for the broader upstream provider set. + +To route OpenAI `web_search` and `source_check` calls through a third-party gateway, set `openaiResponsesUrl` to the gateway's full Responses-compatible endpoint. The default remains OpenAI's official Responses endpoint. Gemini Web browser-cookie access is disabled by default. To opt into that legacy fallback, add `"geminiBrowser": true` to `~/.feynman/web-search.json`. On macOS, that can trigger a Keychain prompt from the browser's cookie store, so API keys are the recommended route. diff --git a/website/src/layouts/main.astro b/website/src/layouts/main.astro index e5e81687..b30a93a8 100644 --- a/website/src/layouts/main.astro +++ b/website/src/layouts/main.astro @@ -89,7 +89,8 @@ const { > - + +