diff --git a/package-lock.json b/package-lock.json index 2afea02e9..ec5289b06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1652,6 +1652,297 @@ "node": ">=6.9.0" } }, + "node_modules/@boudra/claude-code-acp": { + "version": "0.8.1", + "resolved": "https://npm.pkg.github.com/download/@boudra/claude-code-acp/0.8.1/eb5705eac2631f6327d9a15d2b55ce6a24720f94", + "integrity": "sha512-MUOJXVBjfmi9Mrf1iBMWjCnXADmoELD7cgDhmIq/HWlacEqE5hmb8j/WcadoP9EwY1xzrSSLBSzJ62x5tuxuUQ==", + "license": "Apache-2.0", + "dependencies": { + "@agentclientprotocol/sdk": "0.4.9", + "@anthropic-ai/claude-agent-sdk": "0.1.23", + "@anthropic-ai/claude-code": "2.0.24", + "@modelcontextprotocol/sdk": "1.20.1", + "diff": "8.0.2", + "express": "5.1.0", + "uuid": "13.0.0" + }, + "bin": { + "claude-code-acp": "dist/index.js" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/body-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/content-disposition": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/diff": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", + "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/express": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/finalhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@boudra/claude-code-acp/node_modules/uuid": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", + "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, "node_modules/@boudra/expo-two-way-audio": { "version": "0.1.4", "resolved": "https://npm.pkg.github.com/download/@boudra/expo-two-way-audio/0.1.4/6b9f97bb0a8fb57950eb1f7078b2baf6337dfd0c", @@ -21336,7 +21627,7 @@ "dependencies": { "@agentclientprotocol/sdk": "^0.4.9", "@ai-sdk/openai": "^2.0.52", - "@boudra/claude-code-acp": "^0.8.0", + "@boudra/claude-code-acp": "^0.8.1", "@deepgram/sdk": "^3.4.0", "@modelcontextprotocol/sdk": "^1.20.1", "@openrouter/ai-sdk-provider": "^1.2.0", @@ -21362,297 +21653,6 @@ "typescript": "^5.2.2", "vitest": "^3.2.4" } - }, - "packages/server/node_modules/@boudra/claude-code-acp": { - "version": "0.8.0", - "resolved": "https://npm.pkg.github.com/download/@boudra/claude-code-acp/0.8.0/b67fdb37b189c68b9b155e421b2e03a061069239", - "integrity": "sha512-JdCzu8yp/I/D50FKJgT05KJkHK8gMF6CT3tDu9CdHcMbLcizTg/BZbwSXzlPPx9Po6uzttTykLkyexzAQR23EQ==", - "license": "Apache-2.0", - "dependencies": { - "@agentclientprotocol/sdk": "0.4.9", - "@anthropic-ai/claude-agent-sdk": "0.1.23", - "@anthropic-ai/claude-code": "2.0.24", - "@modelcontextprotocol/sdk": "1.20.1", - "diff": "8.0.2", - "express": "5.1.0", - "uuid": "13.0.0" - }, - "bin": { - "claude-code-acp": "dist/index.js" - } - }, - "packages/server/node_modules/@boudra/claude-code-acp/node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "packages/server/node_modules/@boudra/claude-code-acp/node_modules/uuid": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", - "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist-node/bin/uuid" - } - }, - "packages/server/node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "packages/server/node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "packages/server/node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "packages/server/node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "packages/server/node_modules/diff": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", - "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "packages/server/node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "packages/server/node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "packages/server/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/server/node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "packages/server/node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/server/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "packages/server/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "packages/server/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "packages/server/node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/server/node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "packages/server/node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "packages/server/node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } } } } diff --git a/packages/server/agents.json b/packages/server/agents.json deleted file mode 100644 index bd7a6e23d..000000000 --- a/packages/server/agents.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "id": "bcc0019c-9293-4235-adb7-921f8e7d67eb", - "title": "Fix Real-time Footer Spacing", - "sessionId": "019a1575-706b-73fc-8955-d2c7b524e707", - "createdAt": "2025-10-24T09:03:28.577Z", - "cwd": "/Users/moboudra/dev/voice-dev" - } -] \ No newline at end of file diff --git a/packages/server/package.json b/packages/server/package.json index acb308faf..7ce8e0858 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -18,7 +18,7 @@ "dependencies": { "@agentclientprotocol/sdk": "^0.4.9", "@ai-sdk/openai": "^2.0.52", - "@boudra/claude-code-acp": "^0.8.0", + "@boudra/claude-code-acp": "^0.8.1", "@deepgram/sdk": "^3.4.0", "@modelcontextprotocol/sdk": "^1.20.1", "@openrouter/ai-sdk-provider": "^1.2.0", diff --git a/packages/server/src/server/acp/agent-manager.ts b/packages/server/src/server/acp/agent-manager.ts index 27b1ff1f2..88b2be878 100644 --- a/packages/server/src/server/acp/agent-manager.ts +++ b/packages/server/src/server/acp/agent-manager.ts @@ -225,15 +225,28 @@ export class AgentManager { }); // Use the loadSession API to resume the existing session - console.log(`[Agent ${agentId}] Loading session ${persisted.sessionId} via loadSession API`); + // If this is a Claude agent, use the Claude's internal session ID for resumption + const sessionIdToResume = persisted.options.type === "claude" + ? persisted.options.sessionId + : persisted.sessionId; + + console.log(`[Agent ${agentId}] Loading session - ACP: ${persisted.sessionId}, Claude: ${sessionIdToResume}`); const sessionResponse = await agent.connection.loadSession({ - sessionId: persisted.sessionId, + sessionId: sessionIdToResume, cwd, mcpServers: [], }); console.log(`[Agent ${agentId}] Session loaded:`, JSON.stringify(sessionResponse, null, 2)); + // Extract Claude's session ID from the response metadata if available + const claudeSessionId = sessionResponse._meta?.claudeSessionId as string | undefined; + if (claudeSessionId && persisted.options.type === "claude" && persisted.options.sessionId !== claudeSessionId) { + console.log(`[Agent ${agentId}] Updating Claude session ID from ${persisted.options.sessionId} to ${claudeSessionId}`); + persisted.options.sessionId = claudeSessionId; + await this.persistence.upsert(persisted); + } + // Store session modes from response if (sessionResponse.modes) { agent.currentModeId = sessionResponse.modes.currentModeId; @@ -357,6 +370,13 @@ export class AgentManager { const sessionResponse = await agent.connection.newSession(sessionParams); agent.sessionId = sessionResponse.sessionId; + + // Extract Claude's internal session ID from metadata + const claudeSessionId = sessionResponse._meta?.claudeSessionId as string | undefined; + if (claudeSessionId) { + console.log(`[Agent ${agentId}] Claude session ID: ${claudeSessionId}, ACP session ID: ${sessionResponse.sessionId}`); + } + console.log(`[Agent ${agentId}] newSession response:`, JSON.stringify(sessionResponse, null, 2)); // Store session modes from response @@ -385,6 +405,10 @@ export class AgentManager { id: agentId, title: agent.title || `Agent ${agentId.slice(0, 8)}`, sessionId: agent.sessionId, + options: { + type: "claude", + sessionId: claudeSessionId || agent.sessionId, // Use Claude's internal session ID if available + }, createdAt: agent.createdAt.toISOString(), cwd: agent.cwd, }); @@ -1030,6 +1054,32 @@ export class AgentManager { // Remove from pending agent.pendingPermissions.delete(requestId); + + // Emit permission_resolved notification so UI can update + const agentUpdate: AgentUpdate = { + agentId, + timestamp: new Date(), + notification: { + type: 'permission_resolved', + requestId, + agentId, + optionId, + }, + }; + + // Store the update in history + agent.updates.push(agentUpdate); + + // Notify all subscribers (including Session which will forward to WebSocket) + for (const subscriber of agent.subscribers) { + try { + subscriber(agentUpdate); + } catch (error) { + console.error(`[Agent ${agentId}] Subscriber error:`, error); + } + } + + console.log(`[Agent ${agentId}] Permission resolved notification emitted: ${requestId}`); } /** diff --git a/packages/server/src/server/acp/agent-persistence.ts b/packages/server/src/server/acp/agent-persistence.ts index c5001ecfc..e47149f2a 100644 --- a/packages/server/src/server/acp/agent-persistence.ts +++ b/packages/server/src/server/acp/agent-persistence.ts @@ -2,17 +2,33 @@ import { promises as fs } from "fs"; import path from "path"; import { fileURLToPath } from "url"; import { dirname } from "path"; +import { z } from "zod"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); -export interface PersistedAgent { - id: string; - title: string; - sessionId: string; - createdAt: string; - cwd: string; -} +// Zod schema for agent options (discriminated union) +export const AgentOptionsSchema = z.discriminatedUnion("type", [ + z.object({ + type: z.literal("claude"), + sessionId: z.string(), // Claude's internal session ID + }), + // Add more agent types here in the future +]); + +export type AgentOptions = z.infer; + +// Zod schema for persisted agent +export const PersistedAgentSchema = z.object({ + id: z.string(), + title: z.string(), + sessionId: z.string(), // ACP protocol session ID (for backward compatibility) + options: AgentOptionsSchema, // Required field with discriminated union + createdAt: z.string(), + cwd: z.string(), +}); + +export type PersistedAgent = z.infer; export class AgentPersistence { private persistencePath: string; @@ -23,12 +39,26 @@ export class AgentPersistence { } /** - * Load all persisted agents + * Load all persisted agents with Zod validation */ async load(): Promise { try { const data = await fs.readFile(this.persistencePath, "utf-8"); - return JSON.parse(data); + const parsed = JSON.parse(data); + + // Validate each agent with Zod schema + const agents: PersistedAgent[] = []; + for (const agent of parsed) { + try { + const validated = PersistedAgentSchema.parse(agent); + agents.push(validated); + } catch (zodError) { + console.error(`[AgentPersistence] Invalid agent data for ${agent.id}:`, zodError); + // Skip invalid agents + } + } + + return agents; } catch (error) { // File doesn't exist or is invalid, return empty array console.log("[AgentPersistence] No existing agents found or file is invalid"); diff --git a/packages/server/src/server/acp/types.ts b/packages/server/src/server/acp/types.ts index bc68b5b6b..c57aee9da 100644 --- a/packages/server/src/server/acp/types.ts +++ b/packages/server/src/server/acp/types.ts @@ -24,6 +24,7 @@ export interface EnrichedSessionNotification extends Omit fs.createReadStream(tempFilePath!)), - model: config.model || "gpt-4o-transcribe", + language: "en", + model: config.model ?? "gpt-4o-transcribe", + include: ["logprobs"], response_format: "json", // Get language and duration info }); const duration = Date.now() - startTime; + // Get confidence threshold (default: -3.0) + const confidenceThreshold = config.confidenceThreshold ?? -3.0; + + // Analyze logprobs if available + let avgLogprob: number | undefined; + let isLowConfidence = false; + const logprobs = response.logprobs as LogprobToken[] | undefined; + + if (logprobs && logprobs.length > 0) { + // Calculate average logprob + const totalLogprob = logprobs.reduce( + (sum, token) => sum + token.logprob, + 0 + ); + avgLogprob = totalLogprob / logprobs.length; + + // Check if transcription is low confidence + isLowConfidence = avgLogprob < confidenceThreshold; + + if (isLowConfidence) { + console.log( + `[STT] Low confidence transcription detected (avg: ${avgLogprob.toFixed( + 2 + )}, threshold: ${confidenceThreshold}): "${response.text}"` + ); + console.log( + `[STT] Token logprobs:`, + logprobs.map((t) => `${t.token}:${t.logprob.toFixed(2)}`).join(", ") + ); + } + } + console.log( - `[STT] Transcription complete in ${duration}ms: "${response.text}"` + `[STT] Transcription complete in ${duration}ms: "${response.text}"${ + avgLogprob !== undefined + ? ` (avg logprob: ${avgLogprob.toFixed(2)})` + : "" + }` ); return { text: response.text, duration: duration, + logprobs: logprobs, + avgLogprob: avgLogprob, + isLowConfidence: isLowConfidence, }; } catch (error: any) { console.error("[STT] Transcription error:", error); diff --git a/packages/server/src/server/index.ts b/packages/server/src/server/index.ts index 9543fcf39..dc9913ced 100644 --- a/packages/server/src/server/index.ts +++ b/packages/server/src/server/index.ts @@ -80,7 +80,14 @@ async function main() { console.log("✓ OpenAI client initialized"); // Initialize STT (Whisper) - initializeSTT({ apiKey }); + const sttConfidenceThreshold = process.env.STT_CONFIDENCE_THRESHOLD + ? parseFloat(process.env.STT_CONFIDENCE_THRESHOLD) + : undefined; // Will default to -3.0 in stt-openai.ts + + initializeSTT({ + apiKey, + confidenceThreshold: sttConfidenceThreshold + }); // Initialize TTS const ttsVoice = (process.env.TTS_VOICE || "alloy") as diff --git a/packages/server/src/server/messages.ts b/packages/server/src/server/messages.ts index 426a2aaf4..a7740f8aa 100644 --- a/packages/server/src/server/messages.ts +++ b/packages/server/src/server/messages.ts @@ -298,6 +298,15 @@ export const AgentPermissionRequestMessageSchema = z.object({ }), }); +export const AgentPermissionResolvedMessageSchema = z.object({ + type: z.literal("agent_permission_resolved"), + payload: z.object({ + agentId: z.string(), + requestId: z.string(), + optionId: z.string(), + }), +}); + export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [ ActivityLogMessageSchema, AssistantChunkMessageSchema, @@ -313,6 +322,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [ ListConversationsResponseMessageSchema, DeleteConversationResponseMessageSchema, AgentPermissionRequestMessageSchema, + AgentPermissionResolvedMessageSchema, ]); export type SessionOutboundMessage = z.infer< @@ -334,6 +344,7 @@ export type SessionStateMessage = z.infer; export type ListConversationsResponseMessage = z.infer; export type DeleteConversationResponseMessage = z.infer; export type AgentPermissionRequestMessage = z.infer; +export type AgentPermissionResolvedMessage = z.infer; // Type exports for payload types export type ActivityLogPayload = z.infer; diff --git a/packages/server/src/server/session.ts b/packages/server/src/server/session.ts index b92c53a93..64a03cd8c 100644 --- a/packages/server/src/server/session.ts +++ b/packages/server/src/server/session.ts @@ -190,6 +190,22 @@ export class Session { return; } + // Handle permission resolved notifications + if (notification.type === "permission_resolved") { + this.emit({ + type: "agent_permission_resolved", + payload: { + agentId: notification.agentId, + requestId: notification.requestId, + optionId: notification.optionId, + }, + }); + console.log( + `[Session ${this.clientId}] Forwarded permission resolved for agent ${agentId} with requestId ${notification.requestId}` + ); + return; + } + // Handle status updates if (notification.type === "status") { const status = notification.status;