gsd-pi 2.64.0-dev.f8aad9b → 2.65.0-dev.16e10d7
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/dist/headless.js +3 -1
- package/dist/mcp-server.js +6 -2
- package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +22 -7
- package/dist/resources/extensions/bg-shell/process-manager.js +6 -1
- package/dist/resources/extensions/browser-tools/capture.js +20 -1
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +13 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +94 -8
- package/dist/resources/extensions/gsd/auto-model-selection.js +7 -5
- package/dist/resources/extensions/gsd/auto-post-unit.js +115 -7
- package/dist/resources/extensions/gsd/auto-prompts.js +24 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +12 -8
- package/dist/resources/extensions/gsd/auto-start.js +35 -1
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +10 -0
- package/dist/resources/extensions/gsd/auto-verification.js +138 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +29 -7
- package/dist/resources/extensions/gsd/auto.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +17 -4
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +34 -13
- package/dist/resources/extensions/gsd/bootstrap/notify-interceptor.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +6 -4
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +12 -1
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +16 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +20 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
- package/dist/resources/extensions/gsd/commands/context.js +8 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +21 -0
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +104 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-extensions.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +312 -0
- package/dist/resources/extensions/gsd/detection.js +1 -1
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -0
- package/dist/resources/extensions/gsd/doctor.js +2 -1
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +11 -2
- package/dist/resources/extensions/gsd/guided-flow.js +220 -29
- package/dist/resources/extensions/gsd/md-importer.js +14 -7
- package/dist/resources/extensions/gsd/notification-overlay.js +256 -0
- package/dist/resources/extensions/gsd/notification-store.js +273 -0
- package/dist/resources/extensions/gsd/notification-widget.js +56 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +17 -11
- package/dist/resources/extensions/gsd/post-execution-checks.js +407 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +471 -0
- package/dist/resources/extensions/gsd/preferences-types.js +7 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +78 -1
- package/dist/resources/extensions/gsd/preferences.js +13 -2
- package/dist/resources/extensions/gsd/preparation.js +1092 -0
- package/dist/resources/extensions/gsd/prompt-validation.js +67 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +4 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +2 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
- package/dist/resources/extensions/gsd/quick.js +19 -15
- package/dist/resources/extensions/gsd/reactive-graph.js +12 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +24 -5
- package/dist/resources/extensions/gsd/safety/content-validator.js +3 -3
- package/dist/resources/extensions/gsd/session-lock.js +23 -1
- package/dist/resources/extensions/gsd/state.js +100 -12
- package/dist/resources/extensions/gsd/templates/context-enhanced.md +138 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +12 -3
- package/dist/resources/extensions/gsd/tools/complete-task.js +16 -4
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -5
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +5 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +119 -0
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +30 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +18 -0
- package/dist/resources/extensions/gsd/triage-resolution.js +25 -9
- package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +8 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +4 -7
- package/dist/resources/extensions/gsd/workflow-reconcile.js +2 -4
- package/dist/resources/extensions/gsd/workflow-templates.js +11 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +5 -2
- package/dist/resources/extensions/gsd/worktree.js +9 -0
- package/dist/resources/extensions/shared/interview-ui.js +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/routes-manifest.json +6 -0
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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/notifications/route.js +3 -0
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -0
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -0
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
- package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
- 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/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/Z3TgDP0c7kG9j8CVQVGcl/_buildManifest.js +1 -0
- package/dist/web/standalone/.next/static/chunks/6502.8874bcae249c02e1.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/notifications/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-a1c1e452c6b32d04.js → webpack-9fed74684e1c5bb1.js} +1 -1
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +26 -9
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +100 -4
- package/packages/pi-agent-core/src/agent-loop.ts +43 -12
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +38 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +11 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +4 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +30 -19
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +51 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +9 -9
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +10 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +28 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +15 -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 +18 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +64 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +10 -0
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +42 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +5 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +80 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +37 -25
- package/packages/pi-coding-agent/src/core/sdk.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +29 -4
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +27 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +16 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +38 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +66 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -0
- package/packages/pi-tui/dist/components/image.d.ts +2 -0
- package/packages/pi-tui/dist/components/image.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/image.js +4 -0
- package/packages/pi-tui/dist/components/image.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.d.ts +6 -0
- package/packages/pi-tui/dist/components/image.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/components/image.test.js +32 -0
- package/packages/pi-tui/dist/components/image.test.js.map +1 -0
- package/packages/pi-tui/dist/components/loader.d.ts +4 -2
- package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/loader.js +27 -9
- package/packages/pi-tui/dist/components/loader.js.map +1 -1
- package/packages/pi-tui/dist/components/text.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/text.js +2 -0
- package/packages/pi-tui/dist/components/text.js.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.js +12 -1
- package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +4 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +35 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +82 -0
- package/packages/pi-tui/src/components/image.test.ts +36 -0
- package/packages/pi-tui/src/components/image.ts +5 -0
- package/packages/pi-tui/src/components/loader.ts +27 -10
- package/packages/pi-tui/src/components/text.ts +1 -0
- package/packages/pi-tui/src/overlay-layout.ts +13 -1
- package/packages/pi-tui/src/tui.ts +34 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +19 -7
- package/src/resources/extensions/bg-shell/process-manager.ts +8 -2
- package/src/resources/extensions/browser-tools/capture.ts +19 -1
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +12 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +105 -8
- package/src/resources/extensions/gsd/auto-model-selection.ts +7 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +138 -6
- package/src/resources/extensions/gsd/auto-prompts.ts +31 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-start.ts +38 -0
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +10 -0
- package/src/resources/extensions/gsd/auto-verification.ts +190 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +28 -7
- package/src/resources/extensions/gsd/auto.ts +2 -1
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -4
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +35 -13
- package/src/resources/extensions/gsd/bootstrap/notify-interceptor.ts +34 -0
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +5 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -1
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +20 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +28 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
- package/src/resources/extensions/gsd/commands/context.ts +7 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +24 -0
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +140 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-extensions.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +331 -0
- package/src/resources/extensions/gsd/detection.ts +1 -1
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -1
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/gsd-db.ts +13 -2
- package/src/resources/extensions/gsd/guided-flow.ts +254 -30
- package/src/resources/extensions/gsd/md-importer.ts +13 -6
- package/src/resources/extensions/gsd/notification-overlay.ts +295 -0
- package/src/resources/extensions/gsd/notification-store.ts +293 -0
- package/src/resources/extensions/gsd/notification-widget.ts +68 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +19 -11
- package/src/resources/extensions/gsd/post-execution-checks.ts +539 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +581 -0
- package/src/resources/extensions/gsd/preferences-types.ts +53 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +78 -1
- package/src/resources/extensions/gsd/preferences.ts +13 -2
- package/src/resources/extensions/gsd/preparation.ts +1419 -0
- package/src/resources/extensions/gsd/prompt-validation.ts +88 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +4 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +2 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
- package/src/resources/extensions/gsd/quick.ts +20 -15
- package/src/resources/extensions/gsd/reactive-graph.ts +18 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +21 -5
- package/src/resources/extensions/gsd/safety/content-validator.ts +3 -3
- package/src/resources/extensions/gsd/session-lock.ts +17 -1
- package/src/resources/extensions/gsd/state.ts +101 -11
- package/src/resources/extensions/gsd/templates/context-enhanced.md +138 -0
- package/src/resources/extensions/gsd/tests/adversarial-review-fixes.test.ts +223 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +33 -2
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/defer-milestone-stamp.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/discuss-incremental-persistence.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
- package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +28 -30
- package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
- package/src/resources/extensions/gsd/tests/integration-prepared-discussion.test.ts +525 -0
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +282 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +813 -0
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +1197 -0
- package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +266 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +457 -0
- package/src/resources/extensions/gsd/tests/preparation.test.ts +1211 -0
- package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/prompt-builder.test.ts +669 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +7 -4
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/skipped-validation-completion.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +6 -7
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/symlink-extension-discovery.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +16 -17
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +13 -9
- package/src/resources/extensions/gsd/tests/worktree.test.ts +26 -9
- package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +13 -3
- package/src/resources/extensions/gsd/tools/complete-task.ts +16 -4
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +11 -9
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +5 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +152 -0
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +27 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +17 -0
- package/src/resources/extensions/gsd/triage-resolution.ts +29 -10
- package/src/resources/extensions/gsd/types.ts +4 -0
- package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +13 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +4 -6
- package/src/resources/extensions/gsd/workflow-reconcile.ts +2 -3
- package/src/resources/extensions/gsd/workflow-templates.ts +11 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +4 -2
- package/src/resources/extensions/gsd/worktree.ts +10 -0
- package/src/resources/extensions/shared/interview-ui.ts +1 -1
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +8 -10
- package/dist/web/standalone/.next/static/F1mOwzgCW9R8N3Pt1Et87/_buildManifest.js +0 -1
- package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +0 -1
- /package/dist/web/standalone/.next/static/{F1mOwzgCW9R8N3Pt1Et87 → Z3TgDP0c7kG9j8CVQVGcl}/_ssgManifest.js +0 -0
|
@@ -2,6 +2,7 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { Key } from "@gsd/pi-tui";
|
|
4
4
|
import { GSDDashboardOverlay } from "../dashboard-overlay.js";
|
|
5
|
+
import { GSDNotificationOverlay } from "../notification-overlay.js";
|
|
5
6
|
import { ParallelMonitorOverlay } from "../parallel-monitor-overlay.js";
|
|
6
7
|
import { shortcutDesc } from "../../shared/mod.js";
|
|
7
8
|
export function registerShortcuts(pi) {
|
|
@@ -23,6 +24,21 @@ export function registerShortcuts(pi) {
|
|
|
23
24
|
});
|
|
24
25
|
},
|
|
25
26
|
});
|
|
27
|
+
pi.registerShortcut(Key.ctrlAlt("n"), {
|
|
28
|
+
description: shortcutDesc("Open notification history", "/gsd notifications"),
|
|
29
|
+
handler: async (ctx) => {
|
|
30
|
+
await ctx.ui.custom((tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done()), {
|
|
31
|
+
overlay: true,
|
|
32
|
+
overlayOptions: {
|
|
33
|
+
width: "80%",
|
|
34
|
+
minWidth: 60,
|
|
35
|
+
maxHeight: "88%",
|
|
36
|
+
anchor: "center",
|
|
37
|
+
backdrop: true,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
});
|
|
26
42
|
pi.registerShortcut(Key.ctrlAlt("p"), {
|
|
27
43
|
description: shortcutDesc("Open parallel worker monitor", "/gsd parallel watch"),
|
|
28
44
|
handler: async (ctx) => {
|
|
@@ -229,6 +229,12 @@ function buildWorktreeContextBlock() {
|
|
|
229
229
|
}
|
|
230
230
|
return "";
|
|
231
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Low-entropy resume intent patterns — short phrases a user types to
|
|
234
|
+
* continue work after a pause, rate limit, or context reset (#3615).
|
|
235
|
+
* Tested against the trimmed, lowercased prompt with trailing punctuation stripped.
|
|
236
|
+
*/
|
|
237
|
+
const RESUME_INTENT_PATTERNS = /^(continue|resume|ok|go|go ahead|proceed|keep going|carry on|next|yes|yeah|yep|sure|do it|let's go|pick up where you left off)$/;
|
|
232
238
|
async function buildGuidedExecuteContextInjection(prompt, basePath) {
|
|
233
239
|
const executeMatch = prompt.match(/Execute the next task:\s+(T\d+)\s+\("([^"]+)"\)\s+in slice\s+(S\d+)\s+of milestone\s+(M\d+(?:-[a-z0-9]{6})?)/i);
|
|
234
240
|
if (executeMatch) {
|
|
@@ -243,6 +249,20 @@ async function buildGuidedExecuteContextInjection(prompt, basePath) {
|
|
|
243
249
|
return buildTaskExecutionContextInjection(basePath, milestoneId, sliceId, state.activeTask.id, state.activeTask.title);
|
|
244
250
|
}
|
|
245
251
|
}
|
|
252
|
+
// Fallback: low-entropy resume prompt (e.g., "continue", "ok", "go ahead")
|
|
253
|
+
// during an active executing task — inject task context so the agent
|
|
254
|
+
// doesn't rebuild from scratch (#3615).
|
|
255
|
+
// Intent-gated: only fire for short, resume-like prompts to avoid hijacking
|
|
256
|
+
// control/help/diagnostic prompts with unrelated execution context.
|
|
257
|
+
// Phase-gated: only fire during "executing" to avoid misrouting during
|
|
258
|
+
// replanning, gate evaluation, or other non-execution phases.
|
|
259
|
+
const trimmed = prompt.trim().toLowerCase().replace(/[.!?,]+$/g, "");
|
|
260
|
+
if (RESUME_INTENT_PATTERNS.test(trimmed)) {
|
|
261
|
+
const state = await deriveState(basePath);
|
|
262
|
+
if (state.phase === "executing" && state.activeTask && state.activeMilestone && state.activeSlice) {
|
|
263
|
+
return buildTaskExecutionContextInjection(basePath, state.activeMilestone.id, state.activeSlice.id, state.activeTask.id, state.activeTask.title);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
246
266
|
return null;
|
|
247
267
|
}
|
|
248
268
|
async function buildTaskExecutionContextInjection(basePath, milestoneId, sliceId, taskId, taskTitle) {
|
|
@@ -4,7 +4,7 @@ import { join } from "node:path";
|
|
|
4
4
|
import { loadRegistry } from "../workflow-templates.js";
|
|
5
5
|
import { resolveProjectRoot } from "../worktree.js";
|
|
6
6
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
7
|
-
export const GSD_COMMAND_DESCRIPTION = "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|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast|mcp|rethink|codebase";
|
|
7
|
+
export const GSD_COMMAND_DESCRIPTION = "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|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast|mcp|rethink|codebase|notifications";
|
|
8
8
|
export const TOP_LEVEL_SUBCOMMANDS = [
|
|
9
9
|
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
10
10
|
{ cmd: "next", desc: "Explicit step mode (same as /gsd)" },
|
|
@@ -36,6 +36,7 @@ export const TOP_LEVEL_SUBCOMMANDS = [
|
|
|
36
36
|
{ cmd: "hooks", desc: "Show configured post-unit and pre-dispatch hooks" },
|
|
37
37
|
{ cmd: "run-hook", desc: "Manually trigger a specific hook" },
|
|
38
38
|
{ cmd: "skill-health", desc: "Skill lifecycle dashboard" },
|
|
39
|
+
{ cmd: "notifications", desc: "View, filter, and clear persistent notification history" },
|
|
39
40
|
{ cmd: "doctor", desc: "Runtime health checks with auto-fix" },
|
|
40
41
|
{ cmd: "logs", desc: "Browse activity logs, debug logs, and metrics" },
|
|
41
42
|
{ cmd: "forensics", desc: "Examine execution logs" },
|
|
@@ -97,6 +98,11 @@ const NESTED_COMPLETIONS = {
|
|
|
97
98
|
{ cmd: "keys", desc: "Manage API keys" },
|
|
98
99
|
{ cmd: "prefs", desc: "Configure global preferences" },
|
|
99
100
|
],
|
|
101
|
+
notifications: [
|
|
102
|
+
{ cmd: "clear", desc: "Clear all notifications" },
|
|
103
|
+
{ cmd: "tail", desc: "Show last N notifications (default: 20)" },
|
|
104
|
+
{ cmd: "filter", desc: "Filter by severity (error|warning|info|success)" },
|
|
105
|
+
],
|
|
100
106
|
logs: [
|
|
101
107
|
{ cmd: "debug", desc: "List or view debug log files" },
|
|
102
108
|
{ cmd: "tail", desc: "Show last N activity log summaries" },
|
|
@@ -4,7 +4,14 @@ import { resolveProjectRoot } from "../worktree.js";
|
|
|
4
4
|
import { showNextAction } from "../../shared/tui.js";
|
|
5
5
|
import { handleStatus } from "./handlers/core.js";
|
|
6
6
|
export function projectRoot() {
|
|
7
|
-
|
|
7
|
+
let cwd;
|
|
8
|
+
try {
|
|
9
|
+
cwd = process.cwd();
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
// cwd directory was deleted (e.g. worktree teardown) — fall back to HOME (#3598)
|
|
13
|
+
cwd = process.env.HOME ?? "/";
|
|
14
|
+
}
|
|
8
15
|
const root = resolveProjectRoot(cwd);
|
|
9
16
|
if (root !== cwd) {
|
|
10
17
|
assertSafeDirectory(cwd);
|
|
@@ -25,6 +25,7 @@ export function showHelp(ctx) {
|
|
|
25
25
|
" /gsd queue Show queued/dispatched units and execution order",
|
|
26
26
|
" /gsd history View execution history [--cost] [--phase] [--model] [N]",
|
|
27
27
|
" /gsd changelog Show categorized release notes [version]",
|
|
28
|
+
" /gsd notifications View persistent notification history [clear|tail|filter] (Ctrl+Alt+N)",
|
|
28
29
|
"",
|
|
29
30
|
"COURSE CORRECTION",
|
|
30
31
|
" /gsd steer <desc> Apply user override to active work",
|
|
@@ -47,6 +48,7 @@ export function showHelp(ctx) {
|
|
|
47
48
|
" /gsd cmux Manage cmux integration [status|on|off|notifications|sidebar|splits|browser]",
|
|
48
49
|
" /gsd config Set API keys for external tools",
|
|
49
50
|
" /gsd keys API key manager [list|add|remove|test|rotate|doctor]",
|
|
51
|
+
" /gsd show-config Show effective configuration (models, routing, toggles)",
|
|
50
52
|
" /gsd hooks Show post-unit hook configuration",
|
|
51
53
|
" /gsd extensions Manage extensions [list|enable|disable|info]",
|
|
52
54
|
" /gsd fast Toggle OpenAI service tier [on|off|flex|status]",
|
|
@@ -65,6 +67,9 @@ export function showHelp(ctx) {
|
|
|
65
67
|
}
|
|
66
68
|
export async function handleStatus(ctx) {
|
|
67
69
|
const basePath = projectRoot();
|
|
70
|
+
// Open DB in cold sessions so status uses DB-backed state, not filesystem fallback (#3385)
|
|
71
|
+
const { ensureDbOpen } = await import("../../bootstrap/dynamic-tools.js");
|
|
72
|
+
await ensureDbOpen();
|
|
68
73
|
const state = await deriveState(basePath);
|
|
69
74
|
if (state.registry.length === 0) {
|
|
70
75
|
ctx.ui.notify("No GSD milestones found. Run /gsd to start.", "info");
|
|
@@ -187,6 +192,22 @@ export async function handleCoreCommand(trimmed, ctx) {
|
|
|
187
192
|
await handleCmux(trimmed.replace(/^cmux\s*/, "").trim(), ctx);
|
|
188
193
|
return true;
|
|
189
194
|
}
|
|
195
|
+
if (trimmed === "show-config") {
|
|
196
|
+
const { GSDConfigOverlay, formatConfigText } = await import("../../config-overlay.js");
|
|
197
|
+
const result = await ctx.ui.custom((tui, theme, _kb, done) => new GSDConfigOverlay(tui, theme, () => done()), {
|
|
198
|
+
overlay: true,
|
|
199
|
+
overlayOptions: {
|
|
200
|
+
width: "65%",
|
|
201
|
+
minWidth: 55,
|
|
202
|
+
maxHeight: "85%",
|
|
203
|
+
anchor: "center",
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
if (result === undefined) {
|
|
207
|
+
ctx.ui.notify(formatConfigText(), "info");
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
190
211
|
if (trimmed === "setup" || trimmed.startsWith("setup ")) {
|
|
191
212
|
await handleSetup(trimmed.replace(/^setup\s*/, "").trim(), ctx);
|
|
192
213
|
return true;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// GSD Extension — /gsd notifications Command Handler
|
|
2
|
+
// View, filter, and clear the persistent notification history.
|
|
3
|
+
import { readNotifications, clearNotifications, getUnreadCount, suppressPersistence, unsuppressPersistence, } from "../../notification-store.js";
|
|
4
|
+
import { GSDNotificationOverlay } from "../../notification-overlay.js";
|
|
5
|
+
function severityIcon(severity) {
|
|
6
|
+
switch (severity) {
|
|
7
|
+
case "error": return "✗";
|
|
8
|
+
case "warning": return "⚠";
|
|
9
|
+
case "success": return "✓";
|
|
10
|
+
case "info":
|
|
11
|
+
default: return "●";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function formatTimestamp(ts) {
|
|
15
|
+
try {
|
|
16
|
+
const d = new Date(ts);
|
|
17
|
+
return d.toLocaleString("en-US", { hour12: false, month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return ts.slice(0, 19);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function handleNotificationsCommand(args, ctx, pi) {
|
|
24
|
+
// /gsd notifications clear
|
|
25
|
+
if (args === "clear") {
|
|
26
|
+
clearNotifications();
|
|
27
|
+
// Suppress persistence so the confirmation toast doesn't re-populate the store
|
|
28
|
+
suppressPersistence();
|
|
29
|
+
try {
|
|
30
|
+
ctx.ui.notify("All notifications cleared.", "success");
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
unsuppressPersistence();
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
// /gsd notifications tail [N]
|
|
38
|
+
if (args === "tail" || args.startsWith("tail ")) {
|
|
39
|
+
const countStr = args.replace(/^tail\s*/, "").trim();
|
|
40
|
+
const count = countStr ? parseInt(countStr, 10) : 20;
|
|
41
|
+
const n = isNaN(count) || count < 1 ? 20 : Math.min(count, 100);
|
|
42
|
+
const entries = readNotifications().slice(0, n);
|
|
43
|
+
if (entries.length === 0) {
|
|
44
|
+
ctx.ui.notify("No notifications.", "info");
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
const lines = entries.map((e) => `${severityIcon(e.severity)} [${formatTimestamp(e.ts)}] ${e.message}`);
|
|
48
|
+
ctx.ui.notify(`Last ${entries.length} notification(s):\n${lines.join("\n")}`, "info");
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
// /gsd notifications filter <severity>
|
|
52
|
+
if (args.startsWith("filter ")) {
|
|
53
|
+
const severity = args.replace(/^filter\s+/, "").trim().toLowerCase();
|
|
54
|
+
if (!["error", "warning", "info", "success"].includes(severity)) {
|
|
55
|
+
ctx.ui.notify("Usage: /gsd notifications filter <error|warning|info|success>", "warning");
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
const entries = readNotifications().filter((e) => e.severity === severity);
|
|
59
|
+
if (entries.length === 0) {
|
|
60
|
+
ctx.ui.notify(`No ${severity} notifications.`, "info");
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
const lines = entries.slice(0, 20).map((e) => `${severityIcon(e.severity)} [${formatTimestamp(e.ts)}] ${e.message}`);
|
|
64
|
+
const suffix = entries.length > 20 ? `\n... and ${entries.length - 20} more` : "";
|
|
65
|
+
ctx.ui.notify(`${severity} notifications (${entries.length}):\n${lines.join("\n")}${suffix}`, "info");
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
// /gsd notifications (no args) — open overlay in TUI, or print summary
|
|
69
|
+
if (args === "" || args === "status") {
|
|
70
|
+
// Try overlay first (TUI mode)
|
|
71
|
+
if (ctx.hasUI) {
|
|
72
|
+
try {
|
|
73
|
+
await ctx.ui.custom((tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done()), {
|
|
74
|
+
overlay: true,
|
|
75
|
+
overlayOptions: {
|
|
76
|
+
width: "80%",
|
|
77
|
+
minWidth: 60,
|
|
78
|
+
maxHeight: "88%",
|
|
79
|
+
anchor: "center",
|
|
80
|
+
backdrop: true,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Fall through to text output if overlay fails
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Text fallback (RPC/headless mode)
|
|
90
|
+
const unread = getUnreadCount();
|
|
91
|
+
const entries = readNotifications().slice(0, 10);
|
|
92
|
+
if (entries.length === 0) {
|
|
93
|
+
ctx.ui.notify("No notifications.", "info");
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
const lines = entries.map((e) => `${severityIcon(e.severity)} [${formatTimestamp(e.ts)}] ${e.message}`);
|
|
97
|
+
const header = unread > 0 ? `${unread} unread — ` : "";
|
|
98
|
+
ctx.ui.notify(`${header}Recent notifications:\n${lines.join("\n")}`, "info");
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
// Unknown subcommand
|
|
102
|
+
ctx.ui.notify("Usage: /gsd notifications [clear|tail [N]|filter <severity>]", "warning");
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
@@ -175,6 +175,11 @@ Examples:
|
|
|
175
175
|
await dispatchDirectPhase(ctx, pi, phase, projectRoot());
|
|
176
176
|
return true;
|
|
177
177
|
}
|
|
178
|
+
if (trimmed === "notifications" || trimmed.startsWith("notifications ")) {
|
|
179
|
+
const { handleNotificationsCommand } = await import("./notifications-handler.js");
|
|
180
|
+
await handleNotificationsCommand(trimmed.replace(/^notifications\s*/, "").trim(), ctx, pi);
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
178
183
|
if (trimmed === "inspect") {
|
|
179
184
|
await handleInspect(ctx);
|
|
180
185
|
return true;
|
|
@@ -68,7 +68,7 @@ function discoverManifests() {
|
|
|
68
68
|
if (!existsSync(extDir))
|
|
69
69
|
return manifests;
|
|
70
70
|
for (const entry of readdirSync(extDir, { withFileTypes: true })) {
|
|
71
|
-
if (!entry.isDirectory())
|
|
71
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink())
|
|
72
72
|
continue;
|
|
73
73
|
const m = readManifest(join(extDir, entry.name));
|
|
74
74
|
if (m)
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD Configuration Overlay
|
|
3
|
+
*
|
|
4
|
+
* Read-only TUI overlay showing the effective GSD configuration:
|
|
5
|
+
* token profile, model assignments, dynamic routing, git settings,
|
|
6
|
+
* budget, workflow toggles, and preference file sources.
|
|
7
|
+
* Opened via `/gsd show-config` or `/gsd config`.
|
|
8
|
+
*/
|
|
9
|
+
import { matchesKey, Key, truncateToWidth } from "@gsd/pi-tui";
|
|
10
|
+
import { loadEffectiveGSDPreferences, loadGlobalGSDPreferences, loadProjectGSDPreferences, getGlobalGSDPreferencesPath, getProjectGSDPreferencesPath, resolveDynamicRoutingConfig, resolveEffectiveProfile, resolveModelWithFallbacksForUnit, resolveAutoSupervisorConfig, } from "./preferences.js";
|
|
11
|
+
function collectConfigSections() {
|
|
12
|
+
const sections = [];
|
|
13
|
+
const globalPrefs = loadGlobalGSDPreferences();
|
|
14
|
+
const projectPrefs = loadProjectGSDPreferences();
|
|
15
|
+
const effective = loadEffectiveGSDPreferences();
|
|
16
|
+
const prefs = effective?.preferences;
|
|
17
|
+
// ─── Sources ─────────────────────────────────────────────────────────
|
|
18
|
+
sections.push({
|
|
19
|
+
title: "Sources",
|
|
20
|
+
rows: [
|
|
21
|
+
{ label: "Global", value: globalPrefs ? globalPrefs.path : `(none) ${getGlobalGSDPreferencesPath()}` },
|
|
22
|
+
{ label: "Project", value: projectPrefs ? projectPrefs.path : `(none) ${getProjectGSDPreferencesPath()}` },
|
|
23
|
+
],
|
|
24
|
+
});
|
|
25
|
+
// ─── Profile ─────────────────────────────────────────────────────────
|
|
26
|
+
const profile = resolveEffectiveProfile();
|
|
27
|
+
const profileRows = [
|
|
28
|
+
{ label: "Token profile", value: `${profile}${!prefs?.token_profile ? " (default)" : ""}`, accent: true },
|
|
29
|
+
];
|
|
30
|
+
if (prefs?.mode)
|
|
31
|
+
profileRows.push({ label: "Workflow mode", value: prefs.mode });
|
|
32
|
+
sections.push({ title: "Profile", rows: profileRows });
|
|
33
|
+
// ─── Models ──────────────────────────────────────────────────────────
|
|
34
|
+
const unitTypes = [
|
|
35
|
+
["research", "research-milestone"],
|
|
36
|
+
["planning", "plan-milestone"],
|
|
37
|
+
["discuss", "discuss-milestone"],
|
|
38
|
+
["execution", "execute-task"],
|
|
39
|
+
["completion", "complete-slice"],
|
|
40
|
+
["validation", "run-uat"],
|
|
41
|
+
];
|
|
42
|
+
const modelRows = [];
|
|
43
|
+
for (const [label, unitType] of unitTypes) {
|
|
44
|
+
const resolved = resolveModelWithFallbacksForUnit(unitType);
|
|
45
|
+
if (resolved) {
|
|
46
|
+
let val = resolved.primary;
|
|
47
|
+
if (resolved.fallbacks.length > 0) {
|
|
48
|
+
val += ` \u2192 ${resolved.fallbacks.join(" \u2192 ")}`;
|
|
49
|
+
}
|
|
50
|
+
modelRows.push({ label, value: val });
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
modelRows.push({ label, value: "(inherit)" });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// subagent is a direct config key
|
|
57
|
+
const models = prefs?.models;
|
|
58
|
+
const subVal = models?.subagent;
|
|
59
|
+
if (subVal) {
|
|
60
|
+
const model = typeof subVal === "string" ? subVal : subVal?.model ?? "?";
|
|
61
|
+
modelRows.push({ label: "subagent", value: model });
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
modelRows.push({ label: "subagent", value: "(inherit)" });
|
|
65
|
+
}
|
|
66
|
+
sections.push({ title: "Models", rows: modelRows });
|
|
67
|
+
// ─── Dynamic Routing ─────────────────────────────────────────────────
|
|
68
|
+
const routing = resolveDynamicRoutingConfig();
|
|
69
|
+
const routingRows = [
|
|
70
|
+
{ label: "Enabled", value: routing.enabled ? "yes" : "no", accent: routing.enabled },
|
|
71
|
+
];
|
|
72
|
+
if (routing.enabled) {
|
|
73
|
+
routingRows.push({ label: "Escalate on fail", value: routing.escalate_on_failure !== false ? "yes" : "no" });
|
|
74
|
+
routingRows.push({ label: "Budget pressure", value: routing.budget_pressure !== false ? "yes" : "no" });
|
|
75
|
+
routingRows.push({ label: "Cross-provider", value: routing.cross_provider !== false ? "yes" : "no" });
|
|
76
|
+
if (routing.tier_models) {
|
|
77
|
+
const tm = routing.tier_models;
|
|
78
|
+
if (tm.light)
|
|
79
|
+
routingRows.push({ label: "[L] light", value: tm.light });
|
|
80
|
+
if (tm.standard)
|
|
81
|
+
routingRows.push({ label: "[S] standard", value: tm.standard });
|
|
82
|
+
if (tm.heavy)
|
|
83
|
+
routingRows.push({ label: "[H] heavy", value: tm.heavy });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
sections.push({ title: "Dynamic Routing", rows: routingRows });
|
|
87
|
+
// ─── Git ─────────────────────────────────────────────────────────────
|
|
88
|
+
if (prefs?.git) {
|
|
89
|
+
const g = prefs.git;
|
|
90
|
+
const gitRows = [];
|
|
91
|
+
if (g.isolation !== undefined)
|
|
92
|
+
gitRows.push({ label: "Isolation", value: String(g.isolation) });
|
|
93
|
+
if (g.auto_push !== undefined)
|
|
94
|
+
gitRows.push({ label: "Auto push", value: String(g.auto_push) });
|
|
95
|
+
if (g.push_branches !== undefined)
|
|
96
|
+
gitRows.push({ label: "Push branches", value: String(g.push_branches) });
|
|
97
|
+
if (g.merge_strategy)
|
|
98
|
+
gitRows.push({ label: "Merge strategy", value: g.merge_strategy });
|
|
99
|
+
if (g.main_branch)
|
|
100
|
+
gitRows.push({ label: "Main branch", value: g.main_branch });
|
|
101
|
+
if (g.remote)
|
|
102
|
+
gitRows.push({ label: "Remote", value: g.remote });
|
|
103
|
+
if (gitRows.length > 0)
|
|
104
|
+
sections.push({ title: "Git", rows: gitRows });
|
|
105
|
+
}
|
|
106
|
+
// ─── Budget ──────────────────────────────────────────────────────────
|
|
107
|
+
if (prefs?.budget_ceiling !== undefined || prefs?.budget_enforcement) {
|
|
108
|
+
const budgetRows = [];
|
|
109
|
+
if (prefs.budget_ceiling !== undefined)
|
|
110
|
+
budgetRows.push({ label: "Ceiling", value: `$${prefs.budget_ceiling}` });
|
|
111
|
+
if (prefs.budget_enforcement)
|
|
112
|
+
budgetRows.push({ label: "Enforcement", value: String(prefs.budget_enforcement) });
|
|
113
|
+
sections.push({ title: "Budget", rows: budgetRows });
|
|
114
|
+
}
|
|
115
|
+
// ─── Auto Supervisor ─────────────────────────────────────────────────
|
|
116
|
+
if (prefs?.auto_supervisor) {
|
|
117
|
+
const sup = resolveAutoSupervisorConfig();
|
|
118
|
+
const supRows = [];
|
|
119
|
+
if (sup.model)
|
|
120
|
+
supRows.push({ label: "Model", value: sup.model });
|
|
121
|
+
supRows.push({ label: "Soft timeout", value: `${sup.soft_timeout_minutes}m` });
|
|
122
|
+
supRows.push({ label: "Idle timeout", value: `${sup.idle_timeout_minutes}m` });
|
|
123
|
+
supRows.push({ label: "Hard timeout", value: `${sup.hard_timeout_minutes}m` });
|
|
124
|
+
sections.push({ title: "Auto Supervisor", rows: supRows });
|
|
125
|
+
}
|
|
126
|
+
// ─── Toggles ─────────────────────────────────────────────────────────
|
|
127
|
+
const toggleRows = [];
|
|
128
|
+
if (prefs?.phases) {
|
|
129
|
+
const p = prefs.phases;
|
|
130
|
+
if (p.skip_research)
|
|
131
|
+
toggleRows.push({ label: "skip_research", value: "on" });
|
|
132
|
+
if (p.skip_reassess)
|
|
133
|
+
toggleRows.push({ label: "skip_reassess", value: "on" });
|
|
134
|
+
if (p.skip_slice_research)
|
|
135
|
+
toggleRows.push({ label: "skip_slice_research", value: "on" });
|
|
136
|
+
if (p.skip_milestone_validation)
|
|
137
|
+
toggleRows.push({ label: "skip_milestone_validation", value: "on" });
|
|
138
|
+
if (p.require_slice_discussion)
|
|
139
|
+
toggleRows.push({ label: "require_slice_discussion", value: "on" });
|
|
140
|
+
}
|
|
141
|
+
if (prefs?.uat_dispatch)
|
|
142
|
+
toggleRows.push({ label: "uat_dispatch", value: "on" });
|
|
143
|
+
if (prefs?.auto_visualize)
|
|
144
|
+
toggleRows.push({ label: "auto_visualize", value: "on" });
|
|
145
|
+
if (prefs?.auto_report === false)
|
|
146
|
+
toggleRows.push({ label: "auto_report", value: "off" });
|
|
147
|
+
if (prefs?.show_token_cost)
|
|
148
|
+
toggleRows.push({ label: "show_token_cost", value: "on" });
|
|
149
|
+
if (prefs?.forensics_dedup)
|
|
150
|
+
toggleRows.push({ label: "forensics_dedup", value: "on" });
|
|
151
|
+
if (prefs?.unique_milestone_ids)
|
|
152
|
+
toggleRows.push({ label: "unique_milestone_ids", value: "on" });
|
|
153
|
+
if (prefs?.service_tier)
|
|
154
|
+
toggleRows.push({ label: "service_tier", value: prefs.service_tier });
|
|
155
|
+
if (prefs?.search_provider && prefs.search_provider !== "auto")
|
|
156
|
+
toggleRows.push({ label: "search_provider", value: prefs.search_provider });
|
|
157
|
+
if (prefs?.context_selection)
|
|
158
|
+
toggleRows.push({ label: "context_selection", value: prefs.context_selection });
|
|
159
|
+
if (prefs?.widget_mode && prefs.widget_mode !== "full")
|
|
160
|
+
toggleRows.push({ label: "widget_mode", value: prefs.widget_mode });
|
|
161
|
+
if (prefs?.experimental?.rtk)
|
|
162
|
+
toggleRows.push({ label: "experimental.rtk", value: "on" });
|
|
163
|
+
if (toggleRows.length > 0)
|
|
164
|
+
sections.push({ title: "Toggles", rows: toggleRows });
|
|
165
|
+
// ─── Parallel ────────────────────────────────────────────────────────
|
|
166
|
+
if (prefs?.parallel) {
|
|
167
|
+
const pc = prefs.parallel;
|
|
168
|
+
const parallelRows = [];
|
|
169
|
+
if (pc.max_workers !== undefined)
|
|
170
|
+
parallelRows.push({ label: "Max workers", value: String(pc.max_workers) });
|
|
171
|
+
if (pc.merge_strategy)
|
|
172
|
+
parallelRows.push({ label: "Merge strategy", value: pc.merge_strategy });
|
|
173
|
+
if (pc.auto_merge)
|
|
174
|
+
parallelRows.push({ label: "Auto merge", value: pc.auto_merge });
|
|
175
|
+
if (parallelRows.length > 0)
|
|
176
|
+
sections.push({ title: "Parallel", rows: parallelRows });
|
|
177
|
+
}
|
|
178
|
+
// ─── Hooks ───────────────────────────────────────────────────────────
|
|
179
|
+
const postHooks = prefs?.post_unit_hooks?.filter(h => h.enabled !== false) ?? [];
|
|
180
|
+
const preHooks = prefs?.pre_dispatch_hooks?.filter(h => h.enabled !== false) ?? [];
|
|
181
|
+
if (postHooks.length > 0 || preHooks.length > 0) {
|
|
182
|
+
const hookRows = [];
|
|
183
|
+
if (preHooks.length > 0)
|
|
184
|
+
hookRows.push({ label: "Pre-dispatch", value: `${preHooks.length} active` });
|
|
185
|
+
if (postHooks.length > 0)
|
|
186
|
+
hookRows.push({ label: "Post-unit", value: `${postHooks.length} active` });
|
|
187
|
+
sections.push({ title: "Hooks", rows: hookRows });
|
|
188
|
+
}
|
|
189
|
+
// ─── Warnings ────────────────────────────────────────────────────────
|
|
190
|
+
const warnings = [
|
|
191
|
+
...(globalPrefs?.warnings ?? []),
|
|
192
|
+
...(projectPrefs?.warnings ?? []),
|
|
193
|
+
];
|
|
194
|
+
if (warnings.length > 0) {
|
|
195
|
+
sections.push({
|
|
196
|
+
title: "Warnings",
|
|
197
|
+
rows: warnings.map(w => ({ label: "\u26a0", value: w })),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
return sections;
|
|
201
|
+
}
|
|
202
|
+
// ─── Plain Text Formatter (headless/RPC fallback) ─────────────────────────
|
|
203
|
+
export function formatConfigText() {
|
|
204
|
+
const sections = collectConfigSections();
|
|
205
|
+
const lines = ["GSD Configuration\n"];
|
|
206
|
+
let maxLabel = 0;
|
|
207
|
+
for (const section of sections) {
|
|
208
|
+
for (const row of section.rows) {
|
|
209
|
+
if (row.label.length > maxLabel)
|
|
210
|
+
maxLabel = row.label.length;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const pad = Math.min(maxLabel + 2, 24);
|
|
214
|
+
for (const section of sections) {
|
|
215
|
+
lines.push("");
|
|
216
|
+
lines.push(section.title.toUpperCase());
|
|
217
|
+
for (const row of section.rows) {
|
|
218
|
+
lines.push(` ${row.label.padEnd(pad)}${row.value}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return lines.join("\n");
|
|
222
|
+
}
|
|
223
|
+
// ─── Overlay Class ────────────────────────────────────────────────────────
|
|
224
|
+
export class GSDConfigOverlay {
|
|
225
|
+
tui;
|
|
226
|
+
theme;
|
|
227
|
+
onClose;
|
|
228
|
+
sections;
|
|
229
|
+
cachedLines;
|
|
230
|
+
scrollOffset = 0;
|
|
231
|
+
disposed = false;
|
|
232
|
+
constructor(tui, theme, onClose) {
|
|
233
|
+
this.tui = tui;
|
|
234
|
+
this.theme = theme;
|
|
235
|
+
this.onClose = onClose;
|
|
236
|
+
this.sections = collectConfigSections();
|
|
237
|
+
}
|
|
238
|
+
invalidate() {
|
|
239
|
+
this.cachedLines = undefined;
|
|
240
|
+
}
|
|
241
|
+
dispose() {
|
|
242
|
+
this.disposed = true;
|
|
243
|
+
}
|
|
244
|
+
handleInput(data) {
|
|
245
|
+
if (matchesKey(data, Key.escape) || data === "q") {
|
|
246
|
+
this.dispose();
|
|
247
|
+
this.onClose();
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (matchesKey(data, Key.down) || data === "j") {
|
|
251
|
+
this.scrollOffset++;
|
|
252
|
+
this.cachedLines = undefined;
|
|
253
|
+
this.tui.requestRender();
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (matchesKey(data, Key.up) || data === "k") {
|
|
257
|
+
this.scrollOffset = Math.max(0, this.scrollOffset - 1);
|
|
258
|
+
this.cachedLines = undefined;
|
|
259
|
+
this.tui.requestRender();
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (matchesKey(data, Key.pageDown)) {
|
|
263
|
+
this.scrollOffset += 10;
|
|
264
|
+
this.cachedLines = undefined;
|
|
265
|
+
this.tui.requestRender();
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (matchesKey(data, Key.pageUp)) {
|
|
269
|
+
this.scrollOffset = Math.max(0, this.scrollOffset - 10);
|
|
270
|
+
this.cachedLines = undefined;
|
|
271
|
+
this.tui.requestRender();
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
render(width) {
|
|
276
|
+
if (this.cachedLines)
|
|
277
|
+
return this.cachedLines;
|
|
278
|
+
const t = this.theme;
|
|
279
|
+
const w = Math.max(width, 50);
|
|
280
|
+
const allLines = [];
|
|
281
|
+
// Header
|
|
282
|
+
allLines.push(t.bold(t.fg("accent", " GSD Configuration ")));
|
|
283
|
+
allLines.push(t.fg("muted", "\u2500".repeat(w)));
|
|
284
|
+
// Find max label width for alignment
|
|
285
|
+
let maxLabel = 0;
|
|
286
|
+
for (const section of this.sections) {
|
|
287
|
+
for (const row of section.rows) {
|
|
288
|
+
if (row.label.length > maxLabel)
|
|
289
|
+
maxLabel = row.label.length;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const labelPad = Math.min(maxLabel + 2, 24);
|
|
293
|
+
for (const section of this.sections) {
|
|
294
|
+
allLines.push("");
|
|
295
|
+
allLines.push(t.bold(t.fg("accent", ` ${section.title}`)));
|
|
296
|
+
for (const row of section.rows) {
|
|
297
|
+
const label = t.fg("muted", ` ${row.label.padEnd(labelPad)}`);
|
|
298
|
+
const value = row.accent ? t.bold(row.value) : row.value;
|
|
299
|
+
allLines.push(truncateToWidth(`${label}${value}`, w));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
allLines.push("");
|
|
303
|
+
allLines.push(t.fg("muted", ` ${"\u2500".repeat(w - 4)}`));
|
|
304
|
+
allLines.push(t.fg("muted", " esc/q close \u2502 \u2191\u2193/jk scroll \u2502 /gsd prefs to edit"));
|
|
305
|
+
// Apply scroll
|
|
306
|
+
const maxScroll = Math.max(0, allLines.length - 20);
|
|
307
|
+
this.scrollOffset = Math.min(this.scrollOffset, maxScroll);
|
|
308
|
+
const visible = allLines.slice(this.scrollOffset);
|
|
309
|
+
this.cachedLines = visible;
|
|
310
|
+
return visible;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
@@ -945,7 +945,7 @@ function resolveVersionCatalogAccessors(basePath, versionCatalogFiles, settingsF
|
|
|
945
945
|
}
|
|
946
946
|
return accessors;
|
|
947
947
|
}
|
|
948
|
-
function scanProjectFiles(basePath) {
|
|
948
|
+
export function scanProjectFiles(basePath) {
|
|
949
949
|
const files = [];
|
|
950
950
|
const queue = [{ path: basePath, depth: 0 }];
|
|
951
951
|
while (queue.length > 0 && files.length < MAX_RECURSIVE_SCAN_FILES) {
|
|
@@ -4,6 +4,7 @@ import { findMilestoneIds } from "./guided-flow.js";
|
|
|
4
4
|
import { parseUnitId } from "./unit-id.js";
|
|
5
5
|
import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
|
|
6
6
|
import { parseRoadmap } from "./parsers-legacy.js";
|
|
7
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
7
8
|
import { readFileSync } from "node:fs";
|
|
8
9
|
const SLICE_DISPATCH_TYPES = new Set([
|
|
9
10
|
"research-slice",
|
|
@@ -46,7 +47,7 @@ export function getPriorSliceCompletionBlocker(base, _mainBranch, unitType, unit
|
|
|
46
47
|
if (rows.length > 0) {
|
|
47
48
|
slices = rows.map((r) => ({
|
|
48
49
|
id: r.id,
|
|
49
|
-
done: r.status
|
|
50
|
+
done: isClosedStatus(r.status),
|
|
50
51
|
depends: r.depends ?? [],
|
|
51
52
|
}));
|
|
52
53
|
}
|
|
@@ -211,6 +211,7 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
|
|
|
211
211
|
- `budget_ceiling`: number — optional per-parallel-run budget ceiling.
|
|
212
212
|
- `merge_strategy`: `"per-slice"` or `"per-milestone"` — when to merge worktree results back. Default: `"per-milestone"`.
|
|
213
213
|
- `auto_merge`: `"auto"`, `"confirm"`, or `"manual"` — merge behavior after completion. `"auto"` merges immediately; `"confirm"` asks first; `"manual"` leaves branches for you. Default: `"confirm"`.
|
|
214
|
+
- `worker_model`: string — optional model override for parallel milestone workers. When set, workers use this model (e.g. `"claude-haiku-4-5"`) instead of inheriting the coordinator's model. Useful for cost savings on execution-heavy milestones.
|
|
214
215
|
|
|
215
216
|
- `verification_commands`: string[] — shell commands to run as verification after task execution (e.g., `["npm test", "npm run lint"]`). Commands run in order; if any fails, the task is marked as needing fixes.
|
|
216
217
|
|
|
@@ -75,7 +75,8 @@ function validatePreferenceShape(preferences) {
|
|
|
75
75
|
}
|
|
76
76
|
return issues;
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
/** Build STATE.md content from derived state. Exported for guided-flow pre-dispatch rebuild (#3475). */
|
|
79
|
+
export function buildStateMarkdown(state) {
|
|
79
80
|
const lines = [];
|
|
80
81
|
lines.push("# GSD State", "");
|
|
81
82
|
const activeMilestone = state.activeMilestone
|