gsd-pi 2.46.1 → 2.47.0-dev.8cfe772
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -29
- package/dist/resources/extensions/claude-code-cli/index.js +25 -0
- package/dist/resources/extensions/claude-code-cli/models.js +40 -0
- package/dist/resources/extensions/claude-code-cli/package.json +11 -0
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +223 -0
- package/dist/resources/extensions/claude-code-cli/readiness.js +26 -0
- package/dist/resources/extensions/claude-code-cli/sdk-types.js +8 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +309 -0
- package/dist/resources/extensions/gsd/auto-start.js +17 -9
- package/dist/resources/extensions/gsd/guided-flow.js +78 -2
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/run-uat.md +2 -2
- package/dist/resources/extensions/gsd/repo-identity.js +5 -2
- package/dist/resources/extensions/gsd/session-forensics.js +10 -1
- package/dist/resources/extensions/gsd/state.js +29 -2
- package/dist/resources/extensions/gsd/workflow-events.js +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +3 -1
- package/packages/pi-agent-core/dist/agent-loop.js +27 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +7 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +9 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +26 -1
- package/packages/pi-agent-core/src/agent.ts +10 -0
- package/packages/pi-agent-core/src/types.ts +10 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +27 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +43 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +26 -3
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +27 -2
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +70 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +29 -2
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -0
- package/packages/pi-tui/dist/components/box.d.ts +1 -0
- package/packages/pi-tui/dist/components/box.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/box.js +10 -0
- package/packages/pi-tui/dist/components/box.js.map +1 -1
- package/packages/pi-tui/src/components/box.ts +10 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/index.ts +28 -0
- package/src/resources/extensions/claude-code-cli/models.ts +42 -0
- package/src/resources/extensions/claude-code-cli/package.json +11 -0
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +258 -0
- package/src/resources/extensions/claude-code-cli/readiness.ts +30 -0
- package/src/resources/extensions/claude-code-cli/sdk-types.ts +149 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +370 -0
- package/src/resources/extensions/gsd/auto-start.ts +15 -8
- package/src/resources/extensions/gsd/guided-flow.ts +96 -2
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/run-uat.md +2 -2
- package/src/resources/extensions/gsd/repo-identity.ts +5 -2
- package/src/resources/extensions/gsd/session-forensics.ts +11 -1
- package/src/resources/extensions/gsd/state.ts +33 -1
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +241 -0
- package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/preflight-context-draft-filter.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +25 -0
- package/src/resources/extensions/gsd/workflow-events.ts +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{P4nF4UcdATjrbNMBH_Ulh → DyrX2zX_4v7KZDbUNxE2q}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{P4nF4UcdATjrbNMBH_Ulh → DyrX2zX_4v7KZDbUNxE2q}/_ssgManifest.js +0 -0
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type Api,
|
|
7
7
|
type AssistantMessageEventStream,
|
|
8
8
|
type Context,
|
|
9
|
+
getApiProvider,
|
|
9
10
|
getModels,
|
|
10
11
|
getProviders,
|
|
11
12
|
type KnownProvider,
|
|
@@ -635,11 +636,37 @@ export class ModelRegistry {
|
|
|
635
636
|
})
|
|
636
637
|
: rawStreamSimple;
|
|
637
638
|
|
|
639
|
+
// Guard: if there's already a handler registered for this API, wrap
|
|
640
|
+
// the new one so it only fires for models from this provider and
|
|
641
|
+
// delegates to the previous handler for all other providers. Without
|
|
642
|
+
// this, a custom provider using api:"anthropic-messages" would clobber
|
|
643
|
+
// the built-in Anthropic stream handler (#2536).
|
|
644
|
+
const existingProvider = getApiProvider(config.api as Api);
|
|
645
|
+
const scopedStream = existingProvider
|
|
646
|
+
? (model: Model<Api>, context: Context, options?: SimpleStreamOptions): AssistantMessageEventStream => {
|
|
647
|
+
if (model.provider === providerName) {
|
|
648
|
+
return streamSimple(model, context, options);
|
|
649
|
+
}
|
|
650
|
+
return existingProvider.streamSimple(model, context, options);
|
|
651
|
+
}
|
|
652
|
+
: streamSimple;
|
|
653
|
+
|
|
654
|
+
const newFullStream = (model: Model<Api>, context: Context, options?: SimpleStreamOptions) =>
|
|
655
|
+
scopedStream(model, context, options as SimpleStreamOptions);
|
|
656
|
+
const scopedFullStream = existingProvider
|
|
657
|
+
? (model: Model<Api>, context: Context, options?: Record<string, unknown>) => {
|
|
658
|
+
if (model.provider === providerName) {
|
|
659
|
+
return newFullStream(model, context, options as SimpleStreamOptions);
|
|
660
|
+
}
|
|
661
|
+
return existingProvider.stream(model, context, options);
|
|
662
|
+
}
|
|
663
|
+
: newFullStream;
|
|
664
|
+
|
|
638
665
|
registerApiProvider(
|
|
639
666
|
{
|
|
640
667
|
api: config.api,
|
|
641
|
-
stream:
|
|
642
|
-
streamSimple,
|
|
668
|
+
stream: scopedFullStream as any,
|
|
669
|
+
streamSimple: scopedStream,
|
|
643
670
|
},
|
|
644
671
|
`provider:${providerName}`,
|
|
645
672
|
);
|
|
@@ -326,6 +326,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
326
326
|
transport: settingsManager.getTransport(),
|
|
327
327
|
thinkingBudgets: settingsManager.getThinkingBudgets(),
|
|
328
328
|
maxRetryDelayMs: settingsManager.getRetrySettings().maxDelayMs,
|
|
329
|
+
externalToolExecution: (m) => modelRegistry.getProviderAuthMode(m.provider) === "externalCli",
|
|
329
330
|
getApiKey: async (provider) => {
|
|
330
331
|
// Use the provider argument from the in-flight request;
|
|
331
332
|
// agent.state.model may already be switched mid-turn.
|
|
@@ -10,6 +10,7 @@ export declare class Box implements Component {
|
|
|
10
10
|
private cache?;
|
|
11
11
|
constructor(paddingX?: number, paddingY?: number, bgFn?: (text: string) => string);
|
|
12
12
|
addChild(component: Component): void;
|
|
13
|
+
insertChildBefore(component: Component, before: Component): void;
|
|
13
14
|
removeChild(component: Component): void;
|
|
14
15
|
clear(): void;
|
|
15
16
|
setBgFn(bgFn?: (text: string) => string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C;;GAEG;AACH,qBAAa,GAAI,YAAW,SAAS;IACpC,QAAQ,EAAE,SAAS,EAAE,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAC,CAA2B;IAGxC,OAAO,CAAC,KAAK,CAAC,CAAc;gBAEhB,QAAQ,SAAI,EAAE,QAAQ,SAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM;IAMvE,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAKpC,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAQvC,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI;IAK9C,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,UAAU;IAWlB,UAAU,IAAI,IAAI;IAOlB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAqD/B,OAAO,CAAC,OAAO;CAUf"}
|
|
1
|
+
{"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C;;GAEG;AACH,qBAAa,GAAI,YAAW,SAAS;IACpC,QAAQ,EAAE,SAAS,EAAE,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAC,CAA2B;IAGxC,OAAO,CAAC,KAAK,CAAC,CAAc;gBAEhB,QAAQ,SAAI,EAAE,QAAQ,SAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM;IAMvE,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAKpC,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI;IAUhE,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAQvC,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI;IAK9C,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,UAAU;IAWlB,UAAU,IAAI,IAAI;IAOlB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAqD/B,OAAO,CAAC,OAAO;CAUf"}
|
|
@@ -13,6 +13,16 @@ export class Box {
|
|
|
13
13
|
this.children.push(component);
|
|
14
14
|
this.invalidateCache();
|
|
15
15
|
}
|
|
16
|
+
insertChildBefore(component, before) {
|
|
17
|
+
const index = this.children.indexOf(before);
|
|
18
|
+
if (index !== -1) {
|
|
19
|
+
this.children.splice(index, 0, component);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.children.push(component);
|
|
23
|
+
}
|
|
24
|
+
this.invalidateCache();
|
|
25
|
+
}
|
|
16
26
|
removeChild(component) {
|
|
17
27
|
const index = this.children.indexOf(component);
|
|
18
28
|
if (index !== -1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"../tui.js\";\nimport { applyBackgroundToLine, visibleWidth } from \"../utils.js\";\n\ntype RenderCache = {\n\tchildLines: string[];\n\twidth: number;\n\tbgSample: string | undefined;\n\tlines: string[];\n};\n\n/**\n * Box component - a container that applies padding and background to all children\n */\nexport class Box implements Component {\n\tchildren: Component[] = [];\n\tprivate paddingX: number;\n\tprivate paddingY: number;\n\tprivate bgFn?: (text: string) => string;\n\n\t// Cache for rendered output\n\tprivate cache?: RenderCache;\n\n\tconstructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.bgFn = bgFn;\n\t}\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t\tthis.invalidateCache();\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tthis.invalidateCache();\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tsetBgFn(bgFn?: (text: string) => string): void {\n\t\tthis.bgFn = bgFn;\n\t\t// Don't invalidate here - we'll detect bgFn changes by sampling output\n\t}\n\n\tprivate invalidateCache(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tprivate matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {\n\t\tconst cache = this.cache;\n\t\treturn (\n\t\t\t!!cache &&\n\t\t\tcache.width === width &&\n\t\t\tcache.bgSample === bgSample &&\n\t\t\tcache.childLines.length === childLines.length &&\n\t\t\tcache.childLines.every((line, i) => line === childLines[i])\n\t\t);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.invalidateCache();\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.children.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\n\t\t// Render all children\n\t\tconst childLines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst lines = child.render(contentWidth);\n\t\t\tfor (const line of lines) {\n\t\t\t\tchildLines.push(leftPad + line);\n\t\t\t}\n\t\t}\n\n\t\tif (childLines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Check if bgFn output changed by sampling\n\t\tconst bgSample = this.bgFn ? this.bgFn(\"test\") : undefined;\n\n\t\t// Check cache validity\n\t\tif (this.matchCache(width, childLines, bgSample)) {\n\t\t\treturn this.cache!.lines;\n\t\t}\n\n\t\t// Apply background and padding\n\t\tconst result: string[] = [];\n\n\t\t// Top padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Content\n\t\tfor (const line of childLines) {\n\t\t\tresult.push(this.applyBg(line, width));\n\t\t}\n\n\t\t// Bottom padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Update cache\n\t\tthis.cache = { childLines, width, bgSample, lines: result };\n\n\t\treturn result;\n\t}\n\n\tprivate applyBg(line: string, width: number): string {\n\t\tconst visLen = visibleWidth(line);\n\t\tconst padNeeded = Math.max(0, width - visLen);\n\t\tconst padded = line + \" \".repeat(padNeeded);\n\n\t\tif (this.bgFn) {\n\t\t\treturn applyBackgroundToLine(padded, width, this.bgFn);\n\t\t}\n\t\treturn padded;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"../tui.js\";\nimport { applyBackgroundToLine, visibleWidth } from \"../utils.js\";\n\ntype RenderCache = {\n\tchildLines: string[];\n\twidth: number;\n\tbgSample: string | undefined;\n\tlines: string[];\n};\n\n/**\n * Box component - a container that applies padding and background to all children\n */\nexport class Box implements Component {\n\tchildren: Component[] = [];\n\tprivate paddingX: number;\n\tprivate paddingY: number;\n\tprivate bgFn?: (text: string) => string;\n\n\t// Cache for rendered output\n\tprivate cache?: RenderCache;\n\n\tconstructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.bgFn = bgFn;\n\t}\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t\tthis.invalidateCache();\n\t}\n\n\tinsertChildBefore(component: Component, before: Component): void {\n\t\tconst index = this.children.indexOf(before);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 0, component);\n\t\t} else {\n\t\t\tthis.children.push(component);\n\t\t}\n\t\tthis.invalidateCache();\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tthis.invalidateCache();\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tsetBgFn(bgFn?: (text: string) => string): void {\n\t\tthis.bgFn = bgFn;\n\t\t// Don't invalidate here - we'll detect bgFn changes by sampling output\n\t}\n\n\tprivate invalidateCache(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tprivate matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {\n\t\tconst cache = this.cache;\n\t\treturn (\n\t\t\t!!cache &&\n\t\t\tcache.width === width &&\n\t\t\tcache.bgSample === bgSample &&\n\t\t\tcache.childLines.length === childLines.length &&\n\t\t\tcache.childLines.every((line, i) => line === childLines[i])\n\t\t);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.invalidateCache();\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.children.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\n\t\t// Render all children\n\t\tconst childLines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst lines = child.render(contentWidth);\n\t\t\tfor (const line of lines) {\n\t\t\t\tchildLines.push(leftPad + line);\n\t\t\t}\n\t\t}\n\n\t\tif (childLines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Check if bgFn output changed by sampling\n\t\tconst bgSample = this.bgFn ? this.bgFn(\"test\") : undefined;\n\n\t\t// Check cache validity\n\t\tif (this.matchCache(width, childLines, bgSample)) {\n\t\t\treturn this.cache!.lines;\n\t\t}\n\n\t\t// Apply background and padding\n\t\tconst result: string[] = [];\n\n\t\t// Top padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Content\n\t\tfor (const line of childLines) {\n\t\t\tresult.push(this.applyBg(line, width));\n\t\t}\n\n\t\t// Bottom padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Update cache\n\t\tthis.cache = { childLines, width, bgSample, lines: result };\n\n\t\treturn result;\n\t}\n\n\tprivate applyBg(line: string, width: number): string {\n\t\tconst visLen = visibleWidth(line);\n\t\tconst padNeeded = Math.max(0, width - visLen);\n\t\tconst padded = line + \" \".repeat(padNeeded);\n\n\t\tif (this.bgFn) {\n\t\t\treturn applyBackgroundToLine(padded, width, this.bgFn);\n\t\t}\n\t\treturn padded;\n\t}\n}\n"]}
|
|
@@ -31,6 +31,16 @@ export class Box implements Component {
|
|
|
31
31
|
this.invalidateCache();
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
insertChildBefore(component: Component, before: Component): void {
|
|
35
|
+
const index = this.children.indexOf(before);
|
|
36
|
+
if (index !== -1) {
|
|
37
|
+
this.children.splice(index, 0, component);
|
|
38
|
+
} else {
|
|
39
|
+
this.children.push(component);
|
|
40
|
+
}
|
|
41
|
+
this.invalidateCache();
|
|
42
|
+
}
|
|
43
|
+
|
|
34
44
|
removeChild(component: Component): void {
|
|
35
45
|
const index = this.children.indexOf(component);
|
|
36
46
|
if (index !== -1) {
|
package/pkg/package.json
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code CLI Provider Extension
|
|
3
|
+
*
|
|
4
|
+
* Registers a model provider that delegates inference to the user's
|
|
5
|
+
* locally-installed Claude Code CLI via the official Agent SDK.
|
|
6
|
+
*
|
|
7
|
+
* Users with a Claude Code subscription (Pro/Max/Team) get access to
|
|
8
|
+
* subsidized inference through GSD's UI — no API key required.
|
|
9
|
+
*
|
|
10
|
+
* TOS-compliant: uses Anthropic's official `@anthropic-ai/claude-agent-sdk`,
|
|
11
|
+
* never touches credentials, never offers a login flow.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
15
|
+
import { CLAUDE_CODE_MODELS } from "./models.js";
|
|
16
|
+
import { isClaudeCodeReady } from "./readiness.js";
|
|
17
|
+
import { streamViaClaudeCode } from "./stream-adapter.js";
|
|
18
|
+
|
|
19
|
+
export default function claudeCodeCli(pi: ExtensionAPI) {
|
|
20
|
+
pi.registerProvider("claude-code", {
|
|
21
|
+
authMode: "externalCli",
|
|
22
|
+
api: "anthropic-messages",
|
|
23
|
+
baseUrl: "local://claude-code",
|
|
24
|
+
isReady: isClaudeCodeReady,
|
|
25
|
+
streamSimple: streamViaClaudeCode,
|
|
26
|
+
models: CLAUDE_CODE_MODELS,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model definitions for the Claude Code CLI provider.
|
|
3
|
+
*
|
|
4
|
+
* Costs are zero because inference is covered by the user's Claude Code
|
|
5
|
+
* subscription. The SDK's `result` message still provides token counts
|
|
6
|
+
* for display in the TUI.
|
|
7
|
+
*
|
|
8
|
+
* Context windows and max tokens match the Anthropic API definitions
|
|
9
|
+
* in models.generated.ts.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const ZERO_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
13
|
+
|
|
14
|
+
export const CLAUDE_CODE_MODELS = [
|
|
15
|
+
{
|
|
16
|
+
id: "claude-opus-4-6",
|
|
17
|
+
name: "Claude Opus 4.6 (via Claude Code)",
|
|
18
|
+
reasoning: true,
|
|
19
|
+
input: ["text", "image"] as ("text" | "image")[],
|
|
20
|
+
cost: ZERO_COST,
|
|
21
|
+
contextWindow: 1_000_000,
|
|
22
|
+
maxTokens: 128_000,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "claude-sonnet-4-6",
|
|
26
|
+
name: "Claude Sonnet 4.6 (via Claude Code)",
|
|
27
|
+
reasoning: true,
|
|
28
|
+
input: ["text", "image"] as ("text" | "image")[],
|
|
29
|
+
cost: ZERO_COST,
|
|
30
|
+
contextWindow: 1_000_000,
|
|
31
|
+
maxTokens: 64_000,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "claude-haiku-4-5",
|
|
35
|
+
name: "Claude Haiku 4.5 (via Claude Code)",
|
|
36
|
+
reasoning: true,
|
|
37
|
+
input: ["text", "image"] as ("text" | "image")[],
|
|
38
|
+
cost: ZERO_COST,
|
|
39
|
+
contextWindow: 200_000,
|
|
40
|
+
maxTokens: 64_000,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-block mapping helpers and streaming state tracker.
|
|
3
|
+
*
|
|
4
|
+
* Translates the Claude Agent SDK's `BetaRawMessageStreamEvent` sequence
|
|
5
|
+
* into GSD's `AssistantMessageEvent` deltas for incremental TUI rendering.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
AssistantMessage,
|
|
10
|
+
AssistantMessageEvent,
|
|
11
|
+
ServerToolUseContent,
|
|
12
|
+
StopReason,
|
|
13
|
+
TextContent,
|
|
14
|
+
ThinkingContent,
|
|
15
|
+
ToolCall,
|
|
16
|
+
Usage,
|
|
17
|
+
WebSearchResultContent,
|
|
18
|
+
} from "@gsd/pi-ai";
|
|
19
|
+
import type { BetaContentBlock, BetaRawMessageStreamEvent, NonNullableUsage } from "./sdk-types.js";
|
|
20
|
+
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Content-block mapping helpers
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Convert a single BetaContentBlock to the corresponding GSD content type.
|
|
27
|
+
*/
|
|
28
|
+
export function mapContentBlock(
|
|
29
|
+
block: BetaContentBlock,
|
|
30
|
+
): TextContent | ThinkingContent | ToolCall | ServerToolUseContent | WebSearchResultContent {
|
|
31
|
+
switch (block.type) {
|
|
32
|
+
case "text":
|
|
33
|
+
return { type: "text", text: block.text } satisfies TextContent;
|
|
34
|
+
|
|
35
|
+
case "thinking":
|
|
36
|
+
return {
|
|
37
|
+
type: "thinking",
|
|
38
|
+
thinking: block.thinking,
|
|
39
|
+
...(block.signature ? { thinkingSignature: block.signature } : {}),
|
|
40
|
+
} satisfies ThinkingContent;
|
|
41
|
+
|
|
42
|
+
case "tool_use":
|
|
43
|
+
return {
|
|
44
|
+
type: "toolCall",
|
|
45
|
+
id: block.id,
|
|
46
|
+
name: block.name,
|
|
47
|
+
arguments: block.input,
|
|
48
|
+
} satisfies ToolCall;
|
|
49
|
+
|
|
50
|
+
case "server_tool_use":
|
|
51
|
+
return {
|
|
52
|
+
type: "serverToolUse",
|
|
53
|
+
id: block.id,
|
|
54
|
+
name: block.name,
|
|
55
|
+
input: block.input,
|
|
56
|
+
} satisfies ServerToolUseContent;
|
|
57
|
+
|
|
58
|
+
case "web_search_tool_result":
|
|
59
|
+
return {
|
|
60
|
+
type: "webSearchResult",
|
|
61
|
+
toolUseId: block.tool_use_id,
|
|
62
|
+
content: block.content,
|
|
63
|
+
} satisfies WebSearchResultContent;
|
|
64
|
+
|
|
65
|
+
default: {
|
|
66
|
+
const unknown = block as Record<string, unknown>;
|
|
67
|
+
return { type: "text", text: `[unknown content block: ${JSON.stringify(unknown)}]` };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function mapStopReason(reason: string | null): StopReason {
|
|
73
|
+
switch (reason) {
|
|
74
|
+
case "end_turn":
|
|
75
|
+
case "stop_sequence":
|
|
76
|
+
return "stop";
|
|
77
|
+
case "max_tokens":
|
|
78
|
+
return "length";
|
|
79
|
+
case "tool_use":
|
|
80
|
+
return "toolUse";
|
|
81
|
+
default:
|
|
82
|
+
return "stop";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Convert SDK usage + total_cost_usd into GSD's Usage shape.
|
|
88
|
+
*
|
|
89
|
+
* The SDK does not break cost down per-bucket, so all cost is
|
|
90
|
+
* attributed to `cost.total`.
|
|
91
|
+
*/
|
|
92
|
+
export function mapUsage(sdkUsage: NonNullableUsage, totalCostUsd: number): Usage {
|
|
93
|
+
return {
|
|
94
|
+
input: sdkUsage.input_tokens,
|
|
95
|
+
output: sdkUsage.output_tokens,
|
|
96
|
+
cacheRead: sdkUsage.cache_read_input_tokens,
|
|
97
|
+
cacheWrite: sdkUsage.cache_creation_input_tokens,
|
|
98
|
+
totalTokens:
|
|
99
|
+
sdkUsage.input_tokens +
|
|
100
|
+
sdkUsage.output_tokens +
|
|
101
|
+
sdkUsage.cache_read_input_tokens +
|
|
102
|
+
sdkUsage.cache_creation_input_tokens,
|
|
103
|
+
cost: {
|
|
104
|
+
input: 0,
|
|
105
|
+
output: 0,
|
|
106
|
+
cacheRead: 0,
|
|
107
|
+
cacheWrite: 0,
|
|
108
|
+
total: totalCostUsd,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Zero-cost usage constant
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
export const ZERO_USAGE: Usage = {
|
|
118
|
+
input: 0,
|
|
119
|
+
output: 0,
|
|
120
|
+
cacheRead: 0,
|
|
121
|
+
cacheWrite: 0,
|
|
122
|
+
totalTokens: 0,
|
|
123
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// Streaming partial-message state tracker
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Mutable accumulator that tracks the partial AssistantMessage being built
|
|
132
|
+
* from a sequence of stream_event messages. Produces AssistantMessageEvent
|
|
133
|
+
* deltas that the TUI can render incrementally.
|
|
134
|
+
*/
|
|
135
|
+
export class PartialMessageBuilder {
|
|
136
|
+
private partial: AssistantMessage;
|
|
137
|
+
/** Map from stream-event `index` to our content array index. */
|
|
138
|
+
private indexMap = new Map<number, number>();
|
|
139
|
+
/** Accumulated JSON input string per tool_use block (keyed by stream index). */
|
|
140
|
+
private toolJsonAccum = new Map<number, string>();
|
|
141
|
+
|
|
142
|
+
constructor(model: string) {
|
|
143
|
+
this.partial = {
|
|
144
|
+
role: "assistant",
|
|
145
|
+
content: [],
|
|
146
|
+
api: "anthropic-messages",
|
|
147
|
+
provider: "claude-code",
|
|
148
|
+
model,
|
|
149
|
+
usage: { ...ZERO_USAGE },
|
|
150
|
+
stopReason: "stop",
|
|
151
|
+
timestamp: Date.now(),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
get message(): AssistantMessage {
|
|
156
|
+
return this.partial;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Feed a BetaRawMessageStreamEvent and return the corresponding
|
|
161
|
+
* AssistantMessageEvent (or null if the event is not mapped).
|
|
162
|
+
*/
|
|
163
|
+
handleEvent(event: BetaRawMessageStreamEvent): AssistantMessageEvent | null {
|
|
164
|
+
const streamIndex = event.index ?? 0;
|
|
165
|
+
|
|
166
|
+
switch (event.type) {
|
|
167
|
+
// ---- Block start ----
|
|
168
|
+
case "content_block_start": {
|
|
169
|
+
const block = event.content_block;
|
|
170
|
+
if (!block) return null;
|
|
171
|
+
|
|
172
|
+
const contentIndex = this.partial.content.length;
|
|
173
|
+
this.indexMap.set(streamIndex, contentIndex);
|
|
174
|
+
|
|
175
|
+
if (block.type === "text") {
|
|
176
|
+
this.partial.content.push({ type: "text", text: "" });
|
|
177
|
+
return { type: "text_start", contentIndex, partial: this.partial };
|
|
178
|
+
}
|
|
179
|
+
if (block.type === "thinking") {
|
|
180
|
+
this.partial.content.push({ type: "thinking", thinking: "" });
|
|
181
|
+
return { type: "thinking_start", contentIndex, partial: this.partial };
|
|
182
|
+
}
|
|
183
|
+
if (block.type === "tool_use") {
|
|
184
|
+
this.toolJsonAccum.set(streamIndex, "");
|
|
185
|
+
this.partial.content.push({
|
|
186
|
+
type: "toolCall",
|
|
187
|
+
id: block.id,
|
|
188
|
+
name: block.name,
|
|
189
|
+
arguments: {},
|
|
190
|
+
});
|
|
191
|
+
return { type: "toolcall_start", contentIndex, partial: this.partial };
|
|
192
|
+
}
|
|
193
|
+
if (block.type === "server_tool_use") {
|
|
194
|
+
this.partial.content.push({
|
|
195
|
+
type: "serverToolUse",
|
|
196
|
+
id: block.id,
|
|
197
|
+
name: block.name,
|
|
198
|
+
input: block.input,
|
|
199
|
+
});
|
|
200
|
+
return { type: "server_tool_use", contentIndex, partial: this.partial };
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ---- Block delta ----
|
|
206
|
+
case "content_block_delta": {
|
|
207
|
+
const contentIndex = this.indexMap.get(streamIndex);
|
|
208
|
+
if (contentIndex === undefined) return null;
|
|
209
|
+
const delta = event.delta;
|
|
210
|
+
if (!delta) return null;
|
|
211
|
+
|
|
212
|
+
if (delta.type === "text_delta" && typeof delta.text === "string") {
|
|
213
|
+
const existing = this.partial.content[contentIndex] as TextContent;
|
|
214
|
+
existing.text += delta.text;
|
|
215
|
+
return { type: "text_delta", contentIndex, delta: delta.text, partial: this.partial };
|
|
216
|
+
}
|
|
217
|
+
if (delta.type === "thinking_delta" && typeof delta.thinking === "string") {
|
|
218
|
+
const existing = this.partial.content[contentIndex] as ThinkingContent;
|
|
219
|
+
existing.thinking += delta.thinking;
|
|
220
|
+
return { type: "thinking_delta", contentIndex, delta: delta.thinking, partial: this.partial };
|
|
221
|
+
}
|
|
222
|
+
if (delta.type === "input_json_delta" && typeof delta.partial_json === "string") {
|
|
223
|
+
const accum = (this.toolJsonAccum.get(streamIndex) ?? "") + delta.partial_json;
|
|
224
|
+
this.toolJsonAccum.set(streamIndex, accum);
|
|
225
|
+
return { type: "toolcall_delta", contentIndex, delta: delta.partial_json, partial: this.partial };
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ---- Block stop ----
|
|
231
|
+
case "content_block_stop": {
|
|
232
|
+
const contentIndex = this.indexMap.get(streamIndex);
|
|
233
|
+
if (contentIndex === undefined) return null;
|
|
234
|
+
const block = this.partial.content[contentIndex];
|
|
235
|
+
|
|
236
|
+
if (block.type === "text") {
|
|
237
|
+
return { type: "text_end", contentIndex, content: block.text, partial: this.partial };
|
|
238
|
+
}
|
|
239
|
+
if (block.type === "thinking") {
|
|
240
|
+
return { type: "thinking_end", contentIndex, content: block.thinking, partial: this.partial };
|
|
241
|
+
}
|
|
242
|
+
if (block.type === "toolCall") {
|
|
243
|
+
const jsonStr = this.toolJsonAccum.get(streamIndex) ?? "{}";
|
|
244
|
+
try {
|
|
245
|
+
block.arguments = JSON.parse(jsonStr);
|
|
246
|
+
} catch {
|
|
247
|
+
block.arguments = { _raw: jsonStr };
|
|
248
|
+
}
|
|
249
|
+
return { type: "toolcall_end", contentIndex, toolCall: block, partial: this.partial };
|
|
250
|
+
}
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
default:
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Readiness check for the Claude Code CLI provider.
|
|
3
|
+
*
|
|
4
|
+
* Verifies the `claude` binary is installed and responsive.
|
|
5
|
+
* Result is cached for 30 seconds to avoid shelling out on every
|
|
6
|
+
* model-availability check.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { execSync } from "node:child_process";
|
|
10
|
+
|
|
11
|
+
let cachedReady: boolean | null = null;
|
|
12
|
+
let lastCheckMs = 0;
|
|
13
|
+
const CHECK_INTERVAL_MS = 30_000;
|
|
14
|
+
|
|
15
|
+
export function isClaudeCodeReady(): boolean {
|
|
16
|
+
const now = Date.now();
|
|
17
|
+
if (cachedReady !== null && now - lastCheckMs < CHECK_INTERVAL_MS) {
|
|
18
|
+
return cachedReady;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
execSync("claude --version", { timeout: 5_000, stdio: "pipe" });
|
|
23
|
+
cachedReady = true;
|
|
24
|
+
} catch {
|
|
25
|
+
cachedReady = false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
lastCheckMs = now;
|
|
29
|
+
return cachedReady;
|
|
30
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight type mirrors for the Claude Agent SDK.
|
|
3
|
+
*
|
|
4
|
+
* These stubs allow the extension to compile without a hard dependency on
|
|
5
|
+
* `@anthropic-ai/claude-agent-sdk`. The real SDK is imported dynamically
|
|
6
|
+
* at runtime in stream-adapter.ts.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** UUID branded string from the SDK. */
|
|
10
|
+
export type UUID = string;
|
|
11
|
+
|
|
12
|
+
/** BetaMessage from the Anthropic SDK, as wrapped by SDKAssistantMessage. */
|
|
13
|
+
export interface BetaMessage {
|
|
14
|
+
id: string;
|
|
15
|
+
type: "message";
|
|
16
|
+
role: "assistant";
|
|
17
|
+
content: BetaContentBlock[];
|
|
18
|
+
model: string;
|
|
19
|
+
stop_reason: "end_turn" | "max_tokens" | "stop_sequence" | "tool_use" | null;
|
|
20
|
+
usage: { input_tokens: number; output_tokens: number };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type BetaContentBlock =
|
|
24
|
+
| { type: "text"; text: string }
|
|
25
|
+
| { type: "thinking"; thinking: string; signature?: string }
|
|
26
|
+
| { type: "tool_use"; id: string; name: string; input: Record<string, unknown> }
|
|
27
|
+
| { type: "server_tool_use"; id: string; name: string; input: unknown }
|
|
28
|
+
| { type: "web_search_tool_result"; tool_use_id: string; content: unknown };
|
|
29
|
+
|
|
30
|
+
/** Streaming event emitted when includePartialMessages is true. */
|
|
31
|
+
export interface BetaRawMessageStreamEvent {
|
|
32
|
+
type: string;
|
|
33
|
+
index?: number;
|
|
34
|
+
content_block?: BetaContentBlock;
|
|
35
|
+
delta?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface SDKAssistantMessage {
|
|
39
|
+
type: "assistant";
|
|
40
|
+
uuid: UUID;
|
|
41
|
+
session_id: string;
|
|
42
|
+
message: BetaMessage;
|
|
43
|
+
parent_tool_use_id: string | null;
|
|
44
|
+
error?: { type: string; message: string };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface SDKUserMessage {
|
|
48
|
+
type: "user";
|
|
49
|
+
uuid?: UUID;
|
|
50
|
+
session_id: string;
|
|
51
|
+
message: unknown;
|
|
52
|
+
parent_tool_use_id: string | null;
|
|
53
|
+
isSynthetic?: boolean;
|
|
54
|
+
tool_use_result?: unknown;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface SDKSystemMessage {
|
|
58
|
+
type: "system";
|
|
59
|
+
subtype: "init";
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface SDKStatusMessage {
|
|
64
|
+
type: "system";
|
|
65
|
+
subtype: "status";
|
|
66
|
+
status: "compacting" | null;
|
|
67
|
+
uuid: UUID;
|
|
68
|
+
session_id: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface SDKPartialAssistantMessage {
|
|
72
|
+
type: "stream_event";
|
|
73
|
+
event: BetaRawMessageStreamEvent;
|
|
74
|
+
parent_tool_use_id: string | null;
|
|
75
|
+
uuid: UUID;
|
|
76
|
+
session_id: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface SDKToolProgressMessage {
|
|
80
|
+
type: "tool_progress";
|
|
81
|
+
tool_use_id: string;
|
|
82
|
+
tool_name: string;
|
|
83
|
+
parent_tool_use_id: string | null;
|
|
84
|
+
elapsed_time_seconds: number;
|
|
85
|
+
task_id?: string;
|
|
86
|
+
uuid: UUID;
|
|
87
|
+
session_id: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface NonNullableUsage {
|
|
91
|
+
input_tokens: number;
|
|
92
|
+
output_tokens: number;
|
|
93
|
+
cache_read_input_tokens: number;
|
|
94
|
+
cache_creation_input_tokens: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type SDKResultMessage =
|
|
98
|
+
| {
|
|
99
|
+
type: "result";
|
|
100
|
+
subtype: "success";
|
|
101
|
+
uuid: UUID;
|
|
102
|
+
session_id: string;
|
|
103
|
+
duration_ms: number;
|
|
104
|
+
duration_api_ms: number;
|
|
105
|
+
is_error: boolean;
|
|
106
|
+
num_turns: number;
|
|
107
|
+
result: string;
|
|
108
|
+
stop_reason: string | null;
|
|
109
|
+
total_cost_usd: number;
|
|
110
|
+
usage: NonNullableUsage;
|
|
111
|
+
}
|
|
112
|
+
| {
|
|
113
|
+
type: "result";
|
|
114
|
+
subtype:
|
|
115
|
+
| "error_max_turns"
|
|
116
|
+
| "error_during_execution"
|
|
117
|
+
| "error_max_budget_usd"
|
|
118
|
+
| "error_max_structured_output_retries";
|
|
119
|
+
uuid: UUID;
|
|
120
|
+
session_id: string;
|
|
121
|
+
duration_ms: number;
|
|
122
|
+
duration_api_ms: number;
|
|
123
|
+
is_error: boolean;
|
|
124
|
+
num_turns: number;
|
|
125
|
+
stop_reason: string | null;
|
|
126
|
+
total_cost_usd: number;
|
|
127
|
+
usage: NonNullableUsage;
|
|
128
|
+
errors: string[];
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/** Catch-all for SDK message types we don't map. */
|
|
132
|
+
export interface SDKOtherMessage {
|
|
133
|
+
type: string;
|
|
134
|
+
[key: string]: unknown;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Union of all SDK message types this extension handles.
|
|
139
|
+
* Mirrors the real `SDKMessage` from `@anthropic-ai/claude-agent-sdk`.
|
|
140
|
+
*/
|
|
141
|
+
export type SDKMessage =
|
|
142
|
+
| SDKAssistantMessage
|
|
143
|
+
| SDKUserMessage
|
|
144
|
+
| SDKResultMessage
|
|
145
|
+
| SDKSystemMessage
|
|
146
|
+
| SDKStatusMessage
|
|
147
|
+
| SDKPartialAssistantMessage
|
|
148
|
+
| SDKToolProgressMessage
|
|
149
|
+
| SDKOtherMessage;
|