gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.8b8d129d7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -18
- package/dist/cli.js +20 -9
- package/dist/headless.js +9 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +110 -37
- package/dist/resources/extensions/gsd/auto/orchestrator.js +12 -1
- package/dist/resources/extensions/gsd/auto/phases.js +97 -38
- package/dist/resources/extensions/gsd/auto/session.js +6 -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 +278 -137
- package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
- package/dist/resources/extensions/gsd/auto-recovery.js +79 -14
- package/dist/resources/extensions/gsd/auto-start.js +87 -14
- package/dist/resources/extensions/gsd/auto-timers.js +11 -3
- package/dist/resources/extensions/gsd/auto-verification.js +102 -34
- package/dist/resources/extensions/gsd/auto-worktree.js +178 -11
- package/dist/resources/extensions/gsd/auto.js +98 -54
- 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 +5 -4
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -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-base-schema.js +2 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
- package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor.js +2 -28
- package/dist/resources/extensions/gsd/export-html.js +27 -425
- package/dist/resources/extensions/gsd/forensics.js +8 -3
- package/dist/resources/extensions/gsd/git-service.js +138 -10
- package/dist/resources/extensions/gsd/gsd-db.js +76 -33
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +110 -117
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/init-wizard.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -8
- package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
- package/dist/resources/extensions/gsd/pre-execution-checks.js +38 -11
- package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +138 -0
- package/dist/resources/extensions/gsd/preferences.js +2 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/repository-registry.js +44 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +59 -2
- 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 +14 -4
- package/dist/resources/extensions/gsd/status-guards.js +14 -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 +151 -15
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +36 -17
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +142 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/shared/interview-ui.js +6 -4
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- package/dist/resources/skills/forensics/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +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-8c10ec293ae0f1d5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/package.json +4 -4
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +13 -4
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/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/controllers/input-controller.js +7 -7
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/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/controllers/input-controller.test.ts +15 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +106 -27
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/src/tui.ts +108 -27
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +10 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +17 -6
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +111 -38
- package/src/resources/extensions/gsd/auto/orchestrator.ts +12 -1
- package/src/resources/extensions/gsd/auto/phases.ts +115 -49
- package/src/resources/extensions/gsd/auto/session.ts +16 -0
- package/src/resources/extensions/gsd/auto/types.ts +3 -0
- package/src/resources/extensions/gsd/auto/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 +312 -148
- package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
- package/src/resources/extensions/gsd/auto-recovery.ts +83 -11
- package/src/resources/extensions/gsd/auto-start.ts +94 -12
- package/src/resources/extensions/gsd/auto-timers.ts +10 -3
- package/src/resources/extensions/gsd/auto-verification.ts +124 -42
- package/src/resources/extensions/gsd/auto-worktree.ts +195 -11
- package/src/resources/extensions/gsd/auto.ts +91 -42
- 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 +5 -4
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- 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-base-schema.ts +2 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
- package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -27
- package/src/resources/extensions/gsd/export-html.ts +27 -427
- package/src/resources/extensions/gsd/forensics.ts +7 -3
- package/src/resources/extensions/gsd/git-service.ts +166 -11
- package/src/resources/extensions/gsd/gsd-db.ts +80 -31
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +142 -134
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/init-wizard.ts +17 -2
- package/src/resources/extensions/gsd/journal.ts +8 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +10 -8
- package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
- package/src/resources/extensions/gsd/pre-execution-checks.ts +49 -11
- package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
- package/src/resources/extensions/gsd/preferences-types.ts +33 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +145 -0
- package/src/resources/extensions/gsd/preferences.ts +5 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/repository-registry.ts +77 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +52 -1
- 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 +15 -4
- package/src/resources/extensions/gsd/status-guards.ts +16 -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 +300 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +174 -8
- 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 +129 -6
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +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/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-task-slice-rows.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +199 -2
- 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 +49 -3
- package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +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 +59 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +70 -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/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/repository-registry.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +72 -1
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +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 +17 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +128 -9
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +173 -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/worktree-preferences-sync.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +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 +172 -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 +51 -18
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +170 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
- package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/shared/interview-ui.ts +6 -4
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/src/resources/skills/forensics/SKILL.md +1 -1
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → _kljR-_Miq_YV1IW0wpRO}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → _kljR-_Miq_YV1IW0wpRO}/_ssgManifest.js +0 -0
|
@@ -24,6 +24,7 @@ export async function showQueueReorder(ctx, completed, pending) {
|
|
|
24
24
|
const items = [...pending];
|
|
25
25
|
let cursor = 0;
|
|
26
26
|
let grabbed = false;
|
|
27
|
+
let scrollOffset = 0;
|
|
27
28
|
let cachedLines;
|
|
28
29
|
let validation;
|
|
29
30
|
// Mutable deps map — tracks removals during this session
|
|
@@ -128,9 +129,11 @@ export async function showQueueReorder(ctx, completed, pending) {
|
|
|
128
129
|
return cachedLines;
|
|
129
130
|
const ui = makeUI(theme, width);
|
|
130
131
|
const lines = [];
|
|
132
|
+
const queueRows = [];
|
|
131
133
|
const push = (...rows) => { for (const r of rows)
|
|
132
134
|
lines.push(...r); };
|
|
133
135
|
const add = (s) => truncateToWidth(s, width);
|
|
136
|
+
let cursorQueueRow = 0;
|
|
134
137
|
const headerText = grabbed ? " Queue Reorder — Moving Item" : " Queue Reorder";
|
|
135
138
|
push(ui.bar(), ui.blank(), ui.header(headerText), ui.blank());
|
|
136
139
|
// Completed milestones (dimmed)
|
|
@@ -153,13 +156,15 @@ export async function showQueueReorder(ctx, completed, pending) {
|
|
|
153
156
|
const num = i + 1;
|
|
154
157
|
const label = item.title && item.title !== item.id ? `${item.id} ${item.title}` : item.id;
|
|
155
158
|
if (isCursor && grabbed) {
|
|
156
|
-
|
|
159
|
+
cursorQueueRow = queueRows.length;
|
|
160
|
+
queueRows.push(add(` ${theme.fg("warning", `▸▸ ${num}. ${label}`)}`));
|
|
157
161
|
}
|
|
158
162
|
else if (isCursor) {
|
|
159
|
-
|
|
163
|
+
cursorQueueRow = queueRows.length;
|
|
164
|
+
queueRows.push(add(` ${theme.fg("accent", `${GLYPH.cursor} ${num}. ${label}`)}`));
|
|
160
165
|
}
|
|
161
166
|
else {
|
|
162
|
-
|
|
167
|
+
queueRows.push(add(` ${theme.fg("text", `${num}. ${label}`)}`));
|
|
163
168
|
}
|
|
164
169
|
// depends_on annotations
|
|
165
170
|
const deps = liveDeps.get(item.id) ?? [];
|
|
@@ -168,34 +173,35 @@ export async function showQueueReorder(ctx, completed, pending) {
|
|
|
168
173
|
continue;
|
|
169
174
|
const pairKey = `${item.id}:${dep}`;
|
|
170
175
|
if (violatedPairs.has(pairKey)) {
|
|
171
|
-
|
|
176
|
+
queueRows.push(add(` ${theme.fg("warning", `${GLYPH.statusWarning} depends_on: ${dep} — auto-removed on confirm`)}`));
|
|
172
177
|
}
|
|
173
178
|
else if (redundantPairs.has(pairKey)) {
|
|
174
|
-
|
|
179
|
+
queueRows.push(add(` ${theme.fg("dim", `↳ depends_on: ${dep} (redundant)`)}`));
|
|
175
180
|
}
|
|
176
181
|
else {
|
|
177
|
-
|
|
182
|
+
queueRows.push(add(` ${theme.fg("dim", `↳ depends_on: ${dep}`)}`));
|
|
178
183
|
}
|
|
179
184
|
}
|
|
180
185
|
// Missing deps
|
|
181
186
|
for (const v of validation.violations.filter(v => v.milestone === item.id && v.type === 'missing_dep')) {
|
|
182
|
-
|
|
187
|
+
queueRows.push(add(` ${theme.fg("error", `${GLYPH.statusWarning} depends_on: ${v.dependsOn} (does not exist)`)}`));
|
|
183
188
|
}
|
|
184
189
|
}
|
|
185
190
|
// Removed deps feedback
|
|
191
|
+
const trailingLines = [];
|
|
186
192
|
if (removedDeps.length > 0) {
|
|
187
|
-
push(ui.blank());
|
|
193
|
+
trailingLines.push(...ui.blank());
|
|
188
194
|
for (const r of removedDeps) {
|
|
189
|
-
|
|
195
|
+
trailingLines.push(add(` ${theme.fg("success", `${GLYPH.statusDone} Removed: ${r.milestone} depends_on ${r.dep}`)}`));
|
|
190
196
|
}
|
|
191
197
|
}
|
|
192
198
|
// Circular warning
|
|
193
199
|
const circ = validation.violations.find(v => v.type === 'circular');
|
|
194
200
|
if (circ) {
|
|
195
|
-
push(ui.blank());
|
|
196
|
-
|
|
201
|
+
trailingLines.push(...ui.blank());
|
|
202
|
+
trailingLines.push(add(` ${theme.fg("error", `${GLYPH.statusWarning} ${circ.message}`)}`));
|
|
197
203
|
}
|
|
198
|
-
push(ui.blank());
|
|
204
|
+
trailingLines.push(...ui.blank());
|
|
199
205
|
// Hints — context-sensitive based on grab state
|
|
200
206
|
const hints = [];
|
|
201
207
|
if (grabbed) {
|
|
@@ -215,7 +221,18 @@ export async function showQueueReorder(ctx, completed, pending) {
|
|
|
215
221
|
hints.push("enter ok");
|
|
216
222
|
}
|
|
217
223
|
hints.push("esc");
|
|
218
|
-
push(ui.hints(hints), ui.bar());
|
|
224
|
+
trailingLines.push(...ui.hints(hints), ...ui.bar());
|
|
225
|
+
const maxOverlayRows = Math.max(10, process.stdout.rows ? Math.floor(process.stdout.rows * 0.8) : 24);
|
|
226
|
+
const availableQueueRows = Math.max(1, maxOverlayRows - lines.length - trailingLines.length);
|
|
227
|
+
const maxScroll = Math.max(0, queueRows.length - availableQueueRows);
|
|
228
|
+
if (cursorQueueRow < scrollOffset) {
|
|
229
|
+
scrollOffset = cursorQueueRow;
|
|
230
|
+
}
|
|
231
|
+
else if (cursorQueueRow >= scrollOffset + availableQueueRows) {
|
|
232
|
+
scrollOffset = cursorQueueRow - availableQueueRows + 1;
|
|
233
|
+
}
|
|
234
|
+
scrollOffset = Math.min(Math.max(scrollOffset, 0), maxScroll);
|
|
235
|
+
lines.push(...queueRows.slice(scrollOffset, scrollOffset + availableQueueRows), ...trailingLines);
|
|
219
236
|
cachedLines = lines;
|
|
220
237
|
return lines;
|
|
221
238
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// GSD-2 + Repository registry seam for parent workspace multi-repo resolution.
|
|
2
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
|
+
import { resolveGsdPathContract } from "./paths.js";
|
|
4
|
+
function assertInsideProjectRoot(projectRoot, candidateRoot, repoId) {
|
|
5
|
+
const rel = relative(projectRoot, candidateRoot);
|
|
6
|
+
if (rel === "")
|
|
7
|
+
return;
|
|
8
|
+
if (rel.startsWith("..") || isAbsolute(rel)) {
|
|
9
|
+
throw new Error(`workspace.repositories.${repoId}.path resolves outside project root: ${candidateRoot}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function resolveRepositoryRoot(projectRoot, repoId, repo) {
|
|
13
|
+
const root = resolve(projectRoot, repo.path);
|
|
14
|
+
assertInsideProjectRoot(projectRoot, root, repoId);
|
|
15
|
+
return {
|
|
16
|
+
id: repoId,
|
|
17
|
+
root,
|
|
18
|
+
role: repo.role,
|
|
19
|
+
verification: repo.verification,
|
|
20
|
+
commitPolicy: repo.commit_policy,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function createRepositoryRegistry(basePath, workspacePrefs) {
|
|
24
|
+
const contract = resolveGsdPathContract(basePath);
|
|
25
|
+
const projectRoot = contract.projectRoot;
|
|
26
|
+
const mode = workspacePrefs?.mode ?? "project";
|
|
27
|
+
const repoMap = new Map();
|
|
28
|
+
// Backward-compatible default for single-repo projects.
|
|
29
|
+
// Explicit workspacePrefs?.repositories entries can override "project"
|
|
30
|
+
// via resolveRepositoryRoot to customize role/verification/commit policy.
|
|
31
|
+
repoMap.set("project", { id: "project", root: projectRoot });
|
|
32
|
+
for (const [repoId, repoConfig] of Object.entries(workspacePrefs?.repositories ?? {})) {
|
|
33
|
+
repoMap.set(repoId, resolveRepositoryRoot(projectRoot, repoId, repoConfig));
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
projectRoot,
|
|
37
|
+
mode,
|
|
38
|
+
repositories: Array.from(repoMap.values()),
|
|
39
|
+
byId: repoMap,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function createRepositoryRegistryFromPreferences(basePath, preferences) {
|
|
43
|
+
return createRepositoryRegistry(basePath, preferences?.workspace);
|
|
44
|
+
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
export function crossReferenceEvidence(claimedEvidence, actualEvidence) {
|
|
16
16
|
const bashCalls = actualEvidence.filter((e) => e.kind === "bash");
|
|
17
17
|
const mismatches = [];
|
|
18
|
-
for (const claimed of claimedEvidence) {
|
|
18
|
+
for (const claimed of latestClaimBatch(claimedEvidence)) {
|
|
19
19
|
// Skip coerced entries — they're already flagged with exitCode: -1
|
|
20
20
|
// and verdict: "unknown (coerced from string)" by db-tools.ts
|
|
21
21
|
if (claimed.verdict?.includes("coerced from string"))
|
|
@@ -25,9 +25,11 @@ export function crossReferenceEvidence(claimedEvidence, actualEvidence) {
|
|
|
25
25
|
// Skip entries with empty or generic commands
|
|
26
26
|
if (!claimed.command || claimed.command.length < 3)
|
|
27
27
|
continue;
|
|
28
|
-
// Find matching bash
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
// Find matching bash calls by command similarity. A command may be retried
|
|
29
|
+
// after a failed first run; the newest matching execution is the one that
|
|
30
|
+
// supports or rejects a claimed pass.
|
|
31
|
+
const matches = findMatches(claimed.command, bashCalls);
|
|
32
|
+
if (matches.length === 0) {
|
|
31
33
|
mismatches.push({
|
|
32
34
|
severity: "warning",
|
|
33
35
|
claimed,
|
|
@@ -37,6 +39,7 @@ export function crossReferenceEvidence(claimedEvidence, actualEvidence) {
|
|
|
37
39
|
continue;
|
|
38
40
|
}
|
|
39
41
|
// Exit code mismatch: LLM claims success but actual command failed
|
|
42
|
+
const match = latestMatch(matches);
|
|
40
43
|
if (claimed.exitCode === 0 && match.exitCode !== 0) {
|
|
41
44
|
mismatches.push({
|
|
42
45
|
severity: "error",
|
|
@@ -50,34 +53,55 @@ export function crossReferenceEvidence(claimedEvidence, actualEvidence) {
|
|
|
50
53
|
}
|
|
51
54
|
// ─── Internals ──────────────────────────────────────────────────────────────
|
|
52
55
|
/**
|
|
53
|
-
*
|
|
56
|
+
* Verification evidence rows are append-only across retries, but a task
|
|
57
|
+
* completion inserts one batch at a single created_at timestamp. When that
|
|
58
|
+
* timestamp is present, safety should judge the newest completion claim only.
|
|
59
|
+
*/
|
|
60
|
+
function latestClaimBatch(claimedEvidence) {
|
|
61
|
+
const dated = claimedEvidence
|
|
62
|
+
.map((claim) => ({
|
|
63
|
+
claim,
|
|
64
|
+
time: typeof claim.createdAt === "string" ? Date.parse(claim.createdAt) : Number.NaN,
|
|
65
|
+
}))
|
|
66
|
+
.filter((entry) => Number.isFinite(entry.time));
|
|
67
|
+
if (dated.length === 0)
|
|
68
|
+
return claimedEvidence;
|
|
69
|
+
const latestTime = Math.max(...dated.map((entry) => entry.time));
|
|
70
|
+
return claimedEvidence.filter((claim) => (typeof claim.createdAt === "string" && Date.parse(claim.createdAt) === latestTime));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Find bash evidence entries matching a claimed command.
|
|
54
74
|
* Uses substring matching — the claimed command may be a shortened version
|
|
55
75
|
* of the actual command, or vice versa.
|
|
56
76
|
*/
|
|
57
|
-
function
|
|
77
|
+
function findMatches(claimedCommand, bashCalls) {
|
|
58
78
|
const normalized = claimedCommand.trim();
|
|
59
|
-
// Exact
|
|
60
|
-
const exact = bashCalls.
|
|
61
|
-
if (exact)
|
|
79
|
+
// Exact matches first
|
|
80
|
+
const exact = bashCalls.filter(b => b.command.trim() === normalized);
|
|
81
|
+
if (exact.length > 0)
|
|
62
82
|
return exact;
|
|
63
83
|
// Substring match: claimed is contained in actual or actual in claimed
|
|
64
|
-
const substring = bashCalls.
|
|
65
|
-
if (substring)
|
|
84
|
+
const substring = bashCalls.filter(b => b.command.includes(normalized) || normalized.includes(b.command));
|
|
85
|
+
if (substring.length > 0)
|
|
66
86
|
return substring;
|
|
67
87
|
// Token match: split on whitespace and check significant overlap
|
|
68
88
|
const claimedTokens = normalized.split(/\s+/).filter(t => t.length > 2);
|
|
69
89
|
if (claimedTokens.length === 0)
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
let bestScore = 0;
|
|
90
|
+
return [];
|
|
91
|
+
const scoredMatches = [];
|
|
73
92
|
for (const call of bashCalls) {
|
|
74
93
|
const callTokens = new Set(call.command.split(/\s+/));
|
|
75
94
|
const matchCount = claimedTokens.filter(t => callTokens.has(t)).length;
|
|
76
95
|
const score = matchCount / claimedTokens.length;
|
|
77
|
-
if (score
|
|
78
|
-
|
|
79
|
-
bestMatch = call;
|
|
96
|
+
if (score >= 0.5) {
|
|
97
|
+
scoredMatches.push({ call, score });
|
|
80
98
|
}
|
|
81
99
|
}
|
|
82
|
-
|
|
100
|
+
const bestScore = Math.max(0, ...scoredMatches.map((match) => match.score));
|
|
101
|
+
return scoredMatches
|
|
102
|
+
.filter((match) => match.score === bestScore)
|
|
103
|
+
.map((match) => match.call);
|
|
104
|
+
}
|
|
105
|
+
function latestMatch(matches) {
|
|
106
|
+
return matches.reduce((latest, match) => (match.timestamp > latest.timestamp ? match : latest));
|
|
83
107
|
}
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { execFileSync, spawn } from "node:child_process";
|
|
16
16
|
import { randomUUID } from "node:crypto";
|
|
17
|
-
import { appendFileSync, existsSync, writeFileSync, readFileSync, mkdirSync, renameSync, unlinkSync, } from "node:fs";
|
|
18
|
-
import { join, dirname } from "node:path";
|
|
17
|
+
import { appendFileSync, existsSync, lstatSync, rmSync, writeFileSync, readFileSync, mkdirSync, renameSync, unlinkSync, } from "node:fs";
|
|
18
|
+
import { isAbsolute, join, dirname, resolve } from "node:path";
|
|
19
19
|
import { fileURLToPath } from "node:url";
|
|
20
20
|
import { gsdRoot } from "./paths.js";
|
|
21
21
|
import { createWorktree, worktreePath, removeWorktree } from "./worktree-manager.js";
|
|
@@ -46,6 +46,44 @@ export function _buildSliceWorkerEnvForTest(basePath, milestoneId, sliceId, work
|
|
|
46
46
|
GSD_SLICE_WORKER_TOKEN: workerToken,
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
+
function isValidSliceWorktreePath(basePath, wtPath) {
|
|
50
|
+
if (!existsSync(wtPath))
|
|
51
|
+
return false;
|
|
52
|
+
const gitPath = join(wtPath, ".git");
|
|
53
|
+
if (!existsSync(gitPath))
|
|
54
|
+
return false;
|
|
55
|
+
try {
|
|
56
|
+
if (!lstatSync(gitPath).isFile())
|
|
57
|
+
return false;
|
|
58
|
+
const content = readFileSync(gitPath, "utf8").trim();
|
|
59
|
+
if (!content.startsWith("gitdir: "))
|
|
60
|
+
return false;
|
|
61
|
+
const rawGitdir = content.slice("gitdir: ".length).trim();
|
|
62
|
+
if (!rawGitdir)
|
|
63
|
+
return false;
|
|
64
|
+
const resolvedGitdir = isAbsolute(rawGitdir) ? rawGitdir : resolve(wtPath, rawGitdir);
|
|
65
|
+
const expectedPrefix = join(basePath, ".git", "worktrees").replaceAll("\\", "/");
|
|
66
|
+
const normalized = resolvedGitdir.replaceAll("\\", "/");
|
|
67
|
+
return normalized === expectedPrefix || normalized.startsWith(`${expectedPrefix}/`);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isWorkerPidAlive(pid) {
|
|
74
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
75
|
+
return false;
|
|
76
|
+
try {
|
|
77
|
+
process.kill(pid, 0);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
const code = err?.code;
|
|
82
|
+
if (code === "ESRCH")
|
|
83
|
+
return false;
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
49
87
|
function sliceStateFilePath(basePath) {
|
|
50
88
|
return join(gsdRoot(basePath), SLICE_ORCHESTRATOR_STATE_FILE);
|
|
51
89
|
}
|
|
@@ -318,6 +356,9 @@ export async function startSliceParallel(basePath, milestoneId, eligibleSlices,
|
|
|
318
356
|
const wtBranch = `slice/${milestoneId}/${slice.id}`;
|
|
319
357
|
const wtName = `${milestoneId}-${slice.id}`;
|
|
320
358
|
const wtPath = worktreePath(basePath, wtName);
|
|
359
|
+
if (existsSync(wtPath) && !isValidSliceWorktreePath(basePath, wtPath)) {
|
|
360
|
+
rmSync(wtPath, { recursive: true, force: true });
|
|
361
|
+
}
|
|
321
362
|
if (!existsSync(wtPath)) {
|
|
322
363
|
createWorktree(basePath, wtName, { branch: wtBranch });
|
|
323
364
|
}
|
|
@@ -361,6 +402,22 @@ export async function startSliceParallel(basePath, milestoneId, eligibleSlices,
|
|
|
361
402
|
catch { /* ignore cleanup failures */ }
|
|
362
403
|
}
|
|
363
404
|
}
|
|
405
|
+
// Guard: if workers died immediately, treat as failed start so callers
|
|
406
|
+
// don't exit auto-mode and re-dispatch in a rapid loop.
|
|
407
|
+
for (let i = started.length - 1; i >= 0; i--) {
|
|
408
|
+
const sid = started[i];
|
|
409
|
+
const worker = sliceState.workers.get(sid);
|
|
410
|
+
if (worker && isWorkerPidAlive(worker.pid))
|
|
411
|
+
continue;
|
|
412
|
+
started.splice(i, 1);
|
|
413
|
+
errors.push({ sid, error: "Worker exited immediately after spawn" });
|
|
414
|
+
sliceState.workers.delete(sid);
|
|
415
|
+
const wtName = `${milestoneId}-${sid}`;
|
|
416
|
+
try {
|
|
417
|
+
removeWorktree(basePath, wtName, { deleteBranch: true, force: true });
|
|
418
|
+
}
|
|
419
|
+
catch { /* ignore cleanup failures */ }
|
|
420
|
+
}
|
|
364
421
|
// If nothing started, deactivate
|
|
365
422
|
if (started.length === 0) {
|
|
366
423
|
sliceState.active = false;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// GSD-2 — Smart entry routing decisions.
|
|
2
|
+
// Pure route selection for /gsd guided wizard choices.
|
|
3
|
+
export function resolveGuidedExecuteLaunchMode(isolationMode) {
|
|
4
|
+
return isolationMode === "worktree" ? "auto-step" : "guided-dispatch";
|
|
5
|
+
}
|
|
6
|
+
export function resolveActiveTaskChoiceRoute(input) {
|
|
7
|
+
if (input.choice === "auto") {
|
|
8
|
+
return {
|
|
9
|
+
kind: "auto-bootstrap",
|
|
10
|
+
verboseMode: false,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (input.choice === "execute") {
|
|
14
|
+
if (resolveGuidedExecuteLaunchMode(input.isolationMode) === "auto-step") {
|
|
15
|
+
return {
|
|
16
|
+
kind: "auto-bootstrap",
|
|
17
|
+
verboseMode: false,
|
|
18
|
+
options: {
|
|
19
|
+
step: true,
|
|
20
|
+
milestoneLock: input.milestoneId,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
kind: "guided-dispatch",
|
|
26
|
+
unitType: "execute-task",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (input.choice === "status") {
|
|
30
|
+
return { kind: "status" };
|
|
31
|
+
}
|
|
32
|
+
if (input.choice === "milestone_actions") {
|
|
33
|
+
return { kind: "milestone-actions" };
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`Invalid ActiveTaskChoice: ${input.choice}`);
|
|
36
|
+
}
|
|
@@ -10,6 +10,7 @@ import { isAbsolute, join, resolve } from "node:path";
|
|
|
10
10
|
import { getErrorMessage } from "../../error-utils.js";
|
|
11
11
|
import { nativeAddPaths, nativeCheckoutTheirs, nativeCommit, nativeConflictFiles, nativeMergeAbort, nativeRebaseAbort, nativeResetHard, } from "../../native-git-bridge.js";
|
|
12
12
|
import { logError, logWarning } from "../../workflow-logger.js";
|
|
13
|
+
import { isGsdWorktreePath } from "../../worktree-root.js";
|
|
13
14
|
const SILENT_NOTIFY = () => { };
|
|
14
15
|
function resolveGitDir(basePath) {
|
|
15
16
|
try {
|
|
@@ -23,7 +24,11 @@ function resolveGitDir(basePath) {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
catch (err) {
|
|
26
|
-
|
|
27
|
+
const message = getErrorMessage(err);
|
|
28
|
+
logWarning("recovery", `gitdir resolution failed: ${message}`);
|
|
29
|
+
if (isGsdWorktreePath(basePath)) {
|
|
30
|
+
throw new Error(`Worktree integrity failure: ${basePath} is not a valid git worktree (git rev-parse failed: ${message.split("\n")[0]}). Repair or recreate the worktree before retrying.`);
|
|
31
|
+
}
|
|
27
32
|
}
|
|
28
33
|
return join(basePath, ".git");
|
|
29
34
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// Project/App: GSD-2
|
|
2
2
|
// File Purpose: ADR-017 unregistered-milestone drift handler. Detects
|
|
3
3
|
// milestones whose on-disk directory has meaningful content (ROADMAP/
|
|
4
|
-
// CONTEXT/SUMMARY) but no DB row, then
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// CONTEXT/SUMMARY) but no DB row, then fails closed with an explicit recovery
|
|
5
|
+
// instruction. Markdown hierarchy import is reserved for operator-controlled
|
|
6
|
+
// migration/recovery commands, not automatic runtime reconciliation.
|
|
7
7
|
import { existsSync } from "node:fs";
|
|
8
8
|
import { getMilestone, isDbAvailable } from "../../gsd-db.js";
|
|
9
|
-
import { migrateHierarchyToDb } from "../../md-importer.js";
|
|
10
9
|
import { findMilestoneIds } from "../../milestone-ids.js";
|
|
11
10
|
import { resolveMilestoneFile } from "../../paths.js";
|
|
12
11
|
function milestoneHasContent(basePath, milestoneId) {
|
|
@@ -31,17 +30,13 @@ export function detectUnregisteredMilestoneDrift(_state, ctx) {
|
|
|
31
30
|
return drifts;
|
|
32
31
|
}
|
|
33
32
|
/**
|
|
34
|
-
* Repair
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* Note: even though we receive one record at a time, the importer is a
|
|
39
|
-
* project-wide operation. Repeated invocation across multiple drift records
|
|
40
|
-
* in the same pass is wasteful but safe; a future optimization could
|
|
41
|
-
* coalesce by checking whether the importer has already run this pass.
|
|
33
|
+
* Repair intentionally fails closed. The project-root DB is authoritative at
|
|
34
|
+
* runtime; markdown-only milestones must be imported through an explicit
|
|
35
|
+
* migration/recovery command so operators opt into changing canonical state.
|
|
42
36
|
*/
|
|
43
|
-
export function repairUnregisteredMilestone(
|
|
44
|
-
|
|
37
|
+
export function repairUnregisteredMilestone(record, _ctx) {
|
|
38
|
+
throw new Error(`Milestone ${record.milestoneId} exists only as markdown projection. ` +
|
|
39
|
+
"Runtime reconciliation will not import markdown into the authoritative DB; run explicit GSD recovery/migration if this markdown should repopulate the database.");
|
|
45
40
|
}
|
|
46
41
|
export const unregisteredMilestoneHandler = {
|
|
47
42
|
kind: "unregistered-milestone",
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// Project/App: GSD-2
|
|
2
2
|
// File Purpose: ADR-017 roadmap-divergence drift handler. Detects mismatches
|
|
3
|
-
// between ROADMAP.md (parsed slice sequence
|
|
4
|
-
// DB slice rows for that milestone, then
|
|
5
|
-
//
|
|
3
|
+
// between ROADMAP.md (parsed slice sequence, depends declarations, and
|
|
4
|
+
// checkboxes) and the DB slice rows for that milestone, then re-renders the
|
|
5
|
+
// ROADMAP projection from the authoritative DB rows.
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
7
|
-
import { getMilestone, getMilestoneSlices, isDbAvailable,
|
|
8
|
-
import {
|
|
7
|
+
import { getMilestone, getMilestoneSlices, isDbAvailable, } from "../../gsd-db.js";
|
|
8
|
+
import { renderRoadmapFromDb } from "../../markdown-renderer.js";
|
|
9
9
|
import { findMilestoneIds } from "../../milestone-ids.js";
|
|
10
10
|
import { parseRoadmap } from "../../parsers-legacy.js";
|
|
11
11
|
import { resolveMilestoneFile } from "../../paths.js";
|
|
12
|
+
import { isClosedStatus } from "../../status-guards.js";
|
|
12
13
|
function arraysEqual(a, b) {
|
|
13
14
|
if (a.length !== b.length)
|
|
14
15
|
return false;
|
|
@@ -30,8 +31,10 @@ function milestoneHasDivergence(basePath, milestoneId) {
|
|
|
30
31
|
}
|
|
31
32
|
const dbSlices = getMilestoneSlices(milestoneId);
|
|
32
33
|
const dbSliceMap = new Map(dbSlices.map((s) => [s.id, s]));
|
|
34
|
+
const roadmapSliceIds = new Set();
|
|
33
35
|
for (let i = 0; i < roadmap.slices.length; i++) {
|
|
34
36
|
const roadmapSlice = roadmap.slices[i];
|
|
37
|
+
roadmapSliceIds.add(roadmapSlice.id);
|
|
35
38
|
const expectedSequence = i + 1;
|
|
36
39
|
const dbSlice = dbSliceMap.get(roadmapSlice.id);
|
|
37
40
|
if (!dbSlice)
|
|
@@ -40,6 +43,12 @@ function milestoneHasDivergence(basePath, milestoneId) {
|
|
|
40
43
|
return true;
|
|
41
44
|
if (!arraysEqual(dbSlice.depends, roadmapSlice.depends))
|
|
42
45
|
return true;
|
|
46
|
+
if (isClosedStatus(dbSlice.status) !== roadmapSlice.done)
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
for (const dbSlice of dbSlices) {
|
|
50
|
+
if (!roadmapSliceIds.has(dbSlice.id))
|
|
51
|
+
return true;
|
|
43
52
|
}
|
|
44
53
|
return false;
|
|
45
54
|
}
|
|
@@ -59,26 +68,12 @@ export function detectRoadmapDivergenceDrift(_state, ctx) {
|
|
|
59
68
|
return drifts;
|
|
60
69
|
}
|
|
61
70
|
/**
|
|
62
|
-
* Repair a milestone's roadmap divergence
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* 2. syncSliceDependencies updates the junction table per slice — the
|
|
66
|
-
* importer only writes the JSON column, not the relational view.
|
|
71
|
+
* Repair a milestone's roadmap divergence by regenerating the projection from
|
|
72
|
+
* DB rows. ROADMAP.md is a projection; runtime reconciliation must not import
|
|
73
|
+
* slice presence, sequence, dependencies, or checkbox state from markdown.
|
|
67
74
|
*/
|
|
68
|
-
export function repairRoadmapDivergence(record, ctx) {
|
|
69
|
-
|
|
70
|
-
const roadmapPath = resolveMilestoneFile(ctx.basePath, record.milestoneId, "ROADMAP");
|
|
71
|
-
if (!roadmapPath || !existsSync(roadmapPath))
|
|
72
|
-
return;
|
|
73
|
-
try {
|
|
74
|
-
const roadmap = parseRoadmap(readFileSync(roadmapPath, "utf-8"));
|
|
75
|
-
for (const slice of roadmap.slices) {
|
|
76
|
-
syncSliceDependencies(record.milestoneId, slice.id, slice.depends);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
catch {
|
|
80
|
-
/* parse failure: detector will fire again next pass */
|
|
81
|
-
}
|
|
75
|
+
export async function repairRoadmapDivergence(record, ctx) {
|
|
76
|
+
await renderRoadmapFromDb(ctx.basePath, record.milestoneId);
|
|
82
77
|
}
|
|
83
78
|
export const roadmapDivergenceHandler = {
|
|
84
79
|
kind: "roadmap-divergence",
|
|
@@ -352,6 +352,12 @@ async function buildRegistryAndFindActive(basePath, milestones, completeMileston
|
|
|
352
352
|
continue;
|
|
353
353
|
}
|
|
354
354
|
if (allSlicesDone) {
|
|
355
|
+
const validation = getLatestAssessmentByScope(m.id, "milestone-validation");
|
|
356
|
+
const verdict = typeof validation?.status === "string" ? validation.status : undefined;
|
|
357
|
+
if (verdict === "needs-attention") {
|
|
358
|
+
registry.push({ id: m.id, title, status: "parked", ...(deps.length > 0 ? { dependsOn: deps } : {}) });
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
355
361
|
activeMilestone = { id: m.id, title };
|
|
356
362
|
activeMilestoneSlices = slices;
|
|
357
363
|
activeMilestoneFound = true;
|
|
@@ -460,7 +466,7 @@ async function handleAllSlicesDone(basePath, activeMilestone, registry, requirem
|
|
|
460
466
|
recentDecisions: [],
|
|
461
467
|
blockers: [
|
|
462
468
|
`Milestone ${activeMilestone.id} validation verdict is needs-remediation but all slices are complete. ` +
|
|
463
|
-
`Add remediation slices via gsd_reassess_roadmap or
|
|
469
|
+
`Add remediation slices via gsd_reassess_roadmap, or run \`/gsd verdict pass --rationale "..."\` to override.`,
|
|
464
470
|
],
|
|
465
471
|
nextAction: `Resolve ${activeMilestone.id} remediation before proceeding.`,
|
|
466
472
|
registry, requirements,
|
|
@@ -892,6 +898,10 @@ export async function _deriveStateImpl(basePath, opts) {
|
|
|
892
898
|
const validationContent = validationFile ? await cachedLoadFile(validationFile) : null;
|
|
893
899
|
const validationTerminal = validationContent ? isValidationTerminal(validationContent) : false;
|
|
894
900
|
const verdict = validationContent ? extractVerdict(validationContent) : undefined;
|
|
901
|
+
if (verdict === "needs-attention") {
|
|
902
|
+
registry.push({ id: mid, title, status: "parked" });
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
895
905
|
// needs-remediation is terminal but requires re-validation (#3596)
|
|
896
906
|
const needsRevalidation = !validationTerminal || verdict === 'needs-remediation';
|
|
897
907
|
if (summaryFile && await isTerminalMilestoneSummaryFile(summaryFile, cachedLoadFile)) {
|
|
@@ -911,7 +921,7 @@ export async function _deriveStateImpl(basePath, opts) {
|
|
|
911
921
|
registry.push({ id: mid, title, status: 'pending' });
|
|
912
922
|
}
|
|
913
923
|
else if (!activeMilestoneFound) {
|
|
914
|
-
// Terminal validation
|
|
924
|
+
// Terminal passing validation but no summary → completing-milestone
|
|
915
925
|
activeMilestone = { id: mid, title };
|
|
916
926
|
activeRoadmap = roadmap;
|
|
917
927
|
activeMilestoneFound = true;
|
|
@@ -1132,7 +1142,7 @@ export async function _deriveStateImpl(basePath, opts) {
|
|
|
1132
1142
|
recentDecisions: [],
|
|
1133
1143
|
blockers: [
|
|
1134
1144
|
`Milestone ${activeMilestone.id} validation verdict is needs-remediation but all slices are complete. ` +
|
|
1135
|
-
`Add remediation slices via gsd_reassess_roadmap or
|
|
1145
|
+
`Add remediation slices via gsd_reassess_roadmap, or run \`/gsd verdict pass --rationale "..."\` to override.`,
|
|
1136
1146
|
],
|
|
1137
1147
|
nextAction: `Resolve ${activeMilestone.id} remediation before proceeding.`,
|
|
1138
1148
|
registry,
|
|
@@ -1253,7 +1263,7 @@ export async function _deriveStateImpl(basePath, opts) {
|
|
|
1253
1263
|
const summaryPath = resolveTaskFile(basePath, activeMilestone.id, activeSlice.id, t.id, "SUMMARY");
|
|
1254
1264
|
if (summaryPath && existsSync(summaryPath)) {
|
|
1255
1265
|
t.done = true;
|
|
1256
|
-
logWarning("reconcile", `task ${activeMilestone.id}/${activeSlice.id}/${t.id} reconciled via SUMMARY on disk
|
|
1266
|
+
logWarning("reconcile", `task ${activeMilestone.id}/${activeSlice.id}/${t.id} reconciled via SUMMARY on disk`, { mid: activeMilestone.id, sid: activeSlice.id, tid: t.id });
|
|
1257
1267
|
}
|
|
1258
1268
|
}
|
|
1259
1269
|
const taskProgress = {
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
* Status predicates for GSD state-machine guards.
|
|
3
3
|
*
|
|
4
4
|
* The DB stores status as free-form strings. Three values indicate
|
|
5
|
-
* "closed": "complete" (canonical), "done" (legacy / alias),
|
|
5
|
+
* "closed": "complete" (canonical), "done" (legacy / alias),
|
|
6
|
+
* "closed" (legacy/imported), and
|
|
6
7
|
* "skipped" (user-directed skip via rethink or backtrack).
|
|
7
8
|
* Every inline `status === "complete" || status === "done"` should
|
|
8
9
|
* use isClosedStatus() instead.
|
|
9
10
|
*/
|
|
10
11
|
/** Returns true when a milestone, slice, or task status indicates closure. */
|
|
11
12
|
export function isClosedStatus(status) {
|
|
12
|
-
return status === "complete" || status === "done" || status === "skipped";
|
|
13
|
+
return status === "complete" || status === "done" || status === "skipped" || status === "closed";
|
|
13
14
|
}
|
|
14
15
|
/** Returns true when a slice status indicates it was deferred by a decision. */
|
|
15
16
|
export function isDeferredStatus(status) {
|
|
@@ -22,3 +23,14 @@ export function isDeferredStatus(status) {
|
|
|
22
23
|
export function isInactiveStatus(status) {
|
|
23
24
|
return isClosedStatus(status) || isDeferredStatus(status);
|
|
24
25
|
}
|
|
26
|
+
/** Returns true when a prior milestone should not block dispatch ordering. */
|
|
27
|
+
export function isSkippedForDispatch(status) {
|
|
28
|
+
return isClosedStatus(status) || status === "parked" || isDeferredStatus(status);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns true when a milestone is future/backlog work (not currently executing).
|
|
32
|
+
* Includes legacy/project-specific alias "planned" for compatibility.
|
|
33
|
+
*/
|
|
34
|
+
export function isFutureMilestoneStatus(status) {
|
|
35
|
+
return status === "pending" || status === "queued" || status === "planned";
|
|
36
|
+
}
|
|
@@ -99,11 +99,11 @@
|
|
|
99
99
|
- "Improve UI"
|
|
100
100
|
|
|
101
101
|
Each task should usually include:
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
102
|
+
- description: why this task exists, concrete steps, and done-when acceptance
|
|
103
|
+
- files: JSON array of likely touched paths
|
|
104
|
+
- verify: the command, test, or runtime check that proves it worked
|
|
105
|
+
- inputs: JSON array of existing paths or prior task outputs this task consumes
|
|
106
|
+
- expectedOutput: JSON array of paths this task creates or overwrites
|
|
107
107
|
|
|
108
108
|
Keep the checkbox line format exactly:
|
|
109
109
|
- [ ] **T01: Title** `est:30m`
|
|
@@ -131,10 +131,14 @@
|
|
|
131
131
|
|
|
132
132
|
Verify field rules:
|
|
133
133
|
- MUST be a mechanically executable command: `npm test`, `grep -q "pattern" file`, `test -f path`
|
|
134
|
+
- MUST NOT use shell pipes, redirects, semicolons, backticks, command substitution, or output trimming
|
|
135
|
+
- MUST NOT use inline `node -e` assertions for verification; put assertions in a real test file and run it with `node --test` or a package test script
|
|
134
136
|
- For content/document tasks: verify file existence, section count, YAML validity, or word count
|
|
135
137
|
NOT exact phrasing, specific formulas, or "zero TBD" aspirational criteria
|
|
136
138
|
- If no command can verify the output, write: "Manual review — file exists and is non-empty"
|
|
139
|
+
- BAD: `python3 -m pytest tests/ -q --tb=short 2>&1 | tail -5`
|
|
137
140
|
- BAD: "Sections 3.1 and 3.2 exist with exact formulas. Zero TBD/TODO."
|
|
141
|
+
- GOOD: `python3 -m pytest tests/ -q --tb=short`
|
|
138
142
|
- GOOD: `grep -c "^## " doc.md` returns >= 4 (4+ sections), `! grep -q "TBD\|TODO" doc.md`
|
|
139
143
|
|
|
140
144
|
Integration closure rule:
|