gsd-pi 2.52.0 → 2.53.0-dev.a67436f
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 +55 -32
- package/dist/headless-query.js +1 -1
- package/dist/headless-ui.d.ts +2 -2
- package/dist/headless-ui.js +18 -15
- package/dist/headless.d.ts +11 -0
- package/dist/headless.js +178 -38
- package/dist/resources/extensions/get-secrets-from-user.js +7 -0
- package/dist/resources/extensions/gsd/auto/phases.js +28 -8
- package/dist/resources/extensions/gsd/auto-dispatch.js +5 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +70 -14
- package/dist/resources/extensions/gsd/auto.js +22 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +4 -10
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
- package/dist/resources/extensions/gsd/git-service.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +4 -3
- package/dist/resources/extensions/gsd/markdown-renderer.js +5 -4
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +18 -2
- package/dist/resources/extensions/gsd/preferences-types.js +1 -1
- package/dist/resources/extensions/gsd/state.js +18 -29
- package/dist/resources/extensions/gsd/status-guards.js +12 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -3
- package/dist/resources/extensions/gsd/tools/complete-slice.js +4 -3
- package/dist/resources/extensions/gsd/tools/complete-task.js +4 -3
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +4 -14
- package/dist/resources/extensions/gsd/tools/plan-slice.js +4 -14
- package/dist/resources/extensions/gsd/tools/plan-task.js +4 -14
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +6 -7
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +4 -3
- package/dist/resources/extensions/gsd/tools/reopen-task.js +5 -4
- package/dist/resources/extensions/gsd/tools/replan-slice.js +5 -6
- package/dist/resources/extensions/gsd/validation.js +21 -0
- package/dist/resources/extensions/shared/rtk.js +14 -4
- package/dist/rtk.js +3 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -20
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- 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/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/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 +2 -2
- 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 +20 -20
- package/dist/web/standalone/.next/server/chunks/2229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-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/4024.87fd909ae0110f50.js +9 -0
- 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-b950e4e384cc62b3.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/.next/static/chunks/{webpack-024d82be84800e52.js → webpack-bca0e732db0dcec3.js} +1 -1
- 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 +1 -1
- package/packages/mcp-server/README.md +6 -6
- package/packages/mcp-server/package.json +14 -4
- package/packages/mcp-server/src/cli.ts +1 -1
- package/packages/mcp-server/src/index.ts +1 -1
- package/packages/mcp-server/src/mcp-server.test.ts +2 -2
- package/packages/mcp-server/src/session-manager.ts +2 -2
- package/packages/mcp-server/src/types.ts +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/rpc-client/README.md +125 -0
- package/packages/rpc-client/examples/basic-usage.ts +13 -0
- package/packages/rpc-client/package.json +17 -3
- package/packages/rpc-client/src/index.ts +10 -0
- package/packages/rpc-client/src/jsonl.ts +64 -0
- package/packages/rpc-client/src/rpc-client.test.ts +568 -0
- package/packages/rpc-client/src/rpc-client.ts +666 -0
- package/packages/rpc-client/src/rpc-types.ts +399 -0
- package/packages/rpc-client/tsconfig.examples.json +17 -0
- package/packages/rpc-client/tsconfig.json +24 -0
- package/pkg/package.json +1 -1
- package/scripts/ensure-workspace-builds.cjs +36 -8
- package/src/resources/extensions/get-secrets-from-user.ts +8 -0
- package/src/resources/extensions/gsd/auto/phases.ts +38 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +6 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +73 -14
- package/src/resources/extensions/gsd/auto.ts +21 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +4 -11
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +3 -3
- package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
- package/src/resources/extensions/gsd/git-service.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +4 -3
- package/src/resources/extensions/gsd/markdown-renderer.ts +5 -4
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -1
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/state.ts +18 -29
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/tests/active-milestone-id-guard.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/auto-stale-lock-self-kill.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +64 -30
- package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +277 -0
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/rate-limit-model-fallback.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +9 -8
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +124 -0
- package/src/resources/extensions/gsd/tests/validation.test.ts +72 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +4 -3
- package/src/resources/extensions/gsd/tools/complete-slice.ts +4 -3
- package/src/resources/extensions/gsd/tools/complete-task.ts +4 -3
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +4 -16
- package/src/resources/extensions/gsd/tools/plan-slice.ts +4 -16
- package/src/resources/extensions/gsd/tools/plan-task.ts +4 -16
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +6 -7
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +4 -3
- package/src/resources/extensions/gsd/tools/reopen-task.ts +5 -4
- package/src/resources/extensions/gsd/tools/replan-slice.ts +5 -7
- package/src/resources/extensions/gsd/validation.ts +23 -0
- package/src/resources/extensions/shared/rtk.ts +22 -4
- package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-fbecd1237e2d6d1f.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/{vlgS2rkXjxeKhgXhdp4lh → YO-PWFRitlHM-L-dotlmm}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vlgS2rkXjxeKhgXhdp4lh → YO-PWFRitlHM-L-dotlmm}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC protocol types for headless operation.
|
|
3
|
+
*
|
|
4
|
+
* Commands are sent as JSON lines on stdin.
|
|
5
|
+
* Responses and events are emitted as JSON lines on stdout.
|
|
6
|
+
*
|
|
7
|
+
* This file is self-contained — all types that were previously imported from
|
|
8
|
+
* internal packages are inlined so that this package has zero internal
|
|
9
|
+
* dependencies.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Inlined types (originally from internal packages)
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
/** Thinking budget level (inlined from agent-core) */
|
|
17
|
+
export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
18
|
+
|
|
19
|
+
/** Image attachment (inlined from pi-ai) */
|
|
20
|
+
export interface ImageContent {
|
|
21
|
+
type: "image";
|
|
22
|
+
data: string; // base64 encoded image data
|
|
23
|
+
mimeType: string; // e.g., "image/jpeg", "image/png"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Model descriptor — opaque for SDK consumers */
|
|
27
|
+
export interface ModelInfo {
|
|
28
|
+
provider: string;
|
|
29
|
+
id: string;
|
|
30
|
+
contextWindow?: number;
|
|
31
|
+
reasoning?: boolean;
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Session statistics (from agent-session.ts) */
|
|
36
|
+
export interface SessionStats {
|
|
37
|
+
sessionFile: string | undefined;
|
|
38
|
+
sessionId: string;
|
|
39
|
+
userMessages: number;
|
|
40
|
+
assistantMessages: number;
|
|
41
|
+
toolCalls: number;
|
|
42
|
+
toolResults: number;
|
|
43
|
+
totalMessages: number;
|
|
44
|
+
tokens: {
|
|
45
|
+
input: number;
|
|
46
|
+
output: number;
|
|
47
|
+
cacheRead: number;
|
|
48
|
+
cacheWrite: number;
|
|
49
|
+
total: number;
|
|
50
|
+
};
|
|
51
|
+
cost: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Bash command result (from bash-executor.ts) */
|
|
55
|
+
export interface BashResult {
|
|
56
|
+
/** Combined stdout + stderr output (sanitized, possibly truncated) */
|
|
57
|
+
output: string;
|
|
58
|
+
/** Process exit code (undefined if killed/cancelled) */
|
|
59
|
+
exitCode: number | undefined;
|
|
60
|
+
/** Whether the command was cancelled via signal */
|
|
61
|
+
cancelled: boolean;
|
|
62
|
+
/** Whether the output was truncated */
|
|
63
|
+
truncated: boolean;
|
|
64
|
+
/** Path to temp file containing full output (if output exceeded truncation threshold) */
|
|
65
|
+
fullOutputPath?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Compaction result (from compaction.ts) */
|
|
69
|
+
export interface CompactionResult<T = unknown> {
|
|
70
|
+
summary: string;
|
|
71
|
+
firstKeptEntryId: string;
|
|
72
|
+
tokensBefore: number;
|
|
73
|
+
/** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */
|
|
74
|
+
details?: T;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// RPC Protocol Versioning
|
|
79
|
+
// ============================================================================
|
|
80
|
+
|
|
81
|
+
/** Supported protocol versions. v1 is the implicit default; v2 requires an init handshake. */
|
|
82
|
+
export type RpcProtocolVersion = 1 | 2;
|
|
83
|
+
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// RPC Commands (stdin)
|
|
86
|
+
// ============================================================================
|
|
87
|
+
|
|
88
|
+
export type RpcCommand =
|
|
89
|
+
// Prompting
|
|
90
|
+
| { id?: string; type: "prompt"; message: string; images?: ImageContent[]; streamingBehavior?: "steer" | "followUp" }
|
|
91
|
+
| { id?: string; type: "steer"; message: string; images?: ImageContent[] }
|
|
92
|
+
| { id?: string; type: "follow_up"; message: string; images?: ImageContent[] }
|
|
93
|
+
| { id?: string; type: "abort" }
|
|
94
|
+
| { id?: string; type: "new_session"; parentSession?: string }
|
|
95
|
+
|
|
96
|
+
// State
|
|
97
|
+
| { id?: string; type: "get_state" }
|
|
98
|
+
|
|
99
|
+
// Model
|
|
100
|
+
| { id?: string; type: "set_model"; provider: string; modelId: string }
|
|
101
|
+
| { id?: string; type: "cycle_model" }
|
|
102
|
+
| { id?: string; type: "get_available_models" }
|
|
103
|
+
|
|
104
|
+
// Thinking
|
|
105
|
+
| { id?: string; type: "set_thinking_level"; level: ThinkingLevel }
|
|
106
|
+
| { id?: string; type: "cycle_thinking_level" }
|
|
107
|
+
|
|
108
|
+
// Queue modes
|
|
109
|
+
| { id?: string; type: "set_steering_mode"; mode: "all" | "one-at-a-time" }
|
|
110
|
+
| { id?: string; type: "set_follow_up_mode"; mode: "all" | "one-at-a-time" }
|
|
111
|
+
|
|
112
|
+
// Compaction
|
|
113
|
+
| { id?: string; type: "compact"; customInstructions?: string }
|
|
114
|
+
| { id?: string; type: "set_auto_compaction"; enabled: boolean }
|
|
115
|
+
|
|
116
|
+
// Retry
|
|
117
|
+
| { id?: string; type: "set_auto_retry"; enabled: boolean }
|
|
118
|
+
| { id?: string; type: "abort_retry" }
|
|
119
|
+
|
|
120
|
+
// Bash
|
|
121
|
+
| { id?: string; type: "bash"; command: string }
|
|
122
|
+
| { id?: string; type: "abort_bash" }
|
|
123
|
+
|
|
124
|
+
// Session
|
|
125
|
+
| { id?: string; type: "get_session_stats" }
|
|
126
|
+
| { id?: string; type: "export_html"; outputPath?: string }
|
|
127
|
+
| { id?: string; type: "switch_session"; sessionPath: string }
|
|
128
|
+
| { id?: string; type: "fork"; entryId: string }
|
|
129
|
+
| { id?: string; type: "get_fork_messages" }
|
|
130
|
+
| { id?: string; type: "get_last_assistant_text" }
|
|
131
|
+
| { id?: string; type: "set_session_name"; name: string }
|
|
132
|
+
|
|
133
|
+
// Messages
|
|
134
|
+
| { id?: string; type: "get_messages" }
|
|
135
|
+
|
|
136
|
+
// Commands (available for invocation via prompt)
|
|
137
|
+
| { id?: string; type: "get_commands" }
|
|
138
|
+
|
|
139
|
+
// Bridge-hosted native terminal
|
|
140
|
+
| { id?: string; type: "terminal_input"; data: string }
|
|
141
|
+
| { id?: string; type: "terminal_resize"; cols: number; rows: number }
|
|
142
|
+
| { id?: string; type: "terminal_redraw" }
|
|
143
|
+
|
|
144
|
+
// v2 Protocol
|
|
145
|
+
| { id?: string; type: "init"; protocolVersion: 2; clientId?: string }
|
|
146
|
+
| { id?: string; type: "shutdown"; graceful?: boolean }
|
|
147
|
+
| { id?: string; type: "subscribe"; events: string[] };
|
|
148
|
+
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// RPC Slash Command (for get_commands response)
|
|
151
|
+
// ============================================================================
|
|
152
|
+
|
|
153
|
+
/** A command available for invocation via prompt */
|
|
154
|
+
export interface RpcSlashCommand {
|
|
155
|
+
/** Command name (without leading slash) */
|
|
156
|
+
name: string;
|
|
157
|
+
/** Human-readable description */
|
|
158
|
+
description?: string;
|
|
159
|
+
/** What kind of command this is */
|
|
160
|
+
source: "extension" | "prompt" | "skill";
|
|
161
|
+
/** Where the command was loaded from (undefined for extensions) */
|
|
162
|
+
location?: "user" | "project" | "path";
|
|
163
|
+
/** File path to the command source */
|
|
164
|
+
path?: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ============================================================================
|
|
168
|
+
// RPC State
|
|
169
|
+
// ============================================================================
|
|
170
|
+
|
|
171
|
+
export interface RpcSessionState {
|
|
172
|
+
model?: ModelInfo;
|
|
173
|
+
thinkingLevel: ThinkingLevel;
|
|
174
|
+
isStreaming: boolean;
|
|
175
|
+
isCompacting: boolean;
|
|
176
|
+
steeringMode: "all" | "one-at-a-time";
|
|
177
|
+
followUpMode: "all" | "one-at-a-time";
|
|
178
|
+
sessionFile?: string;
|
|
179
|
+
sessionId: string;
|
|
180
|
+
sessionName?: string;
|
|
181
|
+
autoCompactionEnabled: boolean;
|
|
182
|
+
autoRetryEnabled: boolean;
|
|
183
|
+
retryInProgress: boolean;
|
|
184
|
+
retryAttempt: number;
|
|
185
|
+
messageCount: number;
|
|
186
|
+
pendingMessageCount: number;
|
|
187
|
+
/** Whether extension loading has completed. Commands from `get_commands` may be incomplete until true. */
|
|
188
|
+
extensionsReady: boolean;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ============================================================================
|
|
192
|
+
// RPC Responses (stdout)
|
|
193
|
+
// ============================================================================
|
|
194
|
+
|
|
195
|
+
// Success responses with data
|
|
196
|
+
export type RpcResponse =
|
|
197
|
+
// Prompting (async - events follow)
|
|
198
|
+
| { id?: string; type: "response"; command: "prompt"; success: true; runId?: string }
|
|
199
|
+
| { id?: string; type: "response"; command: "steer"; success: true; runId?: string }
|
|
200
|
+
| { id?: string; type: "response"; command: "follow_up"; success: true; runId?: string }
|
|
201
|
+
| { id?: string; type: "response"; command: "abort"; success: true }
|
|
202
|
+
| { id?: string; type: "response"; command: "new_session"; success: true; data: { cancelled: boolean } }
|
|
203
|
+
|
|
204
|
+
// State
|
|
205
|
+
| { id?: string; type: "response"; command: "get_state"; success: true; data: RpcSessionState }
|
|
206
|
+
|
|
207
|
+
// Model
|
|
208
|
+
| {
|
|
209
|
+
id?: string;
|
|
210
|
+
type: "response";
|
|
211
|
+
command: "set_model";
|
|
212
|
+
success: true;
|
|
213
|
+
data: ModelInfo;
|
|
214
|
+
}
|
|
215
|
+
| {
|
|
216
|
+
id?: string;
|
|
217
|
+
type: "response";
|
|
218
|
+
command: "cycle_model";
|
|
219
|
+
success: true;
|
|
220
|
+
data: { model: ModelInfo; thinkingLevel: ThinkingLevel; isScoped: boolean } | null;
|
|
221
|
+
}
|
|
222
|
+
| {
|
|
223
|
+
id?: string;
|
|
224
|
+
type: "response";
|
|
225
|
+
command: "get_available_models";
|
|
226
|
+
success: true;
|
|
227
|
+
data: { models: ModelInfo[] };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Thinking
|
|
231
|
+
| { id?: string; type: "response"; command: "set_thinking_level"; success: true }
|
|
232
|
+
| {
|
|
233
|
+
id?: string;
|
|
234
|
+
type: "response";
|
|
235
|
+
command: "cycle_thinking_level";
|
|
236
|
+
success: true;
|
|
237
|
+
data: { level: ThinkingLevel } | null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Queue modes
|
|
241
|
+
| { id?: string; type: "response"; command: "set_steering_mode"; success: true }
|
|
242
|
+
| { id?: string; type: "response"; command: "set_follow_up_mode"; success: true }
|
|
243
|
+
|
|
244
|
+
// Compaction
|
|
245
|
+
| { id?: string; type: "response"; command: "compact"; success: true; data: CompactionResult }
|
|
246
|
+
| { id?: string; type: "response"; command: "set_auto_compaction"; success: true }
|
|
247
|
+
|
|
248
|
+
// Retry
|
|
249
|
+
| { id?: string; type: "response"; command: "set_auto_retry"; success: true }
|
|
250
|
+
| { id?: string; type: "response"; command: "abort_retry"; success: true }
|
|
251
|
+
|
|
252
|
+
// Bash
|
|
253
|
+
| { id?: string; type: "response"; command: "bash"; success: true; data: BashResult }
|
|
254
|
+
| { id?: string; type: "response"; command: "abort_bash"; success: true }
|
|
255
|
+
|
|
256
|
+
// Session
|
|
257
|
+
| { id?: string; type: "response"; command: "get_session_stats"; success: true; data: SessionStats }
|
|
258
|
+
| { id?: string; type: "response"; command: "export_html"; success: true; data: { path: string } }
|
|
259
|
+
| { id?: string; type: "response"; command: "switch_session"; success: true; data: { cancelled: boolean } }
|
|
260
|
+
| { id?: string; type: "response"; command: "fork"; success: true; data: { text: string; cancelled: boolean } }
|
|
261
|
+
| {
|
|
262
|
+
id?: string;
|
|
263
|
+
type: "response";
|
|
264
|
+
command: "get_fork_messages";
|
|
265
|
+
success: true;
|
|
266
|
+
data: { messages: Array<{ entryId: string; text: string }> };
|
|
267
|
+
}
|
|
268
|
+
| {
|
|
269
|
+
id?: string;
|
|
270
|
+
type: "response";
|
|
271
|
+
command: "get_last_assistant_text";
|
|
272
|
+
success: true;
|
|
273
|
+
data: { text: string | null };
|
|
274
|
+
}
|
|
275
|
+
| { id?: string; type: "response"; command: "set_session_name"; success: true }
|
|
276
|
+
|
|
277
|
+
// Messages — AgentMessage is opaque for SDK consumers
|
|
278
|
+
| { id?: string; type: "response"; command: "get_messages"; success: true; data: { messages: unknown[] } }
|
|
279
|
+
|
|
280
|
+
// Commands
|
|
281
|
+
| {
|
|
282
|
+
id?: string;
|
|
283
|
+
type: "response";
|
|
284
|
+
command: "get_commands";
|
|
285
|
+
success: true;
|
|
286
|
+
data: { commands: RpcSlashCommand[] };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Bridge-hosted native terminal
|
|
290
|
+
| { id?: string; type: "response"; command: "terminal_input"; success: true }
|
|
291
|
+
| { id?: string; type: "response"; command: "terminal_resize"; success: true }
|
|
292
|
+
| { id?: string; type: "response"; command: "terminal_redraw"; success: true }
|
|
293
|
+
|
|
294
|
+
// v2 Protocol
|
|
295
|
+
| { id?: string; type: "response"; command: "init"; success: true; data: RpcInitResult }
|
|
296
|
+
| { id?: string; type: "response"; command: "shutdown"; success: true }
|
|
297
|
+
| { id?: string; type: "response"; command: "subscribe"; success: true }
|
|
298
|
+
|
|
299
|
+
// Error response (any command can fail)
|
|
300
|
+
| { id?: string; type: "response"; command: string; success: false; error: string };
|
|
301
|
+
|
|
302
|
+
// ============================================================================
|
|
303
|
+
// v2 Protocol Types
|
|
304
|
+
// ============================================================================
|
|
305
|
+
|
|
306
|
+
/** Result of the init handshake (v2 only) */
|
|
307
|
+
export interface RpcInitResult {
|
|
308
|
+
protocolVersion: 2;
|
|
309
|
+
sessionId: string;
|
|
310
|
+
capabilities: {
|
|
311
|
+
events: string[];
|
|
312
|
+
commands: string[];
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** v2 execution_complete event — emitted when a prompt/steer/follow_up finishes */
|
|
317
|
+
export interface RpcExecutionCompleteEvent {
|
|
318
|
+
type: "execution_complete";
|
|
319
|
+
runId: string;
|
|
320
|
+
status: "completed" | "error" | "cancelled";
|
|
321
|
+
reason?: string;
|
|
322
|
+
stats: SessionStats;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** v2 cost_update event — emitted per-turn with running cost data */
|
|
326
|
+
export interface RpcCostUpdateEvent {
|
|
327
|
+
type: "cost_update";
|
|
328
|
+
runId: string;
|
|
329
|
+
turnCost: number;
|
|
330
|
+
cumulativeCost: number;
|
|
331
|
+
tokens: {
|
|
332
|
+
input: number;
|
|
333
|
+
output: number;
|
|
334
|
+
cacheRead: number;
|
|
335
|
+
cacheWrite: number;
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** Discriminated union of all v2-only event types */
|
|
340
|
+
export type RpcV2Event = RpcExecutionCompleteEvent | RpcCostUpdateEvent;
|
|
341
|
+
|
|
342
|
+
// ============================================================================
|
|
343
|
+
// Extension UI Events (stdout)
|
|
344
|
+
// ============================================================================
|
|
345
|
+
|
|
346
|
+
/** Emitted when an extension needs user input */
|
|
347
|
+
export type RpcExtensionUIRequest =
|
|
348
|
+
| { type: "extension_ui_request"; id: string; method: "select"; title: string; options: string[]; timeout?: number; allowMultiple?: boolean }
|
|
349
|
+
| { type: "extension_ui_request"; id: string; method: "confirm"; title: string; message: string; timeout?: number }
|
|
350
|
+
| {
|
|
351
|
+
type: "extension_ui_request";
|
|
352
|
+
id: string;
|
|
353
|
+
method: "input";
|
|
354
|
+
title: string;
|
|
355
|
+
placeholder?: string;
|
|
356
|
+
timeout?: number;
|
|
357
|
+
}
|
|
358
|
+
| { type: "extension_ui_request"; id: string; method: "editor"; title: string; prefill?: string }
|
|
359
|
+
| {
|
|
360
|
+
type: "extension_ui_request";
|
|
361
|
+
id: string;
|
|
362
|
+
method: "notify";
|
|
363
|
+
message: string;
|
|
364
|
+
notifyType?: "info" | "warning" | "error";
|
|
365
|
+
}
|
|
366
|
+
| {
|
|
367
|
+
type: "extension_ui_request";
|
|
368
|
+
id: string;
|
|
369
|
+
method: "setStatus";
|
|
370
|
+
statusKey: string;
|
|
371
|
+
statusText: string | undefined;
|
|
372
|
+
}
|
|
373
|
+
| {
|
|
374
|
+
type: "extension_ui_request";
|
|
375
|
+
id: string;
|
|
376
|
+
method: "setWidget";
|
|
377
|
+
widgetKey: string;
|
|
378
|
+
widgetLines: string[] | undefined;
|
|
379
|
+
widgetPlacement?: "aboveEditor" | "belowEditor";
|
|
380
|
+
}
|
|
381
|
+
| { type: "extension_ui_request"; id: string; method: "setTitle"; title: string }
|
|
382
|
+
| { type: "extension_ui_request"; id: string; method: "set_editor_text"; text: string };
|
|
383
|
+
|
|
384
|
+
// ============================================================================
|
|
385
|
+
// Extension UI Commands (stdin)
|
|
386
|
+
// ============================================================================
|
|
387
|
+
|
|
388
|
+
/** Response to an extension UI request */
|
|
389
|
+
export type RpcExtensionUIResponse =
|
|
390
|
+
| { type: "extension_ui_response"; id: string; value: string }
|
|
391
|
+
| { type: "extension_ui_response"; id: string; values: string[] }
|
|
392
|
+
| { type: "extension_ui_response"; id: string; confirmed: boolean }
|
|
393
|
+
| { type: "extension_ui_response"; id: string; cancelled: true };
|
|
394
|
+
|
|
395
|
+
// ============================================================================
|
|
396
|
+
// Helper type for extracting command types
|
|
397
|
+
// ============================================================================
|
|
398
|
+
|
|
399
|
+
export type RpcCommandType = RpcCommand["type"];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"module": "Node16",
|
|
5
|
+
"lib": ["ES2024"],
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"moduleResolution": "Node16",
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"types": ["node"],
|
|
12
|
+
"paths": {
|
|
13
|
+
"@gsd-build/rpc-client": ["./src/index.ts"]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"include": ["examples/**/*.ts"]
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"module": "Node16",
|
|
5
|
+
"lib": ["ES2024"],
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"sourceMap": true,
|
|
13
|
+
"inlineSources": true,
|
|
14
|
+
"inlineSourceMap": false,
|
|
15
|
+
"moduleResolution": "Node16",
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"allowImportingTsExtensions": false,
|
|
18
|
+
"types": ["node"],
|
|
19
|
+
"outDir": "./dist",
|
|
20
|
+
"rootDir": "./src"
|
|
21
|
+
},
|
|
22
|
+
"include": ["src/**/*.ts"],
|
|
23
|
+
"exclude": ["node_modules", "dist", "**/*.d.ts", "src/**/*.d.ts"]
|
|
24
|
+
}
|
package/pkg/package.json
CHANGED
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
* ensure-workspace-builds.cjs
|
|
4
4
|
*
|
|
5
5
|
* Checks whether workspace packages have been compiled (dist/ exists with
|
|
6
|
-
* index.js)
|
|
6
|
+
* index.js) and that the build is not stale (no src/ file newer than dist/).
|
|
7
|
+
* If any are missing or stale, runs the build for those packages.
|
|
7
8
|
*
|
|
8
9
|
* Designed for the postinstall hook so that `npm install` in a fresh clone
|
|
9
|
-
* produces a working runtime without a manual `npm run build` step.
|
|
10
|
+
* produces a working runtime without a manual `npm run build` step. Also
|
|
11
|
+
* catches the common case where `git pull` updates package sources but the
|
|
12
|
+
* old dist/ remains, causing TypeScript type errors.
|
|
10
13
|
*
|
|
11
14
|
* Skipped in CI (where the full build pipeline handles this) and when
|
|
12
15
|
* installing as an end-user dependency (no packages/ directory).
|
|
13
16
|
*/
|
|
14
|
-
const { existsSync } = require('fs')
|
|
17
|
+
const { existsSync, statSync, readdirSync } = require('fs')
|
|
15
18
|
const { resolve, join } = require('path')
|
|
16
19
|
const { execSync } = require('child_process')
|
|
17
20
|
|
|
@@ -34,19 +37,44 @@ const WORKSPACE_PACKAGES = [
|
|
|
34
37
|
'pi-coding-agent',
|
|
35
38
|
]
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Returns the most recent mtime (ms) of any .ts file under dir, recursively.
|
|
42
|
+
* Returns 0 if no .ts files found.
|
|
43
|
+
*/
|
|
44
|
+
function newestSrcMtime(dir) {
|
|
45
|
+
if (!existsSync(dir)) return 0
|
|
46
|
+
let newest = 0
|
|
47
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
48
|
+
if (entry.name === 'node_modules') continue
|
|
49
|
+
const full = join(dir, entry.name)
|
|
50
|
+
if (entry.isDirectory()) {
|
|
51
|
+
newest = Math.max(newest, newestSrcMtime(full))
|
|
52
|
+
} else if (entry.isFile() && entry.name.endsWith('.ts')) {
|
|
53
|
+
newest = Math.max(newest, statSync(full).mtimeMs)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return newest
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const stale = []
|
|
38
60
|
for (const pkg of WORKSPACE_PACKAGES) {
|
|
39
61
|
const distIndex = join(packagesDir, pkg, 'dist', 'index.js')
|
|
40
62
|
if (!existsSync(distIndex)) {
|
|
41
|
-
|
|
63
|
+
stale.push(pkg)
|
|
64
|
+
continue
|
|
65
|
+
}
|
|
66
|
+
const distMtime = statSync(distIndex).mtimeMs
|
|
67
|
+
const srcMtime = newestSrcMtime(join(packagesDir, pkg, 'src'))
|
|
68
|
+
if (srcMtime > distMtime) {
|
|
69
|
+
stale.push(pkg)
|
|
42
70
|
}
|
|
43
71
|
}
|
|
44
72
|
|
|
45
|
-
if (
|
|
73
|
+
if (stale.length === 0) process.exit(0)
|
|
46
74
|
|
|
47
|
-
process.stderr.write(` Building ${
|
|
75
|
+
process.stderr.write(` Building ${stale.length} workspace package(s) with stale or missing dist/: ${stale.join(', ')}\n`)
|
|
48
76
|
|
|
49
|
-
for (const pkg of
|
|
77
|
+
for (const pkg of stale) {
|
|
50
78
|
const pkgDir = join(packagesDir, pkg)
|
|
51
79
|
try {
|
|
52
80
|
execSync('npm run build', { cwd: pkgDir, stdio: 'pipe' })
|
|
@@ -47,6 +47,12 @@ function shellEscapeSingle(value: string): string {
|
|
|
47
47
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
function hydrateProcessEnv(key: string, value: string): void {
|
|
51
|
+
// Make newly collected secrets immediately visible to the current session.
|
|
52
|
+
// Some extensions read process.env directly and do not reload .env on every call.
|
|
53
|
+
process.env[key] = value;
|
|
54
|
+
}
|
|
55
|
+
|
|
50
56
|
async function writeEnvKey(filePath: string, key: string, value: string): Promise<void> {
|
|
51
57
|
let content = "";
|
|
52
58
|
try {
|
|
@@ -312,6 +318,7 @@ async function applySecrets(
|
|
|
312
318
|
try {
|
|
313
319
|
await writeEnvKey(opts.envFilePath, key, value);
|
|
314
320
|
applied.push(key);
|
|
321
|
+
hydrateProcessEnv(key, value);
|
|
315
322
|
} catch (err: any) {
|
|
316
323
|
errors.push(`${key}: ${err.message}`);
|
|
317
324
|
}
|
|
@@ -330,6 +337,7 @@ async function applySecrets(
|
|
|
330
337
|
errors.push(`${key}: ${result.stderr.slice(0, 200)}`);
|
|
331
338
|
} else {
|
|
332
339
|
applied.push(key);
|
|
340
|
+
hydrateProcessEnv(key, value);
|
|
333
341
|
}
|
|
334
342
|
} catch (err: any) {
|
|
335
343
|
errors.push(`${key}: ${err.message}`);
|
|
@@ -36,6 +36,15 @@ import { writeUnitRuntimeRecord } from "../unit-runtime.js";
|
|
|
36
36
|
|
|
37
37
|
// ─── generateMilestoneReport ──────────────────────────────────────────────────
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the base path for milestone reports.
|
|
41
|
+
* Prefers originalBasePath (project root) over basePath (which may be a worktree).
|
|
42
|
+
* Exported for testing as _resolveReportBasePath.
|
|
43
|
+
*/
|
|
44
|
+
export function _resolveReportBasePath(s: Pick<AutoSession, "originalBasePath" | "basePath">): string {
|
|
45
|
+
return s.originalBasePath || s.basePath;
|
|
46
|
+
}
|
|
47
|
+
|
|
39
48
|
/**
|
|
40
49
|
* Generate and write an HTML milestone report snapshot.
|
|
41
50
|
* Extracted from the milestone-transition block in autoLoop.
|
|
@@ -50,13 +59,15 @@ async function generateMilestoneReport(
|
|
|
50
59
|
const { writeReportSnapshot } = await importExtensionModule<typeof import("../reports.js")>(import.meta.url, "../reports.js");
|
|
51
60
|
const { basename } = await import("node:path");
|
|
52
61
|
|
|
53
|
-
const
|
|
62
|
+
const reportBasePath = _resolveReportBasePath(s);
|
|
63
|
+
|
|
64
|
+
const snapData = await loadVisualizerData(reportBasePath);
|
|
54
65
|
const completedMs = snapData.milestones.find(
|
|
55
66
|
(m: { id: string }) => m.id === milestoneId,
|
|
56
67
|
);
|
|
57
68
|
const msTitle = completedMs?.title ?? milestoneId;
|
|
58
69
|
const gsdVersion = process.env.GSD_VERSION ?? "0.0.0";
|
|
59
|
-
const projName = basename(
|
|
70
|
+
const projName = basename(reportBasePath);
|
|
60
71
|
const doneSlices = snapData.milestones.reduce(
|
|
61
72
|
(acc: number, m: { slices: { done: boolean }[] }) =>
|
|
62
73
|
acc + m.slices.filter((sl: { done: boolean }) => sl.done).length,
|
|
@@ -67,10 +78,10 @@ async function generateMilestoneReport(
|
|
|
67
78
|
0,
|
|
68
79
|
);
|
|
69
80
|
const outPath = writeReportSnapshot({
|
|
70
|
-
basePath:
|
|
81
|
+
basePath: reportBasePath,
|
|
71
82
|
html: generateHtmlReport(snapData, {
|
|
72
83
|
projectName: projName,
|
|
73
|
-
projectPath:
|
|
84
|
+
projectPath: reportBasePath,
|
|
74
85
|
gsdVersion,
|
|
75
86
|
milestoneId,
|
|
76
87
|
indexRelPath: "index.html",
|
|
@@ -79,7 +90,7 @@ async function generateMilestoneReport(
|
|
|
79
90
|
milestoneTitle: msTitle,
|
|
80
91
|
kind: "milestone",
|
|
81
92
|
projectName: projName,
|
|
82
|
-
projectPath:
|
|
93
|
+
projectPath: reportBasePath,
|
|
83
94
|
gsdVersion,
|
|
84
95
|
totalCost: snapData.totals?.cost ?? 0,
|
|
85
96
|
totalTokens: snapData.totals?.tokens.total ?? 0,
|
|
@@ -250,8 +261,14 @@ export async function runPreDispatch(
|
|
|
250
261
|
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
251
262
|
return { action: "break", reason: "merge-conflict" };
|
|
252
263
|
}
|
|
253
|
-
// Non-conflict merge errors —
|
|
254
|
-
|
|
264
|
+
// Non-conflict merge errors — stop auto to avoid advancing with unmerged work
|
|
265
|
+
logError("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId!, error: String(mergeErr) });
|
|
266
|
+
ctx.ui.notify(
|
|
267
|
+
`Merge failed: ${mergeErr instanceof Error ? mergeErr.message : String(mergeErr)}. Resolve and run /gsd auto to resume.`,
|
|
268
|
+
"error",
|
|
269
|
+
);
|
|
270
|
+
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
271
|
+
return { action: "break", reason: "merge-failed" };
|
|
255
272
|
}
|
|
256
273
|
|
|
257
274
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
@@ -344,6 +361,13 @@ export async function runPreDispatch(
|
|
|
344
361
|
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
345
362
|
return { action: "break", reason: "merge-conflict" };
|
|
346
363
|
}
|
|
364
|
+
logError("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId!, error: String(mergeErr) });
|
|
365
|
+
ctx.ui.notify(
|
|
366
|
+
`Merge failed: ${mergeErr instanceof Error ? mergeErr.message : String(mergeErr)}. Resolve and run /gsd auto to resume.`,
|
|
367
|
+
"error",
|
|
368
|
+
);
|
|
369
|
+
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
370
|
+
return { action: "break", reason: "merge-failed" };
|
|
347
371
|
}
|
|
348
372
|
|
|
349
373
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
@@ -441,6 +465,13 @@ export async function runPreDispatch(
|
|
|
441
465
|
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
442
466
|
return { action: "break", reason: "merge-conflict" };
|
|
443
467
|
}
|
|
468
|
+
logError("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId!, error: String(mergeErr) });
|
|
469
|
+
ctx.ui.notify(
|
|
470
|
+
`Merge failed: ${mergeErr instanceof Error ? mergeErr.message : String(mergeErr)}. Resolve and run /gsd auto to resume.`,
|
|
471
|
+
"error",
|
|
472
|
+
);
|
|
473
|
+
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
474
|
+
return { action: "break", reason: "merge-failed" };
|
|
444
475
|
}
|
|
445
476
|
|
|
446
477
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
@@ -677,9 +677,14 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
677
677
|
if (validationPath) {
|
|
678
678
|
const validationContent = await loadFile(validationPath);
|
|
679
679
|
if (validationContent) {
|
|
680
|
-
|
|
680
|
+
// Accept either the structured template format (table with MET/N/A)
|
|
681
|
+
// or prose evidence patterns the validation agent may emit.
|
|
682
|
+
const structuredMatch =
|
|
681
683
|
validationContent.includes("Operational") &&
|
|
682
684
|
(validationContent.includes("MET") || validationContent.includes("N/A"));
|
|
685
|
+
const proseMatch =
|
|
686
|
+
/[Oo]perational[\s:][^\n]*(?:pass|verified|confirmed|met|complete|true|yes|addressed|covered|n\/a|not\s+applicable)/i.test(validationContent);
|
|
687
|
+
const hasOperationalCheck = structuredMatch || proseMatch;
|
|
683
688
|
if (!hasOperationalCheck) {
|
|
684
689
|
return {
|
|
685
690
|
action: "stop" as const,
|