gsd-pi 2.82.0 → 3.0.0
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 +51 -32
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
- package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +19 -6
- package/dist/resources/extensions/gsd/auto/orchestrator.js +124 -6
- package/dist/resources/extensions/gsd/auto/phases.js +90 -31
- package/dist/resources/extensions/gsd/auto/session.js +4 -0
- 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-dashboard.js +66 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +246 -133
- package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
- package/dist/resources/extensions/gsd/auto-recovery.js +71 -14
- package/dist/resources/extensions/gsd/auto-start.js +87 -14
- package/dist/resources/extensions/gsd/auto-verification.js +45 -26
- package/dist/resources/extensions/gsd/auto-worktree.js +176 -10
- package/dist/resources/extensions/gsd/auto.js +178 -63
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -2
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +17 -3
- 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 +39 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
- package/dist/resources/extensions/gsd/context-store.js +112 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +43 -5
- 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-writer.js +150 -84
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +87 -7
- 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 +3 -3
- package/dist/resources/extensions/gsd/git-service.js +45 -3
- package/dist/resources/extensions/gsd/gsd-db.js +21 -6
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +101 -116
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
- package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
- package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
- package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +16 -9
- package/dist/resources/extensions/gsd/md-importer.js +1 -1
- package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
- package/dist/resources/extensions/gsd/migrate/command.js +5 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
- package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
- package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
- package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
- 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 +48 -12
- 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/post-execution-checks.js +73 -2
- package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
- 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/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/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/system.md +2 -2
- package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- 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 +3 -3
- package/dist/resources/extensions/gsd/status-guards.js +11 -0
- package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
- 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 +6 -8
- package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +87 -14
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +68 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -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 +54 -10
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- 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/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- 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/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 +9 -9
- 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-b23b3f6858dc6dc8.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/package.json +6 -5
- 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 +14 -3
- 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-parity.test.ts +244 -0
- 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-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -2
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -1
- package/packages/pi-ai/dist/index.js.map +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/dist/providers/transform-messages.d.ts +11 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/index.ts +7 -2
- 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/src/providers/transform-messages.ts +24 -0
- 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/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
- package/packages/pi-coding-agent/dist/core/system-prompt.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/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.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/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
- 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/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
- 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/src/tests/system-prompt-file-safety.test.ts +22 -0
- 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/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 +5 -0
- 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/terminal.ts +11 -0
- package/packages/pi-tui/src/tui.ts +6 -0
- 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/browser-tools/tools/screenshot.ts +1 -0
- package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
- 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 +9 -0
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +59 -16
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +22 -6
- package/src/resources/extensions/gsd/auto/orchestrator.ts +129 -6
- package/src/resources/extensions/gsd/auto/phases.ts +104 -38
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- 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-dashboard.ts +72 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +21 -19
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +279 -144
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
- package/src/resources/extensions/gsd/auto-recovery.ts +74 -11
- package/src/resources/extensions/gsd/auto-start.ts +94 -12
- package/src/resources/extensions/gsd/auto-verification.ts +58 -36
- package/src/resources/extensions/gsd/auto-worktree.ts +193 -10
- package/src/resources/extensions/gsd/auto.ts +187 -61
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -2
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +20 -4
- 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 +42 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- package/src/resources/extensions/gsd/context-store.ts +120 -1
- package/src/resources/extensions/gsd/crash-recovery.ts +44 -4
- 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-writer.ts +167 -84
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +89 -7
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +3 -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 +3 -3
- package/src/resources/extensions/gsd/git-service.ts +51 -4
- package/src/resources/extensions/gsd/gsd-db.ts +21 -6
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +134 -133
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
- package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
- package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
- package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +16 -9
- package/src/resources/extensions/gsd/md-importer.ts +1 -1
- package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
- package/src/resources/extensions/gsd/migrate/command.ts +5 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
- package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
- package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
- package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
- 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 +54 -12
- 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/post-execution-checks.ts +87 -2
- package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
- 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/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/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/system.md +2 -2
- package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- 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 +3 -3
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
- 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/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 +131 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +487 -4
- 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 +91 -6
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
- 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-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -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 +11 -2
- 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 +4 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +86 -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-writer.test.ts +13 -8
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
- 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/integration/doctor-git.test.ts +44 -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 +112 -1
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
- package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
- package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -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 +63 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- 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-sketch-render.test.ts +157 -0
- 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 +251 -2
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
- 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 +86 -0
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -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 +53 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
- 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/provider-switch-observer.test.ts +252 -0
- 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/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -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 +13 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +103 -7
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -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 +1 -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 +25 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +97 -12
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +78 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -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 +61 -10
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
- package/src/resources/extensions/shared/html-shell.ts +412 -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/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-9ecfd95f343793f0.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/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_ssgManifest.js +0 -0
|
@@ -57,6 +57,12 @@ skills_used:
|
|
|
57
57
|
- {{howToVerifyThisTaskIsActuallyDone}}
|
|
58
58
|
- {{commandToRun_OR_behaviorToCheck}}
|
|
59
59
|
|
|
60
|
+
## Verify Rules
|
|
61
|
+
|
|
62
|
+
- Use a real executable check, not prose.
|
|
63
|
+
- If the check needs file-content assertions, write a `node:test` file and run it with `node --test` or a package test script.
|
|
64
|
+
- Do not use inline `node -e` assertions for verification.
|
|
65
|
+
|
|
60
66
|
## Observability Impact
|
|
61
67
|
|
|
62
68
|
<!-- OMIT THIS SECTION ENTIRELY for simple tasks that don't touch runtime boundaries,
|
|
@@ -72,7 +78,8 @@ skills_used:
|
|
|
72
78
|
<!-- Every input MUST be a backtick-wrapped file path. These paths are machine-parsed to
|
|
73
79
|
derive task dependencies — vague descriptions without paths break dependency detection.
|
|
74
80
|
For the first task in a slice with no prior task outputs, list the existing source files
|
|
75
|
-
this task reads or modifies.
|
|
81
|
+
this task reads or modifies.
|
|
82
|
+
Tool field: inputs must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
|
|
76
83
|
|
|
77
84
|
- `{{filePath}}` — {{whatThisTaskNeedsFromPriorWork}}
|
|
78
85
|
|
|
@@ -82,6 +89,7 @@ skills_used:
|
|
|
82
89
|
or modifies. These paths are machine-parsed to derive task dependencies.
|
|
83
90
|
This task should produce a real increment toward making the slice goal/demo true. A full
|
|
84
91
|
slice plan should not be able to mark every task complete while the claimed slice behavior
|
|
85
|
-
still does not work at the stated proof level.
|
|
92
|
+
still does not work at the stated proof level.
|
|
93
|
+
Tool field: expectedOutput must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
|
|
86
94
|
|
|
87
95
|
- `{{filePath}}` — {{whatThisTaskCreatesOrModifies}}
|
|
@@ -24,11 +24,11 @@ function renderMilestoneSummaryMarkdown(params, completedAt) {
|
|
|
24
24
|
const keyFiles = params.keyFiles ?? [];
|
|
25
25
|
const lessonsLearned = params.lessonsLearned ?? [];
|
|
26
26
|
const keyDecisionsYaml = keyDecisions.length > 0
|
|
27
|
-
? keyDecisions.map(d => ` - ${d}`).join("\n")
|
|
28
|
-
: "
|
|
27
|
+
? `\n${keyDecisions.map(d => ` - ${d}`).join("\n")}`
|
|
28
|
+
: " []";
|
|
29
29
|
const keyFilesYaml = keyFiles.length > 0
|
|
30
|
-
? keyFiles.map(f => ` - ${f}`).join("\n")
|
|
31
|
-
: "
|
|
30
|
+
? `\n${keyFiles.map(f => ` - ${f}`).join("\n")}`
|
|
31
|
+
: " []";
|
|
32
32
|
const lessonsYaml = lessonsLearned.length > 0
|
|
33
33
|
? lessonsLearned.map(l => ` - ${l}`).join("\n")
|
|
34
34
|
: " - (none)";
|
|
@@ -37,10 +37,8 @@ id: ${params.milestoneId}
|
|
|
37
37
|
title: "${displayTitle}"
|
|
38
38
|
status: complete
|
|
39
39
|
completed_at: ${completedAt}
|
|
40
|
-
key_decisions
|
|
41
|
-
|
|
42
|
-
key_files:
|
|
43
|
-
${keyFilesYaml}
|
|
40
|
+
key_decisions:${keyDecisionsYaml}
|
|
41
|
+
key_files:${keyFilesYaml}
|
|
44
42
|
lessons_learned:
|
|
45
43
|
${lessonsYaml}
|
|
46
44
|
---
|
|
@@ -65,11 +65,11 @@ function renderSliceSummaryMarkdown(params) {
|
|
|
65
65
|
? affects.map(a => ` - ${a}`).join("\n")
|
|
66
66
|
: " []";
|
|
67
67
|
const keyFilesYaml = keyFiles.length > 0
|
|
68
|
-
? keyFiles.map(f => ` - ${f}`).join("\n")
|
|
69
|
-
: "
|
|
68
|
+
? `\n${keyFiles.map(f => ` - ${f}`).join("\n")}`
|
|
69
|
+
: " []";
|
|
70
70
|
const keyDecisionsYaml = keyDecisions.length > 0
|
|
71
|
-
? keyDecisions.map(d => ` - ${d}`).join("\n")
|
|
72
|
-
: "
|
|
71
|
+
? `\n${keyDecisions.map(d => ` - ${d}`).join("\n")}`
|
|
72
|
+
: " []";
|
|
73
73
|
const patternsYaml = patternsEstablished.length > 0
|
|
74
74
|
? patternsEstablished.map(p => ` - ${p}`).join("\n")
|
|
75
75
|
: " - (none)";
|
|
@@ -106,10 +106,8 @@ requires:
|
|
|
106
106
|
${requiresYaml}
|
|
107
107
|
affects:
|
|
108
108
|
${affectsYaml}
|
|
109
|
-
key_files
|
|
110
|
-
|
|
111
|
-
key_decisions:
|
|
112
|
-
${keyDecisionsYaml}
|
|
109
|
+
key_files:${keyFilesYaml}
|
|
110
|
+
key_decisions:${keyDecisionsYaml}
|
|
113
111
|
patterns_established:
|
|
114
112
|
${patternsYaml}
|
|
115
113
|
observability_surfaces:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
2
|
import { isClosedStatus } from "../status-guards.js";
|
|
3
|
-
import { isNonEmptyString, validateStringArray } from "../validation.js";
|
|
3
|
+
import { isNonEmptyString, validateStringArray, validateTitle } from "../validation.js";
|
|
4
4
|
import { transaction, getMilestone, getMilestoneSlices, getSlice, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
|
|
5
5
|
import { invalidateStateCache } from "../state.js";
|
|
6
6
|
import { renderRoadmapFromDb } from "../markdown-renderer.js";
|
|
@@ -77,6 +77,9 @@ function validateSlices(value) {
|
|
|
77
77
|
seen.add(sliceId);
|
|
78
78
|
if (!isNonEmptyString(title))
|
|
79
79
|
throw new Error(`slices[${index}].title must be a non-empty string`);
|
|
80
|
+
const titleIssue = validateTitle(title);
|
|
81
|
+
if (titleIssue)
|
|
82
|
+
throw new Error(`slices[${index}].title is invalid: ${titleIssue}`);
|
|
80
83
|
if (!isNonEmptyString(risk))
|
|
81
84
|
throw new Error(`slices[${index}].risk must be a non-empty string`);
|
|
82
85
|
if (!Array.isArray(depends) || depends.some((item) => !isNonEmptyString(item))) {
|
|
@@ -127,6 +130,9 @@ function validateParams(params) {
|
|
|
127
130
|
throw new Error("title is required");
|
|
128
131
|
if (!isNonEmptyString(params?.vision))
|
|
129
132
|
throw new Error("vision is required");
|
|
133
|
+
const milestoneTitleIssue = validateTitle(params.title);
|
|
134
|
+
if (milestoneTitleIssue)
|
|
135
|
+
throw new Error(`title is invalid: ${milestoneTitleIssue}`);
|
|
130
136
|
return {
|
|
131
137
|
...params,
|
|
132
138
|
dependsOn: params.dependsOn ? validateStringArray(params.dependsOn, "dependsOn") : [],
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { existsSync, rmSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
1
3
|
import { clearParseCache } from "../files.js";
|
|
2
4
|
import { isClosedStatus, isDeferredStatus } from "../status-guards.js";
|
|
3
|
-
import { isNonEmptyString } from "../validation.js";
|
|
4
|
-
import { transaction, getMilestone, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, updateSliceStatus, } from "../gsd-db.js";
|
|
5
|
+
import { isNonEmptyString, validateStringArray } from "../validation.js";
|
|
6
|
+
import { transaction, getMilestone, getSlice, getSliceTasks, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, updateSliceStatus, setSliceSketchFlag, deleteTask, deleteArtifactByPath, } from "../gsd-db.js";
|
|
5
7
|
import { invalidateStateCache } from "../state.js";
|
|
6
8
|
import { renderPlanFromDb } from "../markdown-renderer.js";
|
|
7
9
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
@@ -9,6 +11,8 @@ import { writeManifest } from "../workflow-manifest.js";
|
|
|
9
11
|
import { appendEvent } from "../workflow-events.js";
|
|
10
12
|
import { logWarning } from "../workflow-logger.js";
|
|
11
13
|
import { validatePlanningPathScope } from "../planning-path-scope.js";
|
|
14
|
+
import { checkFilePathConsistency, checkTaskOrdering } from "../pre-execution-checks.js";
|
|
15
|
+
import { buildTaskFileName, gsdProjectionRoot } from "../paths.js";
|
|
12
16
|
function validateTasks(value) {
|
|
13
17
|
if (!Array.isArray(value) || value.length === 0) {
|
|
14
18
|
throw new Error("tasks must be a non-empty array");
|
|
@@ -39,17 +43,11 @@ function validateTasks(value) {
|
|
|
39
43
|
throw new Error(`tasks[${index}].description must be a non-empty string`);
|
|
40
44
|
if (!isNonEmptyString(estimate))
|
|
41
45
|
throw new Error(`tasks[${index}].estimate must be a non-empty string`);
|
|
42
|
-
|
|
43
|
-
throw new Error(`tasks[${index}].files must be an array of non-empty strings`);
|
|
44
|
-
}
|
|
46
|
+
const validatedFiles = validateStringArray(files, `tasks[${index}].files`);
|
|
45
47
|
if (!isNonEmptyString(verify))
|
|
46
48
|
throw new Error(`tasks[${index}].verify must be a non-empty string`);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
if (!Array.isArray(expectedOutput) || expectedOutput.some((item) => !isNonEmptyString(item))) {
|
|
51
|
-
throw new Error(`tasks[${index}].expectedOutput must be an array of non-empty strings`);
|
|
52
|
-
}
|
|
49
|
+
const validatedInputs = validateStringArray(inputs, `tasks[${index}].inputs`);
|
|
50
|
+
const validatedExpectedOutput = validateStringArray(expectedOutput, `tasks[${index}].expectedOutput`);
|
|
53
51
|
if (observabilityImpact !== undefined && !isNonEmptyString(observabilityImpact)) {
|
|
54
52
|
throw new Error(`tasks[${index}].observabilityImpact must be a non-empty string when provided`);
|
|
55
53
|
}
|
|
@@ -58,10 +56,10 @@ function validateTasks(value) {
|
|
|
58
56
|
title,
|
|
59
57
|
description,
|
|
60
58
|
estimate,
|
|
61
|
-
files,
|
|
59
|
+
files: validatedFiles,
|
|
62
60
|
verify,
|
|
63
|
-
inputs,
|
|
64
|
-
expectedOutput,
|
|
61
|
+
inputs: validatedInputs,
|
|
62
|
+
expectedOutput: validatedExpectedOutput,
|
|
65
63
|
observabilityImpact: typeof observabilityImpact === "string" ? observabilityImpact : "",
|
|
66
64
|
};
|
|
67
65
|
});
|
|
@@ -84,6 +82,53 @@ function validateParams(params) {
|
|
|
84
82
|
tasks: validateTasks(params.tasks),
|
|
85
83
|
};
|
|
86
84
|
}
|
|
85
|
+
function toTaskRows(params) {
|
|
86
|
+
return params.tasks.map((task, index) => ({
|
|
87
|
+
milestone_id: params.milestoneId,
|
|
88
|
+
slice_id: params.sliceId,
|
|
89
|
+
id: task.taskId,
|
|
90
|
+
title: task.title,
|
|
91
|
+
status: "pending",
|
|
92
|
+
one_liner: "",
|
|
93
|
+
narrative: "",
|
|
94
|
+
verification_result: "",
|
|
95
|
+
duration: "",
|
|
96
|
+
completed_at: null,
|
|
97
|
+
blocker_discovered: false,
|
|
98
|
+
deviations: "",
|
|
99
|
+
known_issues: "",
|
|
100
|
+
key_files: [],
|
|
101
|
+
key_decisions: [],
|
|
102
|
+
full_summary_md: "",
|
|
103
|
+
description: task.description,
|
|
104
|
+
estimate: task.estimate,
|
|
105
|
+
files: task.files,
|
|
106
|
+
verify: task.verify,
|
|
107
|
+
inputs: task.inputs,
|
|
108
|
+
expected_output: task.expectedOutput,
|
|
109
|
+
observability_impact: task.observabilityImpact ?? "",
|
|
110
|
+
full_plan_md: task.fullPlanMd ?? "",
|
|
111
|
+
sequence: index + 1,
|
|
112
|
+
blocker_source: "",
|
|
113
|
+
escalation_pending: 0,
|
|
114
|
+
escalation_awaiting_review: 0,
|
|
115
|
+
escalation_artifact_path: null,
|
|
116
|
+
escalation_override_applied_at: null,
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
function validateTaskPathsBeforePersist(params, basePath) {
|
|
120
|
+
const taskRows = toTaskRows(params);
|
|
121
|
+
const checks = [
|
|
122
|
+
...checkFilePathConsistency(taskRows, basePath),
|
|
123
|
+
...checkTaskOrdering(taskRows, basePath),
|
|
124
|
+
];
|
|
125
|
+
const blocking = checks.filter((check) => !check.passed && check.blocking);
|
|
126
|
+
if (blocking.length === 0)
|
|
127
|
+
return null;
|
|
128
|
+
return blocking
|
|
129
|
+
.map((check) => `[${check.category}] ${check.target}: ${check.message}`)
|
|
130
|
+
.join("\n");
|
|
131
|
+
}
|
|
87
132
|
export async function handlePlanSlice(rawParams, basePath) {
|
|
88
133
|
let params;
|
|
89
134
|
try {
|
|
@@ -100,10 +145,15 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
100
145
|
if (pathScopeError) {
|
|
101
146
|
return { error: `validation failed: ${pathScopeError}` };
|
|
102
147
|
}
|
|
148
|
+
const pathError = validateTaskPathsBeforePersist(params, basePath);
|
|
149
|
+
if (pathError) {
|
|
150
|
+
return { error: `pre-execution validation failed:\n${pathError}` };
|
|
151
|
+
}
|
|
103
152
|
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
104
153
|
// Guards must be inside the transaction so the state they check cannot
|
|
105
154
|
// change between the read and the write (#2723).
|
|
106
155
|
let guardError = null;
|
|
156
|
+
let omittedTaskIds = [];
|
|
107
157
|
try {
|
|
108
158
|
transaction(() => {
|
|
109
159
|
const parentMilestone = getMilestone(params.milestoneId);
|
|
@@ -124,9 +174,21 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
124
174
|
guardError = `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first`;
|
|
125
175
|
return;
|
|
126
176
|
}
|
|
177
|
+
const newTaskIds = new Set(params.tasks.map((task) => task.taskId));
|
|
178
|
+
const existingTasks = getSliceTasks(params.milestoneId, params.sliceId);
|
|
179
|
+
omittedTaskIds = existingTasks
|
|
180
|
+
.filter((task) => !newTaskIds.has(task.id))
|
|
181
|
+
.map((task) => task.id);
|
|
182
|
+
for (const task of existingTasks) {
|
|
183
|
+
if (!newTaskIds.has(task.id) && isClosedStatus(task.status)) {
|
|
184
|
+
guardError = `cannot remove completed task ${task.id}`;
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
127
188
|
if (isDeferredStatus(parentSlice.status)) {
|
|
128
189
|
updateSliceStatus(params.milestoneId, params.sliceId, "pending");
|
|
129
190
|
}
|
|
191
|
+
setSliceSketchFlag(params.milestoneId, params.sliceId, false);
|
|
130
192
|
upsertSlicePlanning(params.milestoneId, params.sliceId, {
|
|
131
193
|
goal: params.goal,
|
|
132
194
|
successCriteria: params.successCriteria,
|
|
@@ -134,6 +196,9 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
134
196
|
integrationClosure: params.integrationClosure,
|
|
135
197
|
observabilityImpact: params.observabilityImpact,
|
|
136
198
|
});
|
|
199
|
+
for (const taskId of omittedTaskIds) {
|
|
200
|
+
deleteTask(params.milestoneId, params.sliceId, taskId);
|
|
201
|
+
}
|
|
137
202
|
for (const task of params.tasks) {
|
|
138
203
|
insertTask({
|
|
139
204
|
id: task.taskId,
|
|
@@ -176,6 +241,14 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
176
241
|
return { error: guardError };
|
|
177
242
|
}
|
|
178
243
|
try {
|
|
244
|
+
const tasksDir = join(gsdProjectionRoot(basePath), "milestones", params.milestoneId, "slices", params.sliceId, "tasks");
|
|
245
|
+
for (const taskId of omittedTaskIds) {
|
|
246
|
+
const taskPlanPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
|
|
247
|
+
if (existsSync(taskPlanPath))
|
|
248
|
+
rmSync(taskPlanPath, { force: true });
|
|
249
|
+
const artifactPath = relative(gsdProjectionRoot(basePath), taskPlanPath).replace(/\\/g, "/");
|
|
250
|
+
deleteArtifactByPath(artifactPath);
|
|
251
|
+
}
|
|
179
252
|
const renderResult = await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
|
|
180
253
|
invalidateStateCache();
|
|
181
254
|
clearParseCache();
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Adapts shared GSD workflow handlers for MCP executor calls.
|
|
1
3
|
import { ensureDbOpen } from "../bootstrap/dynamic-tools.js";
|
|
2
4
|
import { sanitizeCompleteMilestoneParams } from "../bootstrap/sanitize-complete-milestone.js";
|
|
3
5
|
import { loadWriteGateSnapshot, shouldBlockContextArtifactSaveInSnapshot, shouldBlockRootArtifactSaveInSnapshot } from "../bootstrap/write-gate.js";
|
|
@@ -12,6 +14,9 @@ import { handleCompleteSlice } from "./complete-slice.js";
|
|
|
12
14
|
import { handlePlanMilestone } from "./plan-milestone.js";
|
|
13
15
|
import { handlePlanSlice } from "./plan-slice.js";
|
|
14
16
|
import { handleReplanSlice } from "./replan-slice.js";
|
|
17
|
+
import { handleReopenMilestone } from "./reopen-milestone.js";
|
|
18
|
+
import { handleReopenSlice } from "./reopen-slice.js";
|
|
19
|
+
import { handleReopenTask } from "./reopen-task.js";
|
|
15
20
|
import { handleReassessRoadmap } from "./reassess-roadmap.js";
|
|
16
21
|
import { handleValidateMilestone } from "./validate-milestone.js";
|
|
17
22
|
import { logError, logWarning } from "../workflow-logger.js";
|
|
@@ -274,6 +279,120 @@ export async function executeTaskComplete(params, basePath = process.cwd()) {
|
|
|
274
279
|
};
|
|
275
280
|
}
|
|
276
281
|
}
|
|
282
|
+
export async function executeTaskReopen(params, basePath = process.cwd()) {
|
|
283
|
+
const dbAvailable = await ensureDbOpen(basePath);
|
|
284
|
+
if (!dbAvailable) {
|
|
285
|
+
return {
|
|
286
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen task." }],
|
|
287
|
+
details: { operation: "reopen_task", error: "db_unavailable" },
|
|
288
|
+
isError: true,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
const result = await handleReopenTask(params, basePath);
|
|
293
|
+
if ("error" in result) {
|
|
294
|
+
return {
|
|
295
|
+
content: [{ type: "text", text: `Error reopening task: ${result.error}` }],
|
|
296
|
+
details: { operation: "reopen_task", error: result.error },
|
|
297
|
+
isError: true,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
content: [{ type: "text", text: `Reopened task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
|
|
302
|
+
details: {
|
|
303
|
+
operation: "reopen_task",
|
|
304
|
+
taskId: result.taskId,
|
|
305
|
+
sliceId: result.sliceId,
|
|
306
|
+
milestoneId: result.milestoneId,
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
catch (err) {
|
|
311
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
312
|
+
logError("tool", `reopen_task tool failed: ${msg}`, { tool: "gsd_task_reopen", error: String(err) });
|
|
313
|
+
return {
|
|
314
|
+
content: [{ type: "text", text: `Error reopening task: ${msg}` }],
|
|
315
|
+
details: { operation: "reopen_task", error: msg },
|
|
316
|
+
isError: true,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
export async function executeSliceReopen(params, basePath = process.cwd()) {
|
|
321
|
+
const dbAvailable = await ensureDbOpen(basePath);
|
|
322
|
+
if (!dbAvailable) {
|
|
323
|
+
return {
|
|
324
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen slice." }],
|
|
325
|
+
details: { operation: "reopen_slice", error: "db_unavailable" },
|
|
326
|
+
isError: true,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
try {
|
|
330
|
+
const result = await handleReopenSlice(params, basePath);
|
|
331
|
+
if ("error" in result) {
|
|
332
|
+
return {
|
|
333
|
+
content: [{ type: "text", text: `Error reopening slice: ${result.error}` }],
|
|
334
|
+
details: { operation: "reopen_slice", error: result.error },
|
|
335
|
+
isError: true,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
content: [{ type: "text", text: `Reopened slice ${result.sliceId} (${result.milestoneId})` }],
|
|
340
|
+
details: {
|
|
341
|
+
operation: "reopen_slice",
|
|
342
|
+
sliceId: result.sliceId,
|
|
343
|
+
milestoneId: result.milestoneId,
|
|
344
|
+
tasksReset: result.tasksReset,
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
catch (err) {
|
|
349
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
350
|
+
logError("tool", `reopen_slice tool failed: ${msg}`, { tool: "gsd_slice_reopen", error: String(err) });
|
|
351
|
+
return {
|
|
352
|
+
content: [{ type: "text", text: `Error reopening slice: ${msg}` }],
|
|
353
|
+
details: { operation: "reopen_slice", error: msg },
|
|
354
|
+
isError: true,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
export async function executeMilestoneReopen(params, basePath = process.cwd()) {
|
|
359
|
+
const dbAvailable = await ensureDbOpen(basePath);
|
|
360
|
+
if (!dbAvailable) {
|
|
361
|
+
return {
|
|
362
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen milestone." }],
|
|
363
|
+
details: { operation: "reopen_milestone", error: "db_unavailable" },
|
|
364
|
+
isError: true,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
try {
|
|
368
|
+
const result = await handleReopenMilestone(params, basePath);
|
|
369
|
+
if ("error" in result) {
|
|
370
|
+
return {
|
|
371
|
+
content: [{ type: "text", text: `Error reopening milestone: ${result.error}` }],
|
|
372
|
+
details: { operation: "reopen_milestone", error: result.error },
|
|
373
|
+
isError: true,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
return {
|
|
377
|
+
content: [{ type: "text", text: `Reopened milestone ${result.milestoneId}` }],
|
|
378
|
+
details: {
|
|
379
|
+
operation: "reopen_milestone",
|
|
380
|
+
milestoneId: result.milestoneId,
|
|
381
|
+
slicesReset: result.slicesReset,
|
|
382
|
+
tasksReset: result.tasksReset,
|
|
383
|
+
},
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
catch (err) {
|
|
387
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
388
|
+
logError("tool", `reopen_milestone tool failed: ${msg}`, { tool: "gsd_milestone_reopen", error: String(err) });
|
|
389
|
+
return {
|
|
390
|
+
content: [{ type: "text", text: `Error reopening milestone: ${msg}` }],
|
|
391
|
+
details: { operation: "reopen_milestone", error: msg },
|
|
392
|
+
isError: true,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
277
396
|
export async function executeSliceComplete(params, basePath = process.cwd()) {
|
|
278
397
|
const dbAvailable = await ensureDbOpen(basePath);
|
|
279
398
|
if (!dbAvailable) {
|
|
@@ -73,6 +73,7 @@ const COMMON_BUDGET_SMALL = 250_000; // ~65K tokens
|
|
|
73
73
|
// allowed-path set for the docs policy lives in one reviewable place.
|
|
74
74
|
const TOOLS_ALL = { mode: "all" };
|
|
75
75
|
const TOOLS_PLANNING = { mode: "planning" };
|
|
76
|
+
const TOOLS_VERIFICATION = { mode: "verification" };
|
|
76
77
|
// Like TOOLS_PLANNING but permits dispatch to read-only recon/planning
|
|
77
78
|
// specialists. Runtime-enforced by write-gate.ts before the subagent tool runs.
|
|
78
79
|
const TOOLS_PLANNING_DISPATCH_RECON = {
|
|
@@ -187,8 +188,8 @@ export const UNIT_MANIFESTS = {
|
|
|
187
188
|
contextMode: "verification",
|
|
188
189
|
// planning-dispatch: validation is a verification-fan-out unit. It reads
|
|
189
190
|
// the milestone surface and dispatches reviewer/security/tester subagents
|
|
190
|
-
// to report findings without touching user source.
|
|
191
|
-
//
|
|
191
|
+
// to report findings without touching user source. Write isolation to
|
|
192
|
+
// .gsd/ is preserved.
|
|
192
193
|
tools: TOOLS_PLANNING_DISPATCH_REVIEW,
|
|
193
194
|
artifacts: {
|
|
194
195
|
inline: ["roadmap", "slice-summary", "slice-uat", "requirements", "decisions", "templates"],
|
|
@@ -204,11 +205,9 @@ export const UNIT_MANIFESTS = {
|
|
|
204
205
|
codebaseMap: false,
|
|
205
206
|
preferences: "active-only",
|
|
206
207
|
contextMode: "verification",
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
// preserved.
|
|
211
|
-
tools: TOOLS_PLANNING_DISPATCH_REVIEW,
|
|
208
|
+
// Milestone closeout must run unrestricted shell verification commands
|
|
209
|
+
// against the final diff before recording completion.
|
|
210
|
+
tools: TOOLS_ALL,
|
|
212
211
|
artifacts: {
|
|
213
212
|
// #4780 landed slice-summary as excerpt for this unit; phase 2 of
|
|
214
213
|
// the architecture will read this manifest as the source of truth
|
|
@@ -227,7 +226,9 @@ export const UNIT_MANIFESTS = {
|
|
|
227
226
|
codebaseMap: true,
|
|
228
227
|
preferences: "active-only",
|
|
229
228
|
contextMode: "research",
|
|
230
|
-
|
|
229
|
+
// Multi-slice research dispatches use the research-slice unit contract to
|
|
230
|
+
// fan out scout subagents that write .gsd research artifacts.
|
|
231
|
+
tools: TOOLS_PLANNING_DISPATCH_RECON,
|
|
231
232
|
artifacts: {
|
|
232
233
|
inline: ["roadmap", "milestone-research", "dependency-summaries", "templates"],
|
|
233
234
|
excerpt: [],
|
|
@@ -365,7 +366,7 @@ export const UNIT_MANIFESTS = {
|
|
|
365
366
|
codebaseMap: false,
|
|
366
367
|
preferences: "active-only",
|
|
367
368
|
contextMode: "verification",
|
|
368
|
-
tools:
|
|
369
|
+
tools: TOOLS_VERIFICATION,
|
|
369
370
|
artifacts: {
|
|
370
371
|
// Phase 3 migration (#4782): manifest matches today's actual
|
|
371
372
|
// buildRunUatPrompt inlining. Prior phase-1 entry listed
|
|
@@ -384,7 +385,9 @@ export const UNIT_MANIFESTS = {
|
|
|
384
385
|
codebaseMap: false,
|
|
385
386
|
preferences: "active-only",
|
|
386
387
|
contextMode: "verification",
|
|
387
|
-
|
|
388
|
+
// Gate evaluation fans out tester-style subagents, which read the slice
|
|
389
|
+
// plan and report via the DB-backed gate-result tool.
|
|
390
|
+
tools: TOOLS_PLANNING_DISPATCH_REVIEW,
|
|
388
391
|
artifacts: {
|
|
389
392
|
inline: ["slice-plan", "prior-task-summaries"],
|
|
390
393
|
excerpt: [],
|
|
@@ -509,3 +512,22 @@ export const UNIT_MANIFESTS = {
|
|
|
509
512
|
export function resolveManifest(unitType) {
|
|
510
513
|
return UNIT_MANIFESTS[unitType] ?? null;
|
|
511
514
|
}
|
|
515
|
+
export function compileSubagentPermissionContract(policy) {
|
|
516
|
+
if (!policy) {
|
|
517
|
+
return { allowed: false, allowedSubagents: [], toolsMode: "unknown" };
|
|
518
|
+
}
|
|
519
|
+
if (policy.mode === "all") {
|
|
520
|
+
return { allowed: true, allowedSubagents: ["*"], toolsMode: policy.mode };
|
|
521
|
+
}
|
|
522
|
+
if (policy.mode === "planning-dispatch") {
|
|
523
|
+
return {
|
|
524
|
+
allowed: true,
|
|
525
|
+
allowedSubagents: [...policy.allowedSubagents],
|
|
526
|
+
toolsMode: policy.mode,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
return { allowed: false, allowedSubagents: [], toolsMode: policy.mode };
|
|
530
|
+
}
|
|
531
|
+
export function resolveSubagentPermissionContract(unitType) {
|
|
532
|
+
return compileSubagentPermissionContract(resolveManifest(unitType)?.tools);
|
|
533
|
+
}
|
|
@@ -5,6 +5,27 @@
|
|
|
5
5
|
export function isNonEmptyString(value) {
|
|
6
6
|
return typeof value === "string" && value.trim().length > 0;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Characters that are used as delimiters in GSD state management documents
|
|
10
|
+
* and should not appear in milestone or slice titles.
|
|
11
|
+
*/
|
|
12
|
+
const TITLE_DELIMITER_RE = /[\u2014\u2013\/]/; // em dash, en dash, forward slash
|
|
13
|
+
/**
|
|
14
|
+
* Check whether a milestone or slice title contains characters that conflict
|
|
15
|
+
* with GSD's state document delimiter conventions.
|
|
16
|
+
* Returns a human-readable description of the problem, or null if the title is safe.
|
|
17
|
+
*/
|
|
18
|
+
export function validateTitle(title) {
|
|
19
|
+
if (TITLE_DELIMITER_RE.test(title)) {
|
|
20
|
+
const found = [];
|
|
21
|
+
if (/[\u2014\u2013]/.test(title))
|
|
22
|
+
found.push("em/en dash (\u2014 or \u2013)");
|
|
23
|
+
if (/\//.test(title))
|
|
24
|
+
found.push("forward slash (/)");
|
|
25
|
+
return `title contains ${found.join(" and ")}, which conflict with GSD state document delimiters`;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
8
29
|
/**
|
|
9
30
|
* Validate that `value` is an array of non-empty strings.
|
|
10
31
|
* Throws with a message referencing `field` on failure.
|
|
@@ -12,7 +33,8 @@ export function isNonEmptyString(value) {
|
|
|
12
33
|
*/
|
|
13
34
|
export function validateStringArray(value, field) {
|
|
14
35
|
if (!Array.isArray(value)) {
|
|
15
|
-
|
|
36
|
+
const received = value === null ? "null" : typeof value;
|
|
37
|
+
throw new Error(`${field} must be an array of strings, not ${received}`);
|
|
16
38
|
}
|
|
17
39
|
if (value.some((item) => !isNonEmptyString(item))) {
|
|
18
40
|
throw new Error(`${field} must contain only non-empty strings`);
|