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
|
@@ -353,7 +353,13 @@ export async function handleReinit(ctx, detection) {
|
|
|
353
353
|
{
|
|
354
354
|
id: "prefs",
|
|
355
355
|
label: "Re-configure preferences",
|
|
356
|
-
description: "
|
|
356
|
+
description: "Run the preferences wizard without affecting milestones",
|
|
357
|
+
recommended: true,
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
id: "skills",
|
|
361
|
+
label: "Suggest & install skills",
|
|
362
|
+
description: "Detect project type and offer matching skill packs",
|
|
357
363
|
recommended: true,
|
|
358
364
|
},
|
|
359
365
|
{
|
|
@@ -365,7 +371,16 @@ export async function handleReinit(ctx, detection) {
|
|
|
365
371
|
notYetMessage: "Run /gsd init when ready.",
|
|
366
372
|
});
|
|
367
373
|
if (choice === "prefs") {
|
|
368
|
-
ctx
|
|
374
|
+
await handlePrefsWizard(ctx, "project");
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (choice === "skills") {
|
|
378
|
+
try {
|
|
379
|
+
await runSkillInstallStep(ctx, detection.projectSignals);
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
// Non-fatal — suggestion/install failures should not break re-init flow
|
|
383
|
+
}
|
|
369
384
|
}
|
|
370
385
|
}
|
|
371
386
|
// ─── Git Preferences Customization ──────────────────────────────────────────────
|
|
@@ -14,7 +14,7 @@ import { isClosedStatus } from "./status-guards.js";
|
|
|
14
14
|
import { join, relative } from "node:path";
|
|
15
15
|
import { createRequire } from "node:module";
|
|
16
16
|
import { getAllMilestones, getMilestone, getMilestoneSlices, getSliceTasks, getTask, getSlice, getArtifact, insertArtifact, getGateResults, } from "./gsd-db.js";
|
|
17
|
-
import { resolveMilestoneFile, resolveSliceFile, resolveSlicePath,
|
|
17
|
+
import { resolveMilestoneFile, resolveSliceFile, resolveSlicePath, gsdProjectionRoot, gsdRoot, buildTaskFileName, buildSliceFileName, } from "./paths.js";
|
|
18
18
|
import { saveFile, clearParseCache } from "./files.js";
|
|
19
19
|
import { invalidateStateCache } from "./state.js";
|
|
20
20
|
import { clearPathCache } from "./paths.js";
|
|
@@ -24,7 +24,11 @@ import { clearPathCache } from "./paths.js";
|
|
|
24
24
|
* E.g. "/project/.gsd/milestones/M001/M001-ROADMAP.md" → "milestones/M001/M001-ROADMAP.md"
|
|
25
25
|
*/
|
|
26
26
|
function toArtifactPath(absPath, basePath) {
|
|
27
|
-
const
|
|
27
|
+
const projectionRoot = gsdProjectionRoot(basePath);
|
|
28
|
+
const projectionRel = relative(projectionRoot, absPath);
|
|
29
|
+
const root = projectionRel && !projectionRel.startsWith("..") && !projectionRel.startsWith("/")
|
|
30
|
+
? projectionRoot
|
|
31
|
+
: gsdRoot(basePath);
|
|
28
32
|
const rel = relative(root, absPath);
|
|
29
33
|
// Normalize to forward slashes for consistent DB keys
|
|
30
34
|
return rel.replace(/\\/g, "/");
|
|
@@ -305,10 +309,9 @@ export async function renderPlanFromDb(basePath, milestoneId, sliceId) {
|
|
|
305
309
|
if (tasks.length === 0) {
|
|
306
310
|
throw new Error(`no tasks found for ${milestoneId}/${sliceId}`);
|
|
307
311
|
}
|
|
308
|
-
const slicePath =
|
|
309
|
-
|
|
310
|
-
const absPath =
|
|
311
|
-
?? join(slicePath, `${sliceId}-PLAN.md`);
|
|
312
|
+
const slicePath = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId);
|
|
313
|
+
mkdirSync(slicePath, { recursive: true });
|
|
314
|
+
const absPath = join(slicePath, `${sliceId}-PLAN.md`);
|
|
312
315
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
313
316
|
const sliceGates = getGateResults(milestoneId, sliceId, "slice");
|
|
314
317
|
const content = renderSlicePlanMarkdown(slice, tasks, sliceGates);
|
|
@@ -329,8 +332,7 @@ export async function renderTaskPlanFromDb(basePath, milestoneId, sliceId, taskI
|
|
|
329
332
|
if (!task) {
|
|
330
333
|
throw new Error(`task ${milestoneId}/${sliceId}/${taskId} not found`);
|
|
331
334
|
}
|
|
332
|
-
const tasksDir =
|
|
333
|
-
?? join(gsdRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
|
|
335
|
+
const tasksDir = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
|
|
334
336
|
mkdirSync(tasksDir, { recursive: true });
|
|
335
337
|
const absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
|
|
336
338
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { resolveModelMcpConfig } from "./preferences-mcp.js";
|
|
4
|
+
export function discoverMcpServerNames(projectDir) {
|
|
5
|
+
const mcpJsonPath = resolve(projectDir, ".mcp.json");
|
|
6
|
+
const settingsPath = resolve(projectDir, ".claude", "settings.json");
|
|
7
|
+
let mcpJsonServers = [];
|
|
8
|
+
if (existsSync(mcpJsonPath)) {
|
|
9
|
+
const raw = readFileSync(mcpJsonPath, "utf-8");
|
|
10
|
+
const parsed = JSON.parse(raw);
|
|
11
|
+
mcpJsonServers = Object.keys(parsed.mcpServers ?? {});
|
|
12
|
+
}
|
|
13
|
+
let settingsServers = [];
|
|
14
|
+
if (existsSync(settingsPath)) {
|
|
15
|
+
try {
|
|
16
|
+
const raw = readFileSync(settingsPath, "utf-8");
|
|
17
|
+
const parsed = JSON.parse(raw);
|
|
18
|
+
if (parsed.mcpServers) {
|
|
19
|
+
settingsServers = Object.keys(parsed.mcpServers);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// settings.json parse errors are silently ignored
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return [...new Set([...mcpJsonServers, ...settingsServers])];
|
|
27
|
+
}
|
|
28
|
+
export function computeMcpDisallowedTools(modelId, mcpConfig, discoveredServers, workflowServerName) {
|
|
29
|
+
if (!mcpConfig)
|
|
30
|
+
return [];
|
|
31
|
+
const entry = resolveModelMcpConfig(modelId, mcpConfig);
|
|
32
|
+
if (!entry)
|
|
33
|
+
return [];
|
|
34
|
+
const allServers = [...discoveredServers, ...(workflowServerName ? [workflowServerName] : [])];
|
|
35
|
+
const blocked = new Set();
|
|
36
|
+
// Allowlist phase: block every server NOT in the allowlist (except workflowServerName)
|
|
37
|
+
if (entry.allowed_servers !== undefined) {
|
|
38
|
+
const allowSet = new Set(entry.allowed_servers);
|
|
39
|
+
for (const server of allServers) {
|
|
40
|
+
if (server === workflowServerName)
|
|
41
|
+
continue;
|
|
42
|
+
if (!allowSet.has(server)) {
|
|
43
|
+
blocked.add(server);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Blocklist phase: explicitly blocked servers are added
|
|
48
|
+
if (entry.blocked_servers !== undefined) {
|
|
49
|
+
for (const server of entry.blocked_servers) {
|
|
50
|
+
blocked.add(server);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// gsd-workflow implicit allow: remove unless explicitly in blocked_servers
|
|
54
|
+
if (workflowServerName && !(entry.blocked_servers ?? []).includes(workflowServerName)) {
|
|
55
|
+
blocked.delete(workflowServerName);
|
|
56
|
+
}
|
|
57
|
+
return [...blocked].map((name) => `mcp__${name}__*`);
|
|
58
|
+
}
|
|
@@ -71,6 +71,16 @@ function parsePhaseEntry(line) {
|
|
|
71
71
|
raw: line,
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
+
// Format 3: - ✅ v1.0 MVP — Phases 1-6
|
|
75
|
+
const fmtVersionPhases = stripped.match(/^-\s+([✅🚧])\s+v\d+(?:\.\d+)*\s+(.+?)\s*[—–]\s*Phases?\s+(\d+(?:\.\d+)?)(?:\s*-\s*\d+(?:\.\d+)?)?(?:\s+\(.*\))?\s*$/iu);
|
|
76
|
+
if (fmtVersionPhases) {
|
|
77
|
+
return {
|
|
78
|
+
number: parseFloat(fmtVersionPhases[3]),
|
|
79
|
+
title: fmtVersionPhases[2].trim(),
|
|
80
|
+
done: fmtVersionPhases[1] === '✅',
|
|
81
|
+
raw: line,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
74
84
|
return null;
|
|
75
85
|
}
|
|
76
86
|
/**
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
|
|
3
|
-
import {
|
|
4
|
-
import { migrateHierarchyToDb } from "./md-importer.js";
|
|
3
|
+
import { getAllMilestones, getMilestoneSlices, getSliceTasks, isDbAvailable, } from "./gsd-db.js";
|
|
5
4
|
import { parsePlan, parseRoadmap } from "./parsers-legacy.js";
|
|
6
5
|
import { milestonesDir, resolveMilestoneFile, resolveSliceFile, } from "./paths.js";
|
|
7
|
-
import { invalidateStateCache } from "./state.js";
|
|
8
6
|
function zeroCounts() {
|
|
9
7
|
return { milestones: 0, slices: 0, tasks: 0 };
|
|
10
8
|
}
|
|
@@ -50,7 +48,7 @@ export function countDbHierarchy() {
|
|
|
50
48
|
}
|
|
51
49
|
return counts;
|
|
52
50
|
}
|
|
53
|
-
export async function
|
|
51
|
+
export async function checkMarkdownHierarchyAgainstDb(basePath) {
|
|
54
52
|
const markdown = countMarkdownHierarchy(basePath);
|
|
55
53
|
if (sameCounts(markdown, zeroCounts())) {
|
|
56
54
|
return {
|
|
@@ -70,18 +68,15 @@ export async function autoImportMarkdownHierarchyIfDbMismatch(basePath) {
|
|
|
70
68
|
return { action: "none", reason: "in-sync", markdown, beforeDb, afterDb: beforeDb };
|
|
71
69
|
}
|
|
72
70
|
const reason = sameCounts(beforeDb, zeroCounts()) ? "db-empty" : "count-mismatch";
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
return {
|
|
72
|
+
action: "recovery-required",
|
|
73
|
+
reason,
|
|
74
|
+
markdown,
|
|
75
|
+
beforeDb,
|
|
76
|
+
afterDb: beforeDb,
|
|
77
|
+
recoveryCommand: "gsd recover",
|
|
78
|
+
message: `Markdown planning artifacts (${markdown.milestones}M/${markdown.slices}S/${markdown.tasks}T) ` +
|
|
79
|
+
`do not match the authoritative DB (${beforeDb.milestones}M/${beforeDb.slices}S/${beforeDb.tasks}T). ` +
|
|
80
|
+
"Runtime startup will not import markdown automatically; run explicit GSD recovery if markdown should repopulate the database.",
|
|
82
81
|
};
|
|
83
|
-
if (!sameCounts(markdown, afterDb)) {
|
|
84
|
-
throw new Error(`migration auto-import verification failed: markdown ${markdown.milestones}M/${markdown.slices}S/${markdown.tasks}T, db ${afterDb.milestones}M/${afterDb.slices}S/${afterDb.tasks}T`);
|
|
85
|
-
}
|
|
86
|
-
return { action: "imported", reason, markdown, beforeDb, afterDb };
|
|
87
82
|
}
|
|
@@ -19,6 +19,7 @@ import { deleteMilestone, getMilestone, isDbAvailable, updateMilestoneStatus } f
|
|
|
19
19
|
import { removeWorktree } from "./worktree-manager.js";
|
|
20
20
|
import { logWarning } from "./workflow-logger.js";
|
|
21
21
|
import { isAutoActive } from "./auto.js";
|
|
22
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
22
23
|
/**
|
|
23
24
|
* Writer-side assert for mutations that race with auto-mode's squash merge (#4704).
|
|
24
25
|
* Auto-mode is confirmed not to call parkMilestone/discardMilestone/unparkMilestone
|
|
@@ -34,7 +35,7 @@ function assertNotAutoActive(action) {
|
|
|
34
35
|
/**
|
|
35
36
|
* Park a milestone — creates a PARKED.md marker file with reason and timestamp.
|
|
36
37
|
* Parked milestones are skipped during active-milestone discovery but stay on disk.
|
|
37
|
-
* Returns true if successfully parked, false if milestone not found
|
|
38
|
+
* Returns true if successfully parked, false if milestone not found, already parked, or complete.
|
|
38
39
|
*/
|
|
39
40
|
export function parkMilestone(basePath, milestoneId, reason) {
|
|
40
41
|
assertNotAutoActive("park milestone");
|
|
@@ -42,9 +43,15 @@ export function parkMilestone(basePath, milestoneId, reason) {
|
|
|
42
43
|
if (!mDir || !existsSync(mDir))
|
|
43
44
|
return false;
|
|
44
45
|
// Guard: do not park a completed milestone — it would corrupt depends_on satisfaction
|
|
45
|
-
const
|
|
46
|
-
|
|
46
|
+
const dbAvailable = isDbAvailable();
|
|
47
|
+
const milestone = dbAvailable ? getMilestone(milestoneId) : null;
|
|
48
|
+
if (milestone && isClosedStatus(milestone.status))
|
|
47
49
|
return false;
|
|
50
|
+
if (!dbAvailable) {
|
|
51
|
+
const summaryFile = resolveMilestoneFile(basePath, milestoneId, "SUMMARY");
|
|
52
|
+
if (summaryFile)
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
48
55
|
const parkedPath = join(mDir, buildMilestoneFileName(milestoneId, "PARKED"));
|
|
49
56
|
if (existsSync(parkedPath))
|
|
50
57
|
return false; // already parked
|
|
@@ -61,7 +68,7 @@ export function parkMilestone(basePath, milestoneId, reason) {
|
|
|
61
68
|
].join("\n");
|
|
62
69
|
writeFileSync(parkedPath, content, "utf-8");
|
|
63
70
|
// Sync DB status so deriveStateFromDb also skips this milestone (#2694)
|
|
64
|
-
if (
|
|
71
|
+
if (dbAvailable) {
|
|
65
72
|
try {
|
|
66
73
|
updateMilestoneStatus(milestoneId, "parked");
|
|
67
74
|
}
|
|
@@ -14,6 +14,8 @@ import { isInfrastructureError } from "./auto/infra-errors.js";
|
|
|
14
14
|
// Issue #453: keep auto-mode bookkeeping on the stable git CLI path unless a
|
|
15
15
|
// caller explicitly opts into the native helper.
|
|
16
16
|
const NATIVE_GSD_GIT_ENABLED = process.env.GSD_ENABLE_NATIVE_GSD_GIT === "1";
|
|
17
|
+
const TRANSIENT_GIT_RETRY_CODES = new Set(["ENOBUFS", "EAGAIN"]);
|
|
18
|
+
const GIT_RETRY_DELAY_MS = 200;
|
|
17
19
|
// ─── Native Module Loading ──────────────────────────────────────────────────
|
|
18
20
|
let nativeModule = null;
|
|
19
21
|
let loadAttempted = false;
|
|
@@ -46,10 +48,42 @@ function gitExec(basePath, args, allowFailure = false) {
|
|
|
46
48
|
env: GIT_NO_PROMPT_ENV,
|
|
47
49
|
}).trim();
|
|
48
50
|
}
|
|
49
|
-
catch {
|
|
51
|
+
catch (err) {
|
|
50
52
|
if (allowFailure)
|
|
51
53
|
return "";
|
|
52
|
-
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}`);
|
|
54
|
+
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}: ${getErrorMessage(err)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** sleepSync uses Atomics.wait for a blocking pause without busy-waiting; it blocks the current thread and requires Atomics.wait support. */
|
|
58
|
+
function sleepSync(ms) {
|
|
59
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
60
|
+
}
|
|
61
|
+
function isRetryableGitError(err) {
|
|
62
|
+
const code = isInfrastructureError(err)
|
|
63
|
+
?? isInfrastructureError(err?.stderr ?? "");
|
|
64
|
+
return code !== null && TRANSIENT_GIT_RETRY_CODES.has(code);
|
|
65
|
+
}
|
|
66
|
+
function execGitFileSyncWithRetry(basePath, args, options) {
|
|
67
|
+
try {
|
|
68
|
+
return execFileSync("git", args, {
|
|
69
|
+
cwd: basePath,
|
|
70
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
71
|
+
encoding: "utf-8",
|
|
72
|
+
env: GIT_NO_PROMPT_ENV,
|
|
73
|
+
...options,
|
|
74
|
+
}).trim();
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
if (!isRetryableGitError(err))
|
|
78
|
+
throw err;
|
|
79
|
+
sleepSync(GIT_RETRY_DELAY_MS);
|
|
80
|
+
return execFileSync("git", args, {
|
|
81
|
+
cwd: basePath,
|
|
82
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
83
|
+
encoding: "utf-8",
|
|
84
|
+
env: GIT_NO_PROMPT_ENV,
|
|
85
|
+
...options,
|
|
86
|
+
}).trim();
|
|
53
87
|
}
|
|
54
88
|
}
|
|
55
89
|
/** Run a git command via execFileSync. Returns trimmed stdout. */
|
|
@@ -62,10 +96,10 @@ function gitFileExec(basePath, args, allowFailure = false) {
|
|
|
62
96
|
env: GIT_NO_PROMPT_ENV,
|
|
63
97
|
}).trim();
|
|
64
98
|
}
|
|
65
|
-
catch {
|
|
99
|
+
catch (err) {
|
|
66
100
|
if (allowFailure)
|
|
67
101
|
return "";
|
|
68
|
-
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}`);
|
|
102
|
+
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}: ${getErrorMessage(err)}`);
|
|
69
103
|
}
|
|
70
104
|
}
|
|
71
105
|
// ─── Existing Read Functions ──────────────────────────────────────────────
|
|
@@ -303,15 +337,20 @@ export function nativeDiffNameStatus(basePath, fromRef, toRef, pathspec, useMerg
|
|
|
303
337
|
}
|
|
304
338
|
/**
|
|
305
339
|
* Get numstat diff between two refs.
|
|
340
|
+
* useMergeBase: if true, uses three-dot semantics.
|
|
306
341
|
* Native: libgit2 patch line stats.
|
|
307
342
|
* Fallback: `git diff --numstat`.
|
|
308
343
|
*/
|
|
309
|
-
export function nativeDiffNumstat(basePath, fromRef, toRef) {
|
|
344
|
+
export function nativeDiffNumstat(basePath, fromRef, toRef, useMergeBase) {
|
|
310
345
|
const native = loadNative();
|
|
311
|
-
if (native) {
|
|
346
|
+
if (native && !useMergeBase) {
|
|
312
347
|
return native.gitDiffNumstat(basePath, fromRef, toRef);
|
|
313
348
|
}
|
|
314
|
-
const
|
|
349
|
+
const refspec = useMergeBase ? `${fromRef}...${toRef}` : undefined;
|
|
350
|
+
const args = refspec
|
|
351
|
+
? ["diff", "--numstat", refspec]
|
|
352
|
+
: ["diff", "--numstat", fromRef, toRef];
|
|
353
|
+
const result = gitExec(basePath, args, true);
|
|
315
354
|
if (!result)
|
|
316
355
|
return [];
|
|
317
356
|
return result.split("\n").filter(Boolean).map(line => {
|
|
@@ -409,7 +448,10 @@ export function nativeBranchList(basePath, pattern) {
|
|
|
409
448
|
const result = gitFileExec(basePath, args, true);
|
|
410
449
|
if (!result)
|
|
411
450
|
return [];
|
|
412
|
-
return result
|
|
451
|
+
return result
|
|
452
|
+
.split("\n")
|
|
453
|
+
.map(b => b.trim().replace(/^[*+]\s+/, ""))
|
|
454
|
+
.filter(Boolean);
|
|
413
455
|
}
|
|
414
456
|
/**
|
|
415
457
|
* List branches merged into target.
|
|
@@ -777,13 +819,10 @@ export function nativeCommit(basePath, message, options) {
|
|
|
777
819
|
const args = ["commit", "-F", "-"];
|
|
778
820
|
if (options?.allowEmpty)
|
|
779
821
|
args.push("--allow-empty");
|
|
780
|
-
const result =
|
|
781
|
-
cwd: basePath,
|
|
822
|
+
const result = execGitFileSyncWithRetry(basePath, args, {
|
|
782
823
|
stdio: ["pipe", "pipe", "pipe"],
|
|
783
|
-
encoding: "utf-8",
|
|
784
|
-
env: GIT_NO_PROMPT_ENV,
|
|
785
824
|
input: message,
|
|
786
|
-
})
|
|
825
|
+
});
|
|
787
826
|
return result;
|
|
788
827
|
}
|
|
789
828
|
catch (err) {
|
|
@@ -792,7 +831,11 @@ export function nativeCommit(basePath, message, options) {
|
|
|
792
831
|
if (combined.includes("nothing to commit") || combined.includes("nothing added to commit") || combined.includes("no changes added")) {
|
|
793
832
|
return null;
|
|
794
833
|
}
|
|
795
|
-
|
|
834
|
+
const commitDetail = errObj.stderr?.trim() || errObj.message || "git commit failed";
|
|
835
|
+
const wrapped = new Error(`git commit failed: ${commitDetail}`);
|
|
836
|
+
wrapped.stdout = errObj.stdout;
|
|
837
|
+
wrapped.stderr = errObj.stderr;
|
|
838
|
+
throw wrapped;
|
|
796
839
|
}
|
|
797
840
|
}
|
|
798
841
|
/**
|
|
@@ -849,6 +849,9 @@ export function refreshWorkerStatuses(basePath, options = {}) {
|
|
|
849
849
|
for (const [mid, worker] of state.workers) {
|
|
850
850
|
const diskStatus = statusMap.get(mid);
|
|
851
851
|
if (!diskStatus) {
|
|
852
|
+
if (worker.state === "stopped" || worker.state === "error") {
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
852
855
|
if (!isPidAlive(worker.pid)) {
|
|
853
856
|
worker.cleanup?.();
|
|
854
857
|
worker.cleanup = undefined;
|
|
@@ -320,6 +320,10 @@ export function resolveGsdPathContract(workRoot, originalProjectRoot) {
|
|
|
320
320
|
isWorktree,
|
|
321
321
|
};
|
|
322
322
|
}
|
|
323
|
+
export function gsdProjectionRoot(basePath) {
|
|
324
|
+
const contract = resolveGsdPathContract(basePath);
|
|
325
|
+
return normalizeRealPath(contract.worktreeGsd ?? contract.projectGsd);
|
|
326
|
+
}
|
|
323
327
|
/**
|
|
324
328
|
* Invalidate the gsdRoot cache.
|
|
325
329
|
* Use ONLY at session-reset boundaries: workspace switch, process exit, or
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// GSD-2 — Pending auto-start handoff state.
|
|
2
|
+
// Stores discuss-to-auto handoff entries keyed by project root.
|
|
3
|
+
import { createWorkspace, scopeMilestone } from "./workspace.js";
|
|
4
|
+
const pendingAutoStartMap = new Map();
|
|
5
|
+
export function getPendingAutoStart(basePath) {
|
|
6
|
+
if (basePath)
|
|
7
|
+
return pendingAutoStartMap.get(basePath) ?? null;
|
|
8
|
+
if (pendingAutoStartMap.size === 1)
|
|
9
|
+
return pendingAutoStartMap.values().next().value;
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
export const _getPendingAutoStart = getPendingAutoStart;
|
|
13
|
+
export function hasPendingAutoStart(basePath) {
|
|
14
|
+
if (basePath)
|
|
15
|
+
return pendingAutoStartMap.has(basePath);
|
|
16
|
+
return pendingAutoStartMap.size > 0;
|
|
17
|
+
}
|
|
18
|
+
export function setPendingAutoStart(basePath, entry) {
|
|
19
|
+
if (!entry.ctx || !entry.pi) {
|
|
20
|
+
throw new Error("setPendingAutoStart requires ctx and pi");
|
|
21
|
+
}
|
|
22
|
+
const ws = createWorkspace(entry.basePath);
|
|
23
|
+
const scope = scopeMilestone(ws, entry.milestoneId);
|
|
24
|
+
pendingAutoStartMap.set(basePath, {
|
|
25
|
+
createdAt: Date.now(),
|
|
26
|
+
planBlockedRecoveryCount: 0,
|
|
27
|
+
...entry,
|
|
28
|
+
scope,
|
|
29
|
+
ctx: entry.ctx,
|
|
30
|
+
pi: entry.pi,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export function deletePendingAutoStart(basePath) {
|
|
34
|
+
pendingAutoStartMap.delete(basePath);
|
|
35
|
+
}
|
|
36
|
+
export function clearPendingAutoStart(basePath) {
|
|
37
|
+
if (basePath) {
|
|
38
|
+
pendingAutoStartMap.delete(basePath);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
pendingAutoStartMap.clear();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function getDiscussionMilestoneId(basePath) {
|
|
45
|
+
if (basePath) {
|
|
46
|
+
return pendingAutoStartMap.get(basePath)?.milestoneId ?? null;
|
|
47
|
+
}
|
|
48
|
+
if (pendingAutoStartMap.size === 1) {
|
|
49
|
+
return pendingAutoStartMap.values().next().value.milestoneId;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
@@ -6,20 +6,26 @@ function isInsideBase(basePath, candidate) {
|
|
|
6
6
|
const rel = relative(base, abs);
|
|
7
7
|
return rel === "" || (!!rel && !rel.startsWith("..") && !isAbsolute(rel));
|
|
8
8
|
}
|
|
9
|
+
function isInsideAnyBase(bases, candidate) {
|
|
10
|
+
return bases.some((base) => isInsideBase(base, candidate));
|
|
11
|
+
}
|
|
9
12
|
/**
|
|
10
13
|
* Planning IO fields are execution contracts. Absolute paths are only safe when
|
|
11
14
|
* they stay inside the active working directory; in worktree mode, an absolute
|
|
12
15
|
* path to the original checkout makes executors edit the wrong tree.
|
|
13
16
|
*/
|
|
14
|
-
export function validatePlanningPathScope(basePath, fields) {
|
|
17
|
+
export function validatePlanningPathScope(basePath, fields, allowedAbsoluteRoots) {
|
|
18
|
+
const absoluteRoots = (allowedAbsoluteRoots && allowedAbsoluteRoots.length > 0)
|
|
19
|
+
? allowedAbsoluteRoots
|
|
20
|
+
: [basePath];
|
|
15
21
|
for (const { field, values } of fields) {
|
|
16
22
|
for (const raw of values) {
|
|
17
23
|
const candidate = normalizePlannedFileReference(raw);
|
|
18
24
|
if (!isAbsolute(candidate))
|
|
19
25
|
continue;
|
|
20
|
-
if (
|
|
26
|
+
if (isInsideAnyBase(absoluteRoots, candidate))
|
|
21
27
|
continue;
|
|
22
|
-
return `${field} contains absolute path outside
|
|
28
|
+
return `${field} contains absolute path outside allowed repository roots: ${candidate}. Use a path relative to one of: ${absoluteRoots.join(", ")}.`;
|
|
23
29
|
}
|
|
24
30
|
}
|
|
25
31
|
return null;
|
|
@@ -17,6 +17,43 @@
|
|
|
17
17
|
import { existsSync, readFileSync } from "node:fs";
|
|
18
18
|
import { resolve, dirname, extname } from "node:path";
|
|
19
19
|
// ─── Import Resolution Check ─────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Replace the contents of single- and double-quoted string literals on a single
|
|
22
|
+
* source line with spaces so import patterns do not match text inside strings.
|
|
23
|
+
* Template-literal spans are handled separately via the inTemplateLiteral flag.
|
|
24
|
+
*/
|
|
25
|
+
function stripStringLiterals(line) {
|
|
26
|
+
let result = "";
|
|
27
|
+
let i = 0;
|
|
28
|
+
while (i < line.length) {
|
|
29
|
+
const ch = line[i];
|
|
30
|
+
if (ch === '"' || ch === "'") {
|
|
31
|
+
result += ch;
|
|
32
|
+
i++;
|
|
33
|
+
while (i < line.length) {
|
|
34
|
+
const c = line[i];
|
|
35
|
+
if (c === "\\" && i + 1 < line.length) {
|
|
36
|
+
result += " ";
|
|
37
|
+
i += 2;
|
|
38
|
+
}
|
|
39
|
+
else if (c === ch) {
|
|
40
|
+
result += ch;
|
|
41
|
+
i++;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
result += " ";
|
|
46
|
+
i++;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
result += ch;
|
|
52
|
+
i++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
20
57
|
/**
|
|
21
58
|
* Extract relative import paths from TypeScript/JavaScript source code.
|
|
22
59
|
* Returns array of { importPath, lineNum } for relative imports.
|
|
@@ -30,11 +67,19 @@ export function extractRelativeImports(source) {
|
|
|
30
67
|
// import './path'
|
|
31
68
|
// require('./path')
|
|
32
69
|
// require("../path")
|
|
33
|
-
const importPattern = /(
|
|
70
|
+
const importPattern = /(?:^|[;{}]\s*)import\s+(?:.*?\s+from\s+)?(['"])(\.\.?\/[^'"]+)\1/g;
|
|
71
|
+
const requirePattern = /require\s*\(\s*(['"])(\.\.?\/[^'"]+)\1/g;
|
|
34
72
|
// Track if we're inside a block comment
|
|
35
73
|
let inBlockComment = false;
|
|
74
|
+
let inTemplateLiteral = false;
|
|
36
75
|
for (let i = 0; i < lines.length; i++) {
|
|
37
76
|
const line = lines[i];
|
|
77
|
+
if (inTemplateLiteral) {
|
|
78
|
+
if ((line.match(/(?<!\\)`/g) ?? []).length % 2 === 1) {
|
|
79
|
+
inTemplateLiteral = false;
|
|
80
|
+
}
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
38
83
|
// Handle block comment boundaries
|
|
39
84
|
if (inBlockComment) {
|
|
40
85
|
if (line.includes("*/")) {
|
|
@@ -61,9 +106,17 @@ export function extractRelativeImports(source) {
|
|
|
61
106
|
let match;
|
|
62
107
|
// Reset lastIndex for each line
|
|
63
108
|
importPattern.lastIndex = 0;
|
|
109
|
+
requirePattern.lastIndex = 0;
|
|
110
|
+
const strippedLine = stripStringLiterals(line);
|
|
64
111
|
while ((match = importPattern.exec(line)) !== null) {
|
|
112
|
+
const importOffset = match[0].indexOf("import");
|
|
113
|
+
const importStart = match.index + importOffset;
|
|
114
|
+
if (strippedLine.slice(importStart, importStart + "import".length) !==
|
|
115
|
+
"import") {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
65
118
|
// Check if this match is after a // comment marker on the same line
|
|
66
|
-
const beforeMatch =
|
|
119
|
+
const beforeMatch = strippedLine.substring(0, match.index);
|
|
67
120
|
if (beforeMatch.includes("//")) {
|
|
68
121
|
continue;
|
|
69
122
|
}
|
|
@@ -72,6 +125,24 @@ export function extractRelativeImports(source) {
|
|
|
72
125
|
lineNum: i + 1,
|
|
73
126
|
});
|
|
74
127
|
}
|
|
128
|
+
while ((match = requirePattern.exec(line)) !== null) {
|
|
129
|
+
if (strippedLine.slice(match.index, match.index + "require".length) !==
|
|
130
|
+
"require") {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// Check if this match is after a // comment marker on the same line
|
|
134
|
+
const beforeMatch = strippedLine.substring(0, match.index);
|
|
135
|
+
if (beforeMatch.includes("//")) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
imports.push({
|
|
139
|
+
importPath: match[2],
|
|
140
|
+
lineNum: i + 1,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
if ((strippedLine.match(/(?<!\\)`/g) ?? []).length % 2 === 1) {
|
|
144
|
+
inTemplateLiteral = true;
|
|
145
|
+
}
|
|
75
146
|
}
|
|
76
147
|
return imports;
|
|
77
148
|
}
|
|
@@ -109,13 +180,6 @@ export function resolveImportPath(importPath, sourceFile, basePath) {
|
|
|
109
180
|
".woff", ".woff2", ".ttf", ".otf", ".eot",
|
|
110
181
|
]);
|
|
111
182
|
const runtimeFallbackExtensions = new Set([".js", ".jsx", ".mjs", ".cjs"]);
|
|
112
|
-
const dottedStemFallbackExtensions = new Set([".server", ".client", ".webhook"]);
|
|
113
|
-
if (explicitExt !== "" &&
|
|
114
|
-
!runtimeFallbackExtensions.has(explicitExt) &&
|
|
115
|
-
!nonFallbackExtensions.has(explicitExt) &&
|
|
116
|
-
!dottedStemFallbackExtensions.has(explicitExt)) {
|
|
117
|
-
return { exists: false, resolvedPath: null };
|
|
118
|
-
}
|
|
119
183
|
if (nonFallbackExtensions.has(explicitExt) && !runtimeFallbackExtensions.has(explicitExt)) {
|
|
120
184
|
return { exists: false, resolvedPath: null };
|
|
121
185
|
}
|