diff --git a/package-lock.json b/package-lock.json index e881db9a..ae7ae5fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@agentclientprotocol/sdk": "1.2.1", - "@anthropic-ai/claude-agent-sdk": "0.3.202", + "@anthropic-ai/claude-agent-sdk": "0.3.205", "zod": "^3.25.0 || ^4.0.0" }, "bin": { @@ -20,7 +20,7 @@ "@anthropic-ai/sdk": "0.110.0", "@eslint/js": "10.0.1", "@tsconfig/node22": "22.0.5", - "@types/node": "26.1.0", + "@types/node": "26.1.1", "@typescript-eslint/eslint-plugin": "8.63.0", "@typescript-eslint/parser": "8.63.0", "eslint": "10.6.0", @@ -45,22 +45,22 @@ } }, "node_modules/@anthropic-ai/claude-agent-sdk": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.202.tgz", - "integrity": "sha512-LnaLxDtsZP7J6g++xRSnnpTX7CHNe4v+cvBRIlD2ar+N+xi0aqY2YDaCsxPsl+haVUB9kqlUMd0zosmwsfTGjQ==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", + "integrity": "sha512-ft6iBw9kXudsusiXNpeybIPBJ07Z3tqp1ROSg5cEJqgA+9i+JJj2sRfQth+QD+lyenbbAU8yPieLxIimvfBhtw==", "license": "SEE LICENSE IN README.md", "engines": { "node": ">=18.0.0" }, "optionalDependencies": { - "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.202", - "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.202", - "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.202", - "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.202", - "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.202", - "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.202", - "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.202", - "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.202" + "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.205", + "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.205", + "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.205", + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.205", + "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.205", + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.205", + "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.205", + "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.205" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", @@ -69,9 +69,9 @@ } }, "node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.202.tgz", - "integrity": "sha512-ujR3zDthDPkZs+AxW95iHpqLT5cuwGImsS3mVxLt1DlDij4qeTnihLX8+EpQTK+oNW9jjvFA86yKwa84fa1KYA==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.205.tgz", + "integrity": "sha512-lrfJ4eVtzfPkCpbSkBOGSMQCBbvmW6nbPzgHE4IwMN3scZlpuFMUFqh2aaJa/X2SAcWD9H2S0t2WWvSRgM7BjA==", "cpu": [ "arm64" ], @@ -82,9 +82,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.202.tgz", - "integrity": "sha512-s/RVSGgkVmIMfyt1ndR8braLLu82bARoijmt1kk8d4IptUZ0Sc+zNUWKoFXwR9XqDBu6rBbBF9RIzD02raT57w==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.205.tgz", + "integrity": "sha512-G6ETPmL5mNzJ2DFsWxG3jmsmrXgZX1N2ZCJvxaGUUpjTsKZJ4Tup1cWYvcd/m7o5fYZmx9REmgzTwsAIc1fdPQ==", "cpu": [ "x64" ], @@ -95,9 +95,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.202.tgz", - "integrity": "sha512-a4YtRkgGYt3ogePJDW8Ts6bNW690jb9LHyZaiWXsi+zT53xCNqJB2zKPyRc7hXWOqzIk4nCfwJpjmhLzMu3WIg==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.205.tgz", + "integrity": "sha512-CXzySK3PV3EizCRPXnxPqeaAtgrBFDnMFOVpMe36oC3U16yDb1b1tAJGqZi/7uFrVvAiaXvnSFxhUWnDDSaO+A==", "cpu": [ "arm64" ], @@ -111,9 +111,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.202.tgz", - "integrity": "sha512-abSb3Gah45kUNyOeKjmQ/dd1KZ4CaQz5JAr9YQxRDXoOwx8wJVx6huBIpDxjms9wyS9X5Rqxn0Lx7zFP+wV2zQ==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.205.tgz", + "integrity": "sha512-91fgdG4aTnQ29sKOcUqgH4+tKCW2ut6PWGRSYmXNDbROasJm1rAlPdzC5brdu/e4c0CDSNV6TWyE5JCjaS/jlQ==", "cpu": [ "arm64" ], @@ -127,9 +127,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.202.tgz", - "integrity": "sha512-XIvhdCWAAT4OdOA82fOJII+WH0Tf8pFckckEbJMMmOgQBKOnHT+609Pd3Ehw6zGcA9iFrhG5mY8Ncuckeo1aMw==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.205.tgz", + "integrity": "sha512-siS+1iNqBSlGFZZvJY6+mhzZ/6/ec/TbX9GMuwmTF0E6fxGhIIp797jJxR1q8r6FAq7d39mEoRNhC0Ffo60uNQ==", "cpu": [ "x64" ], @@ -143,9 +143,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.202.tgz", - "integrity": "sha512-fze5nAQL1ErcMCQNB10ILaWdM0QbJSaTQzBz8NVAy0FGW8ZL0t4Wf/VgFkfzXbfkaxmPuM1C27Dn5HiU7UDEHQ==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.205.tgz", + "integrity": "sha512-vvsb7GlnA8CTSVvvTkrXjcSeRKqxSM7p/tU3Od9ICAZeWHglptekEyzLEApzLuLbI5ewfFF/F0q3NwOBbo18dg==", "cpu": [ "x64" ], @@ -159,9 +159,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.202.tgz", - "integrity": "sha512-N1J0HRvC+8a69bqNY7+ENIYQzR0i7s+rOIGH5XtuLxvLqOnZO8LHxWEZOe8ezabGq5eZqphSCgL6vQnQQpNh+A==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.205.tgz", + "integrity": "sha512-SpP5zF68weFez/6pKrGzq/UVAJDMDNphWqmkLfOpWTDBL5xy6XlIZw5Bl4EXoVnfi2VLFkwuffNeFe+9SdX7kw==", "cpu": [ "arm64" ], @@ -172,9 +172,9 @@ ] }, "node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": { - "version": "0.3.202", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.202.tgz", - "integrity": "sha512-ytLGEC1fjTSiVSoXukS+j9G+06Mi20NSzxxzlG6uE75SEB0+17tHdWUaHqd8PhH/6GPzcYx81czxWQl1MVbq4Q==", + "version": "0.3.205", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.205.tgz", + "integrity": "sha512-kg2kkXyeSoFLruO3Ic2IruLxzBR0xCUtmlJHdWi3SYW7JhAKNJg4fcrdJsWcardmEw23Y2UDGDJbRyxqSVx6wg==", "cpu": [ "x64" ], @@ -544,9 +544,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.138.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.138.0.tgz", - "integrity": "sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA==", + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", "dev": true, "license": "MIT", "funding": { @@ -554,9 +554,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.4.tgz", - "integrity": "sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", "cpu": [ "arm64" ], @@ -571,9 +571,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.4.tgz", - "integrity": "sha512-aUi+HBvmYb7j8krl1+qJgkG8C17fO79gk3c+jPw4S8glRFc1DTija9S3EyaTSQUm5GJXYKDAsugBEhFHH2vYiQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", "cpu": [ "arm64" ], @@ -588,9 +588,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.4.tgz", - "integrity": "sha512-F7hHC3gwY11+vByKPRWqwGbeXWVgKmL+pTGCinaEhdihzBV2aQ0fvZOch9cXYUOKuKKq429HeYXOqQLc7wFCEg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", "cpu": [ "x64" ], @@ -605,9 +605,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.4.tgz", - "integrity": "sha512-sI5yw+7s92SK6odiEhD5lKCBlWcpjHS5qyqpVQbZAJ0fIzEUXrmbl3DH2ybR3PZogulNJF+COLtmA8hUfvkCCQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", "cpu": [ "x64" ], @@ -622,9 +622,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.4.tgz", - "integrity": "sha512-mCi0OKgEieFircrtVYmQAFGszRtMnZ6fpZAXrxanXAu7lqZcsK1E1RAaZNG0uKAnxox3B1f4EyQNnoyMfN1vAA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", "cpu": [ "arm" ], @@ -639,9 +639,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.4.tgz", - "integrity": "sha512-B9Ial3Kv5sh0SHnB1g/QWcUQCEvCF6QKGAl4zXypYj65mVI+B4AhFBwPtSN7pDrJeIx8Z7zdy4ntx+wQABom7w==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", "cpu": [ "arm64" ], @@ -659,9 +659,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.4.tgz", - "integrity": "sha512-lZVym0PuHE1KZ22gmFTC15lAkrg9iTszR617oYRB/iPY1A56ywoJzVKOJBKaot5RiikCObmur6pogpse3gRcng==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", "cpu": [ "arm64" ], @@ -679,9 +679,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.4.tgz", - "integrity": "sha512-t2DNiLJWNTbnEHyUzTumldML6ET4/g16467LZoDDJ3tSxGvguL5/NyC2lCsNKuyRycg9XeDQF5SSv+TNOhQEXg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", "cpu": [ "ppc64" ], @@ -699,9 +699,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.4.tgz", - "integrity": "sha512-0WIRnL1Uw4BvTZRLQt+PVgo6ZKTJadlC2btP+/EOXv2f/DWbY0rEgl+y834mIVwP1FkTlWVTrGGJXf12lru7EQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", "cpu": [ "s390x" ], @@ -719,9 +719,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.4.tgz", - "integrity": "sha512-JWtGshGfX+oENAKonoNkqEJX+7hC8yfhi9GUyPX1VX4mdh1y5r+ZiJLR5XzAB0aoP6s/PcILsGjKq8O0mm24bw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", "cpu": [ "x64" ], @@ -739,9 +739,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.4.tgz", - "integrity": "sha512-rT6yQcxUuXs4CnbofqwHRRV0iem349rLMYpTjkgQGLjrY4ado/eDzwPZPTCgTOlF6Nkp8NEv70yLMTn6qkWxsQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", "cpu": [ "x64" ], @@ -759,9 +759,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.4.tgz", - "integrity": "sha512-KXMGoboq5cyaCQjDA4GLuRiOwBQ0EyFnJoVViLeZ45/3rFItRODEr+NdsBcVpll40hhNArlm/speWGRvj08LzA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", "cpu": [ "arm64" ], @@ -776,9 +776,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.4.tgz", - "integrity": "sha512-5K83rb36oJiY7BCyE9zLZtGcPV4g5wvq+xwdO0XPIwDVZI8cyB/AUjkNXGb92/rnmezEkjMOpgY61rtwjQtFwg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", "cpu": [ "wasm32" ], @@ -795,9 +795,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.4.tgz", - "integrity": "sha512-PnWBtw3TV5KOg69HQQDR0mnQuyCmSGR2pAB4DC1rPF808fgKeTUMj2EOEyKATpgiuxuR5APQmiDO7PDgEjTFSA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", "cpu": [ "arm64" ], @@ -812,9 +812,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.4.tgz", - "integrity": "sha512-M1lpniBePobTfsa7Ks9a199e1akxsXn+GYBUKsEzv3YFzOm1HJAMNwKI3qr0Zq+mxwx9gOZoTdP1yXRYsZUocQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", "cpu": [ "x64" ], @@ -934,9 +934,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.0.tgz", - "integrity": "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==", + "version": "26.1.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz", + "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==", "dev": true, "license": "MIT", "dependencies": { @@ -3324,13 +3324,13 @@ } }, "node_modules/rolldown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.4.tgz", - "integrity": "sha512-IjZYiLxZwpnhwhdBH2ugdTGVSdhCQUmLxLoqyjiL0JxYjyRst+5a0P3xfrTxJ5F638j4Mvvw5FAX5XE6eHpXbA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.138.0", + "@oxc-project/types": "=0.139.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -3340,21 +3340,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.1.4", - "@rolldown/binding-darwin-arm64": "1.1.4", - "@rolldown/binding-darwin-x64": "1.1.4", - "@rolldown/binding-freebsd-x64": "1.1.4", - "@rolldown/binding-linux-arm-gnueabihf": "1.1.4", - "@rolldown/binding-linux-arm64-gnu": "1.1.4", - "@rolldown/binding-linux-arm64-musl": "1.1.4", - "@rolldown/binding-linux-ppc64-gnu": "1.1.4", - "@rolldown/binding-linux-s390x-gnu": "1.1.4", - "@rolldown/binding-linux-x64-gnu": "1.1.4", - "@rolldown/binding-linux-x64-musl": "1.1.4", - "@rolldown/binding-openharmony-arm64": "1.1.4", - "@rolldown/binding-wasm32-wasi": "1.1.4", - "@rolldown/binding-win32-arm64-msvc": "1.1.4", - "@rolldown/binding-win32-x64-msvc": "1.1.4" + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" } }, "node_modules/router": { @@ -3590,9 +3590,9 @@ } }, "node_modules/std-env": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", - "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", "dev": true, "license": "MIT" }, @@ -3826,16 +3826,16 @@ } }, "node_modules/vite": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.3.tgz", - "integrity": "sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==", + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", + "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", - "picomatch": "^4.0.4", + "picomatch": "^4.0.5", "postcss": "^8.5.16", - "rolldown": "~1.1.3", + "rolldown": "~1.1.4", "tinyglobby": "^0.2.17" }, "bin": { diff --git a/package.json b/package.json index 0e817d1c..3cf69ba9 100644 --- a/package.json +++ b/package.json @@ -64,14 +64,14 @@ }, "dependencies": { "@agentclientprotocol/sdk": "1.2.1", - "@anthropic-ai/claude-agent-sdk": "0.3.202", + "@anthropic-ai/claude-agent-sdk": "0.3.205", "zod": "^3.25.0 || ^4.0.0" }, "devDependencies": { "@anthropic-ai/sdk": "0.110.0", "@eslint/js": "10.0.1", "@tsconfig/node22": "22.0.5", - "@types/node": "26.1.0", + "@types/node": "26.1.1", "@typescript-eslint/eslint-plugin": "8.63.0", "@typescript-eslint/parser": "8.63.0", "eslint": "10.6.0", diff --git a/src/acp-agent.ts b/src/acp-agent.ts index d9522e3f..3f2a7d41 100644 --- a/src/acp-agent.ts +++ b/src/acp-agent.ts @@ -229,8 +229,11 @@ type Session = { * the SDK still runs it and emits a result with no uuid we can match. Because * the SDK processes input FIFO, those orphan results arrive (in submission * order) before the next live turn's, so skipping exactly this many leaves - * the genuine head untouched. Reset to 0 on every activation as a backstop - * against an SDK that drops queued input on interrupt (no orphan emitted). */ + * the genuine head untouched. On CLIs with the interrupt receipt, orphans + * the interrupt dropped (absent from `still_queued`) are uncounted as soon + * as the receipt arrives (see cancel()). Reset to 0 on every activation as + * a backstop against a dropped queued input this can't see (older CLIs, a + * receipt lost to a failed control round-trip). */ pendingOrphanResults?: number; /** The long-lived consumer task. Lazily started on the first `prompt()` and * kept alive for the session so between-turn/background messages are still @@ -1777,6 +1780,15 @@ export class ClaudeAcpAgent { lastRefusalExplanation = message.api_refusal_explanation ?? message.content; } break; + // `control_request_progress` only reports on side_question + // control requests, which this adapter never issues. + // `background_tasks_changed` is a level signal (the full live + // background-task set on every membership change) for surfaces + // that render a background-activity indicator; turn lifecycle + // here is driven by results/idle, so there is nothing to track. + case "control_request_progress": + case "background_tasks_changed": + break; default: unreachable(message, this.logger); break; @@ -2388,13 +2400,10 @@ export class ClaudeAcpAgent { // `conversation_reset` (from `/clear`, plan-mode exit, fresh-session // flows) is safe to drop: turn lifecycle here is driven by // results/idle, and the client owns its own transcript view. - // `control_request_progress` only reports on side_question control - // requests, which this adapter never issues. case "tool_use_summary": case "auth_status": case "prompt_suggestion": case "conversation_reset": - case "control_request_progress": break; default: unreachable(message); @@ -2456,22 +2465,22 @@ export class ClaudeAcpAgent { // they have no in-flight SDK work to interrupt. The active turn is settled // by the consumer when it observes the interrupt's trailing idle (or via the // backstop below). Mirrors the old pendingMessages cancellation. + const orphanedUuids: string[] = []; if (session.turnQueue) { - let orphaned = 0; for (const turn of session.turnQueue) { if (turn !== session.activeTurn && !turn.settled) { turn.settled = true; // Deliberately no `usage`: a queued turn never ran, so the session // accumulator (the active turn's tally) is not its spend. turn.resolve({ stopReason: "cancelled" }); - orphaned++; + orphanedUuids.push(turn.promptUuid); } } // Each removed queued turn's user message was already pushed to the SDK, // which processes input FIFO and will still emit a result for it with no // uuid to match. Count those so the consumer skips them (see // ensureActiveTurn) rather than misattributing them to the head. - session.pendingOrphanResults = (session.pendingOrphanResults ?? 0) + orphaned; + session.pendingOrphanResults = (session.pendingOrphanResults ?? 0) + orphanedUuids.length; session.turnQueue = session.turnQueue.filter( (turn) => turn === session.activeTurn && !turn.settled, ); @@ -2503,7 +2512,29 @@ export class ClaudeAcpAgent { }, this.forceCancelGraceMs); } - await session.query.interrupt(); + const receipt = await session.query.interrupt(); + // On CLIs advertising `interrupt_receipt_v1`, the receipt's `still_queued` + // lists exactly which queued messages survive the interrupt and will still + // run. An orphaned turn whose uuid is absent was dropped by the interrupt + // and will never emit a result — uncount it now instead of leaving a stale + // skip that activateTurn's reset only clears once a later live ECHO + // arrives: an echo-less result in between (a local-only command like + // `/context`) would be wrongly swallowed by the leftover count. Subtracting + // a count (rather than tracking uuids) stays race-safe against the + // consumer draining concurrently: dropped uuids produce no results, so the + // consumer's decrements only ever consume the still-queued share. Unknown + // uuids in the receipt (internally-enqueued messages) are ignored, per its + // contract. Older CLIs resolve `undefined` (guard the FIELD, not just the + // receipt, so a bare `{}` success from a gateway can't read as "everything + // was dropped") — keep the count-everything behavior and its + // activation-time self-heal. + if (Array.isArray(receipt?.still_queued) && orphanedUuids.length > 0) { + const stillQueued = new Set(receipt.still_queued); + const dropped = orphanedUuids.filter((uuid) => !stillQueued.has(uuid)).length; + if (dropped > 0) { + session.pendingOrphanResults = Math.max(0, (session.pendingOrphanResults ?? 0) - dropped); + } + } } /** Mark a session's SDK query stream as permanently ended and release the diff --git a/src/sdk-shims.d.ts b/src/sdk-shims.d.ts deleted file mode 100644 index 695542af..00000000 --- a/src/sdk-shims.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Shims for types the `@anthropic-ai/claude-agent-sdk` 0.3.198 `sdk.d.ts` - * references in its `SDKMessage` union but never declares - * (`SDKControlRequestProgressMessage`, `SDKConversationResetMessage`). With - * `skipLibCheck` the dangling references silently become error-`any`, which - * poisons narrowing on the whole union — every exhaustive switch over - * `SDKMessage` stops compiling. - * - * These must stay GLOBAL declarations (no top-level import/export in this - * file): unqualified names inside the SDK's module declaration fall back to - * the global scope, which is the only way a consumer can supply them. Shapes - * are transcribed from the zod schemas embedded in the bundled CLI binary. - * Delete this file once the SDK ships the declarations itself — a proper - * module-scoped declaration will shadow these. - */ - -/** Progress for a long-running client-originated control request (currently - * only `side_question`), correlated by `request_id`. */ -declare type SDKControlRequestProgressMessage = { - type: "control_request_progress"; - request_id: string; - status: "started" | "api_retry"; - attempt?: number; - max_retries?: number; - retry_delay_ms?: number; - error_status?: number | null; - uuid: import("crypto").UUID; - session_id: string; -}; - -/** Emitted by `/clear`, plan-mode exit, and fresh-session flows; the surface - * should mount a fresh transcript under `new_conversation_id`. */ -declare type SDKConversationResetMessage = { - type: "conversation_reset"; - new_conversation_id: import("crypto").UUID; - uuid: import("crypto").UUID; - session_id: string; -}; diff --git a/src/tests/acp-agent.test.ts b/src/tests/acp-agent.test.ts index 4b162580..c25befc7 100644 --- a/src/tests/acp-agent.test.ts +++ b/src/tests/acp-agent.test.ts @@ -6160,6 +6160,145 @@ describe("post-error recovery", () => { expect(compactResult.usage?.inputTokens).toBe(10); await agent.sessions["test-session"]?.consumer; }); + + it("uncounts an orphan the interrupt receipt reports dropped, so a no-echo result isn't swallowed", async () => { + // interrupt_receipt_v1 CLIs: interrupt() resolves with `still_queued` — + // the queued messages that will still run. Here the interrupt DROPS turn + // 2's queued message (still_queued: []), so its orphan result never + // arrives. Without the receipt reconciliation the stale count (1) would + // swallow the next echo-less result — the /compact below — and hang its + // prompt; activation's reset can't help because /compact never echoes. + const agent = createMockAgent(); + let release!: () => void; + const gate = new Promise((resolve) => (release = resolve)); + + injectGeneratorSession(agent, (input) => { + async function* messageGenerator() { + const iter = input[Symbol.asyncIterator](); + const u1 = await iter.next(); + yield userEcho(u1.value); // turn 1 active + await iter.next(); // turn 2's pushed message (cancelled; interrupt drops it) + await gate; // wait until the test cancels and sends /compact + yield { type: "system", subtype: "session_state_changed", state: "idle" }; // turn 1 settles cancelled + // NO orphan result for turn 2 — the interrupt dropped its queued message. + await iter.next(); // /compact's pushed message — never echoes its uuid + yield { + type: "system", + subtype: "status", + status: "compacting", + session_id: "test-session", + }; + yield createResultMessage({ subtype: "success", stop_reason: "end_turn", is_error: false }); + yield { type: "system", subtype: "session_state_changed", state: "idle" }; + } + return messageGenerator(); + }); + // New-CLI interrupt: nothing queued survives the interrupt. + agent.sessions["test-session"]!.query.interrupt = vi.fn(async () => ({ still_queued: [] })); + + const first = agent.prompt({ + sessionId: "test-session", + prompt: [{ type: "text", text: "first" }], + }); + await waitFor(() => !!agent.sessions["test-session"]?.activeTurn); + const second = agent.prompt({ + sessionId: "test-session", + prompt: [{ type: "text", text: "second" }], + }); + await waitFor(() => (agent.sessions["test-session"]?.turnQueue?.length ?? 0) >= 2); + + await agent.cancel({ sessionId: "test-session" }); // counts turn 2, then the receipt uncounts it + expect(agent.sessions["test-session"]?.pendingOrphanResults).toBe(0); + const compact = agent.prompt({ + sessionId: "test-session", + prompt: [{ type: "text", text: "/compact" }], + }); + release(); + + await expect(first).resolves.toEqual({ + stopReason: "cancelled", + usage: cancelledTurnUsage, + }); + await expect(second).resolves.toEqual({ stopReason: "cancelled" }); + const compactResult = await compact; + expect(compactResult.stopReason).toBe("end_turn"); + expect(compactResult.usage?.inputTokens).toBe(10); + await agent.sessions["test-session"]?.consumer; + }); + + it("keeps counting an orphan the interrupt receipt reports still queued", async () => { + // The receipt lists turn 2's uuid in still_queued — its message survives + // the interrupt, runs, and emits an orphan result that must still be + // skipped (not promoted onto the later /compact). + const agent = createMockAgent(); + let release!: () => void; + const gate = new Promise((resolve) => (release = resolve)); + + const orphanResult = createResultMessage({ + subtype: "success", + stop_reason: "end_turn", + is_error: false, + }); + orphanResult.usage.input_tokens = 999; + + injectGeneratorSession(agent, (input) => { + async function* messageGenerator() { + const iter = input[Symbol.asyncIterator](); + const u1 = await iter.next(); + yield userEcho(u1.value); // turn 1 active + await iter.next(); // turn 2's pushed message (cancelled, but survives the interrupt) + await gate; + yield { type: "system", subtype: "session_state_changed", state: "idle" }; // turn 1 settles cancelled + yield orphanResult; // turn 2's orphan — the kept count skips it + await iter.next(); // /compact's pushed message — never echoes its uuid + yield { + type: "system", + subtype: "status", + status: "compacting", + session_id: "test-session", + }; + yield createResultMessage({ subtype: "success", stop_reason: "end_turn", is_error: false }); + yield { type: "system", subtype: "session_state_changed", state: "idle" }; + } + return messageGenerator(); + }); + const first = agent.prompt({ + sessionId: "test-session", + prompt: [{ type: "text", text: "first" }], + }); + await waitFor(() => !!agent.sessions["test-session"]?.activeTurn); + const second = agent.prompt({ + sessionId: "test-session", + prompt: [{ type: "text", text: "second" }], + }); + await waitFor(() => (agent.sessions["test-session"]?.turnQueue?.length ?? 0) >= 2); + + // Report turn 2's queued message as surviving the interrupt. Captured + // before cancel() filters the queue (interrupt runs after the filter). + const session = agent.sessions["test-session"]!; + const survivingUuid = session.turnQueue![1].promptUuid; + session.query.interrupt = vi.fn(async () => ({ still_queued: [survivingUuid] })); + + await agent.cancel({ sessionId: "test-session" }); + expect(agent.sessions["test-session"]?.pendingOrphanResults).toBe(1); + const compact = agent.prompt({ + sessionId: "test-session", + prompt: [{ type: "text", text: "/compact" }], + }); + release(); + + await expect(first).resolves.toEqual({ + stopReason: "cancelled", + usage: cancelledTurnUsage, + }); + await expect(second).resolves.toEqual({ stopReason: "cancelled" }); + const compactResult = await compact; + expect(compactResult.stopReason).toBe("end_turn"); + // /compact settled with its OWN result, proving the surviving orphan was + // skipped rather than promoted onto it (which would leak the 999). + expect(compactResult.usage?.inputTokens).toBe(10); + await agent.sessions["test-session"]?.consumer; + }); }); describe("session/cancel wedge recovery (issue #680)", () => {