gsd-pi 2.82.0-dev.2841a1e44 → 2.82.0-dev.3a3c6509d
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 +3 -3
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +7 -0
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +5 -5
- package/dist/resources/extensions/gsd/auto/orchestrator.js +11 -0
- package/dist/resources/extensions/gsd/auto/phases.js +81 -31
- 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 +71 -10
- package/dist/resources/extensions/gsd/auto-recovery.js +71 -14
- package/dist/resources/extensions/gsd/auto-start.js +87 -14
- package/dist/resources/extensions/gsd/auto-verification.js +17 -4
- package/dist/resources/extensions/gsd/auto-worktree.js +176 -10
- package/dist/resources/extensions/gsd/auto.js +37 -5
- 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 +4 -2
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +5 -2
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +14 -2
- package/dist/resources/extensions/gsd/commands/handlers/core.js +17 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
- 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/dispatch-guard.js +2 -2
- 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 +3 -3
- package/dist/resources/extensions/gsd/git-service.js +45 -3
- package/dist/resources/extensions/gsd/gsd-db.js +21 -6
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +101 -116
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/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 +48 -12
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
- package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
- package/dist/resources/extensions/gsd/state.js +1 -1
- package/dist/resources/extensions/gsd/status-guards.js +11 -0
- package/dist/resources/extensions/gsd/templates/plan.md +8 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +4 -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 +89 -14
- package/dist/resources/extensions/gsd/unit-context-manifest.js +7 -8
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +68 -7
- 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 +33 -8
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +2 -0
- package/dist/resources/extensions/visual-brief/prompts.js +29 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
- 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/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 +11 -11
- 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/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/app/layout-8c10ec293ae0f1d5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-6a95bc41e0f7ec89.js → webpack-9a4db269f9ed63ad.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +1 -1
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +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/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/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/interactive-mode-ordering.test.js +12 -0
- 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.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +19 -8
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +14 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +23 -8
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/src/resources/GSD-WORKFLOW.md +7 -0
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +9 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +14 -6
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +8 -5
- package/src/resources/extensions/gsd/auto/orchestrator.ts +11 -0
- package/src/resources/extensions/gsd/auto/phases.ts +90 -38
- 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 +78 -8
- package/src/resources/extensions/gsd/auto-recovery.ts +74 -11
- package/src/resources/extensions/gsd/auto-start.ts +94 -12
- package/src/resources/extensions/gsd/auto-verification.ts +22 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +193 -10
- package/src/resources/extensions/gsd/auto.ts +40 -5
- 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 +4 -2
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +3 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +17 -2
- package/src/resources/extensions/gsd/commands/handlers/core.ts +17 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
- 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/dispatch-guard.ts +2 -2
- 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 +3 -3
- package/src/resources/extensions/gsd/git-service.ts +51 -4
- package/src/resources/extensions/gsd/gsd-db.ts +21 -6
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +134 -133
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/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 +54 -12
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
- package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
- package/src/resources/extensions/gsd/state.ts +1 -1
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/templates/plan.md +8 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +4 -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 +56 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +80 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +35 -7
- 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 +12 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +91 -6
- 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/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
- 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/deep-project-auto-loop.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +112 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/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 +63 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.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 +225 -1
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +13 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +82 -7
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
- package/src/resources/extensions/gsd/tests/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/write-gate-planning-unit.test.ts +38 -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 +98 -12
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +12 -9
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +78 -6
- 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 +41 -8
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +2 -0
- package/src/resources/extensions/visual-brief/prompts.ts +37 -1
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +40 -0
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/css/0262768ec1b89d34.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/{Qgr2B_MRhPxC0z8fwv4vT → O6femb9LLl3nlgsDaYwS-}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qgr2B_MRhPxC0z8fwv4vT → O6femb9LLl3nlgsDaYwS-}/_ssgManifest.js +0 -0
|
@@ -7,6 +7,27 @@ export function isNonEmptyString(value: unknown): value is string {
|
|
|
7
7
|
return typeof value === "string" && value.trim().length > 0;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Characters that are used as delimiters in GSD state management documents
|
|
12
|
+
* and should not appear in milestone or slice titles.
|
|
13
|
+
*/
|
|
14
|
+
const TITLE_DELIMITER_RE = /[\u2014\u2013\/]/; // em dash, en dash, forward slash
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Check whether a milestone or slice title contains characters that conflict
|
|
18
|
+
* with GSD's state document delimiter conventions.
|
|
19
|
+
* Returns a human-readable description of the problem, or null if the title is safe.
|
|
20
|
+
*/
|
|
21
|
+
export function validateTitle(title: string): string | null {
|
|
22
|
+
if (TITLE_DELIMITER_RE.test(title)) {
|
|
23
|
+
const found: string[] = [];
|
|
24
|
+
if (/[\u2014\u2013]/.test(title)) found.push("em/en dash (\u2014 or \u2013)");
|
|
25
|
+
if (/\//.test(title)) found.push("forward slash (/)");
|
|
26
|
+
return `title contains ${found.join(" and ")}, which conflict with GSD state document delimiters`;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
10
31
|
/**
|
|
11
32
|
* Validate that `value` is an array of non-empty strings.
|
|
12
33
|
* Throws with a message referencing `field` on failure.
|
|
@@ -14,7 +35,8 @@ export function isNonEmptyString(value: unknown): value is string {
|
|
|
14
35
|
*/
|
|
15
36
|
export function validateStringArray(value: unknown, field: string): string[] {
|
|
16
37
|
if (!Array.isArray(value)) {
|
|
17
|
-
|
|
38
|
+
const received = value === null ? "null" : typeof value;
|
|
39
|
+
throw new Error(`${field} must be an array of strings, not ${received}`);
|
|
18
40
|
}
|
|
19
41
|
if (value.some((item) => !isNonEmptyString(item))) {
|
|
20
42
|
throw new Error(`${field} must contain only non-empty strings`);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// First non-empty source wins.
|
|
5
5
|
|
|
6
6
|
import { spawnSync, type SpawnSyncReturns } from "node:child_process";
|
|
7
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
7
|
+
import { existsSync, readFileSync, readdirSync, type Dirent } from "node:fs";
|
|
8
8
|
import { join, basename } from "node:path";
|
|
9
9
|
import type { AuditWarning, RuntimeError, VerificationCheck, VerificationResult } from "./types.js";
|
|
10
10
|
import { DEFAULT_COMMAND_TIMEOUT_MS } from "./constants.js";
|
|
@@ -44,7 +44,8 @@ const PACKAGE_SCRIPT_KEYS = ["typecheck", "lint", "test"] as const;
|
|
|
44
44
|
* 1. Explicit preference commands
|
|
45
45
|
* 2. Task plan verify field (split on &&)
|
|
46
46
|
* 3. package.json scripts (typecheck, lint, test)
|
|
47
|
-
* 4.
|
|
47
|
+
* 4. Python pytest project markers
|
|
48
|
+
* 5. None found
|
|
48
49
|
*/
|
|
49
50
|
export function discoverCommands(options: DiscoverCommandsOptions): DiscoveredCommands {
|
|
50
51
|
// 1. Preference commands
|
|
@@ -91,10 +92,67 @@ export function discoverCommands(options: DiscoverCommandsOptions): DiscoveredCo
|
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
const pythonCommand = discoverPythonPytestCommand(options.cwd);
|
|
96
|
+
if (pythonCommand) {
|
|
97
|
+
return { commands: [pythonCommand], source: "python-project" };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 5. Nothing found
|
|
95
101
|
return { commands: [], source: "none" };
|
|
96
102
|
}
|
|
97
103
|
|
|
104
|
+
function discoverPythonPytestCommand(cwd: string): string | null {
|
|
105
|
+
const hasPythonTestFiles = hasPythonTests(join(cwd, "tests"));
|
|
106
|
+
const hasPytestConfig = existsSync(join(cwd, "pytest.ini"));
|
|
107
|
+
const pyprojectPath = join(cwd, "pyproject.toml");
|
|
108
|
+
const hasPyproject = existsSync(pyprojectPath);
|
|
109
|
+
|
|
110
|
+
if (!hasPythonTestFiles && !hasPytestConfig && !hasPyproject) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (hasPytestConfig || hasPythonTestFiles) {
|
|
115
|
+
return "python3 -m pytest";
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
const pyproject = readFileSync(pyprojectPath, "utf-8");
|
|
120
|
+
if (
|
|
121
|
+
pyproject.includes("[tool.pytest]") ||
|
|
122
|
+
pyproject.includes("[tool.pytest.") ||
|
|
123
|
+
pyproject.includes("[pytest]") ||
|
|
124
|
+
pyproject.includes("[tool:pytest]")
|
|
125
|
+
) {
|
|
126
|
+
return "python3 -m pytest";
|
|
127
|
+
}
|
|
128
|
+
} catch {
|
|
129
|
+
// Ignore unreadable pyproject.toml and fall through.
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function hasPythonTests(dir: string): boolean {
|
|
136
|
+
let entries: Dirent[];
|
|
137
|
+
try {
|
|
138
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
139
|
+
} catch {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
for (const entry of entries) {
|
|
144
|
+
const path = join(dir, entry.name);
|
|
145
|
+
if (entry.isDirectory() && hasPythonTests(path)) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
if (entry.isFile() && /^test_.*\.py$|^.*_test\.py$/.test(entry.name)) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
|
|
98
156
|
// ─── Failure Context Formatting ──────────────────────────────────────────────
|
|
99
157
|
|
|
100
158
|
/** Maximum chars of stderr to include per failed check in failure context. */
|
|
@@ -144,7 +202,7 @@ export function formatFailureContext(result: VerificationResult): string {
|
|
|
144
202
|
// ─── Gate Execution ─────────────────────────────────────────────────────────
|
|
145
203
|
|
|
146
204
|
/** Characters that indicate shell injection when found in a command string. */
|
|
147
|
-
const SHELL_INJECTION_PATTERN = /[
|
|
205
|
+
const SHELL_INJECTION_PATTERN = /[;|`<>]|\$\(/;
|
|
148
206
|
|
|
149
207
|
/**
|
|
150
208
|
* Known executable first-tokens that are safe to run.
|
|
@@ -182,6 +240,7 @@ const KNOWN_COMMAND_PREFIXES = new Set([
|
|
|
182
240
|
* Heuristics (any true → prose-like):
|
|
183
241
|
* 1. First token starts with an uppercase letter and the string has 4+ words
|
|
184
242
|
* 2. String contains commas followed by spaces (prose clause structure)
|
|
243
|
+
* 3. First token has no ASCII letters or digits and the string has 4+ words
|
|
185
244
|
*/
|
|
186
245
|
export function isLikelyCommand(cmd: string): boolean {
|
|
187
246
|
const trimmed = cmd.trim();
|
|
@@ -208,6 +267,9 @@ export function isLikelyCommand(cmd: string): boolean {
|
|
|
208
267
|
// First token has uppercase letters and no path separators → prose
|
|
209
268
|
if (/[A-Z]/.test(firstToken) && !firstToken.includes("/")) return false;
|
|
210
269
|
|
|
270
|
+
// Non-ASCII prose with multiple words should not be executed as a command.
|
|
271
|
+
if (!/[A-Za-z0-9]/.test(firstToken) && tokens.length >= 4) return false;
|
|
272
|
+
|
|
211
273
|
return true;
|
|
212
274
|
}
|
|
213
275
|
|
|
@@ -215,9 +277,19 @@ export function isLikelyCommand(cmd: string): boolean {
|
|
|
215
277
|
* Validate a command string for obvious shell injection patterns.
|
|
216
278
|
* Returns the command unchanged if safe, or null if suspicious.
|
|
217
279
|
*/
|
|
280
|
+
export function validateVerificationCommand(cmd: string): { ok: true } | { ok: false; reason: string } {
|
|
281
|
+
if (SHELL_INJECTION_PATTERN.test(cmd)) {
|
|
282
|
+
return { ok: false, reason: "contains shell control syntax such as pipes, redirects, semicolons, backticks, or command substitution" };
|
|
283
|
+
}
|
|
284
|
+
if (!isLikelyCommand(cmd)) {
|
|
285
|
+
return { ok: false, reason: "does not look like a runnable command" };
|
|
286
|
+
}
|
|
287
|
+
return { ok: true };
|
|
288
|
+
}
|
|
289
|
+
|
|
218
290
|
function sanitizeCommand(cmd: string): string | null {
|
|
219
|
-
|
|
220
|
-
if (!
|
|
291
|
+
const validation = validateVerificationCommand(cmd);
|
|
292
|
+
if (!validation.ok) return null;
|
|
221
293
|
return cmd;
|
|
222
294
|
}
|
|
223
295
|
|
|
@@ -18,6 +18,7 @@ export interface WorkflowCapabilityOptions {
|
|
|
18
18
|
unitType?: string;
|
|
19
19
|
authMode?: "apiKey" | "oauth" | "externalCli" | "none";
|
|
20
20
|
baseUrl?: string;
|
|
21
|
+
activeTools?: string[];
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
const MCP_WORKFLOW_TOOL_SURFACE = new Set([
|
|
@@ -383,6 +384,15 @@ function hasAskUserQuestionsTool(activeTools: string[]): boolean {
|
|
|
383
384
|
});
|
|
384
385
|
}
|
|
385
386
|
|
|
387
|
+
function hasRequiredTool(requiredTool: string, activeTools: string[]): boolean {
|
|
388
|
+
return activeTools.some((toolName) => {
|
|
389
|
+
if (toolName === requiredTool) return true;
|
|
390
|
+
if (!toolName.startsWith("mcp__")) return false;
|
|
391
|
+
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
392
|
+
return toolSeparator >= 0 && toolName.slice(toolSeparator + 2) === requiredTool;
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
386
396
|
function workflowMcpStructuredQuestionsOptIn(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
387
397
|
const value = env.GSD_WORKFLOW_MCP_STRUCTURED_QUESTIONS;
|
|
388
398
|
return value === "1" || value === "true";
|
|
@@ -423,8 +433,15 @@ export function getWorkflowTransportSupportError(
|
|
|
423
433
|
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: the GSD workflow MCP server is not configured or discoverable. Detected Claude Code model but no workflow MCP. Please run /gsd mcp init . from your project root. You can also configure GSD_WORKFLOW_MCP_COMMAND, build packages/mcp-server/dist/cli.js, or install gsd-mcp-server on PATH.`;
|
|
424
434
|
}
|
|
425
435
|
|
|
426
|
-
const
|
|
436
|
+
const uniqueRequired = [...new Set(requiredTools)];
|
|
437
|
+
const missing = (options.activeTools && options.activeTools.length > 0)
|
|
438
|
+
? uniqueRequired.filter((tool) => !hasRequiredTool(tool, options.activeTools!))
|
|
439
|
+
: uniqueRequired.filter((tool) => !MCP_WORKFLOW_TOOL_SURFACE.has(tool));
|
|
427
440
|
if (missing.length === 0) return null;
|
|
428
441
|
|
|
442
|
+
if (options.activeTools && options.activeTools.length > 0) {
|
|
443
|
+
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the active runtime toolset currently exposes only ${options.activeTools.slice().sort().join(", ")}.`;
|
|
444
|
+
}
|
|
445
|
+
|
|
429
446
|
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the workflow MCP transport currently exposes only ${Array.from(MCP_WORKFLOW_TOOL_SURFACE).sort().join(", ")}.`;
|
|
430
447
|
}
|
|
@@ -195,11 +195,11 @@ export function renderSummaryContent(
|
|
|
195
195
|
|
|
196
196
|
// ── Frontmatter (YAML list format, matches parseSummary() expectations) ──
|
|
197
197
|
const keyFilesYaml = taskRow.key_files && taskRow.key_files.length > 0
|
|
198
|
-
? taskRow.key_files.map(f => ` - ${f}`).join("\n")
|
|
199
|
-
: "
|
|
198
|
+
? `\n${taskRow.key_files.map(f => ` - ${f}`).join("\n")}`
|
|
199
|
+
: " []";
|
|
200
200
|
const keyDecisionsYaml = taskRow.key_decisions && taskRow.key_decisions.length > 0
|
|
201
|
-
? taskRow.key_decisions.map(d => ` - ${d}`).join("\n")
|
|
202
|
-
: "
|
|
201
|
+
? `\n${taskRow.key_decisions.map(d => ` - ${d}`).join("\n")}`
|
|
202
|
+
: " []";
|
|
203
203
|
|
|
204
204
|
// Derive verification_result from evidence if available
|
|
205
205
|
const evidenceList = evidence ?? [];
|
|
@@ -230,10 +230,8 @@ export function renderSummaryContent(
|
|
|
230
230
|
id: ${taskRow.id}
|
|
231
231
|
parent: ${sliceId}
|
|
232
232
|
milestone: ${milestoneId}
|
|
233
|
-
key_files
|
|
234
|
-
|
|
235
|
-
key_decisions:
|
|
236
|
-
${keyDecisionsYaml}
|
|
233
|
+
key_files:${keyFilesYaml}
|
|
234
|
+
key_decisions:${keyDecisionsYaml}
|
|
237
235
|
duration: ${taskRow.duration || ""}
|
|
238
236
|
verification_result: ${verificationResult}
|
|
239
237
|
completed_at: ${taskRow.completed_at || ""}
|
|
@@ -23,6 +23,7 @@ import { join } from "node:path";
|
|
|
23
23
|
|
|
24
24
|
import type { AutoSession } from "./auto/session.js";
|
|
25
25
|
import { debugLog } from "./debug-logger.js";
|
|
26
|
+
import { logWarning } from "./workflow-logger.js";
|
|
26
27
|
import { emitJournalEvent } from "./journal.js";
|
|
27
28
|
import { emitWorktreeCreated, emitWorktreeMerged } from "./worktree-telemetry.js";
|
|
28
29
|
import {
|
|
@@ -76,6 +77,13 @@ import {
|
|
|
76
77
|
teardownAutoWorktree,
|
|
77
78
|
} from "./auto-worktree.js";
|
|
78
79
|
|
|
80
|
+
const recentWorktreeMergeFailures = new Map<string, number>();
|
|
81
|
+
const MERGE_FAILURE_DEDUPE_MS = 60_000;
|
|
82
|
+
|
|
83
|
+
export function resetRecentWorktreeMergeFailuresForTest(): void {
|
|
84
|
+
recentWorktreeMergeFailures.clear();
|
|
85
|
+
}
|
|
86
|
+
|
|
79
87
|
// ─── Types ───────────────────────────────────────────────────────────────
|
|
80
88
|
|
|
81
89
|
export interface NotifyCtx {
|
|
@@ -525,7 +533,7 @@ export function _enterMilestoneCore(
|
|
|
525
533
|
|
|
526
534
|
// Phase B: claim a milestone lease before any worktree mutation. Two
|
|
527
535
|
// workers cannot enter the same milestone concurrently. Best-effort:
|
|
528
|
-
//
|
|
536
|
+
// warn if no worker registered (single-worker fallback) or skip if DB
|
|
529
537
|
// unavailable; reuse existing lease if we already hold it on this
|
|
530
538
|
// milestone (re-entry within the same session).
|
|
531
539
|
if (s.workerId) {
|
|
@@ -618,6 +626,11 @@ export function _enterMilestoneCore(
|
|
|
618
626
|
});
|
|
619
627
|
}
|
|
620
628
|
}
|
|
629
|
+
} else {
|
|
630
|
+
logWarning(
|
|
631
|
+
"worktree",
|
|
632
|
+
`enterMilestone(${milestoneId}) ran before auto worker registration; milestone lease was not claimed.`,
|
|
633
|
+
);
|
|
621
634
|
}
|
|
622
635
|
|
|
623
636
|
// Resolve the project root for worktree operations via shared helper.
|
|
@@ -836,6 +849,32 @@ function rebuildGitService(
|
|
|
836
849
|
s.gitService = deps.gitServiceFactory(s.basePath);
|
|
837
850
|
}
|
|
838
851
|
|
|
852
|
+
function emitWorktreeMergeFailedOnce(
|
|
853
|
+
basePath: string,
|
|
854
|
+
milestoneId: string,
|
|
855
|
+
err: unknown,
|
|
856
|
+
): void {
|
|
857
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
858
|
+
const errorCategory = err instanceof Error ? err.name : "Error";
|
|
859
|
+
const now = Date.now();
|
|
860
|
+
const key = `${basePath}\0${milestoneId}\0${errorCategory}`;
|
|
861
|
+
const previous = recentWorktreeMergeFailures.get(key);
|
|
862
|
+
if (previous && now - previous < MERGE_FAILURE_DEDUPE_MS) return;
|
|
863
|
+
for (const [candidate, ts] of recentWorktreeMergeFailures) {
|
|
864
|
+
if (now - ts >= MERGE_FAILURE_DEDUPE_MS) {
|
|
865
|
+
recentWorktreeMergeFailures.delete(candidate);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
emitJournalEvent(basePath, {
|
|
869
|
+
ts: new Date().toISOString(),
|
|
870
|
+
flowId: randomUUID(),
|
|
871
|
+
seq: 0,
|
|
872
|
+
eventType: "worktree-merge-failed",
|
|
873
|
+
data: { milestoneId, error: msg },
|
|
874
|
+
});
|
|
875
|
+
recentWorktreeMergeFailures.set(key, now);
|
|
876
|
+
}
|
|
877
|
+
|
|
839
878
|
// ─── Session-less merge entry (ADR-016 phase 2 / A1) ─────────────────────
|
|
840
879
|
|
|
841
880
|
/**
|
|
@@ -985,13 +1024,7 @@ function _mergeWorktreeModeImpl(
|
|
|
985
1024
|
error: msg,
|
|
986
1025
|
fallback: "chdir-to-project-root",
|
|
987
1026
|
});
|
|
988
|
-
|
|
989
|
-
ts: new Date().toISOString(),
|
|
990
|
-
flowId: randomUUID(),
|
|
991
|
-
seq: 0,
|
|
992
|
-
eventType: "worktree-merge-failed",
|
|
993
|
-
data: { milestoneId, error: msg },
|
|
994
|
-
});
|
|
1027
|
+
emitWorktreeMergeFailedOnce(originalBasePath || worktreeBasePath, milestoneId, err);
|
|
995
1028
|
// Surface a clear, actionable error. Worktree and milestone branch
|
|
996
1029
|
// are intentionally preserved — nothing has been deleted. User can
|
|
997
1030
|
// retry /gsd dispatch complete-milestone or merge manually once the
|
|
@@ -618,7 +618,7 @@ export function removeWorktree(
|
|
|
618
618
|
try {
|
|
619
619
|
rmSync(nestedGitPath, { recursive: true, force: true });
|
|
620
620
|
logWarning("reconcile",
|
|
621
|
-
`Removed nested .git directory from scaffolded project to prevent data loss
|
|
621
|
+
`Removed nested .git directory from scaffolded project to prevent data loss`,
|
|
622
622
|
{ worktree: name, nestedRepo: nestedDir },
|
|
623
623
|
);
|
|
624
624
|
} catch {
|