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
|
@@ -16,6 +16,7 @@ import { gsdRoot } from "./paths.js";
|
|
|
16
16
|
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
17
17
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
18
18
|
import { logWarning } from "./workflow-logger.js";
|
|
19
|
+
import { createRepositoryRegistryFromPreferences } from "./repository-registry.js";
|
|
19
20
|
import { detectWorktreeName, } from "./worktree.js";
|
|
20
21
|
import { SLICE_BRANCH_RE, QUICK_BRANCH_RE, WORKFLOW_BRANCH_RE } from "./branch-patterns.js";
|
|
21
22
|
import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeBranchExists, nativeHasChanges, nativeAddAllWithExclusions, nativeHasStagedChanges, nativeCommit, nativeRmCached, nativeUpdateRef, nativeAddPaths, nativeResetSoft, nativeCommitSubject, nativeIsIgnored, _resetHasChangesCache, } from "./native-git-bridge.js";
|
|
@@ -139,6 +140,30 @@ function isExcludedScopedPath(path, exclusions) {
|
|
|
139
140
|
}
|
|
140
141
|
return false;
|
|
141
142
|
}
|
|
143
|
+
function submodulePathsFromLsFiles(output) {
|
|
144
|
+
const submodulePaths = new Set();
|
|
145
|
+
if (!output)
|
|
146
|
+
return submodulePaths;
|
|
147
|
+
for (const line of output.split("\n")) {
|
|
148
|
+
const match = line.match(/^160000\s+\S+\s+\d+\t(.+)$/);
|
|
149
|
+
if (!match)
|
|
150
|
+
continue;
|
|
151
|
+
submodulePaths.add(match[1].replace(/\\/g, "/").replace(/\/+$/, ""));
|
|
152
|
+
}
|
|
153
|
+
return submodulePaths;
|
|
154
|
+
}
|
|
155
|
+
function isInsideSubmodule(path, submodulePaths) {
|
|
156
|
+
const normalizedPath = path.replace(/\\/g, "/");
|
|
157
|
+
if (submodulePaths.has(normalizedPath))
|
|
158
|
+
return true;
|
|
159
|
+
let slashIndex = normalizedPath.lastIndexOf("/");
|
|
160
|
+
while (slashIndex > 0) {
|
|
161
|
+
if (submodulePaths.has(normalizedPath.slice(0, slashIndex)))
|
|
162
|
+
return true;
|
|
163
|
+
slashIndex = normalizedPath.lastIndexOf("/", slashIndex - 1);
|
|
164
|
+
}
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
142
167
|
/**
|
|
143
168
|
* Thrown when a slice merge hits code conflicts in non-.gsd files.
|
|
144
169
|
* The working tree is left in a conflicted state (no reset) so the
|
|
@@ -213,6 +238,8 @@ export function readIntegrationBranch(basePath, milestoneId) {
|
|
|
213
238
|
return null;
|
|
214
239
|
}
|
|
215
240
|
}
|
|
241
|
+
/** Re-export for backward compatibility — canonical definitions in branch-patterns.ts */
|
|
242
|
+
export { QUICK_BRANCH_RE, WORKFLOW_BRANCH_RE } from "./branch-patterns.js";
|
|
216
243
|
/**
|
|
217
244
|
* Persist the integration branch for a milestone.
|
|
218
245
|
*
|
|
@@ -223,9 +250,11 @@ export function readIntegrationBranch(basePath, milestoneId) {
|
|
|
223
250
|
*
|
|
224
251
|
* The file is committed immediately so the metadata is persisted in git.
|
|
225
252
|
*/
|
|
226
|
-
/** Re-export for backward compatibility — canonical definitions in branch-patterns.ts */
|
|
227
|
-
export { QUICK_BRANCH_RE, WORKFLOW_BRANCH_RE } from "./branch-patterns.js";
|
|
228
253
|
export function writeIntegrationBranch(basePath, milestoneId, branch) {
|
|
254
|
+
// Never persist milestone branches as integration targets.
|
|
255
|
+
// They are ephemeral execution branches and can cause self-diff corruption.
|
|
256
|
+
if (branch.startsWith("milestone/"))
|
|
257
|
+
return;
|
|
229
258
|
// Don't record slice branches as the integration target
|
|
230
259
|
if (SLICE_BRANCH_RE.test(branch))
|
|
231
260
|
return;
|
|
@@ -572,6 +601,20 @@ export class GitServiceImpl {
|
|
|
572
601
|
.filter((file) => file !== null)
|
|
573
602
|
.filter(file => !nativeIsIgnored(this.basePath, file))
|
|
574
603
|
.filter(file => !isExcludedScopedPath(file, allExclusions));
|
|
604
|
+
const scopedPaths = [];
|
|
605
|
+
const submodulePaths = [];
|
|
606
|
+
const repoSubmodules = submodulePathsFromLsFiles(runGit(this.basePath, ["ls-files", "--stage"], { allowFailure: true }));
|
|
607
|
+
for (const path of normalized) {
|
|
608
|
+
if (isInsideSubmodule(path, repoSubmodules)) {
|
|
609
|
+
submodulePaths.push(path);
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
scopedPaths.push(path);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
if (submodulePaths.length > 0) {
|
|
616
|
+
logWarning("engine", `scoped stage: dropping ${submodulePaths.length} keyFile(s) inside git submodule(s): ${submodulePaths.join(", ")}`, { file: "git-service.ts" });
|
|
617
|
+
}
|
|
575
618
|
// Drop entries that don't exist on disk. The LLM occasionally lists files
|
|
576
619
|
// it intended to write but didn't (or names them with wrong casing/path).
|
|
577
620
|
// Pre-`b304f738b` `git add -A` swallowed these silently; the scoped
|
|
@@ -579,7 +622,7 @@ export class GitServiceImpl {
|
|
|
579
622
|
// the whole commit fail (see #5500). Filter so valid paths still commit.
|
|
580
623
|
const missing = [];
|
|
581
624
|
const existing = [];
|
|
582
|
-
for (const path of
|
|
625
|
+
for (const path of scopedPaths) {
|
|
583
626
|
if (existsSync(join(this.basePath, path))) {
|
|
584
627
|
existing.push(path);
|
|
585
628
|
}
|
|
@@ -651,7 +694,23 @@ export class GitServiceImpl {
|
|
|
651
694
|
const message = taskContext
|
|
652
695
|
? buildTaskCommitMessage(taskContext)
|
|
653
696
|
: `chore: auto-commit after ${unitType}\n\nGSD-Unit: ${unitId}`;
|
|
654
|
-
|
|
697
|
+
try {
|
|
698
|
+
nativeCommit(this.basePath, message, { allowEmpty: false });
|
|
699
|
+
}
|
|
700
|
+
catch (err) {
|
|
701
|
+
// Some pre-commit hooks intentionally rewrite files and fail the first
|
|
702
|
+
// commit to force a re-stage + retry.
|
|
703
|
+
if (!nativeHasChanges(this.basePath))
|
|
704
|
+
throw err;
|
|
705
|
+
const retriedScoped = taskContext
|
|
706
|
+
? this.scopedStageTaskFiles(taskContext, extraExclusions)
|
|
707
|
+
: false;
|
|
708
|
+
if (!retriedScoped)
|
|
709
|
+
this.smartStage(extraExclusions);
|
|
710
|
+
if (!nativeHasStagedChanges(this.basePath))
|
|
711
|
+
throw err;
|
|
712
|
+
nativeCommit(this.basePath, message, { allowEmpty: false });
|
|
713
|
+
}
|
|
655
714
|
// Absorb any preceding gsd snapshot commits into this real commit.
|
|
656
715
|
// Walk backwards from HEAD~1 counting consecutive snapshot subjects,
|
|
657
716
|
// then soft-reset to before them and re-commit with the same message.
|
|
@@ -919,21 +978,70 @@ export function handleTurnGitActionError(action, err) {
|
|
|
919
978
|
if (isInfrastructureError(err)) {
|
|
920
979
|
throw err;
|
|
921
980
|
}
|
|
981
|
+
const errorWithStreams = err;
|
|
922
982
|
return {
|
|
923
983
|
action,
|
|
924
984
|
status: "failed",
|
|
925
|
-
error: getErrorMessage(err),
|
|
985
|
+
error: errorWithStreams.stderr?.trim() || errorWithStreams.message || getErrorMessage(err),
|
|
926
986
|
};
|
|
927
987
|
}
|
|
988
|
+
function collectRepositoryDirtyStatus(basePath) {
|
|
989
|
+
const preferences = loadEffectiveGSDPreferences(basePath)?.preferences;
|
|
990
|
+
const registry = createRepositoryRegistryFromPreferences(basePath, preferences);
|
|
991
|
+
const dirtyByRepository = {};
|
|
992
|
+
for (const repo of registry.repositories) {
|
|
993
|
+
try {
|
|
994
|
+
dirtyByRepository[repo.id] = runGit(repo.root, ["status", "--porcelain"]).length > 0;
|
|
995
|
+
}
|
|
996
|
+
catch {
|
|
997
|
+
// Fallback preserves legacy behavior if explicit status probing fails.
|
|
998
|
+
dirtyByRepository[repo.id] = nativeHasChanges(repo.root);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
return dirtyByRepository;
|
|
1002
|
+
}
|
|
1003
|
+
function runPerRepositoryCommitAction(args) {
|
|
1004
|
+
const preferences = loadEffectiveGSDPreferences(args.basePath)?.preferences;
|
|
1005
|
+
const registry = createRepositoryRegistryFromPreferences(args.basePath, preferences);
|
|
1006
|
+
const repoIds = args.targetRepositories ?? ["project"];
|
|
1007
|
+
const gitPrefs = preferences?.git ?? {};
|
|
1008
|
+
const commitMessages = {};
|
|
1009
|
+
const commitErrors = {};
|
|
1010
|
+
const skippedRepositories = [];
|
|
1011
|
+
for (const repoId of repoIds) {
|
|
1012
|
+
const repo = registry.byId.get(repoId);
|
|
1013
|
+
if (!repo) {
|
|
1014
|
+
commitErrors[repoId] = `unknown repository target: ${repoId}`;
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
1017
|
+
if (repo.commitPolicy === "skip") {
|
|
1018
|
+
skippedRepositories.push(repo.id);
|
|
1019
|
+
continue;
|
|
1020
|
+
}
|
|
1021
|
+
try {
|
|
1022
|
+
const message = new GitServiceImpl(repo.root, gitPrefs).autoCommit(args.unitType, args.unitId, [], args.taskContext) ?? "";
|
|
1023
|
+
if (message) {
|
|
1024
|
+
commitMessages[repo.id] = message;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
catch (err) {
|
|
1028
|
+
commitErrors[repo.id] = getErrorMessage(err);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
return { commitMessages, commitErrors, skippedRepositories };
|
|
1032
|
+
}
|
|
928
1033
|
export function runTurnGitAction(args) {
|
|
929
1034
|
try {
|
|
930
1035
|
// Force fresh working-tree status per turn; nativeHasChanges caches briefly.
|
|
931
1036
|
_resetHasChangesCache();
|
|
1037
|
+
const dirtyRepositories = collectRepositoryDirtyStatus(args.basePath);
|
|
1038
|
+
const dirty = Object.values(dirtyRepositories).some(Boolean);
|
|
932
1039
|
if (args.action === "status-only") {
|
|
933
1040
|
return {
|
|
934
1041
|
action: args.action,
|
|
935
1042
|
status: "ok",
|
|
936
|
-
dirty
|
|
1043
|
+
dirty,
|
|
1044
|
+
dirtyRepositories,
|
|
937
1045
|
};
|
|
938
1046
|
}
|
|
939
1047
|
const git = createGitService(args.basePath);
|
|
@@ -944,15 +1052,35 @@ export function runTurnGitAction(args) {
|
|
|
944
1052
|
action: args.action,
|
|
945
1053
|
status: "ok",
|
|
946
1054
|
snapshotLabel: label,
|
|
947
|
-
dirty
|
|
1055
|
+
dirty,
|
|
1056
|
+
dirtyRepositories,
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
const repoCommitResult = runPerRepositoryCommitAction(args);
|
|
1060
|
+
if (Object.keys(repoCommitResult.commitErrors).length > 0) {
|
|
1061
|
+
return {
|
|
1062
|
+
action: args.action,
|
|
1063
|
+
status: "failed",
|
|
1064
|
+
error: Object.entries(repoCommitResult.commitErrors)
|
|
1065
|
+
.map(([repoId, msg]) => `${repoId}: ${msg}`)
|
|
1066
|
+
.join("; "),
|
|
1067
|
+
dirty,
|
|
1068
|
+
dirtyRepositories,
|
|
1069
|
+
commitMessages: repoCommitResult.commitMessages,
|
|
1070
|
+
commitErrors: repoCommitResult.commitErrors,
|
|
1071
|
+
skippedRepositories: repoCommitResult.skippedRepositories,
|
|
948
1072
|
};
|
|
949
1073
|
}
|
|
950
|
-
const
|
|
1074
|
+
const primaryMessage = repoCommitResult.commitMessages[args.targetRepositories?.[0] ?? "project"]
|
|
1075
|
+
?? Object.values(repoCommitResult.commitMessages)[0];
|
|
951
1076
|
return {
|
|
952
1077
|
action: args.action,
|
|
953
1078
|
status: "ok",
|
|
954
|
-
commitMessage,
|
|
955
|
-
dirty
|
|
1079
|
+
commitMessage: primaryMessage,
|
|
1080
|
+
dirty,
|
|
1081
|
+
dirtyRepositories,
|
|
1082
|
+
commitMessages: repoCommitResult.commitMessages,
|
|
1083
|
+
skippedRepositories: repoCommitResult.skippedRepositories,
|
|
956
1084
|
};
|
|
957
1085
|
}
|
|
958
1086
|
catch (err) {
|
|
@@ -37,7 +37,7 @@ import { rowToActiveDecision, rowToActiveRequirement, rowToDecision, rowToRequir
|
|
|
37
37
|
import { rowToGate } from "./db-gate-rows.js";
|
|
38
38
|
import { rowToArtifact, rowToMilestone } from "./db-milestone-artifact-rows.js";
|
|
39
39
|
import { backupDatabaseBeforeMigration } from "./db-migration-backup.js";
|
|
40
|
-
import { applyMigrationV2Artifacts, applyMigrationV3Memories, applyMigrationV4DecisionMadeBy, applyMigrationV5HierarchyTables, applyMigrationV6SliceSummaries, applyMigrationV7Dependencies, applyMigrationV8PlanningFields, applyMigrationV9Ordering, applyMigrationV10ReplanTrigger, applyMigrationV11TaskPlanning, applyMigrationV12QualityGates, applyMigrationV13HotPathIndexes, applyMigrationV14SliceDependencies, applyMigrationV15AuditTables, applyMigrationV16EscalationSource, applyMigrationV17TaskEscalation, applyMigrationV18MemorySources, applyMigrationV19MemoryFts, applyMigrationV20MemoryRelations, applyMigrationV21StructuredMemories, applyMigrationV22QualityGateRepair, applyMigrationV23MilestoneQueue, applyMigrationV26MilestoneCommitAttributions, applyMigrationV27ArtifactHash, applyMigrationV28MemoryLastHitAt, } from "./db-migration-steps.js";
|
|
40
|
+
import { applyMigrationV2Artifacts, applyMigrationV3Memories, applyMigrationV4DecisionMadeBy, applyMigrationV5HierarchyTables, applyMigrationV6SliceSummaries, applyMigrationV7Dependencies, applyMigrationV8PlanningFields, applyMigrationV9Ordering, applyMigrationV10ReplanTrigger, applyMigrationV11TaskPlanning, applyMigrationV12QualityGates, applyMigrationV13HotPathIndexes, applyMigrationV14SliceDependencies, applyMigrationV15AuditTables, applyMigrationV16EscalationSource, applyMigrationV17TaskEscalation, applyMigrationV18MemorySources, applyMigrationV19MemoryFts, applyMigrationV20MemoryRelations, applyMigrationV21StructuredMemories, applyMigrationV22QualityGateRepair, applyMigrationV23MilestoneQueue, applyMigrationV26MilestoneCommitAttributions, applyMigrationV27ArtifactHash, applyMigrationV28MemoryLastHitAt, applyMigrationV29RepositoryTargets, } from "./db-migration-steps.js";
|
|
41
41
|
import { isMemoriesFtsAvailableSchema, tryCreateMemoriesFtsSchema } from "./db-memory-fts-schema.js";
|
|
42
42
|
import { createDbOpenState } from "./db-open-state.js";
|
|
43
43
|
import { createRuntimeKvTableV25 } from "./db-runtime-kv-schema.js";
|
|
@@ -53,19 +53,21 @@ const providerLoader = createSqliteProviderLoader({
|
|
|
53
53
|
nodeVersion: process.versions.node,
|
|
54
54
|
writeStderr: (message) => process.stderr.write(message),
|
|
55
55
|
});
|
|
56
|
-
export const SCHEMA_VERSION =
|
|
57
|
-
|
|
56
|
+
export const SCHEMA_VERSION = 29;
|
|
57
|
+
const TERMINAL_STATUS_SQL = "'complete', 'done', 'skipped', 'closed'";
|
|
58
|
+
function initSchema(db, fileBacked, dbPath) {
|
|
59
|
+
const conservativeFilePragmas = fileBacked && _isLikelyWslDrvFsPathForTest(dbPath);
|
|
58
60
|
if (fileBacked)
|
|
59
|
-
db.exec("PRAGMA journal_mode=WAL");
|
|
61
|
+
db.exec(conservativeFilePragmas ? "PRAGMA journal_mode=DELETE" : "PRAGMA journal_mode=WAL");
|
|
60
62
|
if (fileBacked)
|
|
61
63
|
db.exec("PRAGMA busy_timeout = 5000");
|
|
62
64
|
if (fileBacked)
|
|
63
|
-
db.exec("PRAGMA synchronous = NORMAL");
|
|
65
|
+
db.exec(conservativeFilePragmas ? "PRAGMA synchronous = FULL" : "PRAGMA synchronous = NORMAL");
|
|
64
66
|
if (fileBacked)
|
|
65
67
|
db.exec("PRAGMA auto_vacuum = INCREMENTAL");
|
|
66
68
|
if (fileBacked)
|
|
67
69
|
db.exec("PRAGMA cache_size = -8000"); // 8 MB page cache
|
|
68
|
-
if (fileBacked && process.platform !== "darwin")
|
|
70
|
+
if (fileBacked && !conservativeFilePragmas && process.platform !== "darwin")
|
|
69
71
|
db.exec("PRAGMA mmap_size = 67108864"); // 64 MB mmap
|
|
70
72
|
db.exec("PRAGMA temp_store = MEMORY");
|
|
71
73
|
db.exec("PRAGMA foreign_keys = ON");
|
|
@@ -99,6 +101,19 @@ function initSchema(db, fileBacked) {
|
|
|
99
101
|
}
|
|
100
102
|
migrateSchema(db);
|
|
101
103
|
}
|
|
104
|
+
export function _isLikelyWslDrvFsPathForTest(dbPath) {
|
|
105
|
+
if (!dbPath || process.platform !== "linux")
|
|
106
|
+
return false;
|
|
107
|
+
const drvFsPathPattern = /^\/mnt\/[a-z](?:\/|$)/i;
|
|
108
|
+
if (drvFsPathPattern.test(dbPath))
|
|
109
|
+
return true;
|
|
110
|
+
try {
|
|
111
|
+
return drvFsPathPattern.test(realpathSync(dbPath));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
102
117
|
/**
|
|
103
118
|
* Create the FTS5 virtual table for memories plus the triggers that keep it
|
|
104
119
|
* in sync with the base table. FTS5 may be unavailable on stripped-down
|
|
@@ -259,6 +274,10 @@ function migrateSchema(db) {
|
|
|
259
274
|
applyMigrationV28MemoryLastHitAt(db);
|
|
260
275
|
recordSchemaVersion(db, 28);
|
|
261
276
|
}
|
|
277
|
+
if (currentVersion < 29) {
|
|
278
|
+
applyMigrationV29RepositoryTargets(db);
|
|
279
|
+
recordSchemaVersion(db, 29);
|
|
280
|
+
}
|
|
262
281
|
db.exec("COMMIT");
|
|
263
282
|
}
|
|
264
283
|
catch (err) {
|
|
@@ -504,7 +523,7 @@ export function openDatabase(path) {
|
|
|
504
523
|
const adapter = createDbAdapter(rawDb);
|
|
505
524
|
const fileBacked = path !== ":memory:";
|
|
506
525
|
try {
|
|
507
|
-
initSchema(adapter, fileBacked);
|
|
526
|
+
initSchema(adapter, fileBacked, path);
|
|
508
527
|
}
|
|
509
528
|
catch (err) {
|
|
510
529
|
// Corrupt freelist: DDL fails with "malformed" but VACUUM can rebuild.
|
|
@@ -512,7 +531,7 @@ export function openDatabase(path) {
|
|
|
512
531
|
if (fileBacked && err instanceof Error && err.message?.includes("malformed")) {
|
|
513
532
|
try {
|
|
514
533
|
adapter.exec("VACUUM");
|
|
515
|
-
initSchema(adapter, fileBacked);
|
|
534
|
+
initSchema(adapter, fileBacked, path);
|
|
516
535
|
process.stderr.write("gsd-db: recovered corrupt database via VACUUM\n");
|
|
517
536
|
}
|
|
518
537
|
catch (retryErr) {
|
|
@@ -916,16 +935,16 @@ export function insertSlice(s) {
|
|
|
916
935
|
throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
917
936
|
currentDb.prepare(`INSERT INTO slices (
|
|
918
937
|
milestone_id, id, title, status, risk, depends, demo, created_at,
|
|
919
|
-
goal, success_criteria, proof_level, integration_closure, observability_impact, sequence,
|
|
938
|
+
goal, success_criteria, proof_level, integration_closure, observability_impact, target_repositories, sequence,
|
|
920
939
|
is_sketch, sketch_scope
|
|
921
940
|
) VALUES (
|
|
922
941
|
:milestone_id, :id, :title, :status, :risk, :depends, :demo, :created_at,
|
|
923
|
-
:goal, :success_criteria, :proof_level, :integration_closure, :observability_impact, :sequence,
|
|
942
|
+
:goal, :success_criteria, :proof_level, :integration_closure, :observability_impact, :target_repositories, :sequence,
|
|
924
943
|
:is_sketch, :sketch_scope
|
|
925
944
|
)
|
|
926
945
|
ON CONFLICT (milestone_id, id) DO UPDATE SET
|
|
927
946
|
title = CASE WHEN :raw_title IS NOT NULL THEN excluded.title ELSE slices.title END,
|
|
928
|
-
status = CASE WHEN slices.status IN (
|
|
947
|
+
status = CASE WHEN slices.status IN (${TERMINAL_STATUS_SQL}) THEN slices.status ELSE excluded.status END,
|
|
929
948
|
risk = CASE WHEN :raw_risk IS NOT NULL THEN excluded.risk ELSE slices.risk END,
|
|
930
949
|
depends = excluded.depends,
|
|
931
950
|
demo = CASE WHEN :raw_demo IS NOT NULL THEN excluded.demo ELSE slices.demo END,
|
|
@@ -934,6 +953,7 @@ export function insertSlice(s) {
|
|
|
934
953
|
proof_level = CASE WHEN :raw_proof_level IS NOT NULL THEN excluded.proof_level ELSE slices.proof_level END,
|
|
935
954
|
integration_closure = CASE WHEN :raw_integration_closure IS NOT NULL THEN excluded.integration_closure ELSE slices.integration_closure END,
|
|
936
955
|
observability_impact = CASE WHEN :raw_observability_impact IS NOT NULL THEN excluded.observability_impact ELSE slices.observability_impact END,
|
|
956
|
+
target_repositories = CASE WHEN :raw_target_repositories IS NOT NULL THEN excluded.target_repositories ELSE slices.target_repositories END,
|
|
937
957
|
sequence = CASE WHEN :raw_sequence IS NOT NULL THEN excluded.sequence ELSE slices.sequence END,
|
|
938
958
|
is_sketch = CASE WHEN :raw_is_sketch IS NOT NULL THEN excluded.is_sketch ELSE slices.is_sketch END,
|
|
939
959
|
sketch_scope = CASE WHEN :raw_sketch_scope IS NOT NULL THEN excluded.sketch_scope ELSE slices.sketch_scope END`).run({
|
|
@@ -950,6 +970,7 @@ export function insertSlice(s) {
|
|
|
950
970
|
":proof_level": s.planning?.proofLevel ?? "",
|
|
951
971
|
":integration_closure": s.planning?.integrationClosure ?? "",
|
|
952
972
|
":observability_impact": s.planning?.observabilityImpact ?? "",
|
|
973
|
+
":target_repositories": JSON.stringify(s.planning?.targetRepositories ?? []),
|
|
953
974
|
":sequence": s.sequence ?? 0,
|
|
954
975
|
":is_sketch": s.isSketch ? 1 : 0,
|
|
955
976
|
":sketch_scope": s.sketchScope ?? "",
|
|
@@ -962,6 +983,7 @@ export function insertSlice(s) {
|
|
|
962
983
|
":raw_proof_level": s.planning?.proofLevel ?? null,
|
|
963
984
|
":raw_integration_closure": s.planning?.integrationClosure ?? null,
|
|
964
985
|
":raw_observability_impact": s.planning?.observabilityImpact ?? null,
|
|
986
|
+
":raw_target_repositories": s.planning?.targetRepositories ? JSON.stringify(s.planning.targetRepositories) : null,
|
|
965
987
|
":raw_sequence": s.sequence ?? null,
|
|
966
988
|
":raw_is_sketch": s.isSketch === undefined ? null : (s.isSketch ? 1 : 0),
|
|
967
989
|
// NOTE: use !== undefined (not ??) so an explicit empty string "" is treated
|
|
@@ -996,7 +1018,8 @@ export function upsertSlicePlanning(milestoneId, sliceId, planning) {
|
|
|
996
1018
|
success_criteria = COALESCE(:success_criteria, success_criteria),
|
|
997
1019
|
proof_level = COALESCE(:proof_level, proof_level),
|
|
998
1020
|
integration_closure = COALESCE(:integration_closure, integration_closure),
|
|
999
|
-
observability_impact = COALESCE(:observability_impact, observability_impact)
|
|
1021
|
+
observability_impact = COALESCE(:observability_impact, observability_impact),
|
|
1022
|
+
target_repositories = COALESCE(:target_repositories, target_repositories)
|
|
1000
1023
|
WHERE milestone_id = :milestone_id AND id = :id`).run({
|
|
1001
1024
|
":milestone_id": milestoneId,
|
|
1002
1025
|
":id": sliceId,
|
|
@@ -1005,6 +1028,7 @@ export function upsertSlicePlanning(milestoneId, sliceId, planning) {
|
|
|
1005
1028
|
":proof_level": planning.proofLevel ?? null,
|
|
1006
1029
|
":integration_closure": planning.integrationClosure ?? null,
|
|
1007
1030
|
":observability_impact": planning.observabilityImpact ?? null,
|
|
1031
|
+
":target_repositories": planning.targetRepositories ? JSON.stringify(planning.targetRepositories) : null,
|
|
1008
1032
|
});
|
|
1009
1033
|
}
|
|
1010
1034
|
export function insertTask(t) {
|
|
@@ -1015,11 +1039,13 @@ export function insertTask(t) {
|
|
|
1015
1039
|
verification_result, duration, completed_at, blocker_discovered,
|
|
1016
1040
|
deviations, known_issues, key_files, key_decisions, full_summary_md,
|
|
1017
1041
|
description, estimate, files, verify, inputs, expected_output, observability_impact, sequence
|
|
1042
|
+
, target_repositories
|
|
1018
1043
|
) VALUES (
|
|
1019
1044
|
:milestone_id, :slice_id, :id, :title, :status, :one_liner, :narrative,
|
|
1020
1045
|
:verification_result, :duration, :completed_at, :blocker_discovered,
|
|
1021
1046
|
:deviations, :known_issues, :key_files, :key_decisions, :full_summary_md,
|
|
1022
1047
|
:description, :estimate, :files, :verify, :inputs, :expected_output, :observability_impact, :sequence
|
|
1048
|
+
, :target_repositories
|
|
1023
1049
|
)
|
|
1024
1050
|
ON CONFLICT(milestone_id, slice_id, id) DO UPDATE SET
|
|
1025
1051
|
title = CASE WHEN NULLIF(:title, '') IS NOT NULL THEN :title ELSE tasks.title END,
|
|
@@ -1042,7 +1068,11 @@ export function insertTask(t) {
|
|
|
1042
1068
|
inputs = CASE WHEN NULLIF(:inputs, '[]') IS NOT NULL THEN :inputs ELSE tasks.inputs END,
|
|
1043
1069
|
expected_output = CASE WHEN NULLIF(:expected_output, '[]') IS NOT NULL THEN :expected_output ELSE tasks.expected_output END,
|
|
1044
1070
|
observability_impact = CASE WHEN NULLIF(:observability_impact, '') IS NOT NULL THEN :observability_impact ELSE tasks.observability_impact END,
|
|
1045
|
-
sequence = :sequence
|
|
1071
|
+
sequence = :sequence,
|
|
1072
|
+
target_repositories = CASE
|
|
1073
|
+
WHEN :raw_target_repositories IS NOT NULL THEN :target_repositories
|
|
1074
|
+
ELSE tasks.target_repositories
|
|
1075
|
+
END`).run({
|
|
1046
1076
|
":milestone_id": t.milestoneId,
|
|
1047
1077
|
":slice_id": t.sliceId,
|
|
1048
1078
|
":id": t.id,
|
|
@@ -1067,6 +1097,10 @@ export function insertTask(t) {
|
|
|
1067
1097
|
":expected_output": JSON.stringify(t.planning?.expectedOutput ?? []),
|
|
1068
1098
|
":observability_impact": t.planning?.observabilityImpact ?? "",
|
|
1069
1099
|
":sequence": t.sequence ?? 0,
|
|
1100
|
+
":target_repositories": JSON.stringify(t.planning?.targetRepositories ?? []),
|
|
1101
|
+
":raw_target_repositories": t.planning && "targetRepositories" in t.planning
|
|
1102
|
+
? JSON.stringify(t.planning.targetRepositories ?? [])
|
|
1103
|
+
: null,
|
|
1070
1104
|
});
|
|
1071
1105
|
}
|
|
1072
1106
|
export function updateTaskStatus(milestoneId, sliceId, taskId, status, completedAt) {
|
|
@@ -1098,7 +1132,8 @@ export function upsertTaskPlanning(milestoneId, sliceId, taskId, planning) {
|
|
|
1098
1132
|
inputs = COALESCE(:inputs, inputs),
|
|
1099
1133
|
expected_output = COALESCE(:expected_output, expected_output),
|
|
1100
1134
|
observability_impact = COALESCE(:observability_impact, observability_impact),
|
|
1101
|
-
full_plan_md = COALESCE(:full_plan_md, full_plan_md)
|
|
1135
|
+
full_plan_md = COALESCE(:full_plan_md, full_plan_md),
|
|
1136
|
+
target_repositories = COALESCE(:target_repositories, target_repositories)
|
|
1102
1137
|
WHERE milestone_id = :milestone_id AND slice_id = :slice_id AND id = :id`).run({
|
|
1103
1138
|
":milestone_id": milestoneId,
|
|
1104
1139
|
":slice_id": sliceId,
|
|
@@ -1112,6 +1147,7 @@ export function upsertTaskPlanning(milestoneId, sliceId, taskId, planning) {
|
|
|
1112
1147
|
":expected_output": planning.expectedOutput ? JSON.stringify(planning.expectedOutput) : null,
|
|
1113
1148
|
":observability_impact": planning.observabilityImpact ?? null,
|
|
1114
1149
|
":full_plan_md": planning.fullPlanMd ?? null,
|
|
1150
|
+
":target_repositories": planning.targetRepositories ? JSON.stringify(planning.targetRepositories) : null,
|
|
1115
1151
|
});
|
|
1116
1152
|
}
|
|
1117
1153
|
export function getSlice(milestoneId, sliceId) {
|
|
@@ -1352,7 +1388,7 @@ export function updateMilestoneStatus(milestoneId, status, completedAt) {
|
|
|
1352
1388
|
export function getActiveMilestoneFromDb() {
|
|
1353
1389
|
if (!currentDb)
|
|
1354
1390
|
return null;
|
|
1355
|
-
const row = currentDb.prepare("SELECT * FROM milestones WHERE status NOT IN ('complete', 'parked') ORDER BY id LIMIT 1").get();
|
|
1391
|
+
const row = currentDb.prepare("SELECT * FROM milestones WHERE status NOT IN ('complete', 'done', 'skipped', 'closed', 'parked') ORDER BY id LIMIT 1").get();
|
|
1356
1392
|
if (!row)
|
|
1357
1393
|
return null;
|
|
1358
1394
|
return rowToMilestone(row);
|
|
@@ -1404,7 +1440,7 @@ export function getArtifact(path) {
|
|
|
1404
1440
|
export function getActiveMilestoneIdFromDb() {
|
|
1405
1441
|
if (!currentDb)
|
|
1406
1442
|
return null;
|
|
1407
|
-
const row = currentDb.prepare("SELECT id, status FROM milestones WHERE status NOT IN ('complete', 'parked') ORDER BY id LIMIT 1").get();
|
|
1443
|
+
const row = currentDb.prepare("SELECT id, status FROM milestones WHERE status NOT IN ('complete', 'done', 'skipped', 'closed', 'parked') ORDER BY id LIMIT 1").get();
|
|
1408
1444
|
if (!row)
|
|
1409
1445
|
return null;
|
|
1410
1446
|
return rowToIdStatusSummary(row);
|
|
@@ -1510,12 +1546,14 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
|
1510
1546
|
const wtSliceInfo = adapter.prepare("PRAGMA wt.table_info('slices')").all();
|
|
1511
1547
|
const hasIsSketch = wtSliceInfo.some((col) => col["name"] === "is_sketch");
|
|
1512
1548
|
const hasSketchScope = wtSliceInfo.some((col) => col["name"] === "sketch_scope");
|
|
1549
|
+
const hasSliceTargetRepositories = wtSliceInfo.some((col) => col["name"] === "target_repositories");
|
|
1513
1550
|
const wtTaskInfo = adapter.prepare("PRAGMA wt.table_info('tasks')").all();
|
|
1514
1551
|
const hasBlockerSource = wtTaskInfo.some((col) => col["name"] === "blocker_source");
|
|
1515
1552
|
const hasEscalationPending = wtTaskInfo.some((col) => col["name"] === "escalation_pending");
|
|
1516
1553
|
const hasEscalationAwaiting = wtTaskInfo.some((col) => col["name"] === "escalation_awaiting_review");
|
|
1517
1554
|
const hasEscalationArtifact = wtTaskInfo.some((col) => col["name"] === "escalation_artifact_path");
|
|
1518
1555
|
const hasEscalationOverride = wtTaskInfo.some((col) => col["name"] === "escalation_override_applied_at");
|
|
1556
|
+
const hasTaskTargetRepositories = wtTaskInfo.some((col) => col["name"] === "target_repositories");
|
|
1519
1557
|
const wtArtifactInfo = adapter.prepare("PRAGMA wt.table_info('artifacts')").all();
|
|
1520
1558
|
const hasArtifactContentHash = wtArtifactInfo.some((col) => col["name"] === "content_hash");
|
|
1521
1559
|
const wtMemoryInfo = adapter.prepare("PRAGMA wt.table_info('memories')").all();
|
|
@@ -1580,16 +1618,16 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
|
1580
1618
|
)
|
|
1581
1619
|
SELECT w.id, w.title,
|
|
1582
1620
|
CASE
|
|
1583
|
-
WHEN m.status IN (
|
|
1621
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1584
1622
|
THEN m.status ELSE w.status
|
|
1585
1623
|
END,
|
|
1586
1624
|
w.depends_on,
|
|
1587
1625
|
CASE
|
|
1588
|
-
WHEN m.status IN (
|
|
1626
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1589
1627
|
THEN m.created_at ELSE w.created_at
|
|
1590
1628
|
END,
|
|
1591
1629
|
CASE
|
|
1592
|
-
WHEN m.status IN (
|
|
1630
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1593
1631
|
THEN m.completed_at ELSE w.completed_at
|
|
1594
1632
|
END,
|
|
1595
1633
|
w.vision, w.success_criteria, w.key_risks, w.proof_strategy,
|
|
@@ -1607,21 +1645,23 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
|
1607
1645
|
INSERT OR REPLACE INTO slices (
|
|
1608
1646
|
milestone_id, id, title, status, risk, depends, demo, created_at, completed_at,
|
|
1609
1647
|
full_summary_md, full_uat_md, goal, success_criteria, proof_level,
|
|
1610
|
-
integration_closure, observability_impact, sequence, replan_triggered_at,
|
|
1648
|
+
integration_closure, observability_impact, target_repositories, sequence, replan_triggered_at,
|
|
1611
1649
|
is_sketch, sketch_scope
|
|
1612
1650
|
)
|
|
1613
1651
|
SELECT w.milestone_id, w.id, w.title,
|
|
1614
1652
|
CASE
|
|
1615
|
-
WHEN m.status IN (
|
|
1653
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1616
1654
|
THEN m.status ELSE w.status
|
|
1617
1655
|
END,
|
|
1618
1656
|
w.risk, w.depends, w.demo, w.created_at,
|
|
1619
1657
|
CASE
|
|
1620
|
-
WHEN m.status IN (
|
|
1658
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1621
1659
|
THEN m.completed_at ELSE w.completed_at
|
|
1622
1660
|
END,
|
|
1623
1661
|
w.full_summary_md, w.full_uat_md, w.goal, w.success_criteria, w.proof_level,
|
|
1624
|
-
w.integration_closure, w.observability_impact,
|
|
1662
|
+
w.integration_closure, w.observability_impact,
|
|
1663
|
+
${hasSliceTargetRepositories ? "w.target_repositories" : "COALESCE(m.target_repositories, '[]')"},
|
|
1664
|
+
w.sequence, w.replan_triggered_at,
|
|
1625
1665
|
${hasIsSketch ? "w.is_sketch" : "COALESCE(m.is_sketch, 0)"},
|
|
1626
1666
|
${hasSketchScope ? "w.sketch_scope" : "COALESCE(m.sketch_scope, '')"}
|
|
1627
1667
|
FROM wt.slices w
|
|
@@ -1636,25 +1676,27 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
|
1636
1676
|
verification_result, duration, completed_at, blocker_discovered,
|
|
1637
1677
|
deviations, known_issues, key_files, key_decisions, full_summary_md,
|
|
1638
1678
|
description, estimate, files, verify, inputs, expected_output,
|
|
1639
|
-
observability_impact, full_plan_md, sequence,
|
|
1679
|
+
observability_impact, full_plan_md, target_repositories, sequence,
|
|
1640
1680
|
blocker_source, escalation_pending, escalation_awaiting_review,
|
|
1641
1681
|
escalation_artifact_path, escalation_override_applied_at
|
|
1642
1682
|
)
|
|
1643
1683
|
SELECT w.milestone_id, w.slice_id, w.id, w.title,
|
|
1644
1684
|
CASE
|
|
1645
|
-
WHEN m.status IN (
|
|
1685
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1646
1686
|
THEN m.status ELSE w.status
|
|
1647
1687
|
END,
|
|
1648
1688
|
w.one_liner, w.narrative,
|
|
1649
1689
|
w.verification_result, w.duration,
|
|
1650
1690
|
CASE
|
|
1651
|
-
WHEN m.status IN (
|
|
1691
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1652
1692
|
THEN m.completed_at ELSE w.completed_at
|
|
1653
1693
|
END,
|
|
1654
1694
|
w.blocker_discovered,
|
|
1655
1695
|
w.deviations, w.known_issues, w.key_files, w.key_decisions, w.full_summary_md,
|
|
1656
1696
|
w.description, w.estimate, w.files, w.verify, w.inputs, w.expected_output,
|
|
1657
|
-
w.observability_impact, w.full_plan_md,
|
|
1697
|
+
w.observability_impact, w.full_plan_md,
|
|
1698
|
+
${hasTaskTargetRepositories ? "w.target_repositories" : "COALESCE(m.target_repositories, '[]')"},
|
|
1699
|
+
w.sequence,
|
|
1658
1700
|
${hasBlockerSource ? "w.blocker_source" : "COALESCE(m.blocker_source, '')"},
|
|
1659
1701
|
${hasEscalationPending ? "w.escalation_pending" : "COALESCE(m.escalation_pending, 0)"},
|
|
1660
1702
|
${hasEscalationAwaiting ? "w.escalation_awaiting_review" : "COALESCE(m.escalation_awaiting_review, 0)"},
|
|
@@ -1769,6 +1811,7 @@ export function deleteTask(milestoneId, sliceId, taskId) {
|
|
|
1769
1811
|
transaction(() => {
|
|
1770
1812
|
// Must delete verification_evidence first (FK constraint)
|
|
1771
1813
|
currentDb.prepare(`DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
|
|
1814
|
+
currentDb.prepare(`DELETE FROM quality_gates WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
|
|
1772
1815
|
currentDb.prepare(`DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
|
|
1773
1816
|
});
|
|
1774
1817
|
}
|
|
@@ -2266,22 +2309,22 @@ export function restoreManifest(manifest) {
|
|
|
2266
2309
|
const slStmt = db.prepare(`INSERT INTO slices (milestone_id, id, title, status, risk, depends, demo,
|
|
2267
2310
|
created_at, completed_at, full_summary_md, full_uat_md,
|
|
2268
2311
|
goal, success_criteria, proof_level, integration_closure, observability_impact,
|
|
2269
|
-
sequence, replan_triggered_at, is_sketch, sketch_scope)
|
|
2270
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2312
|
+
target_repositories, sequence, replan_triggered_at, is_sketch, sketch_scope)
|
|
2313
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2271
2314
|
for (const s of manifest.slices) {
|
|
2272
|
-
slStmt.run(s.milestone_id, s.id, s.title, s.status, s.risk, JSON.stringify(s.depends), s.demo, s.created_at, s.completed_at, s.full_summary_md, s.full_uat_md, s.goal, s.success_criteria, s.proof_level, s.integration_closure, s.observability_impact, s.sequence, s.replan_triggered_at, s.is_sketch ?? 0, s.sketch_scope ?? "");
|
|
2315
|
+
slStmt.run(s.milestone_id, s.id, s.title, s.status, s.risk, JSON.stringify(s.depends), s.demo, s.created_at, s.completed_at, s.full_summary_md, s.full_uat_md, s.goal, s.success_criteria, s.proof_level, s.integration_closure, s.observability_impact, JSON.stringify(s.target_repositories ?? []), s.sequence, s.replan_triggered_at, s.is_sketch ?? 0, s.sketch_scope ?? "");
|
|
2273
2316
|
}
|
|
2274
2317
|
// Restore tasks (ADR-011 P2: includes blocker_source + escalation_* columns)
|
|
2275
2318
|
const tkStmt = db.prepare(`INSERT INTO tasks (milestone_id, slice_id, id, title, status,
|
|
2276
2319
|
one_liner, narrative, verification_result, duration, completed_at,
|
|
2277
2320
|
blocker_discovered, deviations, known_issues, key_files, key_decisions,
|
|
2278
2321
|
full_summary_md, description, estimate, files, verify,
|
|
2279
|
-
inputs, expected_output, observability_impact, sequence,
|
|
2322
|
+
inputs, expected_output, observability_impact, target_repositories, sequence,
|
|
2280
2323
|
blocker_source, escalation_pending, escalation_awaiting_review,
|
|
2281
2324
|
escalation_artifact_path, escalation_override_applied_at)
|
|
2282
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2325
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2283
2326
|
for (const t of manifest.tasks) {
|
|
2284
|
-
tkStmt.run(t.milestone_id, t.slice_id, t.id, t.title, t.status, t.one_liner, t.narrative, t.verification_result, t.duration, t.completed_at, t.blocker_discovered ? 1 : 0, t.deviations, t.known_issues, JSON.stringify(t.key_files), JSON.stringify(t.key_decisions), t.full_summary_md, t.description, t.estimate, JSON.stringify(t.files), t.verify, JSON.stringify(t.inputs), JSON.stringify(t.expected_output), t.observability_impact, t.sequence, t.blocker_source ?? "", t.escalation_pending ?? 0, t.escalation_awaiting_review ?? 0, t.escalation_artifact_path ?? null, t.escalation_override_applied_at ?? null);
|
|
2327
|
+
tkStmt.run(t.milestone_id, t.slice_id, t.id, t.title, t.status, t.one_liner, t.narrative, t.verification_result, t.duration, t.completed_at, t.blocker_discovered ? 1 : 0, t.deviations, t.known_issues, JSON.stringify(t.key_files), JSON.stringify(t.key_decisions), t.full_summary_md, t.description, t.estimate, JSON.stringify(t.files), t.verify, JSON.stringify(t.inputs), JSON.stringify(t.expected_output), t.observability_impact, JSON.stringify(t.target_repositories ?? []), t.sequence, t.blocker_source ?? "", t.escalation_pending ?? 0, t.escalation_awaiting_review ?? 0, t.escalation_artifact_path ?? null, t.escalation_override_applied_at ?? null);
|
|
2285
2328
|
}
|
|
2286
2329
|
// Restore decisions (ADR-011 P2: include source so escalation decisions survive)
|
|
2287
2330
|
const dcStmt = db.prepare(`INSERT INTO decisions (seq, id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by)
|
|
@@ -18,6 +18,7 @@ import { nativeAddPaths, nativeCommit } from "./native-git-bridge.js";
|
|
|
18
18
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
19
19
|
import { saveQueueOrder } from "./queue-order.js";
|
|
20
20
|
import { findMilestoneIds, nextMilestoneId } from "./milestone-ids.js";
|
|
21
|
+
import { isFutureMilestoneStatus } from "./status-guards.js";
|
|
21
22
|
// ─── Queue Entry Point ──────────────────────────────────────────────────────
|
|
22
23
|
/**
|
|
23
24
|
* Queue future milestones via conversational intake.
|
|
@@ -48,7 +49,7 @@ export async function showQueue(ctx, pi, basePath) {
|
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
50
51
|
// ── Count pending milestones ────────────────────────────────────────
|
|
51
|
-
const pendingMilestones = state.registry.filter(m => m.status
|
|
52
|
+
const pendingMilestones = state.registry.filter(m => isFutureMilestoneStatus(m.status) || m.status === "active");
|
|
52
53
|
const completeCount = state.registry.filter(m => m.status === "complete").length;
|
|
53
54
|
const parkedCount = state.registry.filter(m => m.status === "parked").length;
|
|
54
55
|
// ── If multiple pending milestones, show queue management hub ──────
|
|
@@ -140,7 +141,7 @@ export async function showQueueAdd(ctx, pi, basePath, state) {
|
|
|
140
141
|
const activePart = state.activeMilestone
|
|
141
142
|
? `Currently executing: ${state.activeMilestone.id} — ${state.activeMilestone.title} (phase: ${state.phase}).`
|
|
142
143
|
: "No milestone currently active.";
|
|
143
|
-
const pendingCount = state.registry.filter(m => m.status
|
|
144
|
+
const pendingCount = state.registry.filter(m => isFutureMilestoneStatus(m.status)).length;
|
|
144
145
|
const completeCount = state.registry.filter(m => m.status === "complete").length;
|
|
145
146
|
const preamble = [
|
|
146
147
|
`Queuing new work onto an existing GSD project.`,
|
|
@@ -223,7 +224,7 @@ export async function buildExistingMilestonesContext(basePath, milestoneIds, sta
|
|
|
223
224
|
}
|
|
224
225
|
// For active/pending/parked milestones, include the roadmap if it exists
|
|
225
226
|
// (shows what's planned but not yet built)
|
|
226
|
-
if (status === "active" || status
|
|
227
|
+
if (status === "active" || isFutureMilestoneStatus(status) || status === "parked") {
|
|
227
228
|
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
228
229
|
if (roadmapFile) {
|
|
229
230
|
const content = await loadFile(roadmapFile);
|