gsd-pi 2.51.0 → 2.52.0-dev.655ad8a
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 +59 -36
- package/dist/headless-events.d.ts +18 -0
- package/dist/headless-events.js +36 -0
- package/dist/headless-query.js +1 -1
- 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/get-secrets-from-user.js +7 -0
- package/dist/resources/extensions/gsd/auto/phases.js +34 -8
- package/dist/resources/extensions/gsd/auto-dispatch.js +23 -1
- 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 +91 -14
- package/dist/resources/extensions/gsd/auto.js +30 -4
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +99 -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/guided-flow.js +4 -3
- 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/parallel-orchestrator.js +18 -2
- 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 +38 -30
- 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 +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 +11 -11
- 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 +11 -11
- 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.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-cfc9a116e6450a6b.js → webpack-bca0e732db0dcec3.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/get-secrets-from-user.ts +8 -0
- package/src/resources/extensions/gsd/auto/phases.ts +44 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +25 -1
- 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 +94 -14
- package/src/resources/extensions/gsd/auto.ts +31 -4
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +118 -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/guided-flow.ts +4 -3
- 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/parallel-orchestrator.ts +23 -1
- 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 +39 -30
- 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/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/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/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/collect-from-manifest.test.ts +39 -0
- 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 +65 -31
- 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/milestone-report-path.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +277 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +103 -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/rate-limit-model-fallback.test.ts +90 -0
- 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/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/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/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/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 +22 -4
- 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 → zpvUPKoW5jRAMB_fWHlPi}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vkr67v-utm1dgZnbrBWQh → zpvUPKoW5jRAMB_fWHlPi}/_ssgManifest.js +0 -0
- /package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
package/README.md
CHANGED
|
@@ -27,55 +27,78 @@ One command. Walk away. Come back to a built project with clean git history.
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
## What's New in v2.
|
|
30
|
+
## What's New in v2.52.0
|
|
31
31
|
|
|
32
|
-
###
|
|
32
|
+
### VS Code Extension & Web UI
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
- **VS Code integration** — status bar, file decorations, bash terminal, session tree, conversation history, and code lens. (#2651)
|
|
35
|
+
- **Dark mode contrast** — raised token floor and flattened opacity tier system for better readability. (#2734)
|
|
36
|
+
- **Auth token gate** — synthetic 401 on missing token, unauthenticated boot state, and recovery screen. (#2740)
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
- **v3 — state machine guards, actor identity, reversibility** — introduces formal state machine guards, tracks which actor (human vs agent) initiated each transition, and makes transitions reversible.
|
|
38
|
-
- **Hardened** — closes TOCTOU race conditions, intercepts bypass attempts, and resolves status inconsistencies.
|
|
38
|
+
### Capability Metadata & Model Routing
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
### v2.45.0 — New Commands and Capabilities
|
|
43
|
-
|
|
44
|
-
- **`/gsd rethink`** — conversational project reorganization. Rethink your milestone structure, slice decomposition, or overall approach through guided discussion. (#2459)
|
|
45
|
-
- **`/gsd mcp`** — MCP server status and connectivity. Check which MCP servers are configured, connected, and healthy. (#2362)
|
|
46
|
-
- **Complete offline mode** — GSD now works fully offline with local models. (#2429)
|
|
47
|
-
- **Global KNOWLEDGE.md injection** — `~/.gsd/agent/KNOWLEDGE.md` is injected into the system prompt, so cross-project knowledge persists globally. (#2331)
|
|
48
|
-
- **Mobile-responsive web UI** — the browser interface now works on phones and tablets. (#2354)
|
|
49
|
-
- **DB tool previews** — `renderCall`/`renderResult` previews on DB tools show what each tool call does before and after execution. (#2273)
|
|
50
|
-
- **Message timestamps** — user and assistant messages now include timestamps. (#2368)
|
|
40
|
+
- **Capability-based model selection** — replaced model-ID pattern matching with capability metadata, making custom provider integration more reliable. (#2548)
|
|
51
41
|
|
|
52
42
|
### Key Changes
|
|
53
43
|
|
|
54
|
-
-
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
44
|
+
- **`--bare` mode** — wired across headless, pi-coding-agent, and resource-loader for minimal-output operation.
|
|
45
|
+
- **RPC protocol v2** — new types, init handshake with version detection, and runId generation on prompt/steer/follow_up commands.
|
|
46
|
+
- **PREFERENCES.md rename** — `preferences.md` renamed to `PREFERENCES.md` for consistency. (#2700, #2738)
|
|
47
|
+
- **Comprehensive SQLite audit** — indexes, caching, safety, and reconciliation fixes across gsd-db.
|
|
48
|
+
- **Unified error classifier** — three overlapping error classifiers consolidated into a single classify-decide-act pipeline.
|
|
58
49
|
|
|
59
50
|
### Key Fixes
|
|
60
51
|
|
|
61
|
-
- **Auto-mode
|
|
62
|
-
- **
|
|
63
|
-
-
|
|
64
|
-
- **
|
|
65
|
-
- **
|
|
66
|
-
- **
|
|
67
|
-
- **Windows
|
|
68
|
-
- **
|
|
52
|
+
- **Auto-mode stops on provider errors** — auto loop now halts after provider errors instead of retrying indefinitely. (#2762, #2764)
|
|
53
|
+
- **Transaction safety** — state machine guards moved inside transactions in 5 tool handlers (#2752), and `transaction()` made re-entrant.
|
|
54
|
+
- **Worktree seeding** — `preferences.md` seeded into auto-mode worktrees and included in worktree sync. (#2693)
|
|
55
|
+
- **Idle watchdog** — interactive tools exempted from stall detection (#2676), and filesystem activity no longer overrides stalled-tool detection. (#2697)
|
|
56
|
+
- **Milestone guards** — `allSlicesDone` guarded against vacuous truth on empty slice arrays (#2679), and `complete-milestone` dispatch blocked when validation is `needs-remediation`. (#2682)
|
|
57
|
+
- **Docker overhaul** — fragile setup replaced with proven container patterns. (#2716)
|
|
58
|
+
- **Windows** — EINVAL prevented by disabling detached process groups on Win32. (#2744)
|
|
59
|
+
- **Audit log** — `setLogBasePath` wired into engine init to resurrect audit logging. (#2745)
|
|
60
|
+
|
|
61
|
+
### v2.51.0 — Skills, RTK, and Verification
|
|
62
|
+
|
|
63
|
+
- **`/terminal` command** — direct shell execution from the slash command interface. (#2349)
|
|
64
|
+
- **Managed RTK integration** — RTK binary auto-provisioned with opt-in preference and web UI toggle. (#2620)
|
|
65
|
+
- **Verification classes** — compliance checked before milestone completion, with classes injected into validation prompts. (#2621, #2623)
|
|
66
|
+
- **Skills overhaul** — 30+ new skill packs covering major frameworks, databases, and cloud platforms; curated catalog with `~/.agents/skills/` as primary directory.
|
|
67
|
+
|
|
68
|
+
### v2.50.0 — Quality Gates
|
|
69
|
+
|
|
70
|
+
- **Quality gates** — 8-question quality gates added to planning and completion templates, with parallel evaluation via `evaluating-gates` phase.
|
|
71
|
+
- **Structured error propagation** — errors wired through `UnitResult` for better diagnostics.
|
|
72
|
+
|
|
73
|
+
### v2.49.0 — Git Trailers & Yolo Mode
|
|
74
|
+
|
|
75
|
+
- **`--yolo` flag** — `/gsd auto --yolo` for non-interactive project init.
|
|
76
|
+
- **Git trailers** — GSD metadata moved from commit subject scopes to git trailers.
|
|
77
|
+
|
|
78
|
+
### v2.48.0 — Forensics & Discussion
|
|
79
|
+
|
|
80
|
+
- **`/gsd discuss` for queued milestones** — target milestones still in the queue. (#2349)
|
|
81
|
+
- **Enhanced forensics** — journal and activity log awareness added to `/gsd forensics`.
|
|
82
|
+
|
|
83
|
+
### v2.47.0 — External Providers
|
|
84
|
+
|
|
85
|
+
- **External tool execution mode** — `externalToolExecution` mode for external providers in agent-core.
|
|
86
|
+
- **Claude Code CLI provider** — new provider extension for Claude Code CLI. (#2382)
|
|
69
87
|
|
|
70
|
-
### Previous highlights (v2.42–v2.
|
|
88
|
+
### Previous highlights (v2.42–v2.46)
|
|
71
89
|
|
|
90
|
+
- **Single-writer state engine** — disciplined state transitions with machine guards, actor identity, reversibility, and TOCTOU hardening. (#2494)
|
|
91
|
+
- **`/gsd rethink`** — conversational project reorganization. (#2459)
|
|
92
|
+
- **`/gsd mcp`** — MCP server status and connectivity. (#2362)
|
|
93
|
+
- **Complete offline mode** — fully offline with local models. (#2429)
|
|
94
|
+
- **Global KNOWLEDGE.md injection** — cross-project knowledge via `~/.gsd/agent/KNOWLEDGE.md`. (#2331)
|
|
95
|
+
- **Mobile-responsive web UI** — browser interface works on phones and tablets. (#2354)
|
|
96
|
+
- **Default isolation mode changed to `none`** — set `git.isolation: worktree` explicitly if needed. (#2481)
|
|
72
97
|
- **Non-API-key provider extensions** — support for Claude Code CLI and similar providers. (#2382)
|
|
73
98
|
- **Docker sandbox template** — official Docker template for isolated auto mode. (#2360)
|
|
74
99
|
- **DB-backed planning tools** — write-side state transitions use atomic SQLite tool calls. (#2141)
|
|
75
100
|
- **Declarative workflow engine** — YAML workflows through auto-loop. (#2024)
|
|
76
101
|
- **`/gsd fast`** — toggle service tier for prioritized API routing. (#1862)
|
|
77
|
-
- **Forensics dedup** — duplicate detection before issue creation. (#2105)
|
|
78
|
-
- **Startup optimizations** — pre-compiled extensions, compile cache, batch discovery. (#2125)
|
|
79
102
|
|
|
80
103
|
---
|
|
81
104
|
|
|
@@ -521,7 +544,7 @@ An auto-generated `index.html` shows all reports with progression metrics across
|
|
|
521
544
|
|
|
522
545
|
### Preferences
|
|
523
546
|
|
|
524
|
-
GSD preferences live in `~/.gsd/
|
|
547
|
+
GSD preferences live in `~/.gsd/PREFERENCES.md` (global) or `.gsd/PREFERENCES.md` (project). Manage with `/gsd prefs`.
|
|
525
548
|
|
|
526
549
|
```yaml
|
|
527
550
|
---
|
|
@@ -672,7 +695,7 @@ The best practice for working in teams is to ensure unique milestone names acros
|
|
|
672
695
|
|
|
673
696
|
### Unique Milestone Names
|
|
674
697
|
|
|
675
|
-
Create or amend your `.gsd/
|
|
698
|
+
Create or amend your `.gsd/PREFERENCES.md` file within the repo to include `unique_milestone_ids: true` e.g.
|
|
676
699
|
|
|
677
700
|
```markdown
|
|
678
701
|
---
|
|
@@ -681,7 +704,7 @@ unique_milestone_ids: true
|
|
|
681
704
|
---
|
|
682
705
|
```
|
|
683
706
|
|
|
684
|
-
With the above `.gitignore` set up, the `.gsd/
|
|
707
|
+
With the above `.gitignore` set up, the `.gsd/PREFERENCES.md` file is checked into the repo ensuring all teammates use unique milestone names to avoid collisions.
|
|
685
708
|
|
|
686
709
|
Milestone names will now be generated with a 6 char random string appended e.g. instead of `M001` you'll get something like `M001-ush8s3`
|
|
687
710
|
|
|
@@ -689,7 +712,7 @@ Milestone names will now be generated with a 6 char random string appended e.g.
|
|
|
689
712
|
|
|
690
713
|
1. Ensure you are not in the middle of any milestones (clean state)
|
|
691
714
|
2. Update the `.gsd/` related entries in your `.gitignore` to follow the `Suggested .gitignore setup` section under `Working in teams` (ensure you are no longer blanket ignoring the whole `.gsd/` directory)
|
|
692
|
-
3. Update your `.gsd/
|
|
715
|
+
3. Update your `.gsd/PREFERENCES.md` file within the repo as per section `Unique Milestone Names`
|
|
693
716
|
4. If you want to update all your existing milestones use this prompt in GSD: `I have turned on unique milestone ids, please update all old milestone ids to use this new format e.g. M001-abc123 where abc123 is a random 6 char lowercase alpha numeric string. Update all references in all .gsd file contents, file names and directory names. Validate your work once done to ensure referential integrity.`
|
|
694
717
|
5. Commit to git
|
|
695
718
|
|
|
@@ -3,7 +3,25 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detects terminal notifications, blocked notifications, milestone-ready signals,
|
|
5
5
|
* and classifies commands as quick (single-turn) vs long-running.
|
|
6
|
+
*
|
|
7
|
+
* Also defines exit code constants and the status→exit-code mapping function.
|
|
8
|
+
*/
|
|
9
|
+
export declare const EXIT_SUCCESS = 0;
|
|
10
|
+
export declare const EXIT_ERROR = 1;
|
|
11
|
+
export declare const EXIT_BLOCKED = 10;
|
|
12
|
+
export declare const EXIT_CANCELLED = 11;
|
|
13
|
+
/**
|
|
14
|
+
* Map a headless session status string to its standardized exit code.
|
|
15
|
+
*
|
|
16
|
+
* success → 0
|
|
17
|
+
* error → 1
|
|
18
|
+
* timeout → 1
|
|
19
|
+
* blocked → 10
|
|
20
|
+
* cancelled → 11
|
|
21
|
+
*
|
|
22
|
+
* Unknown statuses default to EXIT_ERROR (1).
|
|
6
23
|
*/
|
|
24
|
+
export declare function mapStatusToExitCode(status: string): number;
|
|
7
25
|
/**
|
|
8
26
|
* Detect genuine auto-mode termination notifications.
|
|
9
27
|
*
|
package/dist/headless-events.js
CHANGED
|
@@ -3,7 +3,43 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detects terminal notifications, blocked notifications, milestone-ready signals,
|
|
5
5
|
* and classifies commands as quick (single-turn) vs long-running.
|
|
6
|
+
*
|
|
7
|
+
* Also defines exit code constants and the status→exit-code mapping function.
|
|
8
|
+
*/
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Exit Code Constants
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
export const EXIT_SUCCESS = 0;
|
|
13
|
+
export const EXIT_ERROR = 1;
|
|
14
|
+
export const EXIT_BLOCKED = 10;
|
|
15
|
+
export const EXIT_CANCELLED = 11;
|
|
16
|
+
/**
|
|
17
|
+
* Map a headless session status string to its standardized exit code.
|
|
18
|
+
*
|
|
19
|
+
* success → 0
|
|
20
|
+
* error → 1
|
|
21
|
+
* timeout → 1
|
|
22
|
+
* blocked → 10
|
|
23
|
+
* cancelled → 11
|
|
24
|
+
*
|
|
25
|
+
* Unknown statuses default to EXIT_ERROR (1).
|
|
6
26
|
*/
|
|
27
|
+
export function mapStatusToExitCode(status) {
|
|
28
|
+
switch (status) {
|
|
29
|
+
case 'success':
|
|
30
|
+
case 'complete':
|
|
31
|
+
return EXIT_SUCCESS;
|
|
32
|
+
case 'error':
|
|
33
|
+
case 'timeout':
|
|
34
|
+
return EXIT_ERROR;
|
|
35
|
+
case 'blocked':
|
|
36
|
+
return EXIT_BLOCKED;
|
|
37
|
+
case 'cancelled':
|
|
38
|
+
return EXIT_CANCELLED;
|
|
39
|
+
default:
|
|
40
|
+
return EXIT_ERROR;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
7
43
|
// ---------------------------------------------------------------------------
|
|
8
44
|
// Completion Detection
|
|
9
45
|
// ---------------------------------------------------------------------------
|
package/dist/headless-query.js
CHANGED
|
@@ -36,7 +36,7 @@ export async function handleQuery(basePath) {
|
|
|
36
36
|
const state = await deriveState(basePath);
|
|
37
37
|
// Derive next dispatch action
|
|
38
38
|
let next;
|
|
39
|
-
if (!state.activeMilestone) {
|
|
39
|
+
if (!state.activeMilestone?.id) {
|
|
40
40
|
next = {
|
|
41
41
|
action: 'stop',
|
|
42
42
|
reason: state.phase === 'complete' ? 'All milestones complete.' : state.nextAction,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless Types — shared types for the headless orchestrator surface.
|
|
3
|
+
*
|
|
4
|
+
* Contains the structured result type emitted in --output-format json mode
|
|
5
|
+
* and the output format discriminator.
|
|
6
|
+
*/
|
|
7
|
+
export type OutputFormat = 'text' | 'json' | 'stream-json';
|
|
8
|
+
export declare const VALID_OUTPUT_FORMATS: ReadonlySet<string>;
|
|
9
|
+
export interface HeadlessJsonResult {
|
|
10
|
+
status: 'success' | 'error' | 'blocked' | 'cancelled' | 'timeout';
|
|
11
|
+
exitCode: number;
|
|
12
|
+
sessionId?: string;
|
|
13
|
+
duration: number;
|
|
14
|
+
cost: {
|
|
15
|
+
total: number;
|
|
16
|
+
input_tokens: number;
|
|
17
|
+
output_tokens: number;
|
|
18
|
+
cache_read_tokens: number;
|
|
19
|
+
cache_write_tokens: number;
|
|
20
|
+
};
|
|
21
|
+
toolCalls: number;
|
|
22
|
+
events: number;
|
|
23
|
+
milestone?: string;
|
|
24
|
+
phase?: string;
|
|
25
|
+
nextAction?: string;
|
|
26
|
+
artifacts?: string[];
|
|
27
|
+
commits?: string[];
|
|
28
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless Types — shared types for the headless orchestrator surface.
|
|
3
|
+
*
|
|
4
|
+
* Contains the structured result type emitted in --output-format json mode
|
|
5
|
+
* and the output format discriminator.
|
|
6
|
+
*/
|
|
7
|
+
export const VALID_OUTPUT_FORMATS = new Set(['text', 'json', 'stream-json']);
|
package/dist/headless.d.ts
CHANGED
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
* progress to stderr.
|
|
7
7
|
*
|
|
8
8
|
* Exit codes:
|
|
9
|
-
* 0
|
|
10
|
-
* 1
|
|
11
|
-
*
|
|
9
|
+
* 0 — complete (command finished successfully)
|
|
10
|
+
* 1 — error or timeout
|
|
11
|
+
* 10 — blocked (command reported a blocker)
|
|
12
|
+
* 11 — cancelled (SIGINT/SIGTERM received)
|
|
12
13
|
*/
|
|
14
|
+
import type { OutputFormat } from './headless-types.js';
|
|
13
15
|
export interface HeadlessOptions {
|
|
14
16
|
timeout: number;
|
|
15
17
|
json: boolean;
|
|
18
|
+
outputFormat: OutputFormat;
|
|
16
19
|
model?: string;
|
|
17
20
|
command: string;
|
|
18
21
|
commandArgs: string[];
|
|
@@ -25,6 +28,8 @@ export interface HeadlessOptions {
|
|
|
25
28
|
responseTimeout?: number;
|
|
26
29
|
answers?: string;
|
|
27
30
|
eventFilter?: Set<string>;
|
|
31
|
+
resumeSession?: string;
|
|
32
|
+
bare?: boolean;
|
|
28
33
|
}
|
|
29
34
|
export declare function parseHeadlessArgs(argv: string[]): HeadlessOptions;
|
|
30
35
|
export declare function runHeadless(options: HeadlessOptions): Promise<void>;
|
package/dist/headless.js
CHANGED
|
@@ -6,16 +6,18 @@
|
|
|
6
6
|
* progress to stderr.
|
|
7
7
|
*
|
|
8
8
|
* Exit codes:
|
|
9
|
-
* 0
|
|
10
|
-
* 1
|
|
11
|
-
*
|
|
9
|
+
* 0 — complete (command finished successfully)
|
|
10
|
+
* 1 — error or timeout
|
|
11
|
+
* 10 — blocked (command reported a blocker)
|
|
12
|
+
* 11 — cancelled (SIGINT/SIGTERM received)
|
|
12
13
|
*/
|
|
13
14
|
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
14
15
|
import { join } from 'node:path';
|
|
15
16
|
import { resolve } from 'node:path';
|
|
16
17
|
import { RpcClient } from '@gsd/pi-coding-agent';
|
|
17
18
|
import { loadAndValidateAnswerFile, AnswerInjector } from './headless-answers.js';
|
|
18
|
-
import { isTerminalNotification, isBlockedNotification, isMilestoneReadyNotification, isQuickCommand, FIRE_AND_FORGET_METHODS, IDLE_TIMEOUT_MS, NEW_MILESTONE_IDLE_TIMEOUT_MS, } from './headless-events.js';
|
|
19
|
+
import { isTerminalNotification, isBlockedNotification, isMilestoneReadyNotification, isQuickCommand, FIRE_AND_FORGET_METHODS, IDLE_TIMEOUT_MS, NEW_MILESTONE_IDLE_TIMEOUT_MS, EXIT_SUCCESS, EXIT_ERROR, EXIT_BLOCKED, EXIT_CANCELLED, } from './headless-events.js';
|
|
20
|
+
import { VALID_OUTPUT_FORMATS } from './headless-types.js';
|
|
19
21
|
import { handleExtensionUIRequest, formatProgress, startSupervisedStdinReader, } from './headless-ui.js';
|
|
20
22
|
import { loadContext, bootstrapGsdProject, } from './headless-context.js';
|
|
21
23
|
// ---------------------------------------------------------------------------
|
|
@@ -25,6 +27,7 @@ export function parseHeadlessArgs(argv) {
|
|
|
25
27
|
const options = {
|
|
26
28
|
timeout: 300_000,
|
|
27
29
|
json: false,
|
|
30
|
+
outputFormat: 'text',
|
|
28
31
|
command: 'auto',
|
|
29
32
|
commandArgs: [],
|
|
30
33
|
};
|
|
@@ -44,6 +47,18 @@ export function parseHeadlessArgs(argv) {
|
|
|
44
47
|
}
|
|
45
48
|
else if (arg === '--json') {
|
|
46
49
|
options.json = true;
|
|
50
|
+
options.outputFormat = 'stream-json';
|
|
51
|
+
}
|
|
52
|
+
else if (arg === '--output-format' && i + 1 < args.length) {
|
|
53
|
+
const fmt = args[++i];
|
|
54
|
+
if (!VALID_OUTPUT_FORMATS.has(fmt)) {
|
|
55
|
+
process.stderr.write(`[headless] Error: --output-format must be one of: text, json, stream-json (got '${fmt}')\n`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
options.outputFormat = fmt;
|
|
59
|
+
if (fmt === 'stream-json' || fmt === 'json') {
|
|
60
|
+
options.json = true;
|
|
61
|
+
}
|
|
47
62
|
}
|
|
48
63
|
else if (arg === '--model' && i + 1 < args.length) {
|
|
49
64
|
// --model can also be passed from the main CLI; headless-specific takes precedence
|
|
@@ -74,10 +89,16 @@ export function parseHeadlessArgs(argv) {
|
|
|
74
89
|
else if (arg === '--events' && i + 1 < args.length) {
|
|
75
90
|
options.eventFilter = new Set(args[++i].split(','));
|
|
76
91
|
options.json = true; // --events implies --json
|
|
92
|
+
if (options.outputFormat === 'text') {
|
|
93
|
+
options.outputFormat = 'stream-json';
|
|
94
|
+
}
|
|
77
95
|
}
|
|
78
96
|
else if (arg === '--supervised') {
|
|
79
97
|
options.supervised = true;
|
|
80
98
|
options.json = true; // supervised implies json
|
|
99
|
+
if (options.outputFormat === 'text') {
|
|
100
|
+
options.outputFormat = 'stream-json';
|
|
101
|
+
}
|
|
81
102
|
}
|
|
82
103
|
else if (arg === '--response-timeout' && i + 1 < args.length) {
|
|
83
104
|
options.responseTimeout = parseInt(args[++i], 10);
|
|
@@ -86,6 +107,12 @@ export function parseHeadlessArgs(argv) {
|
|
|
86
107
|
process.exit(1);
|
|
87
108
|
}
|
|
88
109
|
}
|
|
110
|
+
else if (arg === '--resume' && i + 1 < args.length) {
|
|
111
|
+
options.resumeSession = args[++i];
|
|
112
|
+
}
|
|
113
|
+
else if (arg === '--bare') {
|
|
114
|
+
options.bare = true;
|
|
115
|
+
}
|
|
89
116
|
}
|
|
90
117
|
else if (!positionalStarted) {
|
|
91
118
|
positionalStarted = true;
|
|
@@ -106,7 +133,7 @@ export async function runHeadless(options) {
|
|
|
106
133
|
while (true) {
|
|
107
134
|
const result = await runHeadlessOnce(options, restartCount);
|
|
108
135
|
// Success or blocked — exit normally
|
|
109
|
-
if (result.exitCode ===
|
|
136
|
+
if (result.exitCode === EXIT_SUCCESS || result.exitCode === EXIT_BLOCKED) {
|
|
110
137
|
process.exit(result.exitCode);
|
|
111
138
|
}
|
|
112
139
|
// Crash/error — check if we should restart
|
|
@@ -216,6 +243,10 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
216
243
|
if (injector) {
|
|
217
244
|
clientOptions.env = injector.getSecretEnvVars();
|
|
218
245
|
}
|
|
246
|
+
// Propagate --bare to the child process
|
|
247
|
+
if (options.bare) {
|
|
248
|
+
clientOptions.args = [...(clientOptions.args || []), '--bare'];
|
|
249
|
+
}
|
|
219
250
|
const client = new RpcClient(clientOptions);
|
|
220
251
|
// Event tracking
|
|
221
252
|
let totalEvents = 0;
|
|
@@ -278,7 +309,7 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
278
309
|
const timeoutTimer = options.timeout > 0
|
|
279
310
|
? setTimeout(() => {
|
|
280
311
|
process.stderr.write(`[headless] Timeout after ${options.timeout / 1000}s\n`);
|
|
281
|
-
exitCode =
|
|
312
|
+
exitCode = EXIT_ERROR;
|
|
282
313
|
resolveCompletion();
|
|
283
314
|
}, options.timeout)
|
|
284
315
|
: null;
|
|
@@ -319,7 +350,7 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
319
350
|
if (injector && !FIRE_AND_FORGET_METHODS.has(String(eventObj.method ?? ''))) {
|
|
320
351
|
if (injector.tryHandle(eventObj, stdinWriter)) {
|
|
321
352
|
if (completed) {
|
|
322
|
-
exitCode = blocked ?
|
|
353
|
+
exitCode = blocked ? EXIT_BLOCKED : EXIT_SUCCESS;
|
|
323
354
|
resolveCompletion();
|
|
324
355
|
}
|
|
325
356
|
return;
|
|
@@ -343,7 +374,7 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
343
374
|
}
|
|
344
375
|
// If we detected a terminal notification, resolve after responding
|
|
345
376
|
if (completed) {
|
|
346
|
-
exitCode = blocked ?
|
|
377
|
+
exitCode = blocked ? EXIT_BLOCKED : EXIT_SUCCESS;
|
|
347
378
|
resolveCompletion();
|
|
348
379
|
return;
|
|
349
380
|
}
|
|
@@ -361,7 +392,7 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
361
392
|
const signalHandler = () => {
|
|
362
393
|
process.stderr.write('\n[headless] Interrupted, stopping child process...\n');
|
|
363
394
|
interrupted = true;
|
|
364
|
-
exitCode =
|
|
395
|
+
exitCode = EXIT_CANCELLED;
|
|
365
396
|
client.stop().finally(() => {
|
|
366
397
|
if (timeoutTimer)
|
|
367
398
|
clearTimeout(timeoutTimer);
|
|
@@ -411,7 +442,7 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
411
442
|
if (!completed) {
|
|
412
443
|
const msg = `[headless] Child process exited unexpectedly with code ${code ?? 'null'}\n`;
|
|
413
444
|
process.stderr.write(msg);
|
|
414
|
-
exitCode =
|
|
445
|
+
exitCode = EXIT_ERROR;
|
|
415
446
|
resolveCompletion();
|
|
416
447
|
}
|
|
417
448
|
});
|
|
@@ -425,14 +456,14 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
425
456
|
}
|
|
426
457
|
catch (err) {
|
|
427
458
|
process.stderr.write(`[headless] Error: Failed to send prompt: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
428
|
-
exitCode =
|
|
459
|
+
exitCode = EXIT_ERROR;
|
|
429
460
|
}
|
|
430
461
|
// Wait for completion
|
|
431
|
-
if (exitCode ===
|
|
462
|
+
if (exitCode === EXIT_SUCCESS || exitCode === EXIT_BLOCKED) {
|
|
432
463
|
await completionPromise;
|
|
433
464
|
}
|
|
434
465
|
// Auto-mode chaining: if --auto and milestone creation succeeded, send /gsd auto
|
|
435
|
-
if (isNewMilestone && options.auto && milestoneReady && !blocked && exitCode ===
|
|
466
|
+
if (isNewMilestone && options.auto && milestoneReady && !blocked && exitCode === EXIT_SUCCESS) {
|
|
436
467
|
if (!options.json) {
|
|
437
468
|
process.stderr.write('[headless] Milestone ready — chaining into auto-mode...\n');
|
|
438
469
|
}
|
|
@@ -451,9 +482,9 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
451
482
|
}
|
|
452
483
|
catch (err) {
|
|
453
484
|
process.stderr.write(`[headless] Error: Failed to start auto-mode: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
454
|
-
exitCode =
|
|
485
|
+
exitCode = EXIT_ERROR;
|
|
455
486
|
}
|
|
456
|
-
if (exitCode ===
|
|
487
|
+
if (exitCode === EXIT_SUCCESS || exitCode === EXIT_BLOCKED) {
|
|
457
488
|
await autoCompletionPromise;
|
|
458
489
|
}
|
|
459
490
|
}
|
|
@@ -471,7 +502,7 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
471
502
|
await client.stop();
|
|
472
503
|
// Summary
|
|
473
504
|
const duration = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
474
|
-
const status = blocked ? 'blocked' : exitCode ===
|
|
505
|
+
const status = blocked ? 'blocked' : exitCode === EXIT_CANCELLED ? 'cancelled' : exitCode === EXIT_ERROR ? (totalEvents === 0 ? 'error' : 'timeout') : 'complete';
|
|
475
506
|
process.stderr.write(`[headless] Status: ${status}\n`);
|
|
476
507
|
process.stderr.write(`[headless] Duration: ${duration}s\n`);
|
|
477
508
|
process.stderr.write(`[headless] Events: ${totalEvents} total, ${toolCallCount} tool calls\n`);
|
package/dist/help-text.js
CHANGED
|
@@ -87,9 +87,12 @@ const SUBCOMMAND_HELP = {
|
|
|
87
87
|
'Run /gsd commands without the TUI. Default command: auto',
|
|
88
88
|
'',
|
|
89
89
|
'Flags:',
|
|
90
|
-
' --timeout N
|
|
91
|
-
' --json
|
|
92
|
-
' --
|
|
90
|
+
' --timeout N Overall timeout in ms (default: 300000)',
|
|
91
|
+
' --json JSONL event stream to stdout (alias for --output-format stream-json)',
|
|
92
|
+
' --output-format <fmt> Output format: text (default), json (structured result), stream-json (JSONL events)',
|
|
93
|
+
' --bare Minimal context: skip CLAUDE.md, AGENTS.md, user settings, user skills',
|
|
94
|
+
' --resume <id> Resume a prior headless session by ID',
|
|
95
|
+
' --model ID Override model',
|
|
93
96
|
' --supervised Forward interactive UI requests to orchestrator via stdout/stdin',
|
|
94
97
|
' --response-timeout N Timeout (ms) for orchestrator response (default: 30000)',
|
|
95
98
|
' --answers <path> Pre-supply answers and secrets (JSON file)',
|
|
@@ -108,11 +111,19 @@ const SUBCOMMAND_HELP = {
|
|
|
108
111
|
' --auto Start auto-mode after milestone creation',
|
|
109
112
|
' --verbose Show tool calls in progress output',
|
|
110
113
|
'',
|
|
114
|
+
'Output formats:',
|
|
115
|
+
' text Human-readable progress on stderr (default)',
|
|
116
|
+
' json Collect events silently, emit structured HeadlessJsonResult on stdout at exit',
|
|
117
|
+
' stream-json Stream JSONL events to stdout in real time (same as --json)',
|
|
118
|
+
'',
|
|
111
119
|
'Examples:',
|
|
112
120
|
' gsd headless Run /gsd auto',
|
|
113
121
|
' gsd headless next Run one unit',
|
|
114
|
-
' gsd headless --json
|
|
122
|
+
' gsd headless --output-format json auto Structured JSON result on stdout',
|
|
123
|
+
' gsd headless --json status Machine-readable JSONL stream',
|
|
115
124
|
' gsd headless --timeout 60000 With 1-minute timeout',
|
|
125
|
+
' gsd headless --bare auto Minimal context (CI/ecosystem use)',
|
|
126
|
+
' gsd headless --resume abc123 auto Resume a prior session',
|
|
116
127
|
' gsd headless new-milestone --context spec.md Create milestone from file',
|
|
117
128
|
' cat spec.md | gsd headless new-milestone --context - From stdin',
|
|
118
129
|
' gsd headless new-milestone --context spec.md --auto Create + auto-execute',
|
|
@@ -121,7 +132,7 @@ const SUBCOMMAND_HELP = {
|
|
|
121
132
|
' gsd headless --events agent_end,extension_ui_request auto Filtered event stream',
|
|
122
133
|
' gsd headless query Instant JSON state snapshot',
|
|
123
134
|
'',
|
|
124
|
-
'Exit codes: 0 =
|
|
135
|
+
'Exit codes: 0 = success, 1 = error/timeout, 10 = blocked, 11 = cancelled',
|
|
125
136
|
].join('\n'),
|
|
126
137
|
};
|
|
127
138
|
// Alias: `gsd wt --help` → same as `gsd worktree --help`
|
package/dist/onboarding.js
CHANGED
|
@@ -568,10 +568,11 @@ async function runToolKeysStep(p, pc, authStorage) {
|
|
|
568
568
|
}
|
|
569
569
|
// ─── Remote Questions Step ────────────────────────────────────────────────────
|
|
570
570
|
async function runRemoteQuestionsStep(p, pc, authStorage) {
|
|
571
|
-
// Check existing config
|
|
572
|
-
const
|
|
573
|
-
const
|
|
574
|
-
const
|
|
571
|
+
// Check existing config — use getCredentialsForProvider to skip empty-key entries
|
|
572
|
+
const hasValidKey = (provider) => authStorage.getCredentialsForProvider(provider).some((c) => c.type === 'api_key' && c.key);
|
|
573
|
+
const hasDiscord = hasValidKey('discord_bot');
|
|
574
|
+
const hasSlack = hasValidKey('slack_bot');
|
|
575
|
+
const hasTelegram = hasValidKey('telegram_bot');
|
|
575
576
|
const existingChannel = hasDiscord ? 'Discord' : hasSlack ? 'Slack' : hasTelegram ? 'Telegram' : null;
|
|
576
577
|
const options = [];
|
|
577
578
|
if (existingChannel) {
|
|
@@ -14,7 +14,7 @@ import { appRoot } from "./app-paths.js";
|
|
|
14
14
|
// boundary — this file is compiled by tsc, but preferences.ts is loaded
|
|
15
15
|
// via jiti at runtime. Importing it as .js fails because no .js exists
|
|
16
16
|
// in dist/. See #592, #1110.
|
|
17
|
-
const GLOBAL_PREFERENCES_PATH = join(appRoot, "
|
|
17
|
+
const GLOBAL_PREFERENCES_PATH = join(appRoot, "PREFERENCES.md");
|
|
18
18
|
export function saveRemoteQuestionsConfig(channel, channelId) {
|
|
19
19
|
const prefsPath = GLOBAL_PREFERENCES_PATH;
|
|
20
20
|
const block = [
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { getShellConfig, sanitizeCommand, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, } from "@gsd/pi-coding-agent";
|
|
9
9
|
import { Type } from "@sinclair/typebox";
|
|
10
|
-
import { spawn } from "node:child_process";
|
|
10
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
11
11
|
import { createWriteStream } from "node:fs";
|
|
12
12
|
import { tmpdir } from "node:os";
|
|
13
13
|
import { join } from "node:path";
|
|
@@ -23,19 +23,33 @@ function getTempFilePath() {
|
|
|
23
23
|
return join(tmpdir(), `pi-async-bash-${id}.log`);
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* Kill a process and its children
|
|
26
|
+
* Kill a process and its children (cross-platform).
|
|
27
|
+
* Uses process group kill on Unix; taskkill /F /T on Windows.
|
|
27
28
|
*/
|
|
28
29
|
function killTree(pid) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if (process.platform === "win32") {
|
|
31
|
+
try {
|
|
32
|
+
spawnSync("taskkill", ["/F", "/T", "/PID", String(pid)], {
|
|
33
|
+
timeout: 5_000,
|
|
34
|
+
stdio: "ignore",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
try {
|
|
39
|
+
process.kill(pid, "SIGTERM");
|
|
40
|
+
}
|
|
41
|
+
catch { /* already exited */ }
|
|
42
|
+
}
|
|
32
43
|
}
|
|
33
|
-
|
|
44
|
+
else {
|
|
34
45
|
try {
|
|
35
|
-
process.kill(pid, "SIGTERM");
|
|
46
|
+
process.kill(-pid, "SIGTERM");
|
|
36
47
|
}
|
|
37
48
|
catch {
|
|
38
|
-
|
|
49
|
+
try {
|
|
50
|
+
process.kill(pid, "SIGTERM");
|
|
51
|
+
}
|
|
52
|
+
catch { /* already exited */ }
|
|
39
53
|
}
|
|
40
54
|
}
|
|
41
55
|
}
|
|
@@ -96,9 +110,13 @@ function executeBashInBackground(command, cwd, signal, timeout) {
|
|
|
96
110
|
const { shell, args } = getShellConfig();
|
|
97
111
|
const rewrittenCommand = rewriteCommandWithRtk(command);
|
|
98
112
|
const resolvedCommand = sanitizeCommand(rewrittenCommand);
|
|
113
|
+
// On Windows, detached: true sets CREATE_NEW_PROCESS_GROUP which can
|
|
114
|
+
// cause EINVAL in VSCode/ConPTY terminal contexts. The bg-shell
|
|
115
|
+
// extension already guards this (process-manager.ts); align here.
|
|
116
|
+
// Process-tree cleanup uses taskkill /F /T on Windows regardless.
|
|
99
117
|
const child = spawn(shell, [...args, resolvedCommand], {
|
|
100
118
|
cwd,
|
|
101
|
-
detached:
|
|
119
|
+
detached: process.platform !== "win32",
|
|
102
120
|
env: { ...process.env },
|
|
103
121
|
stdio: ["ignore", "pipe", "pipe"],
|
|
104
122
|
});
|
|
@@ -118,14 +136,8 @@ function executeBashInBackground(command, cwd, signal, timeout) {
|
|
|
118
136
|
// If the process ignores SIGTERM, escalate to SIGKILL
|
|
119
137
|
sigkillHandle = setTimeout(() => {
|
|
120
138
|
if (child.pid) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
catch { /* ignore */ }
|
|
125
|
-
try {
|
|
126
|
-
process.kill(child.pid, "SIGKILL");
|
|
127
|
-
}
|
|
128
|
-
catch { /* ignore */ }
|
|
139
|
+
// killTree already uses taskkill /F /T on Windows
|
|
140
|
+
killTree(child.pid);
|
|
129
141
|
}
|
|
130
142
|
// Hard deadline: if even SIGKILL doesn't trigger 'close',
|
|
131
143
|
// force-resolve so the job doesn't hang forever (#2186).
|
|
@@ -121,7 +121,10 @@ export class AsyncJobManager {
|
|
|
121
121
|
deliverResult(job) {
|
|
122
122
|
if (!this.onJobComplete)
|
|
123
123
|
return;
|
|
124
|
-
|
|
124
|
+
// Defer delivery by one microtask so await_job's .then() chain runs first
|
|
125
|
+
// and can set job.awaited = true before onJobComplete checks it (#2762).
|
|
126
|
+
const cb = this.onJobComplete;
|
|
127
|
+
queueMicrotask(() => cb(job));
|
|
125
128
|
}
|
|
126
129
|
scheduleEviction(id) {
|
|
127
130
|
const existing = this.evictionTimers.get(id);
|