gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.1b44e695b
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 +93 -18
- package/dist/cli.js +20 -9
- package/dist/headless-ui.js +13 -6
- package/dist/headless.js +9 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +1 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +122 -40
- package/dist/resources/extensions/gsd/auto/orchestrator.js +15 -4
- package/dist/resources/extensions/gsd/auto/phases.js +134 -49
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
- package/dist/resources/extensions/gsd/auto-budget.js +9 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +144 -30
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +329 -137
- package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
- package/dist/resources/extensions/gsd/auto-recovery.js +82 -16
- package/dist/resources/extensions/gsd/auto-start.js +99 -16
- package/dist/resources/extensions/gsd/auto-timers.js +11 -3
- package/dist/resources/extensions/gsd/auto-verification.js +146 -34
- package/dist/resources/extensions/gsd/auto-worktree.js +185 -26
- package/dist/resources/extensions/gsd/auto.js +135 -74
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +65 -10
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +13 -10
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +14 -4
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +55 -7
- package/dist/resources/extensions/gsd/db/auto-workers.js +30 -0
- package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
- package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
- package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor.js +2 -28
- package/dist/resources/extensions/gsd/export-html.js +27 -425
- package/dist/resources/extensions/gsd/forensics.js +10 -3
- package/dist/resources/extensions/gsd/git-service.js +152 -15
- package/dist/resources/extensions/gsd/gsd-db.js +76 -33
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +110 -117
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/init-wizard.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
- package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +121 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
- package/dist/resources/extensions/gsd/pre-execution-checks.js +54 -19
- package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
- package/dist/resources/extensions/gsd/preferences-types.js +3 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +147 -0
- package/dist/resources/extensions/gsd/preferences.js +6 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/repo-identity.js +39 -22
- package/dist/resources/extensions/gsd/repository-registry.js +44 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
- package/dist/resources/extensions/gsd/session-lock.js +15 -2
- package/dist/resources/extensions/gsd/slice-parallel-conflict.js +2 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +84 -5
- package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
- package/dist/resources/extensions/gsd/state.js +28 -7
- package/dist/resources/extensions/gsd/status-guards.js +14 -2
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/dist/resources/extensions/gsd/templates/plan.md +9 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -9
- package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -10
- package/dist/resources/extensions/gsd/tools/exec-tool.js +87 -5
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +32 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +185 -40
- package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +142 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +86 -19
- package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
- package/dist/resources/extensions/gsd/worktree-safety.js +43 -4
- package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
- package/dist/resources/extensions/gsd/worktree-telemetry.js +32 -0
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/shared/interview-ui.js +6 -4
- package/dist/resources/extensions/shared/next-action-ui.js +13 -5
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- package/dist/resources/skills/forensics/SKILL.md +1 -1
- 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 +7 -7
- 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 +5 -5
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- 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.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -7
- 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 +4 -7
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
- package/dist/web/standalone/.next/server/chunks/4266.js +2 -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/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/static/chunks/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
- package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/dist/web/standalone/server.js +1 -1
- package/package.json +4 -4
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +13 -4
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +82 -97
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
- 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 +11 -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-ordering.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -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 +24 -10
- 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-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +91 -102
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +106 -27
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/src/tui.ts +108 -27
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +10 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +19 -6
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +1 -0
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +123 -40
- package/src/resources/extensions/gsd/auto/orchestrator.ts +15 -4
- package/src/resources/extensions/gsd/auto/phases.ts +160 -60
- package/src/resources/extensions/gsd/auto/session.ts +16 -0
- package/src/resources/extensions/gsd/auto/types.ts +3 -0
- package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
- package/src/resources/extensions/gsd/auto-budget.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +164 -29
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +369 -148
- package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
- package/src/resources/extensions/gsd/auto-recovery.ts +86 -13
- package/src/resources/extensions/gsd/auto-start.ts +109 -14
- package/src/resources/extensions/gsd/auto-timers.ts +10 -3
- package/src/resources/extensions/gsd/auto-verification.ts +174 -42
- package/src/resources/extensions/gsd/auto-worktree.ts +202 -30
- package/src/resources/extensions/gsd/auto.ts +172 -81
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +66 -10
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -10
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -4
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -3
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- package/src/resources/extensions/gsd/crash-recovery.ts +55 -6
- package/src/resources/extensions/gsd/db/auto-workers.ts +37 -0
- package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
- package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
- package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -27
- package/src/resources/extensions/gsd/export-html.ts +27 -427
- package/src/resources/extensions/gsd/forensics.ts +9 -3
- package/src/resources/extensions/gsd/git-service.ts +182 -16
- package/src/resources/extensions/gsd/gsd-db.ts +80 -31
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +142 -134
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/init-wizard.ts +17 -2
- package/src/resources/extensions/gsd/journal.ts +8 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
- package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +139 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
- package/src/resources/extensions/gsd/pre-execution-checks.ts +67 -19
- package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
- package/src/resources/extensions/gsd/preferences-types.ts +35 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +154 -0
- package/src/resources/extensions/gsd/preferences.ts +9 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/repo-identity.ts +45 -25
- package/src/resources/extensions/gsd/repository-registry.ts +77 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
- package/src/resources/extensions/gsd/session-lock.ts +15 -2
- package/src/resources/extensions/gsd/slice-parallel-conflict.ts +2 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +75 -3
- package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
- package/src/resources/extensions/gsd/state.ts +33 -7
- package/src/resources/extensions/gsd/status-guards.ts +16 -2
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/src/resources/extensions/gsd/templates/plan.md +9 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +775 -34
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +245 -28
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +136 -13
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-workers.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +55 -2
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +60 -9
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +140 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +99 -1
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +15 -1
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +226 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +5 -21
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
- package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +21 -40
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +59 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +28 -1
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +59 -1
- package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +112 -1
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +94 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +188 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +153 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +73 -2
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +18 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +57 -10
- package/src/resources/extensions/gsd/tools/exec-tool.ts +98 -5
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +31 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +166 -17
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +170 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +98 -20
- package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
- package/src/resources/extensions/gsd/worktree-safety.ts +57 -10
- package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
- package/src/resources/extensions/gsd/worktree-telemetry.ts +39 -0
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/shared/interview-ui.ts +6 -4
- package/src/resources/extensions/shared/next-action-ui.ts +11 -5
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
- package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +32 -0
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/src/resources/skills/forensics/SKILL.md +1 -1
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → Z8H5evS-hDo0qdP22XJPA}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → Z8H5evS-hDo0qdP22XJPA}/_ssgManifest.js +0 -0
|
@@ -487,17 +487,18 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
487
487
|
promptGuidelines: [
|
|
488
488
|
"Use gsd_plan_milestone for milestone planning instead of writing ROADMAP.md directly.",
|
|
489
489
|
"Keep parameters flat and provide the full milestone planning payload, including slices.",
|
|
490
|
+
"Milestone and slice titles must not contain forward slash (/), en dash, or em dash characters.",
|
|
490
491
|
"The tool validates input, writes milestone and slice planning data transactionally, renders ROADMAP.md from DB, and clears both state and parse caches after success.",
|
|
491
492
|
"Use the canonical name gsd_plan_milestone; gsd_milestone_plan is only an alias.",
|
|
492
493
|
],
|
|
493
494
|
parameters: Type.Object({
|
|
494
495
|
// ── Core identification + content (required) ──────────────────────
|
|
495
496
|
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
496
|
-
title: Type.String({ description: "Milestone title" }),
|
|
497
|
+
title: Type.String({ description: "Milestone title; must not contain forward slash (/), en dash, or em dash characters" }),
|
|
497
498
|
vision: Type.String({ description: "Milestone vision" }),
|
|
498
499
|
slices: Type.Array(Type.Object({
|
|
499
500
|
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
500
|
-
title: Type.String({ description: "Slice title" }),
|
|
501
|
+
title: Type.String({ description: "Slice title; must not contain forward slash (/), en dash, or em dash characters" }),
|
|
501
502
|
risk: Type.String({ description: "Slice risk" }),
|
|
502
503
|
depends: Type.Array(Type.String(), { description: "Slice dependency IDs" }),
|
|
503
504
|
demo: Type.String({ description: "Roadmap demo text / After this" }),
|
|
@@ -570,10 +571,10 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
570
571
|
title: Type.String({ description: "Task title" }),
|
|
571
572
|
description: Type.String({ description: "Task description / steps block" }),
|
|
572
573
|
estimate: Type.String({ description: "Task estimate string" }),
|
|
573
|
-
files: Type.Array(Type.String(), { description: "
|
|
574
|
+
files: Type.Array(Type.String(), { description: "Array<string> of files likely touched; pass [\"path\"] or [], never a single string" }),
|
|
574
575
|
verify: Type.String({ description: "Verification command or block" }),
|
|
575
|
-
inputs: Type.Array(Type.String(), { description: "
|
|
576
|
-
expectedOutput: Type.Array(Type.String(), { description: "
|
|
576
|
+
inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
|
|
577
|
+
expectedOutput: Type.Array(Type.String(), { description: "Array<string> of expected output files or artifacts; pass [\"path\"] or [], never a single string" }),
|
|
577
578
|
observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
|
|
578
579
|
}), { description: "Planned tasks for the slice" }),
|
|
579
580
|
// ── Enrichment metadata (optional — defaults to empty) ────────────
|
|
@@ -650,10 +651,10 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
650
651
|
title: Type.String({ description: "Task title" }),
|
|
651
652
|
description: Type.String({ description: "Task description / steps block" }),
|
|
652
653
|
estimate: Type.String({ description: "Task estimate string" }),
|
|
653
|
-
files: Type.Array(Type.String(), { description: "
|
|
654
|
+
files: Type.Array(Type.String(), { description: "Array<string> of files likely touched; pass [\"path\"] or [], never a single string" }),
|
|
654
655
|
verify: Type.String({ description: "Verification command or block" }),
|
|
655
|
-
inputs: Type.Array(Type.String(), { description: "
|
|
656
|
-
expectedOutput: Type.Array(Type.String(), { description: "
|
|
656
|
+
inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
|
|
657
|
+
expectedOutput: Type.Array(Type.String(), { description: "Array<string> of expected output files or artifacts; pass [\"path\"] or [], never a single string" }),
|
|
657
658
|
observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
|
|
658
659
|
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
659
660
|
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
@@ -912,7 +913,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
912
913
|
label: "Skip Slice",
|
|
913
914
|
description:
|
|
914
915
|
"Mark a slice as skipped so auto-mode advances past it without executing. " +
|
|
915
|
-
"Non-closed tasks within the slice are cascaded to skipped so milestone completion is not blocked by leftover pending tasks
|
|
916
|
+
"Non-closed tasks within the slice are cascaded to skipped so milestone completion is not blocked by leftover pending tasks. " +
|
|
916
917
|
"The slice data is preserved for reference. The state machine treats skipped slices like completed ones for dependency satisfaction.",
|
|
917
918
|
promptSnippet: "Skip a GSD slice (mark as skipped, auto-mode will advance past it)",
|
|
918
919
|
promptGuidelines: [
|
|
@@ -992,6 +993,8 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
992
993
|
promptGuidelines: [
|
|
993
994
|
"Use gsd_validate_milestone when all slices are done and the milestone needs validation before completion.",
|
|
994
995
|
"Parameters: milestoneId, verdict, remediationRound, successCriteriaChecklist, sliceDeliveryAudit, crossSliceIntegration, requirementCoverage, verificationClasses (optional), verdictRationale, remediationPlan (optional).",
|
|
996
|
+
"If verification classes were planned, verificationClasses must include canonical class rows using the exact class names Contract, Integration, Operational, and UAT when present in planning.",
|
|
997
|
+
"Planned verification text marked as none/not required/not applicable/N/A (including suffixed variants such as 'not required - backend-only') is treated as not applicable and does not require a class row.",
|
|
995
998
|
"If verdict is 'needs-remediation', also provide remediationPlan and use gsd_reassess_roadmap to add remediation slices to the roadmap.",
|
|
996
999
|
"On success, returns validationPath where VALIDATION.md was written.",
|
|
997
1000
|
],
|
|
@@ -1003,7 +1006,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1003
1006
|
sliceDeliveryAudit: Type.String({ description: "Markdown table auditing each slice's claimed vs delivered output" }),
|
|
1004
1007
|
crossSliceIntegration: Type.String({ description: "Markdown describing any cross-slice boundary mismatches" }),
|
|
1005
1008
|
requirementCoverage: Type.String({ description: "Markdown describing any unaddressed requirements" }),
|
|
1006
|
-
verificationClasses: Type.Optional(Type.String({ description: "Markdown describing verification class compliance and gaps" })),
|
|
1009
|
+
verificationClasses: Type.Optional(Type.String({ description: "Markdown describing verification class compliance and gaps using canonical class names (Contract, Integration, Operational, UAT) for each applicable planned class" })),
|
|
1007
1010
|
verdictRationale: Type.String({ description: "Why this verdict was chosen" }),
|
|
1008
1011
|
remediationPlan: Type.Optional(Type.String({ description: "Remediation plan (required if verdict is needs-remediation)" })),
|
|
1009
1012
|
}),
|
|
@@ -31,6 +31,7 @@ import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
|
31
31
|
import { extractSubagentAgentClasses } from "./subagent-input.js";
|
|
32
32
|
import { approvalGateIdForUnit, isExplicitApprovalResponse, shouldPauseForUserApprovalQuestion } from "../user-input-boundary.js";
|
|
33
33
|
import { resolveSkillManifest } from "../skill-manifest.js";
|
|
34
|
+
import { getGuidedUnitContext } from "../guided-unit-context.js";
|
|
34
35
|
|
|
35
36
|
let approvalQuestionAbortInFlight = false;
|
|
36
37
|
|
|
@@ -507,6 +508,13 @@ export function registerHooks(
|
|
|
507
508
|
const milestoneId = extractDepthVerificationMilestoneId(pendingApprovalGate);
|
|
508
509
|
if (milestoneId) markDepthVerified(milestoneId, beforeAgentBasePath);
|
|
509
510
|
clearPendingGate(beforeAgentBasePath);
|
|
511
|
+
if (isAutoPaused() && !isAutoActive()) {
|
|
512
|
+
const { resumeAutoAfterProviderDelay } = await import("./provider-error-resume.js");
|
|
513
|
+
void resumeAutoAfterProviderDelay(pi, ctx).catch((err) => {
|
|
514
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
515
|
+
ctx.ui.notify(`Failed to resume auto-mode after approval: ${message}`, "warning");
|
|
516
|
+
});
|
|
517
|
+
}
|
|
510
518
|
}
|
|
511
519
|
clearDeferredApprovalGate(beforeAgentBasePath);
|
|
512
520
|
|
|
@@ -640,6 +648,7 @@ export function registerHooks(
|
|
|
640
648
|
if (approvalQuestionAbortInFlight) return;
|
|
641
649
|
|
|
642
650
|
const dash = getAutoRuntimeSnapshot();
|
|
651
|
+
if (dash.active) return;
|
|
643
652
|
let unitType = dash.currentUnit?.type;
|
|
644
653
|
let unitId = dash.currentUnit?.id;
|
|
645
654
|
|
|
@@ -772,7 +781,8 @@ export function registerHooks(
|
|
|
772
781
|
// subagent dispatch. Closes the b23 bug class where a discuss-milestone
|
|
773
782
|
// turn used the host Edit tool to modify user source files.
|
|
774
783
|
const dash = getAutoRuntimeSnapshot();
|
|
775
|
-
const
|
|
784
|
+
const guidedUnit = getGuidedUnitContext(discussionBasePath);
|
|
785
|
+
const activeUnitType = dash.currentUnit?.type ?? guidedUnit?.unitType;
|
|
776
786
|
if (activeUnitType) {
|
|
777
787
|
const manifest = resolveManifest(activeUnitType);
|
|
778
788
|
if (manifest) {
|
|
@@ -791,7 +801,7 @@ export function registerHooks(
|
|
|
791
801
|
const planningGuard = shouldBlockPlanningUnit(
|
|
792
802
|
event.toolName,
|
|
793
803
|
planningInput,
|
|
794
|
-
dash.basePath || discussionBasePath,
|
|
804
|
+
dash.basePath || guidedUnit?.basePath || discussionBasePath,
|
|
795
805
|
activeUnitType,
|
|
796
806
|
manifest.tools,
|
|
797
807
|
agentClasses,
|
|
@@ -805,11 +815,10 @@ export function registerHooks(
|
|
|
805
815
|
// git.isolation=worktree but auto-mode hasn't created the milestone
|
|
806
816
|
// worktree yet. Without this, writes silently orphan outside git history.
|
|
807
817
|
if (isToolCallEventType("write", event) || isToolCallEventType("edit", event)) {
|
|
808
|
-
const wtBasePath = resolveWorktreeProjectRoot(dash.basePath ?? discussionBasePath);
|
|
809
818
|
const wtGuard = shouldBlockWorktreeWrite(
|
|
810
819
|
event.toolName,
|
|
811
820
|
event.input.path,
|
|
812
|
-
|
|
821
|
+
dash.basePath ?? discussionBasePath,
|
|
813
822
|
isAutoActive(),
|
|
814
823
|
dash.currentUnit?.type,
|
|
815
824
|
);
|
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
export function extractSubagentAgentClasses(input: unknown): string[] {
|
|
2
2
|
if (!input || typeof input !== "object") return [];
|
|
3
3
|
|
|
4
|
-
const record = input as Record<string, unknown>;
|
|
5
4
|
const agentClasses: string[] = [];
|
|
5
|
+
const visited = new WeakSet<object>();
|
|
6
6
|
const addAgentClass = (value: unknown): void => {
|
|
7
|
-
if (typeof value
|
|
7
|
+
if (typeof value !== "string") return;
|
|
8
|
+
const normalized = value.trim().replace(/\.md$/i, "");
|
|
9
|
+
if (normalized.length > 0) agentClasses.push(normalized);
|
|
8
10
|
};
|
|
9
|
-
|
|
11
|
+
|
|
12
|
+
const visitItems = (value: unknown): void => {
|
|
10
13
|
if (!Array.isArray(value)) return;
|
|
11
14
|
for (const item of value) {
|
|
12
|
-
|
|
15
|
+
visit(item);
|
|
13
16
|
}
|
|
14
17
|
};
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
const visit = (value: unknown): void => {
|
|
20
|
+
if (!value || typeof value !== "object") return;
|
|
21
|
+
if (visited.has(value)) return;
|
|
22
|
+
visited.add(value);
|
|
23
|
+
const record = value as Record<string, unknown>;
|
|
24
|
+
addAgentClass(record.agent);
|
|
25
|
+
visitItems(record.tasks);
|
|
26
|
+
visitItems(record.chain);
|
|
27
|
+
visitItems(record.parallel);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
visit(input);
|
|
19
31
|
return agentClasses;
|
|
20
32
|
}
|
|
@@ -5,7 +5,7 @@ import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
|
5
5
|
import { minimatch } from "minimatch";
|
|
6
6
|
|
|
7
7
|
import { getIsolationMode } from "../preferences.js";
|
|
8
|
-
import type
|
|
8
|
+
import { compileSubagentPermissionContract, type ToolsPolicy } from "../unit-context-manifest.js";
|
|
9
9
|
import { logWarning } from "../workflow-logger.js";
|
|
10
10
|
import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
11
11
|
|
|
@@ -64,7 +64,8 @@ const QUEUE_SAFE_TOOLS = new Set([
|
|
|
64
64
|
* env / printenv — print environment variables
|
|
65
65
|
* true / false — shell no-ops / test exit codes
|
|
66
66
|
*/
|
|
67
|
-
const BASH_READ_ONLY_RE = /^\s*(cat|head|tail|less|more|wc|file|stat|du|df|which|type|echo|printf|ls|find|grep|rg|awk|sed\b(?!.*-i)|sort|uniq|diff|comm|tr|cut|tee\s+-a\s+\/dev\/null|git\s+(log|show|diff|status|branch|tag|remote|rev-parse|ls-files|blame|shortlog|describe|stash\s+list|config\s+--get|cat-file)|gh\s+(issue|pr|api|repo|release)\s+(view|list|diff|status|checks)|mkdir\s+-p\s+\.gsd|rtk\s|npm\s+run\s+(test|test:\w+|lint|lint:\w+|typecheck|type-check|type-check:\w+|check|verify|audit|outdated|format:check|ci|validate)\b|npm\s+(ls|list|info|view|show|outdated|audit|explain|doctor|ping|--version|-v)\b|npx\s|tsx\s|node\s+(--print|--version|-v\b)|python[23]?\s+(-c\s+'[^']*'|--version|-V\b|-m\s+(pip\s+show|pip\s+list|site))|pip[23]?\s+(show|list|freeze|check|index\s+versions)\b|jq\s|yq\s|curl\s+(-s\b|--silent\b)(?!\s+[^|>]*\s-[oO]\b)(?!\s+[^|>]*\s--output\b)[^|>]*$|openssl\s+(version|x509|s_client)|env\b|printenv\b|true\b|false\b)/;
|
|
67
|
+
const BASH_READ_ONLY_RE = /^\s*((?:cd|pushd|popd)(?:\s|$)|cat|head|tail|less|more|wc|file|stat|du|df|which|type|echo|printf|ls|find|grep|rg|awk|sed\b(?!.*-i)|sort|uniq|diff|comm|tr|cut|tee\s+-a\s+\/dev\/null|git\s+(log|show|diff|status|branch|tag|remote|rev-parse|ls-files|blame|shortlog|describe|stash\s+list|config\s+--get|cat-file)|gh\s+(issue|pr|api|repo|release)\s+(view|list|diff|status|checks)|mkdir\s+-p\s+\.gsd|rtk\s|npm\s+run\s+(test|test:\w+|lint|lint:\w+|typecheck|type-check|type-check:\w+|check|verify|audit|outdated|format:check|ci|validate)\b|npm\s+(ls|list|info|view|show|outdated|audit|explain|doctor|ping|--version|-v)\b|npx\s|tsx\s|node\s+(--print|--version|-v\b)|python[23]?\s+(-c\s+'[^']*'|--version|-V\b|-m\s+(pip\s+show|pip\s+list|site))|pip[23]?\s+(show|list|freeze|check|index\s+versions)\b|jq\s|yq\s|curl\s+(-s\b|--silent\b)(?!\s+[^|>]*\s-[oO]\b)(?!\s+[^|>]*\s--output\b)[^|>]*$|openssl\s+(version|x509|s_client)|env\b|printenv\b|true\b|false\b)/;
|
|
68
|
+
const BASH_VERIFICATION_RE = /^\s*(npm\s+(run\s+(build|test|test:\w+|lint|lint:\w+|typecheck|type-check|verify|ci|validate)\b|test\b)|pnpm\s+(build|test|lint|typecheck|verify)\b|yarn\s+(build|test|lint|typecheck|verify)\b|vitest\b|jest\b|go\s+test\b)/;
|
|
68
69
|
|
|
69
70
|
interface InMemoryWriteGateState {
|
|
70
71
|
verifiedDepthMilestones: Set<string>;
|
|
@@ -747,7 +748,7 @@ function matchesAllowedGlob(absPath: string, basePath: string, globs: readonly s
|
|
|
747
748
|
function blockReason(unitType: string, mode: string, what: string): string {
|
|
748
749
|
return [
|
|
749
750
|
`HARD BLOCK: unit "${unitType}" runs under tools-policy "${mode}" — ${what}.`,
|
|
750
|
-
`This is a mechanical gate enforced by manifest.tools
|
|
751
|
+
`This is a mechanical gate enforced by manifest.tools. You MUST NOT proceed,`,
|
|
751
752
|
`retry the same call, or rationalize past this block. If you need to write user source,`,
|
|
752
753
|
`the work belongs in execute-task, not in a planning unit.`,
|
|
753
754
|
].join(" ");
|
|
@@ -767,6 +768,9 @@ function blockReason(unitType: string, mode: string, what: string): string {
|
|
|
767
768
|
* and listed in the policy's allowedSubagents.
|
|
768
769
|
* - "docs" → like "planning" but also allows writes to paths
|
|
769
770
|
* matching `allowedPathGlobs` relative to basePath.
|
|
771
|
+
* - "verification"
|
|
772
|
+
* → allows Bash for project verification commands, but keeps
|
|
773
|
+
* writes restricted to .gsd/ and blocks subagent dispatch.
|
|
770
774
|
*
|
|
771
775
|
* `pathOrCommand` is the file path for write/edit-shaped tools and the
|
|
772
776
|
* shell command for bash. Other tools ignore this argument.
|
|
@@ -804,14 +808,15 @@ export function shouldBlockPlanningUnit(
|
|
|
804
808
|
return { block: true, reason: blockReason(unitType, policy.mode, `tool "${tool}" is not on the read-only allowlist`) };
|
|
805
809
|
}
|
|
806
810
|
|
|
807
|
-
// planning / planning-dispatch / docs modes share the same surface for safe tools, bash, and subagent.
|
|
811
|
+
// planning / planning-dispatch / docs / verification modes share the same surface for safe tools, bash, and subagent.
|
|
808
812
|
if (PLANNING_SAFE_TOOLS.has(tool)) return { block: false };
|
|
809
813
|
if (tool.startsWith("gsd_")) return { block: false };
|
|
810
814
|
|
|
811
815
|
if (PLANNING_SUBAGENT_TOOLS.has(tool)) {
|
|
812
816
|
if (policy.mode === "planning-dispatch") {
|
|
813
817
|
const requested = (agentClasses ?? []).map(a => a.trim()).filter(Boolean);
|
|
814
|
-
const
|
|
818
|
+
const dispatchContract = compileSubagentPermissionContract(policy);
|
|
819
|
+
const allowedSubagents = dispatchContract.allowedSubagents;
|
|
815
820
|
const allowed = new Set(allowedSubagents);
|
|
816
821
|
// When agentClasses is undefined, the caller has not been updated to extract
|
|
817
822
|
// agent identities yet. Block and warn so stale callers surface in telemetry
|
|
@@ -861,6 +866,17 @@ export function shouldBlockPlanningUnit(
|
|
|
861
866
|
}
|
|
862
867
|
|
|
863
868
|
if (tool === "bash") {
|
|
869
|
+
if (policy.mode === "verification") {
|
|
870
|
+
if (BASH_VERIFICATION_RE.test(pathOrCommand) || BASH_READ_ONLY_RE.test(pathOrCommand)) return { block: false };
|
|
871
|
+
return {
|
|
872
|
+
block: true,
|
|
873
|
+
reason: blockReason(
|
|
874
|
+
unitType,
|
|
875
|
+
policy.mode,
|
|
876
|
+
`bash is restricted to build/test verification commands (npm run build, npm test, etc.); cannot run "${pathOrCommand.slice(0, 80)}${pathOrCommand.length > 80 ? "…" : ""}"`,
|
|
877
|
+
),
|
|
878
|
+
};
|
|
879
|
+
}
|
|
864
880
|
if (BASH_READ_ONLY_RE.test(pathOrCommand)) return { block: false };
|
|
865
881
|
return {
|
|
866
882
|
block: true,
|
|
@@ -951,9 +967,9 @@ function isPathContained(target: string, container: string): boolean {
|
|
|
951
967
|
* while `git.isolation: worktree` is in effect and auto-mode hasn't created
|
|
952
968
|
* (or flipped cwd into) the milestone worktree.
|
|
953
969
|
*
|
|
954
|
-
* Pure / unit-testable. Callers in `register-hooks.ts` supply the
|
|
955
|
-
* project root and current auto liveness;
|
|
956
|
-
* realpath resolution.
|
|
970
|
+
* Pure / unit-testable. Callers in `register-hooks.ts` supply the effective
|
|
971
|
+
* execution base path (worker cwd or project root) and current auto liveness;
|
|
972
|
+
* this function does no I/O beyond realpath resolution.
|
|
957
973
|
*
|
|
958
974
|
* Allow rules (in order):
|
|
959
975
|
* 1. Tool isn't a planning-write (write/edit/multi_edit/notebook_edit).
|
|
@@ -991,10 +1007,11 @@ export function shouldBlockWorktreeWrite(
|
|
|
991
1007
|
};
|
|
992
1008
|
}
|
|
993
1009
|
|
|
994
|
-
// Resolve
|
|
1010
|
+
// Resolve relative targets against the effective execution base path, then
|
|
1011
|
+
// canonicalize against the project root to defeat
|
|
995
1012
|
// symlink-based escapes and prefix tricks (e.g. .gsd/worktrees-extra/).
|
|
996
1013
|
const projectRoot = resolveWorktreeProjectRoot(effectiveBasePath);
|
|
997
|
-
const absTarget = isAbsolute(targetPath) ? targetPath : resolve(
|
|
1014
|
+
const absTarget = isAbsolute(targetPath) ? targetPath : resolve(effectiveBasePath, targetPath);
|
|
998
1015
|
const realTarget = realpathOrResolve(absTarget);
|
|
999
1016
|
const realRoot = realpathOrResolve(projectRoot);
|
|
1000
1017
|
const realGsd = realpathOrResolve(join(projectRoot, ".gsd"));
|
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Design constraints (from Trek-e approval):
|
|
10
10
|
* - Warn the user before stashing (no silent surprises)
|
|
11
|
-
* - git stash push / git stash
|
|
12
|
-
* - Stash/
|
|
11
|
+
* - git stash push / git stash apply+drop for targeted restore
|
|
12
|
+
* - Stash/apply errors are logged but MUST NOT block the merge itself
|
|
13
13
|
* - Fast-path status check — clean trees pay no extra cost
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { execFileSync } from "node:child_process";
|
|
17
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
17
19
|
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
18
20
|
import { logWarning } from "./workflow-logger.js";
|
|
19
21
|
import { nativeHasChanges } from "./native-git-bridge.js";
|
|
@@ -32,6 +34,148 @@ export interface PostflightResult {
|
|
|
32
34
|
needsManualRecovery: boolean;
|
|
33
35
|
message: string;
|
|
34
36
|
stashRef?: string;
|
|
37
|
+
resolution?: "applied" | "already-present-dropped" | "already-present-preserved" | "manual-recovery";
|
|
38
|
+
collidedPaths?: string[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function gitText(basePath: string, args: string[]): string {
|
|
42
|
+
return execFileSync("git", args, {
|
|
43
|
+
cwd: basePath,
|
|
44
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
45
|
+
encoding: "utf-8",
|
|
46
|
+
env: GIT_NO_PROMPT_ENV,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function gitBuffer(basePath: string, args: string[]): Buffer {
|
|
51
|
+
return execFileSync("git", args, {
|
|
52
|
+
cwd: basePath,
|
|
53
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
54
|
+
env: GIT_NO_PROMPT_ENV,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function errorText(err: unknown): string {
|
|
59
|
+
if (!err || typeof err !== "object") return String(err);
|
|
60
|
+
const parts: string[] = [];
|
|
61
|
+
const stderr = (err as { stderr?: unknown }).stderr;
|
|
62
|
+
const stdout = (err as { stdout?: unknown }).stdout;
|
|
63
|
+
for (const value of [stderr, stdout]) {
|
|
64
|
+
if (typeof value === "string") parts.push(value);
|
|
65
|
+
else if (value instanceof Uint8Array) parts.push(Buffer.from(value).toString("utf-8"));
|
|
66
|
+
}
|
|
67
|
+
parts.push(err instanceof Error ? err.message : String(err));
|
|
68
|
+
return parts.filter(Boolean).join("\n");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function parseAlreadyExistsNoCheckoutPaths(text: string): string[] {
|
|
72
|
+
const paths: string[] = [];
|
|
73
|
+
for (const line of text.split(/\r?\n/)) {
|
|
74
|
+
const match = /^(.+?) already exists, no checkout$/i.exec(line.trim());
|
|
75
|
+
if (match?.[1]) paths.push(match[1]);
|
|
76
|
+
}
|
|
77
|
+
return [...new Set(paths)];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function readZeroDelimitedPaths(output: string): string[] {
|
|
81
|
+
return output.split("\0").filter(Boolean);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function listStashUntrackedPaths(basePath: string, stashRef: string): string[] | null {
|
|
85
|
+
try {
|
|
86
|
+
const output = gitText(basePath, ["ls-tree", "-r", "-z", "--name-only", `${stashRef}^3`]);
|
|
87
|
+
return readZeroDelimitedPaths(output);
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function listStashTrackedPaths(basePath: string, stashRef: string): string[] | null {
|
|
94
|
+
try {
|
|
95
|
+
const output = gitText(basePath, ["diff", "--name-only", "-z", `${stashRef}^1`, stashRef]);
|
|
96
|
+
return readZeroDelimitedPaths(output);
|
|
97
|
+
} catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function isWorktreeClean(basePath: string): boolean | null {
|
|
103
|
+
try {
|
|
104
|
+
return gitText(basePath, ["status", "--porcelain"]).trim() === "";
|
|
105
|
+
} catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function stashBlobEqualsWorktreeFile(basePath: string, stashRef: string, path: string): boolean | null {
|
|
111
|
+
try {
|
|
112
|
+
const worktreePath = join(basePath, path);
|
|
113
|
+
if (!existsSync(worktreePath)) return false;
|
|
114
|
+
const worktreeContent = readFileSync(worktreePath);
|
|
115
|
+
const stashContent = gitBuffer(basePath, ["show", `${stashRef}^3:${path}`]);
|
|
116
|
+
return Buffer.compare(worktreeContent, stashContent) === 0;
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function reconcileAlreadyPresentUntrackedStash(
|
|
123
|
+
basePath: string,
|
|
124
|
+
milestoneId: string,
|
|
125
|
+
stashRef: string,
|
|
126
|
+
err: unknown,
|
|
127
|
+
): PostflightResult | null {
|
|
128
|
+
const text = errorText(err);
|
|
129
|
+
const collidedPaths = parseAlreadyExistsNoCheckoutPaths(text);
|
|
130
|
+
if (collidedPaths.length === 0) return null;
|
|
131
|
+
|
|
132
|
+
const untrackedPaths = listStashUntrackedPaths(basePath, stashRef);
|
|
133
|
+
if (!untrackedPaths || untrackedPaths.length === 0) return null;
|
|
134
|
+
|
|
135
|
+
const trackedPaths = listStashTrackedPaths(basePath, stashRef);
|
|
136
|
+
if (trackedPaths === null || trackedPaths.length > 0) return null;
|
|
137
|
+
|
|
138
|
+
const untrackedPathSet = new Set(untrackedPaths);
|
|
139
|
+
if (!collidedPaths.every((path) => untrackedPathSet.has(path))) return null;
|
|
140
|
+
if (!untrackedPaths.every((path) => existsSync(join(basePath, path)))) return null;
|
|
141
|
+
if (isWorktreeClean(basePath) !== true) return null;
|
|
142
|
+
|
|
143
|
+
const blobComparisons = untrackedPaths.map((path) => stashBlobEqualsWorktreeFile(basePath, stashRef, path));
|
|
144
|
+
if (blobComparisons.some((result) => result === null)) return null;
|
|
145
|
+
const allIdentical = blobComparisons.every(Boolean);
|
|
146
|
+
if (allIdentical) {
|
|
147
|
+
let dropped = true;
|
|
148
|
+
try {
|
|
149
|
+
execFileSync("git", ["stash", "drop", stashRef], {
|
|
150
|
+
cwd: basePath,
|
|
151
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
152
|
+
encoding: "utf-8",
|
|
153
|
+
env: GIT_NO_PROMPT_ENV,
|
|
154
|
+
});
|
|
155
|
+
} catch (err) {
|
|
156
|
+
dropped = false;
|
|
157
|
+
logWarning("preflight", `git stash drop ${stashRef} failed after identical preflight stash reconciliation: ${err instanceof Error ? err.message : String(err)}`);
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
restored: true,
|
|
161
|
+
needsManualRecovery: false,
|
|
162
|
+
message: dropped
|
|
163
|
+
? `Preflight stash for milestone ${milestoneId} contained files already present after merge; identical stash dropped.`
|
|
164
|
+
: `Preflight stash for milestone ${milestoneId} contained files already present after merge, but ${stashRef} could not be dropped and remains as a backup.`,
|
|
165
|
+
stashRef,
|
|
166
|
+
resolution: dropped ? "already-present-dropped" : "already-present-preserved",
|
|
167
|
+
collidedPaths,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
restored: false,
|
|
173
|
+
needsManualRecovery: false,
|
|
174
|
+
message: `Preflight stash for milestone ${milestoneId} contained untracked files already present after merge. Keeping merged files and preserving ${stashRef} as a backup.`,
|
|
175
|
+
stashRef,
|
|
176
|
+
resolution: "already-present-preserved",
|
|
177
|
+
collidedPaths,
|
|
178
|
+
};
|
|
35
179
|
}
|
|
36
180
|
|
|
37
181
|
function findPreflightStashRef(basePath: string, milestoneId: string, stashMarker?: string): string | null {
|
|
@@ -141,27 +285,48 @@ export function postflightPopStash(
|
|
|
141
285
|
message: msg,
|
|
142
286
|
};
|
|
143
287
|
}
|
|
144
|
-
execFileSync("git", ["stash", "
|
|
288
|
+
execFileSync("git", ["stash", "apply", stashRef], {
|
|
145
289
|
cwd: basePath,
|
|
146
290
|
stdio: ["ignore", "pipe", "pipe"],
|
|
147
291
|
encoding: "utf-8",
|
|
148
292
|
env: GIT_NO_PROMPT_ENV,
|
|
149
293
|
});
|
|
294
|
+
let dropWarning: string | null = null;
|
|
295
|
+
try {
|
|
296
|
+
execFileSync("git", ["stash", "drop", stashRef], {
|
|
297
|
+
cwd: basePath,
|
|
298
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
299
|
+
encoding: "utf-8",
|
|
300
|
+
env: GIT_NO_PROMPT_ENV,
|
|
301
|
+
});
|
|
302
|
+
} catch (err) {
|
|
303
|
+
dropWarning = ` Stash was restored, but git stash drop ${stashRef} failed: ${err instanceof Error ? err.message : String(err)}.`;
|
|
304
|
+
logWarning("preflight", dropWarning.trim());
|
|
305
|
+
}
|
|
150
306
|
const msg = `Restored stashed changes after milestone ${milestoneId} merge.`;
|
|
151
|
-
notify(msg
|
|
307
|
+
notify(`${msg}${dropWarning ?? ""}`, dropWarning ? "warning" : "info");
|
|
152
308
|
return {
|
|
153
309
|
restored: true,
|
|
154
310
|
needsManualRecovery: false,
|
|
155
|
-
message: msg
|
|
311
|
+
message: `${msg}${dropWarning ?? ""}`,
|
|
156
312
|
stashRef,
|
|
313
|
+
resolution: "applied",
|
|
157
314
|
};
|
|
158
315
|
} catch (err) {
|
|
159
|
-
|
|
316
|
+
if (stashRef) {
|
|
317
|
+
const reconciled = reconcileAlreadyPresentUntrackedStash(basePath, milestoneId, stashRef, err);
|
|
318
|
+
if (reconciled) {
|
|
319
|
+
logWarning("preflight", reconciled.message);
|
|
320
|
+
notify(reconciled.message, reconciled.resolution === "already-present-preserved" ? "warning" : "info");
|
|
321
|
+
return reconciled;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// Apply conflicts mean the merged code collides with the stashed changes.
|
|
160
325
|
// Log a warning — the user needs to resolve manually, but the merge succeeded.
|
|
161
326
|
const restoreHint = stashRef
|
|
162
|
-
? `Run "git stash
|
|
327
|
+
? `Run "git stash apply ${stashRef}" manually to restore the correct stash, then "git stash drop ${stashRef}" after recovery.`
|
|
163
328
|
: `Run "git stash list" to find the matching GSD preflight stash before restoring manually.`;
|
|
164
|
-
const msg = `git stash
|
|
329
|
+
const msg = `git stash apply ${stashRef ?? ""}`.trim() + ` failed after merge of milestone ${milestoneId}: ${err instanceof Error ? err.message : String(err)}. ${restoreHint}`;
|
|
165
330
|
logWarning("preflight", msg);
|
|
166
331
|
notify(msg, "warning");
|
|
167
332
|
return {
|
|
@@ -169,6 +334,7 @@ export function postflightPopStash(
|
|
|
169
334
|
needsManualRecovery: true,
|
|
170
335
|
message: msg,
|
|
171
336
|
...(stashRef ? { stashRef } : {}),
|
|
337
|
+
resolution: "manual-recovery",
|
|
172
338
|
};
|
|
173
339
|
}
|
|
174
340
|
}
|
|
@@ -3,6 +3,7 @@ import { join, resolve } from "node:path";
|
|
|
3
3
|
|
|
4
4
|
import { loadRegistry } from "../workflow-templates.js";
|
|
5
5
|
import { gsdHome } from "../gsd-home.js";
|
|
6
|
+
import { VISUAL_BRIEF_MODES } from "../../visual-brief/prompts.js";
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
export interface GsdCommandDefinition {
|
|
@@ -13,7 +14,7 @@ export interface GsdCommandDefinition {
|
|
|
13
14
|
type CompletionMap = Record<string, readonly GsdCommandDefinition[]>;
|
|
14
15
|
|
|
15
16
|
export const GSD_COMMAND_DESCRIPTION =
|
|
16
|
-
"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|new-project|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|fast|mcp|rethink|workflow|codebase|notifications|ship|do|session-report|backlog|pr-branch|add-tests|scan|language|worktree|eval-review";
|
|
17
|
+
"GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|brief|queue|quick|discuss|capture|triage|dispatch|verdict|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|new-project|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|fast|mcp|rethink|workflow|codebase|notifications|ship|do|session-report|backlog|pr-branch|add-tests|scan|language|worktree|eval-review";
|
|
17
18
|
|
|
18
19
|
export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
19
20
|
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
@@ -24,6 +25,7 @@ export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
|
24
25
|
{ cmd: "status", desc: "Progress dashboard" },
|
|
25
26
|
{ cmd: "widget", desc: "Cycle widget: full → small → min → off" },
|
|
26
27
|
{ cmd: "visualize", desc: "Open 10-tab workflow visualizer (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)" },
|
|
28
|
+
{ cmd: "brief", desc: "Generate a visual HTML brief: diagram, plan, diff review, recap, table, or slides" },
|
|
27
29
|
{ cmd: "queue", desc: "Queue and reorder future milestones" },
|
|
28
30
|
{ cmd: "quick", desc: "Execute a quick task without full planning overhead" },
|
|
29
31
|
{ cmd: "discuss", desc: "Discuss architecture and decisions" },
|
|
@@ -31,6 +33,7 @@ export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
|
31
33
|
{ cmd: "changelog", desc: "Show categorized release notes" },
|
|
32
34
|
{ cmd: "triage", desc: "Manually trigger triage of pending captures" },
|
|
33
35
|
{ cmd: "dispatch", desc: "Dispatch a specific phase directly" },
|
|
36
|
+
{ cmd: "verdict", desc: "Override the recorded milestone validation verdict (pass|needs-attention|needs-remediation)" },
|
|
34
37
|
{ cmd: "history", desc: "View execution history" },
|
|
35
38
|
{ cmd: "undo", desc: "Revert last completed unit" },
|
|
36
39
|
{ cmd: "undo-task", desc: "Reset a specific task's completion state (DB + markdown)" },
|
|
@@ -88,6 +91,7 @@ export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
|
88
91
|
];
|
|
89
92
|
|
|
90
93
|
const NESTED_COMPLETIONS: CompletionMap = {
|
|
94
|
+
brief: VISUAL_BRIEF_MODES.map((mode) => ({ cmd: mode.mode, desc: mode.description })),
|
|
91
95
|
auto: [
|
|
92
96
|
{ cmd: "--verbose", desc: "Show detailed execution output" },
|
|
93
97
|
{ cmd: "--debug", desc: "Enable debug logging" },
|
|
@@ -245,6 +249,11 @@ const NESTED_COMPLETIONS: CompletionMap = {
|
|
|
245
249
|
{ cmd: "uat", desc: "Run user acceptance testing" },
|
|
246
250
|
{ cmd: "replan", desc: "Replan the current slice" },
|
|
247
251
|
],
|
|
252
|
+
verdict: [
|
|
253
|
+
{ cmd: "pass", desc: "Override the milestone validation verdict to pass" },
|
|
254
|
+
{ cmd: "needs-attention", desc: "Override the verdict to needs-attention (requires --rationale)" },
|
|
255
|
+
{ cmd: "needs-remediation", desc: "Override the verdict to needs-remediation (requires --rationale)" },
|
|
256
|
+
],
|
|
248
257
|
rate: [
|
|
249
258
|
{ cmd: "over", desc: "Model was overqualified for this task" },
|
|
250
259
|
{ cmd: "ok", desc: "Model was appropriate for this task" },
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
2
2
|
import type { Model } from "@gsd/pi-ai";
|
|
3
3
|
import type { GSDState } from "../../types.js";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
4
5
|
|
|
5
6
|
import { computeProgressScore, formatProgressLine } from "../../progress-score.js";
|
|
6
7
|
import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath, getProjectGSDPreferencesPath } from "../../preferences.js";
|
|
@@ -11,6 +12,8 @@ import { handleCmux } from "../../commands-cmux.js";
|
|
|
11
12
|
import { setSessionModelOverride } from "../../session-model-override.js";
|
|
12
13
|
import { projectRoot } from "../context.js";
|
|
13
14
|
import { formattedShortcutPair } from "../../shortcut-defs.js";
|
|
15
|
+
import { getVisualBriefOutputDir } from "../../../visual-brief/artifact-policy.js";
|
|
16
|
+
import { buildVisualBriefPrompt, parseVisualBriefArgs, VISUAL_BRIEF_USAGE } from "../../../visual-brief/prompts.js";
|
|
14
17
|
|
|
15
18
|
export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
|
|
16
19
|
const summaryLines = [
|
|
@@ -27,6 +30,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
|
|
|
27
30
|
` /gsd parallel watch Parallel monitor (${formattedShortcutPair("parallel")})`,
|
|
28
31
|
` /gsd notifications Notification history (${formattedShortcutPair("notifications")})`,
|
|
29
32
|
" /gsd visualize Interactive 10-tab TUI",
|
|
33
|
+
" /gsd brief <mode> Visual HTML brief (diagram, plan, diff, recap, table, slides)",
|
|
30
34
|
" /gsd queue Show queued/dispatched units",
|
|
31
35
|
"",
|
|
32
36
|
"COURSE CORRECTION",
|
|
@@ -67,6 +71,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
|
|
|
67
71
|
" /gsd new-project Bootstrap a new project (use --deep for staged project-level discovery)",
|
|
68
72
|
" /gsd quick Execute a quick task without full planning overhead",
|
|
69
73
|
" /gsd dispatch Dispatch a specific phase directly [research|plan|execute|complete|uat|replan]",
|
|
74
|
+
" /gsd verdict <v> Override milestone validation verdict [pass|needs-attention|needs-remediation] [--milestone Mxxx] [--rationale \"...\"]",
|
|
70
75
|
" /gsd parallel Parallel milestone orchestration [start|status|stop|pause|resume|merge|watch]",
|
|
71
76
|
" /gsd workflow Custom workflow lifecycle [new|run|list|validate|pause|resume]",
|
|
72
77
|
"",
|
|
@@ -75,6 +80,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
|
|
|
75
80
|
` /gsd parallel watch Open parallel worker monitor (${formattedShortcutPair("parallel")})`,
|
|
76
81
|
" /gsd widget Cycle status widget [full|small|min|off]",
|
|
77
82
|
" /gsd visualize Interactive 10-tab TUI (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)",
|
|
83
|
+
" /gsd brief <mode> Generate a visual HTML brief [diagram|plan|diff|recap|table|slides] [topic] [--slides]",
|
|
78
84
|
" /gsd queue Show queued/dispatched units and execution order",
|
|
79
85
|
" /gsd history View execution history [--cost] [--phase] [--model] [N]",
|
|
80
86
|
" /gsd changelog Show categorized release notes [version]",
|
|
@@ -203,6 +209,37 @@ export async function handleVisualize(ctx: ExtensionCommandContext): Promise<voi
|
|
|
203
209
|
}
|
|
204
210
|
}
|
|
205
211
|
|
|
212
|
+
export async function handleBrief(args: string, ctx: ExtensionCommandContext, pi?: ExtensionAPI): Promise<void> {
|
|
213
|
+
const request = parseVisualBriefArgs(args);
|
|
214
|
+
if (!request) {
|
|
215
|
+
ctx.ui.notify(VISUAL_BRIEF_USAGE, "info");
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!pi?.sendUserMessage) {
|
|
220
|
+
ctx.ui.notify("Visual brief generation is unavailable in this context.", "warning");
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const outputDir = getVisualBriefOutputDir();
|
|
225
|
+
const version = resolveGsdVersion();
|
|
226
|
+
pi.sendUserMessage(buildVisualBriefPrompt(request, { outputDir, version }));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const briefRequire = createRequire(import.meta.url);
|
|
230
|
+
|
|
231
|
+
function resolveGsdVersion(): string | undefined {
|
|
232
|
+
const envVersion = process.env.GSD_VERSION?.trim();
|
|
233
|
+
if (envVersion) return envVersion;
|
|
234
|
+
try {
|
|
235
|
+
const pkg = briefRequire("../../../../../../package.json") as { version?: unknown };
|
|
236
|
+
const fromPkg = typeof pkg.version === "string" ? pkg.version.trim() : "";
|
|
237
|
+
return fromPkg || undefined;
|
|
238
|
+
} catch {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
206
243
|
export async function handleSetup(args: string, ctx: ExtensionCommandContext, pi?: ExtensionAPI): Promise<void> {
|
|
207
244
|
const { detectProjectState, hasGlobalSetup } = await import("../../detection.js");
|
|
208
245
|
const { isOnboardingComplete, readOnboardingRecord } = await import("../../onboarding-state.js");
|
|
@@ -429,6 +466,10 @@ export async function handleCoreCommand(
|
|
|
429
466
|
await handleVisualize(ctx);
|
|
430
467
|
return true;
|
|
431
468
|
}
|
|
469
|
+
if (trimmed === "brief" || trimmed.startsWith("brief ")) {
|
|
470
|
+
await handleBrief(trimmed.replace(/^brief\s*/, "").trim(), ctx, pi);
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
432
473
|
if (trimmed === "widget" || trimmed.startsWith("widget ")) {
|
|
433
474
|
const { cycleWidgetMode, setWidgetMode, getWidgetMode } = await import("../../auto-dashboard.js");
|
|
434
475
|
const arg = trimmed.replace(/^widget\s*/, "").trim();
|