gsd-pi 2.78.1-dev.84a383f51 → 2.78.1
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 +7 -7
- package/dist/cli.js +55 -95
- package/dist/headless-query.d.ts +0 -22
- package/dist/headless-query.js +4 -24
- package/dist/headless.d.ts +0 -10
- package/dist/headless.js +1 -16
- package/dist/loader.js +10 -7
- package/dist/onboarding.d.ts +0 -10
- package/dist/onboarding.js +2 -2
- package/dist/provider-migrations.d.ts +2 -2
- package/dist/provider-migrations.js +2 -5
- package/dist/resource-loader.d.ts +2 -5
- package/dist/resource-loader.js +5 -28
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +601 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +651 -0
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +91 -0
- package/dist/resources/extensions/gsd/auto/loop.js +0 -23
- package/dist/resources/extensions/gsd/auto/phases.js +2 -2
- package/dist/resources/extensions/gsd/auto/run-unit.js +1 -3
- package/dist/resources/extensions/gsd/auto/session.js +0 -3
- package/dist/resources/extensions/gsd/auto-recovery.js +4 -43
- package/dist/resources/extensions/gsd/auto-start.js +1 -1
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +0 -30
- package/dist/resources/extensions/gsd/auto.js +5 -14
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -14
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +5 -7
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +4 -5
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -94
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +6 -11
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +8 -34
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +2 -38
- package/dist/resources/extensions/gsd/commands/catalog.js +5 -69
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -22
- package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -3
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -4
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +1 -39
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/forensics.js +2 -2
- package/dist/resources/extensions/gsd/git-service.js +5 -12
- package/dist/resources/extensions/gsd/gsd-db.js +2 -11
- package/dist/resources/extensions/gsd/guided-flow.js +23 -23
- package/dist/resources/extensions/gsd/memory-store.js +31 -66
- package/dist/resources/extensions/gsd/model-router.js +9 -114
- package/dist/resources/extensions/gsd/native-git-bridge.js +1 -7
- package/dist/resources/extensions/gsd/preferences-models.js +15 -91
- package/dist/resources/extensions/gsd/preferences-types.js +0 -2
- package/dist/resources/extensions/gsd/preferences-validation.js +0 -32
- package/dist/resources/extensions/gsd/preferences.js +3 -5
- package/dist/resources/extensions/gsd/prompt-loader.js +12 -23
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -9
- package/dist/resources/extensions/gsd/state.js +0 -42
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +0 -1
- package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +53 -0
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +112 -0
- package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +23 -0
- package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +5 -0
- package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -18
- package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
- package/dist/resources/extensions/gsd/watch/header-renderer.js +1 -3
- package/dist/resources/extensions/gsd/worktree-command.js +46 -26
- package/dist/resources/extensions/mcp-client/index.js +3 -6
- package/dist/resources/extensions/slash-commands/create-extension.js +22 -36
- package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -9
- package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
- package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
- package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
- package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
- package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
- package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
- package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +12 -32
- package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
- package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +608 -0
- package/dist/rtk-shared.d.ts +0 -3
- package/dist/rtk-shared.js +0 -17
- package/dist/rtk.d.ts +5 -2
- package/dist/rtk.js +20 -3
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- 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 +4 -44
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/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 -4
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- 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 +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
- package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
- package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +20 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
- package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/package.json +1 -2
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +46 -74
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +0 -26
- package/packages/mcp-server/src/workflow-tools.ts +58 -93
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -48
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +0 -13
- 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/dist/utils/repair-tool-json.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.js +3 -24
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +0 -26
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +20 -52
- package/packages/pi-ai/src/types.ts +0 -13
- package/packages/pi-ai/src/utils/repair-tool-json.ts +3 -24
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +0 -32
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +0 -6
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.js +0 -4
- package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -19
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -10
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +0 -18
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +0 -13
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -20
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -14
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +0 -7
- package/packages/pi-coding-agent/src/core/messages.ts +0 -4
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -32
- package/packages/pi-coding-agent/src/core/model-registry.ts +0 -21
- package/packages/pi-coding-agent/src/core/system-prompt.ts +15 -33
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -17
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +3 -17
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +3 -20
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +2 -24
- package/src/resources/extensions/gsd/auto/phases.ts +3 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +1 -3
- package/src/resources/extensions/gsd/auto/session.ts +0 -3
- package/src/resources/extensions/gsd/auto/types.ts +0 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +8 -46
- package/src/resources/extensions/gsd/auto-start.ts +1 -1
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +4 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +0 -38
- package/src/resources/extensions/gsd/auto.ts +4 -14
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -15
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +7 -8
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +9 -10
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -102
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +6 -12
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +8 -39
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +11 -39
- package/src/resources/extensions/gsd/commands/catalog.ts +5 -75
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -22
- package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -3
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -15
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -4
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +1 -39
- package/src/resources/extensions/gsd/doctor-types.ts +1 -3
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/forensics.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +5 -13
- package/src/resources/extensions/gsd/gsd-db.ts +2 -12
- package/src/resources/extensions/gsd/guided-flow.ts +25 -25
- package/src/resources/extensions/gsd/memory-store.ts +28 -81
- package/src/resources/extensions/gsd/model-router.ts +9 -172
- package/src/resources/extensions/gsd/native-git-bridge.ts +1 -7
- package/src/resources/extensions/gsd/preferences-models.ts +15 -101
- package/src/resources/extensions/gsd/preferences-types.ts +0 -6
- package/src/resources/extensions/gsd/preferences-validation.ts +0 -35
- package/src/resources/extensions/gsd/preferences.ts +2 -16
- package/src/resources/extensions/gsd/prompt-loader.ts +12 -26
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -9
- package/src/resources/extensions/gsd/state.ts +0 -42
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +0 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +1 -178
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +0 -58
- package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -21
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +211 -138
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +59 -142
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +4 -7
- package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +32 -89
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +23 -41
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +43 -3
- package/src/resources/extensions/gsd/tests/debug-logger.test.ts +3 -5
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +87 -22
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +118 -7
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +60 -18
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +76 -14
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +83 -22
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +63 -1
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +1 -26
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +0 -30
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +4 -14
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +12 -22
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +1 -64
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +0 -22
- package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +0 -128
- package/src/resources/extensions/gsd/tests/memory-tools.test.ts +1 -33
- package/src/resources/extensions/gsd/tests/model-router.test.ts +8 -169
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +0 -8
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +43 -32
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +10 -4
- package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -127
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +0 -16
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +0 -7
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +19 -168
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +1 -7
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -23
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +4 -51
- package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +16 -7
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +1 -15
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +0 -15
- package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -17
- package/src/resources/extensions/gsd/unit-context-manifest.ts +8 -8
- package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
- package/src/resources/extensions/gsd/watch/header-renderer.ts +1 -3
- package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
- package/src/resources/extensions/gsd/worktree-command.ts +44 -31
- package/src/resources/extensions/mcp-client/index.ts +3 -6
- package/src/resources/extensions/slash-commands/create-extension.ts +24 -38
- package/src/resources/skills/create-gsd-extension/SKILL.md +5 -9
- package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
- package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
- package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
- package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
- package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
- package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
- package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
- package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
- package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +12 -32
- package/dist/cli-policy.d.ts +0 -13
- package/dist/cli-policy.js +0 -17
- package/dist/resources/.managed-resources-content-hash +0 -1
- package/dist/resources/extensions/gsd/auto-runtime-state.js +0 -31
- package/dist/resources/extensions/gsd/milestone-id-reservation.js +0 -36
- package/dist/resources/extensions/gsd/worktree-session-state.js +0 -33
- package/dist/runtime-checks.d.ts +0 -27
- package/dist/runtime-checks.js +0 -38
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +0 -1
- package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +0 -1
- package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +0 -1
- package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +0 -1
- package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +0 -10
- package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +0 -2
- package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +0 -20
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +0 -1
- package/dist/worktree-status-banner.d.ts +0 -1
- package/dist/worktree-status-banner.js +0 -132
- package/packages/mcp-server/dist/alias-telemetry.d.ts +0 -8
- package/packages/mcp-server/dist/alias-telemetry.d.ts.map +0 -1
- package/packages/mcp-server/dist/alias-telemetry.js +0 -30
- package/packages/mcp-server/dist/alias-telemetry.js.map +0 -1
- package/packages/mcp-server/src/alias-telemetry.test.ts +0 -78
- package/packages/mcp-server/src/alias-telemetry.ts +0 -30
- package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +0 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +0 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +0 -231
- package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +0 -1
- package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +0 -289
- package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +0 -37
- package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/core/token-telemetry.js +0 -49
- package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +0 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +0 -133
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +0 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +0 -2
- package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +0 -78
- package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +0 -1
- package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +0 -2
- package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +0 -181
- package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +0 -1
- package/packages/pi-coding-agent/src/core/token-telemetry.ts +0 -77
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +0 -212
- package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +0 -102
- package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +0 -200
- package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +0 -2
- package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +0 -1
- package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +0 -161
- package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +0 -1
- package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +0 -219
- package/src/resources/extensions/gsd/auto-runtime-state.ts +0 -51
- package/src/resources/extensions/gsd/milestone-id-reservation.ts +0 -47
- package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +0 -116
- package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +0 -100
- package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +0 -93
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +0 -63
- package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +0 -81
- package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +0 -57
- package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +0 -145
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +0 -124
- package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +0 -152
- package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +0 -50
- package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +0 -93
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +0 -101
- package/src/resources/extensions/gsd/worktree-session-state.ts +0 -35
- package/src/resources/extensions/mcp-client/tests/global-config.test.ts +0 -91
- package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +0 -58
- /package/dist/web/standalone/.next/static/{UF5VF4F1tB0miEtJS7LyX → 7afp7gq8-DVbxum83zRQ-}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{UF5VF4F1tB0miEtJS7LyX → 7afp7gq8-DVbxum83zRQ-}/_ssgManifest.js +0 -0
|
@@ -5,16 +5,24 @@ import { isToolCallEventType } from "@gsd/pi-coding-agent";
|
|
|
5
5
|
|
|
6
6
|
import type { GSDEcosystemBeforeAgentStartHandler } from "../ecosystem/gsd-extension-api.js";
|
|
7
7
|
import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
|
|
8
|
+
import { getEcosystemReadyPromise } from "../ecosystem/loader.js";
|
|
8
9
|
|
|
9
10
|
import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
11
|
+
import { buildBeforeAgentStartResult } from "./system-context.js";
|
|
12
|
+
import { handleAgentEnd } from "./agent-end-recovery.js";
|
|
13
|
+
import { clearDiscussionFlowState, isDepthConfirmationAnswer, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockQueueExecution, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
|
|
12
14
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
15
|
+
import { cleanupQuickBranch } from "../quick.js";
|
|
16
|
+
import { getDiscussionMilestoneId } from "../guided-flow.js";
|
|
17
|
+
import { loadToolApiKeys } from "../commands-config.js";
|
|
13
18
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
14
|
-
import {
|
|
19
|
+
import { deriveState } from "../state.js";
|
|
20
|
+
import { getAutoDashboardData, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto.js";
|
|
15
21
|
|
|
22
|
+
import { isParallelActive, shutdownParallel } from "../parallel-orchestrator.js";
|
|
16
23
|
import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
17
24
|
import { saveActivityLog } from "../activity-log.js";
|
|
25
|
+
import { resetAskUserQuestionsCache } from "../../ask-user-questions.js";
|
|
18
26
|
import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
|
|
19
27
|
import { parseUnitId } from "../unit-id.js";
|
|
20
28
|
import { classifyCommand } from "../safety/destructive-guard.js";
|
|
@@ -22,45 +30,17 @@ import { logWarning as safetyLogWarning } from "../workflow-logger.js";
|
|
|
22
30
|
import { installNotifyInterceptor } from "./notify-interceptor.js";
|
|
23
31
|
import { initNotificationStore } from "../notification-store.js";
|
|
24
32
|
import { initNotificationWidget } from "../notification-widget.js";
|
|
33
|
+
import { initHealthWidget } from "../health-widget.js";
|
|
25
34
|
|
|
26
35
|
// Skip the welcome screen on the very first session_start — cli.ts already
|
|
27
36
|
// printed it before the TUI launched. Only re-print on /clear (subsequent sessions).
|
|
28
37
|
let isFirstSession = true;
|
|
29
38
|
|
|
30
|
-
async function deriveGsdState(basePath: string) {
|
|
31
|
-
const { deriveState } = await import("../state.js");
|
|
32
|
-
return deriveState(basePath);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function getDiscussionMilestoneIdFor(basePath: string): Promise<string | null> {
|
|
36
|
-
const { getDiscussionMilestoneId } = await import("../guided-flow.js");
|
|
37
|
-
return getDiscussionMilestoneId(basePath);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function loadToolApiKeysForSession(): Promise<void> {
|
|
41
|
-
const { loadToolApiKeys } = await import("../commands-config.js");
|
|
42
|
-
loadToolApiKeys();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function resetAskUserQuestionsTurnCache(): Promise<void> {
|
|
46
|
-
const { resetAskUserQuestionsCache } = await import("../../ask-user-questions.js");
|
|
47
|
-
resetAskUserQuestionsCache();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
39
|
async function syncServiceTierStatus(ctx: ExtensionContext): Promise<void> {
|
|
51
40
|
const { getEffectiveServiceTier, formatServiceTierFooterStatus } = await import("../service-tier.js");
|
|
52
41
|
ctx.ui.setStatus("gsd-fast", formatServiceTierFooterStatus(getEffectiveServiceTier(), ctx.model?.id));
|
|
53
42
|
}
|
|
54
43
|
|
|
55
|
-
async function applyDisabledModelProviderPolicy(ctx: ExtensionContext): Promise<void> {
|
|
56
|
-
try {
|
|
57
|
-
const { resolveDisabledModelProvidersFromPreferences } = await import("../preferences.js");
|
|
58
|
-
ctx.modelRegistry.setDisabledModelProviders(resolveDisabledModelProvidersFromPreferences());
|
|
59
|
-
} catch {
|
|
60
|
-
// Non-fatal: keep default provider visibility if preferences cannot be loaded.
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
44
|
export function registerHooks(
|
|
65
45
|
pi: ExtensionAPI,
|
|
66
46
|
ecosystemHandlers: GSDEcosystemBeforeAgentStartHandler[],
|
|
@@ -70,14 +50,12 @@ export function registerHooks(
|
|
|
70
50
|
installNotifyInterceptor(ctx);
|
|
71
51
|
initNotificationWidget(ctx);
|
|
72
52
|
if (!isAutoActive()) {
|
|
73
|
-
const { initHealthWidget } = await import("../health-widget.js");
|
|
74
53
|
initHealthWidget(ctx);
|
|
75
54
|
}
|
|
76
55
|
resetWriteGateState();
|
|
77
56
|
resetToolCallLoopGuard();
|
|
78
|
-
|
|
57
|
+
resetAskUserQuestionsCache();
|
|
79
58
|
await syncServiceTierStatus(ctx);
|
|
80
|
-
await applyDisabledModelProviderPolicy(ctx);
|
|
81
59
|
// Skip MCP auto-prep when running inside an auto-worktree (see session_switch below).
|
|
82
60
|
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
83
61
|
if (!isInAutoWorktree(process.cwd())) {
|
|
@@ -113,7 +91,7 @@ export function registerHooks(
|
|
|
113
91
|
}
|
|
114
92
|
} catch { /* non-fatal */ }
|
|
115
93
|
}
|
|
116
|
-
|
|
94
|
+
loadToolApiKeys();
|
|
117
95
|
if (isAutoActive()) {
|
|
118
96
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
119
97
|
}
|
|
@@ -124,10 +102,9 @@ export function registerHooks(
|
|
|
124
102
|
installNotifyInterceptor(ctx);
|
|
125
103
|
resetWriteGateState();
|
|
126
104
|
resetToolCallLoopGuard();
|
|
127
|
-
|
|
105
|
+
resetAskUserQuestionsCache();
|
|
128
106
|
clearDiscussionFlowState();
|
|
129
107
|
await syncServiceTierStatus(ctx);
|
|
130
|
-
await applyDisabledModelProviderPolicy(ctx);
|
|
131
108
|
// Skip MCP auto-prep when running inside an auto-worktree. The worktree
|
|
132
109
|
// already has .mcp.json from createAutoWorktree, and re-running the writer
|
|
133
110
|
// post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
|
|
@@ -137,28 +114,23 @@ export function registerHooks(
|
|
|
137
114
|
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
138
115
|
prepareWorkflowMcpForProject(ctx, process.cwd());
|
|
139
116
|
}
|
|
140
|
-
|
|
141
|
-
if (
|
|
142
|
-
const { initHealthWidget } = await import("../health-widget.js");
|
|
143
|
-
initHealthWidget(ctx);
|
|
144
|
-
} else {
|
|
117
|
+
loadToolApiKeys();
|
|
118
|
+
if (isAutoActive()) {
|
|
145
119
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
146
120
|
}
|
|
147
121
|
});
|
|
148
122
|
|
|
149
123
|
pi.on("before_agent_start", async (event, ctx: ExtensionContext) => {
|
|
150
124
|
// Wait for ecosystem loader to finish (no-op after first turn).
|
|
151
|
-
const { getEcosystemReadyPromise } = await import("../ecosystem/loader.js");
|
|
152
125
|
await getEcosystemReadyPromise();
|
|
153
126
|
|
|
154
127
|
// GSD's own context injection (existing behavior — unchanged).
|
|
155
|
-
const { buildBeforeAgentStartResult } = await import("./system-context.js");
|
|
156
128
|
const gsdResult = await buildBeforeAgentStartResult(event, ctx);
|
|
157
129
|
|
|
158
130
|
// Refresh the snapshot used by ecosystem getPhase()/getActiveUnit().
|
|
159
131
|
// deriveState has its own ~100ms cache so this is cheap on repeat calls.
|
|
160
132
|
try {
|
|
161
|
-
const state = await
|
|
133
|
+
const state = await deriveState(process.cwd());
|
|
162
134
|
updateSnapshot(state);
|
|
163
135
|
} catch {
|
|
164
136
|
updateSnapshot(null);
|
|
@@ -197,8 +169,7 @@ export function registerHooks(
|
|
|
197
169
|
|
|
198
170
|
pi.on("agent_end", async (event, ctx: ExtensionContext) => {
|
|
199
171
|
resetToolCallLoopGuard();
|
|
200
|
-
|
|
201
|
-
const { handleAgentEnd } = await import("./agent-end-recovery.js");
|
|
172
|
+
resetAskUserQuestionsCache();
|
|
202
173
|
await handleAgentEnd(pi, event, ctx);
|
|
203
174
|
});
|
|
204
175
|
|
|
@@ -207,7 +178,6 @@ export function registerHooks(
|
|
|
207
178
|
// quick-return state is pending, so this is safe to call on every turn.
|
|
208
179
|
pi.on("turn_end", async () => {
|
|
209
180
|
try {
|
|
210
|
-
const { cleanupQuickBranch } = await import("../quick.js");
|
|
211
181
|
cleanupQuickBranch();
|
|
212
182
|
} catch {
|
|
213
183
|
// Best-effort: don't break the turn lifecycle if cleanup fails.
|
|
@@ -224,8 +194,8 @@ export function registerHooks(
|
|
|
224
194
|
const basePath = process.cwd();
|
|
225
195
|
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
226
196
|
await ensureDbOpen();
|
|
227
|
-
const state = await
|
|
228
|
-
if (!state.activeMilestone || !state.activeSlice) return;
|
|
197
|
+
const state = await deriveState(basePath);
|
|
198
|
+
if (!state.activeMilestone || !state.activeSlice || !state.activeTask) return;
|
|
229
199
|
// Write checkpoint for ALL phases, not just "executing" — discuss, research,
|
|
230
200
|
// and planning also carry in-memory state (user answers, gate verification)
|
|
231
201
|
// that would be lost on compaction (#4258).
|
|
@@ -240,31 +210,21 @@ export function registerHooks(
|
|
|
240
210
|
if (await loadFile(legacyContinue)) return;
|
|
241
211
|
|
|
242
212
|
const continuePath = join(sliceDir, `${state.activeSlice.id}-CONTINUE.md`);
|
|
243
|
-
const taskId = state.activeTask?.id ?? "none";
|
|
244
|
-
const taskTitle = state.activeTask?.title ?? "";
|
|
245
|
-
const phaseLabel = state.phase.replace(/-/g, " ");
|
|
246
|
-
|
|
247
213
|
await saveFile(continuePath, formatContinue({
|
|
248
214
|
frontmatter: {
|
|
249
215
|
milestone: state.activeMilestone.id,
|
|
250
216
|
slice: state.activeSlice.id,
|
|
251
|
-
task:
|
|
217
|
+
task: state.activeTask.id,
|
|
252
218
|
step: 0,
|
|
253
219
|
totalSteps: 0,
|
|
254
220
|
status: "compacted" as const,
|
|
255
221
|
savedAt: new Date().toISOString(),
|
|
256
222
|
},
|
|
257
|
-
completedWork: state.activeTask
|
|
258
|
-
|
|
259
|
-
: `Slice ${state.activeSlice.id} was in ${phaseLabel} phase when compaction occurred.`,
|
|
260
|
-
remainingWork: state.activeTask
|
|
261
|
-
? "Check the task plan for remaining steps."
|
|
262
|
-
: "Continue this slice from the latest planning/research/discussion artifacts.",
|
|
223
|
+
completedWork: `Task ${state.activeTask.id} (${state.activeTask.title}) was in progress when compaction occurred.`,
|
|
224
|
+
remainingWork: "Check the task plan for remaining steps.",
|
|
263
225
|
decisions: "Check task summary files for prior decisions.",
|
|
264
226
|
context: "Session was auto-compacted by Pi. Resume with /gsd.",
|
|
265
|
-
nextAction: state.activeTask
|
|
266
|
-
? `Resume task ${taskId}: ${taskTitle}.`
|
|
267
|
-
: `Resume ${phaseLabel} work for slice ${state.activeSlice.id}.`,
|
|
227
|
+
nextAction: `Resume task ${state.activeTask.id}: ${state.activeTask.title}.`,
|
|
268
228
|
}));
|
|
269
229
|
});
|
|
270
230
|
|
|
@@ -286,7 +246,7 @@ export function registerHooks(
|
|
|
286
246
|
const basePath = process.cwd();
|
|
287
247
|
let activeContext: string | null = null;
|
|
288
248
|
try {
|
|
289
|
-
const state = await
|
|
249
|
+
const state = await deriveState(basePath);
|
|
290
250
|
if (state.activeMilestone && state.activeSlice && state.activeTask) {
|
|
291
251
|
activeContext =
|
|
292
252
|
`Active: ${state.activeMilestone.id} / ${state.activeSlice.id} / ${state.activeTask.id}` +
|
|
@@ -305,7 +265,6 @@ export function registerHooks(
|
|
|
305
265
|
});
|
|
306
266
|
|
|
307
267
|
pi.on("session_shutdown", async (_event, ctx: ExtensionContext) => {
|
|
308
|
-
const { isParallelActive, shutdownParallel } = await import("../parallel-orchestrator.js");
|
|
309
268
|
if (isParallelActive()) {
|
|
310
269
|
try {
|
|
311
270
|
await shutdownParallel(process.cwd());
|
|
@@ -314,7 +273,7 @@ export function registerHooks(
|
|
|
314
273
|
}
|
|
315
274
|
}
|
|
316
275
|
if (!isAutoActive() && !isAutoPaused()) return;
|
|
317
|
-
const dash =
|
|
276
|
+
const dash = getAutoDashboardData();
|
|
318
277
|
if (dash.currentUnit) {
|
|
319
278
|
saveActivityLog(ctx, dash.basePath, dash.currentUnit.type, dash.currentUnit.id);
|
|
320
279
|
}
|
|
@@ -343,7 +302,7 @@ export function registerHooks(
|
|
|
343
302
|
// If ask_user_questions was called with a gate ID but hasn't been confirmed,
|
|
344
303
|
// block all non-read-only tool calls to prevent the model from skipping gates.
|
|
345
304
|
if (getPendingGate()) {
|
|
346
|
-
const milestoneId =
|
|
305
|
+
const milestoneId = getDiscussionMilestoneId(discussionBasePath);
|
|
347
306
|
if (isToolCallEventType("bash", event)) {
|
|
348
307
|
const bashGuard = shouldBlockPendingGateBash(
|
|
349
308
|
event.input.command,
|
|
@@ -378,36 +337,6 @@ export function registerHooks(
|
|
|
378
337
|
if (queueGuard.block) return queueGuard;
|
|
379
338
|
}
|
|
380
339
|
|
|
381
|
-
// ── Planning-unit tools-policy enforcement (#4934): runtime half ─────
|
|
382
|
-
// The active auto-mode unit's manifest declares a ToolsPolicy. For
|
|
383
|
-
// planning/docs/read-only modes, deny writes outside .gsd/ (or the
|
|
384
|
-
// manifest's allowedPathGlobs), bash that isn't read-only, and
|
|
385
|
-
// subagent dispatch. Closes the b23 bug class where a discuss-milestone
|
|
386
|
-
// turn used the host Edit tool to modify user source files.
|
|
387
|
-
const dash = getAutoRuntimeSnapshot();
|
|
388
|
-
const activeUnitType = dash.currentUnit?.type;
|
|
389
|
-
if (activeUnitType) {
|
|
390
|
-
const manifest = resolveManifest(activeUnitType);
|
|
391
|
-
if (manifest) {
|
|
392
|
-
let planningInput = "";
|
|
393
|
-
if (isToolCallEventType("write", event)) {
|
|
394
|
-
planningInput = event.input.path;
|
|
395
|
-
} else if (isToolCallEventType("edit", event)) {
|
|
396
|
-
planningInput = event.input.path;
|
|
397
|
-
} else if (isToolCallEventType("bash", event)) {
|
|
398
|
-
planningInput = event.input.command;
|
|
399
|
-
}
|
|
400
|
-
const planningGuard = shouldBlockPlanningUnit(
|
|
401
|
-
event.toolName,
|
|
402
|
-
planningInput,
|
|
403
|
-
dash.basePath || discussionBasePath,
|
|
404
|
-
activeUnitType,
|
|
405
|
-
manifest.tools,
|
|
406
|
-
);
|
|
407
|
-
if (planningGuard.block) return planningGuard;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
340
|
// ── Single-writer engine: block direct writes to STATE.md ──────────
|
|
412
341
|
// Covers write, edit, and bash tools to prevent bypass vectors.
|
|
413
342
|
if (isToolCallEventType("write", event)) {
|
|
@@ -433,7 +362,7 @@ export function registerHooks(
|
|
|
433
362
|
const result = shouldBlockContextWrite(
|
|
434
363
|
event.toolName,
|
|
435
364
|
event.input.path,
|
|
436
|
-
|
|
365
|
+
getDiscussionMilestoneId(discussionBasePath),
|
|
437
366
|
isQueuePhaseActive(),
|
|
438
367
|
);
|
|
439
368
|
if (result.block) return result;
|
|
@@ -478,7 +407,7 @@ export function registerHooks(
|
|
|
478
407
|
recordToolInvocationError(event.toolName, errorText);
|
|
479
408
|
}
|
|
480
409
|
if (event.toolName !== "ask_user_questions") return;
|
|
481
|
-
const milestoneId =
|
|
410
|
+
const milestoneId = getDiscussionMilestoneId(process.cwd());
|
|
482
411
|
const queueActive = isQueuePhaseActive();
|
|
483
412
|
|
|
484
413
|
const details = event.details as any;
|
|
@@ -577,7 +506,7 @@ export function registerHooks(
|
|
|
577
506
|
safetyRecordToolResult(event.toolCallId, event.toolName, event.result, event.isError);
|
|
578
507
|
// Persist evidence to disk after each tool result so it survives a session
|
|
579
508
|
// restart mid-unit (Bug #4385 — non-persisted evidence false positives).
|
|
580
|
-
const dash =
|
|
509
|
+
const dash = getAutoDashboardData();
|
|
581
510
|
if (dash.basePath && dash.currentUnit?.type === "execute-task") {
|
|
582
511
|
const { milestone: pMid, slice: pSid, task: pTid } = parseUnitId(dash.currentUnit.id);
|
|
583
512
|
if (pMid && pSid && pTid) {
|
|
@@ -4,14 +4,13 @@ import { join } from "node:path";
|
|
|
4
4
|
import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
5
5
|
import { Key } from "@gsd/pi-tui";
|
|
6
6
|
|
|
7
|
+
import { GSDDashboardOverlay } from "../dashboard-overlay.js";
|
|
8
|
+
import { GSDNotificationOverlay } from "../notification-overlay.js";
|
|
9
|
+
import { ParallelMonitorOverlay } from "../parallel-monitor-overlay.js";
|
|
7
10
|
import { GSD_SHORTCUTS } from "../shortcut-defs.js";
|
|
11
|
+
import { projectRoot } from "../commands/context.js";
|
|
8
12
|
import { shortcutDesc } from "../../shared/mod.js";
|
|
9
13
|
|
|
10
|
-
async function getProjectRoot(): Promise<string> {
|
|
11
|
-
const { projectRoot } = await import("../commands/context.js");
|
|
12
|
-
return projectRoot();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
14
|
export function registerShortcuts(pi: ExtensionAPI): void {
|
|
16
15
|
const overlayOptions = {
|
|
17
16
|
width: "90%",
|
|
@@ -21,10 +20,7 @@ export function registerShortcuts(pi: ExtensionAPI): void {
|
|
|
21
20
|
} as const;
|
|
22
21
|
|
|
23
22
|
const openDashboardOverlay = async (ctx: ExtensionContext) => {
|
|
24
|
-
const
|
|
25
|
-
import("../dashboard-overlay.js"),
|
|
26
|
-
getProjectRoot(),
|
|
27
|
-
]);
|
|
23
|
+
const basePath = projectRoot();
|
|
28
24
|
if (!existsSync(join(basePath, ".gsd"))) {
|
|
29
25
|
ctx.ui.notify("No .gsd/ directory found. Run /gsd to start.", "info");
|
|
30
26
|
return;
|
|
@@ -39,7 +35,6 @@ export function registerShortcuts(pi: ExtensionAPI): void {
|
|
|
39
35
|
};
|
|
40
36
|
|
|
41
37
|
const openNotificationsOverlay = async (ctx: ExtensionContext) => {
|
|
42
|
-
const { GSDNotificationOverlay } = await import("../notification-overlay.js");
|
|
43
38
|
await ctx.ui.custom<boolean>(
|
|
44
39
|
(tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done(true)),
|
|
45
40
|
{
|
|
@@ -56,13 +51,12 @@ export function registerShortcuts(pi: ExtensionAPI): void {
|
|
|
56
51
|
};
|
|
57
52
|
|
|
58
53
|
const openParallelOverlay = async (ctx: ExtensionContext) => {
|
|
59
|
-
const basePath =
|
|
54
|
+
const basePath = projectRoot();
|
|
60
55
|
const parallelDir = join(basePath, ".gsd", "parallel");
|
|
61
56
|
if (!existsSync(parallelDir)) {
|
|
62
57
|
ctx.ui.notify("No parallel workers found. Run /gsd parallel start first.", "info");
|
|
63
58
|
return;
|
|
64
59
|
}
|
|
65
|
-
const { ParallelMonitorOverlay } = await import("../parallel-monitor-overlay.js");
|
|
66
60
|
await ctx.ui.custom<boolean>(
|
|
67
61
|
(tui, theme, _kb, done) => new ParallelMonitorOverlay(tui, theme, () => done(true), basePath),
|
|
68
62
|
{
|
|
@@ -15,7 +15,7 @@ import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile
|
|
|
15
15
|
import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
|
|
16
16
|
import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
|
|
17
17
|
import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
|
|
18
|
-
import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-
|
|
18
|
+
import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-command.js";
|
|
19
19
|
import { deriveState } from "../state.js";
|
|
20
20
|
import { formatOverridesSection, formatShortcut, loadActiveOverrides, loadFile, parseContinue, parseSummary } from "../files.js";
|
|
21
21
|
import { toPosixPath } from "../../shared/mod.js";
|
|
@@ -207,14 +207,7 @@ export async function buildBeforeAgentStartResult(
|
|
|
207
207
|
? `\n\n## Subagent Model\n\nWhen spawning subagents via the \`subagent\` tool, always pass \`model: "${subagentModelConfig.primary}"\` in the tool call parameters. Never omit this — always specify it explicitly.`
|
|
208
208
|
: "";
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
// Removing it from `fullSystem` keeps the system-prompt cache breakpoint
|
|
212
|
-
// stable across calls — the only scoped goal of this fix. The pi-ai
|
|
213
|
-
// Anthropic adapter additionally cache-marks the last user turn, so the
|
|
214
|
-
// memoryBlock injected via the context message may itself be cached up to
|
|
215
|
-
// that boundary; that's orthogonal and unchanged from prior behavior. The
|
|
216
|
-
// load-bearing win here is preserving the system+tools cache hit. (#5019)
|
|
217
|
-
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${newSkillsBlock}${worktreeBlock}${subagentModelBlock}`;
|
|
210
|
+
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}${subagentModelBlock}`;
|
|
218
211
|
|
|
219
212
|
stopContextTimer({
|
|
220
213
|
systemPromptSize: fullSystem.length,
|
|
@@ -223,7 +216,12 @@ export async function buildBeforeAgentStartResult(
|
|
|
223
216
|
hasNewSkills: newSkillsBlock.length > 0,
|
|
224
217
|
});
|
|
225
218
|
|
|
226
|
-
|
|
219
|
+
// Determine which context message to inject (guided execute takes priority)
|
|
220
|
+
const contextMessage = injection
|
|
221
|
+
? { customType: "gsd-guided-context", content: injection, display: false as const }
|
|
222
|
+
: forensicsInjection
|
|
223
|
+
? { customType: "gsd-forensics", content: forensicsInjection, display: false as const }
|
|
224
|
+
: null;
|
|
227
225
|
|
|
228
226
|
return {
|
|
229
227
|
systemPrompt: fullSystem,
|
|
@@ -231,35 +229,6 @@ export async function buildBeforeAgentStartResult(
|
|
|
231
229
|
};
|
|
232
230
|
}
|
|
233
231
|
|
|
234
|
-
/**
|
|
235
|
-
* Route the per-call dynamic blocks (memory, guided-execute, forensics) into a
|
|
236
|
-
* single user-message context payload so they ride the volatile suffix instead
|
|
237
|
-
* of the cached system prefix. Priority when both memory and an injection are
|
|
238
|
-
* present: guided > forensics > memory-only. (#5019)
|
|
239
|
-
*
|
|
240
|
-
* Exported for direct unit testing — the surrounding bootstrap has too many
|
|
241
|
-
* filesystem and DB dependencies to exercise this routing logic in-place.
|
|
242
|
-
*/
|
|
243
|
-
export function buildContextMessage(opts: {
|
|
244
|
-
memoryBlock: string;
|
|
245
|
-
injection: string | null;
|
|
246
|
-
forensicsInjection: string | null;
|
|
247
|
-
}): { customType: string; content: string; display: false } | null {
|
|
248
|
-
const memoryContent = opts.memoryBlock.trim();
|
|
249
|
-
if (opts.injection) {
|
|
250
|
-
const content = memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection;
|
|
251
|
-
return { customType: "gsd-guided-context", content, display: false as const };
|
|
252
|
-
}
|
|
253
|
-
if (opts.forensicsInjection) {
|
|
254
|
-
const content = memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection;
|
|
255
|
-
return { customType: "gsd-forensics", content, display: false as const };
|
|
256
|
-
}
|
|
257
|
-
if (memoryContent) {
|
|
258
|
-
return { customType: "gsd-memory", content: memoryContent, display: false as const };
|
|
259
|
-
}
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
232
|
/**
|
|
264
233
|
* ADR-013 step 4 — auto-injection parity for the memories table.
|
|
265
234
|
*
|
|
@@ -3,7 +3,15 @@ import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
|
3
3
|
|
|
4
4
|
import { minimatch } from "minimatch";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Declarative tools-policy for a unit. Inlined here because the worktree
|
|
8
|
+
* branch predates the full unit-context-manifest export (#4934).
|
|
9
|
+
*/
|
|
10
|
+
export type ToolsPolicy =
|
|
11
|
+
| { mode: "all" }
|
|
12
|
+
| { mode: "read-only" }
|
|
13
|
+
| { mode: "planning" }
|
|
14
|
+
| { mode: "docs"; allowedPathGlobs: readonly string[] };
|
|
7
15
|
|
|
8
16
|
/**
|
|
9
17
|
* Regex matching milestone CONTEXT.md file names in both legacy M001
|
|
@@ -527,33 +535,10 @@ export function shouldBlockQueueExecutionInSnapshot(
|
|
|
527
535
|
}
|
|
528
536
|
|
|
529
537
|
// ─── Planning-unit tools-policy enforcement (#4934) ───────────────────────
|
|
530
|
-
//
|
|
531
|
-
// Runtime half of the declarative ToolsPolicy on UnitContextManifest. The
|
|
532
|
-
// manifest assigns each unit type a tools mode; this predicate is what
|
|
533
|
-
// actually rejects a tool call that violates it.
|
|
534
|
-
//
|
|
535
|
-
// Forensics: a discuss-milestone LLM turn used the host Edit tool to modify
|
|
536
|
-
// index.html in test app b23 (~/Github/test-apps/b23). With this predicate
|
|
537
|
-
// wired into the tool_call hook, the same call returns block=true with a
|
|
538
|
-
// HARD BLOCK reason that the model cannot rationalize past.
|
|
539
|
-
//
|
|
540
|
-
// Activation: the hook supplies the policy resolved from the active unit's
|
|
541
|
-
// manifest. When no unit is active (interactive sessions, unknown unit
|
|
542
|
-
// types), the hook passes null and this predicate is a no-op — falling
|
|
543
|
-
// through to the existing pendingGate / queue-execution / context-write
|
|
544
|
-
// guards.
|
|
545
538
|
|
|
546
539
|
const PLANNING_WRITE_TOOLS = new Set(["write", "edit", "multi_edit", "notebook_edit"]);
|
|
547
540
|
const PLANNING_SUBAGENT_TOOLS = new Set(["subagent", "task"]);
|
|
548
541
|
|
|
549
|
-
/**
|
|
550
|
-
* Read-only / planning-safe tools that any non-"all" mode allows. Mirrors
|
|
551
|
-
* QUEUE_SAFE_TOOLS / GATE_SAFE_TOOLS but is the inclusive default for
|
|
552
|
-
* planning units (which need their full discussion + research surface).
|
|
553
|
-
*
|
|
554
|
-
* gsd_* MCP tools are passed through unconditionally — they have their own
|
|
555
|
-
* domain validation (e.g. depth-verification gate, single-writer DB).
|
|
556
|
-
*/
|
|
557
542
|
const PLANNING_SAFE_TOOLS = new Set([
|
|
558
543
|
"read", "grep", "find", "ls", "glob",
|
|
559
544
|
"ask_user_questions",
|
|
@@ -570,7 +555,6 @@ function isPathUnderGsd(absPath: string, basePath: string): boolean {
|
|
|
570
555
|
function matchesAllowedGlob(absPath: string, basePath: string, globs: readonly string[]): boolean {
|
|
571
556
|
const rel = relative(basePath, absPath);
|
|
572
557
|
if (rel.startsWith("..") || isAbsolute(rel)) return false;
|
|
573
|
-
// Normalize Windows separators for minimatch.
|
|
574
558
|
const posix = rel.split(sep).join("/");
|
|
575
559
|
return globs.some(g => minimatch(posix, g, { dot: false, nocase: false }));
|
|
576
560
|
}
|
|
@@ -595,12 +579,7 @@ function blockReason(unitType: string, mode: string, what: string): string {
|
|
|
595
579
|
* - "docs" → like "planning" but also allows writes to paths
|
|
596
580
|
* matching `allowedPathGlobs` relative to basePath.
|
|
597
581
|
*
|
|
598
|
-
* `
|
|
599
|
-
* shell command for bash. Other tools ignore this argument.
|
|
600
|
-
*
|
|
601
|
-
* `policy` of null means "no manifest resolved" — pass-through. Callers
|
|
602
|
-
* that have no active unit (interactive sessions) pass null and this
|
|
603
|
-
* predicate is a no-op.
|
|
582
|
+
* `policy` of null means "no manifest resolved" — pass-through.
|
|
604
583
|
*/
|
|
605
584
|
export function shouldBlockPlanningUnit(
|
|
606
585
|
toolName: string,
|
|
@@ -614,18 +593,16 @@ export function shouldBlockPlanningUnit(
|
|
|
614
593
|
|
|
615
594
|
const tool = toolName;
|
|
616
595
|
|
|
617
|
-
// Read-only mode: only Read-class tools are permitted.
|
|
618
596
|
if (policy.mode === "read-only") {
|
|
619
597
|
if (PLANNING_SAFE_TOOLS.has(tool)) return { block: false };
|
|
620
598
|
if (tool.startsWith("gsd_")) return { block: false };
|
|
621
599
|
if (PLANNING_WRITE_TOOLS.has(tool) || tool === "bash" || PLANNING_SUBAGENT_TOOLS.has(tool)) {
|
|
622
600
|
return { block: true, reason: blockReason(unitType, policy.mode, `${tool} is not permitted (read-only)`) };
|
|
623
601
|
}
|
|
624
|
-
// Unknown tool in read-only mode — block by default.
|
|
625
602
|
return { block: true, reason: blockReason(unitType, policy.mode, `tool "${tool}" is not on the read-only allowlist`) };
|
|
626
603
|
}
|
|
627
604
|
|
|
628
|
-
// planning / docs modes
|
|
605
|
+
// planning / docs modes
|
|
629
606
|
if (PLANNING_SAFE_TOOLS.has(tool)) return { block: false };
|
|
630
607
|
if (tool.startsWith("gsd_")) return { block: false };
|
|
631
608
|
|
|
@@ -651,10 +628,8 @@ export function shouldBlockPlanningUnit(
|
|
|
651
628
|
}
|
|
652
629
|
const absPath = isAbsolute(pathOrCommand) ? pathOrCommand : resolve(basePath, pathOrCommand);
|
|
653
630
|
|
|
654
|
-
// Always allow .gsd/ writes — that's where planning artifacts live.
|
|
655
631
|
if (isPathUnderGsd(absPath, basePath)) return { block: false };
|
|
656
632
|
|
|
657
|
-
// docs mode additionally allows the manifest's allowedPathGlobs.
|
|
658
633
|
if (policy.mode === "docs" && matchesAllowedGlob(absPath, basePath, policy.allowedPathGlobs)) {
|
|
659
634
|
return { block: false };
|
|
660
635
|
}
|
|
@@ -669,8 +644,5 @@ export function shouldBlockPlanningUnit(
|
|
|
669
644
|
};
|
|
670
645
|
}
|
|
671
646
|
|
|
672
|
-
// Unknown tool name — pass through. Other layers (queue, pending-gate,
|
|
673
|
-
// CONTEXT.md write) catch known mutating shapes; defaulting to allow here
|
|
674
|
-
// avoids breaking gsd_* MCP tools or future safe additions.
|
|
675
647
|
return { block: false };
|
|
676
648
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import { join
|
|
3
|
+
import { join } from "node:path";
|
|
4
4
|
|
|
5
5
|
import { loadRegistry } from "../workflow-templates.js";
|
|
6
|
+
import { resolveProjectRoot } from "../worktree.js";
|
|
6
7
|
|
|
7
8
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
8
9
|
|
|
@@ -14,7 +15,7 @@ export interface GsdCommandDefinition {
|
|
|
14
15
|
type CompletionMap = Record<string, readonly GsdCommandDefinition[]>;
|
|
15
16
|
|
|
16
17
|
export const GSD_COMMAND_DESCRIPTION =
|
|
17
|
-
"GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|fast|mcp|rethink|
|
|
18
|
+
"GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|fast|mcp|rethink|codebase|notifications|ship|do|session-report|backlog|pr-branch|add-tests|scan|language";
|
|
18
19
|
|
|
19
20
|
export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
20
21
|
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
@@ -345,77 +346,6 @@ function getExtensionCompletions(prefix: string, action: string) {
|
|
|
345
346
|
}
|
|
346
347
|
}
|
|
347
348
|
|
|
348
|
-
function normalizePathForCompare(path: string): string {
|
|
349
|
-
return path.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
function findWorktreeSegment(normalizedPath: string): { gsdIdx: number; afterWorktrees: number } | null {
|
|
353
|
-
const directMarker = "/.gsd/worktrees/";
|
|
354
|
-
const directIdx = normalizedPath.indexOf(directMarker);
|
|
355
|
-
if (directIdx !== -1) {
|
|
356
|
-
return { gsdIdx: directIdx, afterWorktrees: directIdx + directMarker.length };
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
const symlinkMatch = normalizedPath.match(/\/\.gsd\/projects\/[a-f0-9]+\/worktrees\//);
|
|
360
|
-
if (symlinkMatch?.index !== undefined) {
|
|
361
|
-
return { gsdIdx: symlinkMatch.index, afterWorktrees: symlinkMatch.index + symlinkMatch[0].length };
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
function resolveProjectRootFromGitFile(worktreePath: string): string | null {
|
|
368
|
-
try {
|
|
369
|
-
let dir = worktreePath;
|
|
370
|
-
for (let i = 0; i < 30; i++) {
|
|
371
|
-
const gitPath = join(dir, ".git");
|
|
372
|
-
if (existsSync(gitPath)) {
|
|
373
|
-
const content = readFileSync(gitPath, "utf8").trim();
|
|
374
|
-
if (content.startsWith("gitdir: ")) {
|
|
375
|
-
const gitDir = resolve(dir, content.slice(8));
|
|
376
|
-
const dotGitDir = resolve(gitDir, "..", "..");
|
|
377
|
-
if (dotGitDir.endsWith(".git") || dotGitDir.endsWith(".git/") || dotGitDir.endsWith(".git\\")) {
|
|
378
|
-
return resolve(dotGitDir, "..");
|
|
379
|
-
}
|
|
380
|
-
const commonDirPath = join(gitDir, "commondir");
|
|
381
|
-
if (existsSync(commonDirPath)) {
|
|
382
|
-
const commonDir = readFileSync(commonDirPath, "utf8").trim();
|
|
383
|
-
return resolve(resolve(gitDir, commonDir), "..");
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
break;
|
|
387
|
-
}
|
|
388
|
-
const parent = resolve(dir, "..");
|
|
389
|
-
if (parent === dir) break;
|
|
390
|
-
dir = parent;
|
|
391
|
-
}
|
|
392
|
-
} catch {
|
|
393
|
-
// Completion must stay best-effort.
|
|
394
|
-
}
|
|
395
|
-
return null;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
function resolveProjectRootForCompletion(basePath: string): string {
|
|
399
|
-
if (process.env.GSD_PROJECT_ROOT) return process.env.GSD_PROJECT_ROOT;
|
|
400
|
-
|
|
401
|
-
const normalizedPath = normalizePathForCompare(basePath);
|
|
402
|
-
const segment = findWorktreeSegment(normalizedPath);
|
|
403
|
-
if (!segment) return basePath;
|
|
404
|
-
|
|
405
|
-
const separator = basePath.includes("\\") ? "\\" : "/";
|
|
406
|
-
const gsdMarker = `${separator}.gsd${separator}`;
|
|
407
|
-
const gsdIdx = basePath.indexOf(gsdMarker);
|
|
408
|
-
const candidate = gsdIdx !== -1 ? basePath.slice(0, gsdIdx) : basePath.slice(0, segment.gsdIdx);
|
|
409
|
-
|
|
410
|
-
const normalizedGsdHome = normalizePathForCompare(gsdHome);
|
|
411
|
-
const candidateGsdPath = normalizePathForCompare(join(candidate, ".gsd"));
|
|
412
|
-
if (candidateGsdPath === normalizedGsdHome || candidateGsdPath.startsWith(`${normalizedGsdHome}/`)) {
|
|
413
|
-
return resolveProjectRootFromGitFile(basePath) ?? basePath;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
return candidate;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
349
|
export function getGsdArgumentCompletions(prefix: string) {
|
|
420
350
|
const hasTrailingSpace = prefix.endsWith(" ");
|
|
421
351
|
const parts = prefix.trim().split(/\s+/);
|
|
@@ -476,7 +406,7 @@ export function getGsdArgumentCompletions(prefix: string) {
|
|
|
476
406
|
// Workflow definition-name completion for `workflow run <name>` and `workflow validate <name>`
|
|
477
407
|
if (command === "workflow" && (subcommand === "run" || subcommand === "validate") && parts.length <= 3) {
|
|
478
408
|
try {
|
|
479
|
-
const defsDir = join(
|
|
409
|
+
const defsDir = join(resolveProjectRoot(process.cwd()), ".gsd", "workflow-defs");
|
|
480
410
|
if (existsSync(defsDir)) {
|
|
481
411
|
return readdirSync(defsDir)
|
|
482
412
|
.filter((f) => f.endsWith(".yaml") && f.startsWith(third))
|
|
@@ -513,7 +443,7 @@ export function getGsdArgumentCompletions(prefix: string) {
|
|
|
513
443
|
} catch { /* ignore */ }
|
|
514
444
|
};
|
|
515
445
|
try {
|
|
516
|
-
const base =
|
|
446
|
+
const base = resolveProjectRoot(process.cwd());
|
|
517
447
|
scanDir(join(base, ".gsd", "workflows"), "project");
|
|
518
448
|
scanDir(join(base, ".gsd", "workflow-defs"), "project-legacy");
|
|
519
449
|
scanDir(join(gsdHome, "workflows"), "global");
|