gsd-pi 2.51.0 → 2.52.0-dev.585e355
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 +4 -4
- package/dist/headless-events.d.ts +18 -0
- package/dist/headless-events.js +36 -0
- package/dist/headless-types.d.ts +28 -0
- package/dist/headless-types.js +7 -0
- package/dist/headless.d.ts +8 -3
- package/dist/headless.js +47 -16
- package/dist/help-text.js +16 -5
- package/dist/onboarding.js +5 -4
- package/dist/remote-questions-config.js +1 -1
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +29 -17
- package/dist/resources/extensions/async-jobs/job-manager.js +4 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +18 -19
- package/dist/resources/extensions/gsd/auto/phases.js +6 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +18 -0
- package/dist/resources/extensions/gsd/auto-start.js +2 -0
- package/dist/resources/extensions/gsd/auto-timers.js +24 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +25 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +21 -0
- package/dist/resources/extensions/gsd/auto.js +8 -4
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +105 -70
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +12 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +1 -1
- package/dist/resources/extensions/gsd/claude-import.js +60 -9
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +69 -6
- package/dist/resources/extensions/gsd/commands-config.js +10 -5
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +4 -4
- package/dist/resources/extensions/gsd/detection.js +6 -6
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +5 -5
- package/dist/resources/extensions/gsd/error-classifier.js +105 -0
- package/dist/resources/extensions/gsd/git-service.js +4 -3
- package/dist/resources/extensions/gsd/gitignore.js +7 -7
- package/dist/resources/extensions/gsd/gsd-db.js +298 -45
- package/dist/resources/extensions/gsd/init-wizard.js +2 -2
- package/dist/resources/extensions/gsd/key-manager.js +7 -16
- package/dist/resources/extensions/gsd/markdown-renderer.js +5 -4
- package/dist/resources/extensions/gsd/memory-store.js +28 -13
- package/dist/resources/extensions/gsd/milestone-actions.js +19 -0
- package/dist/resources/extensions/gsd/preferences-models.js +1 -13
- package/dist/resources/extensions/gsd/preferences-types.js +1 -1
- package/dist/resources/extensions/gsd/preferences.js +13 -13
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/provider-error-pause.js +0 -44
- package/dist/resources/extensions/gsd/rule-registry.js +1 -1
- package/dist/resources/extensions/gsd/service-tier.js +13 -2
- package/dist/resources/extensions/gsd/state.js +33 -19
- package/dist/resources/extensions/gsd/status-guards.js +12 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +7 -13
- package/dist/resources/extensions/gsd/tools/complete-slice.js +7 -20
- package/dist/resources/extensions/gsd/tools/complete-task.js +11 -21
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +28 -29
- package/dist/resources/extensions/gsd/tools/plan-slice.js +27 -26
- package/dist/resources/extensions/gsd/tools/plan-task.js +23 -23
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +50 -41
- 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 +51 -41
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +23 -16
- package/dist/resources/extensions/gsd/validation.js +21 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +0 -1
- package/dist/resources/extensions/remote-questions/config.js +1 -1
- package/dist/resources/extensions/remote-questions/remote-command.js +1 -1
- package/dist/resources/extensions/search-the-web/native-search.js +1 -1
- package/dist/resources/extensions/search-the-web/provider.js +1 -1
- package/dist/resources/extensions/shared/rtk.js +5 -3
- 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 +15 -15
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 +4 -4
- 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 +2 -2
- 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 +5 -5
- 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 +5 -5
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- 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 +15 -15
- package/dist/web/standalone/.next/server/chunks/2229.js +3 -3
- 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.21054f459af5cc78.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-cfc9a116e6450a6b.js → webpack-024d82be84800e52.js} +1 -1
- package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +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/dist/wizard.js +4 -1
- package/package.json +2 -2
- package/packages/mcp-server/README.md +202 -0
- package/packages/mcp-server/package.json +36 -0
- package/packages/mcp-server/src/cli.ts +68 -0
- package/packages/mcp-server/src/index.ts +14 -0
- package/packages/mcp-server/src/mcp-server.test.ts +628 -0
- package/packages/mcp-server/src/server.ts +278 -0
- package/packages/mcp-server/src/session-manager.ts +328 -0
- package/packages/mcp-server/src/types.ts +107 -0
- package/packages/mcp-server/tsconfig.json +24 -0
- package/packages/pi-ai/dist/models.d.ts +14 -3
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.js +53 -10
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +102 -1
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +30 -0
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/src/models.test.ts +114 -1
- package/packages/pi-ai/src/models.ts +70 -13
- package/packages/pi-ai/src/types.ts +31 -0
- package/packages/pi-coding-agent/dist/cli/args.d.ts +2 -0
- package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/cli/args.js +3 -0
- package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/bash-executor.js +5 -1
- package/packages/pi-coding-agent/dist/core/bash-executor.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 +9 -4
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +83 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +5 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +5 -3
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -2
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +28 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +49 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +114 -6
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js +831 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +66 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +0 -1
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/cli/args.ts +4 -0
- package/packages/pi-coding-agent/src/core/bash-executor.ts +5 -1
- package/packages/pi-coding-agent/src/core/model-registry.ts +10 -3
- package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +101 -0
- package/packages/pi-coding-agent/src/core/tools/bash.ts +5 -1
- package/packages/pi-coding-agent/src/index.ts +3 -0
- package/packages/pi-coding-agent/src/main.ts +5 -3
- package/packages/pi-coding-agent/src/modes/index.ts +8 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +54 -1
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +124 -6
- package/packages/pi-coding-agent/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
- package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +61 -4
- package/packages/pi-coding-agent/src/utils/shell.ts +0 -1
- package/packages/rpc-client/package.json +20 -0
- package/pkg/package.json +1 -1
- package/scripts/ensure-workspace-builds.cjs +36 -8
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +22 -11
- package/src/resources/extensions/async-jobs/job-manager.ts +4 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +19 -20
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +21 -0
- package/src/resources/extensions/gsd/auto/phases.ts +6 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +19 -0
- package/src/resources/extensions/gsd/auto-start.ts +2 -0
- package/src/resources/extensions/gsd/auto-timers.ts +25 -1
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +30 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +21 -0
- package/src/resources/extensions/gsd/auto.ts +10 -4
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +125 -73
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +11 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +1 -1
- package/src/resources/extensions/gsd/claude-import.ts +58 -9
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +73 -6
- package/src/resources/extensions/gsd/commands-config.ts +11 -5
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -4
- package/src/resources/extensions/gsd/detection.ts +6 -6
- package/src/resources/extensions/gsd/docs/preferences-reference.md +5 -5
- package/src/resources/extensions/gsd/error-classifier.ts +139 -0
- package/src/resources/extensions/gsd/git-service.ts +4 -3
- package/src/resources/extensions/gsd/gitignore.ts +7 -7
- package/src/resources/extensions/gsd/gsd-db.ts +355 -63
- package/src/resources/extensions/gsd/init-wizard.ts +2 -2
- package/src/resources/extensions/gsd/key-manager.ts +7 -16
- package/src/resources/extensions/gsd/markdown-renderer.ts +5 -4
- package/src/resources/extensions/gsd/memory-store.ts +29 -18
- package/src/resources/extensions/gsd/milestone-actions.ts +17 -0
- package/src/resources/extensions/gsd/preferences-models.ts +1 -13
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/preferences.ts +12 -13
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/provider-error-pause.ts +0 -57
- package/src/resources/extensions/gsd/rule-registry.ts +1 -1
- package/src/resources/extensions/gsd/service-tier.ts +14 -2
- package/src/resources/extensions/gsd/state.ts +34 -20
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +191 -0
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/commands-config.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +35 -7
- package/src/resources/extensions/gsd/tests/detection.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +37 -4
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +119 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +77 -70
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +42 -31
- package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/validation.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +81 -1
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +130 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +7 -17
- package/src/resources/extensions/gsd/tools/complete-slice.ts +7 -24
- package/src/resources/extensions/gsd/tools/complete-task.ts +13 -25
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +30 -32
- package/src/resources/extensions/gsd/tools/plan-slice.ts +30 -30
- package/src/resources/extensions/gsd/tools/plan-task.ts +26 -26
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +57 -46
- 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 +55 -44
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +26 -20
- package/src/resources/extensions/gsd/validation.ts +23 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
- package/src/resources/extensions/remote-questions/config.ts +1 -1
- package/src/resources/extensions/remote-questions/remote-command.ts +1 -1
- package/src/resources/extensions/search-the-web/native-search.ts +1 -1
- package/src/resources/extensions/search-the-web/provider.ts +1 -1
- package/src/resources/extensions/shared/rtk.ts +12 -3
- package/dist/web/standalone/.next/static/chunks/4024.9ad5def014d90ce4.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/css/de141508b083f922.css +0 -1
- /package/dist/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
- /package/dist/web/standalone/.next/static/{vkr67v-utm1dgZnbrBWQh → KTe1kB5nPLQFIIFz2OcmI}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vkr67v-utm1dgZnbrBWQh → KTe1kB5nPLQFIIFz2OcmI}/_ssgManifest.js +0 -0
- /package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bash-spawn-windows.test.ts — Regression test for Windows spawn EINVAL.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that bash tool spawn options disable `detached: true` on Windows
|
|
5
|
+
* to prevent EINVAL errors in ConPTY / VSCode terminal contexts.
|
|
6
|
+
*
|
|
7
|
+
* Background:
|
|
8
|
+
* On Windows, `spawn()` with `detached: true` sets the
|
|
9
|
+
* CREATE_NEW_PROCESS_GROUP flag in CreateProcess. In certain terminal
|
|
10
|
+
* contexts (VSCode integrated terminal, ConPTY, Windows Terminal) this
|
|
11
|
+
* flag conflicts with the parent process group and causes a synchronous
|
|
12
|
+
* EINVAL from libuv. The bg-shell extension already guards against this
|
|
13
|
+
* with `detached: process.platform !== "win32"` (process-manager.ts);
|
|
14
|
+
* this test ensures all other spawn sites are aligned.
|
|
15
|
+
*
|
|
16
|
+
* See: gsd-build/gsd-2#XXXX
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import test from "node:test";
|
|
20
|
+
import assert from "node:assert/strict";
|
|
21
|
+
import { spawn } from "node:child_process";
|
|
22
|
+
|
|
23
|
+
// Verify the spawn option pattern used across the codebase.
|
|
24
|
+
// This is a static/structural test — it reads the source files and asserts
|
|
25
|
+
// they use the platform-guarded detached flag.
|
|
26
|
+
import { readFileSync } from "node:fs";
|
|
27
|
+
import { join, dirname } from "node:path";
|
|
28
|
+
import { fileURLToPath } from "node:url";
|
|
29
|
+
|
|
30
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
|
|
32
|
+
const SPAWN_FILES = [
|
|
33
|
+
join(__dirname, "bash.ts"),
|
|
34
|
+
join(__dirname, "..", "bash-executor.ts"),
|
|
35
|
+
join(__dirname, "..", "..", "utils", "shell.ts"),
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
test("spawn calls use platform-guarded detached flag (no unconditional detached: true)", () => {
|
|
39
|
+
for (const file of SPAWN_FILES) {
|
|
40
|
+
const content = readFileSync(file, "utf-8");
|
|
41
|
+
const lines = content.split("\n");
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < lines.length; i++) {
|
|
44
|
+
const line = lines[i]!;
|
|
45
|
+
// Skip comments
|
|
46
|
+
if (line.trim().startsWith("//") || line.trim().startsWith("*")) continue;
|
|
47
|
+
// Check for unconditional `detached: true`
|
|
48
|
+
if (/detached:\s*true\b/.test(line)) {
|
|
49
|
+
assert.fail(
|
|
50
|
+
`${file}:${i + 1} has unconditional 'detached: true' — ` +
|
|
51
|
+
`must use 'detached: process.platform !== "win32"' ` +
|
|
52
|
+
`to prevent EINVAL on Windows (ConPTY / VSCode terminal)`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("killProcessTree does not use detached: true for taskkill on Windows", () => {
|
|
60
|
+
const shellFile = join(__dirname, "..", "..", "utils", "shell.ts");
|
|
61
|
+
const content = readFileSync(shellFile, "utf-8");
|
|
62
|
+
|
|
63
|
+
// Find the taskkill spawn call and ensure it doesn't have detached: true
|
|
64
|
+
const taskkillRegion = content.match(/spawn\("taskkill"[\s\S]*?\}\)/);
|
|
65
|
+
if (taskkillRegion) {
|
|
66
|
+
assert.ok(
|
|
67
|
+
!/detached:\s*true/.test(taskkillRegion[0]),
|
|
68
|
+
"taskkill spawn should not use detached: true — " +
|
|
69
|
+
"it can cause EINVAL on Windows and is unnecessary for a utility process",
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Smoke test: spawn with platform-guarded detached flag actually works
|
|
75
|
+
test("spawn with detached: process.platform !== 'win32' succeeds", async () => {
|
|
76
|
+
const { promise, resolve, reject } = Promise.withResolvers<void>();
|
|
77
|
+
|
|
78
|
+
const child = spawn(
|
|
79
|
+
process.platform === "win32" ? "cmd" : "sh",
|
|
80
|
+
process.platform === "win32" ? ["/c", "echo ok"] : ["-c", "echo ok"],
|
|
81
|
+
{
|
|
82
|
+
detached: process.platform !== "win32",
|
|
83
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
let output = "";
|
|
88
|
+
child.stdout?.on("data", (d: Buffer) => { output += d.toString(); });
|
|
89
|
+
child.on("error", reject);
|
|
90
|
+
child.on("close", (code) => {
|
|
91
|
+
try {
|
|
92
|
+
assert.equal(code, 0, "spawn should succeed");
|
|
93
|
+
assert.ok(output.trim().includes("ok"), `Expected 'ok' in output, got: ${output}`);
|
|
94
|
+
resolve();
|
|
95
|
+
} catch (e) {
|
|
96
|
+
reject(e);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await promise;
|
|
101
|
+
});
|
|
@@ -158,9 +158,13 @@ const defaultBashOperations: BashOperations = {
|
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
// On Windows, detached: true sets CREATE_NEW_PROCESS_GROUP which can
|
|
162
|
+
// cause EINVAL in VSCode/ConPTY terminal contexts. The bg-shell
|
|
163
|
+
// extension already guards this (process-manager.ts); align here.
|
|
164
|
+
// Process-tree cleanup uses taskkill /F /T on Windows regardless.
|
|
161
165
|
const child = spawn(shell, [...args, command], {
|
|
162
166
|
cwd,
|
|
163
|
-
detached:
|
|
167
|
+
detached: process.platform !== "win32",
|
|
164
168
|
env: env ?? getShellEnv(),
|
|
165
169
|
stdio: ["ignore", "pipe", "pipe"],
|
|
166
170
|
});
|
|
@@ -314,8 +314,11 @@ export {
|
|
|
314
314
|
type RpcClientOptions,
|
|
315
315
|
type RpcEventListener,
|
|
316
316
|
type RpcCommand,
|
|
317
|
+
type RpcInitResult,
|
|
318
|
+
type RpcProtocolVersion,
|
|
317
319
|
type RpcResponse,
|
|
318
320
|
type RpcSessionState,
|
|
321
|
+
type RpcV2Event,
|
|
319
322
|
} from "./modes/index.js";
|
|
320
323
|
// RPC JSONL utilities
|
|
321
324
|
export { attachJsonlLineReader, serializeJsonLine } from "./modes/rpc/jsonl.js";
|
|
@@ -419,11 +419,13 @@ export async function main(args: string[]) {
|
|
|
419
419
|
additionalPromptTemplatePaths: firstPass.promptTemplates,
|
|
420
420
|
additionalThemePaths: firstPass.themes,
|
|
421
421
|
noExtensions: firstPass.noExtensions,
|
|
422
|
-
noSkills: firstPass.noSkills,
|
|
423
|
-
noPromptTemplates: firstPass.noPromptTemplates,
|
|
424
|
-
noThemes: firstPass.noThemes,
|
|
422
|
+
noSkills: firstPass.noSkills || firstPass.bare,
|
|
423
|
+
noPromptTemplates: firstPass.noPromptTemplates || firstPass.bare,
|
|
424
|
+
noThemes: firstPass.noThemes || firstPass.bare,
|
|
425
425
|
systemPrompt: firstPass.systemPrompt,
|
|
426
426
|
appendSystemPrompt: firstPass.appendSystemPrompt,
|
|
427
|
+
// --bare: suppress CLAUDE.md/AGENTS.md ancestor walk
|
|
428
|
+
...(firstPass.bare ? { agentsFilesOverride: () => ({ agentsFiles: [] }) } : {}),
|
|
427
429
|
});
|
|
428
430
|
await resourceLoader.reload();
|
|
429
431
|
time("resourceLoader.reload");
|
|
@@ -6,4 +6,11 @@ export { InteractiveMode, type InteractiveModeOptions } from "./interactive/inte
|
|
|
6
6
|
export { type PrintModeOptions, runPrintMode } from "./print-mode.js";
|
|
7
7
|
export { type ModelInfo, RpcClient, type RpcClientOptions, type RpcEventListener } from "./rpc/rpc-client.js";
|
|
8
8
|
export { runRpcMode } from "./rpc/rpc-mode.js";
|
|
9
|
-
export type {
|
|
9
|
+
export type {
|
|
10
|
+
RpcCommand,
|
|
11
|
+
RpcInitResult,
|
|
12
|
+
RpcProtocolVersion,
|
|
13
|
+
RpcResponse,
|
|
14
|
+
RpcSessionState,
|
|
15
|
+
RpcV2Event,
|
|
16
|
+
} from "./rpc/rpc-types.js";
|
|
@@ -150,7 +150,6 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
150
150
|
content: [{ type: "text", text: "Web search disabled (offline mode)" }],
|
|
151
151
|
isError: false,
|
|
152
152
|
});
|
|
153
|
-
host.pendingTools.delete(content.toolUseId);
|
|
154
153
|
} else {
|
|
155
154
|
const searchContent = content.content;
|
|
156
155
|
const isError = searchContent && typeof searchContent === "object" && "type" in (searchContent as any) && (searchContent as any).type === "web_search_tool_result_error";
|
|
@@ -158,7 +157,6 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
158
157
|
content: [{ type: "text", text: host.formatWebSearchResult(searchContent) }],
|
|
159
158
|
isError: !!isError,
|
|
160
159
|
});
|
|
161
|
-
host.pendingTools.delete(content.toolUseId);
|
|
162
160
|
}
|
|
163
161
|
}
|
|
164
162
|
}
|
|
@@ -11,7 +11,7 @@ import type { SessionStats } from "../../core/agent-session.js";
|
|
|
11
11
|
import type { BashResult } from "../../core/bash-executor.js";
|
|
12
12
|
import type { CompactionResult } from "../../core/compaction/index.js";
|
|
13
13
|
import { attachJsonlLineReader, serializeJsonLine } from "./jsonl.js";
|
|
14
|
-
import type { RpcCommand, RpcResponse, RpcSessionState, RpcSlashCommand } from "./rpc-types.js";
|
|
14
|
+
import type { RpcCommand, RpcInitResult, RpcResponse, RpcSessionState, RpcSlashCommand } from "./rpc-types.js";
|
|
15
15
|
|
|
16
16
|
// ============================================================================
|
|
17
17
|
// Types
|
|
@@ -398,6 +398,59 @@ export class RpcClient {
|
|
|
398
398
|
return this.getData<{ commands: RpcSlashCommand[] }>(response).commands;
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
+
/**
|
|
402
|
+
* Send a UI response to a pending extension_ui_request.
|
|
403
|
+
* Fire-and-forget — no request/response correlation.
|
|
404
|
+
*/
|
|
405
|
+
sendUIResponse(id: string, response: { value?: string; values?: string[]; confirmed?: boolean; cancelled?: boolean }): void {
|
|
406
|
+
if (!this.process?.stdin) {
|
|
407
|
+
throw new Error("Client not started");
|
|
408
|
+
}
|
|
409
|
+
this.process.stdin.write(serializeJsonLine({
|
|
410
|
+
type: "extension_ui_response",
|
|
411
|
+
id,
|
|
412
|
+
...response,
|
|
413
|
+
}));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Initialize a v2 protocol session. Must be sent as the first command.
|
|
418
|
+
* Returns the negotiated protocol version, session ID, and server capabilities.
|
|
419
|
+
*/
|
|
420
|
+
async init(options?: { clientId?: string }): Promise<RpcInitResult> {
|
|
421
|
+
const response = await this.send({ type: "init", protocolVersion: 2, clientId: options?.clientId });
|
|
422
|
+
return this.getData<RpcInitResult>(response);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Request a graceful shutdown of the agent process.
|
|
427
|
+
* Waits for the response before the process exits.
|
|
428
|
+
*/
|
|
429
|
+
async shutdown(): Promise<void> {
|
|
430
|
+
await this.send({ type: "shutdown" });
|
|
431
|
+
// Wait for process to exit after shutdown acknowledgment
|
|
432
|
+
if (this.process) {
|
|
433
|
+
await new Promise<void>((resolve) => {
|
|
434
|
+
const timeout = setTimeout(() => {
|
|
435
|
+
this.process?.kill("SIGKILL");
|
|
436
|
+
resolve();
|
|
437
|
+
}, 5000);
|
|
438
|
+
this.process?.on("exit", () => {
|
|
439
|
+
clearTimeout(timeout);
|
|
440
|
+
resolve();
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Subscribe to specific event types (v2 only).
|
|
448
|
+
* Pass ["*"] to receive all events, or a list of event type strings to filter.
|
|
449
|
+
*/
|
|
450
|
+
async subscribe(events: string[]): Promise<void> {
|
|
451
|
+
await this.send({ type: "subscribe", events });
|
|
452
|
+
}
|
|
453
|
+
|
|
401
454
|
// =========================================================================
|
|
402
455
|
// Helpers
|
|
403
456
|
// =========================================================================
|
|
@@ -27,6 +27,7 @@ import type {
|
|
|
27
27
|
RpcCommand,
|
|
28
28
|
RpcExtensionUIRequest,
|
|
29
29
|
RpcExtensionUIResponse,
|
|
30
|
+
RpcInitResult,
|
|
30
31
|
RpcResponse,
|
|
31
32
|
RpcSessionState,
|
|
32
33
|
RpcSlashCommand,
|
|
@@ -37,8 +38,11 @@ export type {
|
|
|
37
38
|
RpcCommand,
|
|
38
39
|
RpcExtensionUIRequest,
|
|
39
40
|
RpcExtensionUIResponse,
|
|
41
|
+
RpcInitResult,
|
|
42
|
+
RpcProtocolVersion,
|
|
40
43
|
RpcResponse,
|
|
41
44
|
RpcSessionState,
|
|
45
|
+
RpcV2Event,
|
|
42
46
|
} from "./rpc-types.js";
|
|
43
47
|
|
|
44
48
|
/**
|
|
@@ -74,6 +78,16 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
74
78
|
// Shutdown request flag
|
|
75
79
|
let shutdownRequested = false;
|
|
76
80
|
|
|
81
|
+
// v2 protocol version detection state
|
|
82
|
+
let protocolVersion: 1 | 2 = 1;
|
|
83
|
+
let protocolLocked = false;
|
|
84
|
+
|
|
85
|
+
// v2 runId threading: tracks the current execution run
|
|
86
|
+
let currentRunId: string | null = null;
|
|
87
|
+
|
|
88
|
+
// v2 event filtering: null = no filter (all events); Set = only listed event types
|
|
89
|
+
let eventFilter: Set<string> | null = null;
|
|
90
|
+
|
|
77
91
|
const embeddedTerminalEnabled = process.env.GSD_WEB_BRIDGE_TUI === "1";
|
|
78
92
|
const remoteTerminal = embeddedTerminalEnabled
|
|
79
93
|
? new RemoteTerminal({
|
|
@@ -425,7 +439,55 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
425
439
|
|
|
426
440
|
// Output all agent events as JSON
|
|
427
441
|
const unsubscribe = session.subscribe((event) => {
|
|
428
|
-
|
|
442
|
+
// v2: emit synthesized events before the regular event
|
|
443
|
+
if (protocolVersion === 2) {
|
|
444
|
+
// cost_update on assistant message_end
|
|
445
|
+
if (event.type === "message_end" && event.message.role === "assistant" && currentRunId) {
|
|
446
|
+
const stats = session.getSessionStats();
|
|
447
|
+
const costUpdate = {
|
|
448
|
+
type: "cost_update" as const,
|
|
449
|
+
runId: currentRunId,
|
|
450
|
+
turnCost: session.getLastTurnCost(),
|
|
451
|
+
cumulativeCost: stats.cost,
|
|
452
|
+
tokens: {
|
|
453
|
+
input: stats.tokens.input,
|
|
454
|
+
output: stats.tokens.output,
|
|
455
|
+
cacheRead: stats.tokens.cacheRead,
|
|
456
|
+
cacheWrite: stats.tokens.cacheWrite,
|
|
457
|
+
},
|
|
458
|
+
};
|
|
459
|
+
if (!eventFilter || eventFilter.has("cost_update")) {
|
|
460
|
+
output(costUpdate);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// execution_complete on agent_end
|
|
465
|
+
if (event.type === "agent_end" && currentRunId) {
|
|
466
|
+
const stats = session.getSessionStats();
|
|
467
|
+
const completionEvent = {
|
|
468
|
+
type: "execution_complete" as const,
|
|
469
|
+
runId: currentRunId,
|
|
470
|
+
status: "completed" as const,
|
|
471
|
+
stats,
|
|
472
|
+
};
|
|
473
|
+
if (!eventFilter || eventFilter.has("execution_complete")) {
|
|
474
|
+
output(completionEvent);
|
|
475
|
+
}
|
|
476
|
+
currentRunId = null;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Apply event filter (v2 only, applies to agent session events only)
|
|
481
|
+
if (protocolVersion === 2 && eventFilter && !eventFilter.has(event.type)) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Emit the regular event, with runId injection in v2 mode
|
|
486
|
+
if (protocolVersion === 2 && currentRunId) {
|
|
487
|
+
output({ ...event, runId: currentRunId });
|
|
488
|
+
} else {
|
|
489
|
+
output(event);
|
|
490
|
+
}
|
|
429
491
|
});
|
|
430
492
|
|
|
431
493
|
// Handle a single command
|
|
@@ -438,6 +500,9 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
438
500
|
// =================================================================
|
|
439
501
|
|
|
440
502
|
case "prompt": {
|
|
503
|
+
// v2: generate runId for execution tracking
|
|
504
|
+
const runId = protocolVersion === 2 ? crypto.randomUUID() : undefined;
|
|
505
|
+
if (runId) currentRunId = runId;
|
|
441
506
|
// Don't await - events will stream
|
|
442
507
|
// Extension commands are executed immediately, file prompt templates are expanded
|
|
443
508
|
// If streaming and streamingBehavior specified, queues via steer/followUp
|
|
@@ -448,17 +513,23 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
448
513
|
source: "rpc",
|
|
449
514
|
})
|
|
450
515
|
.catch((e) => output(error(id, "prompt", e.message)));
|
|
451
|
-
return
|
|
516
|
+
return { id, type: "response", command: "prompt", success: true, ...(runId && { runId }) } as RpcResponse;
|
|
452
517
|
}
|
|
453
518
|
|
|
454
519
|
case "steer": {
|
|
520
|
+
// v2: generate runId for execution tracking
|
|
521
|
+
const runId = protocolVersion === 2 ? crypto.randomUUID() : undefined;
|
|
522
|
+
if (runId) currentRunId = runId;
|
|
455
523
|
await session.steer(command.message, command.images);
|
|
456
|
-
return
|
|
524
|
+
return { id, type: "response", command: "steer", success: true, ...(runId && { runId }) } as RpcResponse;
|
|
457
525
|
}
|
|
458
526
|
|
|
459
527
|
case "follow_up": {
|
|
528
|
+
// v2: generate runId for execution tracking
|
|
529
|
+
const runId = protocolVersion === 2 ? crypto.randomUUID() : undefined;
|
|
530
|
+
if (runId) currentRunId = runId;
|
|
460
531
|
await session.followUp(command.message, command.images);
|
|
461
|
-
return
|
|
532
|
+
return { id, type: "response", command: "follow_up", success: true, ...(runId && { runId }) } as RpcResponse;
|
|
462
533
|
}
|
|
463
534
|
|
|
464
535
|
case "abort": {
|
|
@@ -709,6 +780,28 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
709
780
|
return success(id, "terminal_redraw");
|
|
710
781
|
}
|
|
711
782
|
|
|
783
|
+
// =================================================================
|
|
784
|
+
// v2 Protocol: subscribe
|
|
785
|
+
// =================================================================
|
|
786
|
+
|
|
787
|
+
case "subscribe": {
|
|
788
|
+
if (command.events.includes("*")) {
|
|
789
|
+
eventFilter = null; // wildcard = all events
|
|
790
|
+
} else {
|
|
791
|
+
eventFilter = new Set(command.events);
|
|
792
|
+
}
|
|
793
|
+
return success(id, "subscribe");
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// =================================================================
|
|
797
|
+
// v2 Protocol: shutdown
|
|
798
|
+
// =================================================================
|
|
799
|
+
|
|
800
|
+
case "shutdown": {
|
|
801
|
+
shutdownRequested = true;
|
|
802
|
+
return success(id, "shutdown");
|
|
803
|
+
}
|
|
804
|
+
|
|
712
805
|
default: {
|
|
713
806
|
const unknownCommand = command as { type: string; id?: string };
|
|
714
807
|
return error(unknownCommand.id, unknownCommand.type, `Unknown command: ${unknownCommand.type}`);
|
|
@@ -741,7 +834,7 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
741
834
|
try {
|
|
742
835
|
const parsed = JSON.parse(line);
|
|
743
836
|
|
|
744
|
-
// Handle extension UI responses
|
|
837
|
+
// Handle extension UI responses (bypass protocol detection)
|
|
745
838
|
if (parsed.type === "extension_ui_response") {
|
|
746
839
|
const response = parsed as RpcExtensionUIResponse;
|
|
747
840
|
const pending = pendingExtensionRequests.get(response.id);
|
|
@@ -752,8 +845,33 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
752
845
|
return;
|
|
753
846
|
}
|
|
754
847
|
|
|
755
|
-
// Handle regular commands
|
|
756
848
|
const command = parsed as RpcCommand;
|
|
849
|
+
|
|
850
|
+
// Protocol version detection: first non-UI-response command locks the version
|
|
851
|
+
if (!protocolLocked) {
|
|
852
|
+
protocolLocked = true;
|
|
853
|
+
if (command.type === "init") {
|
|
854
|
+
protocolVersion = 2;
|
|
855
|
+
const initResult: RpcInitResult = {
|
|
856
|
+
protocolVersion: 2,
|
|
857
|
+
sessionId: session.sessionId,
|
|
858
|
+
capabilities: {
|
|
859
|
+
events: ["execution_complete", "cost_update"],
|
|
860
|
+
commands: ["init", "shutdown", "subscribe"],
|
|
861
|
+
},
|
|
862
|
+
};
|
|
863
|
+
output(success(command.id, "init", initResult));
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
// Non-init first message: lock to v1, fall through to normal handling
|
|
867
|
+
protocolVersion = 1;
|
|
868
|
+
} else if (command.type === "init") {
|
|
869
|
+
// Already locked — reject re-init
|
|
870
|
+
output(error(command.id, "init", "Protocol version already locked. init must be the first command."));
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// Handle regular commands
|
|
757
875
|
const response = await handleCommand(command);
|
|
758
876
|
output(response);
|
|
759
877
|
|