diff --git a/package-lock.json b/package-lock.json index f5b3b9c7..71427fbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,24 +9,24 @@ "version": "0.60.0", "license": "Apache-2.0", "dependencies": { - "@agentclientprotocol/sdk": "1.2.1", - "@anthropic-ai/claude-agent-sdk": "0.3.215", + "@agentclientprotocol/sdk": "1.3.0", + "@anthropic-ai/claude-agent-sdk": "0.3.217", "zod": "^3.25.0 || ^4.0.0" }, "bin": { "claude-agent-acp": "dist/index.js" }, "devDependencies": { - "@anthropic-ai/sdk": "0.112.3", + "@anthropic-ai/sdk": "0.112.5", "@eslint/js": "10.0.1", "@tsconfig/node22": "22.0.5", "@types/node": "26.1.1", - "@typescript-eslint/eslint-plugin": "8.64.0", - "@typescript-eslint/parser": "8.64.0", + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", "eslint": "10.7.0", "eslint-config-prettier": "10.1.8", "globals": "17.7.0", - "prettier": "3.9.5", + "prettier": "3.9.6", "ts-node": "10.9.2", "typescript": "6.0.3", "vitest": "4.1.10" @@ -36,31 +36,31 @@ } }, "node_modules/@agentclientprotocol/sdk": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-1.2.1.tgz", - "integrity": "sha512-jwYUdOQR7tc+Zfch53VL4JJyUNK/46q03uUTYb+PjECsmnNl94XFXOfYLJ8RBpMNidXd1rpOAVgb0vqD98xImA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-1.3.0.tgz", + "integrity": "sha512-i3h/efaeuMUFAO1HSfo97QZQnnvMd7wWBYtBsdL6UMZg3a78sk3Ffya5Xu7C7tYsXomXoDXJBAzQF2PcFKAhIQ==", "license": "Apache-2.0", "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "node_modules/@anthropic-ai/claude-agent-sdk": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.215.tgz", - "integrity": "sha512-fBktJCwfu8ZeOSnnSLcWVkIHyp/pjouJsGVGtRnQ0HkcRuOReIbRcB/6n2O5dYV331Ok+MfdGHiPaTORj7pCtQ==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.217.tgz", + "integrity": "sha512-juszT3itL8R6OQ6nb/8IZE34UjKps8Jf7N8vjCXLx+vbJc+k3EojZOs93tJwT5iTRvfV1a0N53zJbKn/iJpKrQ==", "license": "SEE LICENSE IN README.md", "engines": { "node": ">=18.0.0" }, "optionalDependencies": { - "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.215", - "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.215", - "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.215", - "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.215", - "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.215", - "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.215", - "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.215", - "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.215" + "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.217", + "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.217", + "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.217", + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.217", + "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.217", + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.217", + "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.217", + "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.217" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", @@ -69,9 +69,9 @@ } }, "node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.215.tgz", - "integrity": "sha512-KIOe3N/ypVIdsI7fnJUHT0Djei1RH01TbxK6LI2mgoHKZ6NVDt/Q9kQ1+On3b/l899RhE6C1SMAiQ0iB4sbkjA==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.217.tgz", + "integrity": "sha512-dl119zmL1Ssyd8Fx0xfVMpss2scrGCZwf+rhZwl2lHa2dYuXVluLgqi4DUIWDj3rRYdrAvaMpjCAv6a5w07ddw==", "cpu": [ "arm64" ], @@ -82,9 +82,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.215.tgz", - "integrity": "sha512-cyjfQgkgF/zZbSJP6uJpPXoIJE/gYFOgz+u/SjklvakcO56BpEnsbdl/oHVu5G8GCw69V11hKFZ8T8YsVOiv2w==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.217.tgz", + "integrity": "sha512-IeKL1HN8fEcRQ4uw5d02by1ThpjhRtOgfHcCTBQ2KS4JfEIHvc1VGWt6Exb2a7VHhT8uRcfjPk9urbmYayZmaw==", "cpu": [ "x64" ], @@ -95,9 +95,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.215.tgz", - "integrity": "sha512-lb7ayxZeWLiEhlOjzF8oX+DdJHrVgR1hvwkwRdYo+LgTT3hSxv6h43sheS3hZ1I9LYvOTKWa2E0O1EnffOzyCg==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.217.tgz", + "integrity": "sha512-KtrnfEwUSCdq2cc4Pgysl+U66vqw3h7u04N5/OLHmYZ4AZYy8JcqdOaSJZ27iL2bgbAxyKwu5/9YmEk9A4IswA==", "cpu": [ "arm64" ], @@ -111,9 +111,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.215.tgz", - "integrity": "sha512-dXMR8afbZCFWUKQGyvn9swDYYvMtZWGqqbZ994ahS7HvGN4AgF63uvojHVErW1Xxn2601Bm+eCYQt+BSLk6iZQ==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.217.tgz", + "integrity": "sha512-Bb4AJxqrVPouM4sYIdvX3/AO5womhe70u3Euv+6B5J2OoqcRaWarVvYevX3KRruC5TvlV2Josw14dsL5qVNL+A==", "cpu": [ "arm64" ], @@ -127,9 +127,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.215.tgz", - "integrity": "sha512-Iivu3oq7hIEc81dpTu1W0GJ/kCE8TRtj9tb+wdZCp1grsuGEJiS3Bh1tLxCrhLOTDxPggK6xZGVN/RPJh84ywA==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.217.tgz", + "integrity": "sha512-JsAQyfl4n0PR4LX0h1SxMo0raERGb8B8dvbaoNQRRSpb9A2vvcwPEjyKu0eRKHRhTvspvuD6TfNxzxrmnouX9A==", "cpu": [ "x64" ], @@ -143,9 +143,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.215.tgz", - "integrity": "sha512-jSmrjSupnWtw8/I1Wmr32J6lB02gFXytmNbse4kcLEgH6UGtdZckKnDVnh/ejHma4QE9WGSn54xLsSFnjHVrRg==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.217.tgz", + "integrity": "sha512-qhugNZd77vAoPMIGM8vFHlbwTltFyI1POmfyl0ZJSpc6v7RE9+5+nqL2aGbGSDsDQkEHrJasXURxIeTMn9ut2w==", "cpu": [ "x64" ], @@ -159,9 +159,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.215.tgz", - "integrity": "sha512-9Xtpwd4DzfObOycDkfYfQ7clhWoFu2fmRqmMZWyQRyk2mEHWR3gLBwUgpfjYb6m4Fke9eTmIx2lXDG2i1OaBzA==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.217.tgz", + "integrity": "sha512-LuaQ+PXZvIToAR81JoiGa6Me9HDma2WH2oiYlAWh43IWaXHyOqgaI1aqSM0BjDhy2UiYWTvGzAopnqPnk+jSBw==", "cpu": [ "arm64" ], @@ -172,9 +172,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": { - "version": "0.3.215", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.215.tgz", - "integrity": "sha512-DkPwdc1zS6KIf6YNKXhlqAw95wnjG8Uh5bSXRrFA+MxsaWedlVFeja6zFM5uZ84ouGrcHEeU3PGUcGaKR1U4cQ==", + "version": "0.3.217", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.217.tgz", + "integrity": "sha512-4r/T+ze/S/CLZ58tP4Mw52XPmsc/LOrCOd8jZOqM13FCPWdCMU2osWmszEIKGVMRG2cGsaLVDYcks5cWFqjCjw==", "cpu": [ "x64" ], @@ -185,9 +185,9 @@ ] }, "node_modules/@anthropic-ai/sdk": { - "version": "0.112.3", - "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.112.3.tgz", - "integrity": "sha512-wjcozJlitVIuBEw9cj/xBuRznwkhcLmXmNzlFoeHbh4AvrDG3HGZrdvEOTTmobcbhjGkfOpKbmDTCQ4s9LQvCg==", + "version": "0.112.5", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.112.5.tgz", + "integrity": "sha512-FaaGkyS4/zW4n+8Pr9jQkyo5zWcBNw+R+heCLXdoKDUEuALbPALBk6zLAlmsU+veREiaATxVG0TwkK/cQ3NZsQ==", "license": "MIT", "dependencies": { "json-schema-to-ts": "^3.1.1", @@ -262,16 +262,16 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.0.tgz", + "integrity": "sha512-rd6n9Sefya1R1Vd594TRwzeHq2VnmICbvh3jebyt1Hs/6OoCSYNVpjGRRsKSTwAq3SKl09w0AfRCU57hoDLmxg==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.4.3" + "eslint-visitor-keys": "^5.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -944,17 +944,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz", - "integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/type-utils": "8.64.0", - "@typescript-eslint/utils": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -967,22 +967,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.64.0", + "@typescript-eslint/parser": "^8.65.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz", - "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" }, "engines": { @@ -998,14 +998,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz", - "integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.64.0", - "@typescript-eslint/types": "^8.64.0", + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" }, "engines": { @@ -1020,14 +1020,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz", - "integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0" + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1038,9 +1038,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz", - "integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, "license": "MIT", "engines": { @@ -1055,15 +1055,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz", - "integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0", - "@typescript-eslint/utils": "8.64.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1080,9 +1080,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz", - "integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true, "license": "MIT", "engines": { @@ -1094,16 +1094,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz", - "integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.64.0", - "@typescript-eslint/tsconfig-utils": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1122,16 +1122,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz", - "integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0" + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1146,13 +1146,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz", - "integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1163,19 +1163,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@vitest/expect": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", @@ -1835,13 +1822,13 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -1864,19 +1851,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/eslint/node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -1912,19 +1886,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -2503,9 +2464,9 @@ "license": "ISC" }, "node_modules/jose": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", - "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.4.tgz", + "integrity": "sha512-N8acGzVsQy6M/fjFcxtysNc4Q379TcM5dM/qKkNtsHFji88yANnXTr7BLeP75iPnFwBfQzM/jg2BZ9+HZrHCZA==", "license": "MIT", "peer": true, "funding": { @@ -3189,9 +3150,9 @@ } }, "node_modules/postcss": { - "version": "8.5.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.20.tgz", - "integrity": "sha512-lW616l85ucIQL+FocMmL7pQFPqBmwejrCMg+iPxyImlrANNJG9NHq/RkyCZopDhd8C3LA03PHRJDjkbGu8vvug==", + "version": "8.5.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.22.tgz", + "integrity": "sha512-KBDEIpLrvpv16pp3K0Fw+UCoZfopFjjgeB+0tA/aaThfEE74kKDLrgg603YvOWJyg3+WYtyq3xYsQWsIyZlPqQ==", "dev": true, "funding": [ { @@ -3228,9 +3189,9 @@ } }, "node_modules/prettier": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.5.tgz", - "integrity": "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "dev": true, "license": "MIT", "bin": { diff --git a/package.json b/package.json index 9b477acf..6215d6b6 100644 --- a/package.json +++ b/package.json @@ -63,21 +63,21 @@ "node": ">=22" }, "dependencies": { - "@agentclientprotocol/sdk": "1.2.1", - "@anthropic-ai/claude-agent-sdk": "0.3.215", + "@agentclientprotocol/sdk": "1.3.0", + "@anthropic-ai/claude-agent-sdk": "0.3.217", "zod": "^3.25.0 || ^4.0.0" }, "devDependencies": { - "@anthropic-ai/sdk": "0.112.3", + "@anthropic-ai/sdk": "0.112.5", "@eslint/js": "10.0.1", "@tsconfig/node22": "22.0.5", "@types/node": "26.1.1", - "@typescript-eslint/eslint-plugin": "8.64.0", - "@typescript-eslint/parser": "8.64.0", + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", "eslint": "10.7.0", "eslint-config-prettier": "10.1.8", "globals": "17.7.0", - "prettier": "3.9.5", + "prettier": "3.9.6", "ts-node": "10.9.2", "typescript": "6.0.3", "vitest": "4.1.10" diff --git a/src/acp-agent.ts b/src/acp-agent.ts index 8aa840da..c7eba075 100644 --- a/src/acp-agent.ts +++ b/src/acp-agent.ts @@ -804,6 +804,15 @@ export type ToolUpdateMeta = { Agent/Task call that spawned the subagent. Mirrors the SDK's `parent_tool_use_id` on streamed subagent messages. */ parentToolUseId?: string; + /* On a "failed" tool_call_update: why the tool never actually ran, so a + client can render the denial/cancellation distinctly from a real tool + failure. From the SDK's `tool_result_meta` non_execution_kind: + "user-rejected", "permission-rule", "interrupted", "cancelled", … + (open set). Absent when the tool executed — including real failures. */ + nonExecutionKind?: string; + /* Free-text the user supplied when rejecting the tool call, when the + harness collected any. Only ever present alongside nonExecutionKind. */ + userFeedback?: string; }; /* Terminal metadata for Bash tool execution, matching codex-acp's _meta protocol. */ terminal_info?: { @@ -2686,9 +2695,9 @@ export class ClaudeAcpAgent { // Push the full slash-command list after a mid-session change // (e.g. skills discovered dynamically as the agent works in a // subdirectory). The client should REPLACE its cached command - // list with this payload: supportedCommands() is captured once - // at initialize and never reflects mid-session changes, so we - // forward message.commands directly rather than re-querying. + // list with this payload. Forward message.commands directly — + // it's authoritative, and re-querying supportedCommands() + // would just return the same list with an extra round-trip. await sendUpdate({ sessionId: message.session_id, update: { @@ -3682,6 +3691,12 @@ export class ClaudeAcpAgent { emittedToolCalls: session.emittedToolCalls, messageId: messageIdForGrouping(message), toolUseResult: message.type === "user" ? message.tool_use_result : undefined, + // On the wire since CLI 2.1.216 but not in SDKUserMessage's + // type, hence the cast. Validated by parseToolResultMeta. + toolResultMeta: + message.type === "user" + ? (message as { tool_result_meta?: unknown }).tool_result_meta + : undefined, }, )) { // sendUpdate records delivery. Subagent text/thinking is @@ -6769,6 +6784,36 @@ function streamedInputRefinement( }; } +/** Validates the SDK user message's `tool_result_meta` sidecar (emitted on the + * wire by CLI ≥ 2.1.216 but absent from sdk.d.ts, hence unknown-typed) into a + * by-tool_use_id lookup. Each entry explains why an is_error tool_result + * carries harness prose instead of the tool's own output — "user-rejected", + * "permission-rule", "interrupted", "cancelled", … (open set: new kinds ship + * on the wire ahead of schema updates, so no enum check). Malformed entries + * are skipped rather than failing the message. */ +function parseToolResultMeta( + raw: unknown, +): Map | undefined { + if (!Array.isArray(raw)) { + return undefined; + } + let byToolUseId: Map | undefined; + for (const entry of raw) { + if (typeof entry !== "object" || entry === null) { + continue; + } + const { id, non_execution_kind, user_feedback } = entry as Record; + if (typeof id !== "string" || typeof non_execution_kind !== "string") { + continue; + } + (byToolUseId ??= new Map()).set(id, { + nonExecutionKind: non_execution_kind, + ...(typeof user_feedback === "string" ? { userFeedback: user_feedback } : {}), + }); + } + return byToolUseId; +} + /** * Convert an SDKAssistantMessage (Claude) to a SessionNotification (ACP). * Only handles text, image, and thinking chunks for now. @@ -6804,6 +6849,10 @@ export function toAcpNotifications( // Agent/Task results from the structured subagent report instead of the raw // text (which ends in a model-directed agentId/usage trailer). toolUseResult?: unknown; + // The SDK user message's `tool_result_meta` sidecar, passed raw (it's + // untyped in sdk.d.ts) and validated by `parseToolResultMeta`. Stamps + // denied/interrupted tool_call_updates with why the tool never ran. + toolResultMeta?: unknown; }, ): SessionNotification[] { const taskState = options?.taskState ?? new Map(); @@ -6846,6 +6895,10 @@ export function toAcpNotifications( ? options.toolUseResult : undefined; + // Unlike `tool_use_result`, entries carry their own tool_use_id, so batched + // messages need no single-block guard. + const toolResultMeta = parseToolResultMeta(options?.toolResultMeta); + const output = []; // Only handle the first chunk for streaming; extend as needed for batching for (const chunk of content) { @@ -6996,6 +7049,12 @@ export function toAcpNotifications( case "mcp_tool_result": { const wasEmitted = options?.emittedToolCalls?.has(chunk.tool_use_id) === true; options?.emittedToolCalls?.delete(chunk.tool_use_id); + // Why this is_error result carries harness prose instead of tool + // output (user-rejected / interrupted / …), when the SDK said so. + // Spread into the claudeCode meta of every update emitted below; the + // untracked-tool fallback can't carry it (claudeCode metas always + // carry `toolName`, which is unknown there). + const nonExecution = toolResultMeta?.get(chunk.tool_use_id); const toolUse = toolUseCache[chunk.tool_use_id]; if (!toolUse) { // The permission flow may have surfaced this tool_call even though @@ -7039,6 +7098,7 @@ export function toAcpNotifications( _meta: { claudeCode: { toolName: toolUse.name, + ...(nonExecution ?? {}), ...(options?.parentToolUseId ? { parentToolUseId: options.parentToolUseId } : {}), }, } satisfies ToolUpdateMeta, @@ -7110,6 +7170,7 @@ export function toAcpNotifications( _meta: { claudeCode: { toolName: toolUse.name, + ...(nonExecution ?? {}), }, ...(toolMeta?.terminal_exit ? { terminal_exit: toolMeta.terminal_exit } : {}), } satisfies ToolUpdateMeta, diff --git a/src/tests/tools.test.ts b/src/tests/tools.test.ts index b4961596..e08b6731 100644 --- a/src/tests/tools.test.ts +++ b/src/tests/tools.test.ts @@ -2435,6 +2435,154 @@ describe("Agent/Task tool_result rendering from tool_use_result", () => { }); }); +describe("tool_result_meta non-execution stamping", () => { + const mockClient = {} as AcpClient; + const mockLogger: Logger = { log: () => {}, error: () => {} }; + + const bashToolUse = { + type: "tool_use" as const, + id: "toolu_bash", + name: "Bash", + input: { command: "rm -rf build" }, + }; + + const deniedResult: ToolResultBlockParam = { + type: "tool_result", + tool_use_id: "toolu_bash", + is_error: true, + content: "The user doesn't want to proceed with this tool use.", + }; + + it("stamps nonExecutionKind and userFeedback on the failed tool_call_update", () => { + const toolUseCache: ToolUseCache = { toolu_bash: bashToolUse }; + + const notifications = toAcpNotifications( + [deniedResult] as any, + "user", + "test-session", + toolUseCache, + mockClient, + mockLogger, + { + toolResultMeta: [ + { id: "toolu_bash", non_execution_kind: "user-rejected", user_feedback: "use npm" }, + ], + }, + ); + + expect(notifications).toHaveLength(1); + expect(notifications[0].update).toMatchObject({ + sessionUpdate: "tool_call_update", + toolCallId: "toolu_bash", + status: "failed", + _meta: { + claudeCode: { + toolName: "Bash", + nonExecutionKind: "user-rejected", + userFeedback: "use npm", + }, + }, + }); + }); + + it("attributes entries by tool_use_id, so only the flagged result in a batch is stamped", () => { + const toolUseCache: ToolUseCache = { + toolu_bash: bashToolUse, + toolu_bash2: { ...bashToolUse, id: "toolu_bash2" }, + }; + + const notifications = toAcpNotifications( + [ + deniedResult, + { + type: "tool_result", + tool_use_id: "toolu_bash2", + content: "ok", + }, + ] as any, + "user", + "test-session", + toolUseCache, + mockClient, + mockLogger, + { toolResultMeta: [{ id: "toolu_bash", non_execution_kind: "user-rejected" }] }, + ); + + expect(notifications).toHaveLength(2); + const [denied, ran] = notifications.map((n) => n.update) as any[]; + expect(denied._meta.claudeCode).toMatchObject({ nonExecutionKind: "user-rejected" }); + // No user_feedback on the wire entry → no userFeedback key at all. + expect(denied._meta.claudeCode).not.toHaveProperty("userFeedback"); + expect(ran._meta.claudeCode).not.toHaveProperty("nonExecutionKind"); + }); + + it("ignores a malformed sidecar and malformed entries", () => { + for (const malformed of [ + "user-rejected", // not an array + [{ non_execution_kind: "user-rejected" }], // entry missing id + [{ id: "toolu_bash", non_execution_kind: 7 }], // kind not a string + [null, 42], // entries not objects + ]) { + const toolUseCache: ToolUseCache = { toolu_bash: bashToolUse }; + const notifications = toAcpNotifications( + [deniedResult] as any, + "user", + "test-session", + toolUseCache, + mockClient, + mockLogger, + { toolResultMeta: malformed }, + ); + + expect(notifications).toHaveLength(1); + expect((notifications[0].update as any)._meta.claudeCode).not.toHaveProperty( + "nonExecutionKind", + ); + } + }); + + it("stamps the resolve of a permission-surfaced suppressed tool (Task*)", () => { + // A TaskGet surfaced as a real tool_call by the permission flow never gets + // a tool_call_update from the suppressed Task* branch; the wasEmitted + // resolve must carry the denial kind too. + const taskGetToolUse = { + type: "tool_use" as const, + id: "toolu_taskget", + name: "TaskGet", + input: { taskId: "1" }, + }; + const toolUseCache: ToolUseCache = { toolu_taskget: taskGetToolUse }; + + const notifications = toAcpNotifications( + [ + { + type: "tool_result", + tool_use_id: "toolu_taskget", + is_error: true, + content: "The user doesn't want to proceed with this tool use.", + }, + ] as any, + "user", + "test-session", + toolUseCache, + mockClient, + mockLogger, + { + emittedToolCalls: new Set(["toolu_taskget"]), + toolResultMeta: [{ id: "toolu_taskget", non_execution_kind: "user-rejected" }], + }, + ); + + expect(notifications).toHaveLength(1); + expect(notifications[0].update).toMatchObject({ + sessionUpdate: "tool_call_update", + toolCallId: "toolu_taskget", + status: "failed", + _meta: { claudeCode: { toolName: "TaskGet", nonExecutionKind: "user-rejected" } }, + }); + }); +}); + describe("structured tool_use_result rendering (Read/Bash/WebSearch)", () => { describe("Read", () => { const readToolUse = {