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
|
@@ -497,6 +497,7 @@ test('Scenario 11: Requirements edge cases', () => {
|
|
|
497
497
|
makeRequirement('', 'Another No ID', 'validated'),
|
|
498
498
|
makeRequirement('R005', 'Has ID', 'something-weird'),
|
|
499
499
|
makeRequirement('R006', 'Deferred One', 'DEFERRED'),
|
|
500
|
+
makeRequirement('AUTH-7', 'Legacy ID', 'active'),
|
|
500
501
|
],
|
|
501
502
|
phases: {
|
|
502
503
|
'1-req-edge': makePhase('1-req-edge', 1, 'req-edge'),
|
|
@@ -510,6 +511,8 @@ test('Scenario 11: Requirements edge cases', () => {
|
|
|
510
511
|
assert.deepStrictEqual(result.requirements[2]?.id, 'R005', 'req-edge: existing id preserved');
|
|
511
512
|
assert.deepStrictEqual(result.requirements[2]?.status, 'active', 'req-edge: unknown status normalized to active');
|
|
512
513
|
assert.deepStrictEqual(result.requirements[3]?.status, 'deferred', 'req-edge: uppercase DEFERRED normalized');
|
|
514
|
+
assert.deepStrictEqual(result.requirements[4]?.id, 'R003', 'req-edge: non-R legacy id gets next canonical id');
|
|
515
|
+
assert.ok(result.requirements[4]?.description.includes('Legacy ID: AUTH-7'), 'req-edge: original legacy id is preserved in description');
|
|
513
516
|
});
|
|
514
517
|
|
|
515
518
|
// ─── Scenario 12: Vision derivation ────────────────────────────────────────
|
|
@@ -553,6 +556,8 @@ test('Scenario 13: Decisions content', () => {
|
|
|
553
556
|
const result = transformToGSD(project);
|
|
554
557
|
|
|
555
558
|
assert.ok(result.decisionsContent.includes('decision-01'), 'decisions: extracts key-decisions from summaries');
|
|
559
|
+
assert.ok(result.decisionsContent.includes('| D001 |'), 'decisions: writes DB-importable decision ID');
|
|
560
|
+
assert.ok(result.decisionsContent.includes('| # | When | Scope | Decision | Choice | Rationale | Revisable? | Made By |'), 'decisions: writes canonical table header');
|
|
556
561
|
});
|
|
557
562
|
|
|
558
563
|
// ─── Scenario 14: No undefined values in output ───────────────────────────
|
|
@@ -616,4 +621,3 @@ test('Scenario 15: Empty research', () => {
|
|
|
616
621
|
});
|
|
617
622
|
|
|
618
623
|
// ─── Results ───────────────────────────────────────────────────────────────
|
|
619
|
-
|
|
@@ -41,6 +41,15 @@ const SAMPLE_ROADMAP = `# Project Roadmap
|
|
|
41
41
|
- [ ] 31 — Notifications
|
|
42
42
|
`;
|
|
43
43
|
|
|
44
|
+
const SAMPLE_VERSION_PREFIX_ROADMAP = `# Project Roadmap
|
|
45
|
+
|
|
46
|
+
## Phases
|
|
47
|
+
|
|
48
|
+
- ✅ **v1.0 MVP** — Phases 1-6 (shipped 2026-02-24)
|
|
49
|
+
- ✅ **v1.1 Onboarding** — Phases 7-9 (shipped 2026-03-01)
|
|
50
|
+
- 🚧 **v1.8 Production** — Phases 44-53
|
|
51
|
+
`;
|
|
52
|
+
|
|
44
53
|
const SAMPLE_PROJECT = `# My Project
|
|
45
54
|
|
|
46
55
|
A sample project for testing the migration parser.
|
|
@@ -246,6 +255,21 @@ test('parseOldRoadmap: flat format', () => {
|
|
|
246
255
|
assert.deepStrictEqual(roadmap.phases[1].done, false, 'flat roadmap: second phase not done');
|
|
247
256
|
});
|
|
248
257
|
|
|
258
|
+
test('parseOldRoadmap: emoji version-prefix phase ranges', () => {
|
|
259
|
+
const roadmap = parseOldRoadmap(SAMPLE_VERSION_PREFIX_ROADMAP);
|
|
260
|
+
assert.deepStrictEqual(roadmap.milestones.length, 0, 'version roadmap: no milestone sections');
|
|
261
|
+
assert.deepStrictEqual(roadmap.phases.length, 3, 'version roadmap: 3 phase ranges');
|
|
262
|
+
assert.deepStrictEqual(roadmap.phases[0].number, 1, 'version roadmap: first range starts at phase 1');
|
|
263
|
+
assert.deepStrictEqual(roadmap.phases[0].title, 'MVP', 'version roadmap: first title');
|
|
264
|
+
assert.deepStrictEqual(roadmap.phases[0].done, true, 'version roadmap: first range done');
|
|
265
|
+
assert.deepStrictEqual(roadmap.phases[1].number, 7, 'version roadmap: second range starts at phase 7');
|
|
266
|
+
assert.deepStrictEqual(roadmap.phases[1].title, 'Onboarding', 'version roadmap: second title');
|
|
267
|
+
assert.deepStrictEqual(roadmap.phases[1].done, true, 'version roadmap: second range done');
|
|
268
|
+
assert.deepStrictEqual(roadmap.phases[2].number, 44, 'version roadmap: third range starts at phase 44');
|
|
269
|
+
assert.deepStrictEqual(roadmap.phases[2].title, 'Production', 'version roadmap: third title');
|
|
270
|
+
assert.deepStrictEqual(roadmap.phases[2].done, false, 'version roadmap: third range in progress');
|
|
271
|
+
});
|
|
272
|
+
|
|
249
273
|
test('parseOldRoadmap: milestone-sectioned with <details>', () => {
|
|
250
274
|
const roadmap = parseOldRoadmap(SAMPLE_MILESTONE_SECTIONED_ROADMAP);
|
|
251
275
|
assert.ok(roadmap.milestones.length >= 2, 'ms roadmap: has milestone sections');
|
|
@@ -387,4 +411,3 @@ test('parseOldProject', () => {
|
|
|
387
411
|
const project = parseOldProject(SAMPLE_PROJECT);
|
|
388
412
|
assert.deepStrictEqual(project, SAMPLE_PROJECT, 'project: returns raw content');
|
|
389
413
|
});
|
|
390
|
-
|
|
@@ -14,7 +14,7 @@ import { parseSummary } from '../files.ts';
|
|
|
14
14
|
import { deriveState } from '../state.ts';
|
|
15
15
|
import { invalidateAllCaches } from '../cache.ts';
|
|
16
16
|
import { ensureDbOpen } from '../bootstrap/dynamic-tools.ts';
|
|
17
|
-
import { closeDatabase, getAllMilestones } from '../gsd-db.ts';
|
|
17
|
+
import { closeDatabase, getAllMilestones, getArtifact } from '../gsd-db.ts';
|
|
18
18
|
import { importWrittenMigrationToDb } from '../migrate/command.ts';
|
|
19
19
|
import type {
|
|
20
20
|
GSDProject,
|
|
@@ -336,7 +336,12 @@ test('Scenario 2: Fully complete project — deriveState phase', async () => {
|
|
|
336
336
|
assert.deepStrictEqual(preview.taskCompletionPct, 100, 'complete: preview taskCompletionPct');
|
|
337
337
|
assert.deepStrictEqual(preview.requirements.total, 0, 'complete: preview requirements total');
|
|
338
338
|
|
|
339
|
+
const imported = await importWrittenMigrationToDb(base, preview);
|
|
340
|
+
assert.ok(imported.artifacts >= 6, 'complete: imports generated milestone artifacts');
|
|
341
|
+
assert.ok(getArtifact('milestones/M001/M001-VALIDATION.md') !== null, 'complete: M001-VALIDATION.md imported as artifact');
|
|
342
|
+
assert.ok(getArtifact('milestones/M001/M001-SUMMARY.md') !== null, 'complete: M001-SUMMARY.md imported as artifact');
|
|
339
343
|
} finally {
|
|
344
|
+
closeDatabase();
|
|
340
345
|
rmSync(base, { recursive: true, force: true });
|
|
341
346
|
}
|
|
342
347
|
});
|
|
@@ -6,13 +6,15 @@ import test from "node:test";
|
|
|
6
6
|
|
|
7
7
|
import { ensureDbOpen } from "../bootstrap/dynamic-tools.ts";
|
|
8
8
|
import {
|
|
9
|
-
_getAdapter,
|
|
10
9
|
closeDatabase,
|
|
11
10
|
getAllMilestones,
|
|
11
|
+
insertMilestone,
|
|
12
|
+
insertSlice,
|
|
13
|
+
insertTask,
|
|
12
14
|
getSliceTasks,
|
|
13
15
|
} from "../gsd-db.ts";
|
|
14
16
|
import {
|
|
15
|
-
|
|
17
|
+
checkMarkdownHierarchyAgainstDb,
|
|
16
18
|
countMarkdownHierarchy,
|
|
17
19
|
} from "../migration-auto-check.ts";
|
|
18
20
|
import { writeGSDDirectory } from "../migrate/writer.ts";
|
|
@@ -70,7 +72,7 @@ function projectFixture(): GSDProject {
|
|
|
70
72
|
};
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
test("migration auto-check
|
|
75
|
+
test("migration auto-check preserves empty DB and reports explicit recovery", async () => {
|
|
74
76
|
const base = makeBase();
|
|
75
77
|
try {
|
|
76
78
|
await writeGSDDirectory(projectFixture(), base);
|
|
@@ -79,32 +81,35 @@ test("migration auto-check imports markdown hierarchy when DB is empty", async (
|
|
|
79
81
|
assert.equal(await ensureDbOpen(base), true);
|
|
80
82
|
assert.equal(getAllMilestones().length, 0, "fresh authoritative DB starts empty");
|
|
81
83
|
|
|
82
|
-
const result = await
|
|
83
|
-
assert.equal(result.action, "
|
|
84
|
+
const result = await checkMarkdownHierarchyAgainstDb(base);
|
|
85
|
+
assert.equal(result.action, "recovery-required");
|
|
84
86
|
assert.equal(result.reason, "db-empty");
|
|
85
|
-
assert.deepEqual(result.afterDb, { milestones:
|
|
86
|
-
assert.equal(
|
|
87
|
-
assert.
|
|
87
|
+
assert.deepEqual(result.afterDb, { milestones: 0, slices: 0, tasks: 0 });
|
|
88
|
+
assert.equal(result.recoveryCommand, "gsd recover");
|
|
89
|
+
assert.match(result.message ?? "", /will not import markdown automatically/);
|
|
90
|
+
assert.equal(getAllMilestones().length, 0);
|
|
91
|
+
assert.equal(getSliceTasks("M001", "S01").length, 0);
|
|
88
92
|
} finally {
|
|
89
93
|
cleanup(base);
|
|
90
94
|
}
|
|
91
95
|
});
|
|
92
96
|
|
|
93
|
-
test("migration auto-check
|
|
97
|
+
test("migration auto-check preserves DB on hierarchy count mismatch", async () => {
|
|
94
98
|
const base = makeBase();
|
|
95
99
|
try {
|
|
96
100
|
await writeGSDDirectory(projectFixture(), base);
|
|
97
|
-
await
|
|
98
|
-
|
|
99
|
-
|
|
101
|
+
assert.equal(await ensureDbOpen(base), true);
|
|
102
|
+
insertMilestone({ id: "M001", title: "Legacy Milestone", status: "active" });
|
|
103
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Legacy Slice", status: "pending", risk: "medium", depends: [], demo: "Legacy slice demo", sequence: 1 });
|
|
100
104
|
assert.equal(getSliceTasks("M001", "S01").length, 0, "test fixture simulates stale DB task count");
|
|
101
105
|
|
|
102
|
-
const result = await
|
|
103
|
-
assert.equal(result.action, "
|
|
106
|
+
const result = await checkMarkdownHierarchyAgainstDb(base);
|
|
107
|
+
assert.equal(result.action, "recovery-required");
|
|
104
108
|
assert.equal(result.reason, "count-mismatch");
|
|
105
109
|
assert.deepEqual(result.beforeDb, { milestones: 1, slices: 1, tasks: 0 });
|
|
106
|
-
assert.deepEqual(result.afterDb, { milestones: 1, slices: 1, tasks:
|
|
107
|
-
assert.equal(
|
|
110
|
+
assert.deepEqual(result.afterDb, { milestones: 1, slices: 1, tasks: 0 });
|
|
111
|
+
assert.equal(result.recoveryCommand, "gsd recover");
|
|
112
|
+
assert.equal(getSliceTasks("M001", "S01").length, 0);
|
|
108
113
|
} finally {
|
|
109
114
|
cleanup(base);
|
|
110
115
|
}
|
|
@@ -114,9 +119,12 @@ test("migration auto-check leaves matching DB hierarchy alone", async () => {
|
|
|
114
119
|
const base = makeBase();
|
|
115
120
|
try {
|
|
116
121
|
await writeGSDDirectory(projectFixture(), base);
|
|
117
|
-
await
|
|
122
|
+
assert.equal(await ensureDbOpen(base), true);
|
|
123
|
+
insertMilestone({ id: "M001", title: "Legacy Milestone", status: "active" });
|
|
124
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Legacy Slice", status: "pending", risk: "medium", depends: [], demo: "Legacy slice demo", sequence: 1 });
|
|
125
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Legacy Task", status: "pending" });
|
|
118
126
|
|
|
119
|
-
const result = await
|
|
127
|
+
const result = await checkMarkdownHierarchyAgainstDb(base);
|
|
120
128
|
assert.equal(result.action, "none");
|
|
121
129
|
assert.equal(result.reason, "in-sync");
|
|
122
130
|
assert.deepEqual(result.markdown, { milestones: 1, slices: 1, tasks: 1 });
|
|
@@ -13,17 +13,19 @@
|
|
|
13
13
|
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
14
14
|
import assert from "node:assert/strict";
|
|
15
15
|
import { chmodSync, existsSync, mkdtempSync, writeFileSync, readFileSync, rmSync } from "node:fs";
|
|
16
|
-
import { join } from "node:path";
|
|
16
|
+
import { delimiter, join } from "node:path";
|
|
17
17
|
import { tmpdir } from "node:os";
|
|
18
18
|
import { execFileSync } from "node:child_process";
|
|
19
19
|
import {
|
|
20
20
|
assertWorktreeMaterialized,
|
|
21
21
|
nativeBranchDelete,
|
|
22
22
|
nativeCommit,
|
|
23
|
+
nativeGetCurrentBranch,
|
|
23
24
|
nativeIsRepo,
|
|
24
25
|
nativeResetHard,
|
|
25
26
|
nativeWorktreeAdd,
|
|
26
27
|
} from "../native-git-bridge.js";
|
|
28
|
+
import { GIT_NO_PROMPT_ENV } from "../git-constants.js";
|
|
27
29
|
|
|
28
30
|
// Note: prior static-analysis tests that scanned native-git-bridge.ts for
|
|
29
31
|
// the raw shell-spawn pattern were removed under #4827 — the integration
|
|
@@ -78,6 +80,55 @@ describe("native-git-bridge #4180: fallback runtime behaviour", () => {
|
|
|
78
80
|
assert.equal(subject, "test: regression commit #4180");
|
|
79
81
|
});
|
|
80
82
|
|
|
83
|
+
test("nativeCommit retries once after transient ENOBUFS from git", (t) => {
|
|
84
|
+
const bin = mkdtempSync(join(tmpdir(), "ngb-enobufs-bin-"));
|
|
85
|
+
t.after(() => rmSync(bin, { recursive: true, force: true }));
|
|
86
|
+
|
|
87
|
+
const realGit = execFileSync("git", ["--exec-path"], { encoding: "utf-8" }).trim();
|
|
88
|
+
const attempts = join(bin, "attempts.txt");
|
|
89
|
+
const fakeGit = join(bin, "fake-git.cjs");
|
|
90
|
+
writeFileSync(fakeGit, `
|
|
91
|
+
const { appendFileSync, readFileSync } = require("node:fs");
|
|
92
|
+
const { spawnSync } = require("node:child_process");
|
|
93
|
+
const attempts = ${JSON.stringify(attempts)};
|
|
94
|
+
const realGit = ${JSON.stringify(join(realGit, process.platform === "win32" ? "git.exe" : "git"))};
|
|
95
|
+
appendFileSync(attempts, "1");
|
|
96
|
+
if (process.argv[2] === "commit" && readFileSync(attempts, "utf-8").length === 1) {
|
|
97
|
+
console.error("spawnSync git ENOBUFS");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
const result = spawnSync(realGit, process.argv.slice(2), { stdio: "inherit" });
|
|
101
|
+
process.exit(result.status ?? 1);
|
|
102
|
+
`, "utf-8");
|
|
103
|
+
|
|
104
|
+
if (process.platform === "win32") {
|
|
105
|
+
writeFileSync(join(bin, "git.cmd"), `@echo off\r\nnode "${fakeGit}" %*\r\n`, "utf-8");
|
|
106
|
+
} else {
|
|
107
|
+
const shim = join(bin, "git");
|
|
108
|
+
writeFileSync(shim, `#!/bin/sh\nexec node "${fakeGit}" "$@"\n`, "utf-8");
|
|
109
|
+
chmodSync(shim, 0o755);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
writeFileSync(join(repo, "file.txt"), "retry commit\n");
|
|
113
|
+
git(["add", "."], repo);
|
|
114
|
+
|
|
115
|
+
const originalPath = process.env.PATH ?? "";
|
|
116
|
+
const gitEnv = GIT_NO_PROMPT_ENV as NodeJS.ProcessEnv;
|
|
117
|
+
const originalGitEnvPath = gitEnv.PATH;
|
|
118
|
+
try {
|
|
119
|
+
process.env.PATH = `${bin}${delimiter}${originalPath}`;
|
|
120
|
+
gitEnv.PATH = process.env.PATH;
|
|
121
|
+
const result = nativeCommit(repo, "test: retry ENOBUFS commit");
|
|
122
|
+
assert.ok(result !== null, "commit should succeed after retry");
|
|
123
|
+
} finally {
|
|
124
|
+
process.env.PATH = originalPath;
|
|
125
|
+
gitEnv.PATH = originalGitEnvPath;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
assert.equal(readFileSync(attempts, "utf-8").length, 2);
|
|
129
|
+
assert.equal(git(["log", "-1", "--format=%s"], repo), "test: retry ENOBUFS commit");
|
|
130
|
+
});
|
|
131
|
+
|
|
81
132
|
test("nativeCommit runs commit hooks", () => {
|
|
82
133
|
const hookPath = join(repo, ".git", "hooks", "commit-msg");
|
|
83
134
|
const marker = join(repo, "hook-ran.txt");
|
|
@@ -119,7 +170,17 @@ describe("native-git-bridge #4180: fallback runtime behaviour", () => {
|
|
|
119
170
|
test("nativeBranchDelete throws when git cannot delete the branch", () => {
|
|
120
171
|
assert.throws(
|
|
121
172
|
() => nativeBranchDelete(repo, "does-not-exist"),
|
|
122
|
-
/
|
|
173
|
+
/git branch -D does-not-exist failed[\s\S]*does-not-exist/,
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test("nativeGetCurrentBranch preserves git stderr in fallback errors", (t) => {
|
|
178
|
+
const dir = mkdtempSync(join(tmpdir(), "ngb-stderr-notrepo-"));
|
|
179
|
+
t.after(() => rmSync(dir, { recursive: true, force: true }));
|
|
180
|
+
|
|
181
|
+
assert.throws(
|
|
182
|
+
() => nativeGetCurrentBranch(dir),
|
|
183
|
+
/git branch --show-current failed[\s\S]*(not a git repository|not a git repo|fatal:)/,
|
|
123
184
|
);
|
|
124
185
|
});
|
|
125
186
|
|
|
@@ -243,7 +243,7 @@ describe("auditOrphanedMilestoneBranches", () => {
|
|
|
243
243
|
);
|
|
244
244
|
});
|
|
245
245
|
|
|
246
|
-
test("
|
|
246
|
+
test("milestone in DB, no branch, no worktree dir → no-op", () => {
|
|
247
247
|
insertMilestone({ id: "M001", title: "Test", status: "complete" });
|
|
248
248
|
|
|
249
249
|
const result = auditOrphanedMilestoneBranches(dir, "worktree");
|
|
@@ -251,4 +251,124 @@ describe("auditOrphanedMilestoneBranches", () => {
|
|
|
251
251
|
assert.deepStrictEqual(result.recovered, []);
|
|
252
252
|
assert.deepStrictEqual(result.warnings, []);
|
|
253
253
|
});
|
|
254
|
+
|
|
255
|
+
test("#5879 — cleans orphaned worktree dir for complete milestone whose branch was already deleted", () => {
|
|
256
|
+
// Reproduces the postflight-stash-restore-failed scenario:
|
|
257
|
+
// 1. An earlier audit deleted milestone/M001 (merged + complete).
|
|
258
|
+
// 2. The worktree dir cleanup failed silently (logWarning only).
|
|
259
|
+
// 3. On the next startup the branch is gone, so the existing branch-keyed
|
|
260
|
+
// loop is invisible to the orphan dir. Without the second pass, the
|
|
261
|
+
// directory lives forever.
|
|
262
|
+
insertMilestone({ id: "M001", title: "Test", status: "complete" });
|
|
263
|
+
|
|
264
|
+
const wtDir = join(dir, ".gsd", "worktrees", "M001");
|
|
265
|
+
mkdirSync(wtDir, { recursive: true });
|
|
266
|
+
writeFileSync(join(wtDir, "leftover.txt"), "stranded from a prior session\n");
|
|
267
|
+
|
|
268
|
+
// No milestone/M001 branch — already deleted on a previous run.
|
|
269
|
+
const branches = run("git branch --list milestone/M001", dir);
|
|
270
|
+
assert.equal(branches, "", "test fixture: branch should not exist");
|
|
271
|
+
|
|
272
|
+
const result = auditOrphanedMilestoneBranches(dir, "worktree");
|
|
273
|
+
|
|
274
|
+
assert.ok(
|
|
275
|
+
result.recovered.some((r) => r.includes("M001") && r.includes("branch already deleted")),
|
|
276
|
+
`should report branch-less orphan cleanup; got: ${JSON.stringify(result.recovered)}`,
|
|
277
|
+
);
|
|
278
|
+
assert.ok(!existsSync(wtDir), "branch-less orphan worktree dir should be removed");
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("#5879 — branch list failure still cleans complete orphan only after branch absence is verified", () => {
|
|
282
|
+
insertMilestone({ id: "M001", title: "Test", status: "complete" });
|
|
283
|
+
|
|
284
|
+
const wtDir = join(dir, ".gsd", "worktrees", "M001");
|
|
285
|
+
mkdirSync(wtDir, { recursive: true });
|
|
286
|
+
writeFileSync(join(wtDir, "leftover.txt"), "stranded from a prior session\n");
|
|
287
|
+
|
|
288
|
+
const result = auditOrphanedMilestoneBranches(dir, "worktree", {
|
|
289
|
+
branchList: () => {
|
|
290
|
+
throw new Error("branch list failed");
|
|
291
|
+
},
|
|
292
|
+
branchExists: (_basePath, branch) => {
|
|
293
|
+
assert.equal(branch, "milestone/M001");
|
|
294
|
+
return false;
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
assert.ok(
|
|
299
|
+
result.recovered.some((r) => r.includes("M001") && r.includes("branch already deleted")),
|
|
300
|
+
`should report verified branch-less orphan cleanup; got: ${JSON.stringify(result.recovered)}`,
|
|
301
|
+
);
|
|
302
|
+
assert.ok(!existsSync(wtDir), "verified branch-less orphan worktree dir should be removed");
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
test("#5879 — branch list failure preserves complete worktree when branch still exists", () => {
|
|
306
|
+
insertMilestone({ id: "M001", title: "Test", status: "complete" });
|
|
307
|
+
|
|
308
|
+
const wtDir = join(dir, ".gsd", "worktrees", "M001");
|
|
309
|
+
mkdirSync(wtDir, { recursive: true });
|
|
310
|
+
writeFileSync(join(wtDir, "live-work.txt"), "do not delete\n");
|
|
311
|
+
|
|
312
|
+
const result = auditOrphanedMilestoneBranches(dir, "worktree", {
|
|
313
|
+
branchList: () => {
|
|
314
|
+
throw new Error("branch list failed");
|
|
315
|
+
},
|
|
316
|
+
branchExists: (_basePath, branch) => {
|
|
317
|
+
assert.equal(branch, "milestone/M001");
|
|
318
|
+
return true;
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
assert.deepStrictEqual(result.recovered, []);
|
|
323
|
+
assert.ok(existsSync(wtDir), "worktree dir must be preserved when branch existence is verified");
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
test("#5879 — skips branch-less orphan for milestone that is not complete", () => {
|
|
327
|
+
// Defensive: only `complete` milestones get the branch-less cleanup. An
|
|
328
|
+
// `active` milestone with no branch but a worktree dir is a different
|
|
329
|
+
// state (probably mid-recovery) and should not be silently wiped.
|
|
330
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
331
|
+
|
|
332
|
+
const wtDir = join(dir, ".gsd", "worktrees", "M001");
|
|
333
|
+
mkdirSync(wtDir, { recursive: true });
|
|
334
|
+
writeFileSync(join(wtDir, "live-work.txt"), "do not delete\n");
|
|
335
|
+
|
|
336
|
+
const result = auditOrphanedMilestoneBranches(dir, "worktree");
|
|
337
|
+
|
|
338
|
+
assert.deepStrictEqual(result.recovered, []);
|
|
339
|
+
assert.ok(existsSync(wtDir), "active milestone worktree dir must be preserved");
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
test("#5879 — branch list failure does not delete worktree for milestone that is not complete", () => {
|
|
343
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
344
|
+
|
|
345
|
+
const wtDir = join(dir, ".gsd", "worktrees", "M001");
|
|
346
|
+
mkdirSync(wtDir, { recursive: true });
|
|
347
|
+
writeFileSync(join(wtDir, "live-work.txt"), "do not delete\n");
|
|
348
|
+
|
|
349
|
+
const result = auditOrphanedMilestoneBranches(dir, "worktree", {
|
|
350
|
+
branchList: () => {
|
|
351
|
+
throw new Error("branch list failed");
|
|
352
|
+
},
|
|
353
|
+
branchExists: () => {
|
|
354
|
+
throw new Error("branchExists should not be called for active milestones");
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
assert.deepStrictEqual(result.recovered, []);
|
|
359
|
+
assert.ok(existsSync(wtDir), "active milestone worktree dir must be preserved");
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
test("#5879 — skips branch-less orphan in 'none' isolation mode", () => {
|
|
363
|
+
insertMilestone({ id: "M001", title: "Test", status: "complete" });
|
|
364
|
+
|
|
365
|
+
const wtDir = join(dir, ".gsd", "worktrees", "M001");
|
|
366
|
+
mkdirSync(wtDir, { recursive: true });
|
|
367
|
+
writeFileSync(join(wtDir, "leftover.txt"), "stranded\n");
|
|
368
|
+
|
|
369
|
+
const result = auditOrphanedMilestoneBranches(dir, "none");
|
|
370
|
+
|
|
371
|
+
assert.deepStrictEqual(result.recovered, []);
|
|
372
|
+
assert.ok(existsSync(wtDir), "'none' mode must not touch worktree dirs");
|
|
373
|
+
});
|
|
254
374
|
});
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { test } from "node:test";
|
|
9
9
|
import assert from "node:assert/strict";
|
|
10
|
-
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
10
|
+
import { existsSync, mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { tmpdir } from "node:os";
|
|
13
13
|
|
|
@@ -48,6 +48,60 @@ test("parkMilestone updates DB status to 'parked' (#2694)", () => {
|
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
+
test("parkMilestone ignores blocked SUMMARY.md when DB milestone is active (#5828)", () => {
|
|
52
|
+
const base = createBase();
|
|
53
|
+
try {
|
|
54
|
+
openDatabase(":memory:");
|
|
55
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
56
|
+
writeFileSync(
|
|
57
|
+
join(base, ".gsd", "milestones", "M001", "M001-SUMMARY.md"),
|
|
58
|
+
[
|
|
59
|
+
"---",
|
|
60
|
+
"status: closeout_blocked",
|
|
61
|
+
"---",
|
|
62
|
+
"",
|
|
63
|
+
"# M001 Summary",
|
|
64
|
+
"",
|
|
65
|
+
"Completion was not persisted.",
|
|
66
|
+
].join("\n"),
|
|
67
|
+
"utf-8",
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const parked = parkMilestone(base, "M001", "test");
|
|
71
|
+
|
|
72
|
+
assert.ok(parked, "active DB row should allow parking despite a blocked SUMMARY.md");
|
|
73
|
+
assert.ok(
|
|
74
|
+
existsSync(join(base, ".gsd", "milestones", "M001", "M001-PARKED.md")),
|
|
75
|
+
"PARKED.md should be written",
|
|
76
|
+
);
|
|
77
|
+
assert.equal(getMilestone("M001")!.status, "parked", "DB status should be parked");
|
|
78
|
+
} finally {
|
|
79
|
+
closeDatabase();
|
|
80
|
+
rmSync(base, { recursive: true, force: true });
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("parkMilestone refuses DB-complete milestones (#5828)", () => {
|
|
85
|
+
const base = createBase();
|
|
86
|
+
try {
|
|
87
|
+
openDatabase(":memory:");
|
|
88
|
+
insertMilestone({ id: "M001", title: "Test", status: "complete" });
|
|
89
|
+
|
|
90
|
+
const parked = parkMilestone(base, "M001", "test");
|
|
91
|
+
|
|
92
|
+
assert.equal(parked, false, "complete DB row should not be parkable");
|
|
93
|
+
assert.equal(
|
|
94
|
+
existsSync(join(base, ".gsd", "milestones", "M001", "M001-PARKED.md")),
|
|
95
|
+
false,
|
|
96
|
+
"PARKED.md should not be written",
|
|
97
|
+
);
|
|
98
|
+
assert.equal(getMilestone("M001")!.status, "complete", "DB status should remain complete");
|
|
99
|
+
} finally {
|
|
100
|
+
closeDatabase();
|
|
101
|
+
rmSync(base, { recursive: true, force: true });
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
51
105
|
test("unparkMilestone updates DB status to 'active' (#2694)", () => {
|
|
52
106
|
const base = createBase();
|
|
53
107
|
try {
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
clearPendingAutoStart,
|
|
12
12
|
_getPendingAutoStart,
|
|
13
13
|
} from "../guided-flow.ts";
|
|
14
|
+
import type { PendingAutoStartInput } from "../pending-auto-start.ts";
|
|
14
15
|
|
|
15
16
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
16
17
|
|
|
@@ -20,6 +21,15 @@ function makeProjectDir(): string {
|
|
|
20
21
|
return dir;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
function pendingInput(basePath: string, milestoneId: string) {
|
|
25
|
+
return {
|
|
26
|
+
basePath,
|
|
27
|
+
milestoneId,
|
|
28
|
+
ctx: { ui: { notify: () => undefined } } as any,
|
|
29
|
+
pi: { sendMessage: () => undefined } as any,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
// ─── Tests ───────────────────────────────────────────────────────────────────
|
|
24
34
|
|
|
25
35
|
describe("pendingAutoStart scope pinning (C1)", () => {
|
|
@@ -38,7 +48,7 @@ describe("pendingAutoStart scope pinning (C1)", () => {
|
|
|
38
48
|
});
|
|
39
49
|
|
|
40
50
|
test("setPendingAutoStart stores a scope whose paths derive from the basePath at reservation time", () => {
|
|
41
|
-
setPendingAutoStart(base,
|
|
51
|
+
setPendingAutoStart(base, pendingInput(base, "M001"));
|
|
42
52
|
|
|
43
53
|
const entry = _getPendingAutoStart(base);
|
|
44
54
|
assert.ok(entry, "entry should exist");
|
|
@@ -54,8 +64,22 @@ describe("pendingAutoStart scope pinning (C1)", () => {
|
|
|
54
64
|
assert.equal(entry.scope.stateFile(), expectedState);
|
|
55
65
|
});
|
|
56
66
|
|
|
67
|
+
test("setPendingAutoStart rejects entries without ctx and pi before storing them", () => {
|
|
68
|
+
assert.throws(
|
|
69
|
+
() =>
|
|
70
|
+
setPendingAutoStart(base, {
|
|
71
|
+
basePath: base,
|
|
72
|
+
milestoneId: "M001",
|
|
73
|
+
} as PendingAutoStartInput),
|
|
74
|
+
/requires ctx and pi/,
|
|
75
|
+
"pending entries must include the handles later used by auto-start recovery",
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
assert.equal(_getPendingAutoStart(base), null);
|
|
79
|
+
});
|
|
80
|
+
|
|
57
81
|
test("scope paths are unaffected by process.chdir after reservation", (t) => {
|
|
58
|
-
setPendingAutoStart(base,
|
|
82
|
+
setPendingAutoStart(base, pendingInput(base, "M002"));
|
|
59
83
|
|
|
60
84
|
const entry = _getPendingAutoStart(base);
|
|
61
85
|
assert.ok(entry, "entry should exist");
|
|
@@ -82,7 +106,7 @@ describe("pendingAutoStart scope pinning (C1)", () => {
|
|
|
82
106
|
|
|
83
107
|
test("scope identityKey matches the realpath of the original basePath even with trailing slash", () => {
|
|
84
108
|
const baseWithSlash = base + "/";
|
|
85
|
-
setPendingAutoStart(base,
|
|
109
|
+
setPendingAutoStart(base, pendingInput(baseWithSlash, "M003"));
|
|
86
110
|
|
|
87
111
|
const entry = _getPendingAutoStart(base);
|
|
88
112
|
assert.ok(entry, "entry should exist");
|
|
@@ -96,7 +120,7 @@ describe("pendingAutoStart scope pinning (C1)", () => {
|
|
|
96
120
|
});
|
|
97
121
|
|
|
98
122
|
test("clearPendingAutoStart removes the entry", () => {
|
|
99
|
-
setPendingAutoStart(base,
|
|
123
|
+
setPendingAutoStart(base, pendingInput(base, "M001"));
|
|
100
124
|
|
|
101
125
|
const before = _getPendingAutoStart(base);
|
|
102
126
|
assert.ok(before, "entry should exist before clear");
|
|
@@ -108,7 +132,7 @@ describe("pendingAutoStart scope pinning (C1)", () => {
|
|
|
108
132
|
});
|
|
109
133
|
|
|
110
134
|
test("_getPendingAutoStart with no basePath argument returns the sole entry", () => {
|
|
111
|
-
setPendingAutoStart(base,
|
|
135
|
+
setPendingAutoStart(base, pendingInput(base, "M001"));
|
|
112
136
|
|
|
113
137
|
// No argument — should return the sole entry
|
|
114
138
|
const entry = _getPendingAutoStart();
|
|
@@ -243,7 +243,8 @@ test("#4781 phase 2: validate-milestone rule writes pass-through VALIDATION for
|
|
|
243
243
|
const content = readFileSync(validationPath, "utf-8");
|
|
244
244
|
assert.match(content, /verdict: pass/);
|
|
245
245
|
assert.match(content, /skip_validation: true/);
|
|
246
|
-
assert.match(content, /trivial-scope pipeline variant
|
|
246
|
+
assert.match(content, /trivial-scope pipeline variant/);
|
|
247
|
+
assert.doesNotMatch(content, /#[0-9]{3,}/, "validation output must not include tracker-style refs");
|
|
247
248
|
});
|
|
248
249
|
|
|
249
250
|
test("#4781 phase 2: validate-milestone skip path does not persist gates without a real slice", async (t) => {
|