diff --git a/PLANS.md b/PLANS.md new file mode 100644 index 000000000..94fade335 --- /dev/null +++ b/PLANS.md @@ -0,0 +1,25 @@ +# Plans + +This file tracks multi-step implementation plans for repository work. Keep +entries concise and update them when a task changes scope. + +## VS Code Slash Commands And ACP Runtime + +Owner: project-lead +Status: active + +Acceptance gates: +- Slash command catalog includes canonical commands, aliases, and argument + hints from the agent. +- Commands with subcommands expose keyboard-selectable first-level options. +- `/mcp enable`, `/mcp disable`, and `/mcp reconnect` expose configured server + names as second-level options when known. +- ACP/headless slash command execution completes without relying on terminal + Ink effects. +- Verification includes typecheck, Biome lint, unit tests, extension smoke, and + ACP smoke. + +Stop conditions: +- All verification commands pass. +- No known slash-command execution path remains stuck in pending state. +- Any remaining limitation has a concrete owner and test plan. diff --git a/biome.json b/biome.json index debb5e3e4..297e5ebe6 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.10/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.13/schema.json", "vcs": { "enabled": true, "clientKind": "git", @@ -81,6 +81,11 @@ "enabled": false } }, + "css": { + "parser": { + "tailwindDirectives": true + } + }, "javascript": { "formatter": { "quoteStyle": "single", diff --git a/build.ts b/build.ts index 6a4c9321e..252930666 100644 --- a/build.ts +++ b/build.ts @@ -6,7 +6,7 @@ import { DEFAULT_BUILD_FEATURES } from './scripts/defines.ts' const outdir = 'dist' // Step 1: Clean output directory -const { rmSync } = await import('fs') +const { existsSync, rmSync } = await import('fs') rmSync(outdir, { recursive: true, force: true }) // Collect FEATURE_* env vars → Bun.build features @@ -80,7 +80,20 @@ const vendorDir = join(outdir, 'vendor', 'audio-capture') await cp('vendor/audio-capture', vendorDir, { recursive: true }) console.log(`Copied vendor/audio-capture/ → ${vendorDir}/`) -// Step 5: Generate cli-bun and cli-node executable entry points +// Step 5: Copy postinstall-managed ripgrep vendor binary when present. +// If it is absent, runtime falls back to PATH rg so Glob/Grep still work. +const ripgrepSourceDir = join('src', 'utils', 'vendor', 'ripgrep') +if (existsSync(ripgrepSourceDir)) { + const ripgrepVendorDir = join(outdir, 'vendor', 'ripgrep') + await cp(ripgrepSourceDir, ripgrepVendorDir, { recursive: true }) + console.log(`Copied ${ripgrepSourceDir}/ → ${ripgrepVendorDir}/`) +} else { + console.warn( + `Skipped ripgrep vendor copy: ${ripgrepSourceDir}/ does not exist`, + ) +} + +// Step 6: Generate cli-bun and cli-node executable entry points const cliBun = join(outdir, 'cli-bun.js') const cliNode = join(outdir, 'cli-node.js') diff --git a/bun.lock b/bun.lock index d27afe1ec..183e186e4 100644 --- a/bun.lock +++ b/bun.lock @@ -5,7 +5,7 @@ "": { "name": "claude-code-best", "dependencies": { - "@agentclientprotocol/sdk": "^0.19.0", + "@agentclientprotocol/sdk": "^0.19.2", "@claude-code-best/mcp-chrome-bridge": "^3.0.1", "highlight.js": "^11.11.1", "ws": "^8.20.0", @@ -17,29 +17,29 @@ "@ant/computer-use-mcp": "workspace:*", "@ant/computer-use-swift": "workspace:*", "@ant/model-provider": "workspace:*", - "@anthropic-ai/bedrock-sdk": "^0.26.4", - "@anthropic-ai/claude-agent-sdk": "^0.2.114", + "@anthropic-ai/bedrock-sdk": "^0.29.0", + "@anthropic-ai/claude-agent-sdk": "^0.2.119", "@anthropic-ai/foundry-sdk": "^0.2.3", "@anthropic-ai/mcpb": "^2.1.2", "@anthropic-ai/sandbox-runtime": "^0.0.44", - "@anthropic-ai/sdk": "^0.80.0", + "@anthropic-ai/sdk": "^0.81.0", "@anthropic-ai/vertex-sdk": "^0.14.4", "@anthropic/ink": "workspace:*", - "@aws-sdk/client-bedrock": "^3.1032.0", - "@aws-sdk/client-bedrock-runtime": "^3.1032.0", - "@aws-sdk/client-sts": "^3.1032.0", - "@aws-sdk/credential-provider-node": "^3.972.32", - "@aws-sdk/credential-providers": "^3.1032.0", + "@aws-sdk/client-bedrock": "^3.1037.0", + "@aws-sdk/client-bedrock-runtime": "^3.1037.0", + "@aws-sdk/client-sts": "^3.1037.0", + "@aws-sdk/credential-provider-node": "^3.972.36", + "@aws-sdk/credential-providers": "^3.1037.0", "@azure/identity": "^4.13.1", - "@biomejs/biome": "^2.4.12", + "@biomejs/biome": "^2.4.13", "@claude-code-best/agent-tools": "workspace:*", "@claude-code-best/builtin-tools": "workspace:*", "@claude-code-best/mcp-client": "workspace:*", "@claude-code-best/weixin": "workspace:*", "@commander-js/extra-typings": "^14.0.0", "@growthbook/growthbook": "^1.6.5", - "@langfuse/otel": "^5.1.0", - "@langfuse/tracing": "^5.1.0", + "@langfuse/otel": "^5.2.0", + "@langfuse/tracing": "^5.2.0", "@modelcontextprotocol/sdk": "^1.29.0", "@opentelemetry/api": "^1.9.1", "@opentelemetry/api-logs": "^0.214.0", @@ -59,10 +59,10 @@ "@opentelemetry/sdk-metrics": "^2.7.0", "@opentelemetry/sdk-trace-base": "^2.7.0", "@opentelemetry/semantic-conventions": "^1.40.0", - "@sentry/node": "^10.49.0", - "@smithy/core": "^3.23.15", - "@smithy/node-http-handler": "^4.5.3", - "@types/bun": "^1.3.12", + "@sentry/node": "^10.50.0", + "@smithy/core": "^3.23.17", + "@smithy/node-http-handler": "^4.6.1", + "@types/bun": "^1.3.13", "@types/cacache": "^20.0.1", "@types/he": "^1.2.3", "@types/lodash-es": "^4.17.12", @@ -79,11 +79,11 @@ "@types/stack-utils": "^2.0.3", "@types/turndown": "^5.0.6", "@types/ws": "^8.18.1", - "ajv": "^8.18.0", + "ajv": "^8.20.0", "asciichart": "^1.5.25", "audio-capture-napi": "workspace:*", "auto-bind": "^5.0.1", - "axios": "^1.15.0", + "axios": "^1.15.2", "bidi-js": "^1.0.3", "cacache": "^20.0.4", "chalk": "^5.6.2", @@ -107,7 +107,7 @@ "image-processor-napi": "workspace:*", "indent-string": "^5.0.0", "jsonc-parser": "^3.3.1", - "knip": "^6.4.1", + "knip": "^6.6.3", "lodash-es": "^4.18.1", "lru-cache": "^11.3.5", "marked": "^17.0.6", @@ -136,7 +136,7 @@ "undici": "^7.25.0", "url-handler-napi": "workspace:*", "usehooks-ts": "^3.1.1", - "vite": "^8.0.8", + "vite": "^8.0.10", "vscode-jsonrpc": "^8.2.1", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-types": "^3.17.5", @@ -192,7 +192,7 @@ "name": "@ant/model-provider", "version": "1.0.0", "dependencies": { - "@anthropic-ai/sdk": "^0.80.0", + "@anthropic-ai/sdk": "^0.81.0", "openai": "^6.33.0", }, }, @@ -208,7 +208,7 @@ "@hono/node-ws": "^1.0.5", "@stricli/auto-complete": "^1.2.4", "@stricli/core": "^1.2.4", - "hono": "^4.7.0", + "hono": "^4.12.15", "pino": "^10.3.0", "pino-pretty": "^13.1.3", "selfsigned": "^5.5.0", @@ -289,7 +289,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", - "hono": "^4.7.0", + "hono": "^4.12.15", "jsqr": "^1.4.0", "lucide-react": "^0.555.0", "motion": "^12.29.2", @@ -304,7 +304,7 @@ "streamdown": "^1.6.8", "tailwind-merge": "^3.3.1", "use-stick-to-bottom": "^1.1.1", - "uuid": "^11.0.0", + "uuid": "^14.0.0", }, "devDependencies": { "@tailwindcss/vite": "^4.0.0", @@ -325,6 +325,23 @@ "name": "url-handler-napi", "version": "1.0.0", }, + "packages/vscode-extension": { + "name": "ccb-vscode", + "version": "0.3.0", + "dependencies": { + "@agentclientprotocol/sdk": "^0.19.0", + "marked": "^15.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "zod": "^3.25.0", + }, + "devDependencies": { + "@types/node": "^22", + "@types/vscode": "^1.85.0", + "esbuild": "^0.28.0", + "typescript": "^5.5.0", + }, + }, "packages/weixin": { "name": "@claude-code-best/weixin", "version": "1.0.0", @@ -333,8 +350,19 @@ }, }, }, + "overrides": { + "@xmldom/xmldom": "0.8.13", + "esbuild": "0.28.0", + "fast-xml-parser": "5.7.1", + "follow-redirects": "1.16.0", + "hono": "4.12.15", + "postcss": "8.5.10", + "protobufjs": "7.5.5", + "tmp": "0.2.5", + "uuid": "14.0.0", + }, "packages": { - "@agentclientprotocol/sdk": ["@agentclientprotocol/sdk@0.19.0", "https://registry.npmmirror.com/@agentclientprotocol/sdk/-/sdk-0.19.0.tgz", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-U9I8ws9WTOk6jCBAWpXefGSDgVXn14/kV6HFzwWGcstQ02mOQgClMAROHmoIn9GqZbDBDEOkdIbP4P4TEMQdug=="], + "@agentclientprotocol/sdk": ["@agentclientprotocol/sdk@0.19.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-G1Qi50Kc2GZxYjvH6t6yG8KFZMVe5vWTzZH4c7ylb0yiqMfNQSBDHPy0FMxYLPsorMqlM+eyV4yRp4oeUjl/Lw=="], "@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.104", "https://registry.npmmirror.com/@ai-sdk/gateway/-/gateway-3.0.104.tgz", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZKX5n74io8VIRlhIMSLWVlvT3sXC8Z7cZ9GHuWBWZDVi96+62AIsWuLGvMfcBA1STYuSoDrp6rIziZmvrTq0TA=="], @@ -358,25 +386,25 @@ "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "https://registry.npmmirror.com/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], - "@anthropic-ai/bedrock-sdk": ["@anthropic-ai/bedrock-sdk@0.26.4", "https://registry.npmmirror.com/@anthropic-ai/bedrock-sdk/-/bedrock-sdk-0.26.4.tgz", { "dependencies": { "@anthropic-ai/sdk": ">=0.50.3 <1", "@aws-crypto/sha256-js": "^4.0.0", "@aws-sdk/client-bedrock-runtime": "^3.797.0", "@aws-sdk/credential-providers": "^3.796.0", "@smithy/eventstream-serde-node": "^2.0.10", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/protocol-http": "^3.0.6", "@smithy/signature-v4": "^3.1.1", "@smithy/smithy-client": "^2.1.9", "@smithy/types": "^2.3.4", "@smithy/util-base64": "^2.0.0" } }, "sha512-0Z2NY3T2wnzT9esRit6BiWpQXvL+F2b3z3Z9in3mXh7MDf122rVi2bcPowQHmo9ITXAPJmv/3H3t0V1z3Fugfw=="], + "@anthropic-ai/bedrock-sdk": ["@anthropic-ai/bedrock-sdk@0.29.0", "", { "dependencies": { "@anthropic-ai/sdk": ">=0.50.3 <1", "@aws-crypto/sha256-js": "^4.0.0", "@aws-sdk/client-bedrock-runtime": "^3.797.0", "@aws-sdk/credential-providers": "^3.796.0", "@smithy/eventstream-serde-node": "^2.0.10", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/protocol-http": "^3.0.6", "@smithy/signature-v4": "^3.1.1", "@smithy/smithy-client": "^2.1.9", "@smithy/types": "^2.3.4", "@smithy/util-base64": "^2.0.0" } }, "sha512-7yUCF1QYHrrLcodCyRDoEDORbcBVUw2DQW4sk7oaP8TK2e8ArvQsuF8Z9HoCqT8V21zNK5T6xnwpidJZ4JNupA=="], - "@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.2.114", "", { "dependencies": { "@anthropic-ai/sdk": "^0.81.0", "@modelcontextprotocol/sdk": "^1.29.0" }, "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.2.114", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.2.114", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.2.114", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.2.114", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.2.114", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.2.114", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.2.114", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.2.114" }, "peerDependencies": { "zod": "^4.0.0" } }, "sha512-plJ+j17jew9tDMHir/90hXrwoB8cZ9GrIyG19zIJcFyQ8pVhRXjZRJCtF2ElfPoiwkxMmNu1Klqyui4xP4shPg=="], + "@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.2.119", "", { "dependencies": { "@anthropic-ai/sdk": "^0.81.0", "@modelcontextprotocol/sdk": "^1.29.0" }, "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.2.119", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.2.119", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.2.119", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.2.119", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.2.119", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.2.119", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.2.119", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.2.119" }, "peerDependencies": { "zod": "^4.0.0" } }, "sha512-6AvthpsaOTlkn514brSGOcCSLHDXODnU+ExN1O3CJCjxr5RBcmzR057C9EIM0G7IchnXsRfMZgRO1QKsjTXdbA=="], - "@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.2.114", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0/6LWrNilWpmiX6Xrj5plsBmCrCdKGERgAlKUZQEJZplnfuweFAJu7WXZB4KBaUpGlPO91zB/yqDh6kp5aZFbA=="], + "@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.2.119", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kxnG37SZqUata2Jcp/YQ0n9Y7o/sinE/8LdG4ltM1gePh+z+0Mfa4vBUUTEBMBFth9PTovKoesIuVuyFpvO/Cw=="], - "@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.2.114", "", { "os": "darwin", "cpu": "x64" }, "sha512-sOHxq1rEO/KZg2iEZILTPn62lMRRMPqtxKx41uGLi3xjVDrAej6Ury9dDZjYBKkK9n4kBylXV0Oom2CZ14dDYw=="], + "@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.2.119", "", { "os": "darwin", "cpu": "x64" }, "sha512-9Aj8g3ELsmZuOFg17TCkikeg/Wt2ucVT8hOOPQUatzLd7BKhydrHLA0RP42nBpWECO1B/n/mPdQ4iS/LS3s2Fg=="], - "@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.2.114", "", { "os": "linux", "cpu": "arm64" }, "sha512-j/SfEoN6+fyEsp8EuPe+xKcGfsZtaBmdUUH+YSRk5H/lYgy38yNsDhdt+AJMQcdMKfHsiwZ3Y9Ajoe9G9wNwHQ=="], + "@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.2.119", "", { "os": "linux", "cpu": "arm64" }, "sha512-v3o464XkiYehp/OKidQQirxdVb+aGSvdJvHF2zH9p33W8M/NC21zwwh4dhwDnKsyrtBIgkt2CcMwzIl30r0OtA=="], - "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.2.114", "", { "os": "linux", "cpu": "arm64" }, "sha512-Mhd7bumTwWvkgjSJnYvCgyt8DfmLiUoK92mfvAKxHX7i5YSw+h5Kprqh2Cap+2SBbpwZvnwIoEYGCxhGwE5ddg=="], + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.2.119", "", { "os": "linux", "cpu": "arm64" }, "sha512-IPGWgtz+gGnD7fxKAvSf913EUT/lYBTBE8EZ7lh3+x5ZP2859LWLmrCm053Lf3nMWo/CWikZsVPwkDVwpz6tIQ=="], - "@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.2.114", "", { "os": "linux", "cpu": "x64" }, "sha512-wbaExKDleLlm2zHEhb74GKMLVhtO0IUmFhdimQcdL6CdTkmDE8ZJi53tYWE9+jq+XWNRXoM2yEmKPzXoUmsJng=="], + "@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.2.119", "", { "os": "linux", "cpu": "x64" }, "sha512-9ePt4ZN+hsqDw4AgS4KtcWIGKfL9Oq28kwkrTER/QAcSrVKxiLonp81cCLzg7Ok/IUJu4Cfd71GZbFv/WE54zw=="], - "@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.2.114", "", { "os": "linux", "cpu": "x64" }, "sha512-c1URsameGHAcghen+mY6jvr2oypiAPHXJIdP4huxR25zPdXWv2x+BCy+vcRVeajsq4VmFzAyQJwaM+BXkmXjAw=="], + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.2.119", "", { "os": "linux", "cpu": "x64" }, "sha512-QYxFNAe4FFridPkKhGlNcNBJ0TaIygWYyvfI9g4kX0i+RVbresUWuZVkWY06ioJ0fXoixFJ+HNQBMB7dLrIp8Q=="], - "@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.2.114", "", { "os": "win32", "cpu": "arm64" }, "sha512-qeWdUpQymcKCA92osPmffG4QogrOSvuffPvm6c2OlMDjCPYs8vKG7bSe1Vq5tP9tfBszKPVJWBDh+2ANkNissQ=="], + "@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.2.119", "", { "os": "win32", "cpu": "arm64" }, "sha512-p/TjcKQvkCYtXGPlR+mdyNwqCmvRcQL34Wtq0yUZ+iqmI/eyCe59IJ3AZrE0EZoqmiAevEYzatPIt9sncC9uxw=="], - "@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.2.114", "", { "os": "win32", "cpu": "x64" }, "sha512-nVr43WwsKvWA6rojw15qBS/f31srukdLxy1KwKzpftlpmkzQ9Lh8uhIafOmoIPzz67f8VJ8JqHE0caA5YrhX9A=="], + "@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.2.119", "", { "os": "win32", "cpu": "x64" }, "sha512-k98Ju0wtktm6FhqTE/cXlVr6K4kGqBolVjEGzeKkW6ZILc7124euwNapAvkQCwMAavAxS/ZnO3jdKMtHtwTVTA=="], "@anthropic-ai/foundry-sdk": ["@anthropic-ai/foundry-sdk@0.2.3", "https://registry.npmmirror.com/@anthropic-ai/foundry-sdk/-/foundry-sdk-0.2.3.tgz", { "dependencies": { "@anthropic-ai/sdk": ">=0.50.3 <1" } }, "sha512-pD5yYnAeem5s8wDLbdf8/N8CejF/edRd9TJV+0PrT9tLKv6ggQimnr7d05pQn6FrIYACPmty9hekCo2JgepP0w=="], @@ -384,7 +412,7 @@ "@anthropic-ai/sandbox-runtime": ["@anthropic-ai/sandbox-runtime@0.0.44", "https://registry.npmmirror.com/@anthropic-ai/sandbox-runtime/-/sandbox-runtime-0.0.44.tgz", { "dependencies": { "@pondwader/socks5-server": "^1.0.10", "@types/lodash-es": "^4.17.12", "commander": "^12.1.0", "lodash-es": "^4.17.23", "shell-quote": "^1.8.3", "zod": "^3.24.1" }, "bin": { "srt": "dist/cli.js" } }, "sha512-mmyjq0mzsHnQZyiU+FGYyaiJcPckuQpP78VB8iqFi2IOu8rcb9i5SmaOKyJENJNfY8l/1grzLMQgWq4Apvmozw=="], - "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.80.0", "https://registry.npmmirror.com/@anthropic-ai/sdk/-/sdk-0.80.0.tgz", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-WeXLn7zNVk3yjeshn+xZHvld6AoFUOR3Sep6pSoHho5YbSi6HwcirqgPA5ccFuW8QTVJAAU7N8uQQC6Wa9TG+g=="], + "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.81.0", "https://registry.npmmirror.com/@anthropic-ai/sdk/-/sdk-0.81.0.tgz", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-D4K5PvEV6wPiRtVlVsJHIUhHAmOZ6IT/I9rKlTf84gR7GyyAurPJK7z9BOf/AZqC5d1DhYQGJNKRmV+q8dGhgw=="], "@anthropic-ai/vertex-sdk": ["@anthropic-ai/vertex-sdk@0.14.4", "https://registry.npmmirror.com/@anthropic-ai/vertex-sdk/-/vertex-sdk-0.14.4.tgz", { "dependencies": { "@anthropic-ai/sdk": ">=0.50.3 <1", "google-auth-library": "^9.4.2" } }, "sha512-BZUPRWghZxfSFtAxU563wH+jfWBPoedAwsVxG35FhmNsjeV8tyfN+lFriWhCpcZApxA4NdT6Soov+PzfnxxD5g=="], @@ -402,35 +430,35 @@ "@aws-crypto/util": ["@aws-crypto/util@4.0.0", "https://registry.npmmirror.com/@aws-crypto/util/-/util-4.0.0.tgz", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } }, "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ=="], - "@aws-sdk/client-bedrock": ["@aws-sdk/client-bedrock@3.1032.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.1", "@aws-sdk/credential-provider-node": "^3.972.32", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.31", "@aws-sdk/region-config-resolver": "^3.972.12", "@aws-sdk/token-providers": "3.1032.0", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.7", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.17", "@smithy/config-resolver": "^4.4.16", "@smithy/core": "^3.23.15", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-retry": "^4.5.3", "@smithy/middleware-serde": "^4.2.18", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.5.3", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.47", "@smithy/util-defaults-mode-node": "^4.2.52", "@smithy/util-endpoints": "^3.4.1", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-r8SoLJ0RyGUaNqRMMCr7X4Y9atZtcyWsK4b7HkJZm4IFHJm3AVtTOZrc/xLAmhjy9peOoNCMcRPBmBjfEiHgiw=="], + "@aws-sdk/client-bedrock": ["@aws-sdk/client-bedrock@3.1037.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.5", "@aws-sdk/credential-provider-node": "^3.972.36", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.35", "@aws-sdk/region-config-resolver": "^3.972.13", "@aws-sdk/token-providers": "3.1037.0", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.8", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.21", "@smithy/config-resolver": "^4.4.17", "@smithy/core": "^3.23.17", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-retry": "^4.5.5", "@smithy/middleware-serde": "^4.2.20", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.6.1", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.49", "@smithy/util-defaults-mode-node": "^4.2.54", "@smithy/util-endpoints": "^3.4.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.4", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XGuJ86vuuEsqp0Gq8fMCSMd/VNCwqTvKwFT99SU2OOLyNp31ChZ+LdIckJZl/A3jpUyZYpXjn7IxP/N/6UFiZA=="], - "@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.1032.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.1", "@aws-sdk/credential-provider-node": "^3.972.32", "@aws-sdk/eventstream-handler-node": "^3.972.14", "@aws-sdk/middleware-eventstream": "^3.972.10", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.31", "@aws-sdk/middleware-websocket": "^3.972.16", "@aws-sdk/region-config-resolver": "^3.972.12", "@aws-sdk/token-providers": "3.1032.0", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.7", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.17", "@smithy/config-resolver": "^4.4.16", "@smithy/core": "^3.23.15", "@smithy/eventstream-serde-browser": "^4.2.14", "@smithy/eventstream-serde-config-resolver": "^4.3.14", "@smithy/eventstream-serde-node": "^4.2.14", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-retry": "^4.5.3", "@smithy/middleware-serde": "^4.2.18", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.5.3", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.47", "@smithy/util-defaults-mode-node": "^4.2.52", "@smithy/util-endpoints": "^3.4.1", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.2", "@smithy/util-stream": "^4.5.23", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-fSRz/48As9c3DeS+9ZWd7kk9171pJntCCuehHBDeprD9CPF+C+ATaVNJ5SOLE5RIBR2IHOVTwjAgJt/nkS/6Yg=="], + "@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.1037.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.5", "@aws-sdk/credential-provider-node": "^3.972.36", "@aws-sdk/eventstream-handler-node": "^3.972.14", "@aws-sdk/middleware-eventstream": "^3.972.10", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.35", "@aws-sdk/middleware-websocket": "^3.972.16", "@aws-sdk/region-config-resolver": "^3.972.13", "@aws-sdk/token-providers": "3.1037.0", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.8", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.21", "@smithy/config-resolver": "^4.4.17", "@smithy/core": "^3.23.17", "@smithy/eventstream-serde-browser": "^4.2.14", "@smithy/eventstream-serde-config-resolver": "^4.3.14", "@smithy/eventstream-serde-node": "^4.2.14", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-retry": "^4.5.5", "@smithy/middleware-serde": "^4.2.20", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.6.1", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.49", "@smithy/util-defaults-mode-node": "^4.2.54", "@smithy/util-endpoints": "^3.4.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.4", "@smithy/util-stream": "^4.5.25", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Evla4DUdBf1pQpQa7pbfquj7jRaRktkI0qGoWBJBXWB9wQISzJ8OEI4sHugk/W6SF47C7hMP/o3Z/XBrfnejCw=="], - "@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.1032.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.1", "@aws-sdk/credential-provider-node": "^3.972.32", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.31", "@aws-sdk/region-config-resolver": "^3.972.12", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.7", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.17", "@smithy/config-resolver": "^4.4.16", "@smithy/core": "^3.23.15", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-retry": "^4.5.3", "@smithy/middleware-serde": "^4.2.18", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.5.3", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.47", "@smithy/util-defaults-mode-node": "^4.2.52", "@smithy/util-endpoints": "^3.4.1", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-TVgbjyb1fJoHZDoBAmW85hNcx00zxi5qXFG3wvS/2C213Q2PusCQIih7Zlub9mKE3iRtES5epxazFmp8jVeLyQ=="], + "@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.1037.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.5", "@aws-sdk/credential-provider-node": "^3.972.36", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.35", "@aws-sdk/region-config-resolver": "^3.972.13", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.8", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.21", "@smithy/config-resolver": "^4.4.17", "@smithy/core": "^3.23.17", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-retry": "^4.5.5", "@smithy/middleware-serde": "^4.2.20", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.6.1", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.49", "@smithy/util-defaults-mode-node": "^4.2.54", "@smithy/util-endpoints": "^3.4.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.4", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-/BQAyz98JRQFg3E8de3fGGydIYnsFRd6Cla4+zkviOe641fLCG0ZkPIk9D22HSi8qy9XKx+zk6ed2PcLO8uuPw=="], - "@aws-sdk/client-sts": ["@aws-sdk/client-sts@3.1032.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.1", "@aws-sdk/credential-provider-node": "^3.972.32", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.31", "@aws-sdk/region-config-resolver": "^3.972.12", "@aws-sdk/signature-v4-multi-region": "^3.996.18", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.7", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.17", "@smithy/config-resolver": "^4.4.16", "@smithy/core": "^3.23.15", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-retry": "^4.5.3", "@smithy/middleware-serde": "^4.2.18", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.5.3", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.47", "@smithy/util-defaults-mode-node": "^4.2.52", "@smithy/util-endpoints": "^3.4.1", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FCLc5VWb+yz1xb/Jv0sXFGqIIs+bHZQWBKbPQKCuypF3wU/7UFygXuSXo9uJfwISKNGVHJwp+0136f8mqmzRcA=="], + "@aws-sdk/client-sts": ["@aws-sdk/client-sts@3.1037.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.5", "@aws-sdk/credential-provider-node": "^3.972.36", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.35", "@aws-sdk/region-config-resolver": "^3.972.13", "@aws-sdk/signature-v4-multi-region": "^3.996.22", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.8", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.21", "@smithy/config-resolver": "^4.4.17", "@smithy/core": "^3.23.17", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-retry": "^4.5.5", "@smithy/middleware-serde": "^4.2.20", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.6.1", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.49", "@smithy/util-defaults-mode-node": "^4.2.54", "@smithy/util-endpoints": "^3.4.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.4", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Ye+BEvy1Fd/JtqfF1T9PiodIU52/Cd9sP4oBLnj8QQEyYRUcYG1OQ2xIFXF/gzAAMjfVN8HqGJo9LxdmScxZAQ=="], - "@aws-sdk/core": ["@aws-sdk/core@3.974.1", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@aws-sdk/xml-builder": "^3.972.18", "@smithy/core": "^3.23.15", "@smithy/node-config-provider": "^4.3.14", "@smithy/property-provider": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/signature-v4": "^5.3.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-gy/gffKz0zaHDaqRiLCdIvgHmaAL/HXuAtMcBP7euYSFx4BsbsdlfmUBJag+Gqe62z6/XuloKyQyaiH+kS3Vrg=="], + "@aws-sdk/core": ["@aws-sdk/core@3.974.5", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@aws-sdk/xml-builder": "^3.972.19", "@smithy/core": "^3.23.17", "@smithy/node-config-provider": "^4.3.14", "@smithy/property-provider": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/signature-v4": "^5.3.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.4", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-lMPlYlYfQdNZhlkJgnkmESwrY+hNh3PljmZ+37oAqLNdJ6rnILAwFSyc6B3bJeDOtMORNnMQIej0aTRuOlDyhQ=="], - "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.24", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.996.21", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-i6eMWlKfgQkNY3S/kg1ZnBZm2lhd6r8B3yobCalvrfCCGjvthREwsyDViuWl7gOWSvuUjQEFFGcJhGbCstcqJg=="], + "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.28", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.997.3", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-UXhc4FfxbfNaIqycDnIZ+W8CMAoCtcJJfZkq+cWSUwQRN0V0d0uAoN2qCFyKZip8inlHeKJmNQsPliKKcElP8Q=="], - "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-xfUt2CUZDC+Tf16A6roD1b4pk/nrXdkoLY3TEhv198AXDtBo5xUJP1zd0e8SmuKLN4PpIBX96OizZbmMlcI6oQ=="], + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.31", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-X/yGB73LmDW/6MdDJGCDzZBUXnM3ys4vs9l+5ZTJmiEswDdP1OjeoAFlFjVGS9o4KB2wZWQ9KOfdVNSSK6Ep3w=="], - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/types": "^3.973.8", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/node-http-handler": "^4.5.3", "@smithy/property-provider": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-hjNeYb6oLyHgMihra83ie0J/T2y9om3cy1qC90h9DRgvYXEoN4BCFf8bHguZjKhXunnv7YkmZRuYL5Mkk77eCA=="], + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.33", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/types": "^3.973.8", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/node-http-handler": "^4.6.1", "@smithy/property-provider": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-c0ZF+lwoWVvX5iCaGKL5T/4DnIw88CGqxA0BcBs3U86mIp5EZYPVg+KSPkMXOyokmADvNewiMUfSG2uFwjRp0g=="], - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.31", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/credential-provider-env": "^3.972.27", "@aws-sdk/credential-provider-http": "^3.972.29", "@aws-sdk/credential-provider-login": "^3.972.31", "@aws-sdk/credential-provider-process": "^3.972.27", "@aws-sdk/credential-provider-sso": "^3.972.31", "@aws-sdk/credential-provider-web-identity": "^3.972.31", "@aws-sdk/nested-clients": "^3.996.21", "@aws-sdk/types": "^3.973.8", "@smithy/credential-provider-imds": "^4.2.14", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-PuQ7e8WYzAPpzvFcajxf8c0LqSzakVHVlKw8M0oubk8Kf347YOCCqT1seQrHs5AdZuIh2RD9LX4O+Xa5ImEBfQ=="], + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.35", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/credential-provider-env": "^3.972.31", "@aws-sdk/credential-provider-http": "^3.972.33", "@aws-sdk/credential-provider-login": "^3.972.35", "@aws-sdk/credential-provider-process": "^3.972.31", "@aws-sdk/credential-provider-sso": "^3.972.35", "@aws-sdk/credential-provider-web-identity": "^3.972.35", "@aws-sdk/nested-clients": "^3.997.3", "@aws-sdk/types": "^3.973.8", "@smithy/credential-provider-imds": "^4.2.14", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-jsU4u/cRkKFLKQS0k918FQ27fzXLG5ENiLWQMYE6581zLeI2hWh04ptlrvZMB3wJT/5d+vSzJk74X1CMFr4y8Q=="], - "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.31", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/nested-clients": "^3.996.21", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-bBmWDmtSpmLOZR6a0kmowBcVL1hiL8Vlap/RXeMpFd7JbWl87YcwqL6T9LH/0oBVEZXu1dUZAtojgSuZgMO5xw=="], + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.35", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/nested-clients": "^3.997.3", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-5oa3j0cA50jPqgNhZ9XdJVopuzUf1klRb28/2MfLYWWiPi9DRVvbrBWT+DidbHTT36520VuXZJahQwR+YgSjrg=="], - "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.32", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.27", "@aws-sdk/credential-provider-http": "^3.972.29", "@aws-sdk/credential-provider-ini": "^3.972.31", "@aws-sdk/credential-provider-process": "^3.972.27", "@aws-sdk/credential-provider-sso": "^3.972.31", "@aws-sdk/credential-provider-web-identity": "^3.972.31", "@aws-sdk/types": "^3.973.8", "@smithy/credential-provider-imds": "^4.2.14", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-9aj0x9hGYUondBZSD0XkksAdHhOKttFw4BWpLCeggeg40qSJxGrAP++g0GCm0VqWc1WtC/NRFiAVzPCy56vmog=="], + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.36", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.31", "@aws-sdk/credential-provider-http": "^3.972.33", "@aws-sdk/credential-provider-ini": "^3.972.35", "@aws-sdk/credential-provider-process": "^3.972.31", "@aws-sdk/credential-provider-sso": "^3.972.35", "@aws-sdk/credential-provider-web-identity": "^3.972.35", "@aws-sdk/types": "^3.973.8", "@smithy/credential-provider-imds": "^4.2.14", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-4nT2T8Z7vH8KE9EdjEsuIlHpZSlcaK2PrKbQBjuUGU46BCCzF3WvP0u0Uiosni3Ykmmn4rWLVawoOCLotUtCbg=="], - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-1CZvfb1WzudWWIFAVQkd1OI/T1RxPcSvNWzNsb2BMBVsBJzBtB8dV5f2nymHVU4UqwxipdVt/DAbgdDRf33JDg=="], + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.31", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-eKeT4MXumpBJsrDLCYcSzIkFPVTFn/es7It2oogp2OhU/ic7P/+xzFpQx9ZhwtXS57Mc5S42BPWi7lHmvs/nYg=="], - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.31", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/nested-clients": "^3.996.21", "@aws-sdk/token-providers": "3.1032.0", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-x8Mx18S48XMl9bEEpYwmXDTvjWGPIfDadReN37Lc099/DUrlL4Zs9T9rwwggo6DkKS1aev6v+MTUx7JTa87TZQ=="], + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.35", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/nested-clients": "^3.997.3", "@aws-sdk/token-providers": "3.1036.0", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-bCuBdfnj0KGDMdLp6utMTLiJcFN2ek9EgZinxQZZSc3FxjJ/HSqeqab2cjbnoNfy8RM6suDCsRkmVY1izp9I+A=="], - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.31", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/nested-clients": "^3.996.21", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-zfuNMIkGfjYsHis9qytYf74Bcmq6Ji9Xwf4w53baRCI/b2otTwZv3SW1uRiJ5Di7999QzRGhHZ96+eUeo3gSOA=="], + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.35", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/nested-clients": "^3.997.3", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-swW6Bwvl8lanyEMtZOWE/oR6yqcRQH4HTQZUVsnDVgoXvRjRywpYpLv2BWwjUFyjPrqsdX6FeTkf4tMSe/qFTQ=="], - "@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.1032.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.1032.0", "@aws-sdk/core": "^3.974.1", "@aws-sdk/credential-provider-cognito-identity": "^3.972.24", "@aws-sdk/credential-provider-env": "^3.972.27", "@aws-sdk/credential-provider-http": "^3.972.29", "@aws-sdk/credential-provider-ini": "^3.972.31", "@aws-sdk/credential-provider-login": "^3.972.31", "@aws-sdk/credential-provider-node": "^3.972.32", "@aws-sdk/credential-provider-process": "^3.972.27", "@aws-sdk/credential-provider-sso": "^3.972.31", "@aws-sdk/credential-provider-web-identity": "^3.972.31", "@aws-sdk/nested-clients": "^3.996.21", "@aws-sdk/types": "^3.973.8", "@smithy/config-resolver": "^4.4.16", "@smithy/core": "^3.23.15", "@smithy/credential-provider-imds": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/property-provider": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-OT+4/Kf62PKslLoJJGEzpQricgaMOuXFNf65FR56i3QugNLlNHfkhDWkk1CDvN1NYCHZbYZMJusdGjxVxQKgjQ=="], + "@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.1037.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.1037.0", "@aws-sdk/core": "^3.974.5", "@aws-sdk/credential-provider-cognito-identity": "^3.972.28", "@aws-sdk/credential-provider-env": "^3.972.31", "@aws-sdk/credential-provider-http": "^3.972.33", "@aws-sdk/credential-provider-ini": "^3.972.35", "@aws-sdk/credential-provider-login": "^3.972.35", "@aws-sdk/credential-provider-node": "^3.972.36", "@aws-sdk/credential-provider-process": "^3.972.31", "@aws-sdk/credential-provider-sso": "^3.972.35", "@aws-sdk/credential-provider-web-identity": "^3.972.35", "@aws-sdk/nested-clients": "^3.997.3", "@aws-sdk/types": "^3.973.8", "@smithy/config-resolver": "^4.4.17", "@smithy/core": "^3.23.17", "@smithy/credential-provider-imds": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/property-provider": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-TPPoQzfNkWltNgjJn3RRY1S8VXffDvv49xGGs9K0DrYS9LZCLLsoHmSmShx9HQusPc/4Oz23rfRWTolCU19PdQ=="], "@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.972.14", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@smithy/eventstream-codec": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-m4X56gxG76/CKfxNVbOFuYwnAZcHgS6HOH8lgp15HoGHIAVTcZfZrXvcYzJFOMLEJgVn+JHBu6EiNV+xSNXXFg=="], @@ -442,25 +470,25 @@ "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ=="], - "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.30", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-arn-parser": "^3.972.3", "@smithy/core": "^3.23.15", "@smithy/node-config-provider": "^4.3.14", "@smithy/protocol-http": "^5.3.14", "@smithy/signature-v4": "^5.3.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-stream": "^4.5.23", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-hoQRxjJu4tt3gEOQin21rJKotClJC+x7AmCh9ylRct1DJeaNI/BRlFxMbuhJe54bG6xANPagSs0my8K30QyV9g=="], + "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.34", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-arn-parser": "^3.972.3", "@smithy/core": "^3.23.17", "@smithy/node-config-provider": "^4.3.14", "@smithy/protocol-http": "^5.3.14", "@smithy/signature-v4": "^5.3.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-stream": "^4.5.25", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-/UL96JKjsjdodcRRMKl99tLQvK6Oi9ptLC9iU1yiTF/ruaDX0mtBBtnLNZDxIZRJOCVOtB49ed1YaTadqygk8Q=="], - "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.31", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.7", "@smithy/core": "^3.23.15", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-retry": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-L+hXN2HDomlIsWSHW5DVD7ppccCeRnlHXZ5uHG34ePTjF5bm0I1fmrJLbUGiW97xRXWryit5cjdP4Sx2FwiGog=="], + "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.35", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.8", "@smithy/core": "^3.23.17", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-retry": "^4.3.4", "tslib": "^2.6.2" } }, "sha512-hOFWNOjVmOocpRlrU04nYxjMOeoe0Obu5AXEuhB8zblMCPl3cG1hdluQCZERRKFyhMQjwZnDbhSHjoMUjetFGw=="], "@aws-sdk/middleware-websocket": ["@aws-sdk/middleware-websocket@3.972.16", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-format-url": "^3.972.10", "@smithy/eventstream-codec": "^4.2.14", "@smithy/eventstream-serde-browser": "^4.2.14", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/protocol-http": "^5.3.14", "@smithy/signature-v4": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-86+S9oCyRVGzoMRpQhxkArp7kD2K75GPmaNevd9B6EyNhWoNvnCZZ3WbgN4j7ZT+jvtvBCGZvI2XHsWZJ+BRIg=="], - "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.21", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.1", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.31", "@aws-sdk/region-config-resolver": "^3.972.12", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.7", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.17", "@smithy/config-resolver": "^4.4.16", "@smithy/core": "^3.23.15", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-retry": "^4.5.3", "@smithy/middleware-serde": "^4.2.18", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.5.3", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.47", "@smithy/util-defaults-mode-node": "^4.2.52", "@smithy/util-endpoints": "^3.4.1", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Me3d/ua2lb2G0bQfFmvCeQQp3+nN6GSPqMxDmi/IQlQ8CrlpQ5C0JJHpz2AnOUkEFI0lBNrAL3Vnt29l44ndkA=="], + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.3", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.5", "@aws-sdk/middleware-host-header": "^3.972.10", "@aws-sdk/middleware-logger": "^3.972.10", "@aws-sdk/middleware-recursion-detection": "^3.972.11", "@aws-sdk/middleware-user-agent": "^3.972.35", "@aws-sdk/region-config-resolver": "^3.972.13", "@aws-sdk/signature-v4-multi-region": "^3.996.22", "@aws-sdk/types": "^3.973.8", "@aws-sdk/util-endpoints": "^3.996.8", "@aws-sdk/util-user-agent-browser": "^3.972.10", "@aws-sdk/util-user-agent-node": "^3.973.21", "@smithy/config-resolver": "^4.4.17", "@smithy/core": "^3.23.17", "@smithy/fetch-http-handler": "^5.3.17", "@smithy/hash-node": "^4.2.14", "@smithy/invalid-dependency": "^4.2.14", "@smithy/middleware-content-length": "^4.2.14", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-retry": "^4.5.5", "@smithy/middleware-serde": "^4.2.20", "@smithy/middleware-stack": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/node-http-handler": "^4.6.1", "@smithy/protocol-http": "^5.3.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.49", "@smithy/util-defaults-mode-node": "^4.2.54", "@smithy/util-endpoints": "^3.4.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.4", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-SivE6GP228IVgfsrr2c/vqTg95X0Qj39Yw4uIrcddpkUzIltNMoNOR62leHOLhODfjv9K8X2mPTwS69A5kT0nQ=="], - "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.12", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@smithy/config-resolver": "^4.4.16", "@smithy/node-config-provider": "^4.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-QQI43Mxd53nBij0pm8HXC+t4IOC6gnhhZfzxE0OATQyO6QfPV4e+aTIRRuAJKA6Nig/cR8eLwPryqYTX9ZrjAQ=="], + "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.13", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@smithy/config-resolver": "^4.4.17", "@smithy/node-config-provider": "^4.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A=="], - "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.18", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "^3.972.30", "@aws-sdk/types": "^3.973.8", "@smithy/protocol-http": "^5.3.14", "@smithy/signature-v4": "^5.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-4KT8UXRmvNAP5zKq9UI1MIwbnmSChZncBt89RKu/skMqZSSWGkBZTAJsZ+no+txfmF3kVaUFv31CTBZkQ5BJpQ=="], + "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.22", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "^3.972.34", "@aws-sdk/types": "^3.973.8", "@smithy/protocol-http": "^5.3.14", "@smithy/signature-v4": "^5.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-/rXhMXteD+BqhFd0nYprAgcZ/KtU+963uftPqd3tiFcFfooHZINXUGtOmo2SQjRVauCTNqIEzkwuSETdZFqTTA=="], - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1032.0", "", { "dependencies": { "@aws-sdk/core": "^3.974.1", "@aws-sdk/nested-clients": "^3.996.21", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-n+PU8Z+gll7p3wDrH+Wo6fkt8sPrVnq30YYM6Ryga95oJlEneNMEbDHj0iqjMX3V7gaGdJo/hJWyPo4lscP+mA=="], + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1037.0", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/nested-clients": "^3.997.3", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-csxa484KboWLs3f8jFQ5v9RwH8FVf0fQ+SO3GSXyu4Jtinhh4qXmOWLSVX30RBpB933dZaKGHGEXzEEY88NqRw=="], "@aws-sdk/types": ["@aws-sdk/types@3.973.8", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw=="], "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.972.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA=="], - "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-endpoints": "^3.4.1", "tslib": "^2.6.2" } }, "sha512-ty4LQxN1QC+YhUP28NfEgZDEGXkyqOQy+BDriBozqHsrYO4JMgiPhfizqOGF7P+euBTZ5Ez6SKlLAMCLo8tzmw=="], + "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-endpoints": "^3.4.2", "tslib": "^2.6.2" } }, "sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g=="], "@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-DEKiHNJVtNxdyTeQspzY+15Po/kHm6sF0Cs4HV9Q2+lplB63+DrvdeiSoOSdWEWAoO2RcY1veoXVDz2tWxWCgQ=="], @@ -468,11 +496,11 @@ "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.8", "@smithy/types": "^4.14.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g=="], - "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.17", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.31", "@aws-sdk/types": "^3.973.8", "@smithy/node-config-provider": "^4.3.14", "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-utF5qjjbuJQuU9VdCkWl7L87sr93cApsrD+uxGfUnlafX8iyEzJrb7EZnufjThURZVTOtelRMXrblWxpefElUg=="], + "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.21", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.35", "@aws-sdk/types": "^3.973.8", "@smithy/node-config-provider": "^4.3.14", "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-Av4UHTcAWgdvbN0IP9pbtf4Qa1+6LtJqQdZWj5pLn5J67w0pnJJAZZ+7JPPcj2KN3378zD2JDM9DwJKEyvyMTQ=="], "@aws-sdk/util-utf8-browser": ["@aws-sdk/util-utf8-browser@3.259.0", "https://registry.npmmirror.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", { "dependencies": { "tslib": "^2.3.1" } }, "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw=="], - "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.18", "", { "dependencies": { "@smithy/types": "^4.14.1", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-BMDNVG1ETXRhl1tnisQiYBef3RShJ1kfZA7x7afivTFMLirfHNTb6U71K569HNXhSXbQZsweHvSDZ6euBw8hPA=="], + "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.19", "", { "dependencies": { "@smithy/types": "^4.14.1", "fast-xml-parser": "5.7.1", "tslib": "^2.6.2" } }, "sha512-Cw8IOMdBUEIl8ZlhRC3Dc/E64D5B5/8JhV6vhPLiPfJwcRC84S6F8aBOIi/N4vR9ZyA4I5Cc0Ateb/9EHaJXeQ=="], "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.4", "https://registry.npmmirror.com/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", {}, "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ=="], @@ -538,23 +566,23 @@ "@babel/types": ["@babel/types@7.29.0", "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], - "@biomejs/biome": ["@biomejs/biome@2.4.12", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.12", "@biomejs/cli-darwin-x64": "2.4.12", "@biomejs/cli-linux-arm64": "2.4.12", "@biomejs/cli-linux-arm64-musl": "2.4.12", "@biomejs/cli-linux-x64": "2.4.12", "@biomejs/cli-linux-x64-musl": "2.4.12", "@biomejs/cli-win32-arm64": "2.4.12", "@biomejs/cli-win32-x64": "2.4.12" }, "bin": { "biome": "bin/biome" } }, "sha512-Rro7adQl3NLq/zJCIL98eElXKI8eEiBtoeu5TbXF/U3qbjuSc7Jb5rjUbeHHcquDWeSf3HnGP7XI5qGrlRk/pA=="], + "@biomejs/biome": ["@biomejs/biome@2.4.13", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.13", "@biomejs/cli-darwin-x64": "2.4.13", "@biomejs/cli-linux-arm64": "2.4.13", "@biomejs/cli-linux-arm64-musl": "2.4.13", "@biomejs/cli-linux-x64": "2.4.13", "@biomejs/cli-linux-x64-musl": "2.4.13", "@biomejs/cli-win32-arm64": "2.4.13", "@biomejs/cli-win32-x64": "2.4.13" }, "bin": { "biome": "bin/biome" } }, "sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA=="], - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BnMU4Pc3ciEVteVpZ0BK33MLr7X57F5w1dwDLDn+/iy/yTrA4Q/N2yftidFtsA4vrDh0FMXDpacNV/Tl3fbmng=="], + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2KImO1jhNFBa2oWConyr0x6flxbQpGKv6902uGXpYM62Xyem8U80j441SyUJ8KyngsmKbQjeIv1q2CQfDkNnYg=="], - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-x9uJ0bI1rJsWICp3VH8w/5PnAVD3A7SqzDpbrfoUQX1QyWrK5jSU4fRLo/wSgGeplCivbxBRKmt5Xq4/nWvq8A=="], + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-BKrJklbaFN4p1Ts4kPBczo+PkbsHQg57kmJ+vON9u2t6uN5okYHaSr7h/MutPCWQgg2lglaWoSmm+zhYW+oOkg=="], - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-tOwuCuZZtKi1jVzbk/5nXmIsziOB6yqN8c9r9QM0EJYPU6DpQWf11uBOSCfFKKM4H3d9ZoarvlgMfbcuD051Pw=="], + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-NzkUDSqfvMBrPplKgVr3aXLHZ2NEELvvF4vZxXulEylKWIGqlvNEcwUcj9OLrn75TD3lJ/GIqCVlBwd1MZCuYQ=="], - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-FhfpkAAlKL6kwvcVap0Hgp4AhZmtd3YImg0kK1jd7C/aSoh4SfsB2f++yG1rU0lr8Y5MCFJrcSkmssiL9Xnnig=="], + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-U5MsuBQW25dXaYtqWWSPM3P96H6Y+fHuja3TQpMNnylocHW0tEbtFTDlUj6oM+YJLntvEkQy4grBvQNUD4+RCg=="], - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.12", "", { "os": "linux", "cpu": "x64" }, "sha512-8pFeAnLU9QdW9jCIslB/v82bI0lhBmz2ZAKc8pVMFPO0t0wAHsoEkrUQUbMkIorTRIjbqyNZHA3lEXavsPWYSw=="], + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Az3ZZedYRBo9EQzNnD9SxFcR1G5QsGo6VEc2hIyVPZ1rdKwee/7E9oeBBZFpE8Z44ekxsDQBqbiWGW5ShOhUSQ=="], - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.12", "", { "os": "linux", "cpu": "x64" }, "sha512-dwTIgZrGutzhkQCuvHynCkyW6hJxUuyZqKKO0YNfaS2GUoRO+tOvxXZqZB6SkWAOdfZTzwaw8IEdUnIkHKHoew=="], + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Z601MienRgTBDza/+u2CH3RSrWoXo9rtr8NK6A4KJzqGgfxx+H3VlyLgTJ4sRo40T3pIsqpTmiOQEvYzQvBRvQ=="], - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-B0DLnx0vA9ya/3v7XyCaP+/lCpnbWbMOfUFFve+xb5OxyYvdHaS55YsSddr228Y+JAFk58agCuZTsqNiw2a6ig=="], + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-Px9PS2B5/Q183bUwy/5VHqp3J2lzdOCeVGzMpphYfl8oSa7VDCqenBdqWpy6DCy/en4Rbf/Y1RieZF6dJPcc9A=="], - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.12", "", { "os": "win32", "cpu": "x64" }, "sha512-yMckRzTyZ83hkk8iDFWswqSdU8tvZxspJKnYNh7JZr/zhZNOlzH13k4ecboU6MurKExCe2HUkH75pGI/O2JwGA=="], + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.13", "", { "os": "win32", "cpu": "x64" }, "sha512-tTcMkXyBrmHi9BfrD2VNHs/5rYIUKETqsBlYOvSAABwBkJhSDVb5e7wPukftsQbO3WzQkXe6kaztC6WtUOXSoQ=="], "@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "https://registry.npmmirror.com/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="], @@ -586,57 +614,57 @@ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "https://registry.npmmirror.com/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.12.tgz", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.0", "", { "os": "android", "cpu": "arm" }, "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.0", "", { "os": "android", "cpu": "arm64" }, "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.12.tgz", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.0", "", { "os": "android", "cpu": "x64" }, "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.0", "", { "os": "linux", "cpu": "x64" }, "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.0", "", { "os": "none", "cpu": "arm64" }, "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.0", "", { "os": "none", "cpu": "x64" }, "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA=="], - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.0", "", { "os": "none", "cpu": "arm64" }, "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.0", "", { "os": "win32", "cpu": "x64" }, "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw=="], "@fastify/otel": ["@fastify/otel@0.18.0", "https://registry.npmmirror.com/@fastify/otel/-/otel-0.18.0.tgz", { "dependencies": { "@opentelemetry/core": "^2.0.0", "@opentelemetry/instrumentation": "^0.212.0", "@opentelemetry/semantic-conventions": "^1.28.0", "minimatch": "^10.2.4" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0" } }, "sha512-3TASCATfw+ctICSb4ymrv7iCm0qJ0N9CarB+CZ7zIJ7KqNbwI5JjyDL1/sxoC0ccTO1Zyd1iQ+oqncPg5FJXaA=="], @@ -752,11 +780,11 @@ "@js-sdsl/ordered-map": ["@js-sdsl/ordered-map@4.4.2", "https://registry.npmmirror.com/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", {}, "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="], - "@langfuse/core": ["@langfuse/core@5.1.0", "https://registry.npmmirror.com/@langfuse/core/-/core-5.1.0.tgz", { "peerDependencies": { "@opentelemetry/api": "^1.9.0" } }, "sha512-yFvC67HBtrY4B3tyzF8+RJaIqK79LBVXtAgtmEc2vhpKauecvSW0zevRnRynFX+ajUHqi9TN7tnD91FJszFLgQ=="], + "@langfuse/core": ["@langfuse/core@5.2.0", "", { "peerDependencies": { "@opentelemetry/api": "^1.9.0" } }, "sha512-zUD0vdrFN/LsufBfR6oPWCT4KIb4zeH8sZtF1YjKVTrPjR+WPWJJb9TI20PFByHo4XFJoLUXdTJNfMWtUx0iEg=="], - "@langfuse/otel": ["@langfuse/otel@5.1.0", "https://registry.npmmirror.com/@langfuse/otel/-/otel-5.1.0.tgz", { "dependencies": { "@langfuse/core": "^5.1.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/core": "^2.0.1", "@opentelemetry/exporter-trace-otlp-http": ">=0.202.0 <1.0.0", "@opentelemetry/sdk-trace-base": "^2.0.1" } }, "sha512-pvaXgZHMHqjsRjn+Gs5amrrq61w0Rxz1OChmLr2FfQzlymNl7+MxSXsWBj5dZQlufGbhyG+LT3wdx3MV8aLXHQ=="], + "@langfuse/otel": ["@langfuse/otel@5.2.0", "", { "dependencies": { "@langfuse/core": "^5.2.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/core": "^2.0.1", "@opentelemetry/exporter-trace-otlp-http": ">=0.202.0 <1.0.0", "@opentelemetry/sdk-trace-base": "^2.0.1" } }, "sha512-U2ArG13tjY7Ybl5K8QE91Igpg2HXoBHXQNqmnw9JNZYatSV/ABgLS6SlUGQS/i4qbdQT+9k6lK3GUf99D+6B4w=="], - "@langfuse/tracing": ["@langfuse/tracing@5.1.0", "https://registry.npmmirror.com/@langfuse/tracing/-/tracing-5.1.0.tgz", { "dependencies": { "@langfuse/core": "^5.1.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0" } }, "sha512-ScwYnQzqLZOaMPZkCsWizx139eb02GI8tD5yxs5XVjGNGZxKdw1DfRPTIONSlOhaAYCY9ILGTJdkqAtNTzsbRg=="], + "@langfuse/tracing": ["@langfuse/tracing@5.2.0", "", { "dependencies": { "@langfuse/core": "^5.2.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0" } }, "sha512-lMNkcwujfsEAHFiw9uJSTGd+90BwdeR1BVP3c/bANujkIfZ/nWhkTSO9IlRU5Gs4dMLAFqaPGEMVZaIgEPLquw=="], "@mermaid-js/parser": ["@mermaid-js/parser@1.1.0", "https://registry.npmmirror.com/@mermaid-js/parser/-/parser-1.1.0.tgz", { "dependencies": { "langium": "^4.0.0" } }, "sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw=="], @@ -764,15 +792,11 @@ "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.29.0", "https://registry.npmmirror.com/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz", { "dependencies": { "@hono/node-server": "^1.19.9", "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" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "https://registry.npmmirror.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], "@noble/hashes": ["@noble/hashes@1.4.0", "https://registry.npmmirror.com/@noble/hashes/-/hashes-1.4.0.tgz", {}, "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="], - "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], - - "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], - - "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@nodable/entities": ["@nodable/entities@2.1.0", "", {}, "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA=="], "@npmcli/fs": ["@npmcli/fs@5.0.0", "https://registry.npmmirror.com/@npmcli/fs/-/fs-5.0.0.tgz", { "dependencies": { "semver": "^7.3.5" } }, "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og=="], @@ -844,8 +868,6 @@ "@opentelemetry/instrumentation-tedious": ["@opentelemetry/instrumentation-tedious@0.33.0", "https://registry.npmmirror.com/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.33.0.tgz", { "dependencies": { "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.33.0", "@types/tedious": "^4.0.14" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-Q6WQwAD01MMTub31GlejoiFACYNw26J426wyjvU7by7fDIr2nZXNW4vhTGs7i7F0TnXBO3xN688g1tdUgYwJ5w=="], - "@opentelemetry/instrumentation-undici": ["@opentelemetry/instrumentation-undici@0.24.0", "https://registry.npmmirror.com/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.24.0.tgz", { "dependencies": { "@opentelemetry/core": "^2.0.0", "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.24.0" }, "peerDependencies": { "@opentelemetry/api": "^1.7.0" } }, "sha512-oKzZ3uvqP17sV0EsoQcJgjEfIp0kiZRbYu/eD8p13Cbahumf8lb/xpYeNr/hfAJ4owzEtIDcGIjprfLcYbIKBQ=="], - "@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.214.0", "https://registry.npmmirror.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.214.0.tgz", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/otlp-transformer": "0.214.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-u1Gdv0/E9wP+apqWf7Wv2npXmgJtxsW2XL0TEv9FZloTZRuMBKmu8cYVXwS4Hm3q/f/3FuCnPTgiwYvIqRSpRg=="], "@opentelemetry/otlp-grpc-exporter-base": ["@opentelemetry/otlp-grpc-exporter-base@0.214.0", "https://registry.npmmirror.com/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.214.0.tgz", { "dependencies": { "@grpc/grpc-js": "^1.14.3", "@opentelemetry/core": "2.6.1", "@opentelemetry/otlp-exporter-base": "0.214.0", "@opentelemetry/otlp-transformer": "0.214.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-IDP6zcyA24RhNZ289MP6eToIZcinlmirHjX8v3zKCQ2ZhPpt5cGwkN91tCth337lqHIgWcTy90uKRiX/SzALDw=="], @@ -866,47 +888,47 @@ "@opentelemetry/sql-common": ["@opentelemetry/sql-common@0.41.2", "https://registry.npmmirror.com/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", { "dependencies": { "@opentelemetry/core": "^2.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0" } }, "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ=="], - "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.121.0.tgz", { "os": "android", "cpu": "arm" }, "sha512-n07FQcySwOlzap424/PLMtOkbS7xOu8nsJduKL8P3COGHKgKoDYXwoAHCbChfgFpHnviehrLWIPX0lKGtbEk/A=="], + "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.127.0", "", { "os": "android", "cpu": "arm" }, "sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ=="], - "@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.121.0.tgz", { "os": "android", "cpu": "arm64" }, "sha512-/Dd1xIXboYAicw+twT2utxPD7bL8qh7d3ej0qvaYIMj3/EgIrGR+tSnjCUkiCT6g6uTC0neSS4JY8LxhdSU/sA=="], + "@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.127.0", "", { "os": "android", "cpu": "arm64" }, "sha512-b5jtVTH6AU5CJXHNdj7Jj9IEiR9yVjjnwHzPJhGyHGPdcsZSzBCkS9GBbV33niRMvKthDwQRFRJfI4a+k4PvYg=="], - "@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.121.0.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-A0jNEvv7QMtCO1yk205t3DWU9sWUjQ2KNF0hSVO5W9R9r/R1BIvzG01UQAfmtC0dQm7sCrs5puixurKSfr2bRQ=="], + "@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.127.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-obCE8B7ISKkJidjlhv9xRGJPOSDG2Yu6PRga9Ruaz35uintHxbp1Ki/Yc71wx4rj3Edrm0a1kzG1TAwit0wFpg=="], - "@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.121.0.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-SsHzipdxTKUs3I9EOAPmnIimEeJOemqRlRDOp9LIj+96wtxZejF51gNibmoGq8KoqbT1ssAI5po/E3J+vEtXGA=="], + "@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.127.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-JL6Xb5IwPQT8rUzlpsX7E+AgfcdNklXNPFp8pjCQQ5MQOQo5rtEB2ui+3Hgg9Sn7Y9Egj6YOLLiHhLpdAe12Aw=="], - "@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.121.0.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-v1APOTkCp+RWOIDAHRoaeW/UoaHF15a60E8eUL6kUQXh+i4K7PBwq2Wi7jm8p0ymID5/m/oC1w3W31Z/+r7HQw=="], + "@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.127.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SDQ/3MQFw58fqQz3Z1PhSKFF3JoCF4gmlNjziDm8X02tTahCw0qJbd7FGPDKw1i4VTBZene9JPyC3mHtSvi+wA=="], - "@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.121.0.tgz", { "os": "linux", "cpu": "arm" }, "sha512-PmqPQuqHZyFVWA4ycr0eu4VnTMmq9laOHZd+8R359w6kzuNZPvmmunmNJ8ybkm769A0nCoVp3TJ6dUz7B3FYIQ=="], + "@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.127.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Av+D1MIqzV0YMGPT9we2SIZaMKD7Cxs4CvXSx/yxaWHewZjYEjScpOf5igc8IILASViw4WTnjlwUdI1KzVtDHQ=="], - "@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.121.0.tgz", { "os": "linux", "cpu": "arm" }, "sha512-vF24htj+MOH+Q7y9A8NuC6pUZu8t/C2Fr/kDOi2OcNf28oogr2xadBPXAbml802E8wRAVfbta6YLDQTearz+jw=="], + "@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.127.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Cs2fdJ8cPpFdeebj6p4dag8A4+56hPvZ0AhQQzlaLswGz1tz7bXt1nETLeorrM9+AMcWFFkqxcXwDGfTVidY8g=="], - "@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.121.0.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-wjH8cIG2Lu/3d64iZpbYr73hREMgKAfu7fqpXjgM2S16y2zhTfDIp8EQjxO8vlDtKP5Rc7waZW72lh8nZtWrpA=="], + "@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.127.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-qdOfTcT6SY8gsJrrV92uyEUyjqMGPpIB5JZUG6QN5dukYd+7/j0kX6MwK1DgQj39jtUYixxPiaRUiEN1+0CXgQ=="], - "@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.121.0.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-qT663J/W8yQFw3dtscbEi9LKJevr20V7uWs2MPGTnvNZ3rm8anhhE16gXGpxDOHeg9raySaSHKhd4IGa3YZvuw=="], + "@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.127.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTCZneNFU/P2qrpEM+RHmQwt+CvDkyGESG6qhr7KaegXLZwePfbrkCDfAk8/rhxbDUVGsZILX+2tqPzFtoFWA=="], - "@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.121.0.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-mYNe4NhVvDBbPkAP8JaVS8lC1dsoJZWH5WCjpw5E+sjhk1R08wt3NnXYUzum7tIiWPfgQxbCMcoxgeemFASbRw=="], + "@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.127.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-zALjmZYgxFLHjXeudcDF0xFGNydTAtkAeXAr2EuC17ywCyFxcmQra4w0BMde0Yi/re4Bi4iwEoEXtYN7l6eBLQ=="], - "@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.121.0.tgz", { "os": "linux", "cpu": "none" }, "sha512-+QiFoGxhAbaI/amqX567784cDyyuZIpinBrJNxUzb+/L2aBRX67mN6Jv40pqduHf15yYByI+K5gUEygCuv0z9w=="], + "@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.127.0", "", { "os": "linux", "cpu": "none" }, "sha512-fPP8M6zQLS7Jz7o9d5ArUSuAuSK3e+WCYVrCpdzeCOejidtZExJ9tjhDrAd3HEPqARBCPmdpqxESPFqy44vkBQ=="], - "@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.121.0.tgz", { "os": "linux", "cpu": "none" }, "sha512-9ykEgyTa5JD/Uhv2sttbKnCfl2PieUfOjyxJC/oDL2UO0qtXOtjPLl7H8Kaj5G7p3hIvFgu3YWvAxvE0sqY+hQ=="], + "@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.127.0", "", { "os": "linux", "cpu": "none" }, "sha512-7IcC4Ao02oGpfnjt+X/oF4U2mllo2qoSkw5xxiXNKL9MCTsTiAC6616beOuehdxGcnz1bRoPC1RQ2f1GQDdN+g=="], - "@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.121.0.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-DB1EW5VHZdc1lIRjOI3bW/wV6R6y0xlfvdVrqj6kKi7Ayu2U3UqUBdq9KviVkcUGd5Oq+dROqvUEEFRXGAM7EQ=="], + "@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.127.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-pbXIhiNFHoqWeqDNLiJ9JkpHz1IM9k4DXa66x+1GTWMG7iLxtkXgE53iiuKSXwmk3zIYmaPVfBvgcAhS583K4Q=="], - "@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.121.0.tgz", { "os": "linux", "cpu": "x64" }, "sha512-s4lfobX9p4kPTclvMiH3gcQUd88VlnkMTF6n2MTMDAyX5FPNRhhRSFZK05Ykhf8Zy5NibV4PbGR6DnK7FGNN6A=="], + "@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.127.0", "", { "os": "linux", "cpu": "x64" }, "sha512-MYCguB9RvBvlSd6gbuNI7QwiLoCCAlGnlRJFPrzLI6U1/9wkC/WK6LtBAUln55H1Ctqw45PWmqrobKoMhsYQzQ=="], - "@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.121.0.tgz", { "os": "linux", "cpu": "x64" }, "sha512-P9KlyTpuBuMi3NRGpJO8MicuGZfOoqZVRP1WjOecwx8yk4L/+mrCRNc5egSi0byhuReblBF2oVoDSMgV9Bj4Hw=="], + "@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.127.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5eY0B/bxf1xIUxb4NOTvOI3KWtBQfPWYyKAzgcrCt0mDibSZygVpO1Pz8bkeiSZ5Jj9+M09dkggG3H8I5d0Uyg=="], - "@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.121.0.tgz", { "os": "none", "cpu": "arm64" }, "sha512-R+4jrWOfF2OAPPhj3Eb3U5CaKNAH9/btMveMULIrcNW/hjfysFQlF8wE0GaVBr81dWz8JLgQlsxwctoL78JwXw=="], + "@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.127.0", "", { "os": "none", "cpu": "arm64" }, "sha512-Gld0ajrFTUXNtdw20fVBuTQx66FA75nIVg+//pPfR3sXkuABB4mTBhl3r9JNzrJpgW//qiwxf0nWXUWGJSL3UQ=="], - "@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.121.0.tgz", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-5TFISkPTymKvsmIlKasPVTPuWxzCcrT8pM+p77+mtQbIZDd1UC8zww4CJcRI46kolmgrEX6QpKO8AvWMVZ+ifw=="], + "@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.127.0", "", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-T6KVD7rhLzFlwGRXMnxUFfkCZD8FHnb968wVXW1mXzgRFc5RNXOBY2mPPDZ77x5Ln76ltLMgtPg0cOkU1NSrEQ=="], - "@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.121.0.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-V0pxh4mql4XTt3aiEtRNUeBAUFOw5jzZNxPABLaOKAWrVzSr9+XUaB095lY7jqMf5t8vkfh8NManGB28zanYKw=="], + "@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.127.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Ujvw4X+LD1CCGULcsQcvb4YNVoBGqt+JHgNNzGGaCImELiZLk477ifUH53gIbE7EKd933NdTi25JWEr9K2HwXw=="], - "@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.121.0.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-4Ob1qvYMPnlF2N9rdmKdkQFdrq16QVcQwBsO8yiPZXof0fHKFF+LmQV501XFbi7lHyrKm8rlJRfQ/M8bZZPVLw=="], + "@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.127.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-0cwxKO7KHQQQfo4Uf4B2SQrhgm+cJaP9OvFFhx52Tkg4bezsacu83GB2/In5bC415Ueeym+kXdnge/57rbSfTw=="], - "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.121.0", "https://registry.npmmirror.com/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.121.0.tgz", { "os": "win32", "cpu": "x64" }, "sha512-BOp1KCzdboB1tPqoCPXgntgFs0jjeSyOXHzgxVFR7B/qfr3F8r4YDacHkTOUNXtDgM8YwKnkf3rE5gwALYX7NA=="], + "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.127.0", "", { "os": "win32", "cpu": "x64" }, "sha512-rOrnSQSCbhI2kowr9XxE7m9a8oQXnBHjnS6j95LxxAnEZ0+Fz20WlRXG4ondQb+ejjt2KOsa65sE6++L6kUd+w=="], - "@oxc-project/types": ["@oxc-project/types@0.121.0", "https://registry.npmmirror.com/@oxc-project/types/-/types-0.121.0.tgz", {}, "sha512-CGtOARQb9tyv7ECgdAlFxi0Fv7lmzvmlm2rpD/RdijOO9rfk/JvB1CjT8EnoD+tjna/IYgKKw3IV7objRb+aYw=="], + "@oxc-project/types": ["@oxc-project/types@0.127.0", "", {}, "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ=="], "@oxc-resolver/binding-android-arm-eabi": ["@oxc-resolver/binding-android-arm-eabi@11.19.1", "https://registry.npmmirror.com/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.19.1.tgz", { "os": "android", "cpu": "arm" }, "sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg=="], @@ -1116,35 +1138,35 @@ "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "https://registry.npmmirror.com/@radix-ui/rect/-/rect-1.1.1.tgz", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz", { "os": "android", "cpu": "arm64" }, "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.17", "", { "os": "android", "cpu": "arm64" }, "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg=="], + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw=="], + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw=="], + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "arm" }, "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA=="], + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17", "", { "os": "linux", "cpu": "arm" }, "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w=="], + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ=="], + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg=="], - "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ=="], + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17", "", { "os": "linux", "cpu": "ppc64" }, "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA=="], - "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ=="], + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17", "", { "os": "linux", "cpu": "s390x" }, "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "x64" }, "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA=="], + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.17", "", { "os": "linux", "cpu": "x64" }, "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "x64" }, "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw=="], + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.17", "", { "os": "linux", "cpu": "x64" }, "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz", { "os": "none", "cpu": "arm64" }, "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg=="], + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.17", "", { "os": "none", "cpu": "arm64" }, "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA=="], - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.3" }, "cpu": "none" }, "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q=="], + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.17", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA=="], + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz", { "os": "win32", "cpu": "x64" }, "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g=="], + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.17", "", { "os": "win32", "cpu": "x64" }, "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], @@ -1200,13 +1222,13 @@ "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "https://registry.npmmirror.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], - "@sentry/core": ["@sentry/core@10.49.0", "", {}, "sha512-UaFeum3LUM1mB0d67jvKnqId1yWQjyqmaDV6kWngG03x+jqXb08tJdGpSoxjXZe13jFBbiBL/wKDDYIK7rCK4g=="], + "@sentry/core": ["@sentry/core@10.50.0", "", {}, "sha512-J4A+vzUO3adl0TkFCjaN1+4miamrjHiEIYuLHiuu1lmAjq5WIVw32ObvAh4yMwNtxyaEMosTrrh5M6f12XSJFg=="], - "@sentry/node": ["@sentry/node@10.49.0", "", { "dependencies": { "@fastify/otel": "0.18.0", "@opentelemetry/api": "^1.9.1", "@opentelemetry/core": "^2.6.1", "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/instrumentation-amqplib": "0.61.0", "@opentelemetry/instrumentation-connect": "0.57.0", "@opentelemetry/instrumentation-dataloader": "0.31.0", "@opentelemetry/instrumentation-fs": "0.33.0", "@opentelemetry/instrumentation-generic-pool": "0.57.0", "@opentelemetry/instrumentation-graphql": "0.62.0", "@opentelemetry/instrumentation-hapi": "0.60.0", "@opentelemetry/instrumentation-http": "0.214.0", "@opentelemetry/instrumentation-ioredis": "0.62.0", "@opentelemetry/instrumentation-kafkajs": "0.23.0", "@opentelemetry/instrumentation-knex": "0.58.0", "@opentelemetry/instrumentation-koa": "0.62.0", "@opentelemetry/instrumentation-lru-memoizer": "0.58.0", "@opentelemetry/instrumentation-mongodb": "0.67.0", "@opentelemetry/instrumentation-mongoose": "0.60.0", "@opentelemetry/instrumentation-mysql": "0.60.0", "@opentelemetry/instrumentation-mysql2": "0.60.0", "@opentelemetry/instrumentation-pg": "0.66.0", "@opentelemetry/instrumentation-redis": "0.62.0", "@opentelemetry/instrumentation-tedious": "0.33.0", "@opentelemetry/instrumentation-undici": "0.24.0", "@opentelemetry/sdk-trace-base": "^2.6.1", "@opentelemetry/semantic-conventions": "^1.40.0", "@prisma/instrumentation": "7.6.0", "@sentry/core": "10.49.0", "@sentry/node-core": "10.49.0", "@sentry/opentelemetry": "10.49.0", "import-in-the-middle": "^3.0.0" } }, "sha512-xr+HXABCiO5mgAJRQxsXRdNOLO0+Ee6CvXAAIqovL2A1GlhxNWc5ooPWeIrrLDJ/KGyT8zI91O5scpVXdXs0uQ=="], + "@sentry/node": ["@sentry/node@10.50.0", "", { "dependencies": { "@fastify/otel": "0.18.0", "@opentelemetry/api": "^1.9.1", "@opentelemetry/core": "^2.6.1", "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/instrumentation-amqplib": "0.61.0", "@opentelemetry/instrumentation-connect": "0.57.0", "@opentelemetry/instrumentation-dataloader": "0.31.0", "@opentelemetry/instrumentation-fs": "0.33.0", "@opentelemetry/instrumentation-generic-pool": "0.57.0", "@opentelemetry/instrumentation-graphql": "0.62.0", "@opentelemetry/instrumentation-hapi": "0.60.0", "@opentelemetry/instrumentation-http": "0.214.0", "@opentelemetry/instrumentation-ioredis": "0.62.0", "@opentelemetry/instrumentation-kafkajs": "0.23.0", "@opentelemetry/instrumentation-knex": "0.58.0", "@opentelemetry/instrumentation-koa": "0.62.0", "@opentelemetry/instrumentation-lru-memoizer": "0.58.0", "@opentelemetry/instrumentation-mongodb": "0.67.0", "@opentelemetry/instrumentation-mongoose": "0.60.0", "@opentelemetry/instrumentation-mysql": "0.60.0", "@opentelemetry/instrumentation-mysql2": "0.60.0", "@opentelemetry/instrumentation-pg": "0.66.0", "@opentelemetry/instrumentation-redis": "0.62.0", "@opentelemetry/instrumentation-tedious": "0.33.0", "@opentelemetry/sdk-trace-base": "^2.6.1", "@opentelemetry/semantic-conventions": "^1.40.0", "@prisma/instrumentation": "7.6.0", "@sentry/core": "10.50.0", "@sentry/node-core": "10.50.0", "@sentry/opentelemetry": "10.50.0", "import-in-the-middle": "^3.0.0" } }, "sha512-TvwzFQu8MGKzMQ2/tqxcNzFA8UG2kKTB+GDmA4uOzx3+GT849YZRRSJzEXCmYhk1teVd2fbmgqyYY2nyLF5a+Q=="], - "@sentry/node-core": ["@sentry/node-core@10.49.0", "", { "dependencies": { "@sentry/core": "10.49.0", "@sentry/opentelemetry": "10.49.0", "import-in-the-middle": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0", "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1", "@opentelemetry/instrumentation": ">=0.57.1 <1", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", "@opentelemetry/semantic-conventions": "^1.39.0" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/core", "@opentelemetry/exporter-trace-otlp-http", "@opentelemetry/instrumentation", "@opentelemetry/sdk-trace-base", "@opentelemetry/semantic-conventions"] }, "sha512-7WO0KuCDPSq3G54TVUSI1CKFJwB67LasG+n/gDMBqbrarzs/Yh/s34OOMU5gfVQpncxQAmQsy4nEboQms8iNqA=="], + "@sentry/node-core": ["@sentry/node-core@10.50.0", "", { "dependencies": { "@sentry/core": "10.50.0", "@sentry/opentelemetry": "10.50.0", "import-in-the-middle": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0", "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1", "@opentelemetry/instrumentation": ">=0.57.1 <1", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", "@opentelemetry/semantic-conventions": "^1.39.0" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/core", "@opentelemetry/exporter-trace-otlp-http", "@opentelemetry/instrumentation", "@opentelemetry/sdk-trace-base", "@opentelemetry/semantic-conventions"] }, "sha512-Eb1BYf4Lc7ZYmdX3acKP6SgyGikrBA370gbGHaWI5jRu7G7vig8sIu1ghPmY5AlvqBPOetado7GniXr6fAXbTw=="], - "@sentry/opentelemetry": ["@sentry/opentelemetry@10.49.0", "", { "dependencies": { "@sentry/core": "10.49.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", "@opentelemetry/semantic-conventions": "^1.39.0" } }, "sha512-XNLm4dXmtegXQf+EEE2Cs84Ymlo/f5wMx+lg2S2XS4qLbXaPN/HttjhwKftd8D+8iUNfmH+xNMCSshx4s1B/1w=="], + "@sentry/opentelemetry": ["@sentry/opentelemetry@10.50.0", "", { "dependencies": { "@sentry/core": "10.50.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", "@opentelemetry/semantic-conventions": "^1.39.0" } }, "sha512-axn3pgDPveGdaMUC0abMCmFN7ux2pA5ebPufCef4lMIsyg7BBQvaEJ+vE19wjstMaBCAJGsdZlL3eeP2rtgRMw=="], "@shikijs/core": ["@shikijs/core@3.23.0", "https://registry.npmmirror.com/@shikijs/core/-/core-3.23.0.tgz", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], @@ -1226,9 +1248,9 @@ "@smithy/abort-controller": ["@smithy/abort-controller@2.2.0", "https://registry.npmmirror.com/@smithy/abort-controller/-/abort-controller-2.2.0.tgz", { "dependencies": { "@smithy/types": "^2.12.0", "tslib": "^2.6.2" } }, "sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw=="], - "@smithy/config-resolver": ["@smithy/config-resolver@4.4.16", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.14", "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.4.1", "@smithy/util-middleware": "^4.2.14", "tslib": "^2.6.2" } }, "sha512-GFlGPNLZKrGfqWpqVb31z7hvYCA9ZscfX1buYnvvMGcRYsQQnhH+4uN6mWWflcD5jB4OXP/LBrdpukEdjl41tg=="], + "@smithy/config-resolver": ["@smithy/config-resolver@4.4.17", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.14", "@smithy/types": "^4.14.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.4.2", "@smithy/util-middleware": "^4.2.14", "tslib": "^2.6.2" } }, "sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ=="], - "@smithy/core": ["@smithy/core@3.23.15", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-stream": "^4.5.23", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-E7GVCgsQttzfujEZb6Qep005wWf4xiL4x06apFEtzQMWYBPggZh/0cnOxPficw5cuK/YjjkehKoIN4YUaSh0UQ=="], + "@smithy/core": ["@smithy/core@3.23.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-stream": "^4.5.25", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ=="], "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.14", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.14", "@smithy/property-provider": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "tslib": "^2.6.2" } }, "sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg=="], @@ -1242,7 +1264,7 @@ "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@2.2.0", "https://registry.npmmirror.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.2.0.tgz", { "dependencies": { "@smithy/eventstream-codec": "^2.2.0", "@smithy/types": "^2.12.0", "tslib": "^2.6.2" } }, "sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA=="], - "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.16", "https://registry.npmmirror.com/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.16.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/querystring-builder": "^4.2.13", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-nYDRUIvNd4mFmuXraRWt6w5UsZTNqtj4hXJA/iiOD4tuseIdLP9Lq38teH/SZTcIFCa2f+27o7hYpIsWktJKEQ=="], + "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], "@smithy/hash-node": ["@smithy/hash-node@4.2.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g=="], @@ -1252,17 +1274,17 @@ "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.14", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw=="], - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.30", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-serde": "^4.2.18", "@smithy/node-config-provider": "^4.3.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-middleware": "^4.2.14", "tslib": "^2.6.2" } }, "sha512-qS2XqhKeXmdZ4nEQ4cOxIczSP/Y91wPAHYuRwmWDCh975B7/57uxsm5d6sisnUThn2u2FwzMdJNM7AbO1YPsPg=="], + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.32", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-serde": "^4.2.20", "@smithy/node-config-provider": "^4.3.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "@smithy/url-parser": "^4.2.14", "@smithy/util-middleware": "^4.2.14", "tslib": "^2.6.2" } }, "sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q=="], - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.5.3", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/node-config-provider": "^4.3.14", "@smithy/protocol-http": "^5.3.14", "@smithy/service-error-classification": "^4.2.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-TE8dJNi6JuxzGSxMCVd3i9IEWDndCl3bmluLsBNDWok8olgj65OfkndMhl9SZ7m14c+C5SQn/PcUmrDl57rSFw=="], + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.5.5", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/node-config-provider": "^4.3.14", "@smithy/protocol-http": "^5.3.14", "@smithy/service-error-classification": "^4.3.0", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "@smithy/util-middleware": "^4.2.14", "@smithy/util-retry": "^4.3.4", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-wnYOpB5vATFKWrY2Z9Alb0KhjZI6AbzU6Fbz3Hq2GnURdRYWB4q+qWivQtSTwXcmWUA3MZ6krfwL6Cq5MAbxsA=="], - "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.18", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-M6CSgnp3v4tYz9ynj2JHbA60woBZcGqEwNjTKjBsNHPV26R1ZX52+0wW8WsZU18q45jD0tw2wL22S17Ze9LpEw=="], + "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.20", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ=="], "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA=="], "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.14", "", { "dependencies": { "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg=="], - "@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.3", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-lc5jFL++x17sPhIwMWJ3YOnqmSjw/2Po6VLDlUIXvxVWRuJwRXnJ4jOBBLB0cfI5BB5ehIl02Fxr1PDvk/kxDw=="], + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.6.1", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg=="], "@smithy/property-provider": ["@smithy/property-provider@4.2.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ=="], @@ -1272,7 +1294,7 @@ "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw=="], - "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.14", "", { "dependencies": { "@smithy/types": "^4.14.1" } }, "sha512-vVimoUnGxlx4eLLQbZImdOZFOe+Zh+5ACntv8VxZuGP72LdWu5GV3oEmCahSEReBgRJoWjypFkrehSj7BWx1HQ=="], + "@smithy/service-error-classification": ["@smithy/service-error-classification@4.3.0", "", { "dependencies": { "@smithy/types": "^4.14.1" } }, "sha512-9jKsBYQRPR0xBLgc2415RsA5PIcP2sis4oBdN9s0D13cg1B1284mNTjx9Yc+BEERXzuPm5ObktI96OxsKh8E9A=="], "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.9", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ=="], @@ -1294,19 +1316,19 @@ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.2", "https://registry.npmmirror.com/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ=="], - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.47", "", { "dependencies": { "@smithy/property-provider": "^4.2.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-zlIuXai3/SHjQUQ8y3g/woLvrH573SK2wNjcDaHu5e9VOcC0JwM1MI0Sq0GZJyN3BwSUneIhpjZ18nsiz5AtQw=="], + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.49", "", { "dependencies": { "@smithy/property-provider": "^4.2.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw=="], - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.52", "", { "dependencies": { "@smithy/config-resolver": "^4.4.16", "@smithy/credential-provider-imds": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/property-provider": "^4.2.14", "@smithy/smithy-client": "^4.12.11", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-cQBz8g68Vnw1W2meXlkb3D/hXJU+Taiyj9P8qLJtjREEV9/Td65xi4A/H1sRQ8EIgX5qbZbvdYPKygKLholZ3w=="], + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.54", "", { "dependencies": { "@smithy/config-resolver": "^4.4.17", "@smithy/credential-provider-imds": "^4.2.14", "@smithy/node-config-provider": "^4.3.14", "@smithy/property-provider": "^4.2.14", "@smithy/smithy-client": "^4.12.13", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw=="], - "@smithy/util-endpoints": ["@smithy/util-endpoints@3.4.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-wMxNDZJrgS5mQV9oxCs4TWl5767VMgOfqfZ3JHyCkMtGC2ykW9iPqMvFur695Otcc5yxLG8OKO/80tsQBxrhXg=="], + "@smithy/util-endpoints": ["@smithy/util-endpoints@3.4.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-a55Tr+3OKld4TTtnT+RhKOQHyPxm3j/xL4OR83WBUhLJaKDS9dnJ7arRMOp3t31dcLhApwG9bgvrRXBHlLdIkg=="], "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], "@smithy/util-middleware": ["@smithy/util-middleware@4.2.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw=="], - "@smithy/util-retry": ["@smithy/util-retry@4.3.2", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-2+KTsJEwTi63NUv4uR9IQ+IFT1yu6Rf6JuoBK2WKaaJ/TRvOiOVGcXAsEqX/TQN2thR9yII21kPUJq1UV/WI2A=="], + "@smithy/util-retry": ["@smithy/util-retry@4.3.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.3.0", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-FY1UQQ1VFmMwiYp1GVS4MeaGD5O0blLNYK0xCRHU+mJgeoH/hSY8Ld8sJWKQ6uznkh14HveRGQJncgPyNl9J+A=="], - "@smithy/util-stream": ["@smithy/util-stream@4.5.23", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.17", "@smithy/node-http-handler": "^4.5.3", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-N6on1+ngJ3RznZOnDWNveIwnTSlqxNnXuNAh7ez889ZZaRdXoNRTXKgmYOLe6dB0gCmAVtuRScE1hymQFl4hpg=="], + "@smithy/util-stream": ["@smithy/util-stream@4.5.25", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.17", "@smithy/node-http-handler": "^4.6.1", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA=="], "@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], @@ -1360,7 +1382,7 @@ "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], - "@types/bun": ["@types/bun@1.3.12", "https://registry.npmmirror.com/@types/bun/-/bun-1.3.12.tgz", { "dependencies": { "bun-types": "1.3.12" } }, "sha512-DBv81elK+/VSwXHDlnH3Qduw+KxkTIWi7TXkAeh24zpi5l0B2kUg9Ga3tb4nJaPcOFswflgi/yAvMVBPrxMB+A=="], + "@types/bun": ["@types/bun@1.3.13", "", { "dependencies": { "bun-types": "1.3.13" } }, "sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw=="], "@types/cacache": ["@types/cacache@20.0.1", "https://registry.npmmirror.com/@types/cacache/-/cacache-20.0.1.tgz", { "dependencies": { "@types/node": "*", "minipass": "*" } }, "sha512-QlKW3AFoFr/hvPHwFHMIVUH/ZCYeetBNou3PCmxu5LaNDvrtBlPJtIA6uhmU9JRt9oxj7IYoqoLcpxtzpPiTcw=="], @@ -1498,6 +1520,8 @@ "@types/uuid": ["@types/uuid@10.0.0", "https://registry.npmmirror.com/@types/uuid/-/uuid-10.0.0.tgz", {}, "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ=="], + "@types/vscode": ["@types/vscode@1.116.0", "", {}, "sha512-sYHp4MO6BqJ2PD7Hjt0hlIS3tMaYsVPJrd0RUjDJ8HtOYnyJIEej0bLSccM8rE77WrC+Xox/kdBwEFDO8MsxNA=="], + "@types/wrap-ansi": ["@types/wrap-ansi@3.0.0", "https://registry.npmmirror.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", {}, "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g=="], "@types/ws": ["@types/ws@8.18.1", "https://registry.npmmirror.com/@types/ws/-/ws-8.18.1.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], @@ -1512,7 +1536,7 @@ "@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="], - "@xmldom/xmldom": ["@xmldom/xmldom@0.8.12", "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.12.tgz", {}, "sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg=="], + "@xmldom/xmldom": ["@xmldom/xmldom@0.8.13", "", {}, "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw=="], "accepts": ["accepts@2.0.0", "https://registry.npmmirror.com/accepts/-/accepts-2.0.0.tgz", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], @@ -1528,7 +1552,7 @@ "ai": ["ai@6.0.168", "https://registry.npmmirror.com/ai/-/ai-6.0.168.tgz", { "dependencies": { "@ai-sdk/gateway": "3.0.104", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-2HqCJuO+1V2aV7vfYs5LFEUfxbkGX+5oa54q/gCCTL7KLTdbxcCu5D7TdLA5kwsrs3Szgjah9q6D9tpjHM3hUQ=="], - "ajv": ["ajv@8.18.0", "https://registry.npmmirror.com/ajv/-/ajv-8.18.0.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], "ajv-formats": ["ajv-formats@3.0.1", "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-3.0.1.tgz", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], @@ -1554,7 +1578,7 @@ "auto-bind": ["auto-bind@5.0.1", "https://registry.npmmirror.com/auto-bind/-/auto-bind-5.0.1.tgz", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="], - "axios": ["axios@1.15.0", "https://registry.npmmirror.com/axios/-/axios-1.15.0.tgz", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q=="], + "axios": ["axios@1.15.2", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A=="], "bail": ["bail@2.0.2", "https://registry.npmmirror.com/bail/-/bail-2.0.2.tgz", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], @@ -1574,15 +1598,13 @@ "brace-expansion": ["brace-expansion@5.0.5", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-5.0.5.tgz", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], - "braces": ["braces@3.0.3", "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - "browser-image-compression": ["browser-image-compression@2.0.2", "https://registry.npmmirror.com/browser-image-compression/-/browser-image-compression-2.0.2.tgz", { "dependencies": { "uzip": "0.20201231.0" } }, "sha512-pBLlQyUf6yB8SmmngrcOw3EoS4RpQ1BcylI3T9Yqn7+4nrQTXJD4sJDe5ODnJdrvNMaio5OicFo75rDyJD2Ucw=="], "browserslist": ["browserslist@4.28.2", "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.2.tgz", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="], "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], - "bun-types": ["bun-types@1.3.12", "https://registry.npmmirror.com/bun-types/-/bun-types-1.3.12.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-HqOLj5PoFajAQciOMRiIZGNoKxDJSr6qigAttOX40vJuSp6DN/CxWp9s3C1Xwm4oH7ybueITwiaOcWXoYVoRkA=="], + "bun-types": ["bun-types@1.3.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA=="], "bundle-name": ["bundle-name@4.1.0", "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], @@ -1600,6 +1622,8 @@ "caniuse-lite": ["caniuse-lite@1.0.30001787", "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001787.tgz", {}, "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg=="], + "ccb-vscode": ["ccb-vscode@workspace:packages/vscode-extension"], + "ccount": ["ccount@2.0.1", "https://registry.npmmirror.com/ccount/-/ccount-2.0.1.tgz", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], "chalk": ["chalk@5.6.2", "https://registry.npmmirror.com/chalk/-/chalk-5.6.2.tgz", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], @@ -1824,7 +1848,7 @@ "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], - "esbuild": ["esbuild@0.25.12", "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.12.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + "esbuild": ["esbuild@0.28.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.0", "@esbuild/android-arm": "0.28.0", "@esbuild/android-arm64": "0.28.0", "@esbuild/android-x64": "0.28.0", "@esbuild/darwin-arm64": "0.28.0", "@esbuild/darwin-x64": "0.28.0", "@esbuild/freebsd-arm64": "0.28.0", "@esbuild/freebsd-x64": "0.28.0", "@esbuild/linux-arm": "0.28.0", "@esbuild/linux-arm64": "0.28.0", "@esbuild/linux-ia32": "0.28.0", "@esbuild/linux-loong64": "0.28.0", "@esbuild/linux-mips64el": "0.28.0", "@esbuild/linux-ppc64": "0.28.0", "@esbuild/linux-riscv64": "0.28.0", "@esbuild/linux-s390x": "0.28.0", "@esbuild/linux-x64": "0.28.0", "@esbuild/netbsd-arm64": "0.28.0", "@esbuild/netbsd-x64": "0.28.0", "@esbuild/openbsd-arm64": "0.28.0", "@esbuild/openbsd-x64": "0.28.0", "@esbuild/openharmony-arm64": "0.28.0", "@esbuild/sunos-x64": "0.28.0", "@esbuild/win32-arm64": "0.28.0", "@esbuild/win32-ia32": "0.28.0", "@esbuild/win32-x64": "0.28.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw=="], "escalade": ["escalade@3.2.0", "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], @@ -1854,17 +1878,13 @@ "fast-deep-equal": ["fast-deep-equal@3.1.3", "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], - "fast-glob": ["fast-glob@3.3.3", "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], - "fast-safe-stringify": ["fast-safe-stringify@2.1.1", "https://registry.npmmirror.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="], "fast-uri": ["fast-uri@3.1.0", "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.1.0.tgz", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], - "fast-xml-builder": ["fast-xml-builder@1.1.4", "https://registry.npmmirror.com/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="], - - "fast-xml-parser": ["fast-xml-parser@5.5.8", "https://registry.npmmirror.com/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], + "fast-xml-builder": ["fast-xml-builder@1.1.5", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA=="], - "fastq": ["fastq@1.20.1", "https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + "fast-xml-parser": ["fast-xml-parser@5.7.1", "", { "dependencies": { "@nodable/entities": "^2.1.0", "fast-xml-builder": "^1.1.5", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA=="], "fd-package-json": ["fd-package-json@2.0.0", "https://registry.npmmirror.com/fd-package-json/-/fd-package-json-2.0.0.tgz", { "dependencies": { "walk-up-path": "^4.0.0" } }, "sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ=="], @@ -1876,15 +1896,13 @@ "figures": ["figures@6.1.0", "https://registry.npmmirror.com/figures/-/figures-6.1.0.tgz", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="], - "fill-range": ["fill-range@7.1.1", "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - "finalhandler": ["finalhandler@2.1.1", "https://registry.npmmirror.com/finalhandler/-/finalhandler-2.1.1.tgz", { "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" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], "find-up": ["find-up@4.1.0", "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], "flora-colossus": ["flora-colossus@2.0.0", "https://registry.npmmirror.com/flora-colossus/-/flora-colossus-2.0.0.tgz", { "dependencies": { "debug": "^4.3.4", "fs-extra": "^10.1.0" } }, "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA=="], - "follow-redirects": ["follow-redirects@1.15.11", "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], + "follow-redirects": ["follow-redirects@1.16.0", "", {}, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="], "form-data": ["form-data@4.0.5", "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], @@ -1930,12 +1948,10 @@ "get-stream": ["get-stream@9.0.1", "https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], - "get-tsconfig": ["get-tsconfig@4.13.7", "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.13.7.tgz", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], + "get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="], "glob": ["glob@13.0.6", "https://registry.npmmirror.com/glob/-/glob-13.0.6.tgz", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - "glob-parent": ["glob-parent@5.1.2", "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - "google-auth-library": ["google-auth-library@10.6.2", "https://registry.npmmirror.com/google-auth-library/-/google-auth-library-10.6.2.tgz", { "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" } }, "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw=="], "google-logging-utils": ["google-logging-utils@1.1.3", "https://registry.npmmirror.com/google-logging-utils/-/google-logging-utils-1.1.3.tgz", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="], @@ -1992,7 +2008,7 @@ "highlight.js": ["highlight.js@11.11.1", "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.11.1.tgz", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="], - "hono": ["hono@4.12.12", "https://registry.npmmirror.com/hono/-/hono-4.12.12.tgz", {}, "sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q=="], + "hono": ["hono@4.12.15", "", {}, "sha512-qM0jDhFEaCBb4TxoW7f53Qrpv9RBiayUHo0S52JudprkhvpjIrGoU1mnnr29Fvd1U335ZFPZQY1wlkqgfGXyLg=="], "html-url-attributes": ["html-url-attributes@3.0.1", "https://registry.npmmirror.com/html-url-attributes/-/html-url-attributes-3.0.1.tgz", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="], @@ -2038,18 +2054,12 @@ "is-docker": ["is-docker@3.0.0", "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], - "is-extglob": ["is-extglob@2.1.1", "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], - "is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], - "is-glob": ["is-glob@4.0.3", "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], - "is-hexadecimal": ["is-hexadecimal@2.0.1", "https://registry.npmmirror.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], "is-inside-container": ["is-inside-container@1.0.0", "https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], - "is-number": ["is-number@7.0.0", "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], - "is-plain-obj": ["is-plain-obj@4.1.0", "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], "is-promise": ["is-promise@4.0.0", "https://registry.npmmirror.com/is-promise/-/is-promise-4.0.0.tgz", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], @@ -2102,7 +2112,7 @@ "khroma": ["khroma@2.1.0", "https://registry.npmmirror.com/khroma/-/khroma-2.1.0.tgz", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="], - "knip": ["knip@6.4.1", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "get-tsconfig": "4.13.7", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.121.0", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-Ry+ywmDFSZvKp/jx7LxMgsZWRTs931alV84e60lh0Stf6kSRYqSIUTkviyyDFRcSO3yY1Kpbi83OirN+4lA2Xw=="], + "knip": ["knip@6.6.3", "", { "dependencies": { "fdir": "^6.5.0", "formatly": "^0.3.0", "get-tsconfig": "4.14.0", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.127.0", "oxc-resolver": "^11.19.1", "picomatch": "^4.0.4", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "tinyglobby": "^0.2.16", "unbash": "^3.0.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-7HSf5bLx6r66+sjXwSvSiDEE9RjRzHuAkrEFLE6XXHqaPDY97tdzNvyRVF9DeusbiV72kStAFiNnhj72rxJNGQ=="], "langium": ["langium@4.2.2", "https://registry.npmmirror.com/langium/-/langium-4.2.2.tgz", { "dependencies": { "@chevrotain/regexp-to-ast": "~12.0.0", "chevrotain": "~12.0.0", "chevrotain-allstar": "~0.4.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ=="], @@ -2208,8 +2218,6 @@ "merge-stream": ["merge-stream@2.0.0", "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], - "merge2": ["merge2@1.4.1", "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], - "mermaid": ["mermaid@11.14.0", "https://registry.npmmirror.com/mermaid/-/mermaid-11.14.0.tgz", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.1.0", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.1", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.19", "dompurify": "^3.3.1", "katex": "^0.16.25", "khroma": "^2.1.0", "lodash-es": "^4.17.23", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-GSGloRsBs+JINmmhl0JDwjpuezCsHB4WGI4NASHxL3fHo3o/BRXTxhDLKnln8/Q0lRFRyDdEjmk1/d5Sn1Xz8g=="], "micromark": ["micromark@4.0.2", "https://registry.npmmirror.com/micromark/-/micromark-4.0.2.tgz", { "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" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], @@ -2276,8 +2284,6 @@ "micromark-util-types": ["micromark-util-types@2.0.2", "https://registry.npmmirror.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], - "micromatch": ["micromatch@4.0.8", "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], - "mime-db": ["mime-db@1.54.0", "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], "mime-types": ["mime-types@3.0.2", "https://registry.npmmirror.com/mime-types/-/mime-types-3.0.2.tgz", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], @@ -2350,9 +2356,7 @@ "opus-encdec": ["opus-encdec@0.1.1", "", {}, "sha512-TDzyGqYqrwn5UEUNaLsfLGu8Ma+HRNrgLYj7Vx5wfTnafAA21G6Bnm/qTIa3orQi/yZPZYmkdpO/gez4nfA1Rw=="], - "os-tmpdir": ["os-tmpdir@1.0.2", "https://registry.npmmirror.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz", {}, "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g=="], - - "oxc-parser": ["oxc-parser@0.121.0", "https://registry.npmmirror.com/oxc-parser/-/oxc-parser-0.121.0.tgz", { "dependencies": { "@oxc-project/types": "^0.121.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.121.0", "@oxc-parser/binding-android-arm64": "0.121.0", "@oxc-parser/binding-darwin-arm64": "0.121.0", "@oxc-parser/binding-darwin-x64": "0.121.0", "@oxc-parser/binding-freebsd-x64": "0.121.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.121.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.121.0", "@oxc-parser/binding-linux-arm64-gnu": "0.121.0", "@oxc-parser/binding-linux-arm64-musl": "0.121.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.121.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.121.0", "@oxc-parser/binding-linux-riscv64-musl": "0.121.0", "@oxc-parser/binding-linux-s390x-gnu": "0.121.0", "@oxc-parser/binding-linux-x64-gnu": "0.121.0", "@oxc-parser/binding-linux-x64-musl": "0.121.0", "@oxc-parser/binding-openharmony-arm64": "0.121.0", "@oxc-parser/binding-wasm32-wasi": "0.121.0", "@oxc-parser/binding-win32-arm64-msvc": "0.121.0", "@oxc-parser/binding-win32-ia32-msvc": "0.121.0", "@oxc-parser/binding-win32-x64-msvc": "0.121.0" } }, "sha512-ek9o58+SCv6AV7nchiAcUJy1DNE2CC5WRdBcO0mF+W4oRjNQfPO7b3pLjTHSFECpHkKGOZSQxx3hk8viIL5YCg=="], + "oxc-parser": ["oxc-parser@0.127.0", "", { "dependencies": { "@oxc-project/types": "^0.127.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.127.0", "@oxc-parser/binding-android-arm64": "0.127.0", "@oxc-parser/binding-darwin-arm64": "0.127.0", "@oxc-parser/binding-darwin-x64": "0.127.0", "@oxc-parser/binding-freebsd-x64": "0.127.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.127.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.127.0", "@oxc-parser/binding-linux-arm64-gnu": "0.127.0", "@oxc-parser/binding-linux-arm64-musl": "0.127.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.127.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.127.0", "@oxc-parser/binding-linux-riscv64-musl": "0.127.0", "@oxc-parser/binding-linux-s390x-gnu": "0.127.0", "@oxc-parser/binding-linux-x64-gnu": "0.127.0", "@oxc-parser/binding-linux-x64-musl": "0.127.0", "@oxc-parser/binding-openharmony-arm64": "0.127.0", "@oxc-parser/binding-wasm32-wasi": "0.127.0", "@oxc-parser/binding-win32-arm64-msvc": "0.127.0", "@oxc-parser/binding-win32-ia32-msvc": "0.127.0", "@oxc-parser/binding-win32-x64-msvc": "0.127.0" } }, "sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA=="], "oxc-resolver": ["oxc-resolver@11.19.1", "https://registry.npmmirror.com/oxc-resolver/-/oxc-resolver-11.19.1.tgz", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.19.1", "@oxc-resolver/binding-android-arm64": "11.19.1", "@oxc-resolver/binding-darwin-arm64": "11.19.1", "@oxc-resolver/binding-darwin-x64": "11.19.1", "@oxc-resolver/binding-freebsd-x64": "11.19.1", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-musl": "11.19.1", "@oxc-resolver/binding-openharmony-arm64": "11.19.1", "@oxc-resolver/binding-wasm32-wasi": "11.19.1", "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg=="], @@ -2422,7 +2426,7 @@ "points-on-path": ["points-on-path@0.2.1", "https://registry.npmmirror.com/points-on-path/-/points-on-path-0.2.1.tgz", { "dependencies": { "path-data-parser": "0.1.0", "points-on-curve": "0.2.0" } }, "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g=="], - "postcss": ["postcss@8.5.9", "https://registry.npmmirror.com/postcss/-/postcss-8.5.9.tgz", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], + "postcss": ["postcss@8.5.10", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ=="], "postgres-array": ["postgres-array@2.0.0", "https://registry.npmmirror.com/postgres-array/-/postgres-array-2.0.0.tgz", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], @@ -2442,7 +2446,7 @@ "property-information": ["property-information@7.1.0", "https://registry.npmmirror.com/property-information/-/property-information-7.1.0.tgz", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - "protobufjs": ["protobufjs@8.0.1", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-NWWCCscLjs+cOKF/s/XVNFRW7Yih0fdH+9brffR5NZCy8k42yRdl5KlWKMVXuI1vfCoy4o1z80XR/W/QUb3V3w=="], + "protobufjs": ["protobufjs@7.5.5", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg=="], "proxy-addr": ["proxy-addr@2.0.7", "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], @@ -2460,8 +2464,6 @@ "qs": ["qs@6.15.1", "https://registry.npmmirror.com/qs/-/qs-6.15.1.tgz", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg=="], - "queue-microtask": ["queue-microtask@1.2.3", "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], - "quick-format-unescaped": ["quick-format-unescaped@4.0.4", "https://registry.npmmirror.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="], "radix-ui": ["radix-ui@1.4.3", "https://registry.npmmirror.com/radix-ui/-/radix-ui-1.4.3.tgz", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-accessible-icon": "1.1.7", "@radix-ui/react-accordion": "1.2.12", "@radix-ui/react-alert-dialog": "1.1.15", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-aspect-ratio": "1.1.7", "@radix-ui/react-avatar": "1.1.10", "@radix-ui/react-checkbox": "1.3.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-context-menu": "2.2.16", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-form": "0.1.8", "@radix-ui/react-hover-card": "1.1.15", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-menubar": "1.1.16", "@radix-ui/react-navigation-menu": "1.2.14", "@radix-ui/react-one-time-password-field": "0.1.8", "@radix-ui/react-password-toggle-field": "0.1.3", "@radix-ui/react-popover": "1.1.15", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-progress": "1.1.7", "@radix-ui/react-radio-group": "1.3.8", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-scroll-area": "1.2.10", "@radix-ui/react-select": "2.2.6", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-slider": "1.3.6", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-switch": "1.2.6", "@radix-ui/react-tabs": "1.1.13", "@radix-ui/react-toast": "1.2.15", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-toggle-group": "1.1.11", "@radix-ui/react-toolbar": "1.1.11", "@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-escape-keydown": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA=="], @@ -2536,11 +2538,9 @@ "retry": ["retry@0.12.0", "https://registry.npmmirror.com/retry/-/retry-0.12.0.tgz", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], - "reusify": ["reusify@1.1.0", "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "robust-predicates": ["robust-predicates@3.0.3", "https://registry.npmmirror.com/robust-predicates/-/robust-predicates-3.0.3.tgz", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="], - "rolldown": ["rolldown@1.0.0-rc.15", "https://registry.npmmirror.com/rolldown/-/rolldown-1.0.0-rc.15.tgz", { "dependencies": { "@oxc-project/types": "=0.124.0", "@rolldown/pluginutils": "1.0.0-rc.15" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-x64": "1.0.0-rc.15", "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g=="], + "rolldown": ["rolldown@1.0.0-rc.17", "", { "dependencies": { "@oxc-project/types": "=0.127.0", "@rolldown/pluginutils": "1.0.0-rc.17" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.17", "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", "@rolldown/binding-darwin-x64": "1.0.0-rc.17", "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA=="], "rollup": ["rollup@4.60.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.2", "@rollup/rollup-android-arm64": "4.60.2", "@rollup/rollup-darwin-arm64": "4.60.2", "@rollup/rollup-darwin-x64": "4.60.2", "@rollup/rollup-freebsd-arm64": "4.60.2", "@rollup/rollup-freebsd-x64": "4.60.2", "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", "@rollup/rollup-linux-arm-musleabihf": "4.60.2", "@rollup/rollup-linux-arm64-gnu": "4.60.2", "@rollup/rollup-linux-arm64-musl": "4.60.2", "@rollup/rollup-linux-loong64-gnu": "4.60.2", "@rollup/rollup-linux-loong64-musl": "4.60.2", "@rollup/rollup-linux-ppc64-gnu": "4.60.2", "@rollup/rollup-linux-ppc64-musl": "4.60.2", "@rollup/rollup-linux-riscv64-gnu": "4.60.2", "@rollup/rollup-linux-riscv64-musl": "4.60.2", "@rollup/rollup-linux-s390x-gnu": "4.60.2", "@rollup/rollup-linux-x64-gnu": "4.60.2", "@rollup/rollup-linux-x64-musl": "4.60.2", "@rollup/rollup-openbsd-x64": "4.60.2", "@rollup/rollup-openharmony-arm64": "4.60.2", "@rollup/rollup-win32-arm64-msvc": "4.60.2", "@rollup/rollup-win32-ia32-msvc": "4.60.2", "@rollup/rollup-win32-x64-gnu": "4.60.2", "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ=="], @@ -2550,8 +2550,6 @@ "run-applescript": ["run-applescript@7.1.0", "https://registry.npmmirror.com/run-applescript/-/run-applescript-7.1.0.tgz", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], - "run-parallel": ["run-parallel@1.2.0", "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], - "rw": ["rw@1.3.3", "https://registry.npmmirror.com/rw/-/rw-1.3.3.tgz", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="], "safe-buffer": ["safe-buffer@5.2.1", "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], @@ -2660,9 +2658,7 @@ "tinyglobby": ["tinyglobby@0.2.16", "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.16.tgz", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], - "tmp": ["tmp@0.0.33", "https://registry.npmmirror.com/tmp/-/tmp-0.0.33.tgz", { "dependencies": { "os-tmpdir": "~1.0.2" } }, "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw=="], - - "to-regex-range": ["to-regex-range@5.0.1", "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + "tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="], "toidentifier": ["toidentifier@1.0.1", "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], @@ -2694,7 +2690,7 @@ "ufo": ["ufo@1.6.3", "https://registry.npmmirror.com/ufo/-/ufo-1.6.3.tgz", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], - "unbash": ["unbash@2.2.0", "https://registry.npmmirror.com/unbash/-/unbash-2.2.0.tgz", {}, "sha512-X2wH19RAPZE3+ldGicOkoj/SIA83OIxcJ6Cuaw23hf8Xc6fQpvZXY0SftE2JgS0QhYLUG4uwodSI3R53keyh7w=="], + "unbash": ["unbash@3.0.0", "", {}, "sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA=="], "undici": ["undici@7.25.0", "", {}, "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ=="], @@ -2736,7 +2732,7 @@ "usehooks-ts": ["usehooks-ts@3.1.1", "https://registry.npmmirror.com/usehooks-ts/-/usehooks-ts-3.1.1.tgz", { "dependencies": { "lodash.debounce": "^4.0.8" }, "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA=="], - "uuid": ["uuid@11.1.0", "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="], + "uuid": ["uuid@14.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg=="], "uzip": ["uzip@0.20201231.0", "https://registry.npmmirror.com/uzip/-/uzip-0.20201231.0.tgz", {}, "sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng=="], @@ -2748,7 +2744,7 @@ "vfile-message": ["vfile-message@4.0.3", "https://registry.npmmirror.com/vfile-message/-/vfile-message-4.0.3.tgz", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "vite": ["vite@8.0.8", "https://registry.npmmirror.com/vite/-/vite-8.0.8.tgz", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.15", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw=="], + "vite": ["vite@8.0.10", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.10", "rolldown": "1.0.0-rc.17", "tinyglobby": "^0.2.16" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw=="], "vscode-jsonrpc": ["vscode-jsonrpc@8.2.1", "https://registry.npmmirror.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz", {}, "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ=="], @@ -2810,22 +2806,12 @@ "zwitch": ["zwitch@2.0.4", "https://registry.npmmirror.com/zwitch/-/zwitch-2.0.4.tgz", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.1029.0", "https://registry.npmmirror.com/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1029.0.tgz", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/credential-provider-node": "^3.972.30", "@aws-sdk/eventstream-handler-node": "^3.972.13", "@aws-sdk/middleware-eventstream": "^3.972.9", "@aws-sdk/middleware-host-header": "^3.972.9", "@aws-sdk/middleware-logger": "^3.972.9", "@aws-sdk/middleware-recursion-detection": "^3.972.10", "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/middleware-websocket": "^3.972.15", "@aws-sdk/region-config-resolver": "^3.972.11", "@aws-sdk/token-providers": "3.1029.0", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@aws-sdk/util-user-agent-browser": "^3.972.9", "@aws-sdk/util-user-agent-node": "^3.973.15", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/eventstream-serde-browser": "^4.2.13", "@smithy/eventstream-serde-config-resolver": "^4.3.13", "@smithy/eventstream-serde-node": "^4.2.13", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/hash-node": "^4.2.13", "@smithy/invalid-dependency": "^4.2.13", "@smithy/middleware-content-length": "^4.2.13", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-retry": "^4.5.0", "@smithy/middleware-serde": "^4.2.17", "@smithy/middleware-stack": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/node-http-handler": "^4.5.2", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.45", "@smithy/util-defaults-mode-node": "^4.2.49", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.0", "@smithy/util-stream": "^4.5.22", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-LFmNV+rLPXS87vdQBfNOmhlo+3T+t07tvyEmHeGec8jUAbOFckKbU7TTy7ePe9xVYOXQYcLw+pwslJ/VZvxDkw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.1029.0", "https://registry.npmmirror.com/@aws-sdk/credential-providers/-/credential-providers-3.1029.0.tgz", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.1029.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/credential-provider-cognito-identity": "^3.972.22", "@aws-sdk/credential-provider-env": "^3.972.25", "@aws-sdk/credential-provider-http": "^3.972.27", "@aws-sdk/credential-provider-ini": "^3.972.29", "@aws-sdk/credential-provider-login": "^3.972.29", "@aws-sdk/credential-provider-node": "^3.972.30", "@aws-sdk/credential-provider-process": "^3.972.25", "@aws-sdk/credential-provider-sso": "^3.972.29", "@aws-sdk/credential-provider-web-identity": "^3.972.29", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/credential-provider-imds": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-oGkmHMuzj1tfvuCS9fWPvzy3vZqUQKClYClQ7QGAdMd1uH0QqrJQgJtX/jw2Be5nA0ZZ2DG7QEexqM1/TT1JHQ=="], - - "@anthropic-ai/claude-agent-sdk/@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.81.0", "https://registry.npmmirror.com/@anthropic-ai/sdk/-/sdk-0.81.0.tgz", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-D4K5PvEV6wPiRtVlVsJHIUhHAmOZ6IT/I9rKlTf84gR7GyyAurPJK7z9BOf/AZqC5d1DhYQGJNKRmV+q8dGhgw=="], - - "@anthropic-ai/foundry-sdk/@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.81.0", "https://registry.npmmirror.com/@anthropic-ai/sdk/-/sdk-0.81.0.tgz", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-D4K5PvEV6wPiRtVlVsJHIUhHAmOZ6IT/I9rKlTf84gR7GyyAurPJK7z9BOf/AZqC5d1DhYQGJNKRmV+q8dGhgw=="], - "@anthropic-ai/mcpb/zod": ["zod@3.25.76", "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@anthropic-ai/sandbox-runtime/commander": ["commander@12.1.0", "https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], "@anthropic-ai/sandbox-runtime/zod": ["zod@3.25.76", "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@anthropic-ai/vertex-sdk/@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.81.0", "https://registry.npmmirror.com/@anthropic-ai/sdk/-/sdk-0.81.0.tgz", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-D4K5PvEV6wPiRtVlVsJHIUhHAmOZ6IT/I9rKlTf84gR7GyyAurPJK7z9BOf/AZqC5d1DhYQGJNKRmV+q8dGhgw=="], - "@anthropic-ai/vertex-sdk/google-auth-library": ["google-auth-library@9.15.1", "https://registry.npmmirror.com/google-auth-library/-/google-auth-library-9.15.1.tgz", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^6.1.1", "gcp-metadata": "^6.1.0", "gtoken": "^7.0.0", "jws": "^4.0.0" } }, "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng=="], "@anthropic/remote-control-server/typescript": ["typescript@5.9.3", "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], @@ -2854,11 +2840,9 @@ "@aws-sdk/client-bedrock/@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "https://registry.npmmirror.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], - "@aws-sdk/client-bedrock/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], - "@aws-sdk/client-bedrock/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@aws-sdk/client-bedrock/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@aws-sdk/client-bedrock/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@aws-sdk/client-bedrock/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -2868,11 +2852,9 @@ "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.14", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.14", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-Ht/8BuGlKfFTy0H3+8eEu0vdpwGztCnaLLXtpXNdQqiR7Hj4vFScU3T436vRAjATglOIPjJXronY+1WxxNLSiw=="], - "@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], - "@aws-sdk/client-bedrock-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -2880,11 +2862,9 @@ "@aws-sdk/client-cognito-identity/@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "https://registry.npmmirror.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], - "@aws-sdk/client-cognito-identity/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], - "@aws-sdk/client-cognito-identity/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@aws-sdk/client-cognito-identity/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@aws-sdk/client-cognito-identity/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@aws-sdk/client-cognito-identity/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -2892,11 +2872,9 @@ "@aws-sdk/client-sts/@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "https://registry.npmmirror.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], - "@aws-sdk/client-sts/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], - "@aws-sdk/client-sts/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@aws-sdk/client-sts/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@aws-sdk/client-sts/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@aws-sdk/client-sts/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -2906,7 +2884,7 @@ "@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.14", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA=="], - "@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@aws-sdk/core/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -2916,11 +2894,9 @@ "@aws-sdk/credential-provider-env/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], - "@aws-sdk/credential-provider-http/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], - "@aws-sdk/credential-provider-http/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@aws-sdk/credential-provider-http/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@aws-sdk/credential-provider-http/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@aws-sdk/credential-provider-http/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -2934,6 +2910,8 @@ "@aws-sdk/credential-provider-process/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1036.0", "", { "dependencies": { "@aws-sdk/core": "^3.974.5", "@aws-sdk/nested-clients": "^3.997.3", "@aws-sdk/types": "^3.973.8", "@smithy/property-provider": "^4.2.14", "@smithy/shared-ini-file-loader": "^4.4.9", "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-aNSJ6jjDYayxN9ZA1JpycVScX93Lx03kKZ1EXt3DGOTahcWVLJj3oLAlop0xKP+vP2Ga2t49p1tEaMkTbCCaZA=="], + "@aws-sdk/credential-provider-sso/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], "@aws-sdk/credential-provider-web-identity/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -2960,7 +2938,7 @@ "@aws-sdk/middleware-sdk-s3/@smithy/signature-v4": ["@smithy/signature-v4@5.3.14", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA=="], - "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@aws-sdk/middleware-sdk-s3/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -2968,8 +2946,6 @@ "@aws-sdk/middleware-user-agent/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], - "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], - "@aws-sdk/middleware-websocket/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], "@aws-sdk/middleware-websocket/@smithy/signature-v4": ["@smithy/signature-v4@5.3.14", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.14", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA=="], @@ -2982,11 +2958,9 @@ "@aws-sdk/nested-clients/@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "https://registry.npmmirror.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], - "@aws-sdk/nested-clients/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], - "@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@aws-sdk/nested-clients/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -3014,8 +2988,6 @@ "@aws-sdk/xml-builder/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], - "@azure/msal-node/uuid": ["uuid@8.3.2", "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], - "@babel/core/semver": ["semver@6.3.1", "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], @@ -3036,8 +3008,6 @@ "@fastify/otel/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.212.0", "https://registry.npmmirror.com/@opentelemetry/instrumentation/-/instrumentation-0.212.0.tgz", { "dependencies": { "@opentelemetry/api-logs": "0.212.0", "import-in-the-middle": "^2.0.6", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg=="], - "@grpc/proto-loader/protobufjs": ["protobufjs@7.5.4", "https://registry.npmmirror.com/protobufjs/-/protobufjs-7.5.4.tgz", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="], - "@grpc/proto-loader/yargs": ["yargs@17.7.2", "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz", { "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" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], "@hono/node-ws/@hono/node-server": ["@hono/node-server@1.19.13", "https://registry.npmmirror.com/@hono/node-server/-/node-server-1.19.13.tgz", { "peerDependencies": { "hono": "^4" } }, "sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ=="], @@ -3050,6 +3020,8 @@ "@modelcontextprotocol/sdk/@hono/node-server": ["@hono/node-server@1.19.13", "https://registry.npmmirror.com/@hono/node-server/-/node-server-1.19.13.tgz", { "peerDependencies": { "hono": "^4" } }, "sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ=="], + "@modelcontextprotocol/sdk/ajv": ["ajv@8.18.0", "https://registry.npmmirror.com/ajv/-/ajv-8.18.0.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + "@opentelemetry/exporter-logs-otlp-grpc/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "https://registry.npmmirror.com/@opentelemetry/core/-/core-2.6.1.tgz", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], "@opentelemetry/exporter-logs-otlp-http/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "https://registry.npmmirror.com/@opentelemetry/core/-/core-2.6.1.tgz", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], @@ -3118,8 +3090,6 @@ "@opentelemetry/instrumentation-pg/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "https://registry.npmmirror.com/@opentelemetry/core/-/core-2.6.1.tgz", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], - "@opentelemetry/instrumentation-undici/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "https://registry.npmmirror.com/@opentelemetry/core/-/core-2.6.1.tgz", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], - "@opentelemetry/otlp-exporter-base/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "https://registry.npmmirror.com/@opentelemetry/core/-/core-2.6.1.tgz", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], "@opentelemetry/otlp-grpc-exporter-base/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "https://registry.npmmirror.com/@opentelemetry/core/-/core-2.6.1.tgz", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], @@ -3132,14 +3102,14 @@ "@opentelemetry/otlp-transformer/@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.6.1", "https://registry.npmmirror.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.6.1.tgz", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/resources": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw=="], - "@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.5.4", "https://registry.npmmirror.com/protobufjs/-/protobufjs-7.5.4.tgz", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="], - "@opentelemetry/sdk-logs/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "https://registry.npmmirror.com/@opentelemetry/core/-/core-2.6.1.tgz", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], "@opentelemetry/sdk-logs/@opentelemetry/resources": ["@opentelemetry/resources@2.6.1", "https://registry.npmmirror.com/@opentelemetry/resources/-/resources-2.6.1.tgz", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA=="], "@opentelemetry/sql-common/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "https://registry.npmmirror.com/@opentelemetry/core/-/core-2.6.1.tgz", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], + "@oxc-resolver/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "https://registry.npmmirror.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], + "@prisma/instrumentation/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.207.0", "https://registry.npmmirror.com/@opentelemetry/instrumentation/-/instrumentation-0.207.0.tgz", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA=="], "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], @@ -3166,6 +3136,10 @@ "@radix-ui/react-tooltip/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + "@rolldown/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], + + "@rolldown/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], + "@smithy/config-resolver/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], "@smithy/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], @@ -3188,11 +3162,9 @@ "@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@2.2.0", "https://registry.npmmirror.com/@smithy/eventstream-codec/-/eventstream-codec-2.2.0.tgz", { "dependencies": { "@aws-crypto/crc32": "3.0.0", "@smithy/types": "^2.12.0", "@smithy/util-hex-encoding": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw=="], - "@smithy/fetch-http-handler/@smithy/protocol-http": ["@smithy/protocol-http@5.3.13", "https://registry.npmmirror.com/@smithy/protocol-http/-/protocol-http-5.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg=="], - - "@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-builder/-/querystring-builder-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ=="], + "@smithy/fetch-http-handler/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@smithy/fetch-http-handler/@smithy/types": ["@smithy/types@4.14.0", "https://registry.npmmirror.com/@smithy/types/-/types-4.14.0.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-OWgntFLW88kx2qvf/c/67Vno1yuXm/f9M7QFAtVkkO29IJXGBIg0ycEaBTH0kvCtwmvZxRujrgP5a86RvsXJAQ=="], + "@smithy/fetch-http-handler/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], "@smithy/fetch-http-handler/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], @@ -3210,7 +3182,7 @@ "@smithy/middleware-retry/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@smithy/middleware-retry/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@smithy/middleware-retry/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@smithy/middleware-retry/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -3256,11 +3228,11 @@ "@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], - "@smithy/util-defaults-mode-browser/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@smithy/util-defaults-mode-browser/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@smithy/util-defaults-mode-browser/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], - "@smithy/util-defaults-mode-node/@smithy/smithy-client": ["@smithy/smithy-client@4.12.11", "", { "dependencies": { "@smithy/core": "^3.23.15", "@smithy/middleware-endpoint": "^4.4.30", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.23", "tslib": "^2.6.2" } }, "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg=="], + "@smithy/util-defaults-mode-node/@smithy/smithy-client": ["@smithy/smithy-client@4.12.13", "", { "dependencies": { "@smithy/core": "^3.23.17", "@smithy/middleware-endpoint": "^4.4.32", "@smithy/middleware-stack": "^4.2.14", "@smithy/protocol-http": "^5.3.14", "@smithy/types": "^4.14.1", "@smithy/util-stream": "^4.5.25", "tslib": "^2.6.2" } }, "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA=="], "@smithy/util-defaults-mode-node/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], @@ -3270,8 +3242,6 @@ "@smithy/util-retry/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], - "@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.17", "", { "dependencies": { "@smithy/protocol-http": "^5.3.14", "@smithy/querystring-builder": "^4.2.14", "@smithy/types": "^4.14.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw=="], - "@smithy/util-stream/@smithy/types": ["@smithy/types@4.14.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg=="], "@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], @@ -3300,10 +3270,20 @@ "ai/@opentelemetry/api": ["@opentelemetry/api@1.9.0", "https://registry.npmmirror.com/@opentelemetry/api/-/api-1.9.0.tgz", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], + "ajv-formats/ajv": ["ajv@8.18.0", "https://registry.npmmirror.com/ajv/-/ajv-8.18.0.tgz", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + "ansi-escapes/type-fest": ["type-fest@0.21.3", "https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], "cacache/lru-cache": ["lru-cache@11.3.3", "https://registry.npmmirror.com/lru-cache/-/lru-cache-11.3.3.tgz", {}, "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ=="], + "ccb-vscode/@types/node": ["@types/node@22.19.17", "https://registry.npmmirror.com/@types/node/-/node-22.19.17.tgz", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q=="], + + "ccb-vscode/marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="], + + "ccb-vscode/typescript": ["typescript@5.9.3", "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "ccb-vscode/zod": ["zod@3.25.76", "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "cli-highlight/chalk": ["chalk@4.1.2", "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "cli-highlight/highlight.js": ["highlight.js@10.7.3", "https://registry.npmmirror.com/highlight.js/-/highlight.js-10.7.3.tgz", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], @@ -3348,8 +3328,6 @@ "mermaid/marked": ["marked@16.4.2", "https://registry.npmmirror.com/marked/-/marked-16.4.2.tgz", { "bin": { "marked": "bin/marked.js" } }, "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA=="], - "micromatch/picomatch": ["picomatch@2.3.2", "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.2.tgz", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "minipass-flush/minipass": ["minipass@3.3.6", "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], "minipass-pipeline/minipass": ["minipass@3.3.6", "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], @@ -3374,9 +3352,7 @@ "radix-ui/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "rolldown/@oxc-project/types": ["@oxc-project/types@0.124.0", "https://registry.npmmirror.com/@oxc-project/types/-/types-0.124.0.tgz", {}, "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg=="], - - "rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz", {}, "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g=="], + "rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.17", "", {}, "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg=="], "streamdown/lucide-react": ["lucide-react@0.542.0", "https://registry.npmmirror.com/lucide-react/-/lucide-react-0.542.0.tgz", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-w3hD8/SQB7+lzU2r4VdFyzzOzKnUjTZIF/MQJGSSvni7Llewni4vuViRppfRAa2guOsY5k4jZyxw/i9DQHv+dw=="], @@ -3390,126 +3366,6 @@ "yargs/string-width": ["string-width@4.2.3", "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "https://registry.npmmirror.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/core": ["@aws-sdk/core@3.973.27", "https://registry.npmmirror.com/@aws-sdk/core/-/core-3.973.27.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws-sdk/xml-builder": "^3.972.17", "@smithy/core": "^3.23.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/signature-v4": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.30", "https://registry.npmmirror.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.30.tgz", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.25", "@aws-sdk/credential-provider-http": "^3.972.27", "@aws-sdk/credential-provider-ini": "^3.972.29", "@aws-sdk/credential-provider-process": "^3.972.25", "@aws-sdk/credential-provider-sso": "^3.972.29", "@aws-sdk/credential-provider-web-identity": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/credential-provider-imds": "^4.2.13", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-FMnAnWxc8PG+ZrZ2OBKzY4luCUJhe9CG0B9YwYr4pzrYGLXBS2rl+UoUvjGbAwiptxRL6hyA3lFn03Bv1TLqTw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.972.13", "https://registry.npmmirror.com/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.13.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/eventstream-codec": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-2Pi1kD0MDkMAxDHqvpi/hKMs9hXUYbj2GLEjCwy+0jzfLChAsF50SUYnOeTI+RztA+Ic4pnLAdB03f1e8nggxQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-eventstream": ["@aws-sdk/middleware-eventstream@3.972.9", "https://registry.npmmirror.com/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-ypgOvpWxQTCnQyDHGxnTviqqANE7FIIzII7VczJnTPCJcJlu17hMQXnvE47aKSKsawVJAaaRsyOEbHQuLJF9ng=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "https://registry.npmmirror.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "https://registry.npmmirror.com/@aws-sdk/middleware-logger/-/middleware-logger-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "https://registry.npmmirror.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.10.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "https://registry.npmmirror.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket": ["@aws-sdk/middleware-websocket@3.972.15", "https://registry.npmmirror.com/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.15.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-format-url": "^3.972.9", "@smithy/eventstream-codec": "^4.2.13", "@smithy/eventstream-serde-browser": "^4.2.13", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/protocol-http": "^5.3.13", "@smithy/signature-v4": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-hsZ35FORQsN5hwNdMD6zWmHCphbXkDxO6j+xwCUiuMb0O6gzS/PWgttQNl1OAn7h/uqZAMUG4yOS0wY/yhAieg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "https://registry.npmmirror.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.11.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1029.0", "https://registry.npmmirror.com/@aws-sdk/token-providers/-/token-providers-3.1029.0.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-oU3a9wEBUYHuWsoMpahiRIIQMUy2RSRb9NhlJ9DtKTwYWV2OXZ0hEM+RTjIC8T8I8v/C83OqbZrj7NBg1ATAhw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/types": ["@aws-sdk/types@3.973.7", "https://registry.npmmirror.com/@aws-sdk/types/-/types-3.973.7.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "https://registry.npmmirror.com/@aws-sdk/util-endpoints/-/util-endpoints-3.996.6.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "https://registry.npmmirror.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "https://registry.npmmirror.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.15.tgz", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/config-resolver": ["@smithy/config-resolver@4.4.14", "https://registry.npmmirror.com/@smithy/config-resolver/-/config-resolver-4.4.14.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-N55f8mPEccpzKetUagdvmAy8oohf0J5cuj9jLI1TaSceRlq0pJsIZepY3kmAXAhyxqXPV6hDerDQhqQPKWgAoQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/core": ["@smithy/core@3.23.14", "https://registry.npmmirror.com/@smithy/core/-/core-3.23.14.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-stream": "^4.5.22", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-vJ0IhpZxZAkFYOegMKSrxw7ujhhT2pass/1UEcZ4kfl5srTAqtPU5I7MdYQoreVas3204ykCiNhY1o7Xlz6Yyg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.13", "https://registry.npmmirror.com/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.13.tgz", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-wwybfcOX0tLqCcBP378TIU9IqrDuZq/tDV48LlZNydMpCnqnYr+hWBAYbRE+rFFf/p7IkDJySM3bgiMKP2ihPg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.13", "https://registry.npmmirror.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-ied1lO559PtAsMJzg2TKRlctLnEi1PfkNeMMpdwXDImk1zV9uvS/Oxoy/vcy9uv1GKZAjDAB5xT6ziE9fzm5wA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.13", "https://registry.npmmirror.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.13.tgz", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-hFyK+ORJrxAN3RYoaD6+gsGDQjeix8HOEkosoajvXYZ4VeqonM3G4jd9IIRm/sWGXUKmudkY9KdYjzosUqdM8A=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.13", "https://registry.npmmirror.com/@smithy/hash-node/-/hash-node-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-4/oy9h0jjmY80a2gOIo75iLl8TOPhmtx4E2Hz+PfMjvx/vLtGY4TMU/35WRyH2JHPfT5CVB38u4JRow7gnmzJA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.13", "https://registry.npmmirror.com/@smithy/invalid-dependency/-/invalid-dependency-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-jvC0RB/8BLj2SMIkY0Npl425IdnxZJxInpZJbu563zIRnVjpDMXevU3VMCRSabaLB0kf/eFIOusdGstrLJ8IDg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.13", "https://registry.npmmirror.com/@smithy/middleware-content-length/-/middleware-content-length-4.2.13.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-IPMLm/LE4AZwu6qiE8Rr8vJsWhs9AtOdySRXrOM7xnvclp77Tyh7hMs/FRrMf26kgIe67vFJXXOSmVxS7oKeig=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.29", "https://registry.npmmirror.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.29.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-serde": "^4.2.17", "@smithy/node-config-provider": "^4.3.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-middleware": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-R9Q/58U+qBiSARGWbAbFLczECg/RmysRksX6Q8BaQEpt75I7LI6WGDZnjuC9GXSGKljEbA7N118LhGaMbfrTXw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry": ["@smithy/middleware-retry@4.5.1", "https://registry.npmmirror.com/@smithy/middleware-retry/-/middleware-retry-4.5.1.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/protocol-http": "^5.3.13", "@smithy/service-error-classification": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.1", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-/zY+Gp7Qj2D2hVm3irkCyONER7E9MiX3cUUm/k2ZmhkzZkrPgwVS4aJ5NriZUEN/M0D1hhjrgjUmX04HhRwdWA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.17", "https://registry.npmmirror.com/@smithy/middleware-serde/-/middleware-serde-4.2.17.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-0T2mcaM6v9W1xku86Dk0bEW7aEseG6KenFkPK98XNw0ZhOqOiD1MrMsdnQw9QsL3/Oa85T53iSMlm0SZdSuIEQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.13", "https://registry.npmmirror.com/@smithy/middleware-stack/-/middleware-stack-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-g72jN/sGDLyTanrCLH9fhg3oysO3f7tQa6eWWsMyn2BiYNCgjF24n4/I9wff/5XidFvjj9ilipAoQrurTUrLvw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.13", "https://registry.npmmirror.com/@smithy/node-config-provider/-/node-config-provider-4.3.13.tgz", { "dependencies": { "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-iGxQ04DsKXLckbgnX4ipElrOTk+IHgTyu0q0WssZfYhDm9CQWHmu6cOeI5wmWRxpXbBDhIIfXMWz5tPEtcVqbw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.2", "https://registry.npmmirror.com/@smithy/node-http-handler/-/node-http-handler-4.5.2.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/querystring-builder": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-/oD7u8M0oj2ZTFw7GkuuHWpIxtWdLlnyNkbrWcyVYhd5RJNDuczdkb0wfnQICyNFrVPlr8YHOhamjNy3zidhmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.13", "https://registry.npmmirror.com/@smithy/protocol-http/-/protocol-http-5.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.12.9", "https://registry.npmmirror.com/@smithy/smithy-client/-/smithy-client-4.12.9.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-stack": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-stream": "^4.5.22", "tslib": "^2.6.2" } }, "sha512-ovaLEcTU5olSeHcRXcxV6viaKtpkHZumn6Ps0yn7dRf2rRSfy794vpjOtrWDO0d1auDSvAqxO+lyhERSXQ03EQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.14.0", "https://registry.npmmirror.com/@smithy/types/-/types-4.14.0.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-OWgntFLW88kx2qvf/c/67Vno1yuXm/f9M7QFAtVkkO29IJXGBIg0ycEaBTH0kvCtwmvZxRujrgP5a86RvsXJAQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.13", "https://registry.npmmirror.com/@smithy/url-parser/-/url-parser-4.2.13.tgz", { "dependencies": { "@smithy/querystring-parser": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-2G03yoboIRZlZze2+PT4GZEjgwQsJjUgn6iTsvxA02bVceHR6vp4Cuk7TUnPFWKF+ffNUk3kj4COwkENS2K3vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.45", "https://registry.npmmirror.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.45.tgz", { "dependencies": { "@smithy/property-provider": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-ag9sWc6/nWZAuK3Wm9KlFJUnRkXLrXn33RFjIAmCTFThqLHY+7wCst10BGq56FxslsDrjhSie46c8OULS+BiIw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.49", "https://registry.npmmirror.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.49.tgz", { "dependencies": { "@smithy/config-resolver": "^4.4.14", "@smithy/credential-provider-imds": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-jlN6vHwE8gY5AfiFBavtD3QtCX2f7lM3BKkz7nFKSNfFR5nXLXLg6sqXTJEEyDwtxbztIDBQCfjsGVXlIru2lQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.4", "https://registry.npmmirror.com/@smithy/util-endpoints/-/util-endpoints-3.3.4.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-BKoR/ubPp9KNKFxPpg1J28N1+bgu8NGAtJblBP7yHy8yQPBWhIAv9+l92SlQLpolGm71CVO+btB60gTgzT0wog=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.13", "https://registry.npmmirror.com/@smithy/util-middleware/-/util-middleware-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-GTooyrlmRTqvUen4eK7/K1p6kryF7bnDfq6XsAbIsf2mo51B/utaH+XThY6dKgNCWzMAaH/+OLmqaBuLhLWRow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-retry": ["@smithy/util-retry@4.3.1", "https://registry.npmmirror.com/@smithy/util-retry/-/util-retry-4.3.1.tgz", { "dependencies": { "@smithy/service-error-classification": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-FwmicpgWOkP5kZUjN3y+3JIom8NLGqSAJBeoIgK0rIToI817TEBHCrd0A2qGeKQlgDeP+Jzn4i0H/NLAXGy9uQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-stream": ["@smithy/util-stream@4.5.22", "https://registry.npmmirror.com/@smithy/util-stream/-/util-stream-4.5.22.tgz", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.16", "@smithy/node-http-handler": "^4.5.2", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-3H8iq/0BfQjUs2/4fbHZ9aG9yNzcuZs24LPkcX1Q7Z+qpqaGM8+qbGmE8zo9m2nCRgamyvS98cHdcWvR6YUsew=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.1029.0", "https://registry.npmmirror.com/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1029.0.tgz", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/credential-provider-node": "^3.972.30", "@aws-sdk/middleware-host-header": "^3.972.9", "@aws-sdk/middleware-logger": "^3.972.9", "@aws-sdk/middleware-recursion-detection": "^3.972.10", "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/region-config-resolver": "^3.972.11", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@aws-sdk/util-user-agent-browser": "^3.972.9", "@aws-sdk/util-user-agent-node": "^3.973.15", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/hash-node": "^4.2.13", "@smithy/invalid-dependency": "^4.2.13", "@smithy/middleware-content-length": "^4.2.13", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-retry": "^4.5.0", "@smithy/middleware-serde": "^4.2.17", "@smithy/middleware-stack": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/node-http-handler": "^4.5.2", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.45", "@smithy/util-defaults-mode-node": "^4.2.49", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-wmQpZI+DweZ8mKGvkGXZFLxgyR2PoSqsnSvS8wHEuq9U282eD91zfkFsTK+rgQZK+ZYuCKwlBTjHbKKlQiJEjw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core": ["@aws-sdk/core@3.973.27", "https://registry.npmmirror.com/@aws-sdk/core/-/core-3.973.27.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws-sdk/xml-builder": "^3.972.17", "@smithy/core": "^3.23.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/signature-v4": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.22", "https://registry.npmmirror.com/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.22.tgz", { "dependencies": { "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-ih6ORpme4i2qJqGckOQ9Lt2iiZ+5tm3bnfsT5TwoPyFnuDURXv3OdhYa3Nr/m0iJr38biqKYKdGKb5GR1KB2hw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.25", "https://registry.npmmirror.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.25.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6QfI0wv4jpG5CrdO/AO0JfZ2ux+tKwJPrUwmvxXF50vI5KIypKVGNF6b4vlkYEnKumDTI1NX2zUBi8JoU5QU3A=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.27", "https://registry.npmmirror.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.27.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/node-http-handler": "^4.5.2", "@smithy/property-provider": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-stream": "^4.5.22", "tslib": "^2.6.2" } }, "sha512-3V3Usj9Gs93h865DqN4M2NWJhC5kXU9BvZskfN3+69omuYlE3TZxOEcVQtBGLOloJB7BVfJKXVLqeNhOzHqSlQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.29", "https://registry.npmmirror.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/credential-provider-env": "^3.972.25", "@aws-sdk/credential-provider-http": "^3.972.27", "@aws-sdk/credential-provider-login": "^3.972.29", "@aws-sdk/credential-provider-process": "^3.972.25", "@aws-sdk/credential-provider-sso": "^3.972.29", "@aws-sdk/credential-provider-web-identity": "^3.972.29", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/credential-provider-imds": "^4.2.13", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-SiBuAnXecCbT/OpAf3vqyI/AVE3mTaYr9ShXLybxZiPLBiPCCOIWSGAtYYGQWMRvobBTiqOewaB+wcgMMZI2Aw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.29", "https://registry.npmmirror.com/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-OGOslTbOlxXexKMqhxCEbBQbUIfuhGxU5UXw3Fm56ypXHvrXH4aTt/xb5Y884LOoteP1QST1lVZzHfcTnWhiPQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.30", "https://registry.npmmirror.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.30.tgz", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.25", "@aws-sdk/credential-provider-http": "^3.972.27", "@aws-sdk/credential-provider-ini": "^3.972.29", "@aws-sdk/credential-provider-process": "^3.972.25", "@aws-sdk/credential-provider-sso": "^3.972.29", "@aws-sdk/credential-provider-web-identity": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/credential-provider-imds": "^4.2.13", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-FMnAnWxc8PG+ZrZ2OBKzY4luCUJhe9CG0B9YwYr4pzrYGLXBS2rl+UoUvjGbAwiptxRL6hyA3lFn03Bv1TLqTw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.25", "https://registry.npmmirror.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.25.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HR7ynNRdNhNsdVCOCegy1HsfsRzozCOPtD3RzzT1JouuaHobWyRfJzCBue/3jP7gECHt+kQyZUvwg/cYLWurNQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.29", "https://registry.npmmirror.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/token-providers": "3.1026.0", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HWv4SEq3jZDYPlwryZVef97+U8CxxRos5mK8sgGO1dQaFZpV5giZLzqGE5hkDmh2csYcBO2uf5XHjPTpZcJlig=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.29", "https://registry.npmmirror.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-PdMBza1WEKEUPFEmMGCfnU2RYCz9MskU2e8JxjyUOsMKku7j9YaDKvbDi2dzC0ihFoM6ods2SbhfAAro+Gwlew=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.19", "https://registry.npmmirror.com/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/middleware-host-header": "^3.972.9", "@aws-sdk/middleware-logger": "^3.972.9", "@aws-sdk/middleware-recursion-detection": "^3.972.10", "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/region-config-resolver": "^3.972.11", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@aws-sdk/util-user-agent-browser": "^3.972.9", "@aws-sdk/util-user-agent-node": "^3.973.15", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/hash-node": "^4.2.13", "@smithy/invalid-dependency": "^4.2.13", "@smithy/middleware-content-length": "^4.2.13", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-retry": "^4.5.0", "@smithy/middleware-serde": "^4.2.17", "@smithy/middleware-stack": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/node-http-handler": "^4.5.2", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.45", "@smithy/util-defaults-mode-node": "^4.2.49", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/types": ["@aws-sdk/types@3.973.7", "https://registry.npmmirror.com/@aws-sdk/types/-/types-3.973.7.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/config-resolver": ["@smithy/config-resolver@4.4.14", "https://registry.npmmirror.com/@smithy/config-resolver/-/config-resolver-4.4.14.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-N55f8mPEccpzKetUagdvmAy8oohf0J5cuj9jLI1TaSceRlq0pJsIZepY3kmAXAhyxqXPV6hDerDQhqQPKWgAoQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core": ["@smithy/core@3.23.14", "https://registry.npmmirror.com/@smithy/core/-/core-3.23.14.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-stream": "^4.5.22", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-vJ0IhpZxZAkFYOegMKSrxw7ujhhT2pass/1UEcZ4kfl5srTAqtPU5I7MdYQoreVas3204ykCiNhY1o7Xlz6Yyg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.13", "https://registry.npmmirror.com/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.13.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-wboCPijzf6RJKLOvnjDAiBxGSmSnGXj35o5ZAWKDaHa/cvQ5U3ZJ13D4tMCE8JG4dxVAZFy/P0x/V9CwwdfULQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.13", "https://registry.npmmirror.com/@smithy/node-config-provider/-/node-config-provider-4.3.13.tgz", { "dependencies": { "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-iGxQ04DsKXLckbgnX4ipElrOTk+IHgTyu0q0WssZfYhDm9CQWHmu6cOeI5wmWRxpXbBDhIIfXMWz5tPEtcVqbw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.13", "https://registry.npmmirror.com/@smithy/property-provider/-/property-provider-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-bGzUCthxRmezuxkbu9wD33wWg9KX3hJpCXpQ93vVkPrHn9ZW6KNNdY5xAUWNuRCwQ+VyboFuWirG1lZhhkcyRQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/types": ["@smithy/types@4.14.0", "https://registry.npmmirror.com/@smithy/types/-/types-4.14.0.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-OWgntFLW88kx2qvf/c/67Vno1yuXm/f9M7QFAtVkkO29IJXGBIg0ycEaBTH0kvCtwmvZxRujrgP5a86RvsXJAQ=="], - "@anthropic-ai/vertex-sdk/google-auth-library/gaxios": ["gaxios@6.7.1", "https://registry.npmmirror.com/gaxios/-/gaxios-6.7.1.tgz", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", "uuid": "^9.0.1" } }, "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ=="], "@anthropic-ai/vertex-sdk/google-auth-library/gcp-metadata": ["gcp-metadata@6.1.1", "https://registry.npmmirror.com/gcp-metadata/-/gcp-metadata-6.1.1.tgz", { "dependencies": { "gaxios": "^6.1.1", "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" } }, "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A=="], @@ -3564,8 +3420,6 @@ "@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - "@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], - "@aws-sdk/middleware-sdk-s3/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], "@aws-sdk/middleware-sdk-s3/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], @@ -3620,8 +3474,6 @@ "@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@2.2.0", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ=="], - "@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - "@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], "@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], @@ -3650,14 +3502,14 @@ "@smithy/util-defaults-mode-node/@smithy/smithy-client/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@smithy/util-stream/@smithy/fetch-http-handler/@smithy/protocol-http": ["@smithy/protocol-http@5.3.14", "", { "dependencies": { "@smithy/types": "^4.14.1", "tslib": "^2.6.2" } }, "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ=="], - "@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], "@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], "@typespec/ts-http-runtime/https-proxy-agent/agent-base": ["agent-base@7.1.4", "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "ccb-vscode/@types/node/undici-types": ["undici-types@6.21.0", "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + "cli-highlight/chalk/ansi-styles": ["ansi-styles@4.3.0", "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "cli-highlight/chalk/supports-color": ["supports-color@7.2.0", "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], @@ -3684,8 +3536,6 @@ "gtoken/gaxios/node-fetch": ["node-fetch@2.7.0", "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "gtoken/gaxios/uuid": ["uuid@9.0.1", "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - "image-processor-napi/sharp/@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "https://registry.npmmirror.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], "image-processor-napi/sharp/@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "https://registry.npmmirror.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="], @@ -3750,246 +3600,12 @@ "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-crypto/sha256-js/@aws-crypto/util": ["@aws-crypto/util@5.2.0", "https://registry.npmmirror.com/@aws-crypto/util/-/util-5.2.0.tgz", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "https://registry.npmmirror.com/@aws-sdk/xml-builder/-/xml-builder-3.972.17.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.13", "https://registry.npmmirror.com/@smithy/property-provider/-/property-provider-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-bGzUCthxRmezuxkbu9wD33wWg9KX3hJpCXpQ93vVkPrHn9ZW6KNNdY5xAUWNuRCwQ+VyboFuWirG1lZhhkcyRQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.13", "https://registry.npmmirror.com/@smithy/signature-v4/-/signature-v4-5.3.13.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-YpYSyM0vMDwKbHD/JA7bVOF6kToVRpa+FM5ateEVRpsTNu564g1muBlkTubXhSKKYXInhpADF46FPyrZcTLpXg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.25", "https://registry.npmmirror.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.25.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6QfI0wv4jpG5CrdO/AO0JfZ2ux+tKwJPrUwmvxXF50vI5KIypKVGNF6b4vlkYEnKumDTI1NX2zUBi8JoU5QU3A=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.27", "https://registry.npmmirror.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.27.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/node-http-handler": "^4.5.2", "@smithy/property-provider": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-stream": "^4.5.22", "tslib": "^2.6.2" } }, "sha512-3V3Usj9Gs93h865DqN4M2NWJhC5kXU9BvZskfN3+69omuYlE3TZxOEcVQtBGLOloJB7BVfJKXVLqeNhOzHqSlQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.29", "https://registry.npmmirror.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/credential-provider-env": "^3.972.25", "@aws-sdk/credential-provider-http": "^3.972.27", "@aws-sdk/credential-provider-login": "^3.972.29", "@aws-sdk/credential-provider-process": "^3.972.25", "@aws-sdk/credential-provider-sso": "^3.972.29", "@aws-sdk/credential-provider-web-identity": "^3.972.29", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/credential-provider-imds": "^4.2.13", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-SiBuAnXecCbT/OpAf3vqyI/AVE3mTaYr9ShXLybxZiPLBiPCCOIWSGAtYYGQWMRvobBTiqOewaB+wcgMMZI2Aw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.25", "https://registry.npmmirror.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.25.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HR7ynNRdNhNsdVCOCegy1HsfsRzozCOPtD3RzzT1JouuaHobWyRfJzCBue/3jP7gECHt+kQyZUvwg/cYLWurNQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.29", "https://registry.npmmirror.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/token-providers": "3.1026.0", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HWv4SEq3jZDYPlwryZVef97+U8CxxRos5mK8sgGO1dQaFZpV5giZLzqGE5hkDmh2csYcBO2uf5XHjPTpZcJlig=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.29", "https://registry.npmmirror.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-PdMBza1WEKEUPFEmMGCfnU2RYCz9MskU2e8JxjyUOsMKku7j9YaDKvbDi2dzC0ihFoM6ods2SbhfAAro+Gwlew=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.13", "https://registry.npmmirror.com/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.13.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-wboCPijzf6RJKLOvnjDAiBxGSmSnGXj35o5ZAWKDaHa/cvQ5U3ZJ13D4tMCE8JG4dxVAZFy/P0x/V9CwwdfULQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.13", "https://registry.npmmirror.com/@smithy/property-provider/-/property-provider-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-bGzUCthxRmezuxkbu9wD33wWg9KX3hJpCXpQ93vVkPrHn9ZW6KNNdY5xAUWNuRCwQ+VyboFuWirG1lZhhkcyRQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.13", "https://registry.npmmirror.com/@smithy/eventstream-codec/-/eventstream-codec-4.2.13.tgz", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-vYahwBAtRaAcFbOmE9aLr12z7RiHYDSLcnogSdxfm7kKfsNa3wH+NU5r7vTeB5rKvLsWyPjVX8iH94brP7umiQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.972.9", "https://registry.npmmirror.com/@aws-sdk/util-format-url/-/util-format-url-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/querystring-builder": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-fNJXHrs0ZT7Wx0KGIqKv7zLxlDXt2vqjx9z6oKUQFmpE5o4xxnSryvVHfHpIifYHWKz94hFccIldJ0YSZjlCBw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.13", "https://registry.npmmirror.com/@smithy/eventstream-codec/-/eventstream-codec-4.2.13.tgz", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-vYahwBAtRaAcFbOmE9aLr12z7RiHYDSLcnogSdxfm7kKfsNa3wH+NU5r7vTeB5rKvLsWyPjVX8iH94brP7umiQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4": ["@smithy/signature-v4@5.3.13", "https://registry.npmmirror.com/@smithy/signature-v4/-/signature-v4-5.3.13.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-YpYSyM0vMDwKbHD/JA7bVOF6kToVRpa+FM5ateEVRpsTNu564g1muBlkTubXhSKKYXInhpADF46FPyrZcTLpXg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.19", "https://registry.npmmirror.com/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/middleware-host-header": "^3.972.9", "@aws-sdk/middleware-logger": "^3.972.9", "@aws-sdk/middleware-recursion-detection": "^3.972.10", "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/region-config-resolver": "^3.972.11", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@aws-sdk/util-user-agent-browser": "^3.972.9", "@aws-sdk/util-user-agent-node": "^3.973.15", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/hash-node": "^4.2.13", "@smithy/invalid-dependency": "^4.2.13", "@smithy/middleware-content-length": "^4.2.13", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-retry": "^4.5.0", "@smithy/middleware-serde": "^4.2.17", "@smithy/middleware-stack": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/node-http-handler": "^4.5.2", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.45", "@smithy/util-defaults-mode-node": "^4.2.49", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.13", "https://registry.npmmirror.com/@smithy/property-provider/-/property-provider-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-bGzUCthxRmezuxkbu9wD33wWg9KX3hJpCXpQ93vVkPrHn9ZW6KNNdY5xAUWNuRCwQ+VyboFuWirG1lZhhkcyRQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.13", "https://registry.npmmirror.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.13.tgz", { "dependencies": { "@smithy/eventstream-codec": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-kRrq4EKLGeOxhC2CBEhRNcu1KSzNJzYY7RK3S7CxMPgB5dRrv55WqQOtRwQxQLC04xqORFLUgnDlc6xrNUULaA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.13", "https://registry.npmmirror.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.13.tgz", { "dependencies": { "@smithy/eventstream-codec": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-kRrq4EKLGeOxhC2CBEhRNcu1KSzNJzYY7RK3S7CxMPgB5dRrv55WqQOtRwQxQLC04xqORFLUgnDlc6xrNUULaA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.13", "https://registry.npmmirror.com/@smithy/service-error-classification/-/service-error-classification-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0" } }, "sha512-a0s8XZMfOC/qpqq7RCPvJlk93rWFrElH6O++8WJKz0FqnA4Y7fkNi/0mnGgSH1C4x6MFsuBA8VKu4zxFrMe5Vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.13", "https://registry.npmmirror.com/@smithy/property-provider/-/property-provider-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-bGzUCthxRmezuxkbu9wD33wWg9KX3hJpCXpQ93vVkPrHn9ZW6KNNdY5xAUWNuRCwQ+VyboFuWirG1lZhhkcyRQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-builder/-/querystring-builder-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-parser/-/querystring-parser-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-hqW3Q4P+CDzUyQ87GrboGMeD7XYNMOF+CuTwu936UQRB/zeYn3jys8C3w+wMkDfY7CyyyVwZQ5cNFoG0x1pYmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.13", "https://registry.npmmirror.com/@smithy/property-provider/-/property-provider-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-bGzUCthxRmezuxkbu9wD33wWg9KX3hJpCXpQ93vVkPrHn9ZW6KNNdY5xAUWNuRCwQ+VyboFuWirG1lZhhkcyRQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.13", "https://registry.npmmirror.com/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.13.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-wboCPijzf6RJKLOvnjDAiBxGSmSnGXj35o5ZAWKDaHa/cvQ5U3ZJ13D4tMCE8JG4dxVAZFy/P0x/V9CwwdfULQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.13", "https://registry.npmmirror.com/@smithy/property-provider/-/property-provider-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-bGzUCthxRmezuxkbu9wD33wWg9KX3hJpCXpQ93vVkPrHn9ZW6KNNdY5xAUWNuRCwQ+VyboFuWirG1lZhhkcyRQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.13", "https://registry.npmmirror.com/@smithy/service-error-classification/-/service-error-classification-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0" } }, "sha512-a0s8XZMfOC/qpqq7RCPvJlk93rWFrElH6O++8WJKz0FqnA4Y7fkNi/0mnGgSH1C4x6MFsuBA8VKu4zxFrMe5Vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "https://registry.npmmirror.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "https://registry.npmmirror.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "https://registry.npmmirror.com/@aws-sdk/middleware-logger/-/middleware-logger-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "https://registry.npmmirror.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.10.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "https://registry.npmmirror.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "https://registry.npmmirror.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.11.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "https://registry.npmmirror.com/@aws-sdk/util-endpoints/-/util-endpoints-3.996.6.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "https://registry.npmmirror.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "https://registry.npmmirror.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.15.tgz", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/hash-node": ["@smithy/hash-node@4.2.13", "https://registry.npmmirror.com/@smithy/hash-node/-/hash-node-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-4/oy9h0jjmY80a2gOIo75iLl8TOPhmtx4E2Hz+PfMjvx/vLtGY4TMU/35WRyH2JHPfT5CVB38u4JRow7gnmzJA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.13", "https://registry.npmmirror.com/@smithy/invalid-dependency/-/invalid-dependency-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-jvC0RB/8BLj2SMIkY0Npl425IdnxZJxInpZJbu563zIRnVjpDMXevU3VMCRSabaLB0kf/eFIOusdGstrLJ8IDg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.13", "https://registry.npmmirror.com/@smithy/middleware-content-length/-/middleware-content-length-4.2.13.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-IPMLm/LE4AZwu6qiE8Rr8vJsWhs9AtOdySRXrOM7xnvclp77Tyh7hMs/FRrMf26kgIe67vFJXXOSmVxS7oKeig=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.29", "https://registry.npmmirror.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.29.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-serde": "^4.2.17", "@smithy/node-config-provider": "^4.3.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-middleware": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-R9Q/58U+qBiSARGWbAbFLczECg/RmysRksX6Q8BaQEpt75I7LI6WGDZnjuC9GXSGKljEbA7N118LhGaMbfrTXw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-retry": ["@smithy/middleware-retry@4.5.1", "https://registry.npmmirror.com/@smithy/middleware-retry/-/middleware-retry-4.5.1.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/protocol-http": "^5.3.13", "@smithy/service-error-classification": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.1", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-/zY+Gp7Qj2D2hVm3irkCyONER7E9MiX3cUUm/k2ZmhkzZkrPgwVS4aJ5NriZUEN/M0D1hhjrgjUmX04HhRwdWA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.17", "https://registry.npmmirror.com/@smithy/middleware-serde/-/middleware-serde-4.2.17.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-0T2mcaM6v9W1xku86Dk0bEW7aEseG6KenFkPK98XNw0ZhOqOiD1MrMsdnQw9QsL3/Oa85T53iSMlm0SZdSuIEQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.13", "https://registry.npmmirror.com/@smithy/middleware-stack/-/middleware-stack-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-g72jN/sGDLyTanrCLH9fhg3oysO3f7tQa6eWWsMyn2BiYNCgjF24n4/I9wff/5XidFvjj9ilipAoQrurTUrLvw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.2", "https://registry.npmmirror.com/@smithy/node-http-handler/-/node-http-handler-4.5.2.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/querystring-builder": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-/oD7u8M0oj2ZTFw7GkuuHWpIxtWdLlnyNkbrWcyVYhd5RJNDuczdkb0wfnQICyNFrVPlr8YHOhamjNy3zidhmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/protocol-http": ["@smithy/protocol-http@5.3.13", "https://registry.npmmirror.com/@smithy/protocol-http/-/protocol-http-5.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client": ["@smithy/smithy-client@4.12.9", "https://registry.npmmirror.com/@smithy/smithy-client/-/smithy-client-4.12.9.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-stack": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-stream": "^4.5.22", "tslib": "^2.6.2" } }, "sha512-ovaLEcTU5olSeHcRXcxV6viaKtpkHZumn6Ps0yn7dRf2rRSfy794vpjOtrWDO0d1auDSvAqxO+lyhERSXQ03EQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/url-parser": ["@smithy/url-parser@4.2.13", "https://registry.npmmirror.com/@smithy/url-parser/-/url-parser-4.2.13.tgz", { "dependencies": { "@smithy/querystring-parser": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-2G03yoboIRZlZze2+PT4GZEjgwQsJjUgn6iTsvxA02bVceHR6vp4Cuk7TUnPFWKF+ffNUk3kj4COwkENS2K3vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.45", "https://registry.npmmirror.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.45.tgz", { "dependencies": { "@smithy/property-provider": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-ag9sWc6/nWZAuK3Wm9KlFJUnRkXLrXn33RFjIAmCTFThqLHY+7wCst10BGq56FxslsDrjhSie46c8OULS+BiIw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.49", "https://registry.npmmirror.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.49.tgz", { "dependencies": { "@smithy/config-resolver": "^4.4.14", "@smithy/credential-provider-imds": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-jlN6vHwE8gY5AfiFBavtD3QtCX2f7lM3BKkz7nFKSNfFR5nXLXLg6sqXTJEEyDwtxbztIDBQCfjsGVXlIru2lQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.4", "https://registry.npmmirror.com/@smithy/util-endpoints/-/util-endpoints-3.3.4.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-BKoR/ubPp9KNKFxPpg1J28N1+bgu8NGAtJblBP7yHy8yQPBWhIAv9+l92SlQLpolGm71CVO+btB60gTgzT0wog=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-middleware": ["@smithy/util-middleware@4.2.13", "https://registry.npmmirror.com/@smithy/util-middleware/-/util-middleware-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-GTooyrlmRTqvUen4eK7/K1p6kryF7bnDfq6XsAbIsf2mo51B/utaH+XThY6dKgNCWzMAaH/+OLmqaBuLhLWRow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-retry": ["@smithy/util-retry@4.3.1", "https://registry.npmmirror.com/@smithy/util-retry/-/util-retry-4.3.1.tgz", { "dependencies": { "@smithy/service-error-classification": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-FwmicpgWOkP5kZUjN3y+3JIom8NLGqSAJBeoIgK0rIToI817TEBHCrd0A2qGeKQlgDeP+Jzn4i0H/NLAXGy9uQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "https://registry.npmmirror.com/@aws-sdk/xml-builder/-/xml-builder-3.972.17.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.13", "https://registry.npmmirror.com/@smithy/protocol-http/-/protocol-http-5.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.13", "https://registry.npmmirror.com/@smithy/signature-v4/-/signature-v4-5.3.13.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-YpYSyM0vMDwKbHD/JA7bVOF6kToVRpa+FM5ateEVRpsTNu564g1muBlkTubXhSKKYXInhpADF46FPyrZcTLpXg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.12.9", "https://registry.npmmirror.com/@smithy/smithy-client/-/smithy-client-4.12.9.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-stack": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-stream": "^4.5.22", "tslib": "^2.6.2" } }, "sha512-ovaLEcTU5olSeHcRXcxV6viaKtpkHZumn6Ps0yn7dRf2rRSfy794vpjOtrWDO0d1auDSvAqxO+lyhERSXQ03EQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.13", "https://registry.npmmirror.com/@smithy/util-middleware/-/util-middleware-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-GTooyrlmRTqvUen4eK7/K1p6kryF7bnDfq6XsAbIsf2mo51B/utaH+XThY6dKgNCWzMAaH/+OLmqaBuLhLWRow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.2", "https://registry.npmmirror.com/@smithy/node-http-handler/-/node-http-handler-4.5.2.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/querystring-builder": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-/oD7u8M0oj2ZTFw7GkuuHWpIxtWdLlnyNkbrWcyVYhd5RJNDuczdkb0wfnQICyNFrVPlr8YHOhamjNy3zidhmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/protocol-http": ["@smithy/protocol-http@5.3.13", "https://registry.npmmirror.com/@smithy/protocol-http/-/protocol-http-5.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client": ["@smithy/smithy-client@4.12.9", "https://registry.npmmirror.com/@smithy/smithy-client/-/smithy-client-4.12.9.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-stack": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-stream": "^4.5.22", "tslib": "^2.6.2" } }, "sha512-ovaLEcTU5olSeHcRXcxV6viaKtpkHZumn6Ps0yn7dRf2rRSfy794vpjOtrWDO0d1auDSvAqxO+lyhERSXQ03EQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@4.5.22", "https://registry.npmmirror.com/@smithy/util-stream/-/util-stream-4.5.22.tgz", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.16", "@smithy/node-http-handler": "^4.5.2", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-3H8iq/0BfQjUs2/4fbHZ9aG9yNzcuZs24LPkcX1Q7Z+qpqaGM8+qbGmE8zo9m2nCRgamyvS98cHdcWvR6YUsew=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-ini/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-login/@smithy/protocol-http": ["@smithy/protocol-http@5.3.13", "https://registry.npmmirror.com/@smithy/protocol-http/-/protocol-http-5.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-login/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-process/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1026.0", "https://registry.npmmirror.com/@aws-sdk/token-providers/-/token-providers-3.1026.0.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-Ieq/HiRrbEtrYP387Nes0XlR7H1pJiJOZKv+QyQzMYpvTiDs0VKy2ZB3E2Zf+aFovWmeE7lRE4lXyF7dYM6GgA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-sso/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-web-identity/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "https://registry.npmmirror.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "https://registry.npmmirror.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "https://registry.npmmirror.com/@aws-sdk/middleware-logger/-/middleware-logger-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "https://registry.npmmirror.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.10.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "https://registry.npmmirror.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "https://registry.npmmirror.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.11.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "https://registry.npmmirror.com/@aws-sdk/util-endpoints/-/util-endpoints-3.996.6.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "https://registry.npmmirror.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.9.tgz", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "https://registry.npmmirror.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.15.tgz", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/hash-node": ["@smithy/hash-node@4.2.13", "https://registry.npmmirror.com/@smithy/hash-node/-/hash-node-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-4/oy9h0jjmY80a2gOIo75iLl8TOPhmtx4E2Hz+PfMjvx/vLtGY4TMU/35WRyH2JHPfT5CVB38u4JRow7gnmzJA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.13", "https://registry.npmmirror.com/@smithy/invalid-dependency/-/invalid-dependency-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-jvC0RB/8BLj2SMIkY0Npl425IdnxZJxInpZJbu563zIRnVjpDMXevU3VMCRSabaLB0kf/eFIOusdGstrLJ8IDg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.13", "https://registry.npmmirror.com/@smithy/middleware-content-length/-/middleware-content-length-4.2.13.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-IPMLm/LE4AZwu6qiE8Rr8vJsWhs9AtOdySRXrOM7xnvclp77Tyh7hMs/FRrMf26kgIe67vFJXXOSmVxS7oKeig=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.29", "https://registry.npmmirror.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.29.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-serde": "^4.2.17", "@smithy/node-config-provider": "^4.3.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-middleware": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-R9Q/58U+qBiSARGWbAbFLczECg/RmysRksX6Q8BaQEpt75I7LI6WGDZnjuC9GXSGKljEbA7N118LhGaMbfrTXw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/middleware-retry": ["@smithy/middleware-retry@4.5.1", "https://registry.npmmirror.com/@smithy/middleware-retry/-/middleware-retry-4.5.1.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/protocol-http": "^5.3.13", "@smithy/service-error-classification": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.1", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-/zY+Gp7Qj2D2hVm3irkCyONER7E9MiX3cUUm/k2ZmhkzZkrPgwVS4aJ5NriZUEN/M0D1hhjrgjUmX04HhRwdWA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.17", "https://registry.npmmirror.com/@smithy/middleware-serde/-/middleware-serde-4.2.17.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-0T2mcaM6v9W1xku86Dk0bEW7aEseG6KenFkPK98XNw0ZhOqOiD1MrMsdnQw9QsL3/Oa85T53iSMlm0SZdSuIEQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.13", "https://registry.npmmirror.com/@smithy/middleware-stack/-/middleware-stack-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-g72jN/sGDLyTanrCLH9fhg3oysO3f7tQa6eWWsMyn2BiYNCgjF24n4/I9wff/5XidFvjj9ilipAoQrurTUrLvw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.2", "https://registry.npmmirror.com/@smithy/node-http-handler/-/node-http-handler-4.5.2.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/querystring-builder": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-/oD7u8M0oj2ZTFw7GkuuHWpIxtWdLlnyNkbrWcyVYhd5RJNDuczdkb0wfnQICyNFrVPlr8YHOhamjNy3zidhmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.13", "https://registry.npmmirror.com/@smithy/protocol-http/-/protocol-http-5.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.12.9", "https://registry.npmmirror.com/@smithy/smithy-client/-/smithy-client-4.12.9.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-stack": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-stream": "^4.5.22", "tslib": "^2.6.2" } }, "sha512-ovaLEcTU5olSeHcRXcxV6viaKtpkHZumn6Ps0yn7dRf2rRSfy794vpjOtrWDO0d1auDSvAqxO+lyhERSXQ03EQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.13", "https://registry.npmmirror.com/@smithy/url-parser/-/url-parser-4.2.13.tgz", { "dependencies": { "@smithy/querystring-parser": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-2G03yoboIRZlZze2+PT4GZEjgwQsJjUgn6iTsvxA02bVceHR6vp4Cuk7TUnPFWKF+ffNUk3kj4COwkENS2K3vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.45", "https://registry.npmmirror.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.45.tgz", { "dependencies": { "@smithy/property-provider": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-ag9sWc6/nWZAuK3Wm9KlFJUnRkXLrXn33RFjIAmCTFThqLHY+7wCst10BGq56FxslsDrjhSie46c8OULS+BiIw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.49", "https://registry.npmmirror.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.49.tgz", { "dependencies": { "@smithy/config-resolver": "^4.4.14", "@smithy/credential-provider-imds": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-jlN6vHwE8gY5AfiFBavtD3QtCX2f7lM3BKkz7nFKSNfFR5nXLXLg6sqXTJEEyDwtxbztIDBQCfjsGVXlIru2lQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.4", "https://registry.npmmirror.com/@smithy/util-endpoints/-/util-endpoints-3.3.4.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-BKoR/ubPp9KNKFxPpg1J28N1+bgu8NGAtJblBP7yHy8yQPBWhIAv9+l92SlQLpolGm71CVO+btB60gTgzT0wog=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.13", "https://registry.npmmirror.com/@smithy/util-middleware/-/util-middleware-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-GTooyrlmRTqvUen4eK7/K1p6kryF7bnDfq6XsAbIsf2mo51B/utaH+XThY6dKgNCWzMAaH/+OLmqaBuLhLWRow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.3.1", "https://registry.npmmirror.com/@smithy/util-retry/-/util-retry-4.3.1.tgz", { "dependencies": { "@smithy/service-error-classification": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-FwmicpgWOkP5kZUjN3y+3JIom8NLGqSAJBeoIgK0rIToI817TEBHCrd0A2qGeKQlgDeP+Jzn4i0H/NLAXGy9uQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/config-resolver/@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.4", "https://registry.npmmirror.com/@smithy/util-endpoints/-/util-endpoints-3.3.4.tgz", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-BKoR/ubPp9KNKFxPpg1J28N1+bgu8NGAtJblBP7yHy8yQPBWhIAv9+l92SlQLpolGm71CVO+btB60gTgzT0wog=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/config-resolver/@smithy/util-middleware": ["@smithy/util-middleware@4.2.13", "https://registry.npmmirror.com/@smithy/util-middleware/-/util-middleware-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-GTooyrlmRTqvUen4eK7/K1p6kryF7bnDfq6XsAbIsf2mo51B/utaH+XThY6dKgNCWzMAaH/+OLmqaBuLhLWRow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.13", "https://registry.npmmirror.com/@smithy/protocol-http/-/protocol-http-5.3.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/url-parser": ["@smithy/url-parser@4.2.13", "https://registry.npmmirror.com/@smithy/url-parser/-/url-parser-4.2.13.tgz", { "dependencies": { "@smithy/querystring-parser": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-2G03yoboIRZlZze2+PT4GZEjgwQsJjUgn6iTsvxA02bVceHR6vp4Cuk7TUnPFWKF+ffNUk3kj4COwkENS2K3vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.13", "https://registry.npmmirror.com/@smithy/util-middleware/-/util-middleware-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-GTooyrlmRTqvUen4eK7/K1p6kryF7bnDfq6XsAbIsf2mo51B/utaH+XThY6dKgNCWzMAaH/+OLmqaBuLhLWRow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.22", "https://registry.npmmirror.com/@smithy/util-stream/-/util-stream-4.5.22.tgz", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.16", "@smithy/node-http-handler": "^4.5.2", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-3H8iq/0BfQjUs2/4fbHZ9aG9yNzcuZs24LPkcX1Q7Z+qpqaGM8+qbGmE8zo9m2nCRgamyvS98cHdcWvR6YUsew=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/credential-provider-imds/@smithy/url-parser": ["@smithy/url-parser@4.2.13", "https://registry.npmmirror.com/@smithy/url-parser/-/url-parser-4.2.13.tgz", { "dependencies": { "@smithy/querystring-parser": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-2G03yoboIRZlZze2+PT4GZEjgwQsJjUgn6iTsvxA02bVceHR6vp4Cuk7TUnPFWKF+ffNUk3kj4COwkENS2K3vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - "@anthropic-ai/vertex-sdk/google-auth-library/gaxios/https-proxy-agent": ["https-proxy-agent@7.0.6", "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], "@anthropic-ai/vertex-sdk/google-auth-library/gaxios/is-stream": ["is-stream@2.0.1", "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], "@anthropic-ai/vertex-sdk/google-auth-library/gaxios/node-fetch": ["node-fetch@2.7.0", "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "@anthropic-ai/vertex-sdk/google-auth-library/gaxios/uuid": ["uuid@9.0.1", "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - "@anthropic-ai/vertex-sdk/google-auth-library/gcp-metadata/google-logging-utils": ["google-logging-utils@0.0.2", "https://registry.npmmirror.com/google-logging-utils/-/google-logging-utils-0.0.2.tgz", {}, "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ=="], "@anthropic/remote-control-server/vite/rollup/@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.1", "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", { "os": "android", "cpu": "arm" }, "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA=="], @@ -4068,8 +3684,6 @@ "@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - "@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - "@aws-sdk/middleware-websocket/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], "@aws-sdk/nested-clients/@aws-crypto/sha256-js/@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "https://registry.npmmirror.com/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], @@ -4126,122 +3740,8 @@ "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-crypto/sha256-js/@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "https://registry.npmmirror.com/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.29", "https://registry.npmmirror.com/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.29.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-OGOslTbOlxXexKMqhxCEbBQbUIfuhGxU5UXw3Fm56ypXHvrXH4aTt/xb5Y884LOoteP1QST1lVZzHfcTnWhiPQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.19", "https://registry.npmmirror.com/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/middleware-host-header": "^3.972.9", "@aws-sdk/middleware-logger": "^3.972.9", "@aws-sdk/middleware-recursion-detection": "^3.972.10", "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/region-config-resolver": "^3.972.11", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@aws-sdk/util-user-agent-browser": "^3.972.9", "@aws-sdk/util-user-agent-node": "^3.973.15", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/hash-node": "^4.2.13", "@smithy/invalid-dependency": "^4.2.13", "@smithy/middleware-content-length": "^4.2.13", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-retry": "^4.5.0", "@smithy/middleware-serde": "^4.2.17", "@smithy/middleware-stack": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/node-http-handler": "^4.5.2", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.45", "@smithy/util-defaults-mode-node": "^4.2.49", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.19", "https://registry.npmmirror.com/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/middleware-host-header": "^3.972.9", "@aws-sdk/middleware-logger": "^3.972.9", "@aws-sdk/middleware-recursion-detection": "^3.972.10", "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/region-config-resolver": "^3.972.11", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@aws-sdk/util-user-agent-browser": "^3.972.9", "@aws-sdk/util-user-agent-node": "^3.973.15", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/hash-node": "^4.2.13", "@smithy/invalid-dependency": "^4.2.13", "@smithy/middleware-content-length": "^4.2.13", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-retry": "^4.5.0", "@smithy/middleware-serde": "^4.2.17", "@smithy/middleware-stack": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/node-http-handler": "^4.5.2", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.45", "@smithy/util-defaults-mode-node": "^4.2.49", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1026.0", "https://registry.npmmirror.com/@aws-sdk/token-providers/-/token-providers-3.1026.0.tgz", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-Ieq/HiRrbEtrYP387Nes0XlR7H1pJiJOZKv+QyQzMYpvTiDs0VKy2ZB3E2Zf+aFovWmeE7lRE4lXyF7dYM6GgA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.19", "https://registry.npmmirror.com/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/middleware-host-header": "^3.972.9", "@aws-sdk/middleware-logger": "^3.972.9", "@aws-sdk/middleware-recursion-detection": "^3.972.10", "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/region-config-resolver": "^3.972.11", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@aws-sdk/util-user-agent-browser": "^3.972.9", "@aws-sdk/util-user-agent-node": "^3.973.15", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/hash-node": "^4.2.13", "@smithy/invalid-dependency": "^4.2.13", "@smithy/middleware-content-length": "^4.2.13", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-retry": "^4.5.0", "@smithy/middleware-serde": "^4.2.17", "@smithy/middleware-stack": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/node-http-handler": "^4.5.2", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.45", "@smithy/util-defaults-mode-node": "^4.2.49", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-builder/-/querystring-builder-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.13", "https://registry.npmmirror.com/@smithy/eventstream-codec/-/eventstream-codec-4.2.13.tgz", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-vYahwBAtRaAcFbOmE9aLr12z7RiHYDSLcnogSdxfm7kKfsNa3wH+NU5r7vTeB5rKvLsWyPjVX8iH94brP7umiQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.13", "https://registry.npmmirror.com/@smithy/eventstream-codec/-/eventstream-codec-4.2.13.tgz", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-vYahwBAtRaAcFbOmE9aLr12z7RiHYDSLcnogSdxfm7kKfsNa3wH+NU5r7vTeB5rKvLsWyPjVX8iH94brP7umiQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-crypto/sha256-js/@aws-crypto/util": ["@aws-crypto/util@5.2.0", "https://registry.npmmirror.com/@aws-crypto/util/-/util-5.2.0.tgz", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.13", "https://registry.npmmirror.com/@smithy/service-error-classification/-/service-error-classification-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0" } }, "sha512-a0s8XZMfOC/qpqq7RCPvJlk93rWFrElH6O++8WJKz0FqnA4Y7fkNi/0mnGgSH1C4x6MFsuBA8VKu4zxFrMe5Vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-builder/-/querystring-builder-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.22", "https://registry.npmmirror.com/@smithy/util-stream/-/util-stream-4.5.22.tgz", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.16", "@smithy/node-http-handler": "^4.5.2", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-3H8iq/0BfQjUs2/4fbHZ9aG9yNzcuZs24LPkcX1Q7Z+qpqaGM8+qbGmE8zo9m2nCRgamyvS98cHdcWvR6YUsew=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-parser/-/querystring-parser-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-hqW3Q4P+CDzUyQ87GrboGMeD7XYNMOF+CuTwu936UQRB/zeYn3jys8C3w+wMkDfY7CyyyVwZQ5cNFoG0x1pYmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.13", "https://registry.npmmirror.com/@smithy/service-error-classification/-/service-error-classification-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0" } }, "sha512-a0s8XZMfOC/qpqq7RCPvJlk93rWFrElH6O++8WJKz0FqnA4Y7fkNi/0mnGgSH1C4x6MFsuBA8VKu4zxFrMe5Vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.29", "https://registry.npmmirror.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.29.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-serde": "^4.2.17", "@smithy/node-config-provider": "^4.3.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-middleware": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-R9Q/58U+qBiSARGWbAbFLczECg/RmysRksX6Q8BaQEpt75I7LI6WGDZnjuC9GXSGKljEbA7N118LhGaMbfrTXw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.13", "https://registry.npmmirror.com/@smithy/middleware-stack/-/middleware-stack-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-g72jN/sGDLyTanrCLH9fhg3oysO3f7tQa6eWWsMyn2BiYNCgjF24n4/I9wff/5XidFvjj9ilipAoQrurTUrLvw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.22", "https://registry.npmmirror.com/@smithy/util-stream/-/util-stream-4.5.22.tgz", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.16", "@smithy/node-http-handler": "^4.5.2", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-3H8iq/0BfQjUs2/4fbHZ9aG9yNzcuZs24LPkcX1Q7Z+qpqaGM8+qbGmE8zo9m2nCRgamyvS98cHdcWvR6YUsew=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-builder/-/querystring-builder-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.29", "https://registry.npmmirror.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.29.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/middleware-serde": "^4.2.17", "@smithy/node-config-provider": "^4.3.13", "@smithy/shared-ini-file-loader": "^4.4.8", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-middleware": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-R9Q/58U+qBiSARGWbAbFLczECg/RmysRksX6Q8BaQEpt75I7LI6WGDZnjuC9GXSGKljEbA7N118LhGaMbfrTXw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.13", "https://registry.npmmirror.com/@smithy/middleware-stack/-/middleware-stack-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-g72jN/sGDLyTanrCLH9fhg3oysO3f7tQa6eWWsMyn2BiYNCgjF24n4/I9wff/5XidFvjj9ilipAoQrurTUrLvw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@4.3.2", "https://registry.npmmirror.com/@smithy/util-base64/-/util-base64-4.3.2.tgz", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-crypto/sha256-js/@aws-crypto/util": ["@aws-crypto/util@5.2.0", "https://registry.npmmirror.com/@aws-crypto/util/-/util-5.2.0.tgz", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.13", "https://registry.npmmirror.com/@smithy/service-error-classification/-/service-error-classification-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0" } }, "sha512-a0s8XZMfOC/qpqq7RCPvJlk93rWFrElH6O++8WJKz0FqnA4Y7fkNi/0mnGgSH1C4x6MFsuBA8VKu4zxFrMe5Vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-builder/-/querystring-builder-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.22", "https://registry.npmmirror.com/@smithy/util-stream/-/util-stream-4.5.22.tgz", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.16", "@smithy/node-http-handler": "^4.5.2", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-3H8iq/0BfQjUs2/4fbHZ9aG9yNzcuZs24LPkcX1Q7Z+qpqaGM8+qbGmE8zo9m2nCRgamyvS98cHdcWvR6YUsew=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-parser/-/querystring-parser-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-hqW3Q4P+CDzUyQ87GrboGMeD7XYNMOF+CuTwu936UQRB/zeYn3jys8C3w+wMkDfY7CyyyVwZQ5cNFoG0x1pYmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.13", "https://registry.npmmirror.com/@smithy/service-error-classification/-/service-error-classification-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0" } }, "sha512-a0s8XZMfOC/qpqq7RCPvJlk93rWFrElH6O++8WJKz0FqnA4Y7fkNi/0mnGgSH1C4x6MFsuBA8VKu4zxFrMe5Vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-parser/-/querystring-parser-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-hqW3Q4P+CDzUyQ87GrboGMeD7XYNMOF+CuTwu936UQRB/zeYn3jys8C3w+wMkDfY7CyyyVwZQ5cNFoG0x1pYmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.2", "https://registry.npmmirror.com/@smithy/node-http-handler/-/node-http-handler-4.5.2.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/querystring-builder": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-/oD7u8M0oj2ZTFw7GkuuHWpIxtWdLlnyNkbrWcyVYhd5RJNDuczdkb0wfnQICyNFrVPlr8YHOhamjNy3zidhmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/credential-provider-imds/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-parser/-/querystring-parser-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-hqW3Q4P+CDzUyQ87GrboGMeD7XYNMOF+CuTwu936UQRB/zeYn3jys8C3w+wMkDfY7CyyyVwZQ5cNFoG0x1pYmA=="], - "@anthropic-ai/vertex-sdk/google-auth-library/gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.4", "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - "@grpc/proto-loader/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "@grpc/proto-loader/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], @@ -4261,83 +3761,5 @@ "qrcode/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "qrcode/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-crypto/sha256-js/@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "https://registry.npmmirror.com/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.17", "https://registry.npmmirror.com/@smithy/middleware-serde/-/middleware-serde-4.2.17.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-0T2mcaM6v9W1xku86Dk0bEW7aEseG6KenFkPK98XNw0ZhOqOiD1MrMsdnQw9QsL3/Oa85T53iSMlm0SZdSuIEQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.13", "https://registry.npmmirror.com/@smithy/url-parser/-/url-parser-4.2.13.tgz", { "dependencies": { "@smithy/querystring-parser": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-2G03yoboIRZlZze2+PT4GZEjgwQsJjUgn6iTsvxA02bVceHR6vp4Cuk7TUnPFWKF+ffNUk3kj4COwkENS2K3vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.2", "https://registry.npmmirror.com/@smithy/node-http-handler/-/node-http-handler-4.5.2.tgz", { "dependencies": { "@smithy/protocol-http": "^5.3.13", "@smithy/querystring-builder": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-/oD7u8M0oj2ZTFw7GkuuHWpIxtWdLlnyNkbrWcyVYhd5RJNDuczdkb0wfnQICyNFrVPlr8YHOhamjNy3zidhmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.17", "https://registry.npmmirror.com/@smithy/middleware-serde/-/middleware-serde-4.2.17.tgz", { "dependencies": { "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-0T2mcaM6v9W1xku86Dk0bEW7aEseG6KenFkPK98XNw0ZhOqOiD1MrMsdnQw9QsL3/Oa85T53iSMlm0SZdSuIEQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.8", "https://registry.npmmirror.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.8.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.13", "https://registry.npmmirror.com/@smithy/url-parser/-/url-parser-4.2.13.tgz", { "dependencies": { "@smithy/querystring-parser": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-2G03yoboIRZlZze2+PT4GZEjgwQsJjUgn6iTsvxA02bVceHR6vp4Cuk7TUnPFWKF+ffNUk3kj4COwkENS2K3vw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/util-middleware": ["@smithy/util-middleware@4.2.13", "https://registry.npmmirror.com/@smithy/util-middleware/-/util-middleware-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-GTooyrlmRTqvUen4eK7/K1p6kryF7bnDfq6XsAbIsf2mo51B/utaH+XThY6dKgNCWzMAaH/+OLmqaBuLhLWRow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-crypto/sha256-js/@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "https://registry.npmmirror.com/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "https://registry.npmmirror.com/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "https://registry.npmmirror.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-builder/-/querystring-builder-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-parser/-/querystring-parser-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-hqW3Q4P+CDzUyQ87GrboGMeD7XYNMOF+CuTwu936UQRB/zeYn3jys8C3w+wMkDfY7CyyyVwZQ5cNFoG0x1pYmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-builder/-/querystring-builder-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.13", "https://registry.npmmirror.com/@smithy/querystring-parser/-/querystring-parser-4.2.13.tgz", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-hqW3Q4P+CDzUyQ87GrboGMeD7XYNMOF+CuTwu936UQRB/zeYn3jys8C3w+wMkDfY7CyyyVwZQ5cNFoG0x1pYmA=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "https://registry.npmmirror.com/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@anthropic-ai/bedrock-sdk/@aws-sdk/credential-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "https://registry.npmmirror.com/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], } } diff --git a/codex-slash-bug-trace.md b/codex-slash-bug-trace.md new file mode 100644 index 000000000..f095aa9c4 --- /dev/null +++ b/codex-slash-bug-trace.md @@ -0,0 +1,15 @@ +| Hypothesis | Verdict | Evidence | +| --- | --- | --- | +| CSP/nonce blocks webview script | Rejected | `packages/vscode-extension/src/ChatViewProvider.ts:48-52` enables scripts and allows `dist`; `:603-617` creates a nonce and uses the same nonce on `dist/webview.js`. `packages/vscode-extension/dist/webview.js` exists. Seeing "No matching command" also means React mounted. | +| `acquireVsCodeApi` singleton throws | Rejected | `webview/hooks/useVSCodeAPI.ts:10-14` calls it once at module scope; `rg` shows only `useACP.ts:36,260` imports/uses the hook. | +| `isFromExtension` rejects valid messages | Rejected | `webview/lib/protocol.ts:86-92` accepts any object whose string `type` starts with `ext:`; it is not strict-equal to one literal. | +| Wrong prop name into PromptInput | Rejected | `App.tsx:113-119` passes `availableCommands`; `PromptInput.tsx:30-36` destructures it; `:299-303` passes it as `commands` to `CommandMenu`. | +| CommandMenu keydown masks empty list | Rejected | `CommandMenu.tsx:41-61` listens only to `keydown` and only when visible plus non-empty filtered results; it cannot block `window.message`. | +| `makeClient()` returns stale clients | Rejected | `ACPClient.ts:184` creates one `ClientSideConnection`; SDK `acp.js:467-538` calls `toClient(this)` once and stores that `client`. | +| `ndJsonStream` direction flipped | Rejected | SDK `stream.d.ts:20-24` wants writable output then readable input. `ACPClient.ts:180-182` passes child stdin writable, then child stdout readable. Names are confusing; order is correct. | + +Final root cause: the real break is a readiness race where extension-host messages can be dropped because the webview HTML is assigned before the host receive listener is registered, and extension-to-webview sends are fire-and-forget with no ready queue. + +Evidence: `ChatViewProvider.ts:46-55` sets `webview.html` before `onDidReceiveMessage`; the webview posts `ext:webview_ready` immediately after adding its own listener in `useACP.ts:279-299`. Command replay only starts if that ready message reaches `handleWebviewMessage` (`ChatViewProvider.ts:170-207`, `:585-599`). Meanwhile direct command pushes are one-shot (`:489-498`) and `postToWebview` ignores the returned thenable/ready state (`:576-577`). If `ext:webview_ready` or the one-shot `available_commands_update` lands during that gap, the reducer never sees commands, leaving `CommandMenu` with `commands.length === 0` (`CommandMenu.tsx:22-26`, `:70-80`). + +Minimal patch suggestion: register `webview.onDidReceiveMessage` before assigning `webview.html`, add `private webviewReady = false`, set it true on `ext:webview_ready`, and make `postToWebview` queue `ext:available_commands`/state replay messages until ready, flushing on ready. Also await/log `webview.postMessage(...)` false results. diff --git a/docs/features/vscode-extension-installation.md b/docs/features/vscode-extension-installation.md new file mode 100644 index 000000000..7f6017aad --- /dev/null +++ b/docs/features/vscode-extension-installation.md @@ -0,0 +1,171 @@ +# VS Code 插件安装指南 + +本文面向需要安装 `CCB - Claude Code Best` VS Code 插件的用户。 + +插件本身是 VS Code 侧边栏 UI;实际 agent 由本机的 CCB/Claude Code Best CLI 进程提供。安装插件前,建议先确认 CLI 可以在当前机器运行。 + +## 安装前准备 + +1. 安装 VS Code `1.85.0` 或更高版本。 +2. 安装并构建本项目 CLI,或准备一个可执行的 CCB CLI 路径。 +3. 在终端中确认 CLI 可运行: + +```powershell +ccb --version +``` + +如果系统没有 `ccb` 命令,也可以在插件设置里手动配置 `ccb.cliPath` 指向 CLI 可执行文件。 + +## 方式一:安装 VSIX 包 + +如果你拿到的是发布者提供的 `.vsix` 文件,这是推荐给普通用户的安装方式。 + +### VS Code 界面安装 + +1. 打开 VS Code。 +2. 打开 Extensions 视图。 +3. 点击右上角 `...`。 +4. 选择 `Install from VSIX...`。 +5. 选择发布者提供的 `.vsix` 文件。 +6. 完全退出 VS Code 后重新打开。 + +### 命令行安装 + +Windows PowerShell: + +```powershell +code --install-extension .\ccb-vscode-0.3.0.vsix --force +``` + +macOS/Linux: + +```bash +code --install-extension ./ccb-vscode-0.3.0.vsix --force +``` + +安装后重新打开 VS Code,左侧 Activity Bar 应出现 `CCB` 图标。 + +## 方式二:从源码安装到本机 VS Code + +这是开发者或内测用户使用的方式。它会把 `packages/vscode-extension` 链接到本机 VS Code 扩展目录。 + +在仓库根目录先构建 CLI: + +```powershell +bun run build +``` + +然后构建并安装 VS Code 插件。 + +Windows: + +```powershell +cd packages\vscode-extension +bun run install-local:win +``` + +macOS/Linux: + +```bash +cd packages/vscode-extension +bun run install-local +``` + +安装完成后必须完全退出 VS Code,再重新打开。只执行 `Reload Window` 不一定能更新扩展宿主进程中的旧代码。 + +## 配置 CLI 路径 + +插件默认使用: + +```text +ccb.cliPath = auto +``` + +`auto` 会按以下优先级探测 CLI: + +1. 当前仓库构建产物。 +2. 开发入口。 +3. `PATH` 中的 `ccb` / `claude-code-best` 命令。 + +如果自动探测失败,在 VS Code 设置中搜索 `CCB: Cli Path`,填入明确路径。 + +示例: + +```json +{ + "ccb.cliPath": "E:\\Source_code\\Claude-code-bast-vscode-extension\\dist\\cli-node.js" +} +``` + +## 基础验证 + +安装后按以下步骤确认插件可用: + +1. 打开一个项目文件夹。 +2. 点击左侧 `CCB` 图标。 +3. 输入 `/help`,确认能返回斜杠菜单说明。 +4. 输入 `/login`,确认能看到登录 provider 选项。 +5. 输入 `/mcp`,确认能列出 MCP servers。 +6. 如果需要 Chrome MCP,输入: + +```text +/mcp tools claude-in-chrome +``` + +正常情况下应能看到 `tabs_context_mcp` 等 Chrome MCP 工具。 + +## 发布包不包含源码 + +发布 VSIX 时使用 `packages/vscode-extension/.vscodeignore` 控制包内容。 + +当前发布包只包含: + +```text +package.json +resources/icon.svg +dist/webview.js +dist/extension.js +``` + +不会包含: + +```text +src/ +webview/ +scripts/ +node_modules/ +tsconfig.json +esbuild.config.mjs +*.map +``` + +发布前可在 `packages/vscode-extension` 下运行: + +```powershell +npx @vscode/vsce ls --no-dependencies +``` + +确认 VSIX 内容仍然只有 manifest、资源和编译产物。 + +## 卸载 + +VS Code 界面卸载: + +1. 打开 Extensions。 +2. 搜索 `CCB - Claude Code Best`。 +3. 点击 Uninstall。 +4. 重启 VS Code。 + +命令行卸载: + +```powershell +code --uninstall-extension claude-code-best.ccb-vscode +``` + +如果使用源码本地安装脚本,Windows 下扩展目录通常是: + +```text +C:\Users\<用户名>\.vscode\extensions\claude-code-best.ccb-vscode-0.3.0 +``` + +删除该目录或 junction 后重启 VS Code 即可。 diff --git a/docs/features/vscode-extension.md b/docs/features/vscode-extension.md new file mode 100644 index 000000000..5c6637392 --- /dev/null +++ b/docs/features/vscode-extension.md @@ -0,0 +1,164 @@ +# VS Code Extension — 完整 ACP 集成 + +## 概述 + +VSCode 扩展通过 **ACP (Agent Client Protocol)** 协议直接驱动 Claude Code CLI。 +扩展启动 `claude --acp` 子进程,使用 `@agentclientprotocol/sdk` 的 `ClientSideConnection` ++ `ndJsonStream` 包裹 stdin/stdout,实现完整的双向通信。 + +**完全不修改 `src/commands/`** — 所有能力(模型切换、模式切换、斜杠命令、权限审批、 +plan 可视化、tool call 流式更新)都通过 ACP 协议方法暴露。 + +用户安装步骤见 [VS Code 插件安装指南](./vscode-extension-installation.md)。 + +## 架构 + +``` +┌─────────────────────────────────┐ +│ VS Code Extension │ +│ │ +│ ┌───────────┐ ┌────────────┐ │ +│ │ WebView │ │ Extension │ │ +│ │ (React 19)│◄─┤ Host │ │ +│ │ │ │ │ │ +│ │ ChatView │ │ ACPClient │ │ +│ │ Plan/Tool │ │ Editor │ │ +│ │ Permission│ │ Bridge │ │ +│ │ ModeSel │ │ History │ │ +│ └─────┬─────┘ └─────┬──────┘ │ +│ │ postMessage │ │ +│ └──────┬───────┘ │ +└───────────────┼─────────────────┘ + │ ndjson stdio (ACP) + ┌───────▼─────────┐ + │ claude --acp │ + │ (AcpAgent) │ + └─────────────────┘ +``` + +## 协议层 + +- 扩展 ↔ 子进程:JSON-RPC over stdio (ACP, `@agentclientprotocol/sdk@^0.19`) +- WebView ↔ 扩展:`vscode.postMessage` 桥协议(命名空间 `ext:*`,定义在 + `webview/lib/protocol.ts`,与 RCS Web 同构) + +### ACP method 接入 + +| Method | 触发 | +|---|---| +| `initialize` | 扩展启动后立即调用,携带 `clientCapabilities.fs.{readTextFile,writeTextFile}` | +| `newSession` | 每次 New Chat / 启动;`{cwd, mcpServers, _meta:{permissionMode}}` | +| `prompt` | 用户提交(含图片粘贴的 `image` content blocks) | +| `cancel` | Esc / Cancel 按钮 | +| `unstable_setSessionModel` | StatusBar ModelPicker | +| `setSessionMode` | ModeSelector / Shift+Tab | +| `loadSession` / `unstable_resumeSession` | 历史会话恢复 | +| `listSessions` | "Open Session History" 命令 | + +### Client 回调(agent 调到我们) + +| Method | 实现 | +|---|---| +| `requestPermission` | 转发到 webview 的 PermissionPanel,等待 `permission_response` | +| `sessionUpdate` | 直接转发到 webview 的 threadReducer | +| `readTextFile` | `vscode.workspace.fs.readFile`(优先用打开文档的快照) | +| `writeTextFile` | `vscode.workspace.fs.writeFile`(进入 VSCode undo stack) | + +## 模块清单 + +### Extension 端(Node.js) +| 文件 | 职责 | +|---|---| +| `src/extension.ts` | VSCode 入口;注册命令与快捷键 | +| `src/ChatViewProvider.ts` | webview 生命周期 + 桥协议路由 | +| `src/ACPClient.ts` | 包装 `@agentclientprotocol/sdk` ClientSideConnection | +| `src/agentSpawner.ts` | 解析 CLI 路径(dist 优先 → scripts/dev.ts → claude on PATH) | +| `src/EditorBridge.ts` | VSCode 集成(FS 读写、diff view、@-mention 搜索、诊断) | +| `src/HistoryManager.ts` | sessionId + prompt 历史持久化 | +| `src/StatusBarManager.ts` | VSCode 状态栏(模型 + 模式 + tokens) | + +### WebView 端(React) +| 文件 | 职责 | +|---|---| +| `webview/index.tsx` | React 入口 | +| `webview/App.tsx` | 根组件 | +| `webview/lib/acp/types.ts` | ACP 协议类型 | +| `webview/lib/protocol.ts` | webview ↔ extension 桥协议 | +| `webview/lib/types.ts` | UI thread/entry 类型 | +| `webview/lib/threadReducer.ts` | `SessionUpdate` → ThreadEntry 状态机 | +| `webview/hooks/useACP.ts` | 完整状态机 + protocol 客户端 | +| `webview/components/ChatView.tsx` | 消息流 | +| `webview/components/MessageBubble.tsx` | 用户/助手消息 + thinking | +| `webview/components/ToolCallCard.tsx` | tool call (含 diff 预览) | +| `webview/components/PlanView.tsx` | Plan 可视化 | +| `webview/components/PermissionPanel.tsx` | 权限审批面板 | +| `webview/components/CommandMenu.tsx` | 斜杠命令菜单 (动态从 ACP 拿 commands) | +| `webview/components/ModelPicker.tsx` | 模型切换 | +| `webview/components/ModeSelector.tsx` | 模式切换 | +| `webview/components/StatusBar.tsx` | webview 内状态栏 | +| `webview/components/PromptInput.tsx` | 输入 + 图片粘贴 + @ 触发 + 快捷键 | + +## 完整快捷键体系 + +### VSCode 全局(`package.json` contributes.keybindings) +- `Ctrl+Esc` (Mac: `Cmd+Esc`) — 聚焦聊天 +- `Esc` (聊天聚焦) — 取消/中断 +- `Ctrl+Shift+N` — 新对话 +- `Ctrl+Shift+M` — 循环权限模式 +- `Ctrl+L` — 清空屏幕 +- `Ctrl+R` — 搜索 prompt 历史 +- `Ctrl+T` — 切换 thinking 显示 +- `Ctrl+Shift+L` (编辑器有选区) — 发送选中代码 + +### WebView 内部(`PromptInput`) +- `Enter` — 发送 +- `Shift+Enter` — 换行 +- `Esc` — 取消运行中任务 +- `Shift+Tab` — **循环权限模式(default → acceptEdits → plan → bypass)** +- `Tab` — 接受当前补全 +- `↑` / `↓` — 在历史 prompts 间导航(首/末行时) +- `/` — 触发斜杠命令菜单 +- `@` — 触发文件搜索 +- `Ctrl+V` 含图片 — 自动作为 image content block 入队 + +## 多模态支持 + +- 直接粘贴图片 → 自动 base64 编码 → 作为 `ImageContent` 加入下一条 prompt +- 缩略图预览 + 删除按钮 +- `promptCapabilities.image` 来自 `initialize` 响应(claude-code 默认支持) + +## 启动命令 + +```bash +# 1) 构建 dist(可选,agentSpawner 会优先用它) +bun run build + +# 2) 构建扩展(必需) +cd packages/vscode-extension +bun run build + +# 3) 安装到 VSCode(创建符号链接到 ~/.vscode/extensions/) +# Windows +bun run install-local:win +# Linux/macOS +bun run install-local + +# 4) 重启 VSCode → 侧边栏 "CCB" 出现 +``` + +## 配置 + +| key | 默认 | 说明 | +|---|---|---| +| `ccb.cliPath` | `auto` | CLI 路径;`auto` 自动探测(dist 优先 → scripts/dev.ts → PATH) | +| `ccb.permissionMode` | `default` | 启动时默认权限模式 | +| `ccb.autoScroll` | `true` | 新消息自动滚动 | +| `ccb.showThinking` | `true` | 是否显示 extended thinking | +| `ccb.resumeLastSession` | `true` | 启动时恢复上次会话 | +| `ccb.enableFsCapabilities` | `true` | 允许 agent 通过 VSCode 读写文件(进入 undo stack) | + +## 旧 stream-json 实现 + +之前的 stream-json 实现(仅覆盖 7/32 个 control_request、缺少 plan 可视化、缺少 +图片支持、缺少 permission JSON-RPC 配对)已**完全废弃**。新 ACP 实现解决了所有 +P0 缺口(参见 `docs/plans/vscode-ext-gap-analysis.md`)。 diff --git a/docs/internals/repo-audit-findings-2026-04-24-zh.md b/docs/internals/repo-audit-findings-2026-04-24-zh.md new file mode 100644 index 000000000..dba324c0c --- /dev/null +++ b/docs/internals/repo-audit-findings-2026-04-24-zh.md @@ -0,0 +1,233 @@ +# 仓库审计发现 + +日期: 2026-04-24 +范围: 针对当前仓库状态验证三项已报告的问题 +工作区: `E:\Source_code\Claude-code-bast` + +## 摘要 + +本次审计检查了三项已报告的问题: + +1. `yoga-layout` 重复实现 +2. `src/` 下 `105` 个目录中存在 `621` 个死类型 stub 文件 +3. `CLAUDE.md` 包含六处不准确陈述 + +当前结论: + +- `yoga-layout` 重复实现:**已确认** +- `621 个死类型 stub 文件分布在 105 个目录`:**部分确认** +- `CLAUDE.md` 包含六处不准确陈述:**已确认** + +主要偏差在第二项。仓库确实在 `src/` 下包含 `621` 个自动生成的类型 stub 文件,但 `105` 个目录的数量无法复现,且"死文件"一词过于强硬——至少部分 stub 正被活跃代码导入使用。 + +## 发现 1: `yoga-layout` 重复实现 + +状态: 已确认,但原始报告中声称的 diff 大小不准确 + +存在两份近乎相同的 TypeScript Yoga 移植: + +- `src/native-ts/yoga-layout/index.ts` +- `packages/@ant/ink/src/core/yoga-layout/index.ts` + +支撑证据: + +- [src/native-ts/yoga-layout/index.ts#L2](/E:/Source_code/Claude-code-bast/src/native-ts/yoga-layout/index.ts#L2) +- [packages/@ant/ink/src/core/yoga-layout/index.ts#L2](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/yoga-layout/index.ts#L2) +- [src/native-ts/yoga-layout/index.ts#L1045](/E:/Source_code/Claude-code-bast/src/native-ts/yoga-layout/index.ts#L1045) +- [packages/@ant/ink/src/core/yoga-layout/index.ts#L1044](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/yoga-layout/index.ts#L1044) + +运行时实际使用的是 `packages/@ant/ink` 下的副本: + +- [packages/@ant/ink/src/core/layout/yoga.ts#L14](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/layout/yoga.ts#L14) +- [packages/@ant/ink/src/core/reconciler.ts#L4](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/reconciler.ts#L4) +- [packages/@ant/ink/src/core/ink.tsx#L15](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/ink.tsx#L15) + +直接对比的文件统计: + +- `src/native-ts/yoga-layout/index.ts`: `2581` 行 +- `packages/@ant/ink/src/core/yoga-layout/index.ts`: `2578` 行 +- `git diff --no-index` 显示当前工作区中仅 `3` 行被删除的注释差异 +- 两处的 `enums.ts` 逐行完全一致,均为 `134` 行 + +解读: + +- 重复风险确实存在 +- 漂移风险确实存在,因为有两份需要分别维护的副本 +- 先前声称的"仅 6 行差异"与当前仓库状态不符;当前可见差异为 `index.ts` 中的 `3` 行 + +## 发现 2: `src/` 下 `105` 个目录中存在 `621` 个死类型 stub 文件 + +状态: 部分确认 + +可复现的内容: + +- `src/` 下确实有 `621` 个文件包含标记 `Auto-generated type stub — replace with real implementation` +- 这些文件分布在 `src/` 下的 `344` 个唯一叶目录中,而非 `105` 个 + +计数证据: + +- `SRC_STUB_FILES=621` +- `SRC_STUB_DIRS=344` + +代表性示例: + +- [src/services/lsp/types.ts#L1](/E:/Source_code/Claude-code-bast/src/services/lsp/types.ts#L1) +- [src/utils/src/types/message.ts#L1](/E:/Source_code/Claude-code-bast/src/utils/src/types/message.ts#L1) +- [src/types/src/utils/permissions/PermissionRule.ts#L1](/E:/Source_code/Claude-code-bast/src/types/src/utils/permissions/PermissionRule.ts#L1) + +为什么"死文件"标签证据不充分: + +至少部分 stub 正被活跃代码导入。示例: + +- [src/services/lsp/types.ts#L1](/E:/Source_code/Claude-code-bast/src/services/lsp/types.ts#L1) 导出了 `any` 类型的别名 +- [src/types/plugin.ts#L1](/E:/Source_code/Claude-code-bast/src/types/plugin.ts#L1) 导入了 `LspServerConfig` +- [src/utils/plugins/lspPluginIntegration.ts#L7](/E:/Source_code/Claude-code-bast/src/utils/plugins/lspPluginIntegration.ts#L7) 导入了同一批 stub 类型 + +已确认的风险: + +- 这些文件确实污染了类型表面 +- 其中大量文件将类型坍缩为 `any` +- 这确实会掩盖真正的类型错误并削弱 IDE 反馈 + +未确认的内容: + +- 全部 `621` 个文件是否都是死代码或不可达的 +- 当前的目录分布是否为 `105` + +为准确性推荐的措辞: + +- 推荐: `src 下的 621 个自动生成的类型 stub 文件削弱了类型安全性和 IDE 反馈` +- 避免: `105 个目录中存在 621 个死类型 stub 文件` + +## 发现 3: `CLAUDE.md` 包含六处不准确陈述 + +状态: 已确认 + +### 3.1 `modifiers-napi` 被错误标记为 stub + +不准确的文档: + +- [CLAUDE.md#L174](/E:/Source_code/Claude-code-bast/CLAUDE.md#L174) +- [CLAUDE.md#L257](/E:/Source_code/Claude-code-bast/CLAUDE.md#L257) + +当前实现证据: + +- [packages/modifiers-napi/src/index.ts#L44](/E:/Source_code/Claude-code-bast/packages/modifiers-napi/src/index.ts#L44) — `prewarm()` 通过 `bun:ffi` 加载 macOS Carbon 框架 +- [packages/modifiers-napi/src/index.ts#L48](/E:/Source_code/Claude-code-bast/packages/modifiers-napi/src/index.ts#L48) — `isModifierPressed()` 查询键盘修饰键状态 +- [packages/modifiers-napi/src/__tests__/index.test.ts#L1](/E:/Source_code/Claude-code-bast/packages/modifiers-napi/src/__tests__/index.test.ts#L1) — 有配套测试 + +结论: + +- 已完整实现,通过 FFI 调用 macOS 系统 API +- 不是占位包 + +### 3.2 `url-handler-napi` 被错误标记为 stub + +不准确的文档: + +- [CLAUDE.md#L175](/E:/Source_code/Claude-code-bast/CLAUDE.md#L175) +- [CLAUDE.md#L257](/E:/Source_code/Claude-code-bast/CLAUDE.md#L257) + +当前实现证据: + +- [packages/url-handler-napi/src/index.ts#L12](/E:/Source_code/Claude-code-bast/packages/url-handler-napi/src/index.ts#L12) — `waitForUrlEvent()` 从环境变量/CLI 参数读取 deep link URL +- [packages/url-handler-napi/src/index.ts#L21](/E:/Source_code/Claude-code-bast/packages/url-handler-napi/src/index.ts#L21) — `findUrlEvent()` 按优先级检查三个环境变量 + CLI 参数 +- [packages/url-handler-napi/src/__tests__/index.test.ts#L1](/E:/Source_code/Claude-code-bast/packages/url-handler-napi/src/__tests__/index.test.ts#L1) — 有配套测试 + +结论: + +- 已完整实现(49 行功能代码) +- 不是 stub 包 + +### 3.3 Magic Docs 被错误标记为已移除 + +不准确的文档: + +- [CLAUDE.md#L262](/E:/Source_code/Claude-code-bast/CLAUDE.md#L262) + +当前实现证据: + +- [src/utils/backgroundHousekeeping.ts#L3](/E:/Source_code/Claude-code-bast/src/utils/backgroundHousekeeping.ts#L3) — 静态 import `initMagicDocs` +- [src/utils/backgroundHousekeeping.ts#L32](/E:/Source_code/Claude-code-bast/src/utils/backgroundHousekeeping.ts#L32) — 在后台管理中调用 `void initMagicDocs()` +- [src/commands/clear/caches.ts#L125](/E:/Source_code/Claude-code-bast/src/commands/clear/caches.ts#L125) — 缓存清理流程中引用 +- [src/services/MagicDocs/magicDocs.ts#L44](/E:/Source_code/Claude-code-bast/src/services/MagicDocs/magicDocs.ts#L44) — 完整实现文件 +- [src/services/MagicDocs/magicDocs.ts#L242](/E:/Source_code/Claude-code-bast/src/services/MagicDocs/magicDocs.ts#L242) — 包含数据处理逻辑 + +结论: + +- Magic Docs 仍然存在,且接入了后台管理和缓存清理流程 + +### 3.4 LSP Server 被错误标记为已移除 + +不准确的文档: + +- [CLAUDE.md#L262](/E:/Source_code/Claude-code-bast/CLAUDE.md#L262) + +当前实现证据: + +- [src/main.tsx#L407](/E:/Source_code/Claude-code-bast/src/main.tsx#L407) — 顶部静态 import `initializeLspServerManager` +- [src/main.tsx#L3512-L3515](/E:/Source_code/Claude-code-bast/src/main.tsx#L3512) — 信任对话框通过后初始化 LSP 管理器 +- [src/services/lsp/manager.ts#L63](/E:/Source_code/Claude-code-bast/src/services/lsp/manager.ts#L63) — LSP 服务器管理器实现 +- [src/services/lsp/manager.ts#L100](/E:/Source_code/Claude-code-bast/src/services/lsp/manager.ts#L100) — 服务器实例管理 +- [src/services/lsp/manager.ts#L145](/E:/Source_code/Claude-code-bast/src/services/lsp/manager.ts#L145) — 生命周期管理 +- [packages/builtin-tools/src/tools/LSPTool/LSPTool.ts#L127](/E:/Source_code/Claude-code-bast/packages/builtin-tools/src/tools/LSPTool/LSPTool.ts#L127) — 内置 LSP 工具 + +结论: + +- LSP 基础设施仍然存在 +- 仓库仍然初始化 LSP 管理器并暴露 LSP 工具 + +### 3.5 Plugins 被错误标记为已移除 + +不准确的文档: + +- [CLAUDE.md#L263](/E:/Source_code/Claude-code-bast/CLAUDE.md#L263) + +当前实现证据: + +- [src/main.tsx#L6153](/E:/Source_code/Claude-code-bast/src/main.tsx#L6153) — Commander 注册 `plugin` 命令组 +- [src/main.tsx#L6261](/E:/Source_code/Claude-code-bast/src/main.tsx#L6261) — `plugin install` 子命令 +- [src/services/plugins/pluginOperations.ts#L72](/E:/Source_code/Claude-code-bast/src/services/plugins/pluginOperations.ts#L72) — 插件操作实现 +- [src/commands/plugin/ManagePlugins.tsx](/E:/Source_code/Claude-code-bast/src/commands/plugin/ManagePlugins.tsx) — 插件管理 UI 组件 +- [src/utils/plugins/pluginLoader.ts](/E:/Source_code/Claude-code-bast/src/utils/plugins/pluginLoader.ts) — 插件加载器 + +结论: + +- 插件管理系统仍然完整实现 + +### 3.6 Marketplace 被错误标记为已移除 + +不准确的文档: + +- [CLAUDE.md#L263](/E:/Source_code/Claude-code-bast/CLAUDE.md#L263) + +当前实现证据: + +- [src/main.tsx#L6191-L6255](/E:/Source_code/Claude-code-bast/src/main.tsx#L6191) — Commander 注册 `plugin marketplace` 子命令,包含 `add`、`list`、`remove`、`update` 四个操作 +- [src/main.tsx#L6264](/E:/Source_code/Claude-code-bast/src/main.tsx#L6264) — `plugin install` 引用 marketplace 作为插件来源 +- [src/commands/plugin/BrowseMarketplace.tsx](/E:/Source_code/Claude-code-bast/src/commands/plugin/BrowseMarketplace.tsx) — UI 组件(通过 Commander action handler 中的动态 import 加载) +- [src/utils/plugins/marketplaceManager.ts](/E:/Source_code/Claude-code-bast/src/utils/plugins/marketplaceManager.ts) — Marketplace 数据管理 + +说明: Marketplace 通过 Commander 子命令 + action handler 中的动态 `await import(...)` 接入,而非 `main.tsx` 顶部的静态 import。 + +结论: + +- Marketplace 功能仍然存在,且完整注册在 CLI 命令树中 + +## 最终评估 + +当前仓库状态支持所有三项报告背后的广泛担忧,但具体措辞需要收紧: + +- Yoga 重复问题是真实的 +- 类型 stub 问题是真实的,但当前证据支持的是 `src 下 621 个 stub 文件`,而非 `105 个目录中 621 个死文件` +- 六处 `CLAUDE.md` 不准确之处是真实的,应当修正 + +## 建议的下一步行动 + +1. 更新 `CLAUDE.md`,修正六处过时陈述 +2. 确定哪个 Yoga 实现为权威版本,然后删除副本或替换为共享 import +3. 按类别审计 `621` 个 stub 文件: + - 被活跃导入的兼容性垫片 + - 待真正实现的生成占位符 + - 可删除的不可达重复路径 +4. 将类型 stub 数量视为类型安全债务指标,暂不作为死代码指标 diff --git a/docs/internals/repo-audit-findings-2026-04-24.md b/docs/internals/repo-audit-findings-2026-04-24.md new file mode 100644 index 000000000..5c95416b3 --- /dev/null +++ b/docs/internals/repo-audit-findings-2026-04-24.md @@ -0,0 +1,231 @@ +# Repository Audit Findings + +Date: 2026-04-24 +Scope: Validate three reported issues against the current repository state +Workspace: `E:\Source_code\Claude-code-bast` + +## Summary + +This audit checked three reported issues: + +1. `yoga-layout` duplicate implementation +2. `621` dead type stub files across `105` directories +3. `CLAUDE.md` containing six incorrect statements + +Current conclusion: + +- `yoga-layout` duplicate implementation: confirmed +- `621 dead type stub files across 105 directories`: partially confirmed +- `CLAUDE.md` has six incorrect statements: confirmed + +The main mismatch is in the second item. The repository currently does contain `621` auto-generated type stub files under `src/`, but the `105` directory count was not reproducible, and the term `dead files` is too strong for the current evidence because at least some of those stubs are actively imported. + +## Finding 1: `yoga-layout` duplicate implementation + +Status: Confirmed, but the reported diff size is inaccurate + +Two near-identical TypeScript Yoga ports exist: + +- `src/native-ts/yoga-layout/index.ts` +- `packages/@ant/ink/src/core/yoga-layout/index.ts` + +Supporting evidence: + +- [src/native-ts/yoga-layout/index.ts#L2](/E:/Source_code/Claude-code-bast/src/native-ts/yoga-layout/index.ts#L2) +- [packages/@ant/ink/src/core/yoga-layout/index.ts#L2](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/yoga-layout/index.ts#L2) +- [src/native-ts/yoga-layout/index.ts#L1045](/E:/Source_code/Claude-code-bast/src/native-ts/yoga-layout/index.ts#L1045) +- [packages/@ant/ink/src/core/yoga-layout/index.ts#L1044](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/yoga-layout/index.ts#L1044) + +The active runtime wiring points to the `packages/@ant/ink` copy: + +- [packages/@ant/ink/src/core/layout/yoga.ts#L14](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/layout/yoga.ts#L14) +- [packages/@ant/ink/src/core/reconciler.ts#L4](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/reconciler.ts#L4) +- [packages/@ant/ink/src/core/ink.tsx#L15](/E:/Source_code/Claude-code-bast/packages/@ant/ink/src/core/ink.tsx#L15) + +Observed file stats from direct comparison: + +- `src/native-ts/yoga-layout/index.ts`: `2581` lines +- `packages/@ant/ink/src/core/yoga-layout/index.ts`: `2578` lines +- `git diff --no-index` showed only `3` deleted comment lines in the current workspace +- `enums.ts` in both locations is line-for-line identical at `134` lines + +Interpretation: + +- The duplication risk is real +- Drift risk is real because there are two maintenance copies +- The specific claim `only 6 lines differ` does not match the current repository state; the current visible diff is `3` lines in `index.ts` + +## Finding 2: `621` dead type stub files across `105` directories + +Status: Partially confirmed + +What was reproducible: + +- There are `621` files under `src/` matching the marker `Auto-generated type stub — replace with real implementation` +- Those files are spread across `344` unique leaf directories under `src/`, not `105` + +Count evidence: + +- `SRC_STUB_FILES=621` +- `SRC_STUB_DIRS=344` + +Representative examples: + +- [src/services/lsp/types.ts#L1](/E:/Source_code/Claude-code-bast/src/services/lsp/types.ts#L1) +- [src/utils/src/types/message.ts#L1](/E:/Source_code/Claude-code-bast/src/utils/src/types/message.ts#L1) +- [src/types/src/utils/permissions/PermissionRule.ts#L1](/E:/Source_code/Claude-code-bast/src/types/src/utils/permissions/PermissionRule.ts#L1) + +Why the `dead files` label is not fully supported: + +At least some of these stubs are imported by live code. Example: + +- [src/services/lsp/types.ts#L1](/E:/Source_code/Claude-code-bast/src/services/lsp/types.ts#L1) exports `any`-typed aliases +- [src/types/plugin.ts#L1](/E:/Source_code/Claude-code-bast/src/types/plugin.ts#L1) imports `LspServerConfig` +- [src/utils/plugins/lspPluginIntegration.ts#L7](/E:/Source_code/Claude-code-bast/src/utils/plugins/lspPluginIntegration.ts#L7) imports the same stubbed types + +What is confirmed about the risk: + +- These files do pollute type surfaces +- Many of them collapse types to `any` +- That can absolutely mask genuine type errors and weaken IDE feedback + +What is not confirmed: + +- That all `621` files are dead or unreachable +- That the current directory spread is `105` + +Recommended wording for accuracy: + +- Prefer: `621 auto-generated type stub files under src weaken type safety and IDE feedback` +- Avoid: `621 dead type stub files across 105 directories` + +## Finding 3: `CLAUDE.md` contains six incorrect statements + +Status: Confirmed + +### 3.1 `modifiers-napi` incorrectly marked as stub + +Incorrect documentation: + +- [CLAUDE.md#L174](/E:/Source_code/Claude-code-bast/CLAUDE.md#L174) +- [CLAUDE.md#L257](/E:/Source_code/Claude-code-bast/CLAUDE.md#L257) + +Current implementation evidence: + +- [packages/modifiers-napi/src/index.ts#L44](/E:/Source_code/Claude-code-bast/packages/modifiers-napi/src/index.ts#L44) +- [packages/modifiers-napi/src/index.ts#L48](/E:/Source_code/Claude-code-bast/packages/modifiers-napi/src/index.ts#L48) +- [packages/modifiers-napi/src/__tests__/index.test.ts#L1](/E:/Source_code/Claude-code-bast/packages/modifiers-napi/src/__tests__/index.test.ts#L1) + +Conclusion: + +- It is implemented +- It is not just a placeholder package + +### 3.2 `url-handler-napi` incorrectly marked as stub + +Incorrect documentation: + +- [CLAUDE.md#L175](/E:/Source_code/Claude-code-bast/CLAUDE.md#L175) +- [CLAUDE.md#L257](/E:/Source_code/Claude-code-bast/CLAUDE.md#L257) + +Current implementation evidence: + +- [packages/url-handler-napi/src/index.ts#L12](/E:/Source_code/Claude-code-bast/packages/url-handler-napi/src/index.ts#L12) +- [packages/url-handler-napi/src/index.ts#L21](/E:/Source_code/Claude-code-bast/packages/url-handler-napi/src/index.ts#L21) +- [packages/url-handler-napi/src/__tests__/index.test.ts#L1](/E:/Source_code/Claude-code-bast/packages/url-handler-napi/src/__tests__/index.test.ts#L1) + +Conclusion: + +- It is implemented +- It is not just a stub package + +### 3.3 Magic Docs incorrectly marked as removed + +Incorrect documentation: + +- [CLAUDE.md#L262](/E:/Source_code/Claude-code-bast/CLAUDE.md#L262) + +Current implementation evidence: + +- [src/utils/backgroundHousekeeping.ts#L32](/E:/Source_code/Claude-code-bast/src/utils/backgroundHousekeeping.ts#L32) +- [src/commands/clear/caches.ts#L125](/E:/Source_code/Claude-code-bast/src/commands/clear/caches.ts#L125) +- [src/services/MagicDocs/magicDocs.ts#L44](/E:/Source_code/Claude-code-bast/src/services/MagicDocs/magicDocs.ts#L44) +- [src/services/MagicDocs/magicDocs.ts#L242](/E:/Source_code/Claude-code-bast/src/services/MagicDocs/magicDocs.ts#L242) + +Conclusion: + +- Magic Docs is still present and wired into background housekeeping and cache clearing + +### 3.4 LSP Server incorrectly marked as removed + +Incorrect documentation: + +- [CLAUDE.md#L262](/E:/Source_code/Claude-code-bast/CLAUDE.md#L262) + +Current implementation evidence: + +- [src/main.tsx#L3516](/E:/Source_code/Claude-code-bast/src/main.tsx#L3516) +- [src/services/lsp/manager.ts#L63](/E:/Source_code/Claude-code-bast/src/services/lsp/manager.ts#L63) +- [src/services/lsp/manager.ts#L100](/E:/Source_code/Claude-code-bast/src/services/lsp/manager.ts#L100) +- [src/services/lsp/manager.ts#L145](/E:/Source_code/Claude-code-bast/src/services/lsp/manager.ts#L145) +- [packages/builtin-tools/src/tools/LSPTool/LSPTool.ts#L127](/E:/Source_code/Claude-code-bast/packages/builtin-tools/src/tools/LSPTool/LSPTool.ts#L127) + +Conclusion: + +- LSP infrastructure still exists +- The repository still initializes the manager and exposes an LSP tool + +### 3.5 Plugins incorrectly marked as removed + +Incorrect documentation: + +- [CLAUDE.md#L263](/E:/Source_code/Claude-code-bast/CLAUDE.md#L263) + +Current implementation evidence: + +- [src/main.tsx#L6153](/E:/Source_code/Claude-code-bast/src/main.tsx#L6153) +- [src/main.tsx#L6261](/E:/Source_code/Claude-code-bast/src/main.tsx#L6261) +- [src/services/plugins/pluginOperations.ts#L72](/E:/Source_code/Claude-code-bast/src/services/plugins/pluginOperations.ts#L72) +- [src/commands/plugin/ManagePlugins.tsx](/E:/Source_code/Claude-code-bast/src/commands/plugin/ManagePlugins.tsx) +- [src/utils/plugins/pluginLoader.ts](/E:/Source_code/Claude-code-bast/src/utils/plugins/pluginLoader.ts) + +Conclusion: + +- Plugin management is still implemented + +### 3.6 Marketplace incorrectly marked as removed + +Incorrect documentation: + +- [CLAUDE.md#L263](/E:/Source_code/Claude-code-bast/CLAUDE.md#L263) + +Current implementation evidence: + +- [src/main.tsx#L6191-L6255](/E:/Source_code/Claude-code-bast/src/main.tsx#L6191) — Commander registers `plugin marketplace` subcommand with `add`, `list`, `remove`, `update` actions +- [src/main.tsx#L6264](/E:/Source_code/Claude-code-bast/src/main.tsx#L6264) — `plugin install` references marketplace as plugin source +- [src/commands/plugin/BrowseMarketplace.tsx](/E:/Source_code/Claude-code-bast/src/commands/plugin/BrowseMarketplace.tsx) — UI component (loaded via dynamic import from Commander action handlers) +- [src/utils/plugins/marketplaceManager.ts](/E:/Source_code/Claude-code-bast/src/utils/plugins/marketplaceManager.ts) — Marketplace data management + +Note: Marketplace is wired through Commander subcommands with dynamic `await import(...)` in action handlers, not through top-level static imports in `main.tsx`. + +Conclusion: + +- Marketplace functionality is still present and fully registered in the CLI command tree + +## Final Assessment + +The current repository supports the broad concern behind all three reports, but the exact wording needs tightening: + +- The Yoga duplication issue is real +- The type stub issue is real, but the current evidence supports `621 stub files under src`, not `621 dead files across 105 directories` +- The six `CLAUDE.md` inaccuracies are real and should be corrected + +## Suggested Next Actions + +1. Update `CLAUDE.md` to remove the six stale statements +2. Decide which Yoga implementation is canonical, then either delete the duplicate or replace it with a shared import +3. Audit the `621` stub files by category: + - actively imported compatibility shim + - generated placeholder pending real implementation + - unreachable duplicate path that can be deleted +4. Treat the type stub count as a type-safety debt metric, not yet as a dead-code metric diff --git a/docs/plans/vscode-ext-cli-api.md b/docs/plans/vscode-ext-cli-api.md new file mode 100644 index 000000000..ec23fbbe7 --- /dev/null +++ b/docs/plans/vscode-ext-cli-api.md @@ -0,0 +1,555 @@ +# VSCode 扩展 ↔ Claude Code CLI 协议研究 + +> 目标:摸清 Claude Code CLI 对外暴露的 API 能力,让 VSCode 扩展能通过协议完整驱动 CLI,**不修改 `src/commands/` 中的任何命令文件**。 +> +> 研究方式:只读阅读 + grep 精确定位。所有字段都给出代码位置 (`file:line`)。 +> +> 生成日期:2026-04-24 + +--- + +## 0. 研究要点速览 + +- **启动入口**:`claude --print --input-format stream-json --output-format stream-json --verbose [--permission-mode ]` +- **协议载体**:stdin / stdout,逐行 NDJSON(一行一个 JSON) +- **当前扩展 (`packages/vscode-extension/`) 已实现**:`user_message` 发送、`control_request` 所有常用 subtype、权限响应。本文件把 CLI 侧协议从零梳理一遍,列出还能再挖的能力。 +- **所有 control_request subtype 定义的权威位置**:`src/entrypoints/sdk/controlSchemas.ts`(Zod schema) +- **所有 control_request subtype 的处理分派**:`src/cli/print.ts:2952-4169`(单一 `if/else` 分派表) + +--- + +## 1. Stream JSON 协议 + +### 1.1 启用方式 + +CLI 参数定义:`src/main.tsx:1418-1443` + +```bash +claude --print \ + --input-format stream-json \ + --output-format stream-json \ + --verbose \ + [--permission-mode default|acceptEdits|bypassPermissions|plan|dontAsk|auto] \ + [--replay-user-messages] \ # 回显 stdin 的 user 消息 + [--include-partial-messages] \ # 把 stream_event 也吐到 stdout + [--permission-prompt-tool stdio] \ # 让 canUseTool 走 stdin/stdout + [--session-id ] [--resume ] \ + [--append-system-prompt "..."] [--system-prompt "..."] \ + [--model ] [--agent ] \ + [--max-turns N] [--max-cost-usd X] [--max-thinking-tokens N] \ + [--replay-user-messages] +``` + +- 校验逻辑:`src/main.tsx:2808-2860`(`--input-format=stream-json` 必须 `--output-format=stream-json`,必须 `--print`)。 +- 入参解析:`src/cli/structuredIO.ts:136-265` 的 `StructuredIO.read()`。 +- 出口:`src/cli/structuredIO.ts:471-473` 的 `StructuredIO.write()`(走 `writeToStdout` + NDJSON 序列化);队列化 drain 在 `src/cli/print.ts` 的 `output.enqueue()`。 +- **编码**:每条消息 JSON 后跟 `\n`;空行/`\r\n` 被忽略。 + +### 1.2 输入消息类型(用户 → CLI) + +权威定义:`src/entrypoints/sdk/controlSchemas.ts:655-663`(`StdinMessageSchema` union) + +分派位置:`src/cli/structuredIO.ts:338-469`(`processLine`)。 + +| type | 含义 | 关键字段 | 代码位置 | +|------|------|---------|----------| +| `user` | 用户一轮输入(文本/斜杠/bash) | `message.role: "user"`, `message.content: string \| ContentBlockParam[]`, `parent_tool_use_id: null`, `session_id`, 可选 `uuid`, `priority: "now"\|"next"\|"later"` | Schema `coreSchemas.ts:1277-1299`;消费 `print.ts:4196-4272` | +| `control_request` | 控制类请求(模型/模式/中断 等) | `request_id: string`, `request: { subtype: ... }` | Schema `controlSchemas.ts:578-584`;分派 `print.ts:2952-4169` | +| `control_response` | 回应 CLI 发出的 `control_request`(典型:`can_use_tool` 的 allow/deny) | `response: { subtype: "success"\|"error", request_id, response?, error? }` | `controlSchemas.ts:586-610`;消费 `structuredIO.ts:368-436` | +| `control_cancel_request` | 取消一个在途 control_request | `request_id` | `controlSchemas.ts:612-619` | +| `keep_alive` | 心跳(静默忽略) | — | `controlSchemas.ts:621-627`;`structuredIO.ts:349-351` | +| `update_environment_variables` | 运行时改 `process.env`(bridge 会话 token 刷新用) | `variables: Record` | `controlSchemas.ts:629-636`;消费 `structuredIO.ts:353-367` | +| `assistant` | 历史 assistant 消息回灌(bridge 用) | 标准 AssistantMessage | `print.ts:4183-4192` | +| `system` | 历史 system 消息回灌 | 标准 SystemMessage | `print.ts:4183-4192` | + +**关键:斜杠命令和 bash 命令都通过 `type: "user"` 发送**,CLI 自己识别首字符 `/` 或 `!`。见 `src/utils/processUserInput/processUserInput.ts:536-554`: + +```ts +// 伪代码 +if (inputString.startsWith('/') && !effectiveSkipSlash) { + const { processSlashCommand } = await import('./processSlashCommand.js') + return processSlashCommand(inputString, ..., context, ...) +} +``` + +`effectiveSkipSlash` 由 `user` 消息里的 `skipSlashCommands` 字段控制(bridge 回灌历史才会用,普通扩展**不要**设),见 `src/bridge/inboundMessages.ts` 和 `print.ts:4068`。 + +`SDKUserMessage` 最小样板(扩展已在用,位置 `packages/vscode-extension/src/CLIProcess.ts:272-282`): + +```json +{ + "type": "user", + "message": { "role": "user", "content": [{"type":"text","text":"hello"}] }, + "parent_tool_use_id": null, + "session_id": "" +} +``` + +说明: +- `content` 支持 `string` 或 Anthropic `ContentBlockParam[]`(可带图片)。 +- `session_id` 空字符串 CLI 会用自己的 sessionId 填,不影响功能。 +- `uuid` 可选;填了 CLI 会做去重(`print.ts:4206-4245`)。 +- `priority`(`"now"|"next"|"later"`)用于消息队列排序,一般省略。 + +### 1.3 输出消息类型(CLI → 用户) + +权威定义:`src/entrypoints/sdk/controlSchemas.ts:642-653`(`StdoutMessageSchema` union)+ `coreSchemas.ts:1858-1872`(`SDKMessageSchema`) + +| type | subtype | 含义 | 关键字段 | 代码位置 | +|------|---------|------|----------|----------| +| `system` | `init` | 会话启动 | `tools[]`, `mcp_servers[]`, `model`, `permissionMode`, `slash_commands[]`, `skills[]`, `agents[]?`, `plugins[]`, `output_style`, `cwd`, `apiKeySource`, `claude_code_version`, `session_id` | Schema `coreSchemas.ts:1461-1498` | +| `system` | `compact_boundary` | 压缩分界标记 | `compact_metadata: { trigger: "manual"\|"auto", pre_tokens, preserved_segment? }` | `coreSchemas.ts:1510-1535` | +| `system` | `status` / `task_notification` / `task_started` / `task_progress` / `bridge_state` / `post_turn_summary` / `session_state_changed` / `hook_started` / `hook_progress` / `hook_response` / `elicitation_complete` / `files_persisted` / `error_during_execution` | 各类运行时状态 | 字段因 subtype 而异;都带 `uuid` + `session_id` | `print.ts:643-2509`(搜 `subtype:` 可看) | +| `assistant` | — | 模型输出一条消息 | `message: APIAssistantMessage`(标准 Anthropic 格式,含 `content: Array`, `usage`), `parent_tool_use_id`, `uuid`, `session_id`, `error?` | `coreSchemas.ts:1351-1360` | +| `user` | — | 回灌或 replay 的用户消息(仅 `--replay-user-messages` 时) | 同输入 `user`,多 `isReplay: true` | `coreSchemas.ts:1301-1307` | +| `stream_event` | — | 模型流式事件(仅 `--include-partial-messages`) | `event: RawMessageStreamEvent`(Anthropic SSE delta) | `coreSchemas.ts:1500-1508` | +| `streamlined_text` | — | 精简 text(某些内部模式替换 assistant) | `text`, `uuid`, `session_id` | `coreSchemas.ts:1373-1386` | +| `streamlined_tool_use_summary` | — | 精简 tool use 聚合 | `tool_summary`, `uuid`, `session_id` | `coreSchemas.ts:1388-1401` | +| `result` | `success` | 一轮回答结束,成功 | `duration_ms`, `duration_api_ms`, `num_turns`, `result: string`, `stop_reason`, `total_cost_usd`, `usage`, `modelUsage`, `permission_denials[]` | `coreSchemas.ts:1411-1430` | +| `result` | `error_during_execution` / `error_max_turns` / `error_max_budget_usd` / `error_max_structured_output_retries` | 一轮失败 | 同上 + `errors: string[]` | `coreSchemas.ts:1432-1455` | +| `rate_limit_event` | — | 速率限制变更推送 | `rate_limit_info: { status, resetsAt, rateLimitType, utilization, ... }` | `coreSchemas.ts:1362-1371` | +| `control_request` | `can_use_tool` / `elicitation` / `mcp_message` / `hook_callback` | CLI 反向发给用户等待回应 | `request_id`, `request.subtype`, `request.*` | `controlSchemas.ts:106-122`(can_use_tool)等 | +| `control_response` | `success`/`error` | CLI 回给用户自己发过的 control_request | `response.request_id`, `response.response?` | 同上 | +| `control_cancel_request` | — | CLI 反向取消已发的 control_request | `request_id` | `structuredIO.ts:297-299, 498-500` | +| `keep_alive` | — | 心跳 | — | 仅双向兼容 | + +**关键特性**: +- 所有消息都是 JSON 一行,UTF-8,结尾 `\n`。 +- stdout 上不会出现 TTY ANSI,因为 `--print` 已强制非交互。 +- stderr 上仍有普通调试日志,扩展已把这个当 "stderr" 事件消费(`CLIProcess.ts:131-133`)。 + +--- + +## 2. Control Request 完整清单 + +权威处理位置:`src/cli/print.ts:2952-4169`。下表把 schema 里所有 subtype + print.ts 里额外识别的 subtype 全列出来。 + +| subtype | 入参 | 出参 (成功 response) | 处理位置 | Schema 位置 | +|---------|------|----------------------|----------|-------------| +| `initialize` | `hooks?`, `sdkMcpServers?`, `systemPrompt?`, `appendSystemPrompt?`, `agents?: Record`, `promptSuggestions?`, `agentProgressSummaries?`, `jsonSchema?` | `{ commands: SlashCommand[], agents: AgentInfo[], output_style, available_output_styles[], models: ModelInfo[], account: AccountInfo, pid?, fast_mode_state? }` | `print.ts:2995-3049` (handler at `print.ts:4485-4816`) | `controlSchemas.ts:57-95` | +| `interrupt` | — | `{}` | `print.ts:2963-2981` | `controlSchemas.ts:97-103` | +| `set_model` | `model?: string`(空/`"default"` = 回退默认模型) | `{}` | `print.ts:3065-3076` | `controlSchemas.ts:137-144` | +| `set_permission_mode` | `mode: "default"\|"acceptEdits"\|"bypassPermissions"\|"plan"\|"dontAsk"\|"auto"`, `ultraplan?: boolean` | `{}` | `print.ts:3050-3064` | `controlSchemas.ts:124-135` | +| `set_max_thinking_tokens` | `max_thinking_tokens: number\|null`(0 禁用,null 恢复默认) | `{}` | `print.ts:3077-3088` | `controlSchemas.ts:146-155` | +| `mcp_status` | — | `{ mcpServers: McpServerStatus[] }` | `print.ts:3089-3092` | `controlSchemas.ts:157-173` | +| `mcp_message` | `server_name: string`, `message: JSONRPCMessage` | `{}` | `print.ts:3111-3128` | `controlSchemas.ts:374-382` | +| `mcp_set_servers` | `servers: Record` | `{ added: string[], removed: string[], errors: Record }` | `print.ts:3189-3201` | `controlSchemas.ts:384-403` | +| `mcp_reconnect` | `serverName: string` | `{}` | `print.ts:3271-3343` | `controlSchemas.ts:435-442` | +| `mcp_toggle` | `serverName: string`, `enabled: boolean` | `{}` | `print.ts:3344-3434` | `controlSchemas.ts:444-452` | +| `reload_plugins` | — | `{ commands: SlashCommand[], agents: AgentInfo[], plugins: { name,path,source? }[], mcpServers: McpServerStatus[], error_count: number }` | `print.ts:3202-3270` | `controlSchemas.ts:405-433` | +| `get_context_usage` | — | 大对象:`{ categories[], totalTokens, maxTokens, percentage, gridRows[][], model, memoryFiles[], mcpTools[], deferredBuiltinTools?, systemTools?, systemPromptSections?, agents[], slashCommands?, skills?, isAutoCompactEnabled, messageBreakdown?, apiUsage, ... }` | `print.ts:3093-3110` | `controlSchemas.ts:175-306` | +| `get_settings` | — | `{ effective: object, sources: [{source,settings}], applied: { model, effort } }` | `print.ts:3896-3911` | `controlSchemas.ts:475-520` | +| `apply_flag_settings` | `settings: Record`(`null` = 删除该键) | `{}` | `print.ts:3839-3895` | `controlSchemas.ts:464-473` | +| `rewind_files` | `user_message_id: UUID`, `dry_run?: boolean` | `{ canRewind, error?, filesChanged[]?, insertions?, deletions? }` | `print.ts:3129-3144` | `controlSchemas.ts:308-328` | +| `cancel_async_message` | `message_uuid: string` | `{ cancelled: boolean }` | `print.ts:3145-3150` | `controlSchemas.ts:330-349` | +| `seed_read_state` | `path: string`, `mtime: number` | `{}` | `print.ts:3151-3188` | `controlSchemas.ts:351-361` | +| `hook_callback` | `callback_id: string`, `input: HookInput`, `tool_use_id?` | hookJSONOutput | CLI 发给宿主的方向,宿主处理 | `controlSchemas.ts:363-372` | +| `stop_task` | `task_id: string` | `{}` | `print.ts:3912-3922` | `controlSchemas.ts:455-462` | +| `elicitation` | `mcp_server_name`, `message`, `mode?: "form"\|"url"`, `url?`, `elicitation_id?`, `requested_schema?` | `{ action: "accept"\|"decline"\|"cancel", content? }` | CLI 发给宿主的方向,宿主处理 | `controlSchemas.ts:522-545` | +| `can_use_tool` | `tool_name`, `input`, `tool_use_id`, `permission_suggestions?`, `blocked_path?`, `decision_reason?`, `title?`, `display_name?`, `agent_id?`, `description?` | `PermissionPromptToolResult`(`{ behavior: "allow"\|"deny", updatedInput?, message?, ... }`) | CLI 发出(`structuredIO.ts:592-612`),宿主在 stdin 回 `control_response` | `controlSchemas.ts:106-122` | +| `end_session` | `reason?: string` | `{}`(随后 CLI 关闭 stdin 循环,开始 drain) | `print.ts:2982-2994` | ⚠ schema 未列,代码识别 | +| `channel_enable` | `serverName: string` | — | `print.ts:3435-3447` | ⚠ schema 未列 | +| `mcp_authenticate` | `serverName: string` | OAuth 流 | `print.ts:3448-...` | ⚠ schema 未列 | +| `mcp_oauth_callback_url` | — | — | `print.ts:3603-...` | ⚠ schema 未列 | +| `mcp_clear_auth` | `serverName: string` | `{}` | `print.ts:3791-3838` | ⚠ schema 未列 | +| `claude_authenticate` | — | OAuth 流 | `print.ts:3655-...` | ⚠ schema 未列 | +| `claude_oauth_callback` / `claude_oauth_wait_for_completion` | — | — | `print.ts:3752-3790` | ⚠ schema 未列 | +| `generate_session_title` | `description: string`, `persist: boolean` | `{ title: string\|null }` | `print.ts:3923-3955`(fire-and-forget) | ⚠ schema 未列 | +| `side_question` | `question: string` | `{ response: string }` | `print.ts:3956-4015` | ⚠ schema 未列 | +| `set_proactive` | `enabled: boolean` | `{}`(需 `PROACTIVE` 或 `KAIROS` feature) | `print.ts:4016-4032` | ⚠ schema 未列 | +| `remote_control` | `enabled: boolean` | `{ session_url, connect_url, environment_id }` | `print.ts:4033-4161` | ⚠ schema 未列 | + +**未知 subtype** 会走 `print.ts:4162-4168` 的 fallback:回 `{subtype:"error", error:"Unsupported control request subtype: "}`,不会挂起。 + +**Control Response 结构**(`controlSchemas.ts:586-610`): + +```json +{ + "type": "control_response", + "response": { + "subtype": "success", + "request_id": "", + "response": { ...subtype-specific... } + } +} +``` + +错误: + +```json +{ + "type": "control_response", + "response": { + "subtype": "error", + "request_id": "", + "error": "", + "pending_permission_requests": [...] // 仅 initialize 已初始化时带 + } +} +``` + +**发送工具函数**(print.ts 侧):`print.ts:2865-2880`(`sendControlResponseSuccess` / `sendControlResponseError`)。 + +--- + +## 3. 模型切换 + +### 3.1 API:`set_model` control_request + +已实现,扩展端已在用(`packages/vscode-extension/src/CLIProcess.ts:334-337`,`ChatViewProvider.ts:194-217`)。 + +**请求**: + +```json +{ + "type": "control_request", + "request_id": "vscode_xxx", + "request": { "subtype": "set_model", "model": "claude-sonnet-4-5" } +} +``` + +- `model` 可省略或传 `"default"`,表示回退到 `getDefaultMainLoopModel()` 的配置默认。 +- 支持模型 alias(`"sonnet"`, `"opus"`, `"haiku"`)或完整 ID。解析发生在 `QueryEngine.submitMessage` 调 `parseUserSpecifiedModel()` 时(见 `src/services/acp/agent.ts:389` 注释)。 + +**行为**(`print.ts:3065-3076`): +1. `activeUserSpecifiedModel = model` +2. `setMainLoopModelOverride(model)` — 写 session 级 override,优先级高于 settings。 +3. `notifySessionMetadataChanged({ model })` — 触发 metadata 变更广播(bridge / CCR 会收到)。 +4. `injectModelSwitchBreadcrumbs(requestedModel, model)` — 往 `mutableMessages` 塞一条 system 消息,让模型自己看得见切换事件。 + +**即时生效**:下一轮 API 调用使用新模型。当前轮不中断。 + +### 3.2 替代:通过 `apply_flag_settings` 也能改模型 + +`print.ts:3877-3893` 显示 `apply_flag_settings` 里如果带 `model` key,会走和 `set_model` 一模一样的 override 路径。好处是能同时改其他 settings(比如 `effort`、`maxOutputTokens`)。 + +### 3.3 可用模型列表 + +在 `initialize` response 的 `models: ModelInfo[]` 里返回(`controlSchemas.ts:84`),schema 见 `coreSchemas.ts:1048-1080`: + +```ts +{ value, displayName, description, supportsEffort?, supportedEffortLevels?, supportsAdaptiveThinking?, supportsFastMode?, supportsAutoMode? } +``` + +扩展可以在收到 `initialize` success response 后缓存这个列表给 UI 做 picker。 + +### 3.4 VSCode 扩展侧建议 + +当前 `ChatViewProvider` 已经走 `set_model`,**无需改 `src/commands/`**。增强方向: +1. 扩展启动后**主动**发一次 `initialize` control_request(含空 body),拿到 `models[]` 和 `commands[]` 喂给 webview picker。 +2. UI 侧 picker 改变 → 发 `set_model`。 +3. 监听 `control_response` 的 `subtype: "success"` + 匹配 `request_id` 来确认切换成功。 + +--- + +## 4. 模式切换 + +### 4.1 API:`set_permission_mode` control_request + +已实现(`CLIProcess.ts:351-353`,`ChatViewProvider.ts:226-242`)。 + +**请求**: + +```json +{ + "type": "control_request", + "request_id": "...", + "request": { "subtype": "set_permission_mode", "mode": "acceptEdits" } +} +``` + +### 4.2 可选值 + +**Schema**:`src/entrypoints/sdk/coreSchemas.ts:337-349` + +```ts +'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'dontAsk' | 'auto' +``` + +- `default` — 危险操作弹权限对话(`can_use_tool`)。 +- `acceptEdits` — 自动接受文件编辑类 tool(Write/Edit/MultiEdit)。 +- `bypassPermissions` — 跳过所有权限检查。需要 `isBypassPermissionsModeAvailable`(非 root,或有 `IS_SANDBOX` env),否则 UI 会拒绝选中。检测逻辑:`agent.ts:484-486`。 +- `plan` — 计划模式,不真正执行 tool(除了 read-only 的)。 +- `dontAsk` — 不弹框,未预先 approve 的一律 deny。 +- `auto` — 分类器自动判定(需 `TRANSCRIPT_CLASSIFIER` feature;内部实验特性)。 + +还有两个 **internal only**(`src/types/permissions.ts:28`):`bubble`(不对外暴露)、一个已废弃值。扩展只需要管 6 个 external。 + +### 4.3 行为 + +`print.ts:3050-3064` + `handleSetPermissionMode()`(位置见搜索): +1. 更新 `AppState.toolPermissionContext.mode`。 +2. 如果 `ultraplan: true`(内部用),额外标 `isUltraplanMode`。 +3. 触发 `onChangeAppState` → metadata 变更广播。 +4. 即时生效,当前轮如果还没执行 tool 也会被新模式覆盖。 + +### 4.4 查询当前模式 + +方式 A:`get_settings` control_request,response 里 `effective.permissions.defaultMode`。 +方式 B:听 `system.init` 消息的 `permissionMode` 字段(`coreSchemas.ts:1478`)。 +方式 C:每次 `set_permission_mode` 后自己维护。 + +--- + +## 5. 斜杠命令 + +### 5.1 执行方式:就是发 `type: "user"` + +**关键发现**:CLI 没有单独的 `slash_command` 消息类型。所有斜杠命令都走普通 user message,CLI 的 `processUserInput` 流水线识别首字符 `/` 就调 `processSlashCommand`。 + +**代码路径**: +1. `src/cli/print.ts:4247-4258` — stream-json 里的 user 消息入 queue。 +2. `src/utils/processUserInput/processUserInput.ts:536-554` — 识别 `/` 前缀,dispatch 到 `processSlashCommand.tsx`。 +3. `src/utils/slashCommandParsing.ts:25` — `parseSlashCommand(input)` 解析 `/ `。 +4. `src/commands.ts` — 命令注册表(117 个左右命令,在 `src/commands/` 下)。 + +**消息示例**(直接和普通 user 消息一样): + +```json +{ + "type": "user", + "message": { "role": "user", "content": [{"type":"text","text":"/compact"}] }, + "parent_tool_use_id": null, + "session_id": "" +} +``` + +### 5.2 支持哪些命令? + +**绝大部分支持** `--print` 模式(stream-json 就是 print 的子模式),条件是命令定义带 `supportsNonInteractive: true`。 + +- `compact` — ✅(`src/commands/compact/index.ts:9`) +- `clear` — ✅(大概率;需要每个命令逐查) +- `model`, `config`, `permissions`, `mcp`, `context`, `agents`, `help`, `status`, `cost`, `poor`, `fast`, `vim`, `review`, `init`, `memory`, `skills`, `tasks`, `session` — 基本都支持 +- **不支持 print 模式** 的:需要交互式 UI 的(`doctor`, `hooks`, `status-line`, `terminal-setup`, `login`, `logout`, `onboarding`, `bug`)。扩展当前 `ChatViewProvider.ts:364-405` 里手动拦截了这些并给出 "在终端里跑" 的提示。 + +**枚举可用斜杠命令**:在 `initialize` response 的 `commands: SlashCommand[]` 字段里返回,每项是 `{ name, description, argumentHint }`(schema `coreSchemas.ts:1017-1029`)。 + +`print.ts:3251-3257` 的 `reload_plugins` 会返回更新后的 commands 列表;`commands.filter(cmd => cmd.userInvocable !== false)` 决定哪些对用户可见。 + +### 5.3 带参数的斜杠命令 + +正常拼进 text 里即可:`"/compact summarize only the last 20 messages"`。 + +### 5.4 VSCode 扩展列出可用斜杠命令的正确做法 + +1. 扩展启动后(CLI process ready),发 `initialize` control_request: + ```json + { "type":"control_request", "request_id":"init_1", "request":{"subtype":"initialize"} } + ``` +2. 解析回来的 `control_response.response.commands[]` 喂给 webview 做补全 / picker。 +3. 插件改动时(用户装/卸了 plugin),可以发 `reload_plugins` 刷新。 + +**不要**修改 `src/commands/` 下任何文件。这一切纯协议能拿到。 + +### 5.5 当前扩展的缺陷 + +`ChatViewProvider.ts:186-410` 的 `handleSlashCommand` 把 `/model`、`/permissions`、`/compact` 等**拦截**在扩展侧自己处理。这有一个**不匹配**:扩展侧硬编码了一份命令清单,但实际 CLI 还支持更多(`/cost`, `/session`, `/memory`, `/skills`, `/tasks`...)。改进方案: + +- 对「需要发 control_request 的」命令(`/model`, `/permissions`, `/mcp`, `/context`, `/think`, `/config`):保留拦截(已对)。 +- 对「标准 slash command」(`/compact`, `/clear`, `/review`, `/init`, `/memory`, `/cost`...):**不要**拦截,直接把原文当 user 消息发给 CLI,让 CLI 自己处理。现在 `/compact` 根本没处理(`handleSlashCommand` fallthrough 到 `default: return false` → 走 `sendUserMessage`),实际上这条路已经通了。只是 `/help` 里列 `/compact` 但 `help` 消息是扩展自己生成的,没有动态查 CLI。 + +--- + +## 6. 其他重要 API + +### 6.1 Interrupt / Cancel + +**control_request**: +- `interrupt` — 中断当前 API 调用 + 清 suggestion queue(`print.ts:2963-2981`)。 +- `end_session` — 更激进,同时 break 出 stdin 循环,CLI 准备优雅关闭(`print.ts:2982-2994`)。 +- `control_cancel_request`(独立 type,不是 subtype)— 取消一个在途的 CLI→宿主的 control_request(比如一个 `can_use_tool` 等待权限响应时想换走 bridge 那条路)(`structuredIO.ts:297-299`)。 + +**扩展侧已有**:`CLIProcess.ts:361-379` 的 `interrupt()` 先发 `control_request.interrupt`,失败才 SIGINT 兜底。 + +### 6.2 Compact + +**没有专门的 control_request**。要压缩直接发 user message `/compact`(斜杠命令走普通 user 消息通道)。 + +- 手动触发:`/compact [instructions]`(`src/commands/compact/compact.ts`)。 +- 自动触发:context 达到阈值时 CLI 自己发 system.compact_boundary 事件;`get_context_usage` response 里 `isAutoCompactEnabled` 告诉你开关状态(`controlSchemas.ts:273-274`)。 +- 监听结果:输出流里会出现 `{ type: "system", subtype: "compact_boundary", compact_metadata: {...} }`(`coreSchemas.ts:1510-1535`)。 + +### 6.3 Fork + +**两个概念**: + +1. **Fork session**(新建分支会话,不在当前流里)— 这是 SDK function `forkSession(sessionId, { dir?, upToMessageId?, title? })`,在 `src/entrypoints/agentSdkTypes.ts:268-273`。当前代码里这是 SDK-only,CLI 没暴露成 control_request。若扩展要 fork,目前只能: + - (a) 用 CLI 的 `claude --resume ` 外加自己复制 session JSONL;或者 + - (b) 将来加一个 `fork_session` control_request。 + +2. **Fork subagent**(从当前 assistant 回复 fork 出一个 subagent 并发执行)— 这是 `/fork ` 斜杠命令(`src/commands/fork/fork.tsx`),需要 `FEATURE_FORK_SUBAGENT=1`。发 user 消息 `"/fork 修复 validate.ts 的空指针检查"` 即可。 + +**ACP 协议有**:`unstable_forkSession`(`src/services/acp/agent.ts:209-223`)。如果扩展走 ACP 路径(见 7.3)可以直接用。 + +### 6.4 Clear / New Session + +**没有协议层的 "clear session"**。扩展当前做法(`ChatViewProvider.ts:412-419`):**杀 CLI 进程重启**。这是正确的,因为 CLI 的 session 从 stdin/stdout 打开那一刻就绑定,没法中途清空 mutableMessages。 + +替代路径: +- `/clear` 斜杠命令(`src/commands/clear/`)— 清 CLI 自己看到的历史但保留 process,性能更好。 +- 重启进程 —— 扩展当前的做法,更干净。 + +**想要完整 new session**(换 sessionId、换 cwd 等):必须重启 CLI,传 `--session-id ` 或不传让 CLI 自己生成。 + +### 6.5 Rewind (文件回滚) + +`rewind_files` control_request(`print.ts:3129-3144`):回滚从某条 user message 之后的所有文件编辑。 + +**入参**:`{ user_message_id: UUID, dry_run?: boolean }` + +**出参**:`{ canRewind, error?, filesChanged?, insertions?, deletions? }` + +扩展可以给用户一个 "undo this turn" 按钮。 + +### 6.6 Hook Callback + +当 CLI 加载了 SDK-registered hook(initialize 里 `hooks` 字段)时,会反向发 `hook_callback` control_request 给宿主。宿主用 stdin 回 `control_response` 带 hook output。详见 `structuredIO.ts:667-694`。 + +对 VSCode 扩展:**暂时不需要**。用 settings.json 配置的文件系统 hooks 一样工作,不必通过 SDK hook。 + +### 6.7 MCP Elicitation + +CLI 反向发 `elicitation` control_request(`structuredIO.ts:699-726`)要求用户输入表单/URL,扩展可以弹一个 webview input。当前扩展没实现,是个留白。 + +### 6.8 Session Title Generation + +`generate_session_title` control_request(`print.ts:3923-3955`)让 CLI 用 Haiku 生成标题。 + +**入参**:`{ description: string, persist: boolean }` + +**出参**:`{ title: string | null }` + +扩展可以在 tab/sidebar 上显示智能标题。 + +### 6.9 Side Question + +`side_question` control_request(`print.ts:3956-4015`)用缓存的 prompt prefix 单独问一个问题,不污染主 session。对做 "explain this selection" 很合适。 + +**入参**:`{ question: string }` + +**出参**:`{ response: string }` + +### 6.10 Remote Control(Bridge)开关 + +`remote_control` control_request(`print.ts:4033-4161`)。扩展一般不需要,除非要把 CLI 接到 claude.ai 的 bridge 上。 + +--- + +## 7. 不修改 `src/commands/` 的扩展实现方案 + +### 7.1 对象关系图 + +``` +VSCode Extension (webview) + ↕ vscode.webview.postMessage +ChatViewProvider (packages/vscode-extension/src/) + ↕ stdin / stdout (NDJSON) +CLI Process: claude --print --input-format stream-json --output-format stream-json + ├── Entry: src/entrypoints/cli.tsx → src/main.tsx + ├── I/O: src/cli/structuredIO.ts (StructuredIO) + └── Core loop: src/cli/print.ts (2952-4169 控制分派) +``` + +### 7.2 路径一:继续扩展现有 CLIProcess(推荐) + +优点:**零** CLI 侧改动。已有代码全部可复用。 + +待补能力(按优先级): +1. **主动发 `initialize`**(现有 `sendInitialize()` 已实现但 ChatViewProvider 没调)→ 拿 `commands[]`、`models[]`、`agents[]`、`account`。 +2. **动态斜杠命令补全** — 用 #1 返回的 commands。 +3. **动态模型 picker** — 用 #1 返回的 models。 +4. **`get_context_usage` 面板** — 已 wire,webview 侧画个 grid 即可。 +5. **`rewind_files` undo 按钮**。 +6. **`elicitation` 响应** — 弹 webview form。 +7. **`hook_callback` 响应** — 可选,一般不需要。 +8. **监听 `system.compact_boundary`** — 提示 UI "已压缩"。 + +### 7.3 路径二:走 ACP 协议(重) + +CLI 已有 `--acp` 模式(`src/entrypoints/cli.tsx:136-141`),进 `src/services/acp/` 的 `AcpAgent`。 + +- **优势**:ACP 有 `setSessionModel`、`setSessionMode`、`unstable_forkSession`、`unstable_resumeSession`、`listSessions` 等成熟方法。 +- **劣势**:需要在扩展侧起 ACP client(`@agentclientprotocol/sdk`),多一层封装。`packages/acp-link/` 已有 WebSocket→ACP 桥可复用。 + +两条路可以**并存**:扩展继续用 stream-json 直连,ACP 留给 WebView 远程场景。 + +### 7.4 路径三:自己封装 bridge(不推荐) + +改 `src/bridge/` 来加 VSCode 专用通道。违反「不改 src/」原则,不推荐。 + +--- + +## 8. 风险与注意事项 + +1. **`bypassPermissions` 不一定可用**。Root 用户且非 sandbox 时,CLI 会拒绝该 mode。扩展应先发 `get_settings`,看 `effective.permissions` 或者记住 `initialize` response(无此字段,需要从 `system.init` 消息的 `permissionMode` 兜底),如果 bypass 不可用就灰掉 UI 选项。 +2. **`set_model` 不校验模型可用性** —— 传一个不存在的 model ID 也会成功回 `{}`,但下一轮 API 调用才爆。建议从 `initialize.models` 的 `value` 列表里选。 +3. **`initialize` 只能调用一次**。重复调会回 `{subtype:"error", error:"Already initialized"}`(`print.ts:4504-4515`)。 +4. **`apply_flag_settings` 里 `null` = 删除该键**(`print.ts:3854-3858`),`undefined` 被 JSON 丢弃。想清一个 setting 必须显式传 `null`。 +5. **斜杠命令在 stream-json 模式里有些命令不可用**(`isHidden` / `userInvocable: false` / `supportsNonInteractive: false`)。应只展示 `initialize.commands[]` 返回的那些。 +6. **`control_cancel_request`** 是**独立 type**,不是 subtype。和 `control_request.cancel_async_message` 是两回事: + - `control_cancel_request` — 取消 CLI→宿主的在途请求。 + - `cancel_async_message` — 从 CLI 的 command queue 里摘掉还没开始处理的 user message。 +7. **CLI 重启会丢失所有 override**(set_model、set_permission_mode、set_max_thinking_tokens、apply_flag_settings)。扩展若要持久化,自己记 `settings.json` 或每次启动重新 push。 +8. **Bun runtime 产物自带 `import.meta.require` 补丁**,`node dist/cli.js` 也能跑。扩展当前 `CLIProcess.ts:186-213` 的路径探测已经覆盖这种情况。 + +--- + +## 9. 附录:快速查表 + +### 9.1 典型扩展启动序列 + +```jsonl +→ (spawn) claude --print --output-format stream-json --input-format stream-json --verbose +← {"type":"system","subtype":"init","session_id":"...","tools":[...],"model":"...","permissionMode":"default","slash_commands":[...],"mcp_servers":[...],...} +→ {"type":"control_request","request_id":"init_1","request":{"subtype":"initialize"}} +← {"type":"control_response","response":{"subtype":"success","request_id":"init_1","response":{"commands":[...],"agents":[...],"models":[...],"account":{...}}}} +→ {"type":"user","message":{"role":"user","content":[{"type":"text","text":"hello"}]},"parent_tool_use_id":null,"session_id":""} +← {"type":"assistant","message":{...},"uuid":"...","session_id":"..."} +← {"type":"result","subtype":"success","result":"...","usage":{...}} +``` + +### 9.2 关键文件绝对路径 + +- `E:\Source_code\Claude-code-bast\src\entrypoints\cli.tsx` — 入口,快速路径派发 +- `E:\Source_code\Claude-code-bast\src\entrypoints\sdk\controlSchemas.ts` — control_request 所有 Zod schema(❗单一权威) +- `E:\Source_code\Claude-code-bast\src\entrypoints\sdk\coreSchemas.ts` — SDK 消息类型 Zod schema +- `E:\Source_code\Claude-code-bast\src\cli\print.ts` — stream-json 主循环,2952-4169 行是所有 control_request 分派(❗单一权威) +- `E:\Source_code\Claude-code-bast\src\cli\structuredIO.ts` — 读写 stdin/stdout,权限请求发送,control_response 匹配 +- `E:\Source_code\Claude-code-bast\src\main.tsx:1418-1443` — `--input-format`/`--output-format` CLI flag 定义 +- `E:\Source_code\Claude-code-bast\src\utils\processUserInput\processUserInput.ts:536-554` — 斜杠命令识别 +- `E:\Source_code\Claude-code-bast\src\services\acp\agent.ts` — ACP Agent(替代协议路径) +- `E:\Source_code\Claude-code-bast\src\types\permissions.ts` — PermissionMode 定义 +- `E:\Source_code\Claude-code-bast\packages\vscode-extension\src\CLIProcess.ts` — 扩展现有 CLI 封装(参考 / 可继续增强) +- `E:\Source_code\Claude-code-bast\packages\vscode-extension\src\ChatViewProvider.ts` — 扩展现有 webview 桥 + +### 9.3 Control Request 速查代码模板 + +```ts +// 发送并等待响应(TypeScript) +type ControlRequest = { + type: "control_request" + request_id: string + request: { subtype: string; [k: string]: unknown } +} +type ControlResponse = { + type: "control_response" + response: + | { subtype: "success"; request_id: string; response?: Record } + | { subtype: "error"; request_id: string; error: string; pending_permission_requests?: ControlRequest[] } +} + +// 权限回应(stdin → CLI) +{ + type: "control_response", + response: { + subtype: "success", + request_id: "", + response: { behavior: "allow", /* or "deny" with message */ } + } +} +``` + +--- + +**报告完** diff --git a/docs/plans/vscode-ext-gap-analysis.md b/docs/plans/vscode-ext-gap-analysis.md new file mode 100644 index 000000000..57e6339c9 --- /dev/null +++ b/docs/plans/vscode-ext-gap-analysis.md @@ -0,0 +1,642 @@ +# VSCode Extension — Claude Code UI 完整度缺口审计 + +**审计日期**: 2026-04-24 +**审计对象**: `packages/vscode-extension/` (commit on branch `feat/vscode-extension`) +**参考基线**: +- 终端 CLI REPL (`src/screens/REPL.tsx`, `src/keybindings/defaultBindings.ts`) +- RCS Web UI (`packages/remote-control-server/web/`) +- SDK 控制协议 (`src/entrypoints/sdk/controlSchemas.ts`, `src/entrypoints/sdk/coreSchemas.ts`) + +--- + +## 概览打分 + +| 维度 | 状态 | 得分 | +|------|------|------| +| CLI 启动与连接 | ✅ 完整 | 9/10 | +| stdout 消息解析 | ⚠️ 部分 | 5/10 | +| control_request 发送通道 | ✅ 覆盖齐全 | 8/10 | +| 模型切换 | ⚠️ 硬编码 | 5/10 | +| 模式切换 UI | ❌ 仅 settings.json | 2/10 | +| 斜杠命令 | ⚠️ 大部分占位 | 4/10 | +| 权限审批 | ⚠️ 缺少建议/按工具过滤/计数 | 5/10 | +| 键盘快捷键 | ❌ 仅 Enter/Esc | 2/10 | +| 状态栏 | ⚠️ 无模式显示 | 6/10 | +| 转录/历史 | ❌ 仅存结构,无 UI | 1/10 | +| VSCode 集成 | ⚠️ 基础选区/文件,无 @ 引用 | 4/10 | +| 图片/附件 | ❌ 完全缺失 | 0/10 | +| Plan/Todos 可视化 | ❌ 完全缺失 | 0/10 | +| MCP 可视化 | ⚠️ 仅纯文本 | 3/10 | +| 上下文用量详情 | ⚠️ 仅百分比,无分类 | 3/10 | + +--- + +## ✅ 已实现 (+ 质量评估) + +### 1. CLI 进程启动 (质量: 优) + +**文件**: `src/CLIProcess.ts:71-151`, `resolveCLIPath` (L153-214) + +- 使用标准 `--print --output-format stream-json --input-format stream-json --verbose` 启动(符合 stdioServer/stdin 协议)。 +- `resolveCLIPath` 优先使用 `bun run src/entrypoints/cli.tsx`(源码模式),后备 `dist/cli.js`、`dist/cli-node.js`、PATH 中的 `ccb`。 +- 跨平台 `findBun` (L216-238) 在 Windows 下处理 `bun.exe`。 +- 指数退避重启 (L404-422, 最多 5 次)。 +- permissionMode 作为 `--permission-mode` 参数传入 (L106-108)。 + +**小缺口**: +- 未传入 `--dangerously-skip-permissions` 的 opt-in 绕路。 +- 未传入 `--session-id`、`--resume`、`--continue`(无法恢复历史会话)。 +- 未传入 `--append-system-prompt`、`--agents` 等初始化旗标(当前只能靠 `sendInitialize({})` 空体)。 + +### 2. control_request 通道 (质量: 优) + +**文件**: `src/CLIProcess.ts:284-363` + +- `sendControlResponse(requestId, approved, extra)` 正确封装 success/error 信封 (L284-311)。 +- `sendControlRequest(subtype, payload)` 通用封装,调用方可自定义 subtype (L317-328)。 +- 已封装的控制调用: `sendInitialize`、`sendSetModel`、`sendGetSettings`、`sendMcpStatus`、`sendGetContextUsage`、`sendSetPermissionMode`、`sendSetMaxThinkingTokens`、`sendInterrupt`。 + +**小缺口**: +- 未实现 `rewind_files`、`cancel_async_message`、`mcp_reconnect`、`mcp_toggle`、`stop_task`、`reload_plugins`(仅在 `/agents` 中使用一次)、`hook_callback`、`elicitation`、`mcp_set_servers`、`apply_flag_settings`。完整 SDK 协议有 21 个 subtype,当前覆盖 8 个。 + +### 3. 流式 stream_event 解析 (质量: 良) + +**文件**: `webview/lib/messageParser.ts:95-174` + +- 正确处理 `message_start`、`content_block_start`、`content_block_delta`、`content_block_stop`、`message_stop`。 +- 支持 `text_delta`、`thinking_delta`、`input_json_delta` 三种增量类型。 +- 多 block index 用 `Map` 维护(L16-19)。 + +**小缺口**: `input_json_delta` 只做字符串累加,没有 best-effort 部分 JSON 解析,工具输入预览不友好。 + +### 4. 权限审批 UI (质量: 良) + +**文件**: `webview/components/PermissionCard.tsx`, `App.tsx:358-372` + +- 正确捕获 `control_request` + `subtype: can_use_tool` (messageParser.ts:291-312)。 +- 显示 `displayName`/`description`/截断的 toolInput JSON (PermissionCard.tsx:37-39)。 +- Approve/Deny 回传 `control_response` 带 `behavior: "allow"` 或 `error: "User denied permission"` (CLIProcess.ts:284-311)。 +- 支持多个 pending 权限队列 (App.tsx:142-167)。 +- 支持 `control_cancel_request` 主动取消 (messageParser.ts:314-320)。 + +### 5. 编辑器桥接 (质量: 良) + +**文件**: `src/EditorBridge.ts` + +- `getSelectedTextWithContext` 获取选区 + 行号 + 语言 ID。 +- `getActiveFileContext` 获取当前文件全文。 +- `insertAtCursor`、`copyToClipboard`、`openFile(path, line)`。 +- `applyDiff` 做了最小实现:只提取 `+` 行插入(不是真正的 3-way merge)。 + +### 6. 斜杠命令菜单 UI (质量: 良) + +**文件**: `webview/components/SlashCommandMenu.tsx`, `webview/hooks/useSlashCommands.ts` + +- 弹出式菜单,支持 ArrowUp/Down/Tab/Enter/Esc (useSlashCommands.ts:38-64)。 +- 动态命令通过 `initialize` 响应注入 (messageParser.ts:358-400),与内置列表合并 (slashCommands.ts:45-57)。 +- `BUILTIN_SLASH_COMMANDS` 有 23 条(slashCommands.ts:3-27)。 + +### 7. 增量状态栏 (质量: 中) + +**文件**: `src/StatusBarManager.ts`, `webview/components/StatusBar.tsx` + +- VSCode 原生状态栏显示连接状态图标 + token 计数 + cost。 +- Webview 内部也有独立状态栏。 +- 基于 `result` 消息的 `usage` 自动更新。 + +--- + +## ⚠️ 部分实现 (说明缺什么) + +### 8. 非流式 assistant/user 消息解析 (中优先级) + +**文件**: `webview/lib/messageParser.ts:176-218` + +**缺失**: +- **完全未处理 `type: "user"` 消息**(入站 `tool_result` 载体)。CLI 在 `--print --stream-json` 模式下,每次工具调用后会回发 `{type:"user", message:{role:"user", content:[{type:"tool_result",...}]}}` 来关闭 tool_use cycle。当前 parser 会完全忽略,导致工具执行结果永远不显示。 +- **未处理 stream-only 消息类型**:`SDKStreamlinedTextMessageSchema`、`SDKStreamlinedToolUseSummaryMessageSchema`、`SDKPostTurnSummaryMessageSchema`(coreSchemas.ts:1861)。 +- **未处理 `keep_alive`、`control_cancel_request`(外部取消)**。 +- **未处理 `SDKStatus: "compacting"`** — 压缩中状态不会显示给用户。 +- **未处理 `rate_limit_info` / SDKRateLimitInfoSchema**(coreSchemas.ts:1309)— 速率限制信息丢失。 + +**需改文件**: +- `packages/vscode-extension/webview/lib/messageParser.ts` — 新增 case `"user"`(提取 `tool_result`,匹配到对应 tool_use_id 的 ToolCallCard,设置 `toolStatus: "done"`、注入 result content 到 ToolCallCard body)。 +- `packages/vscode-extension/webview/lib/types.ts` — `ParsedMessage` 增加 `toolUseId?: string`、`toolResult?: {content, isError}`。 +- `packages/vscode-extension/webview/components/ToolCallCard.tsx` — 展示 result payload。 + +**策略**: 两端 (CLI 端无变化,仅 webview parser 重构) +**优先级**: **P0** — 这是导致工具执行看起来"卡住"的核心 bug。 + +--- + +### 9. 模型切换(质量: 中) + +**文件**: `webview/lib/models.ts`, `webview/components/ModelPicker.tsx` + +- `MODELS` 硬编码 5 个条目 (models.ts:3-30),但运行时从 `initialize` 响应拿到的 `sessionModels` 会覆盖 (ModelPicker.tsx:33)。 +- `set_model` 通过 `sendSetModel(modelId)` 正确发送。 + +**缺失**: +- **effort/thinking 档位不可见不可调**:CLI 的 `applied.effort` 支持 `low/medium/high/xhigh/max`(controlSchemas.ts:510),UI 只做 tokens 数字输入(`/think `)不显示档位。 +- **Fast Mode 开关**:`FastModeStateSchema` 存在 (initialize 响应字段 `fast_mode_state`),UI 无切换按钮。 +- **硬编码清单已过时**:列表里没有 `haiku-4-6`、`sonnet-4-7` 等未来型号,应完全依赖 `sessionModels`,保留 hardcode 仅作 fallback。 +- **ModelPicker 下拉无上下文窗口提示**:只显示 `200k` 类 label,但不显示 "1M context (beta)" 等能力标记。 + +**需改文件**: +- `webview/components/ModelPicker.tsx` — 添加 effort 档位子选单。 +- `webview/lib/types.ts` — `ModelInfo` 增加 `capabilities?: string[]`。 +- `src/ChatViewProvider.ts` — 新增 `set_effort` 分发(目前没有 subtype,需要通过 `apply_flag_settings` 实现)。 + +**策略**: UI 端为主 +**优先级**: **P1** + +--- + +### 10. 权限审批(质量: 中) + +**文件**: `webview/components/PermissionCard.tsx` + +**缺失**: +- **忽略 `permission_suggestions` 字段**(controlSchemas.ts:112)。CLI 可以返回"允许此会话"、"允许此命令"、"添加到白名单"等建议选项;当前只有二元 allow/deny。终端 CLI 的权限弹窗是多选项的。 +- **忽略 `blocked_path`、`decision_reason`**(controlSchemas.ts:113-114)— 不显示被阻挡的路径和阻挡原因。 +- **忽略 `agent_id`**(controlSchemas.ts:118)— 不显示是哪个 sub-agent 触发的权限(多-agent 场景下会混乱)。 +- **未按工具类型定制展示**:Edit/Write 应该用 diff 视图(RCS 有),Bash 应当语法高亮,WebFetch 应显示 URL 预览;当前全部是通用 JSON。 +- **无"允许此次/永不再问/仅本会话"三档**:终端 CLI 提供的 `behavior: "allow_once" / "allow_permanent"` 等信息未利用。 + +**需改文件**: +- `webview/components/PermissionCard.tsx` +- `webview/lib/messageParser.ts` — 扩展 `PermissionRequest` 接口提取剩余字段。 +- `webview/lib/types.ts` — `PermissionRequest` 新增 `suggestions?: PermissionUpdate[]`、`blockedPath?`、`decisionReason?`。 + +**策略**: UI 端为主 +**优先级**: **P0** — 直接影响安全决策质量。 + +--- + +### 11. 上下文使用(质量: 中) + +**文件**: `webview/components/ContextUsageBar.tsx`, `App.tsx:233-255` + +**缺失**: +- `SDKControlGetContextUsageResponseSchema` (controlSchemas.ts:205-306) 返回 15+ 个字段:`gridRows`、`memoryFiles`、`mcpTools`、`deferredBuiltinTools`、`systemTools`、`systemPromptSections`、`agents`、`slashCommands`、`skills`、`messageBreakdown`、`apiUsage`、`autoCompactThreshold`、`isAutoCompactEnabled` 等。 +- 当前 UI 只显示"总百分比"和几行 categories(作为 system 消息文本),完全没有可视化。 +- `ContextUsageBar` 基于 `usage.input + usage.output / maxTokens` 计算,但 `maxTokens` 用的是 hardcoded model map,不是 CLI 实际返回的 `rawMaxTokens`/`maxTokens`,会在 1M context beta 场景下完全错误。 +- 无 auto-compact 阈值可视化。 + +**需改文件**: +- `webview/components/ContextUsageBar.tsx` — 重写为完整的分类堆叠条 + 悬停明细。 +- 新增 `webview/components/ContextBreakdownDialog.tsx` — 类似终端 `/context` 命令的网格视图。 + +**策略**: UI 端 +**优先级**: **P1** + +--- + +### 12. MCP 状态(质量: 低) + +**文件**: `App.tsx:187-206` + +**缺失**: +- 只渲染为 system 消息的文本列表。没有独立面板/侧栏。 +- 无 reconnect/toggle/重启按钮(尽管 CLI 已支持 `mcp_reconnect`、`mcp_toggle` subtype)。 +- 无每服务器的工具列表下钻。 +- 无 stderr/错误详情展开。 + +**需改文件**: +- 新增 `webview/components/McpPanel.tsx`。 +- `src/ChatViewProvider.ts` — 分发 `mcp_reconnect`/`mcp_toggle` 消息。 +- `src/CLIProcess.ts` — 新增 `sendMcpReconnect(name)`、`sendMcpToggle(name, enabled)` 封装。 + +**策略**: 两端 +**优先级**: **P2** + +--- + +### 13. 斜杠命令(质量: 低) + +**文件**: `src/ChatViewProvider.ts:186-410` + +**已真实触发**: `/model`、`/config`、`/settings`、`/permissions`、`/mcp`、`/context`、`/agents`、`/clear`、`/interrupt`、`/help`、`/status`、`/think`。 + +**占位/错误处理**: +- `/doctor`、`/hooks`、`/status-line`、`/terminal-setup` — 直接返回"需要终端"(L364-378)。 +- `/login`、`/logout` — 同上。 +- `/bug` — 返回 GitHub issue 链接(L394-405)。 +- `/compact` — 在 `/help` 里列出了,但 **没有实现**,用户输入会直接 fall through 到 CLI 作为普通 prompt。 +- `/cost` — `/help` 列出,**未实现**。 +- `/poor`、`/fast`、`/vim`、`/review`、`/memory`、`/bashes` — `/help` 列出,**未实现**。 +- 动态斜杠命令(来自 plugins / reload_plugins 响应)虽然能出现在菜单中,但**它们的 arg 补全、模板、注入文案**(例如 skill-specific 的参数表单)全部没有。 + +**需改文件**: +- `src/ChatViewProvider.ts` — 把 `/compact` 路由到 `sendControlRequest("compact")`(需检查 CLI 是否有该 subtype,目前 SDK schema 中无;可改为发送 `/compact` 作为 user_input 由 CLI 的斜杠命令路由器处理)。 +- `/cost` 同样应作为 user_input 透传到 CLI(CLI 内部有处理)。 +- 把 "not supported" 占位改为 "fallback 到 user_input 透传"—— CLI 收到 `/compact` 等命令时有自己的处理逻辑。 + +**策略**: CLI 端(透传)+ UI 端(文档化支持列表) +**优先级**: **P0** — `/compact` 对长对话必不可少。 + +--- + +### 14. 快捷键(质量: 低) + +**文件**: `webview/components/PromptInput.tsx:51-77`, `package.json:63-86` + +**已支持**: +- Enter 发送、Shift+Enter 换行、Esc 中断(同一菜单可关闭菜单)。 +- VSCode 原生快捷键:Ctrl+Escape focus、Ctrl+Shift+N new chat、Ctrl+Shift+L 发送选区。 + +**缺失**: +终端 CLI 默认绑定(`src/keybindings/defaultBindings.ts`)有下列关键项在 VSCode 扩展中完全缺失: + +| 快捷键 | 终端 CLI 动作 | VSCode 扩展状态 | +|--------|---------------|----------------| +| `Shift+Tab` | cycleMode(default/plan/acceptEdits/bypass) | ❌ 缺失 — 极其高频 | +| `Esc Esc` 双击 | 回滚到上一 user message + rewind 文件 | ❌ 缺失 | +| `Ctrl+R` | history:search | ❌ 缺失 | +| `Ctrl+O` | toggleTranscript / verbose | ❌ 缺失 | +| `Ctrl+T` | toggleTodos | ❌ 缺失 | +| `Ctrl+G` / `Ctrl+X Ctrl+E` | externalEditor(大段输入) | ❌ 缺失 | +| `Ctrl+S` | chat:stash(暂存当前草稿) | ❌ 缺失 | +| `Ctrl+_` / `Ctrl+Shift+-` | undo(回滚到上轮) | ❌ 缺失 | +| `Up / Down` | history:previous/next | ❌ 缺失 — prompt 历史导航 | +| `Alt+V` (Win) / `Ctrl+V` | imagePaste | ❌ 缺失(图片功能整体不存在) | +| `Meta+P` | modelPicker | ⚠️ 有 UI 但无快捷键 | +| `Meta+O` | fastMode toggle | ❌ 缺失 | +| `Meta+T` | thinking toggle | ❌ 缺失 | +| `Ctrl+X Ctrl+K` | killAgents | ❌ 缺失 | + +**需改文件**: +- `webview/components/PromptInput.tsx` — 扩展 `handleKeyDown` 处理上述组合键。 +- `packages/vscode-extension/package.json` — `contributes.keybindings` 注册。 +- `src/ChatViewProvider.ts` — 新增对应消息分发。 +- 新增 `webview/hooks/usePromptHistory.ts` — Up/Down 浏览历史 prompt。 + +**策略**: 两端 +**优先级**: **P0**(Shift+Tab)、**P1**(Up/Down/Ctrl+R/Esc Esc)、**P2**(其他) + +--- + +### 15. 状态栏模式显示(质量: 中) + +**文件**: `src/StatusBarManager.ts`, `webview/components/StatusBar.tsx` + +**缺失**: +- 状态栏没有显示当前 **permissionMode**(default / plan / acceptEdits / bypassPermissions)。虽然可以通过 settings.json 配置,但运行时改变(Shift+Tab 切换或 `/permissions xxx` 命令)后用户完全看不到当前模式。 +- 没有显示 **effort 档位**(low/medium/high/xhigh/max)。 +- 没有显示 **fast mode 状态**。 +- 没有显示 **session_id**(用于恢复会话)。 + +**需改文件**: +- `webview/components/StatusBar.tsx` — 新增 mode badge、effort badge。 +- `App.tsx` — 订阅 settings 变更,更新 mode state。 + +**策略**: UI 端 +**优先级**: **P0** + +--- + +### 16. 会话历史(质量: 极低) + +**文件**: `src/HistoryManager.ts`, `ChatViewProvider.ts:164-182` + +**已实现**: +- `HistoryManager` 结构完整(getAll/add/get/remove/clear/getRecent)。 +- `ChatViewProvider` 转发 `get_history` / `save_history` 消息。 + +**缺失**: +- **`HistoryEntry` 从未被 webview 主动 save**—— 搜索 `save_history` 在 webview 侧零调用位置(hooks/useCLI.ts 中 `getHistory` 能发送,但代码里从未调用,也没有 `saveHistory` 封装)。历史永远是空的。 +- **UI 侧完全没有历史面板/侧栏**。RCS 有 `SessionSidebar.tsx` 按今天/昨天/更早分组,VSCode 零实现。 +- **无法恢复已结束会话** — `newChat()` 直接 kill 旧 CLI 启新的,没传 `--resume `。 +- `--session-id` / `--continue` CLI 参数未使用。 + +**需改文件**: +- 新增 `webview/components/HistorySidebar.tsx`。 +- 新增 `webview/hooks/useHistory.ts`。 +- `src/CLIProcess.ts` — `start()` 接受可选 `sessionId` 参数,传 `--resume ` 或 `--continue`。 +- `src/ChatViewProvider.ts` — 自动在 `result` 或 streaming done 后 `save_history`。 +- `webview/hooks/useCLI.ts` — 新增 `saveHistory` 封装。 + +**策略**: 两端 +**优先级**: **P1** + +--- + +### 17. VSCode 编辑器集成(质量: 中) + +**已实现**: 右键菜单发送选区/文件、侧边栏新聊天、Ctrl+Shift+L 发送选区。 + +**缺失**: +- **@ 文件引用**:PromptInput 没有识别 `@filename` 的 autocomplete(RCS 虽然也没做,但终端 CLI 有)。 +- **Diff/编辑审计**:当 CLI 建议的 Edit 执行后,没有自动打开 VSCode 的 diff 视图让用户审阅(虽然 `applyDiff` 有极简实现,但不主动触发)。`ExitPlanMode` 的 plan 也无 VSCode diff 预览。 +- **上下文自动同步**:VSCode 活跃编辑器变化时不会通知 CLI(终端 CLI 有 `selection_changed` / `active_file_changed` IDE integration hook)。 +- **`ide-mcp` / IDE integration hook**:`src/hooks/useIDEIntegration.tsx` 存在,VSCode 扩展却没有作为 IDE 端接入它(应该作为 MCP server 暴露 `getOpenTabs`、`getDiagnostics`、`applyEdits` 等工具给 CLI)。 +- **诊断信息**:`mcp__ide__getDiagnostics` 是标准 IDE MCP 协议,扩展没有启动该 MCP server。 +- **多编辑器 tab 追踪**。 + +**需改文件**: +- 新增 `src/IdeMcpServer.ts` — 在扩展进程中起一个 MCP server,CLI 通过 stdio 或 unix socket 连接。 +- `src/CLIProcess.ts` — 启动时自动注册 `mcp_set_servers`,把 IDE MCP server 注入 CLI。 +- `webview/components/PromptInput.tsx` — 识别 `@` 触发文件 picker(用 `vscode.workspace.findFiles`)。 + +**策略**: 两端(特别是 MCP server 实现) +**优先级**: **P1** + +--- + +## ❌ 完全缺失 (需要新增) + +### 18. 图片/文件附件(多模态) + +**当前状态**: webview 完全没有图片/附件 UI;PromptInput 没有 paste 处理;CLIProcess 的 `sendUserMessage` 只发送纯文本 (CLIProcess.ts:272-282)。 + +**Anthropic API 支持**: `content` 数组可包含 `{type: "image", source: {type: "base64", media_type, data}}`。 + +**RCS 实现参考**: `packages/remote-control-server/web/components/chat/ChatInput.tsx:117-138` 有完整 paste/file upload/压缩/预览/删除。 + +**需新增文件**: +- `webview/components/ImageAttachment.tsx` — 缩略图预览 + 删除按钮。 +- `webview/lib/imageUtils.ts` — paste 事件处理 + base64 编码 + 压缩(可用 `browser-image-compression`)。 +- `src/CLIProcess.ts` — 修改 `sendUserMessage(text, images?)` 支持多模态 content 数组。 +- `src/EditorBridge.ts` — 新增 `getImageFromClipboard()` 方法(可用 `vscode.env.clipboard.readImage()` — 注意 VSCode API 本身不直接支持,需用临时文件)。 + +**策略**: 两端 +**优先级**: **P0** — 多模态是基础功能。 + +--- + +### 19. Plan 可视化(ExitPlanMode/Todos) + +**当前状态**: 零实现。CLI 的 `ExitPlanModeV2Tool`、`TaskCreateTool`、`TaskUpdateTool`、`TaskListTool` 会产生结构化 plan 数据,但 VSCode 扩展把它们当作普通 `tool_use` 渲染。 + +**RCS 实现参考**: `packages/remote-control-server/web/components/chat/PlanView.tsx` (143 行)— 带进度条、状态图标、优先级徽章的完整 UI。 + +**CLI 协议**: `session/update plan` 消息类型(ACP 协议),以及 `update_plan` subtype。 + +**需新增文件**: +- `webview/components/PlanView.tsx` — 复刻 RCS 版本。 +- `webview/components/TodosPanel.tsx` — 持久化 Todo 列表侧栏。 +- `webview/lib/messageParser.ts` — 识别 tool_use 中 `name === "ExitPlanModeV2" / "TaskCreate" / "TaskUpdate"` 并派发特殊 action。 +- `webview/lib/types.ts` — 新增 `PlanEntry`、`TodoItem` 类型。 + +**策略**: UI 端(CLI 输出已够用) +**优先级**: **P0** — plan/todos 是 Claude Code 的核心工作流。 + +--- + +### 20. Shift+Tab 模式循环 / PermissionMode 运行时切换 + +**当前状态**: permissionMode 只能通过 VSCode settings.json 配置,或 `/permissions plan` 等命令手动切换,**且需要重启 CLI 才生效**(因为是启动参数)。 + +**终端 CLI**: Shift+Tab 循环 default → plan → acceptEdits → bypassPermissions,热切换,不重启。 + +**需新增文件**: +- `webview/components/ModeBadge.tsx` — 显示当前模式,点击循环。 +- `webview/components/PromptInput.tsx` — 绑定 Shift+Tab 触发循环。 +- `src/ChatViewProvider.ts` — 使用 `sendSetPermissionMode` 热切换(已有方法 CLIProcess.ts:351-353)。 +- `src/extension.ts` — 注册 `ccb.cycleMode` 命令。 + +**策略**: 两端,但 CLI 侧已就绪 +**优先级**: **P0** + +--- + +### 21. 转录/滚动/搜索/导航 + +**当前状态**: `MessageList.tsx` 只有自动滚动到底部(MessageList.tsx:21-41)。 + +**缺失**: +- **搜索**:无 Ctrl+F 搜索消息内容。 +- **消息导航**:无上一条/下一条 user message 跳转(终端 CLI 的 Ctrl+Up/Down)。 +- **折叠/展开长消息**:无长消息折叠。 +- **时间轴/分段**:无"今天/昨天"分隔。 +- **复制整条消息**:无消息级复制按钮(只有 CodeBlock 内有 Copy)。 +- **重试**:无"重发此 prompt"按钮。 +- **编辑 user message + fork 对话分支**:无。 +- **transcript 导出**:无"复制到剪贴板 / 保存为 markdown"功能。 +- **verbose 切换**:无 Ctrl+O 对应的原始 JSON 查看模式。 + +**需新增文件**: +- `webview/components/TranscriptSearch.tsx`。 +- `webview/components/MessageActionsMenu.tsx`(悬浮在每条消息上的编辑/重试/复制/删除)。 +- `webview/hooks/useMessageNavigation.ts`。 + +**策略**: UI 端 +**优先级**: **P2**(搜索)、**P1**(编辑+重试+复制) + +--- + +### 22. Rewind / Esc Esc 文件回滚 + +**当前状态**: CLI 的 `SDKControlRewindFilesRequestSchema` (controlSchemas.ts:308) 支持回滚到指定 user_message_id + dry_run 预览,VSCode 扩展**完全未实现**。 + +**需新增**: +- 消息编辑菜单中 "Rewind to here" 按钮。 +- `webview/hooks/useCLI.ts` — 新增 `rewindFiles(userMessageId, dryRun)` 。 +- `src/CLIProcess.ts` — 新增 `sendRewindFiles` 封装。 +- `src/ChatViewProvider.ts` — 处理 `rewind_files` 响应(显示文件变更列表 + 二次确认)。 + +**策略**: 两端 +**优先级**: **P1** + +--- + +### 23. Hook 系统 / 用户自定义 hooks + +**当前状态**: CLI 支持 `SDKControlInitializeRequestSchema` 接受 `hooks` 配置 (controlSchemas.ts:62)、`SDKHookCallbackRequestSchema` 回调 (L363)。VSCode 扩展的 `sendInitialize` 传空对象,**不注册任何 hook**。 + +**影响**: +- 无法实现 VSCode 侧的 PreToolUse/PostToolUse(比如"Edit 后自动 prettier")。 +- 无法把 VSCode 的 Problems panel 作为 PostToolUse hook 反馈给 CLI。 + +**需新增**: +- `src/hookRegistry.ts` — 管理用户配置的 VSCode 特有 hooks。 +- `src/ChatViewProvider.ts` — 在 `sendInitialize` 时传入 hooks 配置,监听 `hook_callback` 请求并响应。 + +**策略**: 两端 +**优先级**: **P2** + +--- + +### 24. Elicitation(MCP 用户输入请求) + +**当前状态**: CLI 的 `SDKControlElicitationRequestSchema` (controlSchemas.ts:522) 用于 MCP server 反向请求用户填表单 / 打开 URL 认证。VSCode 扩展不处理 → **MCP OAuth / MCP 用户表单全部卡死**。 + +**需新增**: +- `webview/components/ElicitationDialog.tsx` — 动态表单渲染(基于 `requested_schema`)/ URL 跳转。 +- `src/ChatViewProvider.ts` — 捕获 elicitation 请求 + 回传 action=accept/decline/cancel + content。 + +**策略**: 两端 +**优先级**: **P1**(MCP OAuth 场景高频) + +--- + +### 25. Agent 列表面板 + 任务状态 + +**当前状态**: `initialize` 响应的 `agents` 数组只存在 `state.sessionAgents` 里,**UI 从未展示**。 + +**需新增**: +- `webview/components/AgentsPanel.tsx` — 展示可用 agents,点击触发 `TaskCreateTool`。 +- `webview/components/TaskStatusPanel.tsx` — 展示 running sub-agent 任务。 + +**策略**: UI 端 +**优先级**: **P2** + +--- + +### 26. 图片/diff 视图 + VSCode diff editor 集成 + +**当前状态**: `applyDiff` 只提取 `+` 行插入 (EditorBridge.ts:48-71),**完全不是真正的 diff apply**。 + +**需新增**: +- 使用 `vscode.commands.executeCommand('vscode.diff', leftUri, rightUri)` 打开真正的 diff 视图。 +- 在 Edit 工具 result 中提取 before/after,自动弹 diff 让用户审阅后应用。 + +**策略**: VSCode 端为主 +**优先级**: **P1** + +--- + +### 27. Keep-alive / 长连接健康 + +**当前状态**: 扩展不发送 `{type: "keep_alive"}` 消息,CLI 也不处理。长时间 idle 的会话可能被系统级看门狗杀死。 + +**需新增**: `src/CLIProcess.ts` — 每 30s 发 keep_alive。 + +**优先级**: **P2** + +--- + +### 28. 成本/用量累计视图 + +**当前状态**: 只显示最后一轮的 `result.usage`。 + +**缺失**: +- 整个 session 累计 token/cost。 +- 按 category(input/output/cache/cache_creation)分解。 +- 跨会话历史统计。 + +**需新增**: +- `webview/components/UsageDashboard.tsx`。 +- `src/HistoryManager.ts` — 持久化累计数据。 + +**优先级**: **P2** + +--- + +### 29. MCP OAuth / Login / Logout + +**当前状态**: `/login`、`/logout` 斜杠命令直接拒绝(ChatViewProvider.ts:380-392),提示用户去终端。 + +**问题**: 用户在 VSCode 扩展中完全无法配置账号;首次安装没法开箱即用。 + +**需新增**: +- `webview/components/LoginPanel.tsx` — OAuth 流程(跳浏览器 + token 回填)。 +- `src/ChatViewProvider.ts` — 处理 login 流程(可通过 elicitation 机制走 URL mode)。 + +**优先级**: **P1** + +--- + +### 30. 通知系统 + +**当前状态**: 0 个通知 — 当 CLI 需要权限时(focus 在其他地方),用户毫无感知。 + +**需新增**: +- 使用 `vscode.window.showInformationMessage` 在以下时机触发:权限请求到达、长任务完成、错误。 +- 可配置的通知开关(settings.json)。 + +**优先级**: **P1** + +--- + +### 31. 配置面板(替代 settings.json) + +**当前状态**: 用户只能通过 `settings.json` 改 `ccb.permissionMode`。效率低、可发现性差。 + +**缺失**: +- 无 Webview 内的配置面板(类似 RCS `IdentityPanel.tsx`、`TokenManagerDialog.tsx`)。 +- 无 API provider 切换 UI(OpenAI/Gemini/Grok 兼容层用户不可用)。 +- 无 token budget / poor mode 切换开关。 + +**需新增**: `webview/components/SettingsPanel.tsx`。 + +**优先级**: **P2** + +--- + +## 最严重的 10 个缺口(按影响排序) + +| # | 缺口 | 影响 | 优先级 | 关键文件 | +|---|------|------|--------|----------| +| 1 | **messageParser 不处理 `type: "user"` 消息(tool_result 载体)** | 每次工具调用后结果永不显示,UI 显示"工具在运行中"卡住 | **P0** | `webview/lib/messageParser.ts:176` | +| 2 | **Shift+Tab 模式循环 + 状态栏无模式显示** | 用户完全不知道当前在哪个权限模式,且无法热切换 | **P0** | `webview/components/PromptInput.tsx`, `StatusBar.tsx`, `package.json` | +| 3 | **Plan/Todos 可视化完全缺失** | ExitPlanMode + Task 工具输出全部显示为原始 JSON,工作流核心能力不可用 | **P0** | 新增 `webview/components/PlanView.tsx`、`TodosPanel.tsx` | +| 4 | **图片/附件多模态支持为零** | 用户无法粘贴截图,ChatInput、CLIProcess.sendUserMessage 全部纯文本 | **P0** | `webview/components/PromptInput.tsx`, `src/CLIProcess.ts:272` | +| 5 | **权限卡忽略 suggestions/blocked_path/decision_reason/agent_id** | 用户无法做细粒度决策(只有二元 allow/deny),多 agent 场景信息混乱 | **P0** | `webview/components/PermissionCard.tsx`, `messageParser.ts:291` | +| 6 | **/compact、/cost、/poor、/fast、/review、/memory 等斜杠命令全是占位或 fallthrough** | 长对话无法压缩,成本不可见,budget mode 不可切换 | **P0** | `src/ChatViewProvider.ts:186-410` | +| 7 | **prompt 历史 Up/Down 导航 + Ctrl+R 搜索完全缺失** | 相比终端 CLI 交互效率极低 | **P1** | 新增 `webview/hooks/usePromptHistory.ts`、`webview/components/PromptInput.tsx` | +| 8 | **会话历史 save 从未被调用,历史面板不存在** | `HistoryManager` 写了个空壳,`newChat()` 永远丢失上一会话;无法 `--resume` | **P1** | `src/ChatViewProvider.ts`, 新增 `webview/components/HistorySidebar.tsx` | +| 9 | **Rewind / Esc Esc 文件回滚完全缺失** | 误操作后无法回滚,必须手动 git reset | **P1** | 新增 `src/CLIProcess.ts` sendRewindFiles, MessageActionsMenu | +| 10 | **IDE MCP server 未集成,@ 文件引用、Problems 面板、诊断、真正 diff 视图均无** | VSCode 作为 IDE 的优势几乎被抹掉,和终端 CLI 体验无差 | **P1** | 新增 `src/IdeMcpServer.ts`, 扩展 CLI 启动流程 | + +--- + +## 附录: 协议覆盖度对照表 + +| control_request subtype | CLI 支持 | VSCode 扩展支持 | 说明 | +|------------------------|---------|----------------|------| +| `initialize` | ✅ | ⚠️ 仅空请求 | 未传 hooks/agents/systemPrompt | +| `interrupt` | ✅ | ✅ | | +| `can_use_tool` | ✅ | ⚠️ 部分字段丢失 | suggestions/blocked_path/decision_reason 未解析 | +| `set_permission_mode` | ✅ | ✅ | 但无 UI 触发入口(除 /permissions 命令) | +| `set_model` | ✅ | ✅ | 但 effort 档位缺失 | +| `set_max_thinking_tokens` | ✅ | ✅ | 仅通过 /think 命令 | +| `mcp_status` | ✅ | ✅ | UI 展示弱 | +| `get_context_usage` | ✅ | ⚠️ | 仅利用 5% 字段 | +| `hook_callback` | ✅ | ❌ | | +| `mcp_message` | ✅ | ❌ | | +| `rewind_files` | ✅ | ❌ | | +| `cancel_async_message` | ✅ | ❌ | | +| `seed_read_state` | ✅ | ❌ | | +| `mcp_set_servers` | ✅ | ❌ | 阻碍了 IDE MCP server 注入 | +| `reload_plugins` | ✅ | ⚠️ | 仅 /agents 命令触发,响应处理不完整 | +| `mcp_reconnect` | ✅ | ❌ | | +| `mcp_toggle` | ✅ | ❌ | | +| `stop_task` | ✅ | ❌ | | +| `apply_flag_settings` | ✅ | ❌ | | +| `get_settings` | ✅ | ✅ | | +| `elicitation` | ✅ | ❌ | MCP OAuth 等反向输入场景失效 | + +**覆盖度**: 21 个 subtype 中完整支持 5 个(24%),部分 5 个(24%),完全缺失 11 个(52%)。 + +--- + +## 建议的迭代路线图 + +### Sprint 1 (P0 基线修复) — 1 周 +1. messageParser 处理 `type: "user"` tool_result 消息 [#1] +2. Shift+Tab 模式循环 + 状态栏 mode badge [#2] +3. Plan/Todos 可视化 [#3] +4. PermissionCard 扩展字段 [#5] +5. `/compact`、`/cost` 透传到 CLI [#6 部分] + +### Sprint 2 (P0 补完) — 1 周 +6. 图片粘贴 + 多模态 sendUserMessage [#4] +7. 斜杠命令 fallthrough 重构 [#6 完整] +8. prompt 历史 Up/Down 导航 [#7] + +### Sprint 3 (P1 交互升级) — 2 周 +9. 会话历史侧栏 + resume [#8] +10. Rewind / MessageActionsMenu [#9] +11. IDE MCP server [#10] +12. Login 流程 + 通知 + +### Sprint 4 (P2 增强) — 2 周 +13. ContextBreakdownDialog、UsageDashboard +14. MCP 面板、AgentsPanel、TaskStatusPanel +15. 转录搜索、verbose toggle、消息编辑+fork +16. Elicitation dialog、hook 注册 + +--- + +**审计结束** diff --git a/docs/plans/vscode-ext-keybindings.md b/docs/plans/vscode-ext-keybindings.md new file mode 100644 index 000000000..ec8911441 --- /dev/null +++ b/docs/plans/vscode-ext-keybindings.md @@ -0,0 +1,449 @@ +# Claude Code CLI 快捷键体系研究 + +> 读取型研究报告。目标:让 VSCode 扩展完整复刻 CLI 的快捷键与 REPL 行为。 +> 所有 `file:line` 均为 2026-04-24 `feat/vscode-extension` 分支上的位置。 + +--- + +## 1. 架构速览 + +按键流水线分三层: + +1. **捕获层(Ink framework)** + - `packages/@ant/ink/src/keybindings/*`:通用的 Keybinding DSL、chord 机、Context priority。 + - `KeybindingSetup.tsx`(`KeybindingSetup.tsx:52`):挂载 `ChordInterceptor`,维护 `pendingChord` ref 并提供 1000ms 超时取消(`CHORD_TIMEOUT_MS` at line 29)。 + - `ChordInterceptor`(`KeybindingSetup.tsx:211`)在所有 `useInput` 之前捕获按键,识别 chord 前缀时 `stopImmediatePropagation`。 + +2. **路由层(CLI 默认表)** + - `src/keybindings/defaultBindings.ts` — 所有默认 context + binding 定义(349 行)。 + - `src/keybindings/schema.ts` — 所有合法 action 名 + context 名(Zod schema)。 + - 用户覆盖:`~/.claude/keybindings.json` → `src/keybindings/loadUserBindings.ts`。 + - 用户绑定采用“后者胜出”,可用 `null` 值解绑默认绑定。 + +3. **处理层(具体组件)** + - `useKeybinding(action, handler, { context, isActive })`:单 action 注册。 + - `useKeybindings({ action: handler }, { context, isActive })`:批量。 + - 两个 hook 均定义于 `packages/@ant/ink/src/keybindings/useKeybinding.ts:34`/`:114`。 + - 组件通过 `useRegisterKeybindingContext('Chat')` 把当前 context 注入 activeContexts;Global 永远 fallback。 + +### Context 优先级(高 → 低) + +Resolver 使用 `activeContexts` 数组的出现顺序 —— 组件注册的 context 先于 Global,“最后定义的 binding 胜出”(`resolver.ts:42-50`)。VSCode 扩展里若要复刻,必须维护一个等价的 context 栈。 + +### Chord 行为 + +- 单 chord 如 `ctrl+x ctrl+k`(`chat:killAgents`)、`ctrl+x ctrl+e`(`chat:externalEditor`)。 +- 超时:1000ms 未补全则 chord 取消。 +- 当某个 key 可能成为更长 chord 的前缀时,resolver 返回 `chord_started`,按键被 `stopImmediatePropagation` 吃掉(不会进文本输入)。 +- Escape 在 chord 挂起时 → `chord_cancelled`,按键被吞。 + +### 双击机制(不走 keybinding 系统) + +- `useDoublePress`(`packages/@ant/ink/src/hooks/useDoublePress.ts`,re-exported at `src/hooks/useDoublePress.ts`)。 +- 专用于 **Ctrl+C**、**Ctrl+D** 和 **Esc**,因为需要“第一次 press 也有行为”(interrupt),chord 机阻止首键触发,故走独立 time-window。 + +--- + +## 2. 完整快捷键表 + +### 2.1 Global(全局生效) + +| 触发键 | 上下文 | 作用 | 代码位置 | VSCode 实现策略 | +|-------|---------|-----|---------|---------------| +| `Ctrl+C` | Global | `app:interrupt`(双击退出 / 单击中断任务 / 中断 speculation) | defaultBindings.ts:40; useExitOnCtrlCD.ts:45; useCancelRequest.ts:217 | 必须 forward — 任务中断语义由 CLI 侧的 AbortSignal 决定 | +| `Ctrl+D` | Global | `app:exit`(空输入时双击退出) | defaultBindings.ts:41; useTextInput.ts:171; useExitOnCtrlCD.ts:45 | forward 或本地模拟双击逻辑 | +| `Ctrl+L` | Global | `app:redraw`(Ink forceRedraw — 清屏/恢复) | defaultBindings.ts:42; useGlobalKeybindings.tsx:242 | webview 本地:清屏视图并 refresh | +| `Ctrl+T` | Global | `app:toggleTodos`(切换 todo/task/teammate 列表视图) | defaultBindings.ts:43; useGlobalKeybindings.tsx:55-89 | forward — 改变 AppState.expandedView | +| `Ctrl+O` | Global | `app:toggleTranscript`(进入/退出全屏 transcript) | defaultBindings.ts:44; useGlobalKeybindings.tsx:98 | forward — REPL 状态切换 | +| `Ctrl+Shift+B` | Global | `app:toggleBrief`(KAIROS feature flag 下) | defaultBindings.ts:46; useGlobalKeybindings.tsx:176 | forward(仅 flag 启用时) | +| `Ctrl+Shift+O` | Global | `app:toggleTeammatePreview` | defaultBindings.ts:48; useGlobalKeybindings.tsx:212 | forward | +| `Ctrl+R` | Global | `history:search`(进入 history 搜索模式) | defaultBindings.ts:49; useHistorySearch.ts:237 | webview 本地:打开 history picker UI | +| `Ctrl+Shift+F` / `Cmd+Shift+F` | Global | `app:globalSearch`(QUICK_SEARCH feature) | defaultBindings.ts:54 | webview 本地 | +| `Ctrl+Shift+P` / `Cmd+Shift+P` | Global | `app:quickOpen`(QUICK_SEARCH feature) | defaultBindings.ts:56 | webview 本地 | +| `Meta+J` | Global | `app:toggleTerminal`(TERMINAL_PANEL feature) | defaultBindings.ts:60; useGlobalKeybindings.tsx:227 | forward | + +### 2.2 Chat(Prompt 输入聚焦时) + +| 触发键 | 上下文 | 作用 | 代码位置 | VSCode 实现策略 | +|-------|---------|-----|---------|---------------| +| `Esc` | Chat | `chat:cancel`(取消任务、出队 / 空输入双击清空 / 双击打开 MessageSelector) | defaultBindings.ts:66; useCancelRequest.ts:164; useTextInput.ts:127 (handleEscape); PromptInput.tsx:1655 (doublePressEscFromEmpty) | webview 本地(清空/退 mode)+ forward(取消任务)— 双击 fork 通过 forward | +| `Esc Esc` | Chat(空输入时) | 打开 MessageSelector(Fork from previous message) | PromptInput.tsx:1655-1658, 2344-2348 | forward — 触发后端 `openMessageSelector` 状态 | +| `Ctrl+X Ctrl+K` | Chat | `chat:killAgents`(chord:两次触发停止所有后台 agent) | defaultBindings.ts:68; useCancelRequest.ts:271 | forward(需 chord 状态管理) | +| `Shift+Tab` / `Meta+M`(Windows 无 VT 时) | Chat | `chat:cycleMode`(循环 permission modes: default/acceptEdits/plan/bypassPermissions) | defaultBindings.ts:30, 69; PromptInput.tsx:1837 | forward — 改变 toolPermissionContext.mode | +| `Meta+P` | Chat | `chat:modelPicker`(打开模型选择) | defaultBindings.ts:70; PromptInput.tsx:1813 | forward — 后端维护 UI 状态 | +| `Meta+O` | Chat | `chat:fastMode`(fast mode picker) | defaultBindings.ts:71; PromptInput.tsx:2018 | forward | +| `Meta+T` | Chat | `chat:thinkingToggle`(切换 thinking 模式) | defaultBindings.ts:72; PromptInput.tsx:1829 | forward | +| `Enter` | Chat | `chat:submit`(默认提交) | defaultBindings.ts:73; PromptInput.tsx:1968 (registerHandler) | webview 本地 — 提交走 send | +| `Shift+Enter` / `Meta+Enter` / `Opt+Enter` | Chat | 插入换行 | useTextInput.ts:258-261 | webview 本地(文本域 native 行为) | +| `\` + `Enter`(反斜杠后按回车) | Chat | 吞掉反斜杠并插入 `\n` | useTextInput.ts:252-257 | webview 本地(输入框前处理) | +| `↑` | Chat | `history:previous`(光标首行时翻历史,否则移动光标) | defaultBindings.ts:74; useTextInput.ts:270 (upOrHistoryUp) | webview 本地 + fallback forward 历史请求 | +| `↓` | Chat | `history:next`(类似上面) | defaultBindings.ts:75; useTextInput.ts:294 | webview 本地 + fallback forward | +| `Ctrl+_` | Chat | `chat:undo`(传统终端) | defaultBindings.ts:80; PromptInput.tsx:1708 | webview 本地(undo 栈) | +| `Ctrl+Shift+-` | Chat | `chat:undo`(Kitty protocol) | defaultBindings.ts:81 | webview 本地 | +| `Ctrl+X Ctrl+E` | Chat | `chat:externalEditor`(chord:打开 $EDITOR 编辑 prompt) | defaultBindings.ts:83; PromptInput.tsx:1736 | forward — 只有 CLI 能启动外部编辑器 | +| `Ctrl+G` | Chat | `chat:externalEditor`(单键备选) | defaultBindings.ts:84 | forward | +| `Ctrl+S` | Chat | `chat:stash`(存入/弹出暂存) | defaultBindings.ts:85; PromptInput.tsx:1783 | webview 本地或 forward | +| `Ctrl+V`(非 Windows) / `Alt+V`(Windows) | Chat | `chat:imagePaste`(从剪贴板贴图) | defaultBindings.ts:15, 87; PromptInput.tsx:1936 | forward — 需要读系统剪贴板 | +| `Shift+↑` | Chat | `chat:messageActions`(MESSAGE_ACTIONS feature — 进入消息操作光标) | defaultBindings.ts:89; PromptInput.tsx:2012 | forward | +| `Space`(按住) | Chat | `voice:pushToTalk`(VOICE_MODE feature) | defaultBindings.ts:96; useVoiceIntegration.tsx:383 | forward(需音频权限) | + +### 2.3 Autocomplete(补全菜单可见时) + +| 触发键 | 作用 | 代码位置 | +|-------|-----|---------| +| `Tab` | `autocomplete:accept` | defaultBindings.ts:102; useTypeahead.tsx:1418 | +| `Esc` | `autocomplete:dismiss` | defaultBindings.ts:103; useTypeahead.tsx:1423 | +| `↑` | `autocomplete:previous` | defaultBindings.ts:104 | +| `↓` | `autocomplete:next` | defaultBindings.ts:105 | +| `Ctrl+P` | autocomplete previous(`handleKeyDown` 直接处理,绕过 keybinding 系统) | useTypeahead.tsx:1542 | +| `Ctrl+N` | autocomplete next | useTypeahead.tsx:1536 | + +VSCode 实现:**webview 本地**完全托管,最低延迟。只在接受补全时向 CLI 同步输入值。 + +### 2.4 Transcript(全屏历史视图) + +| 触发键 | 作用 | 代码位置 | +|-------|-----|---------| +| `Ctrl+E` | `transcript:toggleShowAll`(展开/折叠全部消息) | defaultBindings.ts:171; useGlobalKeybindings.tsx:145 | +| `Ctrl+C` / `Esc` / `q` | `transcript:exit` | defaultBindings.ts:172-176; useGlobalKeybindings.tsx:154 | +| `/` | 进入 transcript 搜索模式(类 less) | REPL.tsx:5127 | +| `n` / `N` | 下一个/上一个搜索结果(less-style) | REPL.tsx:5140 | +| `[` | 强制 dump-to-scrollback | REPL.tsx:5186 | +| `v` | 用 $VISUAL/$EDITOR 打开完整 transcript | REPL.tsx:5194 | +| `g` / `G` | 顶部/底部(modal pager) | ScrollKeybindingHandler.tsx:1009-1013 | +| `j` / `k` | line down/up(less-style) | ScrollKeybindingHandler.tsx:1017-1019 | +| `Space` | full page down | ScrollKeybindingHandler.tsx:1023 | +| `b` | full page up | ScrollKeybindingHandler.tsx:1025 | +| `Ctrl+U` | half page up | ScrollKeybindingHandler.tsx:985 | +| `Ctrl+D` | half page down | ScrollKeybindingHandler.tsx:987 | +| `Ctrl+B` | full page up | ScrollKeybindingHandler.tsx:989 | +| `Ctrl+F` | full page down | ScrollKeybindingHandler.tsx:991 | + +### 2.5 Scroll(通用滚动,全屏或 transcript) + +| 触发键 | 作用 | 代码位置 | +|-------|-----|---------| +| `PageUp` | `scroll:pageUp` | defaultBindings.ts:206 | +| `PageDown` | `scroll:pageDown` | defaultBindings.ts:207 | +| 滚轮向上 | `scroll:lineUp` | defaultBindings.ts:208 | +| 滚轮向下 | `scroll:lineDown` | defaultBindings.ts:209 | +| `Ctrl+Home` | `scroll:top` | defaultBindings.ts:210 | +| `Ctrl+End` | `scroll:bottom` | defaultBindings.ts:211 | +| `Ctrl+Shift+C` | `selection:copy`(文本选区复制) | defaultBindings.ts:218 | +| `Cmd+C` | `selection:copy`(Kitty protocol) | defaultBindings.ts:219 | + +### 2.6 HistorySearch(Ctrl+R 激活) + +| 触发键 | 作用 | 代码位置 | +|-------|-----|---------| +| `Ctrl+R` | `historySearch:next` | defaultBindings.ts:182 | +| `Esc` / `Tab` | `historySearch:accept` | defaultBindings.ts:183-184 | +| `Ctrl+C` | `historySearch:cancel` | defaultBindings.ts:185 | +| `Enter` | `historySearch:execute` | defaultBindings.ts:186 | + +### 2.7 Settings / Confirmation / FormField / Tabs / Task 等 + +这些 context 内部绑定详见 `defaultBindings.ts:108-348`。典型: + +- **Confirmation**(权限弹窗):`Enter`=`confirm:yes`, `Esc`=`confirm:no`, `↑/↓`=prev/next, `Tab`=nextField, `Space`=toggle, `Shift+Tab`=cycleMode, `Ctrl+E`=toggleExplanation, `Ctrl+D`=permission:toggleDebug。 +- **Settings**:`/`=search, `r`=retry, `Enter`=close (save), `Space`=toggle, `j/k`=nav, `Ctrl+P/N`=nav。 +- **Task**(前台 bash/agent 运行时):`Ctrl+B`=`task:background`(tmux 用户需按两次)。 +- **ThemePicker**:`Ctrl+T`=`theme:toggleSyntaxHighlighting`(覆盖 Global 的 toggleTodos)。 +- **MessageSelector**(rewind dialog):`↑/↓/j/k/Ctrl+P/N`=导航, `Shift+K/J`/`Ctrl+Up/Down`/`Meta+Up/Down`=jump to top/bottom, `Shift+↑/↓`=同。 +- **DiffDialog**:`←/→` prev/next source;`↑/↓` prev/next file;`Enter`=viewDetails;`Esc`=dismiss。 +- **ModelPicker**:`←/→` effort 加减;`Space`=toggle1M。 +- **Attachments**(图片附件导航):`←/→` prev/next;`Backspace`/`Delete`=remove;`↓`/`Esc`=exit。 +- **Footer**(底栏 task/team/diff/loop 指示器):`↑/↓` + `Ctrl+P/N`, `←/→` prev/next, `Enter`=openSelected, `Esc`=clearSelection。 + +### 2.8 Readline-style 文本编辑(Chat 输入框内,不走 keybinding 系统) + +`src/hooks/useTextInput.ts:225-246`: + +| 键 | 作用 | +|----|-----| +| `Ctrl+A` | startOfLine | +| `Ctrl+B` | 左移一格 | +| `Ctrl+E` | endOfLine | +| `Ctrl+F` | 右移一格 | +| `Ctrl+H` | deleteTokenBefore / backspace | +| `Ctrl+K` | kill to line end | +| `Ctrl+N` | 下行/历史下 | +| `Ctrl+P` | 上行/历史上 | +| `Ctrl+U` | kill to line start | +| `Ctrl+W` | killWordBefore | +| `Ctrl+Y` | yank(粘贴 kill ring) | +| `Meta+B` | 前一个词 | +| `Meta+F` | 下一个词 | +| `Meta+D` | deleteWordAfter | +| `Meta+Y` | yankPop | +| `Meta+Backspace`/`Ctrl+Backspace` | killWordBefore | +| `Home`/`End` | 行首/行尾 | +| `Ctrl+←` / `Meta+←` / `Fn+←` | prevWord | +| `Ctrl+→` / `Meta+→` / `Fn+→` | nextWord | + +**注意**:这些绑定在 `useTextInput` 内部通过 `mapKey()` 直接派发,不经过 keybinding 系统,因此 **用户无法通过 `keybindings.json` 改这些**。 + +--- + +## 3. 输入触发器(非按键型) + +输入内容首字符或内联字符触发的行为,定义在 `src/components/PromptInput/inputModes.ts` 以及 `src/hooks/useTypeahead.tsx`: + +### 3.1 `/` — Slash command + +- 触发:输入以 `/` 开头时触发 slash-command 补全(`src/utils/suggestions/commandSuggestions.ts:561`,`findSlashCommandPositions`)。 +- 提交:REPL.tsx:3848 直接识别 `input.trim().startsWith('/')`,命中命令走 `processSlashCommand`。 +- Transcript 内 `/` 激活搜索(REPL.tsx:5127)。 + +### 3.2 `!` — Bash mode + +- 触发:在空输入光标位置敲 `!`,`isInputModeCharacter(input)` 返回 true(inputModes.ts:31),切换到 `bash` mode。 +- 提交:`mode === 'bash'` 时走 `processBashCommand`(processUserInput.ts:520)。 +- 显示:左下角 `PromptInputModeIndicator.tsx` 显示红色 `!`。 + +### 3.3 `@` — File/agent mention + +- 触发:输入 `@` 后跟路径字符,正则 `HAS_AT_SYMBOL_RE`(useTypeahead.tsx:55)匹配后触发文件补全。 +- 特殊:支持 CJK/fullwidth 字符(`\p{L}\p{N}\p{M}`)。 +- 支持 `@file#L10-L20` 行范围(PromptInput.tsx:1691)。 +- IDE 发来的 at-mention 走 `useIdeAtMentioned`(src/hooks/useIdeAtMentioned.ts)。 + +### 3.4 `#` — **不是** 输入模式触发器 + +搜索代码后确认 `#` 不在 `isInputModeCharacter` 中。`#` 仅: +- 在 Slack channel 补全正则 `HASH_CHANNEL_RE`(useTypeahead.tsx:56)中作为 slack 频道前缀。 +- 内存命令通过 `/memory` slash command 调用(`src/commands/memory/memory.tsx` 和 `src/components/memory/MemoryFileSelector.tsx`)。 +- 没有“以 `#` 开头提交 = 记入 CLAUDE.md” 的直接行为(和早期版本不同,已改为走 `/memory` 命令)。 + +### 3.5 `?` — Help toggle + +- onChange 入口 PromptInput.tsx:1142:`if (value === '?')` 切换 helpOpen 状态。 +- 必须是整个输入都是 `?`(即单独打一个问号)才触发。 + +--- + +## 4. 特殊模式 + +### 4.1 Esc+Esc Fork(重点) + +在 **Chat 空输入**状态下连续两次 Esc: + +1. 第一次 Esc:`handleEscape`(useTextInput.ts:127)双击器触发 "show=true" 阶段 → 显示 "Esc again to clear" 通知(原值非空时);若原值为空,showMessage 阶段 no-op。 +2. 第二次 Esc 在 1 秒内: + - 若原输入非空 → 清空 input + 入历史记录。 + - 若原输入为空 **且** `messages.length > 0` **且** 不 isLoading → `doublePressEscFromEmpty()`(PromptInput.tsx:1655, 2344-2348)→ 调用 `onShowMessageSelector()` → 打开 fork-from-previous-message 对话框。 + +代码路径: +``` +PromptInput.tsx:2344-2348 → doublePressEscFromEmpty → onShowMessageSelector +REPL.tsx:4393 handleShowMessageSelector → setIsMessageSelectorVisible(true) +REPL.tsx:6249 +``` + +### 4.2 Ctrl+C 双击退出 + +`useExitOnCtrlCD`(src/hooks/useExitOnCtrlCD.ts:45): +- 第一次 Ctrl+C:显示 "Press Ctrl-C again to exit"。 +- 第二次在 `DOUBLE_PRESS_TIMEOUT_MS` 内:调用 `useApp().exit()`。 +- **但如果有正在运行的任务**(`abortSignal` active):第一次 Ctrl+C 先中断任务(`useCancelRequest.ts:217`),不进入双击流程。 +- **且 speculation 运行中**:抢先调用 `abortSpeculation`(PromptInput.tsx:2078)。 + +### 4.3 Ctrl+D 双击退出 + +- `useTextInput.ts:171 handleCtrlD`: + - 输入非空 → 向前删(iPython-style)。 + - 输入为空 → `handleEmptyCtrlD` 双击 → 退出。 + +### 4.4 Ctrl+X chord 家族 + +通过 `ctrl+x` 作为 chord prefix 避开 readline 编辑键: +- `Ctrl+X Ctrl+K` → kill agents(两次确认) +- `Ctrl+X Ctrl+E` → 外部编辑器(readline-native 绑定) + +Chord 超时 1000ms;Esc 取消。 + +### 4.5 Bash/Memory/Orphaned-permission/Task-notification mode + +`PromptInputMode` 联合类型(`src/types/textInputTypes.ts:265`): +- `'prompt'` | `'bash'` | `'orphaned-permission'` | `'task-notification'` +- `bash` 通过输入 `!` 进入;`Backspace` 退出(`onChange` 中 `mode !== 'prompt' && input === ''` 的分支)。 +- 其余两个由系统事件触发,不是用户按键。 + +### 4.6 Transcript 搜索(类 less) + +- `/` 进搜索输入条 → 输入 → Enter 关闭条但保留高亮。 +- `n`/`N` 跳转下一个/上一个匹配。 +- `Esc`/`q`/`Ctrl+C` 退 transcript。 + +--- + +## 5. VSCode 扩展实现指南 + +### 5.1 必须在 webview 本地处理的(响应速度要求) + +**原则**:所有与"正在输入文本"直接相关的按键必须在 webview 中同步处理,延迟 <16ms。 + +1. **Readline 编辑类**(Ctrl+A/B/E/F/H/K/N/P/U/W/Y + Meta 族) + - 直接在输入框组件的 `keydown` handler 里实现。 + - 参考 `src/hooks/useTextInput.ts` 中 `handleCtrl` / `handleMeta` / `mapKey` 的派发表。 + - 需维护 kill ring(状态:`killRing: string[]`)。 + +2. **Autocomplete 导航**(Tab/Esc/↑/↓/Ctrl+P/N) + - 建议本地维护建议列表并在 webview 内循环,通过 `@mention` / `/command` 补全 API 向后端请求候选。 + +3. **Enter / Shift+Enter / Meta+Enter 分歧** + - 单 Enter = submit;Shift/Meta/Opt+Enter = 换行。 + - `\` + Enter = 删反斜杠插换行(可选实现)。 + +4. **↑/↓ 历史导航 fallback** + - 多行输入时先尝试光标移动,到尽头再走历史 — 本地光标逻辑决定。 + - 历史数据需从 CLI 侧同步(startup 时拉一次 + 新提交时 append)。 + +5. **Esc 清空 / Esc Esc clear**(单键第一次不清空,仅显示提示,1000ms 窗口内第二次才清空) + - 本地维护 DoublePress 状态机。 + +6. **输入触发器匹配**(`/`, `!`, `@` 首字符检测 + 正则 `HAS_AT_SYMBOL_RE` / `AT_TOKEN_HEAD_RE`) + - 正则照抄 useTypeahead.tsx:51-56。 + +7. **Modal pager 键**(transcript 视图下的 g/G/j/k/Space/b/Ctrl+U/D/B/F) + - 通常 VSCode 扩展会把 transcript 作为 webview 内的滚动视图,这些键直接映射到 scrollBy。 + +### 5.2 通过 package.json `contributes.keybindings` 注册的 + +**原则**:需要在 VSCode 窗口级触发(而非只在 webview 聚焦时)或要求用户可自定义的全局快捷键。 + +```json +{ + "contributes": { + "keybindings": [ + { "command": "claudeCode.toggleTranscript", "key": "ctrl+o", "when": "claudeCode.active" }, + { "command": "claudeCode.toggleTodos", "key": "ctrl+t", "when": "claudeCode.active" }, + { "command": "claudeCode.interrupt", "key": "ctrl+c", "when": "claudeCode.focused && claudeCode.running" }, + { "command": "claudeCode.exit", "key": "ctrl+d", "when": "claudeCode.focused && !claudeCode.hasInput" }, + { "command": "claudeCode.redraw", "key": "ctrl+l", "when": "claudeCode.focused" }, + { "command": "claudeCode.historySearch", "key": "ctrl+r", "when": "claudeCode.inputFocused" }, + { "command": "claudeCode.cycleMode", "key": "shift+tab", "when": "claudeCode.inputFocused" }, + { "command": "claudeCode.modelPicker", "key": "alt+p", "when": "claudeCode.inputFocused" }, + { "command": "claudeCode.thinkingToggle", "key": "alt+t", "when": "claudeCode.inputFocused" }, + { "command": "claudeCode.fastMode", "key": "alt+o", "when": "claudeCode.inputFocused" }, + { "command": "claudeCode.imagePaste", "key": "ctrl+v", "mac": "cmd+v", "when": "claudeCode.inputFocused" }, + { "command": "claudeCode.imagePaste", "key": "alt+v", "win": "alt+v", "when": "claudeCode.inputFocused && isWindows" }, + { "command": "claudeCode.externalEditor", "key": "ctrl+g", "when": "claudeCode.inputFocused" }, + { "command": "claudeCode.stash", "key": "ctrl+s", "when": "claudeCode.inputFocused" } + ] + } +} +``` + +**chord 注意**:VSCode 支持 chord 语法 `"ctrl+x ctrl+k"`。 + +### 5.3 通过 control_request 转发给 CLI 的 + +**原则**:行为依赖 CLI 的运行时状态(tasks、modes、permissions)或副作用只能在 CLI 侧发生。 + +| 快捷键 / 动作 | 原因 | 建议 control_request action | +|--------------|-----|---------------------------| +| `app:interrupt` (Ctrl+C in task) | 需要 abort AbortSignal + 清 toolUseConfirmQueue | `interrupt` | +| `app:exit` (Ctrl+D 双击) | 整个进程退出 | `exit` | +| `chat:cancel` (Esc) | 相同 | `cancel` | +| `chat:killAgents` (Ctrl+X Ctrl+K) | 停止后台 agents | `kill_agents` | +| `chat:cycleMode` (Shift+Tab) | 改 toolPermissionContext.mode | `cycle_permission_mode` | +| `chat:modelPicker` / `fastMode` / `thinkingToggle` | 后端管理 overlay 状态 | `toggle_model_picker`/`toggle_fast_mode`/`toggle_thinking` | +| `chat:externalEditor` | 需要 spawn $EDITOR | `open_external_editor` | +| `chat:imagePaste` | 读系统剪贴板 + image resize | `paste_image` | +| `chat:stash` | 配置持久化 hasUsedStash | `stash_prompt` | +| `app:toggleTranscript` / `toggleTodos` / `toggleTeammatePreview` / `toggleBrief` | AppState 切换 | `toggle_view` with payload | +| `history:search` (Ctrl+R) | 历史列表来自 CLI | `start_history_search` | +| `history:previous/next` (↑/↓ at edge) | 从历史缓冲取值 | `history_nav` | +| `Esc Esc` → MessageSelector | 后端 fork 消息树 | `open_message_selector` | +| `voice:pushToTalk` (Space hold) | 音频捕获 | `voice_ptt_down/up` | +| Tool permission `confirm:*` | 权限提示由后端发出 | `permission_response` | +| `task:background` (Ctrl+B) | 后台化运行中任务 | `background_task` | +| `footer:*` / `messageSelector:*` / `diff:*` 等 dialog 内动作 | 纯 UI,但 dialog 由 CLI 创建 | 复用 dialog protocol | + +### 5.4 协议建议 + +- 给 webview 实现一个 `sendKeybindingAction(action: string, context: string)` 接口,直接复用 CLI 的 action 名(`src/keybindings/schema.ts:64-173` 是权威清单,共 ~75 个 action)。 +- 后端侧新增一个 `keybinding-action` control_request 消息类型: + ```json + {"type": "keybinding-action", "action": "chat:cycleMode", "context": "Chat"} + ``` +- 后端在 REPL 主 process 内直接调用 `keybindingContext.invokeAction(action)`(`KeybindingContext.tsx:121-136`),复用现有 handler 注册表,**不需要**改任何业务逻辑。 +- 对于 chord 类(`ctrl+x ctrl+k`),webview 直接发完整 chord string,后端查 bindings 表解析。 + +### 5.5 Chord 状态机(webview 需实现) + +``` +state: { pending: Chord | null, timeoutId: number | null } + +on keydown(key): + if pending: + clearTimeout(timeoutId) + testChord = pending + [key] + if bindings matches testChord fully: + fire action; pending = null + elif bindings has testChord as prefix: + pending = testChord; setTimeout(1000ms, () => pending = null) + else: + pending = null; fall through + else: + if bindings has [key] as prefix of longer chord: + pending = [key]; setTimeout(1000ms, ...) + else: + fire action or fall through +``` + +参考 `packages/@ant/ink/src/keybindings/resolver.ts:166` (`resolveKeyWithChordState`)。 + +### 5.6 用户 overrides + +最好在 VSCode settings 暴露: +```json +{ + "claudeCode.keybindings": [ + { "context": "Chat", "bindings": { "ctrl+k": "chat:modelPicker" } } + ] +} +``` +把这份 config push 给 CLI,让 CLI 的 `loadUserBindings.ts` 合并,或者在 webview 侧单独维护 override 表(两边保持一致)。 + +--- + +## 6. 常见陷阱 + +1. **Ctrl+M === Enter**(`reservedShortcuts.ts:28`)— 终端里两者都是 CR;不要分别绑定。 +2. **Ctrl+C / Ctrl+D 硬编码**(reservedShortcuts.ts:18-26)— 用户 keybindings.json 里绑会被拒绝。 +3. **Alt / Option 在终端 === Meta**(`match.ts:60-78`)— 终端无法区分,配置里 `alt+k` 和 `meta+k` 等价。 +4. **Super (Cmd/Win)** 只在支持 kitty keyboard protocol 的终端上到达 — VSCode webview 没有这个限制,可以正常绑 Cmd。 +5. **Escape quirk**(`match.ts:100; resolver.ts:88`):Ink 在收到 Escape 时会同时置 `key.meta=true`;resolver 专门忽略这个。VSCode 不需要这个 workaround。 +6. **Windows Terminal 的 Shift+Tab**(`defaultBindings.ts:21-30`):没 VT mode 时 shift+tab 收不到,降级成 `Meta+M`。VSCode webview 收得到 shift+tab,直接用。 +7. **Space voice push-to-talk 破坏输入**(`defaultBindings.ts:93-96`):Space 被 `voice:pushToTalk` 吃掉后,Space 不能打入 prompt。VOICE_MODE feature 关闭时不注册。 +8. **`feature()` 不是函数调用**:很多绑定门控在 `if (feature('FLAG'))` 内(Bun compile-time 展开)。VSCode 扩展需要显式读 feature flags 或由后端在 runtime 告知启用了哪些 action。 + +--- + +## 7. 参考文件清单 + +- `packages/@ant/ink/src/keybindings/types.ts` — 类型定义 +- `packages/@ant/ink/src/keybindings/parser.ts` — 字符串 → ParsedKeystroke +- `packages/@ant/ink/src/keybindings/match.ts` — Ink key + input → bindings 匹配 +- `packages/@ant/ink/src/keybindings/resolver.ts` — chord 解析主逻辑 +- `packages/@ant/ink/src/keybindings/KeybindingContext.tsx` — React context + handler registry +- `packages/@ant/ink/src/keybindings/KeybindingSetup.tsx` — ChordInterceptor + 配置加载 +- `packages/@ant/ink/src/keybindings/useKeybinding.ts` — Hook API +- `packages/@ant/ink/docs/08-keybindings.md` — 系统文档 +- `src/keybindings/defaultBindings.ts` — **CLI 默认绑定总表(权威)** +- `src/keybindings/schema.ts` — Zod schema + 所有 action/context 白名单 +- `src/keybindings/reservedShortcuts.ts` — 不可重绑的键 +- `src/keybindings/loadUserBindings.ts` — 用户配置合并逻辑 +- `src/keybindings/KeybindingProviderSetup.tsx` — CLI wrapper +- `src/hooks/useGlobalKeybindings.tsx` — Global context handlers +- `src/hooks/useCancelRequest.ts` — Escape / Ctrl+C / chat:killAgents +- `src/hooks/useExitOnCtrlCD.ts` — 双击退出 +- `src/hooks/useHistorySearch.ts` — Ctrl+R 搜索 +- `src/hooks/useTextInput.ts` — readline 编辑 + Esc double-press +- `src/hooks/useTypeahead.tsx` — 补全 + Tab 行为 +- `src/components/PromptInput/PromptInput.tsx` — Chat handlers 集中注册 +- `src/components/PromptInput/inputModes.ts` — `!` / bash mode 检测 +- `src/components/ScrollKeybindingHandler.tsx` — 滚动 + modal pager +- `src/screens/REPL.tsx` — REPL 根组件(KeybindingSetup 挂载点) diff --git a/docs/plans/vscode-ext-phase2-design.md b/docs/plans/vscode-ext-phase2-design.md new file mode 100644 index 000000000..86ae45810 --- /dev/null +++ b/docs/plans/vscode-ext-phase2-design.md @@ -0,0 +1,185 @@ +# VSCode 扩展 Phase 2 设计 — ACP 协议重构 + +**目标**:用 ACP (Agent Client Protocol) 替换当前 stream-json 实现,闭合 P0 缺口,**完全不修改 `src/commands/`**。 + +参考: +- `docs/plans/vscode-ext-cli-api.md` +- `docs/plans/vscode-ext-keybindings.md` +- `docs/plans/vscode-ext-gap-analysis.md` +- `docs/plans/vscode-ext-reference-impl.md` +- `packages/acp-link/src/server.ts`(spawn + ACP 接线参考) +- `packages/remote-control-server/web/`(UI 层参考,约 50% 可复用) + +--- + +## 架构总览 + +``` +VSCode UI (webview, React) + ↑↓ vscode.postMessage (Bridge Protocol, ProxyMessage/ProxyResponse 同构) +ChatViewProvider (extension host, Node.js) + ↑↓ ACPClient → ClientSideConnection +spawn('claude', ['--acp']) (stdio, ndJsonStream) +``` + +## 模块清单 + +### Extension 端 (`packages/vscode-extension/src/`) +| 文件 | 职责 | +|---|---| +| `extension.ts` | VSCode entry,注册 commands/keybindings | +| `ChatViewProvider.ts` | webview 生命周期 + protocol bridge | +| `ACPClient.ts` (NEW) | 包装 `@agentclientprotocol/sdk` ClientSideConnection | +| `agentSpawner.ts` (NEW) | 解析 CLI 路径 + spawn `claude --acp` | +| `EditorBridge.ts` | 实现 ACP `Client.readTextFile`/`writeTextFile` + diff view + @-mention search + diagnostics | +| `StatusBarManager.ts` | VSCode 状态栏 | +| `HistoryManager.ts` | 本地缓存 sessionId 用于 resume | + +### Webview 端 (`packages/vscode-extension/webview/`) +| 文件 | 职责 | +|---|---| +| `index.tsx` | React entry | +| `App.tsx` | 根组件 | +| `lib/acp/types.ts` (NEW, 移植 RCS) | ACP 类型 | +| `lib/protocol.ts` (NEW) | webview↔extension 协议 | +| `lib/threadReducer.ts` (NEW, 移植 RCS) | session_update → ThreadEntry | +| `lib/types.ts` | UI 类型(ThreadEntry/PendingPermission) | +| `hooks/useACP.ts` (NEW) | 通过 postMessage 连接到 extension | +| `hooks/useChromeStorage.ts` (NEW) | sessionId 持久化 | +| `components/ChatView.tsx` | 消息流 | +| `components/MessageBubble.tsx` | assistant 文本/思考 | +| `components/ToolCallCard.tsx` | tool_call 渲染 (含 diff) | +| `components/PlanView.tsx` (移植 RCS) | Plan 可视化 | +| `components/PermissionPanel.tsx` (移植+增强 RCS) | 权限面板 | +| `components/CommandMenu.tsx` (移植 RCS) | / 触发菜单 | +| `components/ModelPicker.tsx` | 真实模型切换 (`unstable_setSessionModel`) | +| `components/ModeSelector.tsx` (NEW) | 4 模式切换 + Shift+Tab cycling | +| `components/PromptInput.tsx` | 输入 + 图片粘贴 + @ 触发 | +| `components/StatusBar.tsx` | 模型 + 模式 + tokens + cost | + +## Bridge Protocol(webview ↔ extension) + +镜像 RCS `ProxyMessage`/`ProxyResponse`,仅去掉 WebSocket 相关字段。 + +**Webview → Extension** (`type` 前缀 `ext:`): +- `ext:webview_ready` — webview 已就绪 +- `ext:new_session` `{ permissionMode? }` +- `ext:prompt` `{ content: ContentBlock[] }` +- `ext:cancel` +- `ext:permission_response` `{ requestId, outcome }` +- `ext:set_session_model` `{ modelId }` +- `ext:set_session_mode` `{ modeId }` +- `ext:list_sessions` `{ cwd?, cursor? }` +- `ext:load_session` `{ sessionId, cwd? }` +- `ext:resume_session` `{ sessionId, cwd? }` +- `ext:open_file` `{ path, line? }` +- `ext:copy` `{ text }` +- `ext:apply_diff` `{ path, oldText, newText }` +- `ext:send_selection` +- `ext:send_file` +- `ext:find_files` `{ query, requestId }` +- `ext:get_diagnostics` `{ uri?, requestId }` +- `ext:restart_agent` + +**Extension → Webview**: +- `ext:status` `{ connected, agentInfo?, capabilities? }` +- `ext:session_created` `{ sessionId, promptCapabilities?, models?, modes? }` +- `ext:session_update` `{ sessionId, update: SessionUpdate }` +- `ext:prompt_complete` `{ stopReason }` +- `ext:permission_request` `{ requestId, sessionId, options, toolCall }` +- `ext:model_changed` `{ modelId }` +- `ext:mode_changed` `{ modeId }` +- `ext:session_list` `ListSessionsResponse` +- `ext:session_loaded` `{ sessionId, ... }` +- `ext:session_resumed` `{ sessionId, ... }` +- `ext:error` `{ message }` +- `ext:find_files_result` `{ requestId, files }` +- `ext:diagnostics_result` `{ requestId, items }` +- `ext:inject_text` `{ text }` +- `ext:cwd` `{ cwd }` + +## ACP 关键映射 + +| ACP method | 触发 | 协议位置 | +|---|---|---| +| `initialize` | extension 启动后立即调用 | `clientCapabilities.fs.{readTextFile,writeTextFile}=true`,`clientInfo={name:"vscode-ccb", version:"0.3"}` | +| `newSession` | webview `ext:new_session` | `{cwd, mcpServers:[], _meta:{permissionMode}}` | +| `prompt` | webview `ext:prompt` | content blocks | +| `cancel` | webview `ext:cancel` | | +| `unstable_setSessionModel` | `ext:set_session_model` | | +| `setSessionMode` | `ext:set_session_mode` | spec method, ACP 0.19 | +| `loadSession` | `ext:load_session` | history replay | +| `unstable_resumeSession` | `ext:resume_session` | no replay | +| `listSessions` | `ext:list_sessions` | | + +Client 端实现: +- `requestPermission` → 转发 `ext:permission_request`,等待 `ext:permission_response` +- `sessionUpdate` → 转发 `ext:session_update` +- `readTextFile` → `vscode.workspace.fs.readFile` +- `writeTextFile` → `vscode.workspace.fs.writeFile`(进入 VSCode undo stack) +- `createTerminal` → 暂不实现(可降级为 stub) + +## 快捷键体系(package.json + webview) + +VSCode keybindings (package.json contributes.keybindings): +- `ctrl+escape` → `ccb.focus` +- `escape` (focus in chat) → `ccb.cancel` +- `ctrl+shift+n` → `ccb.newChat` +- `ctrl+shift+l` (editor selection) → `ccb.sendSelection` +- `ctrl+shift+m` → `ccb.cycleMode`(手动循环模式,Shift+Tab 替代) + +Webview 内部 (PromptInput key handler): +- `Shift+Tab` → 循环 default→acceptEdits→plan→bypassPermissions +- `Esc` → cancel ongoing +- `Esc Esc` (1s 内) → fork 上一条用户消息(stub) +- `Up`/`Down` (空输入时) → 历史 prompt 导航 +- `Ctrl+R` → 历史搜索 +- `Ctrl+L` → 清屏 +- `Ctrl+C` (空输入双击) → 退出(提示返回 IDE) +- `Tab` → 接受当前 / 补全 +- `/` 触发 → CommandMenu +- `@` 触发 → 文件搜索菜单 +- `Ctrl+T` → 切换 thinking 显示 +- `Ctrl+V` 含图片 → 自动作为 image content 入队 + +## 实现顺序(自顶向下) + +1. **Phase A: 协议层** + - 移植 `lib/acp/types.ts` + - 写 `lib/protocol.ts` + - 写 `src/ACPClient.ts` + `src/agentSpawner.ts` + - 重写 `src/ChatViewProvider.ts` +2. **Phase B: 状态层** + - 写 `lib/threadReducer.ts` + - 写 `hooks/useACP.ts` +3. **Phase C: 核心组件** + - 移植 `PlanView`/`PermissionPanel`/`CommandMenu` + - 重写 `MessageBubble`/`ToolCallCard` + - 重写 `App.tsx`/`PromptInput.tsx` +4. **Phase D: 状态栏 + 模式切换** + - 写 `ModeSelector` + - 重写 `ModelPicker` + `StatusBar` + - 接入 Shift+Tab +5. **Phase E: VSCode 集成** + - `EditorBridge` 实现 readTextFile/writeTextFile + diff view + - `find_files` (`vscode.workspace.findFiles`) + - `get_diagnostics` (`vscode.languages.getDiagnostics`) +6. **Phase F: 多模态 + 历史** + - 图片粘贴 + - resume/load session + - up/down prompt history +7. **Phase G: 验证 + 打包** + +## 兼容性边界 + +- ACP feature flag (`ACP`) 在 build.ts 默认启用 → 已就绪 +- Claude CLI 启动方式:`claude --acp` (`cli.tsx:135-141`) +- ACP SDK 版本:`@agentclientprotocol/sdk@^0.19.0` +- Permission mode 透传:`newSession({_meta:{permissionMode}})` + +## 兜底/降级 + +- 若 agent 不返回 `models` → 隐藏 ModelPicker +- 若不支持 `setSessionMode` → 隐藏 ModeSelector,降级为 settings.json 改 + restart +- 若不支持 `resume_session` → 用本地 HistoryManager 仅记元数据,restart 时新建 session +- 若 readTextFile capability 关闭 → fallback 到 stub diff --git a/docs/plans/vscode-ext-reference-impl.md b/docs/plans/vscode-ext-reference-impl.md new file mode 100644 index 000000000..c464a5450 --- /dev/null +++ b/docs/plans/vscode-ext-reference-impl.md @@ -0,0 +1,375 @@ +# VSCode 扩展 — 项目内同类 UI 实现研究报告 + +研究对象:项目内已有的 Claude Code CLI 表现层实现。目标是把可复用的协议/组件/连接模式抽象出来给 `packages/vscode-extension/` 参考。 + +本次只读研究,覆盖: + +- `packages/remote-control-server/` — 自托管 Web 控制台(React 19 + Vite + Radix UI) +- `packages/acp-link/` — ACP 代理 WebSocket 桥(把 Claude Code 的 stdio ACP agent 暴露成 WS) +- `src/services/acp/` — Claude Code 进程里真正跑 ACP 协议的 agent 实现 +- `src/bridge/` — `claude remote-control` 命令:轮询 Anthropic 官方 bridge API + +## 结论先行:推荐 VSCode 扩展用 ACP 协议对接 CLI + +**推荐用 ACP**(Agent Client Protocol via stdio),复用 `src/services/acp/` 的现成 agent + 搬运 `packages/remote-control-server/web/src/acp/` 的 `ACPClient` / 协议类型到扩展侧 WebView(或 extension 主进程)。 + +三句话理由: + +1. **协议已经为 GUI 设计过**:session/update、tool_call/tool_call_update、permission_request、available_commands_update、plan、current_mode_update、usage_update — 这些事件对应的 UI 渲染代码 RCS Web 已经写好了,**TypeScript 可直接移植到 webview**。 +2. **Claude Code 官方 CLI 带 `claude acp` 子命令**:直接 `spawn('claude', ['acp'])` 就是一个 stdio NDJSON 的 AcpAgent,`extension.ts` 拿 child process 的 stdin/stdout 通过 `@agentclientprotocol/sdk` 的 `ClientSideConnection` 就能对接(`packages/acp-link/src/server.ts` 行 248-286 是现成范例)。 +3. **比 Bridge/Stream-JSON 都轻**:Stream-JSON (`-p --output-format stream-json`) 是单向输出流,没有权限交互、没有 `session/update` 的结构化 tool_call 模型、没有 model/mode 切换;Bridge 是 Anthropic 官方云端轮询协议,需要 OAuth、JWT、`environments-2025-11-01` beta header,对本地 VSCode 扩展毫无意义。 + +备选方案(仅当 ACP 在某场景受限时):把 VSCode 当 RCS 的另一个 Web Client,通过 WS 连 `/acp/ws`;但这额外引入一个服务进程,不建议作为首选。 + +--- + +## RCS Web UI 功能对标表 + +| 功能 | RCS 实现方式 | 代码位置(绝对路径) | VSCode 扩展可复用吗? | +|------|-----------|-------------------|----| +| **启动 CLI 会话** | UI 发 `{type:"connect"}` → acp-link `spawn(AGENT_COMMAND, AGENT_ARGS, {stdio:["pipe","pipe","inherit"]})` → `acp.ClientSideConnection(createClient, ndJsonStream(input,output))` → `connection.initialize({protocolVersion, clientInfo, clientCapabilities:{fs:{readTextFile:true,writeTextFile:true}}})` | `E:\Source_code\Claude-code-bast\packages\acp-link\src\server.ts:223-322` `handleConnect()` | 可直接复用 spawn + ndJsonStream 模板。扩展端把 `AGENT_COMMAND` 换成 `"claude"`、`AGENT_ARGS` 换成 `["acp"]` | +| **创建 session** | UI 发 `{type:"new_session", payload:{cwd, permissionMode}}` → acp-link 把 `permissionMode` 塞进 `_meta` 再 `connection.newSession({cwd, mcpServers:[], _meta:{permissionMode}})` → 返回 `{sessionId, models, modes, configOptions}` | `E:\Source_code\Claude-code-bast\packages\acp-link\src\server.ts:324-357` `handleNewSession()` | 直接复用。注意 `permissionMode` 必须放在 `_meta`,AcpAgent 会从 `params._meta.permissionMode` 取 | +| **模型切换** | UI 调 `client.setSessionModel(modelId)` → 发 `{type:"set_session_model", payload:{modelId}}` → acp-link `connection.unstable_setSessionModel({sessionId, modelId})` → agent 端 `session.queryEngine.setModel(modelId)` → 广播 `model_changed` 事件 | 前端: `packages\remote-control-server\web\src\acp\client.ts:600-605` `setSessionModel()` 后端桥: `packages\acp-link\src\server.ts:552-581` `handleSetSessionModel()` Agent: `src\services\acp\agent.ts:380-391` `unstable_setSessionModel()` | 可直接复用。`modelState` 在 `session_created`/`session_loaded`/`session_resumed` payload 里一次性返回,无需轮询;`useModels` hook 本身也可以照抄 | +| **权限模式切换** | UI 改本地 state(持久化到 `localStorage["acp_permission_mode"]`)→ 下一次 `new_session` 时通过 `_meta.permissionMode` 传给 agent。**切换已有 session 的 mode** 走 `conn.setSessionMode({sessionId, modeId})` 或 `conn.setSessionConfigOption({sessionId, configId:"mode", value})`;agent 收到后 `applySessionMode()` 同步 `modes.currentModeId` 和 `appState.toolPermissionContext.mode`,并回推 `session/update {sessionUpdate:"current_mode_update", currentModeId}` | 前端选择器: `packages\remote-control-server\web\components\ChatInterface.tsx:69-128` `PermissionModeSelector` Agent 同步: `src\services\acp\agent.ts:674-688` `applySessionMode()` ExitPlanMode 特殊流: `src\services\acp\permissions.ts:157-243` `handleExitPlanMode()` | 6 种 mode 枚举 (`default`/`acceptEdits`/`bypassPermissions`/`plan`/`dontAsk`/`auto`) 是 Claude Code 内部定义,直接复用枚举+选择器 UI 即可;bypassPermissions 可用性由 `!IS_ROOT \|\| IS_SANDBOX` 决定 | +| **处理 permission_request** | Agent 端 `createAcpCanUseTool()` 构造 `PermissionOption[]`(Always Allow / Allow / Reject,ExitPlanMode 特殊:bypass/auto/acceptEdits/default/plan)→ `conn.requestPermission({sessionId, toolCall, options})` → acp-link 端 `createClient().requestPermission()` 产生 `requestId`,发 `{type:"permission_request", payload:{requestId, sessionId, options, toolCall}}` 给 UI,Promise 挂起等待 → UI 发 `{type:"permission_response", payload:{requestId, outcome:{outcome:"selected",optionId} \| {outcome:"cancelled"}}}` → acp-link `handlePermissionResponse` 通过 `requestId` 查 `pendingPermissions` 并 resolve Promise → agent 端 optionId 映射回 `{behavior:"allow",updatedInput}` 或 `{behavior:"deny",message}` | 前端: `packages\remote-control-server\web\components\ChatInterface.tsx:200-251` `handlePermissionRequest()` + `632-667` `handlePermissionResponse()` 后端桥: `packages\acp-link\src\server.ts:148-211` `createClient().requestPermission` / `handlePermissionResponse` Agent 映射: `src\services\acp\permissions.ts:40-155` `createAcpCanUseTool()` | 核心协议完全可用。**ACP 的 `requestPermission` 是 JSON-RPC request**(有返回值),SDK 自动处理 requestId 匹配;复用 SDK 后扩展端不需要手动管理 `pendingPermissions` Map | +| **斜杠命令菜单** | Agent 启动 session 时 `sendAvailableCommandsUpdate()` 从 `session.commands`(`getCommands(cwd)` 加载)过滤出 `cmd.type==="prompt" && !cmd.isHidden && cmd.userInvocable!==false`,格式化成 `{name, description, input?:{hint}}` → 发 `session/update {sessionUpdate:"available_commands_update", availableCommands}` → UI 的 `useCommands` hook 订阅 `setAvailableCommandsChangedHandler`,ChatInput 检测到 `/` 前缀打开 `CommandMenu` floating panel(ArrowUp/ArrowDown/Enter 键盘导航 + 前缀过滤) | 推送: `src\services\acp\agent.ts:727-750` `sendAvailableCommandsUpdate()` Client hook: `packages\remote-control-server\web\src\hooks\useCommands.ts` CommandMenu UI: `packages\remote-control-server\web\components\chat\CommandMenu.tsx` ChatInput 联动: `packages\remote-control-server\web\components\chat\ChatInput.tsx:98-149` | CommandMenu 组件约 140 行,纯 React + Tailwind,移植到 webview 要替换图标库(lucide)和样式 tokens,其他直接可用 | +| **消息流渲染** | ACP 统一语义事件 → ChatInterface flat `ThreadEntry[]` 列表(类似 Zed 的 `Vec`),事件处理器根据 last-entry 是否同类进行 append/upsert:`agent_message_chunk` → 续写最近 AssistantMessage 的 `chunks[last].text`;`agent_thought_chunk` → 追加 `{type:"thought",text}`;`tool_call` → 新建 `ToolCallEntry` 或 upsert 已存在;`tool_call_update` → 按 toolCallId 合并 status/content;`plan` → 替换整个 PlanDisplayEntry | 核心: `packages\remote-control-server\web\components\ChatInterface.tsx:253-493` `handleSessionUpdate()` 类型定义: `packages\remote-control-server\web\src\lib\types.ts`(ThreadEntry 联合类型) | React reducer 模式可直接复用;只要 ACP 协议不变,webview 端把状态容器换成 zustand/jotai 就行 | +| **SSE/WebSocket 消息协议** | RCS 实际上有**两套独立协议**:(1) **Web 客户端 ↔ RCS**:`GET /web/sessions/:id/events` SSE 流(`text/event-stream`),`POST /web/sessions/.../events`/`/control`/`/interrupt`(REST),`storeBindSession` 把 session 绑定 uuid。(2) **RCS ↔ acp-link ↔ Agent**:`/acp/ws` NDJSON WebSocket,消息类型见 `ProxyMessage`/`ProxyResponse` 并集;acp-link 端 `relay-handler` 订阅 `getAcpEventBus(channelGroupId).subscribe(...)` 转发 `direction:"inbound"` 的事件给前端,前端发的 `outbound` 事件通过 `sendToAgentWs()` 转发到 agent 的 WS | Web↔RCS SSE: `packages\remote-control-server\src\routes\web\sessions.ts:98-116` + `packages\remote-control-server\web\src\api\sse.ts` Web↔RCS REST: `packages\remote-control-server\src\routes\web\control.ts` ACP WS: `packages\remote-control-server\src\transport\acp-ws-handler.ts` 中继: `packages\remote-control-server\src\transport\acp-relay-handler.ts` | **VSCode 扩展不需要 SSE**;走 ACP stdio 直接就是 NDJSON 双向流。ProxyMessage/ProxyResponse 的 union 类型定义(`packages\remote-control-server\web\src\acp\types.ts`)可**全文复制**到扩展 types 文件,只是把 WebSocket 层换成 stdio | + +--- + +## 可直接复用的代码片段 + +### 1. 协议类型定义(强烈建议整份拷贝) + +**源文件:** `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\src\acp\types.ts`(561 行) + +这份文件完整定义了: + +- `ProxyMessage` / `ProxyResponse` 双向消息 union +- `SessionUpdate` 所有 8 种子类型(`agent_message_chunk` / `agent_thought_chunk` / `user_message_chunk` / `tool_call` / `tool_call_update` / `plan` / `available_commands_update`) +- `ToolCallContent` = `ToolCallContentBlock` | `ToolCallDiffContent` | `ToolCallTerminalContent` +- `ContentBlock` = `TextContent` | `ImageContent` | `ResourceLinkContent` +- `PermissionRequestPayload` / `PermissionResponsePayload` / `PermissionOption` / `PermissionOptionKind` +- `PlanEntry` / `PlanEntryStatus` / `PlanEntryPriority` +- `AvailableCommand` +- `SessionModelState` / `ModelInfo` +- `AgentCapabilities` / `PromptCapabilities` / `SessionCapabilities` +- `AgentSessionInfo` / `ListSessionsResponse` / `LoadSessionRequest` / `ResumeSessionRequest` + +**复用方式**:直接 copy 到 `packages/vscode-extension/src/acp/types.ts`。注意这份文件内所有字段已对齐官方 `@agentclientprotocol/sdk`,若扩展直接依赖 SDK 则可省掉重复定义,只保留 VSCode 扩展与 webview 之间 postMessage 的内部协议类型。 + +### 2. ACPClient 类(WebSocket 版本,stdio 版本需小改) + +**源文件:** `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\src\acp\client.ts`(768 行) + +核心能力: + +- `connect()`/`disconnect()`/`DisconnectRequestedError`(区分"主动断开"和"真正出错") +- `startHeartbeat()` 30 秒 ping,10 秒 pong 超时,连续 2 次丢失断开(webview ↔ host 之间不需要) +- 按事件类型分发:`session_created` → 缓存 `_modelState` / `_promptCapabilities` / `_agentCapabilities`;`session_update` 里 `available_commands_update` → 更新内部 `_availableCommands`;`model_changed` → 改 `_modelState.currentModelId` +- 订阅式 handler:`setConnectionStateHandler` / `setSessionUpdateHandler` / `setPermissionRequestHandler` / `setModelChangedHandler` / `setModelStateChangedHandler` / `setAvailableCommandsChangedHandler` / `setSessionCreatedHandler` / `setSessionLoadedHandler` / `setSessionSwitchingHandler` / `setPromptCompleteHandler` / `setErrorMessageHandler` +- 挂起请求队列:`pendingSessionList` / `pendingSessionLoad` / `pendingSessionResume`,每个都有自己的 timer,断开时统一 reject +- 能力门控:`supportsImages` / `supportsLoadSession` / `supportsResumeSession` / `supportsSessionList` / `supportsSessionHistory` / `supportsModelSelection` getter + +**VSCode 扩展改造建议**: + +- 把 `ws` 成员换成 `child_process.ChildProcess + ndJsonStream`,或者直接用官方 SDK 的 `ClientSideConnection` 包一层(推荐后者,它把 JSON-RPC + requestPermission 的 req/resp 配对都做了) +- `heartbeat` 去掉 +- 其余订阅模型 / 请求状态机 / 能力 getter 全部保留 + +### 3. React Hooks —— 状态订阅 + +**源文件:** + +- `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\src\hooks\useModels.ts`(111 行) +- `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\src\hooks\useCommands.ts`(39 行) + +两者都是"事件驱动 + `localStorage` 持久化选择"的模板,直接 copy 到 webview。`useModels` 里有个关键细节:session 创建后会用 `localStorage.getItem("acp_model_id")` 自动恢复上次选择的模型。 + +### 4. 消息流处理器 — `handleSessionUpdate` 的 switch + +**源文件:** `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\components\ChatInterface.tsx:256-493` + +重点规则(Zed 风格): + +- `agent_message_chunk` / `agent_thought_chunk` / `user_message_chunk`:检查 `lastEntry?.type === "assistant_message"`,若同类 chunk 则 append 到最后一段;若换类别(thought ↔ message)则新增一段 chunk +- `tool_call` 使用 **UPSERT** 语义(先 `findToolCallIndex` 从尾向前找) +- `tool_call_update` 找不到对应 ID 时构造一条 failed 占位(跟 Zed 一致) +- `plan` 为**整份替换**,空 entries 表示清空 + +`findToolCallIndex` 反向扫描(`for (let i = entries.length - 1; i >= 0; i--)`)— 这是 ACP 协议规定的匹配方式,务必保留。 + +### 5. 权限 UI 映射 + +**源文件:** `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\components\ChatInterface.tsx:632-667` + `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\components\chat\PermissionPanel.tsx` + +`handlePermissionResponse(requestId, optionId, optionKind)` 的关键: + +```typescript +const isRejected = optionKind === "reject_once" || optionKind === "reject_always" || optionId === null; +// 对 standalone 权限请求(没有匹配 tool_call 的独立请求)批准后立即 complete +const newStatus = isRejected ? "rejected" + : entry.toolCall.isStandalonePermission ? "complete" + : "running"; +``` + +`handlePermissionPanelRespond(requestId, approved)` 根据 approved 分别找 `kind:"allow_once"` 优先、回退 `"allow_always"`;拒绝同理先 `"reject_once"` 后 `"reject_always"`。 + +### 6. 斜杠命令 CommandMenu + +**源文件:** `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\components\chat\CommandMenu.tsx`(138 行) + +特性: + +- `prefixMatch`(非 fuzzy) +- document-level capture-phase `keydown` 监听处理 Arrow/Enter(避免 textarea 抢焦点) +- `containerRef` 点击外部关闭 +- `scrollIntoView({block:"nearest"})` 让 active 项可见 + +ChatInput 里检测条件是 `value.startsWith("/") && commands?.length > 0`,filter 取 `value.slice(1).split(/\s/)[0]`(第一个空格前的部分)。 + +### 7. RCSChatAdapter(仅 RCS Web 专用,**不推荐 VSCode 复用**) + +**源文件:** `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\src\lib\rcs-chat-adapter.ts`(473 行) + +这个是 RCS 自己的 legacy 协议(SSE + bridge 事件 `user`/`assistant`/`tool_use`/`tool_result`/`control_request`)→ ThreadEntry 的转换。**VSCode 走 ACP,不经过这层**。但里面的 `handleEvent` 可以作为 tool_use 内嵌在 assistant message 时的拆分参考。 + +--- + +## ACP 协议能力映射 + +ACP (Agent Client Protocol) 是 Zed/Claude Code/多个 AI 终端共用的协议。相关规范: +- SDK: `@agentclientprotocol/sdk` +- Claude Code 的 agent 实现:`E:\Source_code\Claude-code-bast\src\services\acp\agent.ts`(~800 行) +- Claude Code 的 SDK→ACP bridge:`E:\Source_code\Claude-code-bast\src\services\acp\bridge.ts`(1257 行,核心翻译层) + +### AcpAgent 实现的方法(全部可被 VSCode 扩展作为 client 调用) + +| ACP 方法 | Claude Code 映射 | 实现位置 | +|---------|-----------------|--------| +| `initialize` | 返回 `{protocolVersion:1, agentInfo, agentCapabilities}`。声明 `promptCapabilities:{image:true, embeddedContext:true}`, `mcpCapabilities:{http:true, sse:true}`, `loadSession:true`, `sessionCapabilities:{fork:{}, list:{}, resume:{}, close:{}}`, `_meta.claudeCode.promptQueueing:true` | `agent.ts:104-148` | +| `authenticate` | no-op,返回 `{}` | `agent.ts:152-155` | +| `newSession` | 调 `createSession(params)` → 设 cwd、`enableConfigs()`、`setOriginalCwd(cwd)`、`process.chdir(cwd)`、构建 `QueryEngine` 并挂 `canUseTool:createAcpCanUseTool(...)` | `agent.ts:159-161` + `441-590` | +| `loadSession` | 读 `~/.claude/projects/.../*.jsonl` 还原消息,构建 session 后调 `replayHistoryMessages()` 把历史重放成 session/update | `agent.ts:177-183` + `592-664` | +| `unstable_resumeSession` | 类似 load 但不 replay | `agent.ts:165-173` | +| `listSessions` | 调 `listSessionsImpl({dir, limit:100})` → 映射为 `{sessionId, cwd, title, updatedAt}` | `agent.ts:187-205` | +| `unstable_forkSession` | 基于 `createSession` 复制一份 | `agent.ts:209-223` | +| `unstable_closeSession` | 调 `cancel({sessionId})` 然后 `sessions.delete(sessionId)` | `agent.ts:227-236` | +| `prompt` | 调 `QueryEngine.submitMessage(text)` → `forwardSessionUpdates(sessionId, sdkMessages, conn, ...)` 把 SDK 的 `assistant`/`stream_event`/`tool_result`/`result` 转成 ACP `session/update` | `agent.ts:240-342` | +| `cancel` | `session.cancelled=true` + `queryEngine.interrupt()` + 清空 pendingMessages 队列 | `agent.ts:346-361` | +| `setSessionMode` | `applySessionMode(sessionId, modeId)` → 同步 `modes.currentModeId` + `appState.toolPermissionContext.mode` | `agent.ts:365-376` | +| `unstable_setSessionModel` | `session.queryEngine.setModel(modelId)` | `agent.ts:380-391` | +| `setSessionConfigOption` | 统一入口处理 `mode`/`model`,回推 `config_option_update` | `agent.ts:395-437` | + +### session/update 事件的 8 种子类型(`SessionUpdate` union) + +在 `src/services/acp/bridge.ts` 里从 `SDKMessage` 产生: + +| sessionUpdate 类型 | 来源 | 说明 | +|---|---|---| +| `agent_message_chunk` | `stream_event: content_block_delta` text_delta / `assistant` 完整消息 | 最常见,助手输出 | +| `agent_thought_chunk` | `stream_event: thinking_delta` | 思考链 | +| `user_message_chunk` | replay 时的 user 消息 | 加载历史用 | +| `tool_call` | `content_block_start: tool_use` 首次出现 | 工具调用开始,附 `toolCallId` / `title` / `kind` / `status:"pending"` / `rawInput` / `content`(含 diff/terminal) | +| `tool_call_update` | 重复 `tool_use` 或 `tool_result` | 更新 status(pending → completed/failed),附 `rawOutput` | +| `plan` | `TodoWrite` 工具调用被特殊拦截 | 整份 `PlanEntry[]`(content/status/priority) | +| `available_commands_update` | `sendAvailableCommandsUpdate` 主动推送 | slash 命令清单 | +| `usage_update` | `result` 消息 | `{used, size, cost}` token 用量 | +| `current_mode_update` | 用户或 ExitPlanMode 切换 mode 时 | 通知 UI 同步 | + +### tool_use → ToolInfo 的映射(bridge.ts:58-235) + +`toolInfoFromToolUse(toolUse, supportsTerminalOutput, cwd)` 把内部 tool 名字翻译成人类可读 title 和 ACP `ToolKind`: + +- `Agent`/`Task` → `think` +- `Bash` → `execute`(附 `terminalId` 或 description) +- `Read` → `read`(title 带显示路径 + offset/limit) +- `Write` → `edit`(附 diff: `{oldText:null, newText}`) +- `Edit` → `edit`(附 diff: `{oldText, newText}`) +- `Glob`/`Grep` → `search` +- `WebFetch`/`WebSearch` → `fetch` +- `TodoWrite` → `think`(但单独处理走 `plan` update) +- `ExitPlanMode` → `switch_mode` +- 其他 → `other` + +**webview 端实际渲染 tool_call 时需要这份映射决定 UI**。VSCode 扩展如果只想做极简版,直接用 `title` + `status` + 第一个 `ToolCallContent` 的 diff 区就够了。 + +### 权限处理流水线(createAcpCanUseTool) + +**源文件:** `E:\Source_code\Claude-code-bast\src\services\acp\permissions.ts`(250 行) + +调用顺序(一定要复用这个流水线,不要简化): + +1. `tool.name === 'ExitPlanMode'` → 走 `handleExitPlanMode` 特殊多选项(5 个 option),用户选的 `optionId` 如果是 `acceptEdits`/`default`/`auto`/`bypassPermissions` 之一,调 `onModeChange(optionId)` 同步 session mode 并发 `current_mode_update` notification。 +2. 有 `forceDecision` → 直接用(coordinator/swarm worker 场景) +3. `hasPermissionsToUseTool()` 跑完整流水线:deny 规则 → allow 规则 → tool 特定检查 → `bypassPermissions`/`dontAsk`/`acceptEdits` 模式 → `auto` 模式的 model classifier +4. 流水线返回 `behavior:'ask'` → 回落到 `conn.requestPermission({sessionId, toolCall, options})`,options 固定 3 个:`Always Allow`/`Allow`/`Reject` +5. 用户 `cancelled` → 返回 `{behavior:'deny', message:'Permission request cancelled by client'}` + +**bypassPermissions 可用性判断**(每次渲染 modes 时用到): +```typescript +const ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX +``` + +### 权限模式透传(feedback 提过的 applySessionMode) + +完整链路: + +1. **客户端端**:扩展启动 new_session 时在 `_meta.permissionMode` 里带 mode(也可从 `process.env.ACP_PERMISSION_MODE` 读) +2. **acp-link 端**:`handleNewSession` 读 `params.permissionMode || DEFAULT_PERMISSION_MODE`,拼成 `_meta:{permissionMode}` 传给 `connection.newSession` +3. **agent 端**:`createSession` 从 `params._meta.permissionMode` 取(行 463-468,带 console.log),fallback 到 `settings.json` 的 `permissions.defaultMode`,再 `resolvePermissionMode` 归一化 +4. **运行时切换**:`applySessionMode()` 同时改两处 —— `session.modes.currentModeId` 和 `session.appState.toolPermissionContext.mode`,后者是 `hasPermissionsToUseTool` 读取的唯一来源 + +**警告**:不要只改 `session.modes`,会导致 permission pipeline 还按旧 mode 走。 + +--- + +## Bridge API 能力集(`src/bridge/`) + +这是 Anthropic 官方云端 bridge 协议,**与 VSCode 本地扩展无关**,仅列出作对照。 + +**源文件:** `E:\Source_code\Claude-code-bast\src\bridge\bridgeApi.ts`(~800 行),`bridgeMain.ts`(2991 行) + +### 必备 header + +```typescript +const BETA_HEADER = 'environments-2025-11-01' +headers = { + Authorization: `Bearer ${accessToken}`, + 'anthropic-version': '2023-06-01', + 'anthropic-beta': 'environments-2025-11-01', + 'x-environment-runner-version': runnerVersion, + 'X-Trusted-Device-Token': trustedDeviceToken // 可选 +} +``` + +### 端点(BridgeApiClient 接口) + +| 端点 | 用途 | +|---|---| +| `POST /v1/environments/bridge` | 注册 bridge environment,返回 `{environment_id, environment_secret}`。body: `{machine_name, directory, branch, git_repo_url, max_sessions, metadata:{worker_type}, environment_id?(resume)}` | +| `GET /v1/environments/{environmentId}/work/poll` | 长轮询领取 work item,返回 `WorkResponse` 或 null | +| `POST /v1/environments/{environmentId}/work/{workId}/ack` | ack work item | +| `POST /v1/environments/{environmentId}/work/{workId}/stop` | 停止 work (force 布尔) | +| `DELETE /v1/environments/bridge/{environmentId}` | 注销 environment | +| `POST /v1/sessions/{sessionId}/archive` | 归档 session | +| `POST /v1/environments/{environmentId}/bridge/reconnect` | 重连 | +| `POST /v1/environments/{environmentId}/work/{workId}/heartbeat` | session 心跳 | + +### JWT 认证 + +- `accessToken` 从 OAuth 拿(`getAccessToken()` 回调) +- 401 → `withOAuthRetry` 调 `onAuth401(staleAccessToken)` 尝试刷新,成功则重试一次 +- 最终 401 抛 `BridgeFatalError`(不可重试) +- worker_jwt 由 RCS 自托管版签发(`generateWorkerJwt(sessionId, expiresIn)`),参见 `packages\remote-control-server\src\routes\v2\code-sessions.ts:17-34` + +### 会话生命周期 + +1. `register` → 拿 `environment_id` + `environment_secret` +2. `poll` 循环,拿到 work 后 `decodeWorkSecret(work.secret)` 得到 `claude_code_args`/`mcp_config`/`api_base_url` +3. 用 `sessionRunner` / `sessionSpawner` 起 session 子进程,spawnMode: `single-session` / `worktree` / `same-dir` +4. 运行期通过 `heartbeatWork` 续期 +5. 完成后 `ack` / `stopWork` +6. exit 时 `deregisterEnvironment` + +**VSCode 扩展不走这条链路**,本地 ACP stdio 即可。 + +--- + +## 推荐 VSCode 扩展架构 + +### 协议层:ACP via stdio + +``` +┌─────────────────────────┐ ┌──────────────────────────┐ +│ VSCode Extension Host │ │ claude CLI child proc │ +│ (Node.js, extension.ts) │ stdio NDJSON (ACP) │ (spawned as `claude │ +│ ├◄────────────────────►┤ acp`) │ +│ ClientSideConnection │ │ AgentSideConnection │ +│ @acp/sdk │ │ → AcpAgent │ +│ │ │ → QueryEngine │ +└─────────────────────────┘ └──────────────────────────┘ + ▲ + │ postMessage API (vscode.WebviewPanel) + ▼ +┌─────────────────────────┐ +│ VSCode Webview (React) │ +│ - ChatView │ +│ - ChatInput + CommandMenu +│ - PermissionPanel │ +│ - ModelSelectorPopover │ +│ - PlanDisplay │ +└─────────────────────────┘ +``` + +### 为什么是 ACP(不是 Stream-JSON 也不是 Bridge) + +**Stream-JSON (`-p --output-format stream-json`) 不够用:** + +- 单向输出,用户输入得靠另一条机制 +- 没有 `permission_request` 的请求/响应配对(ACP 用 JSON-RPC request,Stream-JSON 只有 `control_request` 事件,没有协议保证 request_id 配对) +- 没有 `available_commands_update`,扩展只能自己解析 `~/.claude/commands/` 和 `.claude/commands/`(脆弱) +- 没有结构化 `tool_call` + `tool_call_update` 的 UPSERT 模型,需要自己从 `assistant` / `tool_result` 事件推断 + +**Bridge 不适用:** + +- 需要 claude.ai 订阅(`BRIDGE_LOGIN_INSTRUCTION` "Remote Control is only available with claude.ai subscriptions") +- 需要 OAuth + trusted device token + JWT 签发 +- 是云端长轮询模型,本地扩展跑这套是浪费 + +**ACP 胜在:** + +1. CLI 已经实现 `claude acp` 子命令(`src/services/acp/entry.ts` 行 30-77) +2. `@agentclientprotocol/sdk` 的 `ClientSideConnection` + `ndJsonStream(stdin, stdout)` 现成 +3. 所有 UI 需要的事件(session_update, permission_request, available_commands_update, model_changed, current_mode_update, plan)协议里都有 +4. RCS Web 已经写好所有对应的 React 组件 ——>> **~50% 的 UI 代码可直接搬** + +### 实施建议(阶段划分) + +**Phase 1 — CLI 集成层**(extension 主进程): + +- `spawn('claude', ['acp'], {cwd, env, stdio:['pipe','pipe','inherit']})`(参考 `packages/acp-link/src/server.ts:251-286`) +- 用 `@agentclientprotocol/sdk` 的 `ClientSideConnection` + `ndJsonStream` 包一层 +- 实现 `Client` 接口里的 `requestPermission`(转发到 webview)、`sessionUpdate`(转发到 webview)、`readTextFile` / `writeTextFile`(可接入 `vscode.workspace.fs`) +- 提供 `fs` clientCapabilities: `{readTextFile:true, writeTextFile:true}`,这样 agent 可以通过 ACP 让 VSCode 处理文件读写(符合 VSCode 原生编辑体验,避免 agent 直接写盘绕过 VSCode dirty state) + +**Phase 2 — Webview UI**: + +- 直接移植 `packages/remote-control-server/web/src/acp/types.ts` 类型文件 +- 移植 `packages/remote-control-server/web/src/hooks/useModels.ts`、`useCommands.ts` +- 移植 `packages/remote-control-server/web/components/chat/CommandMenu.tsx`、`PlanView.tsx`、`PermissionPanel.tsx` +- 移植 `ChatInterface.tsx` 里的 `handleSessionUpdate` / `handlePermissionRequest` / `handlePermissionResponse`(Zed 风格的 flat entries 管理) +- 替换:lucide 图标 → `vscode-codicons`;Tailwind tokens → `var(--vscode-*)` CSS 变量 + +**Phase 3 — VSCode 原生整合**(可选): + +- `readTextFile` / `writeTextFile` capability → 接入 `vscode.workspace.openTextDocument` + `edit.replace`(让 Claude 的编辑变成 undo stack 里的 VSCode 操作) +- tool_call 的 `diff` content → 渲染成 inline decoration 或打开 `DiffEditor` +- `Bash` tool 的 terminal content → 接入 `vscode.window.createTerminal` +- `@filepath` 之类的 mention → 用 `vscode.workspace.findFiles` + +### 反面教材:不要做的事 + +- **不要** 自己重新实现 `permission_request` 的 requestId 匹配 —— 用 SDK 自动配对 +- **不要** 复制 `RCSChatAdapter` 那套 SSE → ThreadEntry 的转换(那是 RCS 专有 legacy 协议) +- **不要** 复制 `acp-link/rcs-upstream.ts` 的 RCS 注册逻辑(扩展不需要往云端注册) +- **不要** 给 session mode 加 local-only state —— 用 `setSessionMode` 让 agent 是单一真源 + +--- + +## 关键文件速查 + +| 用途 | 绝对路径 | +|---|---| +| ACP 协议 TS 类型(最完整) | `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\src\acp\types.ts` | +| ACP Client 类(WS 版,作模板) | `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\src\acp\client.ts` | +| useModels/useCommands hooks | `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\src\hooks\` | +| 消息流/权限/命令 UI 组件 | `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\components\chat\` | +| ChatInterface 总装 | `E:\Source_code\Claude-code-bast\packages\remote-control-server\web\components\ChatInterface.tsx` | +| CLI 端 ACP 入口 | `E:\Source_code\Claude-code-bast\src\services\acp\entry.ts` | +| AcpAgent 实现 | `E:\Source_code\Claude-code-bast\src\services\acp\agent.ts` | +| SDKMessage → SessionUpdate 翻译 | `E:\Source_code\Claude-code-bast\src\services\acp\bridge.ts` | +| Permission pipeline | `E:\Source_code\Claude-code-bast\src\services\acp\permissions.ts` | +| stdio spawn + initialize 范例 | `E:\Source_code\Claude-code-bast\packages\acp-link\src\server.ts` | +| Bridge API (对照用,不复用) | `E:\Source_code\Claude-code-bast\src\bridge\bridgeApi.ts` | diff --git a/docs/plans/vscode-ext-slash-commands-fix.md b/docs/plans/vscode-ext-slash-commands-fix.md new file mode 100644 index 000000000..58d20b260 --- /dev/null +++ b/docs/plans/vscode-ext-slash-commands-fix.md @@ -0,0 +1,486 @@ +# VSCode Extension — Slash Commands 统一架构设计 + +**日期**: 2026-04-25 +**分支**: feat/vscode-extension +**状态**: 待确认 + +--- + +## 1. 问题陈述 + +VSCode 扩展中输入 `/` 后命令菜单显示 "No matching command (got 0 total)",用户无法发现和选择任何 slash command。 + +## 2. 根因分析 + +### 2.1 直接原因 + +`src/services/acp/agent.ts:729-734` 的 `sendAvailableCommandsUpdate()` 方法仅发送 `cmd.type === 'prompt'` 类型的命令: + +```typescript +// agent.ts:729-734 — 当前代码 +const availableCommands = session.commands + .filter( + cmd => + cmd.type === 'prompt' && + !cmd.isHidden && + cmd.userInvocable !== false, + ) +``` + +### 2.2 命令类型分布 + +CLI 注册的约 114 个命令中: + +| 类型 | 数量 | 过滤器结果 | +|------|------|-----------| +| `local` | ~34 | ❌ 全部丢弃 | +| `local-jsx` | ~70 | ❌ 全部丢弃 | +| `prompt` | ~10 | ✅ 保留 | + +10 个 `prompt` 类型命令中,`commit` 和 `commit-push-pr` 在 `INTERNAL_ONLY_COMMANDS`(需 `USER_TYPE=ant`),`init-verifiers` 是 `isHidden`,最终到达 webview 的命令接近 0。 + +### 2.3 架构确认(6 agent 独立审计) + +- **通信架构**:单通道 ACP over stdio,干净无混合协议 +- **执行路径**:ACP `prompt()` → `QueryEngine.submitMessage()` → `processUserInput()` → `processSlashCommand()` 能分派**所有三种类型**的命令 +- **问题范围**:纯粹是命令列表的**发现/展示层**过滤过窄,不涉及执行层 + +### 2.4 三种类型在 ACP 模式下的执行行为 + +| 类型 | 机制 | ACP 现状 | +|------|------|---------| +| `prompt` | `getPromptForCommand()` → API 调用 | ✅ 完全正常 | +| `local` | `load()` → `mod.call()` → 文本/compact/skip | ✅ 正常(`supportsNonInteractive: false` 的返回 skip) | +| `local-jsx` | `load()` → `mod.call(onDone, ctx, args)` → JSX | ⚠️ `isNonInteractiveSession: true` 导致 JSX 被丢弃(`processSlashCommand.tsx:820-825`) | + +`local-jsx` 的两种子类型: +- **A 类(`onDone` 完成)**:`/clear`, `/compact` — 主逻辑在 `onDone` 回调中,JSX 只是 UI 反馈,ACP 下正常工作 +- **B 类(依赖 Ink 交互)**:`/model`, `/config`, `/effort`, `/color` — 通过 Ink FuzzyPicker/模态框等待用户交互后才调 `onDone`,ACP 下 JSX 丢弃后 `onDone` 永远不触发,命令静默无响应 + +--- + +## 3. 设计目标 + +**统一机制**:所有命令通过同一路径执行,不分"webview 拦截"和"ACP 透传"两条路。 + +**全部可用**:114 个命令在扩展中都能工作,包括需要交互 UI 的 B 类 `local-jsx` 命令。 + +**不引入补丁**:不在 webview 端硬编码命令列表、不维护 `TERMINAL_ONLY_COMMANDS` 集合、不按命令名做条件分支。 + +--- + +## 4. 核心发现:ACP Elicitation 机制 + +ACP SDK (`@agentclientprotocol/sdk@0.19`) 已内置 `unstable_createElicitation` 协议,支持 agent 向 client 请求结构化用户输入: + +```typescript +// ACP SDK 已有类型(schema/types.gen.d.ts) + +// Agent → Client:请求用户输入 +type CreateElicitationRequest = { + mode: "form"; + message: string; // 人类可读提示 + requestedSchema: ElicitationSchema; // JSON Schema 描述表单字段 + sessionId: string; +}; + +// 字段类型支持 +type ElicitationPropertySchema = + | { type: "string"; enum?: string[]; oneOf?: EnumOption[] } // 单选 + | { type: "number" } + | { type: "boolean" } // 开关 + | { type: "array" } // 多选 + +type EnumOption = { const: string; title: string }; // 带标题的选项 + +// Client → Agent:用户响应 +type CreateElicitationResponse = + | { action: "accept"; content: Record } + | { action: "decline" } + | { action: "cancel" }; +``` + +这个机制设计目的就是让 agent 通过标准协议向 client 请求用户交互,完美匹配 B 类 `local-jsx` 命令的需求。 + +--- + +## 5. 统一架构设计 + +### 5.1 统一执行路径 + +所有命令走同一条路径,无分支: + +``` +用户输入 "/xxx args" + → PromptInput.submit() + → useACP.sendMessage("/xxx args") + → ext:prompt → ChatViewProvider → ACPClient.prompt() + → CLI AcpAgent.prompt() + → QueryEngine.submitMessage("/xxx args") + → processUserInput() → processSlashCommand() + → 按 type 执行: + prompt → getPromptForCommand() → API 调用 → 流式结果通过 sessionUpdate 回传 + local → load() → mod.call() → 文本结果通过 bridge 回传 + local-jsx → load() → mod.call(onDone, ctx, args) + → 需要交互时: CLI 发 createElicitation → webview 渲染原生 UI + → 用户选择 → 响应回传 CLI → onDone 完成 → 结果通过 bridge 回传 +``` + +webview 端不做任何命令级别的拦截或条件分支。`PromptInput.onSlashSelect` 对所有命令做同样的事:填入 textarea,用户按 Enter 发送。 + +### 5.2 改动分层 + +#### 第一层:命令列表修复(发现层) + +解决"看不到命令"的问题。 + +**文件**: `src/services/acp/agent.ts` + +```typescript +// sendAvailableCommandsUpdate() — 修改后 +private async sendAvailableCommandsUpdate(sessionId: string): Promise { + const session = this.sessions.get(sessionId) + if (!session) return + + const availableCommands = session.commands + .filter( + cmd => + !cmd.isHidden && + cmd.userInvocable !== false && + isCommandEnabled(cmd), + ) + .map(cmd => ({ + name: cmd.name, + description: cmd.description, + input: cmd.argumentHint ? { hint: cmd.argumentHint } : undefined, + })) + + await this.conn.sessionUpdate({ + sessionId, + update: { + sessionUpdate: 'available_commands_update', + availableCommands, + }, + }) +} +``` + +改动要点: +- 移除 `cmd.type === 'prompt'` 过滤 +- 增加 `isCommandEnabled(cmd)` 检查(`src/types/command.ts:227-229`,处理 feature flag / 环境条件) +- `AvailableCommand` 类型不变(`name`, `description`, `input`),不透传 `type`——webview 不需要知道命令的内部类型,因为执行路径统一 + +#### 第二层:B 类命令执行修复(交互层) + +解决"需交互 UI 的命令在 ACP 模式下静默无响应"的问题。 + +核心思路:B 类 `local-jsx` 命令在非交互模式下不再静默丢弃,而是通过 ACP Elicitation 向 client 请求用户输入,用户在 webview 的原生 UI 中完成交互后,响应回传 CLI,`onDone` 正常触发。 + +##### 5.2.1 CLI 端:ACP Agent 实现 Elicitation 发送 + +**文件**: `src/services/acp/agent.ts` + +AcpAgent 需要向 `processSlashCommand` 的执行上下文注入 elicitation 能力。当 B 类命令需要用户选择时(如 `/model` 需要选模型),命令内部调用 elicitation 函数,ACP agent 将其转为 `createElicitation` RPC 调用。 + +```typescript +// agent.ts — AcpAgent 新增方法 +private async elicit( + sessionId: string, + message: string, + schema: ElicitationSchema, +): Promise { + return this.conn.unstable_createElicitation({ + mode: 'form', + sessionId, + message, + requestedSchema: schema, + }) +} +``` + +##### 5.2.2 CLI 端:命令上下文注入 elicitation + +**文件**: `src/services/acp/agent.ts` (prompt 方法) + `src/types/command.ts` (上下文类型) + +`processSlashCommand` 的执行上下文(`ToolUseContext & LocalJSXCommandContext`)需要增加一个可选的 `elicit` 函数。ACP agent 在调用 `submitMessage` 前注入: + +```typescript +// command.ts — LocalJSXCommandContext 扩展 +export type LocalJSXCommandContext = { + // ... 现有字段 + /** ACP elicitation: 向客户端请求结构化用户输入。仅在 ACP 模式下可用。 */ + elicit?: (message: string, schema: ElicitationSchema) => Promise +} + +type ElicitationResult = + | { action: 'accept'; content: Record } + | { action: 'decline' } + | { action: 'cancel' } +``` + +##### 5.2.3 CLI 端:B 类命令适配 elicitation + +**以 `/model` 为例** — `src/commands/model/index.ts`(或对应文件) + +当前 `/model` 的实现逻辑大致是: +1. 获取可用模型列表 +2. 渲染 Ink FuzzyPicker 让用户选择 +3. 用户选择后通过 `onDone` 回调设置模型 + +适配后: +1. 获取可用模型列表 +2. 检查 `context.elicit` 是否可用(ACP 模式) + - **有 `elicit`**:构建 elicitation schema(`type: "string", oneOf: models.map(...)`),调用 `context.elicit()`,等待响应,调 `onDone` + - **无 `elicit`(REPL 模式)**:渲染 Ink FuzzyPicker(现有逻辑不变) +3. `onDone` 回调设置模型 + +```typescript +// 概念示例(实际代码结构根据命令实现调整) +async call(onDone, context, args) { + const models = getAvailableModels() + + // 如果有参数,直接设置(已有逻辑) + if (args.trim()) { + const matched = models.find(m => m.id.includes(args.trim())) + if (matched) { + onDone({ messages: [], nextInput: undefined }) + setModel(matched.id) + return null + } + } + + // ACP 模式:通过 elicitation 请求用户选择 + if (context.elicit) { + const response = await context.elicit('Select a model', { + type: 'object', + properties: { + model: { + type: 'string', + title: 'Model', + oneOf: models.map(m => ({ const: m.id, title: m.name })), + }, + }, + required: ['model'], + }) + if (response.action === 'accept') { + setModel(response.content.model as string) + } + onDone({ messages: [], nextInput: undefined }) + return null + } + + // REPL 模式:渲染 Ink FuzzyPicker(现有逻辑) + return { setModel(id); onDone(...) }} /> +} +``` + +##### 5.2.4 webview 端:实现 Elicitation UI + +**文件**: `packages/vscode-extension/src/ACPClient.ts` + +ACPClient 在创建 `ClientSideConnection` 时注册 `unstable_createElicitation` 回调: + +```typescript +// ACPClient.ts — connection 创建时 +const connection = acp.createClientSideConnection(transport, { + // ... 现有回调 + async unstable_createElicitation(params) { + // 转发给 webview,等待用户响应 + return this.handleElicitation(params) + }, +}) +``` + +**文件**: `packages/vscode-extension/webview/` — 新增 ElicitationDialog 组件 + +webview 端收到 elicitation 请求后,根据 `requestedSchema` 渲染原生表单 UI: + +- `string` + `oneOf` → 下拉选择器 / 搜索列表 +- `string` + `enum` → 简单下拉 +- `boolean` → 开关 +- 多字段 → 表单组合 + +用户完成选择后,响应通过 extension host 回传 CLI。 + +**消息协议扩展**: + +`packages/vscode-extension/webview/lib/protocol.ts` 增加两个消息类型: + +```typescript +// Host → Webview +interface ElicitationRequestMessage { + type: 'ext:elicitation_request' + payload: { + requestId: string + message: string + schema: ElicitationSchema + } +} + +// Webview → Host +interface ElicitationResponseMessage { + type: 'ext:elicitation_response' + payload: { + requestId: string + action: 'accept' | 'decline' | 'cancel' + content?: Record + } +} +``` + +##### 5.2.5 processSlashCommand 不再静默丢弃 + +**文件**: `src/utils/processUserInput/processSlashCommand.tsx` + +当前 `isNonInteractiveSession` 时直接丢弃 JSX(行 820-825)。修改为:如果命令的 `onDone` 已在 `mod.call()` 执行过程中被调用(说明命令通过 elicitation 或参数直接完成了),正常返回。如果 `onDone` 未被调用且 JSX 被返回,才记录一条说明信息: + +```typescript +// processSlashCommand.tsx:818-827 — 修改后 +.then(jsx => { + if (jsx == null) return + if (doneWasCalled) return // onDone 已触发(命令通过 elicitation 完成) + if (context.options.isNonInteractiveSession) { + // 命令返回了 JSX 但 onDone 未触发,说明命令依赖 Ink 交互且未适配 elicitation + void resolve({ + messages: [{ + role: 'assistant', + content: `Command /${command.name} requires interactive terminal UI and is not yet available in this environment.`, + }], + shouldQuery: false, + command, + }) + return + } + // REPL 模式:渲染 JSX(现有逻辑不变) + if (doneWasCalled) return + setToolJSX({ jsx, shouldHidePromptInput: true, showSpinner: false, isLocalJSXCommand: true, isImmediate: command.immediate === true }) +}) +``` + +这样未适配 elicitation 的命令也会给用户一个明确反馈,而不是静默返回空。 + +--- + +## 6. 涉及文件清单 + +| 文件 | 改动类型 | 说明 | +|------|---------|------| +| `src/services/acp/agent.ts` | **核心** | 移除 `type === 'prompt'` 过滤;新增 `elicit()` 方法;`prompt()` 中注入 elicitation 上下文 | +| `src/types/command.ts` | 类型扩展 | `LocalJSXCommandContext` 增加 `elicit?` 函数 | +| `src/utils/processUserInput/processSlashCommand.tsx` | 行为修复 | 非交互模式下 JSX 丢弃改为给出明确反馈(未适配的命令) | +| `src/commands/model/` | 命令适配 | 检测 `context.elicit`,ACP 模式用 elicitation 替代 FuzzyPicker | +| `src/commands/effort/` | 命令适配 | 同上(effort level 选择) | +| `src/commands/config/` | 命令适配 | 同上(配置项选择) | +| `src/commands/color/` | 命令适配 | 同上(颜色主题选择) | +| `src/commands/fast/` | 命令适配 | 同上(fast mode 切换) | +| `packages/vscode-extension/src/ACPClient.ts` | ACP 回调 | 注册 `unstable_createElicitation` 回调 | +| `packages/vscode-extension/src/ChatViewProvider.ts` | 消息路由 | elicitation 请求/响应在 host ↔ webview 间中转 | +| `packages/vscode-extension/webview/lib/protocol.ts` | 协议扩展 | 新增 `ext:elicitation_request` / `ext:elicitation_response` | +| `packages/vscode-extension/webview/lib/acp/types.ts` | 类型扩展 | 新增 ElicitationSchema 相关类型 | +| `packages/vscode-extension/webview/components/ElicitationDialog.tsx` | **新文件** | 通用 elicitation UI 组件(下拉、开关、表单) | +| `packages/vscode-extension/webview/hooks/useACP.ts` | 状态管理 | 处理 elicitation 请求/响应的 dispatch | + +--- + +## 7. 数据流 + +### 7.1 普通命令(prompt / local / local-jsx A 类) + +``` +用户: /compact + → webview submit("/compact") + → ACP prompt("/compact") + → processSlashCommand → local-jsx dispatch + → onDone fires (compaction 完成) + → bridge 转为 sessionUpdate + → webview 显示结果 +``` + +### 7.2 需交互的命令(local-jsx B 类)— 修复后 + +``` +用户: /model + → webview submit("/model") + → ACP prompt("/model") + → processSlashCommand → local-jsx dispatch + → 命令检测 context.elicit 可用 + → 命令调用 context.elicit("Select a model", schema) + → ACP createElicitation RPC → ACPClient 回调 + → ChatViewProvider → webview ext:elicitation_request + → webview 渲染 ElicitationDialog(模型选择列表) + → 用户选择 "claude-sonnet-4-6" + → webview ext:elicitation_response → ChatViewProvider → ACPClient → CLI + → 命令收到响应 → setModel("claude-sonnet-4-6") → onDone + → bridge 转为 sessionUpdate + → webview 显示 "Model set to claude-sonnet-4-6" +``` + +### 7.3 未适配 elicitation 的命令 + +``` +用户: /vim + → webview submit("/vim") + → ACP prompt("/vim") + → processSlashCommand → local-jsx dispatch + → context.elicit 可用但命令未使用 + → 命令返回 JSX, onDone 未触发 + → processSlashCommand 检测: isNonInteractive + JSX 返回 + onDone 未调用 + → 返回 "Command /vim requires interactive terminal UI..." + → webview 显示提示信息 +``` + +--- + +## 8. 实施顺序 + +### Phase 1:命令列表修复(立即可用) + +1. 修改 `agent.ts` 的 `sendAvailableCommandsUpdate` 过滤器 +2. 修改 `processSlashCommand.tsx` 非交互 JSX 丢弃改为明确反馈 + +效果:所有命令在菜单可见。`prompt` 和 `local` 命令立即可执行。B 类 `local-jsx` 命令给出明确提示而非静默。 + +### Phase 2:Elicitation 基础设施 + +3. `ACPClient.ts` 注册 `unstable_createElicitation` 回调 +4. `ChatViewProvider.ts` 消息路由 +5. `protocol.ts` 协议扩展 +6. `acp/types.ts` 类型扩展 +7. `ElicitationDialog.tsx` 通用 UI 组件 +8. `useACP.ts` 状态管理 +9. `command.ts` 上下文类型扩展 +10. `agent.ts` 的 `elicit()` 方法和上下文注入 + +效果:ACP Elicitation 通道端到端打通。 + +### Phase 3:命令逐步适配 + +11. `/model` — 最高优先级,用户最常用 +12. `/effort` — effort level 选择 +13. `/fast` — fast mode 切换 +14. `/config` — 配置浏览/修改 +15. `/color` — 颜色主题 +16. 其他 B 类命令按使用频率逐步适配 + +每个命令的改动是独立的、渐进的:检测 `context.elicit`,ACP 模式用 elicitation,REPL 模式用现有 Ink UI。未适配的命令显示明确提示。 + +--- + +## 9. 设计优势 + +1. **单一执行路径**:所有命令走 ACP prompt → processSlashCommand,webview 不做命令级条件分支 +2. **利用已有协议**:ACP Elicitation 是 SDK 内置机制,不是自造协议 +3. **渐进适配**:Phase 1 立即解决"看不到命令",Phase 2/3 逐步补全交互能力,每步都有独立价值 +4. **CLI 不受影响**:REPL 模式代码路径不变,elicitation 是可选的上下文注入 +5. **可扩展**:未来任何新的 `local-jsx` 命令只需检测 `context.elicit` 即可支持 ACP 模式,不需要 webview 端逐一适配 + +--- + +## 10. 风险评估 + +| 风险 | 影响 | 缓解 | +|------|------|------| +| `unstable_createElicitation` 是 experimental API,可能变更 | Elicitation 协议调整 | 通过 `_meta` 做版本协商;或封装 adapter 层隔离 SDK 变更 | +| 命令适配 elicitation 需要逐个修改 | 覆盖速度 | Phase 1 已解决"看不到命令",适配是渐进式的;高频命令优先 | +| ElicitationDialog 需要覆盖多种字段类型 | UI 复杂度 | 先只实现 `string + oneOf`(单选列表),覆盖 80% 场景 | +| ACP SDK schema 可能拒绝 `availableCommands` 中的额外字段 | sessionUpdate 失败 | 不透传 `type`,保持原有 schema | diff --git a/docs/plans/vscode-extension-phase1.md b/docs/plans/vscode-extension-phase1.md new file mode 100644 index 000000000..91df86d8e --- /dev/null +++ b/docs/plans/vscode-extension-phase1.md @@ -0,0 +1,698 @@ +# VSCode Extension — Phase 1 详细实施计划 + +## 目标 + +在 VS Code 侧边栏中与 Claude 对话。spawn CLI 进程,通过已有的 SDK 控制协议 (`--print --output-format stream-json`) 通信,WebView 渲染流式响应。 + +## 核心发现:不需要新协议 + +CLI 已有完整的 SDK 控制协议(`StdoutMessage` 12 种变体 + `StdinMessage` 5 种变体),通过 `--print` + `--output-format stream-json` 激活。VSCode 扩展直接复用这套协议,**零协议设计工作**。 + +### 可直接复用的模块清单 + +| 模块 | 文件 | 复用方式 | +|------|------|----------| +| SDK 控制协议 | `src/entrypoints/sdk/controlTypes.ts` + `controlSchemas.ts` + `coreSchemas.ts` | 导入类型定义 | +| 结构化 IO | `src/cli/structuredIO.ts` (863行) | CLI 端已就绪,扩展只需解析输出 | +| 状态 Store | `src/state/store.ts` (34行) | WebView 直接复制使用 | +| 消息类型 | `src/types/message.ts` + `@ant/model-provider` 类型 | 30+ 纯数据类型 | +| 工具/权限类型 | `src/Tool.ts` + `src/types/permissions.ts` | 纯接口定义 | +| IDE lockfile 发现 | `src/utils/ide.ts` (LockfileJsonContent/IdeLockfileInfo/DetectedIDEInfo) | 扩展写 lockfile,CLI 自动发现 | +| 认证共享 | `src/utils/auth.ts` + `src/utils/config.ts` | 读 `~/.claude/config.json` 同一份凭据 | +| 主题 token | `packages/@ant/ink/src/theme/theme-types.ts` (~80 个语义 token) | 转换为 CSS variables | +| MCP Server 模式 | `packages/@ant/claude-for-chrome-mcp/src/mcpServer.ts` | 照搬结构 | +| Markdown 配置 | `src/utils/markdown.ts` 的 `configureMarked()` | WebView 用 `marked.parse()` | + +--- + +## 分步实施 + +### Step 0: 包骨架搭建 + +**文件**: `packages/vscode-extension/` + +``` +packages/vscode-extension/ +├── package.json # VS Code extension manifest + devDeps +├── tsconfig.json # 独立 tsconfig,不继承主项目 +├── esbuild.config.ts # 两个 entry: extension + webview +├── .vscodeignore +├── resources/ +│ └── icon.svg # Activity Bar 图标 +├── src/ +│ └── (后续 step 创建) +└── webview/ + └── (后续 step 创建) +``` + +**package.json 关键配置**: +```jsonc +{ + "name": "claude-code-best-vscode", + "displayName": "Claude Code Best", + "version": "0.1.0", + "engines": { "vscode": "^1.85.0" }, + "main": "./dist/extension.js", + "activationEvents": ["onStartupFinished"], + "contributes": { + "viewsContainers": { + "activitybar": [{ + "id": "claude-code", + "title": "Claude Code", + "icon": "resources/icon.svg" + }] + }, + "views": { + "claude-code": [{ + "type": "webview", + "id": "claude-code.chat", + "name": "Chat" + }] + }, + "commands": [ + { "command": "claude-code.newChat", "title": "New Chat", "category": "Claude Code" } + ], + "keybindings": [ + { "command": "claude-code.focus", "key": "ctrl+escape", "mac": "cmd+escape" } + ], + "configuration": { + "title": "Claude Code Best", + "properties": { + "claudeCode.cliPath": { + "type": "string", + "default": "ccb", + "description": "Path to the Claude Code CLI binary" + } + } + } + } +} +``` + +**esbuild 配置** (两个 bundle): +1. `src/extension.ts` → `dist/extension.js` (Node.js,VS Code host) +2. `webview/index.tsx` → `dist/webview.js` (浏览器,WebView) + +**构建命令**: +```bash +cd packages/vscode-extension && bun run build # 打包 +cd packages/vscode-extension && bun run dev # watch 模式 +cd packages/vscode-extension && bun run package # 生成 .vsix +``` + +**验收**: `bun run build` 产出 `dist/extension.js` + `dist/webview.js`,无错误。 + +--- + +### Step 1: Extension Host — 入口与生命周期 + +**新建文件**: +- `src/extension.ts` — activate/deactivate +- `src/CLIProcess.ts` — spawn CLI 进程 + NDJSON 解析 +- `src/ChatViewProvider.ts` — WebView provider + +#### 1.1 `src/extension.ts` + +```typescript +import * as vscode from 'vscode' +import { ChatViewProvider } from './ChatViewProvider' + +export function activate(context: vscode.ExtensionContext) { + const provider = new ChatViewProvider(context.extensionUri, context) + + context.subscriptions.push( + vscode.window.registerWebviewViewProvider('claude-code.chat', provider), + vscode.commands.registerCommand('claude-code.newChat', () => provider.newChat()), + ) +} + +export function deactivate() {} +``` + +#### 1.2 `src/CLIProcess.ts` + +核心:spawn `ccb --print --output-format stream-json --input-format stream-json`,解析 stdout 的 NDJSON 行。 + +```typescript +import { spawn, type ChildProcess } from 'child_process' +import { EventEmitter } from 'events' +import type { StdoutMessage, StdinMessage } from './types/sdk' + +export class CLIProcess extends EventEmitter { + private process: ChildProcess | null = null + private buffer = '' + + constructor( + private cliPath: string, + private cwd: string, + ) { super() } + + start(): void { + this.process = spawn(this.cliPath, [ + '--print', + '--output-format', 'stream-json', + '--input-format', 'stream-json', + '--verbose', + ], { + cwd: this.cwd, + stdio: ['pipe', 'pipe', 'pipe'], + env: { ...process.env }, + }) + + this.process.stdout!.on('data', (chunk: Buffer) => { + this.buffer += chunk.toString('utf-8') + this.drainBuffer() + }) + + this.process.stderr!.on('data', (chunk: Buffer) => { + this.emit('stderr', chunk.toString('utf-8')) + }) + + this.process.on('exit', (code) => { + this.emit('exit', code) + this.process = null + }) + } + + send(message: StdinMessage): void { + if (!this.process?.stdin?.writable) return + this.process.stdin.write(JSON.stringify(message) + '\n') + } + + interrupt(): void { + this.send({ type: 'user_input', inputMode: 'interrupt' } as StdinMessage) + } + + kill(): void { + this.process?.kill('SIGTERM') + } + + private drainBuffer(): void { + const lines = this.buffer.split('\n') + this.buffer = lines.pop() ?? '' + for (const line of lines) { + if (!line.trim()) continue + try { + const msg: StdoutMessage = JSON.parse(line) + this.emit('message', msg) + } catch { + this.emit('stderr', line) + } + } + } +} +``` + +**关键**: 复用 CLI 已有的 `--print --output-format stream-json` 路径,不需要新的 `--ipc-mode`。CLI 端 `print.ts` → `StructuredIO` 已完整处理所有消息流。 + +#### 1.3 `src/ChatViewProvider.ts` + +```typescript +import * as vscode from 'vscode' +import { CLIProcess } from './CLIProcess' + +export class ChatViewProvider implements vscode.WebviewViewProvider { + private view?: vscode.WebviewView + private cli?: CLIProcess + + constructor( + private extensionUri: vscode.Uri, + private context: vscode.ExtensionContext, + ) {} + + resolveWebviewView(view: vscode.WebviewView): void { + this.view = view + view.webview.options = { + enableScripts: true, + localResourceRoots: [vscode.Uri.joinPath(this.extensionUri, 'dist')], + } + view.webview.html = this.getHtml(view.webview) + + // WebView → Extension Host + view.webview.onDidReceiveMessage((msg) => this.handleWebViewMessage(msg)) + + // 自动启动 CLI + this.startCLI() + } + + newChat(): void { + this.cli?.kill() + this.startCLI() + this.postToWebView({ type: 'clear' }) + } + + private startCLI(): void { + const config = vscode.workspace.getConfiguration('claudeCode') + const cliPath = config.get('cliPath', 'ccb') + const cwd = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? process.cwd() + + this.cli = new CLIProcess(cliPath, cwd) + + // CLI → WebView 转发 + this.cli.on('message', (msg) => this.postToWebView(msg)) + this.cli.on('stderr', (text) => this.postToWebView({ type: 'log', text })) + this.cli.on('exit', (code) => this.postToWebView({ type: 'disconnected', code })) + + this.cli.start() + } + + private handleWebViewMessage(msg: { type: string; [k: string]: unknown }): void { + switch (msg.type) { + case 'user_input': + this.cli?.send({ + type: 'user_input', + // 将 WebView 的用户输入转为 StdinMessage 格式 + ...msg, + } as any) + break + case 'interrupt': + this.cli?.interrupt() + break + } + } + + private postToWebView(msg: unknown): void { + this.view?.webview.postMessage(msg) + } + + private getHtml(webview: vscode.Webview): string { + const scriptUri = webview.asWebviewUri( + vscode.Uri.joinPath(this.extensionUri, 'dist', 'webview.js') + ) + const nonce = getNonce() + return ` + + + + + + Claude Code + + +
+ + +` + } +} + +function getNonce(): string { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + let result = '' + for (let i = 0; i < 32; i++) { + result += chars.charAt(Math.floor(Math.random() * chars.length)) + } + return result +} +``` + +**验收**: F5 启动 Extension Development Host,Activity Bar 出现图标,点击打开侧边栏。 + +--- + +### Step 2: WebView — React 聊天界面 + +**新建文件**: +``` +webview/ +├── index.tsx # React 入口 +├── App.tsx # 主组件 +├── store.ts # 从 src/state/store.ts 复制(34行) +├── theme.ts # 从 Ink theme 转换的 CSS variables +├── styles.css # 全局样式 +├── hooks/ +│ ├── useCLI.ts # 接收 CLI 消息 +│ └── useVSCodeAPI.ts # VS Code WebView API 封装 +└── components/ + ├── MessageList.tsx # 消息列表 + ├── MessageBubble.tsx # 单条消息 + ├── PromptInput.tsx # 输入框 + └── StatusBar.tsx # 状态栏 +``` + +#### 2.1 状态 Store + +直接复制 `src/state/store.ts`(34行),加上 WebView 特化的状态类型: + +```typescript +// 从 src/state/store.ts 复制,零改动 +export { createStore, type Store } from './store-core' + +// WebView 状态 +export interface ChatState { + messages: RenderedMessage[] + status: 'idle' | 'connecting' | 'thinking' | 'streaming' | 'tool_executing' | 'disconnected' + tokenUsage: { input: number; output: number; cache: number } + model: string +} + +export type RenderedMessage = { + id: string + role: 'user' | 'assistant' | 'system' + content: string // 渲染后的 HTML + timestamp: number + toolCalls?: ToolCallInfo[] + isStreaming?: boolean +} + +export type ToolCallInfo = { + id: string + name: string + status: 'running' | 'done' | 'error' + summary?: string +} +``` + +#### 2.2 `useCLI` Hook + +```typescript +import { useEffect, useRef, useCallback } from 'react' + +const vscode = acquireVsCodeApi() + +export function useCLI(onMessage: (msg: any) => void) { + const callbackRef = useRef(onMessage) + callbackRef.current = onMessage + + useEffect(() => { + const handler = (event: MessageEvent) => callbackRef.current(event.data) + window.addEventListener('message', handler) + return () => window.removeEventListener('message', handler) + }, []) + + const send = useCallback((text: string) => { + vscode.postMessage({ type: 'user_input', content: text }) + }, []) + + const interrupt = useCallback(() => { + vscode.postMessage({ type: 'interrupt' }) + }, []) + + return { send, interrupt } +} +``` + +#### 2.3 消息解析 + +将 `StdoutMessage` 映射到 `RenderedMessage`。核心消息类型处理: + +| StdoutMessage.type | 处理方式 | +|---|---| +| `assistant` (SDKMessage subtype) | 追加/更新助手消息,`marked.parse()` 渲染 | +| `result` | 标记消息完成,更新 token 用量 | +| `tool_use` / `tool_result` | 创建 ToolCallInfo,展示工具名+摘要 | +| `control_request` (can_use_tool) | Phase 2 处理(Phase 1 使用 `--permission-mode acceptEdits`) | +| `session_state` | 更新 status | + +#### 2.4 Markdown 渲染 + +复用 `configureMarked()` 配置,在 WebView 中直接调用 `marked.parse()`: + +```typescript +import { marked } from 'marked' + +// 复用 src/utils/markdown.ts 的配置 +marked.use({ + breaks: true, + gfm: true, + extensions: [/* 从 configureMarked() 复制 */] +}) + +export function renderMarkdown(text: string): string { + return marked.parse(text) as string +} +``` + +#### 2.5 主题 + +从 `packages/@ant/ink/src/theme/theme-types.ts` 的 ~80 个 token 提取 CSS variables: + +```css +:root { + /* 从 getTheme('dark') 机械转换 */ + --theme-claude: rgb(215, 119, 87); + --theme-success: rgb(76, 175, 80); + --theme-error: rgb(244, 67, 54); + --theme-warning: rgb(255, 152, 0); + --theme-diff-added: rgb(76, 175, 80); + --theme-diff-removed: rgb(244, 67, 54); + /* ... */ + + /* VS Code 原生变量融合 */ + --vscode-font-family: var(--vscode-editor-font-family); + --vscode-bg: var(--vscode-editor-background); + --vscode-fg: var(--vscode-editor-foreground); +} +``` + +**验收**: 输入消息,CLI stdout 返回流式响应,WebView 实时渲染 Markdown。 + +--- + +### Step 3: 状态栏与连接管理 + +**新建文件**: +- `src/StatusBarManager.ts` — VS Code 状态栏集成 + +```typescript +import * as vscode from 'vscode' + +export class StatusBarManager { + private item: vscode.StatusBarItem + + constructor() { + this.item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100) + this.item.command = 'claude-code.focus' + this.update('idle') + this.item.show() + } + + update(state: 'idle' | 'connecting' | 'thinking' | 'streaming' | 'disconnected'): void { + const icons: Record = { + idle: '$(circle-outline)', + connecting: '$(loading~spin)', + thinking: '$(loading~spin)', + streaming: '$(pulse)', + disconnected: '$(circle-slash)', + } + this.item.text = `${icons[state]} Claude Code` + } + + dispose(): void { this.item.dispose() } +} +``` + +**进程重启逻辑**(在 `ChatViewProvider` 中): + +```typescript +this.cli.on('exit', (code) => { + if (code !== 0) { + // 非正常退出,3 秒后自动重启 + setTimeout(() => this.startCLI(), 3000) + } +}) +``` + +**验收**: 状态栏显示连接状态图标,CLI 崩溃后自动重启。 + +--- + +### Step 4: 测试与本地安装 + +**新建文件**: +- `packages/vscode-extension/src/__tests__/CLIProcess.test.ts` +- `packages/vscode-extension/src/__tests__/messageParser.test.ts` +- `packages/vscode-extension/scripts/install-local.sh` — 本地安装脚本 +- `packages/vscode-extension/scripts/install-local.ps1` — Windows 安装脚本 + +#### 测试覆盖 + +1. **CLIProcess**: spawn mock → NDJSON 解析 → 消息事件触发 +2. **消息解析**: StdoutMessage → RenderedMessage 映射 +3. **Store**: 状态更新不可变性 + +#### 本地安装(不发布,symlink 方式) + +VS Code 从 `~/.vscode/extensions/` 自动加载扩展。我们通过 symlink 将构建产物链接到该目录,实现"build 一次,VS Code 自动加载"。 + +**目标路径**: `~/.vscode/extensions/claude-code-best-vscode/` + +**Windows 安装脚本** (`scripts/install-local.ps1`): +```powershell +# 构建 +bun run build + +# 创建 symlink(需要管理员权限或开发者模式) +$ExtDir = "$env:USERPROFILE\.vscode\extensions\claude-code-best-vscode" +$SourceDir = (Resolve-Path "..").Path # packages/vscode-extension/ + +# 清理旧链接 +if (Test-Path $ExtDir) { Remove-Item $ExtDir -Force -Recurse } + +# 创建目录 junction(不需要管理员权限) +New-Item -ItemType Junction -Path $ExtDir -Target $SourceDir + +Write-Host "Installed: $ExtDir -> $SourceDir" +Write-Host "Restart VS Code to load the extension." +``` + +**Bash 安装脚本** (`scripts/install-local.sh`): +```bash +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")/.." +bun run build + +EXT_DIR="$HOME/.vscode/extensions/claude-code-best-vscode" +SOURCE_DIR="$(pwd)" + +# 清理旧链接 +rm -rf "$EXT_DIR" + +# 创建 symlink +ln -sf "$SOURCE_DIR" "$EXT_DIR" + +echo "Installed: $EXT_DIR -> $SOURCE_DIR" +echo "Restart VS Code to load the extension." +``` + +#### 目录结构要求 + +symlink 后 VS Code 从 `~/.vscode/extensions/claude-code-best-vscode/` 读取,该目录必须包含: + +``` +claude-code-best-vscode/ # = packages/vscode-extension/ +├── package.json # VS Code extension manifest(必须在根) +├── dist/ +│ ├── extension.js # Extension Host 入口(package.json main 指向这里) +│ └── webview.js # WebView bundle +└── resources/ + └── icon.svg +``` + +VS Code 通过 `package.json` 中的 `main` 字段找到入口,`contributes` 注册命令/视图。**不需要 .vsix 打包**。 + +#### 开发流程 + +```bash +# 首次安装 +cd packages/vscode-extension +bun install +bun run build +./scripts/install-local.sh # 或 PowerShell: .\scripts\install-local.ps1 + +# 日常开发 +bun run dev # watch 模式,自动 rebuild +# symlink 指向源目录,rebuild 后直接生效 +# VS Code 中 Ctrl+Shift+P → "Developer: Reload Window" 热重载 + +# F5 调试(不需要 symlink) +# 在 VS Code 中打开 packages/vscode-extension/ +# F5 启动 Extension Development Host +``` + +#### package.json scripts + +```jsonc +{ + "scripts": { + "build": "node esbuild.config.mjs", + "dev": "node esbuild.config.mjs --watch", + "install-local": "bash scripts/install-local.sh", + "install-local:win": "powershell -File scripts/install-local.ps1", + "typecheck": "tsc --noEmit" + } +} +``` + +**验收**: 运行 `install-local` 脚本后重启 VS Code,Activity Bar 出现 Claude Code 图标,点击打开侧边栏,输入消息收到 CLI 响应。 + +--- + +## 构建顺序 + +``` +Step 0 (骨架) ─── 无依赖 ──────────────── 半天 + │ +Step 1 (Host) ─── 依赖 Step 0 ─────────── 1-2 天 + │ +Step 2 (WebView) ─ 依赖 Step 1 ─────────── 2-3 天 + │ +Step 3 (状态栏) ─ 依赖 Step 1 ─────────── 半天 + │ +Step 4 (测试+本地安装) ─ 依赖 Step 2+3 ──── 1 天 +``` + +**总计: 5-7 天** + +## Phase 1 简化决策 + +| 决策 | 说明 | +|------|------| +| 权限处理 | Phase 1 使用 `--permission-mode acceptEdits`,跳过权限弹窗 | +| 文件 diff | Phase 1 只在消息中展示文本 diff,不集成 VS Code diff editor | +| 会话管理 | Phase 1 单会话,不做历史/恢复 | +| MCP Server | Phase 1 不暴露 IDE 工具给 CLI | +| 模型切换 | Phase 1 使用 CLI 默认模型 | +| 多 IDE 兼容 | Phase 1 只测 VS Code,Cursor/Windsurf 延后 | + +## 部署方式:本地 symlink(不发布) + +本扩展**不发布到 VS Code Marketplace**,仅本地使用。 + +### 安装原理 + +VS Code 启动时扫描 `~/.vscode/extensions/` 下所有目录,查找含 `package.json` + `contributes` 的扩展。通过 symlink / junction 将 `packages/vscode-extension/` 链接到该目录,VS Code 即自动加载。 + +``` +~/.vscode/extensions/ +├── anthropic.claude-code-2.1.119-win32-x64/ # 官方扩展(共存) +├── claude-code-best-vscode/ # ← symlink → packages/vscode-extension/ +│ ├── package.json +│ ├── dist/extension.js +│ └── dist/webview.js +└── ... +``` + +### 与官方扩展共存 + +| 属性 | 官方扩展 | 我们的扩展 | +|------|---------|-----------| +| Extension ID | `anthropic.claude-code` | `claude-code-best.claude-code-best-vscode` | +| Activity Bar ID | `anthropic-claude-code` | `claude-code` | +| Lockfile 前缀 | `anthropic-` | `ccb-` | +| 命令前缀 | `claude-dev.` | `claude-code.` | + +ID 完全不同,不会冲突。 + +### 更新流程 + +```bash +cd packages/vscode-extension +bun run build # rebuild +# VS Code: Ctrl+Shift+P → "Developer: Reload Window" +``` + +因为是 symlink,`dist/` 更新后 VS Code reload 即可生效,无需重新安装。 + +### Cursor / Windsurf 支持 + +这些 fork 的扩展目录类似: +- Cursor: `~/.cursor/extensions/` +- Windsurf: `~/.windsurf/extensions/` + +安装脚本可加 `--target cursor|windsurf` 参数支持。Phase 1 先只做 VS Code。 + +## 风险 + +| 风险 | 缓解 | +|------|------| +| CLI stdout 混入非 JSON 输出 | 所有非 JSON 行归类为 stderr log | +| `--print` 模式下权限阻塞 | Phase 1 用 `--permission-mode acceptEdits` 绕过 | +| Windows 路径问题 | `CLIProcess` 用 `vscode.workspace.workspaceFolders` 获取规范路径 | +| WebView CSP 限制 | 只加载打包后的单文件 JS,不用外部资源 | +| Bun vs Node 运行时差异 | Extension Host 是 Node.js,CLI 是 Bun——已有 build 后的 `dist/cli-node.js` 兼容方案 | +| Windows symlink 权限 | 用 Directory Junction(`New-Item -ItemType Junction`)不需要管理员权限 | +| symlink 指向的源目录被移动/删除 | 安装脚本检查路径有效性,无效时报错提示重新安装 | diff --git a/docs/runbook/STATUS.md b/docs/runbook/STATUS.md new file mode 100644 index 000000000..1b92a32d7 --- /dev/null +++ b/docs/runbook/STATUS.md @@ -0,0 +1,32 @@ +# Runbook Status + +Updated: 2026-04-25 + +## Current Focus + +VS Code extension slash command parity and Windows ACP shell routing. + +## Gates + +| Gate | Owner | Status | Evidence | +| --- | --- | --- | --- | +| Project scope | project-lead | passed | `/mcp` parity scope limited to ACP metadata, slash completion, headless command handling, smoke coverage | +| Frontend slash menu | frontend | passed | `bun test packages/vscode-extension/webview/lib/__tests__/slashCommands.test.ts` | +| ACP command execution | backend | passed | `bun test src/services/acp/__tests__/agent.test.ts packages/vscode-extension/webview/lib/__tests__/slashCommands.test.ts` | +| Runtime install | ops | passed | `bun run install-local:win`; installed junction points to `packages/vscode-extension` | +| QA regression | qa | passed | `bun run typecheck`; `bunx biome lint . --max-diagnostics=1000`; `bun run build`; `bun test`; `bun run test:all` in `packages/vscode-extension` | +| Security review | security | passed | No new dependency, no secret material, no new direct terminal spawning path | +| Independent review | reviewer | passed | Verified MCP command metadata includes structured server catalog and built-in dynamic MCP entries | +| Windows shell routing | ops | passed | VS Code ACP on Windows exposes `PowerShell` instead of `Bash`; orphan `--acp` process check returned `NO_MATCHING_PROCESSES` | + +## Recovery + +If the local VS Code extension behaves stale after installation, fully quit all +VS Code windows and reopen. The local install path is: + +`C:\Users\12180\.vscode\extensions\claude-code-best.ccb-vscode-0.3.0` + +## Known Risks + +No accepted open risks for the current slash-command/shell-routing work. New risks must be +recorded here with owner, mitigation, and verification. diff --git a/package.json b/package.json index 38e3d76bd..6bea7b460 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "rcs": "bun run scripts/rcs.ts" }, "dependencies": { - "@agentclientprotocol/sdk": "^0.19.0", + "@agentclientprotocol/sdk": "^0.19.2", "@claude-code-best/mcp-chrome-bridge": "^3.0.1", "highlight.js": "^11.11.1", "ws": "^8.20.0" @@ -78,29 +78,29 @@ "@ant/computer-use-input": "workspace:*", "@ant/computer-use-mcp": "workspace:*", "@ant/computer-use-swift": "workspace:*", - "@anthropic-ai/bedrock-sdk": "^0.26.4", - "@anthropic-ai/claude-agent-sdk": "^0.2.114", + "@anthropic-ai/bedrock-sdk": "^0.29.0", + "@anthropic-ai/claude-agent-sdk": "^0.2.119", "@anthropic-ai/foundry-sdk": "^0.2.3", "@anthropic-ai/mcpb": "^2.1.2", "@anthropic-ai/sandbox-runtime": "^0.0.44", - "@anthropic-ai/sdk": "^0.80.0", + "@anthropic-ai/sdk": "^0.81.0", "@anthropic-ai/vertex-sdk": "^0.14.4", "@anthropic/ink": "workspace:*", - "@aws-sdk/client-bedrock": "^3.1032.0", - "@aws-sdk/client-bedrock-runtime": "^3.1032.0", - "@aws-sdk/client-sts": "^3.1032.0", - "@aws-sdk/credential-provider-node": "^3.972.32", - "@aws-sdk/credential-providers": "^3.1032.0", + "@aws-sdk/client-bedrock": "^3.1037.0", + "@aws-sdk/client-bedrock-runtime": "^3.1037.0", + "@aws-sdk/client-sts": "^3.1037.0", + "@aws-sdk/credential-provider-node": "^3.972.36", + "@aws-sdk/credential-providers": "^3.1037.0", "@azure/identity": "^4.13.1", - "@biomejs/biome": "^2.4.12", + "@biomejs/biome": "^2.4.13", "@claude-code-best/agent-tools": "workspace:*", "@claude-code-best/builtin-tools": "workspace:*", "@claude-code-best/mcp-client": "workspace:*", "@claude-code-best/weixin": "workspace:*", "@commander-js/extra-typings": "^14.0.0", "@growthbook/growthbook": "^1.6.5", - "@langfuse/otel": "^5.1.0", - "@langfuse/tracing": "^5.1.0", + "@langfuse/otel": "^5.2.0", + "@langfuse/tracing": "^5.2.0", "@modelcontextprotocol/sdk": "^1.29.0", "@opentelemetry/api": "^1.9.1", "@opentelemetry/api-logs": "^0.214.0", @@ -120,10 +120,10 @@ "@opentelemetry/sdk-metrics": "^2.7.0", "@opentelemetry/sdk-trace-base": "^2.7.0", "@opentelemetry/semantic-conventions": "^1.40.0", - "@sentry/node": "^10.49.0", - "@smithy/core": "^3.23.15", - "@smithy/node-http-handler": "^4.5.3", - "@types/bun": "^1.3.12", + "@sentry/node": "^10.50.0", + "@smithy/core": "^3.23.17", + "@smithy/node-http-handler": "^4.6.1", + "@types/bun": "^1.3.13", "@types/cacache": "^20.0.1", "@types/he": "^1.2.3", "@types/lodash-es": "^4.17.12", @@ -140,11 +140,11 @@ "@types/stack-utils": "^2.0.3", "@types/turndown": "^5.0.6", "@types/ws": "^8.18.1", - "ajv": "^8.18.0", + "ajv": "^8.20.0", "asciichart": "^1.5.25", "audio-capture-napi": "workspace:*", "auto-bind": "^5.0.1", - "axios": "^1.15.0", + "axios": "^1.15.2", "bidi-js": "^1.0.3", "cacache": "^20.0.4", "chalk": "^5.6.2", @@ -168,7 +168,7 @@ "image-processor-napi": "workspace:*", "indent-string": "^5.0.0", "jsonc-parser": "^3.3.1", - "knip": "^6.4.1", + "knip": "^6.6.3", "lodash-es": "^4.18.1", "lru-cache": "^11.3.5", "marked": "^17.0.6", @@ -197,7 +197,7 @@ "undici": "^7.25.0", "url-handler-napi": "workspace:*", "usehooks-ts": "^3.1.1", - "vite": "^8.0.8", + "vite": "^8.0.10", "vscode-jsonrpc": "^8.2.1", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-types": "^3.17.5", @@ -208,5 +208,16 @@ }, "optionalDependencies": { "doubaoime-asr": "^0.1.0" + }, + "overrides": { + "@xmldom/xmldom": "0.8.13", + "esbuild": "0.28.0", + "fast-xml-parser": "5.7.1", + "follow-redirects": "1.16.0", + "hono": "4.12.15", + "postcss": "8.5.10", + "protobufjs": "7.5.5", + "tmp": "0.2.5", + "uuid": "14.0.0" } } diff --git a/packages/@ant/model-provider/package.json b/packages/@ant/model-provider/package.json index bd58d736f..64a72a1f4 100644 --- a/packages/@ant/model-provider/package.json +++ b/packages/@ant/model-provider/package.json @@ -12,7 +12,7 @@ "./client": "./src/client/index.ts" }, "dependencies": { - "@anthropic-ai/sdk": "^0.80.0", + "@anthropic-ai/sdk": "^0.81.0", "openai": "^6.33.0" } } diff --git a/packages/acp-link/package.json b/packages/acp-link/package.json index 2a39c27c3..e26596657 100644 --- a/packages/acp-link/package.json +++ b/packages/acp-link/package.json @@ -30,7 +30,7 @@ "@hono/node-ws": "^1.0.5", "@stricli/auto-complete": "^1.2.4", "@stricli/core": "^1.2.4", - "hono": "^4.7.0", + "hono": "^4.12.15", "pino": "^10.3.0", "pino-pretty": "^13.1.3", "selfsigned": "^5.5.0" diff --git a/packages/builtin-tools/src/tools/BashTool/BashTool.tsx b/packages/builtin-tools/src/tools/BashTool/BashTool.tsx index 5966ba418..3b575f8a6 100644 --- a/packages/builtin-tools/src/tools/BashTool/BashTool.tsx +++ b/packages/builtin-tools/src/tools/BashTool/BashTool.tsx @@ -1140,7 +1140,7 @@ async function* runShellCommand({ let lastProgressOutput = '' let lastTotalLines = 0 let lastTotalBytes = 0 - let backgroundShellId: string | undefined = undefined + let backgroundShellId: string | undefined let assistantAutoBackgrounded = false // Progress signal: resolved by onProgress callback from the shared poller, @@ -1314,7 +1314,7 @@ async function* runShellCommand({ // Wait for the initial threshold before showing progress const startTime = Date.now() - let foregroundTaskId: string | undefined = undefined + let foregroundTaskId: string | undefined { const initialResult = await Promise.race([ diff --git a/packages/builtin-tools/src/tools/BashTool/bashSecurity.ts b/packages/builtin-tools/src/tools/BashTool/bashSecurity.ts index e274037f1..0703aaa7d 100644 --- a/packages/builtin-tools/src/tools/BashTool/bashSecurity.ts +++ b/packages/builtin-tools/src/tools/BashTool/bashSecurity.ts @@ -26,7 +26,7 @@ const COMMAND_SUBSTITUTION_PATTERNS = [ message: 'Zsh equals expansion (=cmd)', }, { pattern: /\$\(/, message: '$() command substitution' }, - { pattern: /\$\{/, message: '${} parameter substitution' }, + { pattern: /\$\{/, message: '$' + '{} parameter substitution' }, { pattern: /\$\[/, message: '$[] legacy arithmetic expansion' }, { pattern: /~\[/, message: 'Zsh-style parameter expansion' }, { pattern: /\(e:/, message: 'Zsh-style glob qualifiers' }, @@ -992,11 +992,9 @@ function validateCarriageReturn(context: ValidationContext): PermissionResult { } if (c === "'" && !inDoubleQuote) { inSingleQuote = !inSingleQuote - continue } if (c === '"' && !inSingleQuote) { inDoubleQuote = !inDoubleQuote - continue } if (c === '\r' && !inDoubleQuote) { logEvent('tengu_bash_security_check_triggered', { @@ -1573,7 +1571,6 @@ function hasBackslashEscapedWhitespace(command: string): boolean { if (char === "'" && !inDoubleQuote) { inSingleQuote = !inSingleQuote - continue } } @@ -1686,7 +1683,6 @@ function hasBackslashEscapedOperator(command: string): boolean { } if (char === '"' && !inSingleQuote) { inDoubleQuote = !inDoubleQuote - continue } } @@ -2247,8 +2243,8 @@ function validateZshDangerousCommands( // validators. Bash silently drops null bytes and ignores most control chars, // so an attacker can use them to slip metacharacters past our checks while // bash still executes them (e.g., "echo safe\x00; rm -rf /"). -// eslint-disable-next-line no-control-regex -const CONTROL_CHAR_RE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/ +const CONTROL_CHAR_PATTERN = String.raw`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]` +const CONTROL_CHAR_RE = new RegExp(CONTROL_CHAR_PATTERN) /** * @deprecated Legacy regex/shell-quote path. Only used when tree-sitter is diff --git a/packages/builtin-tools/src/tools/BashTool/sedValidation.ts b/packages/builtin-tools/src/tools/BashTool/sedValidation.ts index 1b6c7898b..e2c47037b 100644 --- a/packages/builtin-tools/src/tools/BashTool/sedValidation.ts +++ b/packages/builtin-tools/src/tools/BashTool/sedValidation.ts @@ -3,6 +3,9 @@ import { splitCommand_DEPRECATED } from 'src/utils/bash/commands.js' import { tryParseShellCommand } from 'src/utils/bash/shellQuote.js' import type { PermissionResult } from 'src/utils/permissions/PermissionResult.js' +const NON_ASCII_PATTERN = String.raw`[^\x01-\x7F]` +const NON_ASCII_RE = new RegExp(NON_ASCII_PATTERN) + /** * Helper: Validate flags against an allowlist * Handles both single flags and combined flags (e.g., -nE) @@ -480,8 +483,7 @@ function containsDangerousOperations(expression: string): boolean { // Reject non-ASCII characters (Unicode homoglyphs, combining chars, etc.) // Examples: w (fullwidth), ᴡ (small capital), w̃ (combining tilde) // Check for characters outside ASCII range (0x01-0x7F, excluding null byte) - // eslint-disable-next-line no-control-regex - if (/[^\x01-\x7F]/.test(cmd)) { + if (NON_ASCII_RE.test(cmd)) { return true } diff --git a/packages/builtin-tools/src/tools/FileReadTool/imageProcessor.ts b/packages/builtin-tools/src/tools/FileReadTool/imageProcessor.ts index de7ea4905..6ee07a746 100644 --- a/packages/builtin-tools/src/tools/FileReadTool/imageProcessor.ts +++ b/packages/builtin-tools/src/tools/FileReadTool/imageProcessor.ts @@ -49,7 +49,6 @@ export async function getImageProcessor(): Promise { return sharpFn } catch { // Fall back to sharp if native module is not available - // biome-ignore lint/suspicious/noConsole: intentional warning console.warn( 'Native image processor not available, falling back to sharp', ) diff --git a/packages/builtin-tools/src/tools/NotebookEditTool/NotebookEditTool.ts b/packages/builtin-tools/src/tools/NotebookEditTool/NotebookEditTool.ts index ac828efc8..1675bf677 100644 --- a/packages/builtin-tools/src/tools/NotebookEditTool/NotebookEditTool.ts +++ b/packages/builtin-tools/src/tools/NotebookEditTool/NotebookEditTool.ts @@ -377,7 +377,7 @@ export const NotebookEditTool = buildTool({ } const language = notebook.metadata.language_info?.name ?? 'python' - let new_cell_id = undefined + let new_cell_id: string | undefined if ( notebook.nbformat > 4 || (notebook.nbformat === 4 && notebook.nbformat_minor >= 5) diff --git a/packages/builtin-tools/src/tools/PowerShellTool/PowerShellTool.tsx b/packages/builtin-tools/src/tools/PowerShellTool/PowerShellTool.tsx index 2b5d7f7fb..499e3b264 100644 --- a/packages/builtin-tools/src/tools/PowerShellTool/PowerShellTool.tsx +++ b/packages/builtin-tools/src/tools/PowerShellTool/PowerShellTool.tsx @@ -908,7 +908,7 @@ async function* runPowerShellCommand({ let lastProgressOutput = '' let lastTotalLines = 0 let lastTotalBytes = 0 - let backgroundShellId: string | undefined = undefined + let backgroundShellId: string | undefined let interruptBackgroundingStarted = false let assistantAutoBackgrounded = false @@ -1109,7 +1109,7 @@ async function* runPowerShellCommand({ // Set up progress yielding with periodic checks const startTime = Date.now() let nextProgressTime = startTime + PROGRESS_THRESHOLD_MS - let foregroundTaskId: string | undefined = undefined + let foregroundTaskId: string | undefined // Progress loop: wrap in try/finally so stopPolling is called on every exit // path — normal completion, timeout/interrupt backgrounding, and Ctrl+B diff --git a/packages/builtin-tools/src/tools/WebFetchTool/utils.ts b/packages/builtin-tools/src/tools/WebFetchTool/utils.ts index 0d8576ece..5ef3158da 100644 --- a/packages/builtin-tools/src/tools/WebFetchTool/utils.ts +++ b/packages/builtin-tools/src/tools/WebFetchTool/utils.ts @@ -58,6 +58,23 @@ type CacheEntry = { persistedSize?: number } +function getResponseHeader( + headers: AxiosResponse['headers'], + name: string, +): string | undefined { + const value = headers[name] + if (typeof value === 'string') { + return value + } + if (Array.isArray(value)) { + return value.join(', ') + } + if (typeof value === 'number' || typeof value === 'boolean') { + return String(value) + } + return undefined +} + // Cache with 15-minute TTL and 50MB size limit // LRUCache handles automatic expiration and eviction const CACHE_TTL_MS = 15 * 60 * 1000 // 15 minutes @@ -286,7 +303,10 @@ export async function getWithPermittedRedirects( error.response && [301, 302, 307, 308].includes(error.response.status) ) { - const redirectLocation = error.response.headers.location + const redirectLocation = getResponseHeader( + error.response.headers, + 'location', + ) if (!redirectLocation) { throw new Error('Redirect missing Location header') } @@ -318,7 +338,8 @@ export async function getWithPermittedRedirects( if ( axios.isAxiosError(error) && error.response?.status === 403 && - error.response.headers['x-proxy-error'] === 'blocked-by-allowlist' + getResponseHeader(error.response.headers, 'x-proxy-error') === + 'blocked-by-allowlist' ) { const hostname = new URL(url).hostname throw new EgressBlockedError(hostname) @@ -430,7 +451,7 @@ export async function getURLMarkdownContent( // This lets GC reclaim up to MAX_HTTP_CONTENT_LENGTH (10MB) before Turndown // builds its DOM tree (which can be 3-5x the HTML size). ;(response as { data: unknown }).data = null - const contentType = response.headers['content-type'] ?? '' + const contentType = getResponseHeader(response.headers, 'content-type') ?? '' // Binary content: save raw bytes to disk with a proper extension so Claude // can inspect the file later. We still fall through to the utf-8 decode + diff --git a/packages/builtin-tools/src/tools/WebSearchTool/adapters/exaAdapter.ts b/packages/builtin-tools/src/tools/WebSearchTool/adapters/exaAdapter.ts index 4ebde5842..2bdcea36f 100644 --- a/packages/builtin-tools/src/tools/WebSearchTool/adapters/exaAdapter.ts +++ b/packages/builtin-tools/src/tools/WebSearchTool/adapters/exaAdapter.ts @@ -173,7 +173,7 @@ export class ExaSearchAdapter implements WebSearchAdapter { // Fallback: markdown links if (results.length === 0) { - const markdownLinkRegex = /\[([^\]]+)\]\((https?:\/\/[^\)]+)\)/g + const markdownLinkRegex = /\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g let match: RegExpExecArray | null while ((match = markdownLinkRegex.exec(text)) !== null) { results.push({ diff --git a/packages/color-diff-napi/src/__tests__/color-diff.test.ts b/packages/color-diff-napi/src/__tests__/color-diff.test.ts index 2c95cc8b4..50388f90d 100644 --- a/packages/color-diff-napi/src/__tests__/color-diff.test.ts +++ b/packages/color-diff-napi/src/__tests__/color-diff.test.ts @@ -2,6 +2,8 @@ import { describe, expect, test } from "bun:test"; import { __test } from "../index"; const { ansi256FromRgb, colorToEscape, detectColorMode, detectLanguage, tokenize } = __test; +const ESC = String.fromCharCode(27); +const color256EscapePattern = new RegExp(`^${ESC}\\[38;5;\\d+m$`); describe("ansi256FromRgb", () => { test("black maps to index 16", () => { @@ -54,7 +56,7 @@ describe("colorToEscape", () => { test("color256 uses 256-color escape", () => { const color = { r: 100, g: 150, b: 200, a: 255 }; const result = colorToEscape(color, true, "color256"); - expect(result).toMatch(/^\x1b\[38;5;\d+m$/); + expect(result).toMatch(color256EscapePattern); }); }); diff --git a/packages/mcp-client/src/connection.ts b/packages/mcp-client/src/connection.ts index 30f3b18d6..f24d86642 100644 --- a/packages/mcp-client/src/connection.ts +++ b/packages/mcp-client/src/connection.ts @@ -310,94 +310,77 @@ export async function terminateWithSignalEscalation( return } - await new Promise(async resolve => { + await new Promise(resolve => { let resolved = false + let checkInterval: ReturnType + let failsafeTimeout: ReturnType + + const finish = (message?: string) => { + if (resolved) return + resolved = true + clearInterval(checkInterval) + clearTimeout(failsafeTimeout) + if (message) logger.debug(message) + resolve() + } - const checkInterval = setInterval(() => { + checkInterval = setInterval(() => { try { process.kill(childPid, 0) } catch { - if (!resolved) { - resolved = true - clearInterval(checkInterval) - clearTimeout(failsafeTimeout) - logger.debug(`[${serverName}] MCP server process exited cleanly`) - resolve() - } + finish(`[${serverName}] MCP server process exited cleanly`) } }, 50) - const failsafeTimeout = setTimeout(() => { - if (!resolved) { - resolved = true - clearInterval(checkInterval) - logger.debug(`[${serverName}] Cleanup timeout reached, stopping process monitoring`) - resolve() - } + failsafeTimeout = setTimeout(() => { + finish(`[${serverName}] Cleanup timeout reached, stopping process monitoring`) }, 600) - try { - // Wait 100ms for SIGINT to work - await sleep(100) - - if (!resolved) { - try { - process.kill(childPid, 0) - // Process still exists, try SIGTERM - logger.debug(`[${serverName}] SIGINT failed, sending SIGTERM`) - try { - process.kill(childPid, 'SIGTERM') - } catch (termError) { - logger.debug(`[${serverName}] Error sending SIGTERM: ${termError}`) - resolved = true - clearInterval(checkInterval) - clearTimeout(failsafeTimeout) - resolve() - return - } - } catch { - resolved = true - clearInterval(checkInterval) - clearTimeout(failsafeTimeout) - resolve() - return - } - - // Wait 400ms for SIGTERM - await sleep(400) + void (async () => { + try { + // Wait 100ms for SIGINT to work + await sleep(100) if (!resolved) { try { process.kill(childPid, 0) - logger.debug(`[${serverName}] SIGTERM failed, sending SIGKILL`) + // Process still exists, try SIGTERM + logger.debug(`[${serverName}] SIGINT failed, sending SIGTERM`) try { - process.kill(childPid, 'SIGKILL') - } catch (killError) { - logger.debug(`[${serverName}] Error sending SIGKILL: ${killError}`) + process.kill(childPid, 'SIGTERM') + } catch (termError) { + logger.debug(`[${serverName}] Error sending SIGTERM: ${termError}`) + finish() + return } } catch { - resolved = true - clearInterval(checkInterval) - clearTimeout(failsafeTimeout) - resolve() + finish() + return + } + + // Wait 400ms for SIGTERM + await sleep(400) + + if (!resolved) { + try { + process.kill(childPid, 0) + logger.debug(`[${serverName}] SIGTERM failed, sending SIGKILL`) + try { + process.kill(childPid, 'SIGKILL') + } catch (killError) { + logger.debug(`[${serverName}] Error sending SIGKILL: ${killError}`) + } + } catch { + finish() + } } } - } - if (!resolved) { - resolved = true - clearInterval(checkInterval) - clearTimeout(failsafeTimeout) - resolve() - } - } catch { - if (!resolved) { - resolved = true - clearInterval(checkInterval) - clearTimeout(failsafeTimeout) - resolve() + finish() + } catch { + finish() } - } + })() }) } catch (processError) { logger.debug(`[${serverName}] Error terminating process: ${processError}`) diff --git a/packages/mcp-client/src/sanitization.ts b/packages/mcp-client/src/sanitization.ts index 91713fc73..94cb06711 100644 --- a/packages/mcp-client/src/sanitization.ts +++ b/packages/mcp-client/src/sanitization.ts @@ -1,6 +1,9 @@ // Unicode sanitization for MCP data // Extracted from src/utils/sanitization.ts +const CONTROL_CHAR_PATTERN = String.raw`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]` +const CONTROL_CHAR_RE = new RegExp(CONTROL_CHAR_PATTERN, 'g') + /** * Recursively sanitizes Unicode characters in MCP server responses. * Removes or replaces problematic Unicode that could cause display or parsing issues. @@ -10,7 +13,7 @@ export function recursivelySanitizeUnicode(data: T): T { // Remove control characters except \t, \n, \r // Replace null bytes and other C0 controls return data - .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '') + .replace(CONTROL_CHAR_RE, '') .replace(/\uFFFD/g, '') // replacement character .normalize('NFC') as unknown as T } diff --git a/packages/remote-control-server/package.json b/packages/remote-control-server/package.json index 1586eaa9b..65baec317 100644 --- a/packages/remote-control-server/package.json +++ b/packages/remote-control-server/package.json @@ -13,10 +13,10 @@ "dependencies": { "@ai-sdk/react": "^3.0.170", "ai": "^6.0.168", - "hono": "^4.7.0", + "hono": "^4.12.15", "jsqr": "^1.4.0", "qrcode": "^1.5.4", - "uuid": "^11.0.0", + "uuid": "^14.0.0", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", diff --git a/packages/remote-control-server/src/__tests__/routes.test.ts b/packages/remote-control-server/src/__tests__/routes.test.ts index c061bbf25..a2960eacc 100644 --- a/packages/remote-control-server/src/__tests__/routes.test.ts +++ b/packages/remote-control-server/src/__tests__/routes.test.ts @@ -1204,8 +1204,8 @@ describe("V1 Session Ingress Routes (HTTP)", () => { }; }); - expect(message).toContain("\"type\":\"user\""); - expect(message).toContain(`\"session_id\":\"${id}\"`); + expect(message).toContain('"type":"user"'); + expect(message).toContain(`"session_id":"${id}"`); expect(message).toContain("compat ws replay"); } finally { await server.stop(true); diff --git a/packages/remote-control-server/src/__tests__/sse-writer.test.ts b/packages/remote-control-server/src/__tests__/sse-writer.test.ts index c2ed6f37b..b43dc4696 100644 --- a/packages/remote-control-server/src/__tests__/sse-writer.test.ts +++ b/packages/remote-control-server/src/__tests__/sse-writer.test.ts @@ -117,7 +117,7 @@ describe("SSE Writer", () => { app.get("/stream/:sessionId", (c) => { const sessionId = c.req.param("sessionId"); - const fromSeq = parseInt(c.req.query("fromSeq") || "0"); + const fromSeq = parseInt(c.req.query("fromSeq") || "0", 10); return createSSEStream(c, sessionId, fromSeq); }); diff --git a/packages/remote-control-server/src/config.ts b/packages/remote-control-server/src/config.ts index 39ba2c400..f2503cf4a 100644 --- a/packages/remote-control-server/src/config.ts +++ b/packages/remote-control-server/src/config.ts @@ -1,20 +1,20 @@ export const config = { version: process.env.RCS_VERSION || "0.1.0", - port: parseInt(process.env.RCS_PORT || "3000"), + port: parseInt(process.env.RCS_PORT || "3000", 10), host: process.env.RCS_HOST || "0.0.0.0", apiKeys: (process.env.RCS_API_KEYS || "").split(",").filter(Boolean), baseUrl: process.env.RCS_BASE_URL || "", - pollTimeout: parseInt(process.env.RCS_POLL_TIMEOUT || "8"), - heartbeatInterval: parseInt(process.env.RCS_HEARTBEAT_INTERVAL || "20"), - jwtExpiresIn: parseInt(process.env.RCS_JWT_EXPIRES_IN || "3600"), - disconnectTimeout: parseInt(process.env.RCS_DISCONNECT_TIMEOUT || "300"), + pollTimeout: parseInt(process.env.RCS_POLL_TIMEOUT || "8", 10), + heartbeatInterval: parseInt(process.env.RCS_HEARTBEAT_INTERVAL || "20", 10), + jwtExpiresIn: parseInt(process.env.RCS_JWT_EXPIRES_IN || "3600", 10), + disconnectTimeout: parseInt(process.env.RCS_DISCONNECT_TIMEOUT || "300", 10), /** Bun WebSocket idle timeout (seconds). Bun sends protocol-level pings after * this many seconds of no received data. Must be shorter than any reverse * proxy's idle timeout (nginx default 60s, Cloudflare 100s). Default 30s. */ - wsIdleTimeout: parseInt(process.env.RCS_WS_IDLE_TIMEOUT || "30"), + wsIdleTimeout: parseInt(process.env.RCS_WS_IDLE_TIMEOUT || "30", 10), /** Server→client keep_alive data-frame interval (seconds). Keeps reverse * proxies from closing idle connections. Default 20s. */ - wsKeepaliveInterval: parseInt(process.env.RCS_WS_KEEPALIVE_INTERVAL || "20"), + wsKeepaliveInterval: parseInt(process.env.RCS_WS_KEEPALIVE_INTERVAL || "20", 10), } as const; export function getBaseUrl(): string { diff --git a/packages/remote-control-server/src/routes/acp/index.ts b/packages/remote-control-server/src/routes/acp/index.ts index faef347ea..a7400644c 100644 --- a/packages/remote-control-server/src/routes/acp/index.ts +++ b/packages/remote-control-server/src/routes/acp/index.ts @@ -100,7 +100,7 @@ app.get("/channel-groups/:id/events", async (c) => { // Support Last-Event-ID / from_sequence_num for reconnection const lastEventId = c.req.header("Last-Event-ID"); const fromSeq = c.req.query("from_sequence_num"); - const fromSeqNum = fromSeq ? parseInt(fromSeq) : lastEventId ? parseInt(lastEventId) : 0; + const fromSeqNum = fromSeq ? parseInt(fromSeq, 10) : lastEventId ? parseInt(lastEventId, 10) : 0; return createAcpSSEStream(c, groupId, fromSeqNum); }); diff --git a/packages/remote-control-server/src/routes/v2/worker-events-stream.ts b/packages/remote-control-server/src/routes/v2/worker-events-stream.ts index 02b605a43..21e86ab94 100644 --- a/packages/remote-control-server/src/routes/v2/worker-events-stream.ts +++ b/packages/remote-control-server/src/routes/v2/worker-events-stream.ts @@ -16,7 +16,7 @@ app.get("/:id/worker/events/stream", acceptCliHeaders, sessionIngressAuth, async // Support Last-Event-ID / from_sequence_num for reconnection const lastEventId = c.req.header("Last-Event-ID"); const fromSeq = c.req.query("from_sequence_num"); - const fromSeqNum = fromSeq ? parseInt(fromSeq) : lastEventId ? parseInt(lastEventId) : 0; + const fromSeqNum = fromSeq ? parseInt(fromSeq, 10) : lastEventId ? parseInt(lastEventId, 10) : 0; return createWorkerEventStream(c, sessionId, fromSeqNum); }); diff --git a/packages/remote-control-server/src/routes/web/sessions.ts b/packages/remote-control-server/src/routes/web/sessions.ts index 8f2f4380a..f77adf16d 100644 --- a/packages/remote-control-server/src/routes/web/sessions.ts +++ b/packages/remote-control-server/src/routes/web/sessions.ts @@ -111,7 +111,7 @@ app.get("/sessions/:id/events", uuidAuth, async (c) => { } const lastEventId = c.req.header("Last-Event-ID"); - const fromSeqNum = lastEventId ? parseInt(lastEventId) : 0; + const fromSeqNum = lastEventId ? parseInt(lastEventId, 10) : 0; return createSSEStream(c, sessionId, fromSeqNum); }); diff --git a/packages/remote-control-server/src/services/automationState.ts b/packages/remote-control-server/src/services/automationState.ts index 544d885cc..2ef5c313b 100644 --- a/packages/remote-control-server/src/services/automationState.ts +++ b/packages/remote-control-server/src/services/automationState.ts @@ -29,7 +29,7 @@ function readAutomationStateValue(metadata: Record | null | und if (!metadata || typeof metadata !== "object") { return undefined; } - if (!Object.prototype.hasOwnProperty.call(metadata, "automation_state")) { + if (!Object.hasOwn(metadata, "automation_state")) { return undefined; } return metadata.automation_state; diff --git a/packages/remote-control-server/web/src/acp/client.ts b/packages/remote-control-server/web/src/acp/client.ts index 81af976d8..18ce753a7 100644 --- a/packages/remote-control-server/web/src/acp/client.ts +++ b/packages/remote-control-server/web/src/acp/client.ts @@ -57,9 +57,7 @@ export class ACPClient { private ws: WebSocket | null = null; private settings: ACPSettings; private connectionState: ConnectionState = "disconnected"; - private sessionId: string | null = null; - private pendingSessionTarget: string | null = null; - // Reference: Zed stores full agentCapabilities from initialize response + private sessionId: string | null = null; // Reference: Zed stores full agentCapabilities from initialize response // Used to check supports_load_session, supports_resume_session, etc. private _agentCapabilities: AgentCapabilities | null = null; // Reference: Zed's prompt_capabilities in MessageEditor @@ -87,7 +85,7 @@ export class ACPClient { private pendingSessionLoad: { resolve: (sessionId: string) => void; reject: (err: Error) => void; timer: ReturnType } | null = null; private pendingSessionResume: { resolve: (sessionId: string) => void; reject: (err: Error) => void; timer: ReturnType } | null = null; - private connectResolve: ((value: void) => void) | null = null; + private connectResolve: (() => void) | null = null; private connectReject: ((error: Error) => void) | null = null; // Heartbeat state @@ -365,9 +363,7 @@ export class ACPClient { case "error": console.error("[ACPClient] Error:", response.payload); - const errorMsg = response.payload?.message || JSON.stringify(response.payload); - this.pendingSessionTarget = null; - // Reject pending session operations if any (clear their timers) + const errorMsg = response.payload?.message || JSON.stringify(response.payload); // Reject pending session operations if any (clear their timers) if (this.pendingSessionList) { clearTimeout(this.pendingSessionList.timer); this.pendingSessionList.reject(new Error(errorMsg)); @@ -396,9 +392,7 @@ export class ACPClient { break; case "session_created": - this.sessionId = response.payload.sessionId; - this.pendingSessionTarget = null; - // Reference: Zed stores promptCapabilities from session/initialize response + this.sessionId = response.payload.sessionId; // Reference: Zed stores promptCapabilities from session/initialize response this._promptCapabilities = response.payload.promptCapabilities ?? null; // Reference: Zed stores model state from NewSessionResponse.models this._modelState = response.payload.models ?? null; @@ -419,9 +413,7 @@ export class ACPClient { break; case "session_loaded": - this.sessionId = response.payload.sessionId; - this.pendingSessionTarget = null; - this._promptCapabilities = response.payload.promptCapabilities ?? null; + this.sessionId = response.payload.sessionId; this._promptCapabilities = response.payload.promptCapabilities ?? null; this._modelState = response.payload.models ?? null; console.log("[ACPClient] Session loaded:", response.payload.sessionId); if (this.pendingSessionLoad) { @@ -434,9 +426,7 @@ export class ACPClient { break; case "session_resumed": - this.sessionId = response.payload.sessionId; - this.pendingSessionTarget = null; - this._promptCapabilities = response.payload.promptCapabilities ?? null; + this.sessionId = response.payload.sessionId; this._promptCapabilities = response.payload.promptCapabilities ?? null; this._modelState = response.payload.models ?? null; console.log("[ACPClient] Session resumed:", response.payload.sessionId); if (this.pendingSessionResume) { @@ -663,13 +653,9 @@ export class ACPClient { if (!this.supportsLoadSession) { throw new Error("Loading sessions is not supported by this agent"); } - return new Promise((resolve, reject) => { - this.pendingSessionTarget = request.sessionId; - this.onSessionSwitching?.(request.sessionId); + return new Promise((resolve, reject) => { this.onSessionSwitching?.(request.sessionId); const timer = setTimeout(() => { - if (this.pendingSessionLoad) { - this.pendingSessionTarget = null; - this.pendingSessionLoad = null; + if (this.pendingSessionLoad) { this.pendingSessionLoad = null; reject(new Error("Load session timed out")); } }, 60000); @@ -677,9 +663,7 @@ export class ACPClient { try { this.send({ type: "load_session", payload: request }); } catch (err) { - clearTimeout(timer); - this.pendingSessionTarget = null; - this.pendingSessionLoad = null; + clearTimeout(timer); this.pendingSessionLoad = null; reject(err); } }); @@ -694,13 +678,9 @@ export class ACPClient { if (!this.supportsResumeSession) { throw new Error("Resuming sessions is not supported by this agent"); } - return new Promise((resolve, reject) => { - this.pendingSessionTarget = request.sessionId; - this.onSessionSwitching?.(request.sessionId); + return new Promise((resolve, reject) => { this.onSessionSwitching?.(request.sessionId); const timer = setTimeout(() => { - if (this.pendingSessionResume) { - this.pendingSessionTarget = null; - this.pendingSessionResume = null; + if (this.pendingSessionResume) { this.pendingSessionResume = null; reject(new Error("Resume session timed out")); } }, 30000); @@ -708,9 +688,7 @@ export class ACPClient { try { this.send({ type: "resume_session", payload: request }); } catch (err) { - clearTimeout(timer); - this.pendingSessionTarget = null; - this.pendingSessionResume = null; + clearTimeout(timer); this.pendingSessionResume = null; reject(err); } }); @@ -738,9 +716,7 @@ export class ACPClient { this.ws = null; } this.setState("disconnected"); - this.sessionId = null; - this.pendingSessionTarget = null; - this._modelState = null; + this.sessionId = null; this._modelState = null; this._agentCapabilities = null; this._availableCommands = []; // Notify model state subscribers that session is gone diff --git a/packages/remote-control-server/web/src/components/EventStream.tsx b/packages/remote-control-server/web/src/components/EventStream.tsx index 8aca84884..3f8cabe88 100644 --- a/packages/remote-control-server/web/src/components/EventStream.tsx +++ b/packages/remote-control-server/web/src/components/EventStream.tsx @@ -1,3 +1,4 @@ +// biome-ignore-all lint/security/noDangerouslySetInnerHtml: formatted assistant and plan HTML is escaped before controlled markup is injected. import { useState, useEffect, useRef } from "react"; import type { SessionEvent, EventPayload } from "../types"; import { esc, truncate, cn, extractEventText, isConversationClearedStatus } from "../lib/utils"; @@ -788,7 +789,7 @@ function LoadingIndicator({ verb }: { verb: string }) { // Event Processing Hook // ============================================================ -export { type DisplayMessage, type TraceEntry, type UserMessage, type AssistantMessage, type SystemMessage, type PermissionMessage, type AskUserMessage, type PlanMessage, type LoadingMessage }; +export type { DisplayMessage, TraceEntry, UserMessage, AssistantMessage, SystemMessage, PermissionMessage, AskUserMessage, PlanMessage, LoadingMessage }; export function useEventProcessor() { const [messages, setMessages] = useState([]); diff --git a/packages/remote-control-server/web/src/components/PermissionViews.tsx b/packages/remote-control-server/web/src/components/PermissionViews.tsx index 3a70a30bc..6d340a4af 100644 --- a/packages/remote-control-server/web/src/components/PermissionViews.tsx +++ b/packages/remote-control-server/web/src/components/PermissionViews.tsx @@ -1,3 +1,4 @@ +// biome-ignore-all lint/security/noDangerouslySetInnerHtml: plan content is escaped before controlled markup is injected. import { useState } from "react"; import type { Question } from "../types"; import { esc, cn, truncate } from "../lib/utils"; diff --git a/packages/remote-control-server/web/src/index.css b/packages/remote-control-server/web/src/index.css index e760e2615..137f3ecad 100644 --- a/packages/remote-control-server/web/src/index.css +++ b/packages/remote-control-server/web/src/index.css @@ -1,3 +1,4 @@ +/* biome-ignore-all lint/complexity/noImportantStyles: reduced-motion reset intentionally overrides component animation styles. */ /* Font imports must precede @import "tailwindcss" per CSS spec */ @import url("https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Poppins:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"); diff --git a/packages/vscode-extension/.vscodeignore b/packages/vscode-extension/.vscodeignore new file mode 100644 index 000000000..3ccf99dfb --- /dev/null +++ b/packages/vscode-extension/.vscodeignore @@ -0,0 +1,9 @@ +node_modules/ +src/ +webview/ +scripts/ +.vscode/ +tsconfig.json +esbuild.config.mjs +.vscodeignore +*.map diff --git a/packages/vscode-extension/README.md b/packages/vscode-extension/README.md new file mode 100644 index 000000000..339d14174 --- /dev/null +++ b/packages/vscode-extension/README.md @@ -0,0 +1,76 @@ +# CCB VS Code Extension + +This directory contains the full source for the VS Code extension. + +The extension is committed to the repository for review and development, while the packaged VSIX intentionally ships only compiled assets and required metadata. + +## Source Layout + +| Path | Purpose | +| --- | --- | +| `src/` | VS Code extension host code. It starts and manages the ACP agent process, registers commands, bridges editor state, and owns extension lifecycle. | +| `webview/` | React webview source. It renders chat, slash commands, permissions, model/mode selectors, plans, and tool call cards. | +| `webview/lib/` | Shared webview protocol, ACP-facing types, slash-command parsing, and thread reducer logic. | +| `scripts/` | Local install and smoke-test scripts. | +| `resources/` | VS Code extension resources, including the activity bar icon. | +| `dist/` | Build output generated by `bun run build`; this is what the VSIX loads at runtime. | + +## Development Install + +From the repository root: + +```powershell +bun run build +cd packages\vscode-extension +bun run install-local:win +``` + +On macOS/Linux: + +```bash +bun run build +cd packages/vscode-extension +bun run install-local +``` + +Fully quit VS Code and reopen it after installation. + +## Build and Smoke Test + +```powershell +cd packages\vscode-extension +bun run test:all +``` + +The smoke test covers extension manifest loading, ACP startup, slash-command metadata, and `/mcp tools claude-in-chrome`. + +## Packaging Boundary + +`packages/vscode-extension/.vscodeignore` excludes source and test files from the VSIX: + +```text +src/ +webview/ +scripts/ +node_modules/ +tsconfig.json +esbuild.config.mjs +*.map +``` + +Before publishing, verify package contents: + +```powershell +npx @vscode/vsce ls --no-dependencies +``` + +Expected packaged files: + +```text +package.json +resources/icon.svg +dist/webview.js +dist/extension.js +``` + +Do not remove the source exclusions unless the release policy changes and the VSIX contents are reviewed again. diff --git a/packages/vscode-extension/esbuild.config.mjs b/packages/vscode-extension/esbuild.config.mjs new file mode 100644 index 000000000..b5b25eb22 --- /dev/null +++ b/packages/vscode-extension/esbuild.config.mjs @@ -0,0 +1,57 @@ +import * as esbuild from "esbuild"; + +const isWatch = process.argv.includes("--watch"); +const isProd = !isWatch || process.env.NODE_ENV === "production"; + +/** @type {esbuild.BuildOptions} */ +const extensionConfig = { + entryPoints: ["src/extension.ts"], + bundle: true, + outfile: "dist/extension.js", + platform: "node", + format: "cjs", + target: "node18", + external: ["vscode"], + sourcemap: !isProd, + minify: isProd, + logLevel: "info", +}; + +/** @type {esbuild.BuildOptions} */ +const webviewConfig = { + entryPoints: ["webview/index.tsx"], + bundle: true, + outfile: "dist/webview.js", + platform: "browser", + format: "iife", + target: "es2020", + sourcemap: !isProd, + minify: isProd, + logLevel: "info", + loader: { + ".css": "text", + }, + define: { + "process.env.NODE_ENV": isProd ? '"production"' : '"development"', + }, +}; + +async function main() { + if (isWatch) { + const extCtx = await esbuild.context(extensionConfig); + const webCtx = await esbuild.context(webviewConfig); + await Promise.all([extCtx.watch(), webCtx.watch()]); + console.log("[esbuild] Watching for changes..."); + } else { + await Promise.all([ + esbuild.build(extensionConfig), + esbuild.build(webviewConfig), + ]); + console.log("[esbuild] Build complete."); + } +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json new file mode 100644 index 000000000..562afa7af --- /dev/null +++ b/packages/vscode-extension/package.json @@ -0,0 +1,223 @@ +{ + "name": "ccb-vscode", + "displayName": "CCB - Claude Code Best", + "description": "Chat sidebar for the CCB (Claude Code Best) CLI — full ACP integration", + "publisher": "claude-code-best", + "version": "0.3.0", + "private": true, + "engines": { + "vscode": "^1.85.0" + }, + "categories": [ + "AI", + "Chat" + ], + "main": "./dist/extension.js", + "activationEvents": [], + "contributes": { + "viewsContainers": { + "activitybar": [ + { + "id": "ccb", + "title": "CCB", + "icon": "resources/icon.svg" + } + ] + }, + "views": { + "ccb": [ + { + "type": "webview", + "id": "ccb.chat", + "name": "Chat" + } + ] + }, + "commands": [ + { + "command": "ccb.newChat", + "title": "CCB: New Chat", + "icon": "$(add)" + }, + { + "command": "ccb.focus", + "title": "CCB: Focus Chat" + }, + { + "command": "ccb.cancel", + "title": "CCB: Cancel / Interrupt" + }, + { + "command": "ccb.cycleMode", + "title": "CCB: Cycle Permission Mode" + }, + { + "command": "ccb.sendSelection", + "title": "CCB: Send Selection to Chat" + }, + { + "command": "ccb.sendFileContext", + "title": "CCB: Send File to Chat" + }, + { + "command": "ccb.restartAgent", + "title": "CCB: Restart Agent" + }, + { + "command": "ccb.openHistory", + "title": "CCB: Open Session History" + }, + { + "command": "ccb.clearScreen", + "title": "CCB: Clear Chat Screen" + }, + { + "command": "ccb.searchHistory", + "title": "CCB: Search Prompt History" + }, + { + "command": "ccb.toggleThinking", + "title": "CCB: Toggle Thinking Visibility" + } + ], + "keybindings": [ + { + "command": "ccb.focus", + "key": "ctrl+escape", + "mac": "cmd+escape" + }, + { + "command": "ccb.cancel", + "key": "escape", + "when": "focusedView == 'ccb.chat'" + }, + { + "command": "ccb.newChat", + "key": "ctrl+shift+n", + "mac": "cmd+shift+n", + "when": "focusedView == 'ccb.chat'" + }, + { + "command": "ccb.cycleMode", + "key": "ctrl+shift+m", + "mac": "cmd+shift+m", + "when": "focusedView == 'ccb.chat'" + }, + { + "command": "ccb.clearScreen", + "key": "ctrl+l", + "mac": "cmd+l", + "when": "focusedView == 'ccb.chat'" + }, + { + "command": "ccb.searchHistory", + "key": "ctrl+r", + "mac": "cmd+r", + "when": "focusedView == 'ccb.chat'" + }, + { + "command": "ccb.toggleThinking", + "key": "ctrl+t", + "mac": "cmd+t", + "when": "focusedView == 'ccb.chat'" + }, + { + "command": "ccb.sendSelection", + "key": "ctrl+shift+l", + "mac": "cmd+shift+l", + "when": "editorHasSelection" + } + ], + "menus": { + "editor/context": [ + { + "command": "ccb.sendSelection", + "when": "editorHasSelection", + "group": "ccb@1" + }, + { + "command": "ccb.sendFileContext", + "group": "ccb@2" + } + ], + "view/title": [ + { + "command": "ccb.openHistory", + "when": "view == ccb.chat", + "group": "navigation@1" + }, + { + "command": "ccb.newChat", + "when": "view == ccb.chat", + "group": "navigation@2" + } + ] + }, + "configuration": { + "title": "CCB", + "properties": { + "ccb.cliPath": { + "type": "string", + "default": "auto", + "description": "Path to the CCB CLI binary. Set to 'auto' to detect from project, or provide a full path." + }, + "ccb.permissionMode": { + "type": "string", + "enum": [ + "default", + "plan", + "acceptEdits", + "bypassPermissions" + ], + "default": "default", + "description": "Default permission mode for new sessions." + }, + "ccb.autoScroll": { + "type": "boolean", + "default": true, + "description": "Auto-scroll to bottom on new messages." + }, + "ccb.showThinking": { + "type": "boolean", + "default": true, + "description": "Show extended thinking blocks in the chat." + }, + "ccb.resumeLastSession": { + "type": "boolean", + "default": true, + "description": "Resume the last session on extension start (when supported)." + }, + "ccb.enableFsCapabilities": { + "type": "boolean", + "default": true, + "description": "Allow the agent to read/write files via VSCode (enters undo stack)." + } + } + } + }, + "scripts": { + "build": "node esbuild.config.mjs", + "dev": "node esbuild.config.mjs --watch", + "test": "bun test webview/lib/__tests__", + "test:smoke": "node scripts/acp-smoke.mjs", + "test:extension-smoke": "node scripts/extension-smoke.cjs", + "test:all": "bun run typecheck && bun test webview/lib/__tests__ && bun run build && node scripts/extension-smoke.cjs && node scripts/acp-smoke.mjs", + "typecheck": "tsc --noEmit", + "install-local": "bash scripts/install-local.sh", + "install-local:win": "powershell -ExecutionPolicy Bypass -File scripts/install-local.ps1", + "package": "node esbuild.config.mjs && npx @vscode/vsce package --no-dependencies" + }, + "devDependencies": { + "@types/node": "^22", + "@types/vscode": "^1.85.0", + "esbuild": "^0.28.0", + "typescript": "^5.5.0" + }, + "dependencies": { + "@agentclientprotocol/sdk": "^0.19.0", + "marked": "^15.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "zod": "^3.25.0" + } +} diff --git a/packages/vscode-extension/resources/icon.svg b/packages/vscode-extension/resources/icon.svg new file mode 100644 index 000000000..9065426d9 --- /dev/null +++ b/packages/vscode-extension/resources/icon.svg @@ -0,0 +1,4 @@ + + + CC + diff --git a/packages/vscode-extension/scripts/acp-smoke.mjs b/packages/vscode-extension/scripts/acp-smoke.mjs new file mode 100644 index 000000000..575e34278 --- /dev/null +++ b/packages/vscode-extension/scripts/acp-smoke.mjs @@ -0,0 +1,515 @@ +#!/usr/bin/env node +import * as acp from "@agentclientprotocol/sdk"; +import { spawn } from "node:child_process"; +import { mkdtemp, readFile, rm } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { dirname, join, resolve } from "node:path"; +import { Readable, Writable } from "node:stream"; +import { fileURLToPath } from "node:url"; +import { setTimeout as delay } from "node:timers/promises"; + +const extensionDir = resolve(dirname(fileURLToPath(import.meta.url)), ".."); +const repoRoot = resolve(extensionDir, "../.."); +const cliPath = resolve(repoRoot, "dist", "cli-node.js"); +const smokeCwd = await mkdtemp(join(tmpdir(), "ccb-vscode-acp-smoke-")); +const DEFAULT_TIMEOUT_MS = 30_000; + +const updates = []; +const elicitations = []; +const permissionRequests = []; +let stderr = ""; +let sessionIdForCleanup; + +function assert(condition, message) { + if (!condition) { + throw new Error(message); + } +} + +function textFromUpdates(slice) { + return slice + .map((params) => { + const update = params.update; + const content = update?.content; + return content?.type === "text" ? content.text : ""; + }) + .filter(Boolean) + .join("\n"); +} + +function waitFor(predicate, label, timeoutMs = DEFAULT_TIMEOUT_MS) { + const started = Date.now(); + return new Promise((resolveWait, reject) => { + const timer = setInterval(() => { + try { + const value = predicate(); + if (value) { + clearInterval(timer); + resolveWait(value); + return; + } + if (Date.now() - started > timeoutMs) { + clearInterval(timer); + reject(new Error(`Timed out waiting for ${label}`)); + } + } catch (error) { + clearInterval(timer); + reject(error); + } + }, 50); + }); +} + +async function withTimeout(promise, label, timeoutMs = DEFAULT_TIMEOUT_MS) { + let timeout; + const timeoutPromise = new Promise((_, reject) => { + timeout = setTimeout( + () => reject(new Error(`Timed out during ${label}`)), + timeoutMs, + ); + }); + try { + return await Promise.race([promise, timeoutPromise]); + } finally { + clearTimeout(timeout); + } +} + +async function removeTempDir(path) { + for (let attempt = 0; attempt < 5; attempt++) { + try { + await rm(path, { recursive: true, force: true }); + return; + } catch (error) { + if (attempt === 4) { + console.warn( + `[acp-smoke] warning: failed to remove temp dir ${path}: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + return; + } + await delay(250); + } + } +} + +async function waitForChildExit(childProcess, timeoutMs) { + if (childProcess.exitCode !== null || childProcess.signalCode !== null) { + return; + } + + await new Promise((resolveWait) => { + const timer = setTimeout(resolveWait, timeoutMs); + childProcess.once("exit", () => { + clearTimeout(timer); + resolveWait(); + }); + }); +} + +const child = spawn(process.execPath, [cliPath, "--acp"], { + cwd: repoRoot, + stdio: ["pipe", "pipe", "pipe"], + windowsHide: true, + env: { + ...process.env, + CCB_VSCODE_ACP: "1", + DISABLE_LOGIN_COMMAND: "0", + }, +}); + +child.stderr.setEncoding("utf8"); +child.stderr.on("data", (chunk) => { + stderr += chunk; +}); + +child.on("exit", (code, signal) => { + if (code !== 0 && code !== null) { + stderr += `\n[acp-smoke] child exited code=${code} signal=${signal ?? ""}`; + } +}); + +const input = Writable.toWeb(child.stdin); +const output = Readable.toWeb(child.stdout); +const stream = acp.ndJsonStream(input, output); + +const client = { + requestPermission: async (params) => { + permissionRequests.push(params); + const option = + params.options.find((o) => o.optionId === "allow") ?? + params.options.find((o) => o.kind === "allow_once") ?? + params.options[0]; + return { outcome: { outcome: "selected", optionId: option.optionId } }; + }, + sessionUpdate: async (params) => { + updates.push(params); + }, + readTextFile: async (params) => ({ + content: await readFile(params.path, "utf8"), + }), + unstable_createElicitation: async (params) => { + elicitations.push(params); + return { action: "decline" }; + }, +}; + +const connection = new acp.ClientSideConnection(() => client, stream); + +async function prompt(sessionId, text, label = text) { + const before = updates.length; + const result = await withTimeout( + connection.prompt({ + sessionId, + prompt: [{ type: "text", text }], + }), + `prompt ${label}`, + ); + return { result, emitted: updates.slice(before) }; +} + +try { + const init = await withTimeout( + connection.initialize({ + protocolVersion: acp.PROTOCOL_VERSION, + clientInfo: { name: "ccb-vscode-smoke", version: "0.0.0" }, + clientCapabilities: { + fs: { readTextFile: true, writeTextFile: false }, + elicitation: { form: {} }, + }, + }), + "initialize", + ); + assert(init.agentInfo?.name, "initialize did not return agentInfo"); + + const session = await withTimeout( + connection.newSession({ + cwd: smokeCwd, + mcpServers: [], + _meta: { permissionMode: "bypassPermissions" }, + }), + "newSession", + ); + assert(session.sessionId, "newSession did not return sessionId"); + sessionIdForCleanup = session.sessionId; + + const commandUpdate = await waitFor( + () => + updates.find( + (params) => params.update?.sessionUpdate === "available_commands_update", + ), + "available_commands_update", + ); + const commands = commandUpdate.update.availableCommands; + const byName = new Map(commands.map((command) => [command.name, command])); + const login = byName.get("login"); + const simplify = byName.get("simplify"); + const mcp = byName.get("mcp"); + + assert(login, "missing /login command"); + assert(simplify, "missing /simplify command"); + assert(mcp, "missing /mcp command"); + assert( + login.input?.hint?.includes("openai_chat_api") && + login.input?.hint?.includes("gemini_api"), + "/login is missing expected provider sub-options", + ); + assert( + mcp.input?.hint?.includes("enable") && + mcp.input?.hint?.includes("disable") && + mcp.input?.hint?.includes("reconnect"), + "/mcp is missing expected subcommands", + ); + assert( + Array.isArray(mcp._meta?.ccbMcpServerNames), + "/mcp metadata is missing MCP server-name candidates", + ); + assert( + mcp._meta.ccbMcpServerNames.includes("mcp-chrome"), + "/mcp metadata is missing built-in MCP server candidates", + ); + assert( + mcp._meta.ccbMcpServerNames.includes("claude-in-chrome"), + "/mcp metadata is missing claude-in-chrome built-in candidate", + ); + assert( + !mcp._meta.ccbMcpServerNames.includes("computer-use"), + "/mcp metadata should not expose interactive computer-use in ACP headless sessions", + ); + assert( + Array.isArray(mcp._meta?.ccbMcpServers) && + mcp._meta.ccbMcpServers.some((server) => server?.name === "mcp-chrome"), + "/mcp metadata is missing structured MCP server entries", + ); + assert( + mcp._meta.ccbMcpServers.some((server) => server?.name === "claude-in-chrome"), + "/mcp metadata is missing structured claude-in-chrome entry", + ); + + const help = await prompt(session.sessionId, "/help", "/help"); + assert(help.result.stopReason === "end_turn", "/help did not end cleanly"); + assert( + textFromUpdates(help.emitted).includes("/login"), + "/help output did not include command catalog", + ); + + const invalidLogin = await prompt( + session.sessionId, + "/login unsupported_provider", + "/login unsupported_provider", + ); + assert( + invalidLogin.result.stopReason === "end_turn", + "invalid /login did not end cleanly", + ); + assert( + textFromUpdates(invalidLogin.emitted).includes("Unsupported /login option"), + "invalid /login did not report a validation message", + ); + + elicitations.length = 0; + const loginPrompt = await prompt(session.sessionId, "/login", "/login"); + assert(loginPrompt.result.stopReason === "end_turn", "/login did not end cleanly"); + const methodElicitation = elicitations[0]; + assert(methodElicitation, "/login did not request method elicitation"); + const methodOptions = + methodElicitation.requestedSchema?.properties?.method?.oneOf ?? []; + const methodValues = methodOptions.map((option) => option.const); + for (const expected of [ + "claudeai", + "console", + "custom_platform", + "openai_chat_api", + "gemini_api", + "platform", + ]) { + assert(methodValues.includes(expected), `/login method missing ${expected}`); + } + + elicitations.length = 0; + const providerLogin = await prompt( + session.sessionId, + "/login openai_chat_api", + "/login openai_chat_api", + ); + assert( + providerLogin.result.stopReason === "end_turn", + "/login openai_chat_api did not end cleanly", + ); + const providerElicitation = elicitations[0]; + assert(providerElicitation, "/login openai_chat_api did not request provider settings"); + const properties = providerElicitation.requestedSchema?.properties ?? {}; + for (const expected of [ + "base_url", + "api_key", + "haiku_model", + "sonnet_model", + "opus_model", + ]) { + assert( + Object.hasOwn(properties, expected), + `/login openai_chat_api schema missing ${expected}`, + ); + } + + const mcpSummary = await prompt(session.sessionId, "/mcp", "/mcp"); + assert(mcpSummary.result.stopReason === "end_turn", "/mcp did not end cleanly"); + assert( + textFromUpdates(mcpSummary.emitted).includes("Manage MCP servers"), + "/mcp summary did not include the MCP manager heading", + ); + assert( + textFromUpdates(mcpSummary.emitted).includes("Built-in MCPs (always available)"), + "/mcp summary did not include the built-in MCP group", + ); + assert( + textFromUpdates(mcpSummary.emitted).includes("claude-in-chrome"), + "/mcp summary did not include claude-in-chrome", + ); + assert( + !textFromUpdates(mcpSummary.emitted).includes("computer-use"), + "/mcp summary should not include interactive computer-use in ACP headless sessions", + ); + assert( + !textFromUpdates(mcpSummary.emitted).includes("/mcp enable [server-name]"), + "/mcp summary should not render executable subcommands as list entries", + ); + + let chromeToolsText = ""; + for (let attempt = 0; attempt < 10; attempt++) { + const chromeTools = await prompt( + session.sessionId, + "/mcp tools claude-in-chrome", + `/mcp tools claude-in-chrome attempt ${attempt + 1}`, + ); + assert( + chromeTools.result.stopReason === "end_turn", + "/mcp tools claude-in-chrome did not end cleanly", + ); + chromeToolsText = textFromUpdates(chromeTools.emitted); + if (chromeToolsText.includes("tabs_context_mcp")) { + break; + } + await delay(500); + } + assert( + chromeToolsText.includes("tabs_context_mcp"), + "/mcp tools claude-in-chrome did not expose Chrome MCP tool schemas", + ); + + const mcpStatus = await prompt( + session.sessionId, + "/mcp status mcp-chrome", + "/mcp status mcp-chrome", + ); + assert( + mcpStatus.result.stopReason === "end_turn", + "/mcp status mcp-chrome did not end cleanly", + ); + assert( + textFromUpdates(mcpStatus.emitted).includes('MCP server "mcp-chrome"'), + "/mcp status did not return a server detail view", + ); + + const mcpTools = await prompt( + session.sessionId, + "/mcp tools mcp-chrome", + "/mcp tools mcp-chrome", + ); + assert( + mcpTools.result.stopReason === "end_turn", + "/mcp tools mcp-chrome did not end cleanly", + ); + assert( + textFromUpdates(mcpTools.emitted).includes('MCP server "mcp-chrome"') || + textFromUpdates(mcpTools.emitted).includes("Tools for mcp-chrome"), + "/mcp tools did not complete through the ACP command path", + ); + + const mcpReconnectMissing = await prompt( + session.sessionId, + "/mcp reconnect __ccb_smoke_missing__", + "/mcp reconnect missing", + ); + assert( + mcpReconnectMissing.result.stopReason === "end_turn", + "/mcp reconnect missing did not end cleanly", + ); + assert( + textFromUpdates(mcpReconnectMissing.emitted).includes('MCP server "__ccb_smoke_missing__" not found'), + "/mcp reconnect missing did not complete through the ACP command path", + ); + + const mcpReconnectDisabled = await prompt( + session.sessionId, + "/mcp reconnect mcp-chrome", + "/mcp reconnect disabled", + ); + assert( + mcpReconnectDisabled.result.stopReason === "end_turn", + "/mcp reconnect disabled did not end cleanly", + ); + assert( + textFromUpdates(mcpReconnectDisabled.emitted).includes('MCP server "mcp-chrome" is disabled'), + "/mcp reconnect disabled should require enabling the server first", + ); + + const mcpEnable = await prompt( + session.sessionId, + "/mcp enable __ccb_smoke_missing__", + "/mcp enable missing", + ); + assert( + mcpEnable.result.stopReason === "end_turn", + "/mcp enable missing did not end cleanly", + ); + assert( + textFromUpdates(mcpEnable.emitted).includes('MCP server "__ccb_smoke_missing__" not found'), + "/mcp enable missing did not complete through the ACP command path", + ); + + const mcpDisable = await prompt( + session.sessionId, + "/mcp disable __ccb_smoke_missing__", + "/mcp disable missing", + ); + assert( + mcpDisable.result.stopReason === "end_turn", + "/mcp disable missing did not end cleanly", + ); + assert( + textFromUpdates(mcpDisable.emitted).includes('MCP server "__ccb_smoke_missing__" not found'), + "/mcp disable missing did not complete through the ACP command path", + ); + + const pendingToolCalls = updates.filter( + (params) => + params.update?.sessionUpdate === "tool_call" && + params.update?.status === "pending", + ); + assert( + pendingToolCalls.length === 0, + `local slash smoke left ${pendingToolCalls.length} pending tool call(s)`, + ); + + console.log( + JSON.stringify( + { + ok: true, + agent: init.agentInfo, + sessionId: session.sessionId, + commands: commands.length, + checked: [ + "/help", + "/login", + "/login openai_chat_api", + "/mcp", + "/mcp tools claude-in-chrome", + "/mcp status mcp-chrome", + "/mcp tools mcp-chrome", + "/mcp reconnect __ccb_smoke_missing__", + "/mcp reconnect mcp-chrome", + "/mcp enable __ccb_smoke_missing__", + "/mcp disable __ccb_smoke_missing__", + ], + permissionRequests: permissionRequests.length, + }, + null, + 2, + ), + ); + if (typeof connection.unstable_closeSession === "function") { + await withTimeout( + connection.unstable_closeSession({ sessionId: session.sessionId }), + "closeSession", + 10_000, + ); + sessionIdForCleanup = undefined; + } +} catch (error) { + console.error("[acp-smoke] failed:", error instanceof Error ? error.message : error); + if (stderr.trim()) { + console.error("[acp-smoke] agent stderr:"); + console.error(stderr.trim().slice(-6000)); + } + process.exitCode = 1; +} finally { + if (sessionIdForCleanup && typeof connection.unstable_closeSession === "function") { + await connection + .unstable_closeSession({ sessionId: sessionIdForCleanup }) + .catch((error) => { + console.error( + "[acp-smoke] closeSession failed:", + error instanceof Error ? error.message : error, + ); + }); + } + child.kill("SIGTERM"); + await waitForChildExit(child, 5000); + if (child.exitCode === null) { + child.kill("SIGKILL"); + await waitForChildExit(child, 1000); + } + await removeTempDir(smokeCwd); +} diff --git a/packages/vscode-extension/scripts/extension-smoke.cjs b/packages/vscode-extension/scripts/extension-smoke.cjs new file mode 100644 index 000000000..fde8fac44 --- /dev/null +++ b/packages/vscode-extension/scripts/extension-smoke.cjs @@ -0,0 +1,151 @@ +#!/usr/bin/env node +const Module = require("node:module"); +const path = require("node:path"); + +const extensionDir = path.resolve(__dirname, ".."); +const registeredCommands = []; +const registeredViews = []; + +function disposable() { + return { dispose() {} }; +} + +const fakeConfiguration = { + get(_key, defaultValue) { + return defaultValue; + }, +}; + +const fakeVscode = { + StatusBarAlignment: { Right: 2 }, + Uri: { + joinPath(base, ...segments) { + return { + fsPath: path.join(base.fsPath ?? String(base), ...segments), + path: path.join(base.path ?? base.fsPath ?? String(base), ...segments), + }; + }, + }, + window: { + createStatusBarItem() { + return { + text: "", + tooltip: "", + command: undefined, + show() {}, + dispose() {}, + }; + }, + createOutputChannel() { + return { + appendLine() {}, + dispose() {}, + }; + }, + registerWebviewViewProvider(id, provider, options) { + registeredViews.push({ id, provider, options }); + return disposable(); + }, + }, + commands: { + registerCommand(id, handler) { + registeredCommands.push({ id, handler }); + return disposable(); + }, + async executeCommand() {}, + }, + workspace: { + getConfiguration() { + return fakeConfiguration; + }, + workspaceFolders: [ + { + uri: { + fsPath: path.resolve(extensionDir, "../.."), + path: path.resolve(extensionDir, "../.."), + }, + }, + ], + }, +}; + +const originalLoad = Module._load; +Module._load = function patchedLoad(request, parent, isMain) { + if (request === "vscode") return fakeVscode; + return originalLoad.call(this, request, parent, isMain); +}; + +function assert(condition, message) { + if (!condition) throw new Error(message); +} + +const extension = require(path.join(extensionDir, "dist", "extension.js")); +const state = new Map(); +const context = { + extensionUri: { fsPath: extensionDir, path: extensionDir }, + globalState: { + get(key, defaultValue) { + return state.has(key) ? state.get(key) : defaultValue; + }, + update(key, value) { + state.set(key, value); + return Promise.resolve(); + }, + keys() { + return [...state.keys()]; + }, + }, + subscriptions: [], +}; + +try { + extension.activate(context); + + assert( + registeredViews.some((view) => view.id === "ccb.chat"), + "ccb.chat webview provider was not registered", + ); + + for (const command of [ + "ccb.newChat", + "ccb.focus", + "ccb.cancel", + "ccb.cycleMode", + "ccb.sendSelection", + "ccb.sendFileContext", + "ccb.restartAgent", + "ccb.openHistory", + "ccb.clearScreen", + "ccb.searchHistory", + "ccb.toggleThinking", + ]) { + assert( + registeredCommands.some((entry) => entry.id === command), + `missing command registration: ${command}`, + ); + } + + assert(context.subscriptions.length >= 13, "expected disposables in subscriptions"); + + extension.deactivate(); + + console.log( + JSON.stringify( + { + ok: true, + views: registeredViews.map((view) => view.id), + commands: registeredCommands.map((entry) => entry.id), + }, + null, + 2, + ), + ); +} catch (error) { + console.error( + "[extension-smoke] failed:", + error instanceof Error ? error.message : error, + ); + process.exitCode = 1; +} finally { + Module._load = originalLoad; +} diff --git a/packages/vscode-extension/scripts/install-local.ps1 b/packages/vscode-extension/scripts/install-local.ps1 new file mode 100644 index 000000000..3d37a0aa6 --- /dev/null +++ b/packages/vscode-extension/scripts/install-local.ps1 @@ -0,0 +1,71 @@ +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest + +if (-not $env:USERPROFILE) { Write-Error "USERPROFILE is not set"; exit 1 } + +function Remove-DirectoryEntry { + param([Parameter(Mandatory = $true)][string]$Path) + + if (-not (Test-Path -LiteralPath $Path)) { + return + } + + $item = Get-Item -LiteralPath $Path -Force + if (($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0) { + [System.IO.Directory]::Delete($item.FullName) + return + } + + Remove-Item -LiteralPath $item.FullName -Force -Recurse -Confirm:$false +} + +$SourceDir = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path +$manifestPath = Join-Path $SourceDir "package.json" +if (-not (Test-Path -LiteralPath $manifestPath)) { + throw "Extension manifest not found at $manifestPath" +} + +Push-Location $SourceDir +try { + Write-Host "Building extension..." + bun run build +} finally { + Pop-Location +} + +$pkg = Get-Content -LiteralPath $manifestPath | ConvertFrom-Json +$ExtensionsRoot = Join-Path $env:USERPROFILE ".vscode\extensions" +$VsixId = "$($pkg.publisher).$($pkg.name)" +$ExtDir = Join-Path $ExtensionsRoot "$VsixId-$($pkg.version)" + +New-Item -ItemType Directory -Path $ExtensionsRoot -Force | Out-Null + +# Clean up *all* prior versions of this extension. VSCode otherwise loads +# multiple versions side-by-side and can cache stale webview bundles, which +# masks our edits and produces "this fix didn't work" false alarms. +$stale = Get-ChildItem -LiteralPath $ExtensionsRoot -Directory -ErrorAction SilentlyContinue | + Where-Object { $_.Name -like "$VsixId-*" -and $_.FullName -ne $ExtDir } +foreach ($entry in $stale) { + Write-Host "Removing stale version: $($entry.Name)" + Remove-DirectoryEntry -Path $entry.FullName +} + +Remove-DirectoryEntry -Path $ExtDir +New-Item -ItemType Junction -Path $ExtDir -Target $SourceDir | Out-Null + +$installedManifest = Join-Path $ExtDir "package.json" +$installedMain = Join-Path $ExtDir "dist\extension.js" +if (-not (Test-Path -LiteralPath $installedManifest)) { + throw "Install verification failed: missing $installedManifest" +} +if (-not (Test-Path -LiteralPath $installedMain)) { + throw "Install verification failed: missing $installedMain" +} + +Write-Host "Installed: $ExtDir -> $SourceDir" +Write-Host "Active extension dirs:" +Get-ChildItem -LiteralPath $ExtensionsRoot -Directory | + Where-Object { $_.Name -like "$VsixId-*" } | + ForEach-Object { Write-Host " $($_.Name)" } +Write-Host "" +Write-Host "Fully QUIT VS Code (not just reload window) and reopen to pick up the fresh build." diff --git a/packages/vscode-extension/scripts/install-local.sh b/packages/vscode-extension/scripts/install-local.sh new file mode 100644 index 000000000..94005e994 --- /dev/null +++ b/packages/vscode-extension/scripts/install-local.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")/.." + +echo "Building extension..." +bun run build + +SOURCE_DIR="$(pwd)" +if [[ ! -f "${SOURCE_DIR}/package.json" ]]; then + echo "Extension manifest not found at ${SOURCE_DIR}/package.json" >&2 + exit 1 +fi + +PKG_PUBLISHER=$(node -p "require('./package.json').publisher") +PKG_NAME=$(node -p "require('./package.json').name") +PKG_VERSION=$(node -p "require('./package.json').version") +EXT_ROOT="$HOME/.vscode/extensions" +VSIX_ID="${PKG_PUBLISHER}.${PKG_NAME}" +EXT_DIR="${EXT_ROOT}/${VSIX_ID}-${PKG_VERSION}" + +mkdir -p "$EXT_ROOT" + +# Remove every prior version of this extension. Leaving older copies behind +# causes VS Code to load stale webview bundles and masks new fixes — every +# install-local must start from a clean slate. +shopt -s nullglob +for entry in "${EXT_ROOT}/${VSIX_ID}-"*; do + if [[ "$entry" != "$EXT_DIR" ]]; then + echo "Removing stale version: $(basename "$entry")" + rm -rf "$entry" + fi +done + +rm -rf "$EXT_DIR" +ln -sf "$SOURCE_DIR" "$EXT_DIR" + +if [[ ! -f "${EXT_DIR}/package.json" ]]; then + echo "Install verification failed: missing ${EXT_DIR}/package.json" >&2 + exit 1 +fi +if [[ ! -f "${EXT_DIR}/dist/extension.js" ]]; then + echo "Install verification failed: missing ${EXT_DIR}/dist/extension.js" >&2 + exit 1 +fi + +echo "Installed: $EXT_DIR -> $SOURCE_DIR" +echo "Active extension dirs:" +for entry in "${EXT_ROOT}/${VSIX_ID}-"*; do + echo " $(basename "$entry")" +done +echo "" +echo "Fully QUIT VS Code (not just reload window) and reopen to pick up the fresh build." diff --git a/packages/vscode-extension/src/ACPClient.ts b/packages/vscode-extension/src/ACPClient.ts new file mode 100644 index 000000000..3645069d1 --- /dev/null +++ b/packages/vscode-extension/src/ACPClient.ts @@ -0,0 +1,577 @@ +import * as acp from "@agentclientprotocol/sdk"; +import { spawn, type ChildProcess } from "node:child_process"; +import { Readable, Writable } from "node:stream"; +import * as vscode from "vscode"; +import { resolveAgent, type ResolvedAgent } from "./agentSpawner"; + +// ============================================================================= +// Types re-exported in shape compatible with the webview protocol +// ============================================================================= + +export interface PendingPermission { + resolve: (outcome: { outcome: "cancelled" } | { outcome: "selected"; optionId: string }) => void; + reject: (err: Error) => void; + timer: ReturnType; +} + +export interface PendingElicitation { + resolve: (response: acp.CreateElicitationResponse) => void; + reject: (err: Error) => void; + timer: ReturnType; +} + +export interface ACPClientHandlers { + onStatus: (status: { connected: boolean; agentInfo?: { name?: string; version?: string }; capabilities?: acp.AgentCapabilities; cwd?: string }) => void; + onSessionCreated: (payload: { + sessionId: string; + promptCapabilities?: acp.PromptCapabilities; + models?: acp.SessionModelState | null; + modes?: acp.SessionModeState | null; + }) => void; + onSessionUpdate: (sessionId: string, update: acp.SessionNotification["update"]) => void; + onPromptComplete: (stopReason: string) => void; + onPermissionRequest: (request: { + requestId: string; + sessionId: string; + options: acp.PermissionOption[]; + toolCall: acp.ToolCallUpdate; + }) => void; + onElicitationRequest: (request: { + requestId: string; + sessionId?: string; + message: string; + schema: acp.ElicitationSchema; + }) => void; + onError: (message: string) => void; + onModeChanged?: (modeId: string) => void; + /** Called when agent process exits unexpectedly; client will need a restart. */ + onProcessExit: (code: number | null, signal: NodeJS.Signals | null) => void; + // VSCode FS hooks (used by Client implementation) + readTextFile: (params: acp.ReadTextFileRequest) => Promise; + writeTextFile: (params: acp.WriteTextFileRequest) => Promise; +} + +export interface ACPClientOptions { + extensionDir: string; + enableFsCapabilities: boolean; + permissionTimeoutMs?: number; + outputChannel?: vscode.OutputChannel; +} + +const PERMISSION_TIMEOUT_DEFAULT = 5 * 60 * 1000; +const ELICITATION_TIMEOUT_DEFAULT = 5 * 60 * 1000; +type SlashCommandType = "prompt" | "local" | "local-jsx"; +type WebviewAvailableCommand = acp.AvailableCommand & { type?: SlashCommandType }; + +/** + * Wraps `@agentclientprotocol/sdk` ClientSideConnection over a child-process + * stdio stream and exposes a promise-friendly API. + * + * Lifecycle: + * start() spawn `claude --acp`, run `initialize`, then notify status + * newSession() create or reuse a session + * prompt() send content blocks; returns when prompt completes + * cancel() cancel current prompt turn + * shutdown() dispose resources + */ +export class ACPClient { + private proc: ChildProcess | null = null; + private connection: acp.ClientSideConnection | null = null; + private sessionId: string | null = null; + private agentCapabilities: acp.AgentCapabilities | null = null; + private promptCapabilities: acp.PromptCapabilities | null = null; + private modelState: acp.SessionModelState | null = null; + private modeState: acp.SessionModeState | null = null; + private availableCommands: WebviewAvailableCommand[] = []; + private resolved: ResolvedAgent | null = null; + private pendingPermissions = new Map(); + private pendingElicitations = new Map(); + private permCounter = 0; + private elicitCounter = 0; + private connectionClosedHandled = false; + + constructor( + private readonly handlers: ACPClientHandlers, + private readonly options: ACPClientOptions, + ) {} + + // --------------------------------------------------------------------------- + // State accessors + // --------------------------------------------------------------------------- + isRunning(): boolean { + return this.proc !== null && this.proc.exitCode === null && !this.proc.killed; + } + + getSessionId(): string | null { + return this.sessionId; + } + + getCwd(): string | null { + return this.resolved?.cwd ?? null; + } + + getCapabilities(): acp.AgentCapabilities | null { + return this.agentCapabilities; + } + + getModelState(): acp.SessionModelState | null { + return this.modelState; + } + + getModeState(): acp.SessionModeState | null { + return this.modeState; + } + + getAvailableCommands(): WebviewAvailableCommand[] { + return this.availableCommands; + } + + // --------------------------------------------------------------------------- + // Lifecycle + // --------------------------------------------------------------------------- + async start(): Promise { + if (this.isRunning()) return; + + let resolved: ResolvedAgent | null; + try { + resolved = resolveAgent(this.options.extensionDir); + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + this.handlers.onError(msg); + this.handlers.onStatus({ connected: false }); + return; + } + if (!resolved) { + this.handlers.onError( + "CCB CLI not found. Build the project (bun run build) or install `claude` on PATH.", + ); + this.handlers.onStatus({ connected: false }); + return; + } + this.resolved = resolved; + + this.log(`spawning (${resolved.runtime}) ${resolved.command} ${resolved.args.join(" ")}`); + let proc: ChildProcess; + try { + proc = spawn(resolved.command, resolved.args, { + cwd: resolved.cwd, + stdio: ["pipe", "pipe", "pipe"], + windowsHide: true, + detached: process.platform !== "win32", + env: buildAgentEnvironment(), + }); + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + this.handlers.onError(`Failed to spawn agent: ${msg}`); + this.handlers.onStatus({ connected: false }); + return; + } + this.proc = proc; + this.connectionClosedHandled = false; + + // Capture stderr separately for diagnostics (don't pollute stdio JSON-RPC channel). + proc.stderr?.setEncoding("utf-8"); + proc.stderr?.on("data", (chunk: string) => this.log(`[agent stderr] ${chunk.trimEnd()}`)); + + proc.on("error", (err) => { + this.handlers.onError(`Agent process error: ${err.message}`); + }); + + proc.on("exit", (code, signal) => { + this.log(`agent exited code=${code} signal=${signal ?? ""}`); + const wasMine = this.proc === proc; + if (wasMine) { + this.proc = null; + this.connection = null; + this.sessionId = null; + this.availableCommands = []; + this.modelState = null; + this.modeState = null; + this.failPendingPermissions("Agent process exited"); + this.failPendingElicitations("Agent process exited"); + } + this.handlers.onProcessExit(code, signal); + this.handlers.onStatus({ connected: false }); + }); + + if (!proc.stdin || !proc.stdout) { + this.handlers.onError("Agent stdio not available"); + return; + } + + const input = Writable.toWeb(proc.stdin) as unknown as WritableStream; + const output = Readable.toWeb(proc.stdout) as unknown as ReadableStream; + const stream = acp.ndJsonStream(input, output); + + const connection = new acp.ClientSideConnection(() => this.makeClient(), stream); + this.connection = connection; + + connection.closed + .then(() => { + if (this.connectionClosedHandled) return; + this.connectionClosedHandled = true; + this.log("ACP connection closed"); + this.connection = null; + this.sessionId = null; + this.failPendingPermissions("Connection closed"); + this.failPendingElicitations("Connection closed"); + this.handlers.onStatus({ connected: false }); + }) + .catch((err) => { + this.connectionClosedHandled = true; + this.log(`ACP connection error: ${(err as Error).message}`); + }); + + try { + const initResult = await connection.initialize({ + protocolVersion: acp.PROTOCOL_VERSION, + clientInfo: { name: "vscode-ccb", version: "0.3.0" }, + clientCapabilities: { + fs: { + readTextFile: this.options.enableFsCapabilities, + writeTextFile: this.options.enableFsCapabilities, + }, + elicitation: { + form: {}, + }, + }, + }); + this.agentCapabilities = initResult.agentCapabilities ?? null; + this.promptCapabilities = initResult.agentCapabilities?.promptCapabilities ?? null; + this.handlers.onStatus({ + connected: true, + agentInfo: initResult.agentInfo ?? undefined, + capabilities: initResult.agentCapabilities, + cwd: this.resolved?.cwd, + }); + this.log("initialize complete"); + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + this.handlers.onError(`Initialize failed: ${msg}`); + this.handlers.onStatus({ connected: false }); + this.shutdown(); + } + } + + async newSession(permissionMode?: string): Promise { + if (!this.connection) throw new Error("Not connected"); + const cwd = this.resolved?.cwd; + if (!cwd) throw new Error("No working directory available"); + const params: acp.NewSessionRequest = { + cwd, + mcpServers: [], + ...(permissionMode ? ({ _meta: { permissionMode } } as Partial) : {}), + }; + const result = await this.connection.newSession(params); + this.sessionId = result.sessionId; + this.modelState = result.models ?? null; + this.modeState = result.modes ?? null; + this.handlers.onSessionCreated({ + sessionId: result.sessionId, + promptCapabilities: this.promptCapabilities ?? undefined, + models: this.modelState, + modes: this.modeState, + }); + } + + async prompt(content: acp.ContentBlock[]): Promise { + if (!this.connection || !this.sessionId) throw new Error("No active session"); + const result = await this.connection.prompt({ + sessionId: this.sessionId, + prompt: content, + }); + this.handlers.onPromptComplete(result.stopReason); + } + + async cancel(): Promise { + if (!this.connection || !this.sessionId) return; + // Resolve all pending permissions as cancelled before notifying agent. + for (const [requestId, pending] of this.pendingPermissions) { + clearTimeout(pending.timer); + pending.resolve({ outcome: "cancelled" }); + this.pendingPermissions.delete(requestId); + } + this.cancelPendingElicitations("Prompt cancelled"); + try { + await this.connection.cancel({ sessionId: this.sessionId }); + } catch (err) { + this.log(`cancel failed: ${(err as Error).message}`); + } + } + + async setSessionModel(modelId: string): Promise { + if (!this.connection || !this.sessionId) throw new Error("No active session"); + if (!this.modelState) throw new Error("Model selection not supported"); + await this.connection.unstable_setSessionModel({ + sessionId: this.sessionId, + modelId, + }); + this.modelState = { ...this.modelState, currentModelId: modelId }; + } + + async setSessionMode(modeId: string): Promise { + if (!this.connection || !this.sessionId) throw new Error("No active session"); + await this.connection.setSessionMode({ + sessionId: this.sessionId, + modeId, + }); + if (this.modeState) { + this.modeState = { ...this.modeState, currentModeId: modeId }; + } + this.handlers.onModeChanged?.(modeId); + } + + async listSessions(req?: { cwd?: string; cursor?: string }): Promise { + if (!this.connection) throw new Error("Not connected"); + const cwd = req?.cwd ?? this.resolved?.cwd ?? ""; + const params: acp.ListSessionsRequest = { cwd }; + if (req?.cursor !== undefined) params.cursor = req.cursor; + return this.connection.listSessions(params); + } + + async loadSession(req: { sessionId: string; cwd?: string }): Promise { + if (!this.connection) throw new Error("Not connected"); + const cwd = req.cwd ?? this.resolved?.cwd; + if (!cwd) throw new Error("No working directory"); + const result = await this.connection.loadSession({ + sessionId: req.sessionId, + cwd, + mcpServers: [], + }); + this.sessionId = req.sessionId; + this.modelState = result.models ?? null; + this.modeState = result.modes ?? null; + this.handlers.onSessionCreated({ + sessionId: req.sessionId, + promptCapabilities: this.promptCapabilities ?? undefined, + models: this.modelState, + modes: this.modeState, + }); + } + + async resumeSession(req: { sessionId: string; cwd?: string }): Promise { + if (!this.connection) throw new Error("Not connected"); + const cwd = req.cwd ?? this.resolved?.cwd; + if (!cwd) throw new Error("No working directory"); + const result = await this.connection.unstable_resumeSession({ + sessionId: req.sessionId, + cwd, + }); + this.sessionId = req.sessionId; + this.modelState = result.models ?? null; + this.modeState = result.modes ?? null; + this.handlers.onSessionCreated({ + sessionId: req.sessionId, + promptCapabilities: this.promptCapabilities ?? undefined, + models: this.modelState, + modes: this.modeState, + }); + } + + async respondToPermission(requestId: string, outcome: { outcome: "cancelled" } | { outcome: "selected"; optionId: string }): Promise { + const pending = this.pendingPermissions.get(requestId); + if (!pending) { + this.log(`permission response for unknown id ${requestId}`); + return; + } + clearTimeout(pending.timer); + this.pendingPermissions.delete(requestId); + pending.resolve(outcome); + } + + async respondToElicitation(requestId: string, response: acp.CreateElicitationResponse): Promise { + const pending = this.pendingElicitations.get(requestId); + if (!pending) { + this.log(`elicitation response for unknown id ${requestId}`); + return; + } + clearTimeout(pending.timer); + this.pendingElicitations.delete(requestId); + pending.resolve(response); + } + + shutdown(): void { + this.failPendingPermissions("Client shutdown"); + this.failPendingElicitations("Client shutdown"); + if (this.proc) { + terminateProcessTree(this.proc, (msg) => this.log(msg)); + this.proc = null; + } + this.connection = null; + this.sessionId = null; + this.availableCommands = []; + this.modelState = null; + this.modeState = null; + } + + // --------------------------------------------------------------------------- + // ACP Client implementation (callbacks the agent invokes on us) + // --------------------------------------------------------------------------- + private makeClient(): acp.Client { + return { + requestPermission: async (params) => { + const requestId = this.nextPermissionId(); + const outcomePromise = new Promise<{ outcome: "cancelled" } | { outcome: "selected"; optionId: string }>((resolve, reject) => { + const timer = setTimeout(() => { + this.pendingPermissions.delete(requestId); + this.log(`permission ${requestId} timed out`); + resolve({ outcome: "cancelled" }); + }, this.options.permissionTimeoutMs ?? PERMISSION_TIMEOUT_DEFAULT); + this.pendingPermissions.set(requestId, { resolve, reject, timer }); + }); + + this.handlers.onPermissionRequest({ + requestId, + sessionId: params.sessionId, + options: params.options, + toolCall: params.toolCall, + }); + + const outcome = await outcomePromise; + return { outcome }; + }, + + unstable_createElicitation: async (params) => { + if (params.mode !== "form") { + return { action: "decline" }; + } + + const requestId = this.nextElicitationId(); + const responsePromise = new Promise((resolve, reject) => { + const timer = setTimeout(() => { + this.pendingElicitations.delete(requestId); + this.log(`elicitation ${requestId} timed out`); + resolve({ action: "cancel" }); + }, ELICITATION_TIMEOUT_DEFAULT); + this.pendingElicitations.set(requestId, { resolve, reject, timer }); + }); + + this.handlers.onElicitationRequest({ + requestId, + sessionId: "sessionId" in params ? params.sessionId : undefined, + message: params.message, + schema: params.requestedSchema, + }); + + return responsePromise; + }, + + sessionUpdate: async (params) => { + // Track current mode locally so the UI can stay in sync. + if (params.update.sessionUpdate === "current_mode_update") { + if (this.modeState) { + this.modeState = { ...this.modeState, currentModeId: params.update.currentModeId }; + } + this.handlers.onModeChanged?.(params.update.currentModeId); + } + // Cache slash-command catalog so the webview can replay it after a + // remount race (the agent emits this update once, asynchronously, + // immediately after newSession returns). + if (params.update.sessionUpdate === "available_commands_update") { + const update = { + ...params.update, + availableCommands: params.update.availableCommands.map(normalizeAvailableCommand), + }; + this.availableCommands = update.availableCommands; + this.handlers.onSessionUpdate(params.sessionId, update as acp.SessionNotification["update"]); + return; + } + this.handlers.onSessionUpdate(params.sessionId, params.update); + }, + + readTextFile: this.handlers.readTextFile, + + writeTextFile: this.handlers.writeTextFile, + }; + } + + private nextPermissionId(): string { + return `perm_${Date.now()}_${++this.permCounter}`; + } + + private nextElicitationId(): string { + return `elicit_${Date.now()}_${++this.elicitCounter}`; + } + + private failPendingPermissions(reason: string): void { + for (const [requestId, pending] of this.pendingPermissions) { + clearTimeout(pending.timer); + pending.resolve({ outcome: "cancelled" }); + this.log(`permission ${requestId} cancelled: ${reason}`); + } + this.pendingPermissions.clear(); + } + + private cancelPendingElicitations(reason: string): void { + for (const [requestId, pending] of this.pendingElicitations) { + clearTimeout(pending.timer); + pending.resolve({ action: "cancel" }); + this.log(`elicitation ${requestId} cancelled: ${reason}`); + } + this.pendingElicitations.clear(); + } + + private failPendingElicitations(reason: string): void { + for (const [requestId, pending] of this.pendingElicitations) { + clearTimeout(pending.timer); + pending.reject(new Error(reason)); + this.log(`elicitation ${requestId} failed: ${reason}`); + } + this.pendingElicitations.clear(); + } + + private log(msg: string): void { + this.options.outputChannel?.appendLine(`[ACPClient] ${msg}`); + } +} + +function normalizeAvailableCommand(command: acp.AvailableCommand): WebviewAvailableCommand { + const rawType = command._meta?.ccbCommandType; + if (rawType === "prompt" || rawType === "local" || rawType === "local-jsx") { + return { ...command, type: rawType }; + } + return { ...command }; +} + +function buildAgentEnvironment(): NodeJS.ProcessEnv { + const env: NodeJS.ProcessEnv = { ...process.env }; + env.CCB_VSCODE_ACP = "1"; + if (process.platform === "win32") { + env.CLAUDE_CODE_USE_POWERSHELL_TOOL ??= "1"; + env.CCB_VSCODE_ENABLE_BASH_TOOL ??= "0"; + } + return env; +} + +function terminateProcessTree(proc: ChildProcess, log: (msg: string) => void): void { + const pid = proc.pid; + if (proc.exitCode !== null || proc.killed) return; + + if (process.platform === "win32" && pid) { + try { + const killer = spawn("taskkill.exe", ["/PID", String(pid), "/T", "/F"], { + stdio: "ignore", + windowsHide: true, + }); + killer.on("error", (err) => log(`taskkill failed for pid=${pid}: ${err.message}`)); + return; + } catch (err) { + log(`taskkill launch failed for pid=${pid}: ${(err as Error).message}`); + } + } + + if (process.platform !== "win32" && pid) { + try { + process.kill(-pid, "SIGTERM"); + return; + } catch (err) { + log(`process group kill failed for pid=${pid}: ${(err as Error).message}`); + } + } + + try { + proc.kill("SIGTERM"); + } catch { + /* already gone */ + } +} diff --git a/packages/vscode-extension/src/ChatViewProvider.ts b/packages/vscode-extension/src/ChatViewProvider.ts new file mode 100644 index 000000000..3a57c2a64 --- /dev/null +++ b/packages/vscode-extension/src/ChatViewProvider.ts @@ -0,0 +1,698 @@ +import { randomBytes } from "node:crypto"; +import * as vscode from "vscode"; +import { ACPClient } from "./ACPClient"; +import { EditorBridge } from "./EditorBridge"; +import { HistoryManager } from "./HistoryManager"; +import { StatusBarManager, type StatusBarState } from "./StatusBarManager"; + +// We don't import the webview protocol module directly — we keep the +// bridge protocol *shape* identical via inline types so both ends stay loose. +// (The webview/lib/protocol.ts file is the single source of truth.) +type AnyMessage = { type: string; payload?: unknown; requestId?: string }; + +const PERMISSION_MODES = ["default", "acceptEdits", "plan", "bypassPermissions"] as const; +type PermissionMode = (typeof PERMISSION_MODES)[number]; + +const PERMISSION_TIMEOUT_MS = 5 * 60 * 1000; + +export class ChatViewProvider implements vscode.WebviewViewProvider, vscode.Disposable { + private view: vscode.WebviewView | undefined; + private client: ACPClient; + private readonly outputChannel: vscode.OutputChannel; + private readonly editorBridge: EditorBridge; + private readonly history: HistoryManager; + private currentPermissionMode: PermissionMode; + private currentSessionId: string | null = null; + private currentMode = ""; + private disposed = false; + private connectedOnce = false; + /** Becomes true once the webview React tree posts ext:webview_ready. */ + private webviewReady = false; + /** + * Buffer for postMessage() calls issued before the webview signaled readiness. + * VSCode's postMessage is fire-and-forget; if the receiving listener has not + * attached yet (cold start race), the message is silently dropped. We queue + * here and flush on ext:webview_ready. + */ + private readyQueue: unknown[] = []; + + constructor( + private readonly extensionUri: vscode.Uri, + private readonly statusBar: StatusBarManager, + globalState: vscode.Memento, + ) { + this.outputChannel = vscode.window.createOutputChannel("CCB"); + this.editorBridge = new EditorBridge(); + this.history = new HistoryManager(globalState); + this.currentPermissionMode = readPermissionModeSetting(); + this.client = this.createClient(); + } + + // --------------------------------------------------------------------------- + // VSCode lifecycle + // --------------------------------------------------------------------------- + resolveWebviewView(webviewView: vscode.WebviewView): void { + // First resolve vs replacing an existing view. When `this.view` was already + // set, the prior React tree is gone and any messages still in readyQueue + // belonged to that dead listener — clear them. When this is the first + // resolve, callers (e.g. sendSelection invoked before sidebar opened) may + // have legitimately queued ext:inject_text / ext:notice; preserve those. + const replacingView = this.view !== undefined; + this.view = webviewView; + // Reset readiness — a freshly resolved view always means a fresh React mount. + this.webviewReady = false; + if (replacingView) { + this.readyQueue = []; + } + webviewView.webview.options = { + enableScripts: true, + localResourceRoots: [vscode.Uri.joinPath(this.extensionUri, "dist")], + }; + // Register the receiver BEFORE assigning HTML so we never miss the + // webview's first ext:webview_ready (Codex finding 2026-04-25). + webviewView.webview.onDidReceiveMessage((msg: AnyMessage) => { + void this.handleWebviewMessage(msg); + }); + webviewView.webview.html = this.buildHtml(webviewView.webview); + + webviewView.onDidChangeVisibility(() => { + if (!webviewView.visible) return; + if (!this.client.isRunning()) { + void this.client.start(); + } + // Re-push cached commands every time the sidebar becomes visible — + // hidden webviews can miss postMessage deliveries even with + // retainContextWhenHidden=true on certain VSCode builds. + const cmds = this.client.getAvailableCommands(); + if (cmds.length > 0) { + this.postToWebview({ type: "ext:available_commands", payload: { commands: cmds } }); + } else { + this.scheduleCommandsRefresh(); + } + }); + + void this.client.start(); + } + + dispose(): void { + if (this.disposed) return; + this.disposed = true; + this.client.shutdown(); + this.outputChannel.dispose(); + } + + // --------------------------------------------------------------------------- + // Public commands invoked from extension.ts + // --------------------------------------------------------------------------- + async newChat(): Promise { + this.connectedOnce = false; + this.client.shutdown(); + this.postToWebview({ type: "ext:notice", payload: { level: "info", message: "Starting a new session..." } }); + this.client = this.createClient(); + await this.client.start(); + } + + cancel(): void { + void this.client.cancel(); + } + + cycleMode(): void { + const next = nextPermissionMode(this.currentPermissionMode); + void this.setPermissionMode(next); + } + + async sendSelection(): Promise { + const ctx = this.editorBridge.getSelectedTextWithContext(); + if (!ctx) { + void vscode.window.showInformationMessage("No text selected."); + return; + } + const text = `Here is code from \`${ctx.filePath}\` (lines ${ctx.startLine}-${ctx.endLine}, ${ctx.language}):\n\`\`\`${ctx.language}\n${ctx.selectedText}\n\`\`\``; + this.postToWebview({ type: "ext:inject_text", payload: { text } }); + await this.sendPromptText(text); + } + + async sendFileContext(): Promise { + const ctx = this.editorBridge.getActiveFileContext(); + if (!ctx) { + void vscode.window.showInformationMessage("No active editor."); + return; + } + const text = `Here is the full content of \`${ctx.filePath}\` (${ctx.language}):\n\`\`\`${ctx.language}\n${ctx.content}\n\`\`\``; + this.postToWebview({ type: "ext:inject_text", payload: { text } }); + await this.sendPromptText(text); + } + + restartAgent(): void { + void this.newChat(); + } + + openHistory(): void { + const entries = this.history.getRecent(20); + void vscode.window + .showQuickPick( + entries.map((e) => ({ + label: e.title || e.id, + description: new Date(e.timestamp).toLocaleString(), + detail: e.preview, + id: e.id, + })), + { title: "CCB session history", placeHolder: "Pick a session to resume" }, + ) + .then((pick) => { + if (!pick) return; + this.postToWebview({ type: "ext:notice", payload: { level: "info", message: `Resuming session ${pick.id}` } }); + // Forward to webview so it can request resume_session through the bridge. + void this.handleWebviewMessage({ type: "ext:resume_session", payload: { sessionId: pick.id } }); + }); + } + + clearScreen(): void { + this.postToWebview({ type: "ext:notice", payload: { level: "info", message: "screen cleared" } }); + // Webview interprets this and clears its message list (handled in App.tsx). + this.postToWebview({ type: "ext:cwd", payload: { cwd: this.client.getCwd() ?? "" } }); + } + + searchHistory(): void { + const prompts = this.history.getPromptHistory(); + if (prompts.length === 0) { + void vscode.window.showInformationMessage("No prompt history yet."); + return; + } + void vscode.window + .showQuickPick(prompts.slice(0, 50), { title: "Search prompt history", matchOnDescription: true }) + .then((pick) => { + if (!pick) return; + this.postToWebview({ type: "ext:inject_text", payload: { text: pick } }); + }); + } + + toggleThinking(): void { + const cfg = vscode.workspace.getConfiguration("ccb"); + const current = cfg.get("showThinking", true); + void cfg.update("showThinking", !current, vscode.ConfigurationTarget.Global); + this.postToWebview({ type: "ext:notice", payload: { level: "info", message: `Extended thinking ${!current ? "shown" : "hidden"}` } }); + } + + // --------------------------------------------------------------------------- + // Webview message handling + // --------------------------------------------------------------------------- + private async handleWebviewMessage(msg: AnyMessage): Promise { + switch (msg.type) { + case "ext:webview_ready": { + // Mark ready and flush anything that was queued before the React tree + // mounted its message listener. + const wasQueued = this.readyQueue.length; + this.webviewReady = true; + if (wasQueued > 0) { + for (const m of this.readyQueue) { + this.view?.webview.postMessage(m); + } + this.readyQueue = []; + } + // Re-publish current state so a freshly-mounted webview catches up. + const caps = this.client.getCapabilities(); + this.postToWebview({ + type: "ext:status", + payload: { + connected: this.client.isRunning(), + capabilities: caps ?? undefined, + cwd: this.client.getCwd() ?? undefined, + }, + }); + if (this.currentSessionId) { + this.postToWebview({ + type: "ext:session_created", + payload: { + sessionId: this.currentSessionId, + models: this.client.getModelState(), + modes: this.client.getModeState(), + }, + }); + } + if (this.currentMode) { + this.postToWebview({ type: "ext:mode_changed", payload: { modeId: this.currentMode } }); + } + const cachedCommands = this.client.getAvailableCommands(); + if (cachedCommands.length > 0) { + this.postToWebview({ type: "ext:available_commands", payload: { commands: cachedCommands } }); + } + // Always also schedule a polling refresh — the cached snapshot may be + // stale (commands changed), or the agent's first + // `available_commands_update` may still be in flight when the webview + // mounts. + this.scheduleCommandsRefresh(); + return; + } + + case "ext:new_session": { + const payload = msg.payload as { permissionMode?: string } | undefined; + const mode = (payload?.permissionMode as PermissionMode | undefined) ?? this.currentPermissionMode; + try { + await this.client.newSession(mode); + } catch (err) { + this.sendError(err); + } + return; + } + + case "ext:prompt": { + const payload = msg.payload as { content: Array<{ type: string; text?: string; data?: string; mimeType?: string; uri?: string }> } | undefined; + if (!payload) return; + // Capture the first text block in prompt history for Up/Down nav. + const firstText = payload.content.find((c) => c.type === "text" && typeof c.text === "string")?.text; + if (firstText) this.history.pushPrompt(firstText); + // The webview can dispatch ext:prompt before bootstrapSession() has + // resolved. Without an active session ACPClient.prompt() throws "No + // active session" and the user sees nothing happen. Lazily create one + // here so the first message always lands. + try { + if (!this.client.getSessionId()) { + await this.client.newSession(this.currentPermissionMode); + } + await this.client.prompt(payload.content as Parameters[0]); + } catch (err) { + this.sendError(err); + } + return; + } + + case "ext:cancel": { + await this.client.cancel(); + return; + } + + case "ext:permission_response": { + const payload = msg.payload as { requestId: string; outcome: { outcome: "cancelled" } | { outcome: "selected"; optionId: string } } | undefined; + if (!payload) return; + await this.client.respondToPermission(payload.requestId, payload.outcome); + return; + } + + case "ext:elicitation_response": { + const payload = msg.payload as { + requestId: string; + response: Parameters[1]; + } | undefined; + if (!payload) return; + await this.client.respondToElicitation(payload.requestId, payload.response); + return; + } + + case "ext:set_session_model": { + const payload = msg.payload as { modelId: string } | undefined; + if (!payload) return; + try { + await this.client.setSessionModel(payload.modelId); + this.statusBar.updateModel(payload.modelId); + this.postToWebview({ type: "ext:model_changed", payload: { modelId: payload.modelId } }); + } catch (err) { + this.sendError(err); + } + return; + } + + case "ext:set_session_mode": { + const payload = msg.payload as { modeId: string } | undefined; + if (!payload) return; + await this.setPermissionMode(payload.modeId as PermissionMode); + return; + } + + case "ext:list_sessions": { + try { + const result = await this.client.listSessions(msg.payload as Parameters[0]); + this.postToWebview({ type: "ext:session_list", payload: result }); + } catch (err) { + this.sendError(err); + } + return; + } + + case "ext:load_session": { + const payload = msg.payload as { sessionId: string; cwd?: string } | undefined; + if (!payload) return; + try { + await this.client.loadSession(payload); + } catch (err) { + this.sendError(err); + } + return; + } + + case "ext:resume_session": { + const payload = msg.payload as { sessionId: string; cwd?: string } | undefined; + if (!payload) return; + try { + await this.client.resumeSession(payload); + } catch (err) { + this.sendError(err); + } + return; + } + + case "ext:open_file": { + const payload = msg.payload as { path: string; line?: number } | undefined; + if (!payload) return; + await this.editorBridge.openFile(payload.path, payload.line); + return; + } + + case "ext:copy": { + const payload = msg.payload as { text: string } | undefined; + if (!payload) return; + await this.editorBridge.copyToClipboard(payload.text); + void vscode.window.showInformationMessage("Copied to clipboard"); + return; + } + + case "ext:apply_diff": { + const payload = msg.payload as { path: string; oldText?: string | null; newText: string } | undefined; + if (!payload) return; + try { + await this.editorBridge.showDiff(payload.path, payload.oldText, payload.newText); + } catch (err) { + this.sendError(err); + } + return; + } + + case "ext:send_selection": { + await this.sendSelection(); + return; + } + + case "ext:send_file": { + await this.sendFileContext(); + return; + } + + case "ext:find_files": { + const payload = msg.payload as { query: string; requestId: string; max?: number } | undefined; + if (!payload) return; + try { + const files = await this.editorBridge.findFiles(payload.query, payload.max); + this.postToWebview({ + type: "ext:find_files_result", + payload: { requestId: payload.requestId, files }, + }); + } catch (err) { + this.sendError(err); + } + return; + } + + case "ext:get_diagnostics": { + const payload = msg.payload as { uri?: string; requestId: string } | undefined; + if (!payload) return; + const items = this.editorBridge.getDiagnostics(payload.uri); + this.postToWebview({ + type: "ext:diagnostics_result", + payload: { requestId: payload.requestId, items }, + }); + return; + } + + case "ext:restart_agent": { + await this.newChat(); + return; + } + + case "ext:save_history_meta": { + const payload = msg.payload as { sessionId: string; title: string; preview: string; messageCount: number; model: string } | undefined; + if (!payload) return; + this.history.upsert({ + id: payload.sessionId, + title: payload.title, + timestamp: Date.now(), + messageCount: payload.messageCount, + model: payload.model, + preview: payload.preview, + cwd: this.client.getCwd() ?? undefined, + }); + this.history.setLastSessionId(payload.sessionId); + return; + } + } + } + + // --------------------------------------------------------------------------- + // Internal helpers + // --------------------------------------------------------------------------- + private async sendPromptText(text: string): Promise { + if (!this.currentSessionId) { + // Defer: send_session implicitly creates one if needed. + try { + await this.client.newSession(this.currentPermissionMode); + } catch (err) { + this.sendError(err); + return; + } + } + try { + await this.client.prompt([{ type: "text", text }]); + } catch (err) { + this.sendError(err); + } + } + + private async setPermissionMode(mode: PermissionMode): Promise { + this.currentPermissionMode = mode; + this.currentMode = mode; + this.statusBar.updateMode(mode); + this.postToWebview({ type: "ext:mode_changed", payload: { modeId: mode } }); + + // Persist as a workspace-scoped default for next launches. + try { + await vscode.workspace + .getConfiguration("ccb") + .update("permissionMode", mode, vscode.ConfigurationTarget.Workspace); + } catch { + /* may not be a workspace; ignore */ + } + + // Try to apply on the live session via ACP setSessionMode. If the agent + // rejects (no live mode state, methodNotFound, or any other error), fall + // back to recreating the session with the new mode in `_meta` — that's + // the only path that's guaranteed to work for agents that don't implement + // `session/set_mode` server-side. + const liveSession = this.client.getModeState() && this.client.getSessionId(); + if (liveSession) { + try { + await this.client.setSessionMode(mode); + return; + } catch (err) { + this.outputChannel.appendLine( + `[ChatViewProvider] setSessionMode rejected (${(err as Error).message}); falling back to session reset`, + ); + } + } + // Fallback: replay newSession with the new permissionMode. The current + // conversation is dropped — that's the cost of the agent not supporting + // live mode switching. We surface a notice so the user understands. + this.postToWebview({ + type: "ext:notice", + payload: { level: "info", message: `Session reset to apply mode "${mode}"` }, + }); + try { + await this.client.newSession(mode); + } catch (err) { + this.sendError(err); + } + } + + private createClient(): ACPClient { + const enableFs = vscode.workspace.getConfiguration("ccb").get("enableFsCapabilities", true); + + const client = new ACPClient( + { + onStatus: (status) => { + if (status.connected && !this.connectedOnce) { + this.connectedOnce = true; + // Auto-create a session as soon as the agent comes up so the user can chat. + const resumeId = vscode.workspace.getConfiguration("ccb").get("resumeLastSession", true) + ? this.history.getLastSessionId() + : undefined; + void this.bootstrapSession(resumeId).catch((err) => this.sendError(err)); + } + this.statusBar.update(status.connected ? "idle" : "disconnected"); + this.postToWebview({ type: "ext:status", payload: status }); + if (status.cwd) this.postToWebview({ type: "ext:cwd", payload: { cwd: status.cwd } }); + }, + onSessionCreated: (payload) => { + this.currentSessionId = payload.sessionId; + if (payload.models?.currentModelId) { + this.statusBar.updateModel(payload.models.currentModelId); + } + if (payload.modes?.currentModeId) { + this.currentMode = payload.modes.currentModeId; + this.statusBar.updateMode(payload.modes.currentModeId); + } + this.postToWebview({ type: "ext:session_created", payload }); + }, + onSessionUpdate: (sessionId, update) => { + this.postToWebview({ type: "ext:session_update", payload: { sessionId, update } }); + // Belt-and-braces: also push a dedicated ext:available_commands + // event so the webview always sees the catalog even if the inline + // session_update path is missed by an early-mounted reducer. + if (update.sessionUpdate === "available_commands_update") { + this.postToWebview({ + type: "ext:available_commands", + payload: { commands: update.availableCommands }, + }); + } + }, + onPromptComplete: (stopReason) => { + this.statusBar.update("idle"); + this.postToWebview({ type: "ext:prompt_complete", payload: { stopReason } }); + // Persist a lightweight record so the user can resume later. + if (this.currentSessionId) { + this.history.setLastSessionId(this.currentSessionId); + } + }, + onPermissionRequest: (req) => { + this.statusBar.update("waiting_permission"); + this.postToWebview({ type: "ext:permission_request", payload: req }); + }, + onElicitationRequest: (req) => { + this.statusBar.update("waiting_permission"); + this.postToWebview({ type: "ext:elicitation_request", payload: req }); + }, + onError: (message) => { + this.outputChannel.appendLine(`[CCB] ${message}`); + this.postToWebview({ type: "ext:error", payload: { message } }); + }, + onModeChanged: (modeId) => { + this.currentMode = modeId; + this.statusBar.updateMode(modeId); + this.postToWebview({ type: "ext:mode_changed", payload: { modeId } }); + }, + onProcessExit: (code) => { + if (code !== 0 && code !== null) { + this.postToWebview({ + type: "ext:notice", + payload: { level: "error", message: `Agent exited with code ${code}` }, + }); + } + }, + readTextFile: async ({ path: absPath, line, limit }) => { + const content = await this.editorBridge.acpReadTextFile(absPath, line ?? undefined, limit ?? undefined); + return { content }; + }, + writeTextFile: async ({ path: absPath, content }) => { + await this.editorBridge.acpWriteTextFile(absPath, content); + return {}; + }, + }, + { + extensionDir: this.extensionUri.fsPath, + enableFsCapabilities: enableFs, + permissionTimeoutMs: PERMISSION_TIMEOUT_MS, + outputChannel: this.outputChannel, + }, + ); + return client; + } + + private async bootstrapSession(resumeId: string | undefined): Promise { + if (resumeId) { + const caps = this.client.getCapabilities(); + const supportsResume = caps?.sessionCapabilities?.resume != null; + const supportsLoad = caps?.loadSession === true; + try { + if (supportsResume) { + await this.client.resumeSession({ sessionId: resumeId }); + return; + } + if (supportsLoad) { + await this.client.loadSession({ sessionId: resumeId }); + return; + } + } catch (err) { + this.outputChannel.appendLine(`[CCB] resume/load failed (${(err as Error).message}), creating new session`); + } + } + await this.client.newSession(this.currentPermissionMode); + } + + private sendError(err: unknown): void { + const message = err instanceof Error ? err.message : String(err); + this.outputChannel.appendLine(`[CCB] ${message}`); + this.postToWebview({ type: "ext:error", payload: { message } }); + } + + private postToWebview(message: unknown): void { + // Ready barrier: VSCode's webview.postMessage is fire-and-forget. If the + // React tree hasn't mounted its message listener yet (cold start race), + // the message is silently dropped. Queue until ext:webview_ready arrives, + // at which point handleWebviewMessage flushes the queue. + if (!this.webviewReady) { + this.readyQueue.push(message); + return; + } + this.view?.webview.postMessage(message); + } + + /** + * Polls the ACPClient command cache and pushes them to the webview as soon + * as they show up. Cold-start can be 2-5 seconds (spawn + initialize + + * newSession + agent's setTimeout(0) emit), so we extend the polling window + * to 30s. Once delivered we stop. Multiple concurrent calls are coalesced + * via a generation counter so we don't spam the webview. + */ + private commandsRefreshGen = 0; + private scheduleCommandsRefresh(): void { + const myGen = ++this.commandsRefreshGen; + let attempts = 0; + const maxAttempts = 150; // 150 × 200ms = 30s + const tick = () => { + // A newer scheduler superseded us — bail out so we don't double-push. + if (myGen !== this.commandsRefreshGen) return; + // The view was disposed; stop polling. + if (!this.view) return; + attempts += 1; + const cmds = this.client.getAvailableCommands(); + if (cmds.length > 0) { + this.postToWebview({ type: "ext:available_commands", payload: { commands: cmds } }); + return; + } + if (attempts < maxAttempts) { + setTimeout(tick, 200); + } + }; + setTimeout(tick, 100); + } + + private buildHtml(webview: vscode.Webview): string { + const nonce = randomBytes(16).toString("hex"); + const scriptUri = webview.asWebviewUri( + vscode.Uri.joinPath(this.extensionUri, "dist", "webview.js"), + ); + return ` + + + + + + CCB Chat + + +
+ + +`; + } +} + +function readPermissionModeSetting(): PermissionMode { + const value = vscode.workspace.getConfiguration("ccb").get("permissionMode", "default"); + return (PERMISSION_MODES as readonly string[]).includes(value) ? (value as PermissionMode) : "default"; +} + +function nextPermissionMode(current: PermissionMode): PermissionMode { + const idx = PERMISSION_MODES.indexOf(current); + return PERMISSION_MODES[(idx + 1) % PERMISSION_MODES.length]; +} + +// Re-export for any downstream type consumers (none yet). +export type ChatStatusBarState = StatusBarState; diff --git a/packages/vscode-extension/src/EditorBridge.ts b/packages/vscode-extension/src/EditorBridge.ts new file mode 100644 index 000000000..34b1b54df --- /dev/null +++ b/packages/vscode-extension/src/EditorBridge.ts @@ -0,0 +1,267 @@ +import * as path from "node:path"; +import * as vscode from "vscode"; + +export interface DiagnosticItem { + uri: string; + range: { startLine: number; endLine: number }; + message: string; + severity: "error" | "warning" | "info" | "hint"; + source?: string; +} + +export interface FileSearchEntry { + path: string; // absolute fs path + relPath: string; // path relative to workspace root +} + +/** + * VSCode integration surface used by both the chat view (selection / diff / + * file context) and the ACP `Client` callbacks (readTextFile / writeTextFile). + * + * All filesystem mutations go through `vscode.workspace.fs` so that they + * participate in the editor's undo stack and trigger language server refreshes. + */ +export class EditorBridge { + // --------------------------------------------------------------------------- + // Editor selection / file context (used by send_selection / send_file) + // --------------------------------------------------------------------------- + + getSelectedText(): string { + const editor = vscode.window.activeTextEditor; + if (!editor || editor.selection.isEmpty) return ""; + return editor.document.getText(editor.selection); + } + + getActiveFileContext(): { filePath: string; language: string; content: string } | null { + const editor = vscode.window.activeTextEditor; + if (!editor) return null; + return { + filePath: editor.document.uri.fsPath, + language: editor.document.languageId, + content: editor.document.getText(), + }; + } + + getSelectedTextWithContext(): { + filePath: string; + language: string; + selectedText: string; + startLine: number; + endLine: number; + } | null { + const editor = vscode.window.activeTextEditor; + if (!editor || editor.selection.isEmpty) return null; + return { + filePath: editor.document.uri.fsPath, + language: editor.document.languageId, + selectedText: editor.document.getText(editor.selection), + startLine: editor.selection.start.line + 1, + endLine: editor.selection.end.line + 1, + }; + } + + // --------------------------------------------------------------------------- + // Diff view (apply_diff) + // --------------------------------------------------------------------------- + + async showDiff(filePath: string, oldText: string | null | undefined, newText: string): Promise { + const fileUri = vscode.Uri.file(filePath); + const original = oldText ?? ""; + // Use untitled scheme for the proposed side so it's editable / closable. + const proposed = vscode.Uri.parse( + `untitled:${path.basename(filePath)}.proposed`, + ); + + // Seed both sides through workspaceEdit so the diff shows real content. + await vscode.workspace.openTextDocument({ content: original, language: this.guessLanguage(filePath) }); + const proposedDoc = await vscode.workspace.openTextDocument(proposed); + const edit = new vscode.WorkspaceEdit(); + edit.insert(proposed, new vscode.Position(0, 0), newText); + await vscode.workspace.applyEdit(edit); + + await vscode.commands.executeCommand( + "vscode.diff", + fileUri, + proposedDoc.uri, + `${path.basename(filePath)}: agent edit preview`, + ); + } + + /** + * Apply a unified diff blob (legacy `apply_diff` from earlier protocol). + * For ACP, prefer writeTextFile or showDiff with explicit oldText/newText. + */ + async applyDiffPreview(filePath: string, oldText: string | null | undefined, newText: string): Promise { + return this.showDiff(filePath, oldText, newText); + } + + // --------------------------------------------------------------------------- + // Open file at line + // --------------------------------------------------------------------------- + + async openFile(filePath: string, line?: number): Promise { + const uri = vscode.Uri.file(filePath); + const doc = await vscode.workspace.openTextDocument(uri); + const editor = await vscode.window.showTextDocument(doc, { preview: true }); + if (line !== undefined && line > 0) { + const pos = new vscode.Position(line - 1, 0); + editor.selection = new vscode.Selection(pos, pos); + editor.revealRange(new vscode.Range(pos, pos), vscode.TextEditorRevealType.InCenter); + } + } + + // --------------------------------------------------------------------------- + // Insert / clipboard + // --------------------------------------------------------------------------- + + async insertAtCursor(text: string): Promise { + const editor = vscode.window.activeTextEditor; + if (!editor) return false; + return editor.edit((b) => b.insert(editor.selection.active, text)); + } + + async copyToClipboard(text: string): Promise { + await vscode.env.clipboard.writeText(text); + } + + // --------------------------------------------------------------------------- + // ACP filesystem capabilities + // --------------------------------------------------------------------------- + + async acpReadTextFile(absPath: string, line?: number, limit?: number): Promise { + const uri = vscode.Uri.file(absPath); + // Prefer the open-document snapshot so unsaved edits are visible to the agent. + const open = vscode.workspace.textDocuments.find((d) => d.uri.toString() === uri.toString()); + let content: string; + if (open) { + content = open.getText(); + } else { + const buf = await vscode.workspace.fs.readFile(uri); + content = new TextDecoder("utf-8").decode(buf); + } + if (line === undefined && limit === undefined) return content; + const lines = content.split(/\r?\n/); + const startIdx = Math.max(0, (line ?? 1) - 1); + const endIdx = limit === undefined ? lines.length : Math.min(lines.length, startIdx + limit); + return lines.slice(startIdx, endIdx).join("\n"); + } + + async acpWriteTextFile(absPath: string, content: string): Promise { + const uri = vscode.Uri.file(absPath); + const open = vscode.workspace.textDocuments.find((d) => d.uri.toString() === uri.toString()); + if (open) { + const edit = new vscode.WorkspaceEdit(); + const fullRange = new vscode.Range( + new vscode.Position(0, 0), + open.lineAt(open.lineCount - 1).range.end, + ); + edit.replace(uri, fullRange, content); + const applied = await vscode.workspace.applyEdit(edit); + if (!applied) { + throw new Error(`workspace.applyEdit refused for ${absPath}`); + } + await open.save(); + return; + } + // Ensure parent directory exists for newly created files. + const parentDir = vscode.Uri.file(path.dirname(absPath)); + try { + await vscode.workspace.fs.createDirectory(parentDir); + } catch { + /* parent may already exist */ + } + await vscode.workspace.fs.writeFile(uri, new TextEncoder().encode(content)); + } + + // --------------------------------------------------------------------------- + // @-mention file search & diagnostics (used by webview lookups) + // --------------------------------------------------------------------------- + + async findFiles(query: string, max = 30): Promise { + const folders = vscode.workspace.workspaceFolders; + if (!folders || folders.length === 0) return []; + const root = folders[0]; + const sanitised = sanitiseGlobQuery(query); + const pattern = new vscode.RelativePattern(root, `**/${sanitised}*`); + const ignore = new vscode.RelativePattern(root, "**/{node_modules,.git,dist,build}/**"); + const files = await vscode.workspace.findFiles(pattern, ignore, max); + return files.map((u) => ({ + path: u.fsPath, + relPath: path.relative(root.uri.fsPath, u.fsPath).replace(/\\/g, "/"), + })); + } + + getDiagnostics(uri?: string): DiagnosticItem[] { + const items: DiagnosticItem[] = []; + const collect = (u: vscode.Uri, ds: readonly vscode.Diagnostic[]) => { + for (const d of ds) { + items.push({ + uri: u.fsPath, + range: { startLine: d.range.start.line + 1, endLine: d.range.end.line + 1 }, + message: d.message, + severity: severityToString(d.severity), + source: d.source, + }); + } + }; + if (uri) { + const u = vscode.Uri.file(uri); + collect(u, vscode.languages.getDiagnostics(u)); + } else { + const all = vscode.languages.getDiagnostics(); + for (const [u, ds] of all) collect(u, ds); + } + return items; + } + + // --------------------------------------------------------------------------- + // Helpers + // --------------------------------------------------------------------------- + + private guessLanguage(filePath: string): string { + const ext = path.extname(filePath).toLowerCase(); + switch (ext) { + case ".ts": + case ".tsx": + return "typescript"; + case ".js": + case ".jsx": + return "javascript"; + case ".py": + return "python"; + case ".go": + return "go"; + case ".rs": + return "rust"; + case ".java": + return "java"; + case ".cpp": + case ".cc": + case ".hpp": + return "cpp"; + case ".md": + return "markdown"; + case ".json": + return "json"; + default: + return "plaintext"; + } + } +} + +function severityToString(s: vscode.DiagnosticSeverity): "error" | "warning" | "info" | "hint" { + switch (s) { + case vscode.DiagnosticSeverity.Error: + return "error"; + case vscode.DiagnosticSeverity.Warning: + return "warning"; + case vscode.DiagnosticSeverity.Information: + return "info"; + case vscode.DiagnosticSeverity.Hint: + return "hint"; + } +} + +function sanitiseGlobQuery(q: string): string { + return q.replace(/[\\{}()[\]!?]/g, ""); +} diff --git a/packages/vscode-extension/src/HistoryManager.ts b/packages/vscode-extension/src/HistoryManager.ts new file mode 100644 index 000000000..6472077a2 --- /dev/null +++ b/packages/vscode-extension/src/HistoryManager.ts @@ -0,0 +1,78 @@ +import * as vscode from "vscode"; + +export interface HistoryEntry { + id: string; // sessionId from agent + title: string; + timestamp: number; // unix ms + messageCount: number; + model: string; + preview: string; + cwd?: string; +} + +const HISTORY_KEY = "ccb.chatHistory"; +const LAST_SESSION_KEY = "ccb.lastSessionId"; +const PROMPT_HISTORY_KEY = "ccb.promptHistory"; +const MAX_ENTRIES = 50; +const MAX_PROMPTS = 200; + +/** + * Persists session metadata + prompt-text history in VSCode globalState + * (per-machine, survives reloads). Session IDs come from the ACP agent so + * they map directly to `unstable_resumeSession` / `loadSession` requests. + */ +export class HistoryManager { + constructor(private readonly globalState: vscode.Memento) {} + + // Session metadata -------------------------------------------------------- + getAll(): HistoryEntry[] { + return this.globalState.get(HISTORY_KEY, []); + } + + upsert(entry: HistoryEntry): void { + const existing = this.getAll().filter((e) => e.id !== entry.id); + const next = [entry, ...existing].slice(0, MAX_ENTRIES); + void this.globalState.update(HISTORY_KEY, next); + } + + remove(id: string): void { + const next = this.getAll().filter((e) => e.id !== id); + void this.globalState.update(HISTORY_KEY, next); + } + + clearSessions(): void { + void this.globalState.update(HISTORY_KEY, []); + } + + getRecent(count: number): HistoryEntry[] { + return this.getAll().slice(0, count); + } + + // Last-active session (for resume on extension reload) + getLastSessionId(): string | undefined { + return this.globalState.get(LAST_SESSION_KEY); + } + + setLastSessionId(id: string | undefined): void { + void this.globalState.update(LAST_SESSION_KEY, id); + } + + // Prompt history (for Up/Down navigation + Ctrl+R search) ---------------- + getPromptHistory(): string[] { + return this.globalState.get(PROMPT_HISTORY_KEY, []); + } + + pushPrompt(text: string): void { + const trimmed = text.trim(); + if (!trimmed) return; + const existing = this.getPromptHistory(); + // Drop consecutive duplicate. + if (existing[0] === trimmed) return; + const next = [trimmed, ...existing.filter((p) => p !== trimmed)].slice(0, MAX_PROMPTS); + void this.globalState.update(PROMPT_HISTORY_KEY, next); + } + + clearPromptHistory(): void { + void this.globalState.update(PROMPT_HISTORY_KEY, []); + } +} diff --git a/packages/vscode-extension/src/StatusBarManager.ts b/packages/vscode-extension/src/StatusBarManager.ts new file mode 100644 index 000000000..a0ebc8779 --- /dev/null +++ b/packages/vscode-extension/src/StatusBarManager.ts @@ -0,0 +1,138 @@ +import * as vscode from "vscode"; + +export type StatusBarState = + | "idle" + | "connecting" + | "thinking" + | "streaming" + | "disconnected" + | "waiting_permission"; + +export class StatusBarManager implements vscode.Disposable { + private item: vscode.StatusBarItem; + private currentState: StatusBarState = "disconnected"; + private inputTokens = 0; + private outputTokens = 0; + private cacheTokens = 0; + private cost = 0; + private model = ""; + private mode = ""; + private disposed = false; + + constructor() { + this.item = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Right, + 100 + ); + this.item.command = "ccb.focus"; + this.update("disconnected"); + this.item.show(); + } + + update(state: StatusBarState): void { + this.currentState = state; + this.render(); + } + + updateModel(model: string): void { + this.model = model; + this.render(); + } + + updateMode(mode: string): void { + this.mode = mode; + this.render(); + } + + updateTokens( + input: number, + output: number, + cache: number, + totalCost: number + ): void { + this.inputTokens = input; + this.outputTokens = output; + this.cacheTokens = cache; + this.cost = totalCost; + this.render(); + } + + resetTokens(): void { + this.inputTokens = 0; + this.outputTokens = 0; + this.cacheTokens = 0; + this.cost = 0; + this.render(); + } + + private render(): void { + const { icon, label } = this.getIconAndLabel(); + const modePart = this.mode ? ` ⋄ ${formatMode(this.mode)}` : ""; + this.item.text = `${icon} ${label}${modePart}`; + this.item.tooltip = this.buildTooltip(); + } + + private getIconAndLabel(): { icon: string; label: string } { + switch (this.currentState) { + case "idle": + return { icon: "$(circle-outline)", label: "CCB" }; + case "connecting": + return { icon: "$(loading~spin)", label: "CCB: Connecting" }; + case "thinking": + return { icon: "$(loading~spin)", label: "CCB: Thinking" }; + case "streaming": + return { icon: "$(pulse)", label: "CCB: Streaming" }; + case "disconnected": + return { icon: "$(circle-slash)", label: "CCB: Offline" }; + case "waiting_permission": + return { icon: "$(shield)", label: "CCB: Permission" }; + } + } + + private buildTooltip(): string { + const lines = [`CCB (Claude Code Best) - ${this.currentState}`]; + if (this.model) lines.push(`Model: ${this.model}`); + if (this.mode) lines.push(`Mode: ${formatMode(this.mode)}`); + if (this.inputTokens > 0 || this.outputTokens > 0) { + lines.push( + `Input: ${formatTokens(this.inputTokens)} | Output: ${formatTokens(this.outputTokens)}` + ); + if (this.cacheTokens > 0) { + lines.push(`Cache: ${formatTokens(this.cacheTokens)}`); + } + if (this.cost > 0) { + lines.push(`Cost: $${this.cost.toFixed(4)}`); + } + } + return lines.join("\n"); + } + + dispose(): void { + if (this.disposed) return; + this.disposed = true; + this.item.dispose(); + } +} + +function formatTokens(n: number): string { + if (n >= 1_000_000) { + return `${(n / 1_000_000).toFixed(1)}M`; + } + if (n >= 1_000) { + return `${(n / 1_000).toFixed(1)}k`; + } + return String(n); +} + +const MODE_LABELS: Record = { + default: "default", + acceptEdits: "auto-edit", + bypassPermissions: "bypass", + plan: "plan", + dontAsk: "dont-ask", + auto: "auto", +}; + +function formatMode(mode: string): string { + return MODE_LABELS[mode] ?? mode; +} diff --git a/packages/vscode-extension/src/agentSpawner.ts b/packages/vscode-extension/src/agentSpawner.ts new file mode 100644 index 000000000..ea627849f --- /dev/null +++ b/packages/vscode-extension/src/agentSpawner.ts @@ -0,0 +1,153 @@ +import { execFileSync } from "node:child_process"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import * as vscode from "vscode"; + +export interface ResolvedAgent { + command: string; + args: string[]; // includes the `--acp` final arg; caller may append further flags + cwd: string; + runtime: "node" | "bun" | "direct"; +} + +/** + * Locate the CCB CLI binary and produce a spawn() command/args that launches + * the agent in ACP mode (`claude --acp` per src/entrypoints/cli.tsx:135). + * + * Resolution order: + * 1. Explicit `ccb.cliPath` setting (absolute path) + * 2. Bun + monorepo source (preferred when developing on the fork) + * 3. dist/cli.js or dist/cli-node.js in monorepo / workspace + * 4. `ccb` or `claude` on PATH + */ +export function resolveAgent(extensionDir: string): ResolvedAgent | null { + const config = vscode.workspace.getConfiguration("ccb"); + const setting = config.get("cliPath", "auto"); + const cwd = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? process.cwd(); + const node = findNode(); + const bun = findBun(); + + if (setting && setting !== "auto") { + if (!path.isAbsolute(setting)) { + throw new Error(`ccb.cliPath must be an absolute path (got "${setting}")`); + } + if (!fs.existsSync(setting)) { + throw new Error(`ccb.cliPath does not exist: ${setting}`); + } + // If setting points to source cli.tsx, run via Bun. + if (setting.endsWith(".tsx") || setting.endsWith(".ts")) { + if (!bun) { + throw new Error(`ccb.cliPath points to TS source but Bun was not found.`); + } + return { command: bun, args: ["run", setting, "--acp"], cwd, runtime: "bun" }; + } + if (isJavaScriptFile(setting)) { + if (node) return { command: node, args: [setting, "--acp"], cwd, runtime: "node" }; + if (bun) return { command: bun, args: [setting, "--acp"], cwd, runtime: "bun" }; + throw new Error(`ccb.cliPath points to JS but neither Node.js nor Bun was found.`); + } + return { command: setting, args: ["--acp"], cwd, runtime: "direct" }; + } + + // auto-detect candidate roots + const realDir = safeRealpath(extensionDir); + const monorepoRoot = path.resolve(realDir, "..", ".."); + const candidateRoots = new Set([safeRealpath(monorepoRoot), safeRealpath(cwd)]); + + for (const root of candidateRoots) { + // 1) bundled dist (preferred — feature flags compiled in) + const cliNodeJs = path.join(root, "dist", "cli-node.js"); + if (fs.existsSync(cliNodeJs) && node) { + return { command: node, args: [cliNodeJs, "--acp"], cwd, runtime: "node" }; + } + const cliJs = path.join(root, "dist", "cli.js"); + if (fs.existsSync(cliJs) && node) { + return { command: node, args: [cliJs, "--acp"], cwd, runtime: "node" }; + } + const cliBunJs = path.join(root, "dist", "cli-bun.js"); + if (fs.existsSync(cliBunJs) && bun) { + return { command: bun, args: [cliBunJs, "--acp"], cwd, runtime: "bun" }; + } + if (fs.existsSync(cliJs) && bun) { + return { command: bun, args: [cliJs, "--acp"], cwd, runtime: "bun" }; + } + // 2) source entry via Bun + scripts/dev.ts (this enables every feature flag, + // including ACP). The plain `bun run cli.tsx` path does NOT enable feature + // gates, so `--acp` would be rejected. + const devScript = path.join(root, "scripts", "dev.ts"); + if (fs.existsSync(devScript) && bun) { + return { command: bun, args: ["run", devScript, "--acp"], cwd, runtime: "bun" }; + } + const cliTsx = path.join(root, "src", "entrypoints", "cli.tsx"); + if (fs.existsSync(cliTsx) && bun) { + // Fallback: explicitly enable ACP feature flag. + return { command: bun, args: ["run", "--feature", "ACP", cliTsx, "--acp"], cwd, runtime: "bun" }; + } + } + + // 3) PATH lookup + for (const candidate of ["ccb", "claude"]) { + const found = findOnPath(candidate); + if (found) return { command: found, args: ["--acp"], cwd, runtime: "direct" }; + } + + return null; +} + +function isJavaScriptFile(p: string): boolean { + return [".js", ".mjs", ".cjs"].includes(path.extname(p).toLowerCase()); +} + +function safeRealpath(p: string): string { + try { + return fs.realpathSync(p); + } catch { + return p; + } +} + +function findBun(): string | null { + const fromPath = findOnPath("bun"); + if (fromPath) return fromPath; + + const home = process.env.USERPROFILE ?? process.env.HOME ?? ""; + const candidates = process.platform === "win32" + ? [path.join(home, ".bun", "bin", "bun.exe")] + : [path.join(home, ".bun", "bin", "bun")]; + for (const c of candidates) { + if (fs.existsSync(c)) return c; + } + return null; +} + +function findNode(): string | null { + const fromPath = findOnPath("node"); + if (fromPath) return fromPath; + + if (process.platform === "win32") { + const candidates = [ + path.join(process.env.ProgramFiles ?? "C:\\Program Files", "nodejs", "node.exe"), + path.join(process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)", "nodejs", "node.exe"), + ]; + for (const candidate of candidates) { + if (fs.existsSync(candidate)) return candidate; + } + } + + return null; +} + +function findOnPath(executable: string): string | null { + const locator = process.platform === "win32" ? "where.exe" : "which"; + try { + const out = execFileSync(locator, [executable], { + encoding: "utf-8", + stdio: ["ignore", "pipe", "ignore"], + }).trim(); + const first = out.split(/\r?\n/).find(Boolean); + if (first && fs.existsSync(first)) return first; + } catch { + /* not on path */ + } + return null; +} diff --git a/packages/vscode-extension/src/extension.ts b/packages/vscode-extension/src/extension.ts new file mode 100644 index 000000000..64775c7b4 --- /dev/null +++ b/packages/vscode-extension/src/extension.ts @@ -0,0 +1,40 @@ +import * as vscode from "vscode"; +import { ChatViewProvider } from "./ChatViewProvider"; +import { StatusBarManager } from "./StatusBarManager"; + +let chatProvider: ChatViewProvider | undefined; +let statusBarManager: StatusBarManager | undefined; + +export function activate(context: vscode.ExtensionContext): void { + statusBarManager = new StatusBarManager(); + chatProvider = new ChatViewProvider(context.extensionUri, statusBarManager, context.globalState); + + const viewRegistration = vscode.window.registerWebviewViewProvider("ccb.chat", chatProvider, { + webviewOptions: { retainContextWhenHidden: true }, + }); + + const commands: Array<[string, () => void | Promise]> = [ + ["ccb.newChat", () => chatProvider?.newChat()], + ["ccb.focus", () => { void vscode.commands.executeCommand("ccb.chat.focus"); }], + ["ccb.cancel", () => chatProvider?.cancel()], + ["ccb.cycleMode", () => chatProvider?.cycleMode()], + ["ccb.sendSelection", () => chatProvider?.sendSelection()], + ["ccb.sendFileContext", () => chatProvider?.sendFileContext()], + ["ccb.restartAgent", () => chatProvider?.restartAgent()], + ["ccb.openHistory", () => chatProvider?.openHistory()], + ["ccb.clearScreen", () => chatProvider?.clearScreen()], + ["ccb.searchHistory", () => chatProvider?.searchHistory()], + ["ccb.toggleThinking", () => chatProvider?.toggleThinking()], + ]; + + const registrations = commands.map(([id, handler]) => vscode.commands.registerCommand(id, handler)); + + context.subscriptions.push(viewRegistration, ...registrations, chatProvider, statusBarManager); +} + +export function deactivate(): void { + chatProvider?.dispose(); + statusBarManager?.dispose(); + chatProvider = undefined; + statusBarManager = undefined; +} diff --git a/packages/vscode-extension/tsconfig.json b/packages/vscode-extension/tsconfig.json new file mode 100644 index 000000000..cc792c23a --- /dev/null +++ b/packages/vscode-extension/tsconfig.json @@ -0,0 +1,37 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": false, + "declarationMap": false, + "sourceMap": true, + "outDir": "dist", + "rootDir": ".", + "lib": [ + "ES2022", + "DOM", + "DOM.Iterable" + ], + "types": [ + "node", + "vscode" + ] + }, + "include": [ + "src/**/*", + "webview/**/*", + "webview/types.d.ts" + ], + "exclude": [ + "node_modules", + "dist", + "**/__tests__/**/*" + ] +} diff --git a/packages/vscode-extension/webview/App.tsx b/packages/vscode-extension/webview/App.tsx new file mode 100644 index 000000000..5433507e3 --- /dev/null +++ b/packages/vscode-extension/webview/App.tsx @@ -0,0 +1,180 @@ +import React, { useCallback, useEffect, useRef, useState } from "react"; +import { useACP } from "./hooks/useACP"; +import { ChatView } from "./components/ChatView"; +import { ElicitationDialog } from "./components/ElicitationDialog"; +import { PermissionPanel } from "./components/PermissionPanel"; +import { PromptInput, type PromptInputHandle } from "./components/PromptInput"; +import { StatusBar } from "./components/StatusBar"; +import { FALLBACK_PERMISSION_MODES } from "./lib/types"; +import cssText from "./styles.css"; + +const SHOW_THINKING_DEFAULT = true; +const AUTOSCROLL_DEFAULT = true; +const PROMPT_HISTORY_LIMIT = 100; + +export function App(): React.ReactElement { + const acp = useACP(); + const inputRef = useRef(null); + const [showThinking, setShowThinking] = useState(SHOW_THINKING_DEFAULT); + const [autoScroll] = useState(AUTOSCROLL_DEFAULT); + const [promptHistory, setPromptHistory] = useState([]); + const [modelPickerOpen, setModelPickerOpen] = useState(false); + const [modeSelectorOpen, setModeSelectorOpen] = useState(false); + + // Subscribe to extension-side text injection (e.g. send_selection from editor). + useEffect(() => { + const off = acp.onInjectText((text) => { + inputRef.current?.insert(text); + }); + return off; + }, [acp]); + + // Keep recent prompts available for ↑/↓ navigation. The extension also + // persists them globally; this is a session-local convenience. + const onPromptSubmitted = useCallback((text: string) => { + if (!text) return; + setPromptHistory((prev) => { + const cleaned = prev.filter((p) => p !== text); + return [text, ...cleaned].slice(0, PROMPT_HISTORY_LIMIT); + }); + }, []); + + const handleSend = useCallback( + (text: string, images?: Parameters[1]) => { + void acp.send(text, images); + }, + [acp], + ); + + const handleCancel = useCallback(() => acp.cancel(), [acp]); + + const handleNewChat = useCallback(() => { + acp.newSession(acp.state.currentMode || "default"); + }, [acp]); + + const handleCycleMode = useCallback(() => { + const modes = acp.state.modeState?.availableModes.map((m) => m.id) ?? Array.from(FALLBACK_PERMISSION_MODES); + if (modes.length === 0) return; + const currentIndex = Math.max(0, modes.indexOf(acp.state.currentMode)); + const next = modes[(currentIndex + 1) % modes.length]; + acp.setMode(next); + }, [acp]); + + const handleOpenModelPicker = useCallback(() => { + setModeSelectorOpen(false); + setModelPickerOpen(true); + }, []); + + const handleSetModeFromSlash = useCallback((modeId: string) => { + setModelPickerOpen(false); + setModeSelectorOpen(false); + acp.setMode(modeId); + }, [acp]); + + const handleToggleThinking = useCallback(() => { + setShowThinking((v) => !v); + }, []); + + const handlePermissionPanelRespond = useCallback( + (requestId: string, optionId: string | null, approved: boolean) => { + acp.respondPermission(requestId, optionId, approved); + }, + [acp], + ); + + const placeholder = computePlaceholder(acp.state.connection, acp.state.isLoading, acp.state.pendingPermissions.length); + const isInputDisabled = acp.state.connection !== "connected"; + + return ( + <> + +
+
+

CCB

+
+ + +
+
+ + {acp.state.errorBanner && ( +
+ {acp.state.errorBanner} +
+ )} + {acp.state.noticeBanner && ( +
+ {acp.state.noticeBanner.message} +
+ )} + + + + + + + + + + +
+ + ); +} + +function computePlaceholder(connection: string, isLoading: boolean, pendingPermissions: number): string { + if (connection !== "connected") { + if (connection === "connecting") return "Connecting to agent..."; + return "Agent disconnected — try Restart Agent from the title bar"; + } + if (pendingPermissions > 0) return `Waiting on ${pendingPermissions} permission${pendingPermissions === 1 ? "" : "s"}...`; + if (isLoading) return "Working — Esc to cancel"; + return "Ask Claude... / for commands · @ for files"; +} diff --git a/packages/vscode-extension/webview/components/ChatView.tsx b/packages/vscode-extension/webview/components/ChatView.tsx new file mode 100644 index 000000000..10828b432 --- /dev/null +++ b/packages/vscode-extension/webview/components/ChatView.tsx @@ -0,0 +1,91 @@ +import React, { useEffect, useRef } from "react"; +import type { ThreadEntry } from "../lib/types"; +import { AssistantBubble, SystemNotice, UserBubble } from "./MessageBubble"; +import { PlanView } from "./PlanView"; +import { ToolCallCard } from "./ToolCallCard"; + +interface ChatViewProps { + entries: ThreadEntry[]; + isLoading: boolean; + showThinking: boolean; + autoScroll: boolean; + onApplyDiff: (path: string, oldText: string | null | undefined, newText: string) => void; + onOpenFile: (path: string, line?: number) => void; +} + +export function ChatView({ + entries, + isLoading, + showThinking, + autoScroll, + onApplyDiff, + onOpenFile, +}: ChatViewProps): React.ReactElement { + const scrollRef = useRef(null); + + useEffect(() => { + if (!autoScroll) return; + const el = scrollRef.current; + if (!el) return; + el.scrollTop = el.scrollHeight; + }, [entries.length, isLoading, autoScroll]); + + if (entries.length === 0) { + return ( +
+
+ +

Ask Claude to start. Type / for commands or @ to reference a file.

+
+
+ ); + } + + return ( +
+ {entries.map((entry) => renderEntry(entry, { showThinking, onApplyDiff, onOpenFile }))} + {isLoading && } +
+ ); +} + +function renderEntry( + entry: ThreadEntry, + ctx: { + showThinking: boolean; + onApplyDiff: ChatViewProps["onApplyDiff"]; + onOpenFile: ChatViewProps["onOpenFile"]; + }, +): React.ReactNode { + switch (entry.type) { + case "user_message": + return ; + case "assistant_message": + return ; + case "tool_call": + return ( + + ); + case "plan": + return ; + case "system": + return ; + } +} + +function LoadingIndicator(): React.ReactElement { + return ( +
+ + + + + +
+ ); +} diff --git a/packages/vscode-extension/webview/components/CommandMenu.tsx b/packages/vscode-extension/webview/components/CommandMenu.tsx new file mode 100644 index 000000000..8f98763e2 --- /dev/null +++ b/packages/vscode-extension/webview/components/CommandMenu.tsx @@ -0,0 +1,121 @@ +import React, { useEffect, useMemo, useRef, useState } from "react"; +import type { AvailableCommand } from "../lib/acp/types"; +import { + commandMatchesFilter, + findCommandByName, + getArgumentOptions, + getStringMeta, +} from "../lib/slashCommands"; + +interface CommandMenuProps { + commands: AvailableCommand[]; + filter: string; + visible: boolean; + commandName?: string; + onSelect: (command: AvailableCommand) => void; + onClose: () => void; +} + +export function CommandMenu({ + commands, + filter, + visible, + commandName, + onSelect, + onClose, +}: CommandMenuProps): React.ReactElement | null { + const containerRef = useRef(null); + const [activeIndex, setActiveIndex] = useState(0); + + const filtered = useMemo(() => { + if (commandName) { + const command = findCommandByName(commands, commandName); + return getArgumentOptions(command?.input?.hint, filter, command).map( + (option): AvailableCommand => ({ + name: option.value, + description: option.label, + input: null, + _meta: { + ccbArgumentFor: commandName, + ccbArgumentValue: option.insertText, + }, + }), + ); + } + + return commands.filter((command) => commandMatchesFilter(command, filter)); + }, [commandName, commands, filter]); + + useEffect(() => setActiveIndex(0), [commandName, filter, commands]); + + useEffect(() => { + if (!visible) return; + function handleClickOutside(e: MouseEvent): void { + if (containerRef.current && !containerRef.current.contains(e.target as Node)) { + onClose(); + } + } + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, [visible, onClose]); + + useEffect(() => { + if (!visible || filtered.length === 0) return; + function handleKey(e: KeyboardEvent): void { + if (e.key === "ArrowDown") { + e.preventDefault(); + setActiveIndex((i) => (i + 1) % filtered.length); + } else if (e.key === "ArrowUp") { + e.preventDefault(); + setActiveIndex((i) => (i - 1 + filtered.length) % filtered.length); + } else if (e.key === "Tab" || (e.key === "Enter" && !e.shiftKey)) { + e.preventDefault(); + const cmd = filtered[activeIndex]; + if (cmd) onSelect(cmd); + } else if (e.key === "Escape") { + e.preventDefault(); + onClose(); + } + } + document.addEventListener("keydown", handleKey, true); + return () => document.removeEventListener("keydown", handleKey, true); + }, [visible, filtered, activeIndex, onSelect, onClose]); + + useEffect(() => { + const root = containerRef.current; + if (!root) return; + const active = root.querySelector("[data-active='true']"); + active?.scrollIntoView({ block: "nearest" }); + }, [activeIndex]); + + if (!visible) return null; + + return ( +
+ {filtered.length === 0 ? ( +
No matching command
+ ) : ( + filtered.map((cmd, i) => { + const argumentFor = getStringMeta(cmd, "ccbArgumentFor"); + return ( + + ); + }) + )} +
+ ); +} diff --git a/packages/vscode-extension/webview/components/ElicitationDialog.tsx b/packages/vscode-extension/webview/components/ElicitationDialog.tsx new file mode 100644 index 000000000..7a3f73c99 --- /dev/null +++ b/packages/vscode-extension/webview/components/ElicitationDialog.tsx @@ -0,0 +1,335 @@ +import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import type { + ElicitationContentValue, + ElicitationPropertySchema, + ElicitationResponse, +} from "../lib/acp/types"; +import type { PendingElicitation } from "../lib/types"; + +interface ElicitationDialogProps { + requests: PendingElicitation[]; + onRespond: (requestId: string, response: ElicitationResponse) => void; +} + +type DraftContent = Record; + +export function ElicitationDialog({ requests, onRespond }: ElicitationDialogProps): React.ReactElement | null { + if (requests.length === 0) return null; + return ( +
+ {requests.map((request) => ( + + ))} +
+ ); +} + +function ElicitationCard({ + request, + onRespond, +}: { + request: PendingElicitation; + onRespond: (requestId: string, response: ElicitationResponse) => void; +}): React.ReactElement { + const cardRef = useRef(null); + const fields = useMemo(() => Object.entries(request.schema.properties ?? {}), [request.schema.properties]); + const required = new Set(request.schema.required ?? []); + const [draft, setDraft] = useState(() => buildInitialContent(fields)); + + const setField = (key: string, value: ElicitationContentValue) => { + setDraft((prev) => ({ ...prev, [key]: value })); + }; + + const canSubmit = fields.every(([key, schema]) => { + if (!required.has(key)) return true; + const value = draft[key]; + if (schema.type === "array") return Array.isArray(value) && value.length > 0; + return value !== undefined && value !== ""; + }); + + const submit = useCallback(() => { + if (!canSubmit) return; + onRespond(request.requestId, { action: "accept", content: draft }); + }, [canSubmit, draft, onRespond, request.requestId]); + + useEffect(() => { + requestAnimationFrame(() => { + const first = cardRef.current?.querySelector("[data-elicit-focus='true']"); + first?.focus(); + }); + }, [request.requestId]); + + const handleKeyDown = useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "Escape") { + event.preventDefault(); + onRespond(request.requestId, { action: "cancel" }); + return; + } + if (event.key === "Enter" && !event.shiftKey && !isChoiceTarget(event.target)) { + event.preventDefault(); + submit(); + } + }, + [onRespond, request.requestId, submit], + ); + + return ( +
+
+ ? + {request.schema.title ?? "Input required"} +
+
{request.message}
+ {request.schema.description &&
{request.schema.description}
} + +
+ {fields.map(([key, schema], index) => ( + setField(key, value)} + onSubmit={submit} + /> + ))} +
+ +
+ + + +
+
+ ); +} + +function ElicitationField({ + fieldKey, + schema, + value, + required, + autoFocus, + onChange, + onSubmit, +}: { + fieldKey: string; + schema: ElicitationPropertySchema; + value: ElicitationContentValue | undefined; + required: boolean; + autoFocus: boolean; + onChange: (value: ElicitationContentValue) => void; + onSubmit: () => void; +}): React.ReactElement { + const label = schema.title ?? fieldKey; + const choices = getChoiceOptions(schema); + + return ( +
+ + {label} + {required ? * : null} + + {schema.description && {schema.description}} + {schema.type === "string" && choices.length > 0 ? ( + + ) : schema.type === "string" ? ( + onChange(event.currentTarget.value)} + onKeyDown={(event) => { + if (event.key === "Enter" && !event.shiftKey) { + event.preventDefault(); + onSubmit(); + } + }} + /> + ) : schema.type === "boolean" ? ( + onChange(event.currentTarget.checked)} + /> + ) : schema.type === "array" ? ( +
+ {choices.map((choice) => { + const selected = Array.isArray(value) ? value.includes(choice.value) : false; + return ( + + ); + })} +
+ ) : ( + onChange(Number(event.currentTarget.value))} + onKeyDown={(event) => { + if (event.key === "Enter" && !event.shiftKey) { + event.preventDefault(); + onSubmit(); + } + }} + /> + )} +
+ ); +} + +function ChoiceInput({ + choices, + value, + autoFocus, + onChange, + onSubmit, +}: { + choices: Array<{ value: string; label: string }>; + value: string; + autoFocus: boolean; + onChange: (value: ElicitationContentValue) => void; + onSubmit: () => void; +}): React.ReactElement { + const optionRefs = useRef>([]); + const selectedIndex = Math.max(0, choices.findIndex((choice) => choice.value === value)); + const [activeIndex, setActiveIndex] = useState(selectedIndex); + + useEffect(() => setActiveIndex(selectedIndex), [selectedIndex]); + + const moveTo = useCallback( + (index: number) => { + const next = (index + choices.length) % choices.length; + setActiveIndex(next); + onChange(choices[next].value); + requestAnimationFrame(() => optionRefs.current[next]?.focus()); + }, + [choices, onChange], + ); + + return ( +
+ {choices.map((choice, index) => ( + + ))} +
+ ); +} + +function buildInitialContent(fields: Array<[string, ElicitationPropertySchema]>): DraftContent { + const content: DraftContent = {}; + for (const [key, schema] of fields) { + content[key] = initialValue(schema); + } + return content; +} + +function initialValue(schema: ElicitationPropertySchema): ElicitationContentValue { + if (schema.type === "string") { + const choices = getChoiceOptions(schema); + return schema.default ?? choices[0]?.value ?? ""; + } + if (schema.type === "boolean") return schema.default ?? false; + if (schema.type === "array") return schema.default ?? []; + return schema.default ?? 0; +} + +function getChoiceOptions(schema: ElicitationPropertySchema): Array<{ value: string; label: string }> { + if (schema.type === "string") { + if (schema.oneOf && schema.oneOf.length > 0) { + return schema.oneOf.map((option) => ({ value: option.const, label: option.title })); + } + if (schema.enum && schema.enum.length > 0) { + return schema.enum.map((value) => ({ value, label: value })); + } + } + if (schema.type === "array") { + if (schema.items.oneOf && schema.items.oneOf.length > 0) { + return schema.items.oneOf.map((option) => ({ value: option.const, label: option.title })); + } + if (schema.items.enum && schema.items.enum.length > 0) { + return schema.items.enum.map((value) => ({ value, label: value })); + } + } + return []; +} + +function isChoiceTarget(target: EventTarget): boolean { + return target instanceof HTMLElement && target.closest(".elicitation-choice-list") !== null; +} diff --git a/packages/vscode-extension/webview/components/MessageBubble.tsx b/packages/vscode-extension/webview/components/MessageBubble.tsx new file mode 100644 index 000000000..b306cd7a2 --- /dev/null +++ b/packages/vscode-extension/webview/components/MessageBubble.tsx @@ -0,0 +1,87 @@ +// biome-ignore-all lint/security/noDangerouslySetInnerHtml: renderMarkdown sanitizes generated HTML before rendering. +import React, { useState } from "react"; +import { renderMarkdown } from "../markdown"; +import type { AssistantChunk, AssistantMessageEntry, UserMessageEntry } from "../lib/types"; + +interface UserBubbleProps { + entry: UserMessageEntry; +} + +export function UserBubble({ entry }: UserBubbleProps): React.ReactElement { + return ( +
+
You
+
+ {entry.images && entry.images.length > 0 && ( +
+ {entry.images.map((img, i) => ( + {`attachment-${i}`} + ))} +
+ )} +
+ ); +} + +interface AssistantBubbleProps { + entry: AssistantMessageEntry; + showThinking: boolean; +} + +export function AssistantBubble({ entry, showThinking }: AssistantBubbleProps): React.ReactElement { + return ( +
+
Claude
+ {entry.chunks.map((chunk, i) => ( + + ))} +
+ ); +} + +function ChunkRenderer({ + chunk, + showThinking, +}: { + chunk: AssistantChunk; + showThinking: boolean; +}): React.ReactElement | null { + if (chunk.type === "thought") { + if (!showThinking) return null; + return ; + } + return ( +
+ ); +} + +function ThinkingBlock({ text }: { text: string }): React.ReactElement { + const [open, setOpen] = useState(false); + return ( +
+ + {open &&
{text}
} +
+ ); +} + +interface SystemNoticeProps { + level: "info" | "warning" | "error"; + text: string; +} + +export function SystemNotice({ level, text }: SystemNoticeProps): React.ReactElement { + return
{text}
; +} diff --git a/packages/vscode-extension/webview/components/ModeSelector.tsx b/packages/vscode-extension/webview/components/ModeSelector.tsx new file mode 100644 index 000000000..ad4662416 --- /dev/null +++ b/packages/vscode-extension/webview/components/ModeSelector.tsx @@ -0,0 +1,92 @@ +import React, { useEffect, useRef, useState } from "react"; +import type { SessionModeState } from "../lib/acp/types"; +import { FALLBACK_PERMISSION_MODES, PERMISSION_MODE_LABELS } from "../lib/types"; + +interface ModeSelectorProps { + /** Mode state advertised by the agent (preferred). Fallback used otherwise. */ + state: SessionModeState | null; + currentMode: string; + onSelect: (modeId: string) => void; + open?: boolean; + onOpenChange?: (open: boolean) => void; +} + +interface ModeOption { + id: string; + label: string; + description: string; +} + +export function ModeSelector({ state, currentMode, onSelect, open: controlledOpen, onOpenChange }: ModeSelectorProps): React.ReactElement { + const [uncontrolledOpen, setUncontrolledOpen] = useState(false); + const wrapRef = useRef(null); + const open = controlledOpen ?? uncontrolledOpen; + const setOpen = (next: boolean | ((prev: boolean) => boolean)): void => { + const value = typeof next === "function" ? next(open) : next; + if (onOpenChange) onOpenChange(value); + else setUncontrolledOpen(value); + }; + + useEffect(() => { + if (!open) return; + function onClick(e: MouseEvent) { + if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) setOpen(false); + } + document.addEventListener("mousedown", onClick); + return () => document.removeEventListener("mousedown", onClick); + }, [open]); + + const options = buildOptions(state); + const current = options.find((o) => o.id === currentMode) ?? options[0]; + + return ( +
+ + {open && ( +
+ {options.map((opt) => ( + + ))} +
+ )} +
+ ); +} + +function buildOptions(state: SessionModeState | null): ModeOption[] { + if (state && state.availableModes.length > 0) { + return state.availableModes.map((m) => ({ + id: m.id, + label: m.name, + description: m.description ?? PERMISSION_MODE_LABELS[m.id]?.description ?? "", + })); + } + return FALLBACK_PERMISSION_MODES.map((id) => ({ + id, + label: PERMISSION_MODE_LABELS[id]?.label ?? id, + description: PERMISSION_MODE_LABELS[id]?.description ?? "", + })); +} diff --git a/packages/vscode-extension/webview/components/ModelPicker.tsx b/packages/vscode-extension/webview/components/ModelPicker.tsx new file mode 100644 index 000000000..988f169af --- /dev/null +++ b/packages/vscode-extension/webview/components/ModelPicker.tsx @@ -0,0 +1,66 @@ +import React, { useEffect, useRef, useState } from "react"; +import type { SessionModelState } from "../lib/acp/types"; + +interface ModelPickerProps { + state: SessionModelState | null; + onSelect: (modelId: string) => void; + open?: boolean; + onOpenChange?: (open: boolean) => void; +} + +export function ModelPicker({ state, onSelect, open: controlledOpen, onOpenChange }: ModelPickerProps): React.ReactElement | null { + const [uncontrolledOpen, setUncontrolledOpen] = useState(false); + const wrapRef = useRef(null); + const open = controlledOpen ?? uncontrolledOpen; + const setOpen = (next: boolean | ((prev: boolean) => boolean)): void => { + const value = typeof next === "function" ? next(open) : next; + if (onOpenChange) onOpenChange(value); + else setUncontrolledOpen(value); + }; + + useEffect(() => { + if (!open) return; + function onClick(e: MouseEvent) { + if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) setOpen(false); + } + document.addEventListener("mousedown", onClick); + return () => document.removeEventListener("mousedown", onClick); + }, [open]); + + if (!state || state.availableModels.length === 0) return null; + + const current = state.availableModels.find((m) => m.modelId === state.currentModelId); + const label = current?.name ?? state.currentModelId; + + return ( +
+ + {open && ( +
+ {state.availableModels.map((m) => ( + + ))} +
+ )} +
+ ); +} diff --git a/packages/vscode-extension/webview/components/PermissionPanel.tsx b/packages/vscode-extension/webview/components/PermissionPanel.tsx new file mode 100644 index 000000000..38a6fdd90 --- /dev/null +++ b/packages/vscode-extension/webview/components/PermissionPanel.tsx @@ -0,0 +1,93 @@ +import React from "react"; +import type { PendingPermission } from "../lib/types"; +import type { PermissionOption } from "../lib/acp/types"; + +interface PermissionPanelProps { + requests: PendingPermission[]; + onRespond: (requestId: string, optionId: string | null, approved: boolean) => void; +} + +/** + * Permission requests are flattened into the chat as tool-call entries with a + * `permissionRequest` payload. This panel mirrors them above the input so the + * user can act without scrolling. + */ +export function PermissionPanel({ requests, onRespond }: PermissionPanelProps): React.ReactElement | null { + if (requests.length === 0) return null; + return ( +
+ {requests.map((req) => ( + + ))} +
+ ); +} + +function PermissionCard({ + request, + onRespond, +}: { + request: PendingPermission; + onRespond: (requestId: string, optionId: string | null, approved: boolean) => void; +}): React.ReactElement { + const allow = pickOption(request.options, ["allow_once", "allow_always"]); + const reject = pickOption(request.options, ["reject_once", "reject_always"]); + + const handle = (option: PermissionOption | undefined, approved: boolean) => { + onRespond(request.requestId, option?.optionId ?? null, approved); + }; + + return ( +
+
+ ! + {request.toolName} +
+ {request.description &&
{request.description}
} + +
+ {request.options.map((opt) => ( + + ))} +
+ {/* Quick fallback when the agent only supplies cryptic option names */} + {request.options.length === 0 && ( +
+ + +
+ )} +
+ ); +} + +function pickOption( + options: PermissionOption[], + preferences: PermissionOption["kind"][], +): PermissionOption | undefined { + for (const k of preferences) { + const match = options.find((o) => o.kind === k); + if (match) return match; + } + return undefined; +} + +function isApprove(kind: PermissionOption["kind"]): boolean { + return kind === "allow_once" || kind === "allow_always"; +} + +function categoryFor(kind: PermissionOption["kind"]): "approve" | "reject" { + return isApprove(kind) ? "approve" : "reject"; +} diff --git a/packages/vscode-extension/webview/components/PlanView.tsx b/packages/vscode-extension/webview/components/PlanView.tsx new file mode 100644 index 000000000..d7fabfe33 --- /dev/null +++ b/packages/vscode-extension/webview/components/PlanView.tsx @@ -0,0 +1,65 @@ +import React, { useState } from "react"; +import type { PlanEntry, PlanEntryPriority, PlanEntryStatus } from "../lib/acp/types"; +import type { PlanDisplayEntry } from "../lib/types"; + +interface PlanViewProps { + entry: PlanDisplayEntry; +} + +export function PlanView({ entry }: PlanViewProps): React.ReactElement | null { + const [collapsed, setCollapsed] = useState(false); + if (entry.entries.length === 0) return null; + + const completed = entry.entries.filter((e) => e.status === "completed").length; + const total = entry.entries.length; + const pct = total > 0 ? Math.round((completed / total) * 100) : 0; + + return ( +
+ + {!collapsed && ( +
+ {entry.entries.map((row, i) => ( + + ))} +
+ )} +
+ ); +} + +function PlanRow({ entry }: { entry: PlanEntry }): React.ReactElement { + return ( +
+ + {entry.content} + +
+ ); +} + +function StatusIcon({ status }: { status: PlanEntryStatus }): React.ReactElement { + if (status === "completed") return ; + if (status === "in_progress") return ; + return ; +} + +function PriorityBadge({ priority }: { priority: PlanEntryPriority }): React.ReactElement { + const labels: Record = { high: "H", medium: "M", low: "L" }; + return {labels[priority]}; +} diff --git a/packages/vscode-extension/webview/components/PromptInput.tsx b/packages/vscode-extension/webview/components/PromptInput.tsx new file mode 100644 index 000000000..e0cdb82c9 --- /dev/null +++ b/packages/vscode-extension/webview/components/PromptInput.tsx @@ -0,0 +1,425 @@ +import React, { useCallback, useEffect, useImperativeHandle, useRef, useState, forwardRef } from "react"; +import type { AvailableCommand } from "../lib/acp/types"; +import type { UserMessageImage } from "../lib/types"; +import { getSlashMenuState, getStringMeta } from "../lib/slashCommands"; +import { CommandMenu } from "./CommandMenu"; + +export interface PromptInputHandle { + focus: () => void; + insert: (text: string) => void; + setValue: (text: string) => void; +} + +interface PromptInputProps { + disabled: boolean; + isLoading: boolean; + placeholder: string; + availableCommands: AvailableCommand[]; + permissionMode: string; + onSend: (text: string, images?: UserMessageImage[]) => void; + onCancel: () => void; + onCycleMode: () => void; + onNewSession?: () => void; + onOpenModelPicker?: () => void; + onSetMode?: (modeId: string) => void; + /** Returns matched files for @-mention popup; provided by useACP. */ + findFiles: (query: string) => Promise>; + /** Provides the prompt history for ↑/↓ navigation. */ + promptHistory: string[]; + onPromptSubmitted?: (text: string) => void; +} + +const HISTORY_NAVIGATION_HINT = "Up/Down: history · Tab: complete · Shift+Tab: cycle mode · Esc: cancel"; + +export const PromptInput = forwardRef(function PromptInput( + { + disabled, + isLoading, + placeholder, + availableCommands, + permissionMode, + onSend, + onCancel, + onCycleMode, + findFiles, + promptHistory, + onPromptSubmitted, + }, + ref, +) { + const textareaRef = useRef(null); + const [value, setValue] = useState(""); + const [pendingImages, setPendingImages] = useState([]); + const [historyIndex, setHistoryIndex] = useState(-1); + const [savedDraft, setSavedDraft] = useState(null); + const [dismissedSlashValue, setDismissedSlashValue] = useState(null); + + // Slash-command menu state derived from textarea content. + const slashFilter = getSlashMenuState(value, availableCommands); + const slashVisible = slashFilter.visible && dismissedSlashValue !== value; + + // @-mention popup state. + const [atQuery, setAtQuery] = useState(null); + const [atResults, setAtResults] = useState>([]); + const [atIndex, setAtIndex] = useState(0); + + useImperativeHandle(ref, () => ({ + focus: () => textareaRef.current?.focus(), + insert: (text) => { + const el = textareaRef.current; + if (!el) return; + const start = el.selectionStart ?? value.length; + const end = el.selectionEnd ?? value.length; + const next = value.slice(0, start) + text + value.slice(end); + setValue(next); + requestAnimationFrame(() => { + el.focus(); + const cursor = start + text.length; + el.setSelectionRange(cursor, cursor); + autoresize(el); + }); + }, + setValue: (text) => { + setValue(text); + requestAnimationFrame(() => { + const el = textareaRef.current; + if (el) autoresize(el); + }); + }, + }), [value]); + + const clearAtPopup = () => { + setAtQuery(null); + setAtResults([]); + setAtIndex(0); + }; + + // Resolve @ trigger asynchronously + useEffect(() => { + if (atQuery === null) return; + let cancelled = false; + (async () => { + const results = await findFiles(atQuery); + if (!cancelled) { + setAtResults(results); + setAtIndex(0); + } + })(); + return () => { cancelled = true; }; + }, [atQuery, findFiles]); + + const updateAtState = useCallback((text: string, cursorPos: number) => { + // Find the @ token closest to the cursor (within whitespace bounds). + const before = text.slice(0, cursorPos); + const match = before.match(/(?:^|\s)@([^\s]*)$/); + if (match) { + setAtQuery(match[1]); + } else if (atQuery !== null) { + clearAtPopup(); + } + }, [atQuery]); + + const handleChange = useCallback( + (e: React.ChangeEvent) => { + const next = e.target.value; + setValue(next); + autoresize(e.target); + // Reset history navigation when user types. + if (historyIndex !== -1) { + setHistoryIndex(-1); + setSavedDraft(null); + } + updateAtState(next, e.target.selectionStart ?? next.length); + }, + [historyIndex, updateAtState], + ); + + const handlePaste = useCallback((e: React.ClipboardEvent) => { + const items = e.clipboardData.items; + if (!items || items.length === 0) return; + const newImages: UserMessageImage[] = []; + for (const item of items) { + if (item.kind !== "file") continue; + const file = item.getAsFile(); + if (!file || !file.type.startsWith("image/")) continue; + e.preventDefault(); + const reader = new FileReader(); + reader.onload = () => { + const result = reader.result as string; + const commaIdx = result.indexOf(","); + const data = commaIdx >= 0 ? result.slice(commaIdx + 1) : result; + newImages.push({ mimeType: file.type, data }); + if (newImages.length === 1) { + setPendingImages((prev) => [...prev, newImages[0]]); + } + }; + reader.readAsDataURL(file); + } + }, []); + + const submit = useCallback(() => { + const trimmed = value.trim(); + if (!trimmed && pendingImages.length === 0) return; + if (disabled) return; + onSend(trimmed, pendingImages.length > 0 ? pendingImages : undefined); + onPromptSubmitted?.(trimmed); + setValue(""); + setPendingImages([]); + setHistoryIndex(-1); + setSavedDraft(null); + clearAtPopup(); + requestAnimationFrame(() => { + const el = textareaRef.current; + if (el) { + el.style.height = "auto"; + el.focus(); + } + }); + }, [value, pendingImages, disabled, onSend, onPromptSubmitted]); + + const handleHistoryNav = useCallback((direction: "up" | "down") => { + if (promptHistory.length === 0) return; + if (direction === "up") { + const next = historyIndex + 1; + if (next >= promptHistory.length) return; + if (historyIndex === -1) setSavedDraft(value); + setHistoryIndex(next); + setValue(promptHistory[next]); + } else { + if (historyIndex <= 0) { + setHistoryIndex(-1); + setValue(savedDraft ?? ""); + setSavedDraft(null); + } else { + const next = historyIndex - 1; + setHistoryIndex(next); + setValue(promptHistory[next]); + } + } + requestAnimationFrame(() => { + const el = textareaRef.current; + if (el) { + autoresize(el); + const len = el.value.length; + el.setSelectionRange(len, len); + } + }); + }, [historyIndex, promptHistory, value, savedDraft]); + + const handleKeyDown = useCallback( + (e: React.KeyboardEvent) => { + // Slash-command menu intercepts arrow keys / Enter / Tab. + // CommandMenu listens at document-level — but we still need to skip our + // own behaviours when the menu is showing. + if (slashVisible) { + return; + } + // @-mention popup priority + if (atQuery !== null && atResults.length > 0) { + if (e.key === "ArrowDown") { + e.preventDefault(); + setAtIndex((i) => (i + 1) % atResults.length); + return; + } + if (e.key === "ArrowUp") { + e.preventDefault(); + setAtIndex((i) => (i - 1 + atResults.length) % atResults.length); + return; + } + if (e.key === "Tab" || (e.key === "Enter" && !e.shiftKey)) { + e.preventDefault(); + const pick = atResults[atIndex]; + if (pick) { + const el = textareaRef.current; + if (!el) return; + const cursor = el.selectionStart ?? value.length; + const before = value.slice(0, cursor); + const after = value.slice(cursor); + const newBefore = before.replace(/(^|\s)@[^\s]*$/, (full, lead) => `${lead}@${pick.relPath} `); + const next = newBefore + after; + setValue(next); + requestAnimationFrame(() => { + el.focus(); + const newPos = newBefore.length; + el.setSelectionRange(newPos, newPos); + autoresize(el); + }); + clearAtPopup(); + } + return; + } + if (e.key === "Escape") { + e.preventDefault(); + clearAtPopup(); + return; + } + } + + if (e.key === "Enter" && !e.shiftKey && !(e.nativeEvent as KeyboardEvent).isComposing) { + e.preventDefault(); + submit(); + return; + } + if (e.key === "Escape") { + e.preventDefault(); + if (isLoading) onCancel(); + return; + } + if (e.key === "Tab" && e.shiftKey) { + e.preventDefault(); + onCycleMode(); + return; + } + // Up/Down history nav only when textarea is single-line / cursor at extremes. + if (e.key === "ArrowUp" && isAtFirstLine(textareaRef.current)) { + e.preventDefault(); + handleHistoryNav("up"); + return; + } + if (e.key === "ArrowDown" && isAtLastLine(textareaRef.current)) { + if (historyIndex >= 0) { + e.preventDefault(); + handleHistoryNav("down"); + } + return; + } + }, + [slashVisible, atQuery, atResults, atIndex, value, submit, isLoading, onCancel, onCycleMode, handleHistoryNav, historyIndex], + ); + + const onSlashSelect = useCallback((cmd: AvailableCommand) => { + const argumentFor = getStringMeta(cmd, "ccbArgumentFor"); + const argumentValue = getStringMeta(cmd, "ccbArgumentValue"); + const nextValue = argumentFor && argumentValue ? `/${argumentFor} ${argumentValue} ` : `/${cmd.name} `; + setDismissedSlashValue(null); + setValue(nextValue); + requestAnimationFrame(() => { + const el = textareaRef.current; + if (el) { + autoresize(el); + const pos = el.value.length; + el.setSelectionRange(pos, pos); + el.focus(); + } + }); + }, []); + + return ( +
+ setDismissedSlashValue(value)} + /> + + {atQuery !== null && atResults.length > 0 && ( +
+ {atResults.map((entry, i) => ( + + ))} +
+ )} + + {pendingImages.length > 0 && ( +
+ {pendingImages.map((img, i) => ( +
+ {`attachment-${i}`} + +
+ ))} +
+ )} + +
+