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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// GSD-2 — Guided workflow Unit context.
|
|
2
|
+
// Tracks the guided Unit whose queued turn should use manifest Tool Contract policy.
|
|
3
|
+
|
|
4
|
+
export interface GuidedUnitContext {
|
|
5
|
+
basePath: string;
|
|
6
|
+
unitType: string;
|
|
7
|
+
startedAt: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const guidedUnitContextByBasePath = new Map<string, GuidedUnitContext>();
|
|
11
|
+
|
|
12
|
+
export function setGuidedUnitContext(basePath: string, unitType: string): GuidedUnitContext {
|
|
13
|
+
const context = { basePath, unitType, startedAt: Date.now() };
|
|
14
|
+
guidedUnitContextByBasePath.set(basePath, context);
|
|
15
|
+
return context;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getGuidedUnitContext(basePath?: string): GuidedUnitContext | null {
|
|
19
|
+
if (basePath) return guidedUnitContextByBasePath.get(basePath) ?? null;
|
|
20
|
+
if (guidedUnitContextByBasePath.size === 1) return guidedUnitContextByBasePath.values().next().value!;
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function clearGuidedUnitContext(basePath?: string): void {
|
|
25
|
+
if (basePath) {
|
|
26
|
+
guidedUnitContextByBasePath.delete(basePath);
|
|
27
|
+
} else {
|
|
28
|
+
guidedUnitContextByBasePath.clear();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -95,6 +95,17 @@ function parsePhaseEntry(line: string): PlanningRoadmapEntry | null {
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// Format 3: - ✅ v1.0 MVP — Phases 1-6
|
|
99
|
+
const fmtVersionPhases = stripped.match(/^-\s+([✅🚧])\s+v\d+(?:\.\d+)*\s+(.+?)\s*[—–]\s*Phases?\s+(\d+(?:\.\d+)?)(?:\s*-\s*\d+(?:\.\d+)?)?(?:\s+\(.*\))?\s*$/iu);
|
|
100
|
+
if (fmtVersionPhases) {
|
|
101
|
+
return {
|
|
102
|
+
number: parseFloat(fmtVersionPhases[3]),
|
|
103
|
+
title: fmtVersionPhases[2].trim(),
|
|
104
|
+
done: fmtVersionPhases[1] === '✅',
|
|
105
|
+
raw: line,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
98
109
|
return null;
|
|
99
110
|
}
|
|
100
111
|
|
|
@@ -2,21 +2,17 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
|
2
2
|
|
|
3
3
|
import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
|
|
4
4
|
import {
|
|
5
|
-
clearEngineHierarchy,
|
|
6
5
|
getAllMilestones,
|
|
7
6
|
getMilestoneSlices,
|
|
8
7
|
getSliceTasks,
|
|
9
8
|
isDbAvailable,
|
|
10
|
-
transaction,
|
|
11
9
|
} from "./gsd-db.js";
|
|
12
|
-
import { migrateHierarchyToDb } from "./md-importer.js";
|
|
13
10
|
import { parsePlan, parseRoadmap } from "./parsers-legacy.js";
|
|
14
11
|
import {
|
|
15
12
|
milestonesDir,
|
|
16
13
|
resolveMilestoneFile,
|
|
17
14
|
resolveSliceFile,
|
|
18
15
|
} from "./paths.js";
|
|
19
|
-
import { invalidateStateCache } from "./state.js";
|
|
20
16
|
|
|
21
17
|
export interface HierarchyCounts {
|
|
22
18
|
milestones: number;
|
|
@@ -25,11 +21,13 @@ export interface HierarchyCounts {
|
|
|
25
21
|
}
|
|
26
22
|
|
|
27
23
|
export interface MigrationAutoCheckResult {
|
|
28
|
-
action: "none" | "
|
|
24
|
+
action: "none" | "recovery-required";
|
|
29
25
|
reason: "no-markdown" | "in-sync" | "db-empty" | "count-mismatch";
|
|
30
26
|
markdown: HierarchyCounts;
|
|
31
27
|
beforeDb: HierarchyCounts;
|
|
32
28
|
afterDb: HierarchyCounts;
|
|
29
|
+
recoveryCommand?: string;
|
|
30
|
+
message?: string;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
function zeroCounts(): HierarchyCounts {
|
|
@@ -83,7 +81,7 @@ export function countDbHierarchy(): HierarchyCounts {
|
|
|
83
81
|
return counts;
|
|
84
82
|
}
|
|
85
83
|
|
|
86
|
-
export async function
|
|
84
|
+
export async function checkMarkdownHierarchyAgainstDb(
|
|
87
85
|
basePath: string,
|
|
88
86
|
): Promise<MigrationAutoCheckResult> {
|
|
89
87
|
const markdown = countMarkdownHierarchy(basePath);
|
|
@@ -108,22 +106,16 @@ export async function autoImportMarkdownHierarchyIfDbMismatch(
|
|
|
108
106
|
}
|
|
109
107
|
|
|
110
108
|
const reason = sameCounts(beforeDb, zeroCounts()) ? "db-empty" : "count-mismatch";
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
109
|
+
return {
|
|
110
|
+
action: "recovery-required",
|
|
111
|
+
reason,
|
|
112
|
+
markdown,
|
|
113
|
+
beforeDb,
|
|
114
|
+
afterDb: beforeDb,
|
|
115
|
+
recoveryCommand: "gsd recover",
|
|
116
|
+
message:
|
|
117
|
+
`Markdown planning artifacts (${markdown.milestones}M/${markdown.slices}S/${markdown.tasks}T) ` +
|
|
118
|
+
`do not match the authoritative DB (${beforeDb.milestones}M/${beforeDb.slices}S/${beforeDb.tasks}T). ` +
|
|
119
|
+
"Runtime startup will not import markdown automatically; run explicit GSD recovery if markdown should repopulate the database.",
|
|
121
120
|
};
|
|
122
|
-
if (!sameCounts(markdown, afterDb)) {
|
|
123
|
-
throw new Error(
|
|
124
|
-
`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`,
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return { action: "imported", reason, markdown, beforeDb, afterDb };
|
|
129
121
|
}
|
|
@@ -24,6 +24,7 @@ import { deleteMilestone, getMilestone, isDbAvailable, updateMilestoneStatus } f
|
|
|
24
24
|
import { removeWorktree } from "./worktree-manager.js";
|
|
25
25
|
import { logWarning } from "./workflow-logger.js";
|
|
26
26
|
import { isAutoActive } from "./auto.js";
|
|
27
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Writer-side assert for mutations that race with auto-mode's squash merge (#4704).
|
|
@@ -44,7 +45,7 @@ function assertNotAutoActive(action: string): void {
|
|
|
44
45
|
/**
|
|
45
46
|
* Park a milestone — creates a PARKED.md marker file with reason and timestamp.
|
|
46
47
|
* Parked milestones are skipped during active-milestone discovery but stay on disk.
|
|
47
|
-
* Returns true if successfully parked, false if milestone not found
|
|
48
|
+
* Returns true if successfully parked, false if milestone not found, already parked, or complete.
|
|
48
49
|
*/
|
|
49
50
|
export function parkMilestone(basePath: string, milestoneId: string, reason: string): boolean {
|
|
50
51
|
assertNotAutoActive("park milestone");
|
|
@@ -52,8 +53,13 @@ export function parkMilestone(basePath: string, milestoneId: string, reason: str
|
|
|
52
53
|
if (!mDir || !existsSync(mDir)) return false;
|
|
53
54
|
|
|
54
55
|
// Guard: do not park a completed milestone — it would corrupt depends_on satisfaction
|
|
55
|
-
const
|
|
56
|
-
|
|
56
|
+
const dbAvailable = isDbAvailable();
|
|
57
|
+
const milestone = dbAvailable ? getMilestone(milestoneId) : null;
|
|
58
|
+
if (milestone && isClosedStatus(milestone.status)) return false;
|
|
59
|
+
if (!dbAvailable) {
|
|
60
|
+
const summaryFile = resolveMilestoneFile(basePath, milestoneId, "SUMMARY");
|
|
61
|
+
if (summaryFile) return false;
|
|
62
|
+
}
|
|
57
63
|
|
|
58
64
|
const parkedPath = join(mDir, buildMilestoneFileName(milestoneId, "PARKED"));
|
|
59
65
|
if (existsSync(parkedPath)) return false; // already parked
|
|
@@ -72,7 +78,7 @@ export function parkMilestone(basePath: string, milestoneId: string, reason: str
|
|
|
72
78
|
|
|
73
79
|
writeFileSync(parkedPath, content, "utf-8");
|
|
74
80
|
// Sync DB status so deriveStateFromDb also skips this milestone (#2694)
|
|
75
|
-
if (
|
|
81
|
+
if (dbAvailable) {
|
|
76
82
|
try {
|
|
77
83
|
updateMilestoneStatus(milestoneId, "parked");
|
|
78
84
|
} catch (err) {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// execSync calls because git2 credential handling is too complex.
|
|
7
7
|
|
|
8
8
|
import { execSync, execFileSync } from "node:child_process";
|
|
9
|
+
import type { ExecFileSyncOptionsWithStringEncoding } from "node:child_process";
|
|
9
10
|
import { existsSync, readFileSync, unlinkSync, rmSync, writeFileSync } from "node:fs";
|
|
10
11
|
import { join } from "node:path";
|
|
11
12
|
import { GSDError, GSD_GIT_ERROR } from "./errors.js";
|
|
@@ -16,6 +17,8 @@ import { isInfrastructureError } from "./auto/infra-errors.js";
|
|
|
16
17
|
// Issue #453: keep auto-mode bookkeeping on the stable git CLI path unless a
|
|
17
18
|
// caller explicitly opts into the native helper.
|
|
18
19
|
const NATIVE_GSD_GIT_ENABLED = process.env.GSD_ENABLE_NATIVE_GSD_GIT === "1";
|
|
20
|
+
const TRANSIENT_GIT_RETRY_CODES = new Set(["ENOBUFS", "EAGAIN"]);
|
|
21
|
+
const GIT_RETRY_DELAY_MS = 200;
|
|
19
22
|
|
|
20
23
|
// ─── Native Module Types ──────────────────────────────────────────────────
|
|
21
24
|
|
|
@@ -144,9 +147,46 @@ function gitExec(basePath: string, args: string[], allowFailure = false): string
|
|
|
144
147
|
encoding: "utf-8",
|
|
145
148
|
env: GIT_NO_PROMPT_ENV,
|
|
146
149
|
}).trim();
|
|
147
|
-
} catch {
|
|
150
|
+
} catch (err) {
|
|
148
151
|
if (allowFailure) return "";
|
|
149
|
-
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}`);
|
|
152
|
+
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}: ${getErrorMessage(err)}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** sleepSync uses Atomics.wait for a blocking pause without busy-waiting; it blocks the current thread and requires Atomics.wait support. */
|
|
157
|
+
function sleepSync(ms: number): void {
|
|
158
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function isRetryableGitError(err: unknown): boolean {
|
|
162
|
+
const code = isInfrastructureError(err)
|
|
163
|
+
?? isInfrastructureError((err as { stderr?: string })?.stderr ?? "");
|
|
164
|
+
return code !== null && TRANSIENT_GIT_RETRY_CODES.has(code);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function execGitFileSyncWithRetry(
|
|
168
|
+
basePath: string,
|
|
169
|
+
args: string[],
|
|
170
|
+
options: Partial<ExecFileSyncOptionsWithStringEncoding>,
|
|
171
|
+
): string {
|
|
172
|
+
try {
|
|
173
|
+
return execFileSync("git", args, {
|
|
174
|
+
cwd: basePath,
|
|
175
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
176
|
+
encoding: "utf-8",
|
|
177
|
+
env: GIT_NO_PROMPT_ENV,
|
|
178
|
+
...options,
|
|
179
|
+
}).trim();
|
|
180
|
+
} catch (err) {
|
|
181
|
+
if (!isRetryableGitError(err)) throw err;
|
|
182
|
+
sleepSync(GIT_RETRY_DELAY_MS);
|
|
183
|
+
return execFileSync("git", args, {
|
|
184
|
+
cwd: basePath,
|
|
185
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
186
|
+
encoding: "utf-8",
|
|
187
|
+
env: GIT_NO_PROMPT_ENV,
|
|
188
|
+
...options,
|
|
189
|
+
}).trim();
|
|
150
190
|
}
|
|
151
191
|
}
|
|
152
192
|
|
|
@@ -159,9 +199,9 @@ function gitFileExec(basePath: string, args: string[], allowFailure = false): st
|
|
|
159
199
|
encoding: "utf-8",
|
|
160
200
|
env: GIT_NO_PROMPT_ENV,
|
|
161
201
|
}).trim();
|
|
162
|
-
} catch {
|
|
202
|
+
} catch (err) {
|
|
163
203
|
if (allowFailure) return "";
|
|
164
|
-
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}`);
|
|
204
|
+
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}: ${getErrorMessage(err)}`);
|
|
165
205
|
}
|
|
166
206
|
}
|
|
167
207
|
|
|
@@ -428,16 +468,21 @@ export function nativeDiffNameStatus(
|
|
|
428
468
|
|
|
429
469
|
/**
|
|
430
470
|
* Get numstat diff between two refs.
|
|
471
|
+
* useMergeBase: if true, uses three-dot semantics.
|
|
431
472
|
* Native: libgit2 patch line stats.
|
|
432
473
|
* Fallback: `git diff --numstat`.
|
|
433
474
|
*/
|
|
434
|
-
export function nativeDiffNumstat(basePath: string, fromRef: string, toRef: string): GitNumstat[] {
|
|
475
|
+
export function nativeDiffNumstat(basePath: string, fromRef: string, toRef: string, useMergeBase?: boolean): GitNumstat[] {
|
|
435
476
|
const native = loadNative();
|
|
436
|
-
if (native) {
|
|
477
|
+
if (native && !useMergeBase) {
|
|
437
478
|
return native.gitDiffNumstat(basePath, fromRef, toRef);
|
|
438
479
|
}
|
|
439
480
|
|
|
440
|
-
const
|
|
481
|
+
const refspec = useMergeBase ? `${fromRef}...${toRef}` : undefined;
|
|
482
|
+
const args = refspec
|
|
483
|
+
? ["diff", "--numstat", refspec]
|
|
484
|
+
: ["diff", "--numstat", fromRef, toRef];
|
|
485
|
+
const result = gitExec(basePath, args, true);
|
|
441
486
|
if (!result) return [];
|
|
442
487
|
|
|
443
488
|
return result.split("\n").filter(Boolean).map(line => {
|
|
@@ -935,13 +980,10 @@ export function nativeCommit(
|
|
|
935
980
|
try {
|
|
936
981
|
const args = ["commit", "-F", "-"];
|
|
937
982
|
if (options?.allowEmpty) args.push("--allow-empty");
|
|
938
|
-
const result =
|
|
939
|
-
cwd: basePath,
|
|
983
|
+
const result = execGitFileSyncWithRetry(basePath, args, {
|
|
940
984
|
stdio: ["pipe", "pipe", "pipe"],
|
|
941
|
-
encoding: "utf-8",
|
|
942
|
-
env: GIT_NO_PROMPT_ENV,
|
|
943
985
|
input: message,
|
|
944
|
-
})
|
|
986
|
+
});
|
|
945
987
|
return result;
|
|
946
988
|
} catch (err: unknown) {
|
|
947
989
|
const errObj = err as { stdout?: string; stderr?: string; message?: string };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// GSD-2 — Pending auto-start handoff state.
|
|
2
|
+
// Stores discuss-to-auto handoff entries keyed by project root.
|
|
3
|
+
|
|
4
|
+
import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
5
|
+
import { createWorkspace, scopeMilestone, type MilestoneScope } from "./workspace.js";
|
|
6
|
+
|
|
7
|
+
export interface PendingAutoStartEntry {
|
|
8
|
+
ctx: ExtensionCommandContext;
|
|
9
|
+
pi: ExtensionAPI;
|
|
10
|
+
basePath: string;
|
|
11
|
+
milestoneId: string;
|
|
12
|
+
step?: boolean;
|
|
13
|
+
createdAt: number;
|
|
14
|
+
readyRejectCount?: number;
|
|
15
|
+
scope: MilestoneScope;
|
|
16
|
+
planBlockedRecoveryCount: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PendingAutoStartInput {
|
|
20
|
+
basePath: string;
|
|
21
|
+
milestoneId: string;
|
|
22
|
+
ctx: ExtensionCommandContext;
|
|
23
|
+
pi: ExtensionAPI;
|
|
24
|
+
step?: boolean;
|
|
25
|
+
createdAt?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const pendingAutoStartMap = new Map<string, PendingAutoStartEntry>();
|
|
29
|
+
|
|
30
|
+
export function getPendingAutoStart(basePath?: string): PendingAutoStartEntry | null {
|
|
31
|
+
if (basePath) return pendingAutoStartMap.get(basePath) ?? null;
|
|
32
|
+
if (pendingAutoStartMap.size === 1) return pendingAutoStartMap.values().next().value!;
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const _getPendingAutoStart = getPendingAutoStart;
|
|
37
|
+
|
|
38
|
+
export function hasPendingAutoStart(basePath?: string): boolean {
|
|
39
|
+
if (basePath) return pendingAutoStartMap.has(basePath);
|
|
40
|
+
return pendingAutoStartMap.size > 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function setPendingAutoStart(basePath: string, entry: PendingAutoStartInput): void {
|
|
44
|
+
if (!entry.ctx || !entry.pi) {
|
|
45
|
+
throw new Error("setPendingAutoStart requires ctx and pi");
|
|
46
|
+
}
|
|
47
|
+
const ws = createWorkspace(entry.basePath);
|
|
48
|
+
const scope = scopeMilestone(ws, entry.milestoneId);
|
|
49
|
+
pendingAutoStartMap.set(basePath, {
|
|
50
|
+
createdAt: Date.now(),
|
|
51
|
+
planBlockedRecoveryCount: 0,
|
|
52
|
+
...entry,
|
|
53
|
+
scope,
|
|
54
|
+
ctx: entry.ctx,
|
|
55
|
+
pi: entry.pi,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function deletePendingAutoStart(basePath: string): void {
|
|
60
|
+
pendingAutoStartMap.delete(basePath);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function clearPendingAutoStart(basePath?: string): void {
|
|
64
|
+
if (basePath) {
|
|
65
|
+
pendingAutoStartMap.delete(basePath);
|
|
66
|
+
} else {
|
|
67
|
+
pendingAutoStartMap.clear();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function getDiscussionMilestoneId(basePath?: string): string | null {
|
|
72
|
+
if (basePath) {
|
|
73
|
+
return pendingAutoStartMap.get(basePath)?.milestoneId ?? null;
|
|
74
|
+
}
|
|
75
|
+
if (pendingAutoStartMap.size === 1) {
|
|
76
|
+
return pendingAutoStartMap.values().next().value!.milestoneId;
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
@@ -46,6 +46,46 @@ export interface PostExecutionResult {
|
|
|
46
46
|
|
|
47
47
|
// ─── Import Resolution Check ─────────────────────────────────────────────────
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Replace the contents of single- and double-quoted string literals on a single
|
|
51
|
+
* source line with spaces so import patterns do not match text inside strings.
|
|
52
|
+
* Template-literal spans are handled separately via the inTemplateLiteral flag.
|
|
53
|
+
*/
|
|
54
|
+
function stripStringLiterals(line: string): string {
|
|
55
|
+
let result = "";
|
|
56
|
+
let i = 0;
|
|
57
|
+
|
|
58
|
+
while (i < line.length) {
|
|
59
|
+
const ch = line[i];
|
|
60
|
+
|
|
61
|
+
if (ch === '"' || ch === "'") {
|
|
62
|
+
result += ch;
|
|
63
|
+
i++;
|
|
64
|
+
|
|
65
|
+
while (i < line.length) {
|
|
66
|
+
const c = line[i];
|
|
67
|
+
|
|
68
|
+
if (c === "\\" && i + 1 < line.length) {
|
|
69
|
+
result += " ";
|
|
70
|
+
i += 2;
|
|
71
|
+
} else if (c === ch) {
|
|
72
|
+
result += ch;
|
|
73
|
+
i++;
|
|
74
|
+
break;
|
|
75
|
+
} else {
|
|
76
|
+
result += " ";
|
|
77
|
+
i++;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
result += ch;
|
|
82
|
+
i++;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
49
89
|
/**
|
|
50
90
|
* Extract relative import paths from TypeScript/JavaScript source code.
|
|
51
91
|
* Returns array of { importPath, lineNum } for relative imports.
|
|
@@ -62,14 +102,23 @@ export function extractRelativeImports(
|
|
|
62
102
|
// import './path'
|
|
63
103
|
// require('./path')
|
|
64
104
|
// require("../path")
|
|
65
|
-
const importPattern = /(
|
|
105
|
+
const importPattern = /(?:^|[;{}]\s*)import\s+(?:.*?\s+from\s+)?(['"])(\.\.?\/[^'"]+)\1/g;
|
|
106
|
+
const requirePattern = /require\s*\(\s*(['"])(\.\.?\/[^'"]+)\1/g;
|
|
66
107
|
|
|
67
108
|
// Track if we're inside a block comment
|
|
68
109
|
let inBlockComment = false;
|
|
110
|
+
let inTemplateLiteral = false;
|
|
69
111
|
|
|
70
112
|
for (let i = 0; i < lines.length; i++) {
|
|
71
113
|
const line = lines[i];
|
|
72
114
|
|
|
115
|
+
if (inTemplateLiteral) {
|
|
116
|
+
if ((line.match(/(?<!\\)`/g) ?? []).length % 2 === 1) {
|
|
117
|
+
inTemplateLiteral = false;
|
|
118
|
+
}
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
73
122
|
// Handle block comment boundaries
|
|
74
123
|
if (inBlockComment) {
|
|
75
124
|
if (line.includes("*/")) {
|
|
@@ -101,10 +150,22 @@ export function extractRelativeImports(
|
|
|
101
150
|
|
|
102
151
|
// Reset lastIndex for each line
|
|
103
152
|
importPattern.lastIndex = 0;
|
|
153
|
+
requirePattern.lastIndex = 0;
|
|
154
|
+
|
|
155
|
+
const strippedLine = stripStringLiterals(line);
|
|
104
156
|
|
|
105
157
|
while ((match = importPattern.exec(line)) !== null) {
|
|
158
|
+
const importOffset = match[0].indexOf("import");
|
|
159
|
+
const importStart = match.index + importOffset;
|
|
160
|
+
if (
|
|
161
|
+
strippedLine.slice(importStart, importStart + "import".length) !==
|
|
162
|
+
"import"
|
|
163
|
+
) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
|
|
106
167
|
// Check if this match is after a // comment marker on the same line
|
|
107
|
-
const beforeMatch =
|
|
168
|
+
const beforeMatch = strippedLine.substring(0, match.index);
|
|
108
169
|
if (beforeMatch.includes("//")) {
|
|
109
170
|
continue;
|
|
110
171
|
}
|
|
@@ -114,6 +175,30 @@ export function extractRelativeImports(
|
|
|
114
175
|
lineNum: i + 1,
|
|
115
176
|
});
|
|
116
177
|
}
|
|
178
|
+
|
|
179
|
+
while ((match = requirePattern.exec(line)) !== null) {
|
|
180
|
+
if (
|
|
181
|
+
strippedLine.slice(match.index, match.index + "require".length) !==
|
|
182
|
+
"require"
|
|
183
|
+
) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Check if this match is after a // comment marker on the same line
|
|
188
|
+
const beforeMatch = strippedLine.substring(0, match.index);
|
|
189
|
+
if (beforeMatch.includes("//")) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
imports.push({
|
|
194
|
+
importPath: match[2],
|
|
195
|
+
lineNum: i + 1,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if ((strippedLine.match(/(?<!\\)`/g) ?? []).length % 2 === 1) {
|
|
200
|
+
inTemplateLiteral = true;
|
|
201
|
+
}
|
|
117
202
|
}
|
|
118
203
|
|
|
119
204
|
return imports;
|
|
@@ -23,6 +23,7 @@ import { homedir } from "node:os";
|
|
|
23
23
|
import { resolve } from "node:path";
|
|
24
24
|
import type { TaskRow } from "./db-task-slice-rows.js";
|
|
25
25
|
import type { PreExecutionCheckJSON } from "./verification-evidence.ts";
|
|
26
|
+
import { validateVerificationCommand } from "./verification-gate.js";
|
|
26
27
|
|
|
27
28
|
const NPM_COMMAND = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
28
29
|
|
|
@@ -37,6 +38,35 @@ export interface PreExecutionResult {
|
|
|
37
38
|
durationMs: number;
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
export function checkVerificationCommands(tasks: TaskRow[]): PreExecutionCheckJSON[] {
|
|
42
|
+
const results: PreExecutionCheckJSON[] = [];
|
|
43
|
+
|
|
44
|
+
for (const task of tasks) {
|
|
45
|
+
const verify = task.verify.trim();
|
|
46
|
+
if (!verify) continue;
|
|
47
|
+
|
|
48
|
+
const commands = verify
|
|
49
|
+
.split("&&")
|
|
50
|
+
.map((command) => command.trim())
|
|
51
|
+
.filter(Boolean);
|
|
52
|
+
|
|
53
|
+
for (const command of commands) {
|
|
54
|
+
const validation = validateVerificationCommand(command);
|
|
55
|
+
if (!validation.ok) {
|
|
56
|
+
results.push({
|
|
57
|
+
category: "tool",
|
|
58
|
+
target: `${task.id} Verify`,
|
|
59
|
+
passed: false,
|
|
60
|
+
message: `Unsafe or non-runnable Verify command: ${command} (${validation.reason})`,
|
|
61
|
+
blocking: true,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return results;
|
|
68
|
+
}
|
|
69
|
+
|
|
40
70
|
// ─── Package Existence Check ─────────────────────────────────────────────────
|
|
41
71
|
|
|
42
72
|
/**
|
|
@@ -757,8 +787,9 @@ export async function runPreExecutionChecks(
|
|
|
757
787
|
const fileChecks = checkFilePathConsistency(tasks, basePath);
|
|
758
788
|
const orderingChecks = checkTaskOrdering(tasks, basePath);
|
|
759
789
|
const contractChecks = checkInterfaceContracts(tasks, basePath);
|
|
790
|
+
const verificationChecks = checkVerificationCommands(tasks);
|
|
760
791
|
|
|
761
|
-
allChecks.push(...fileChecks, ...orderingChecks, ...contractChecks);
|
|
792
|
+
allChecks.push(...fileChecks, ...orderingChecks, ...contractChecks, ...verificationChecks);
|
|
762
793
|
|
|
763
794
|
// Run async package checks
|
|
764
795
|
const packageChecks = await checkPackageExistence(tasks, basePath);
|
|
@@ -200,7 +200,7 @@ export function loadPrompt(name: string, vars: Record<string, string> = {}): str
|
|
|
200
200
|
if (missing.length > 0) {
|
|
201
201
|
throw new GSDError(
|
|
202
202
|
GSD_PARSE_ERROR,
|
|
203
|
-
`loadPrompt("${name}"): template declares {{${missing.join("}}, {{")}}}
|
|
203
|
+
`loadPrompt("${name}"): template declares {{${missing.join("}}, {{")}}} but no value was provided. ` +
|
|
204
204
|
`This usually means the extension code in memory is older than the template on disk. ` +
|
|
205
205
|
`Restart pi to reload the extension.`,
|
|
206
206
|
);
|
|
@@ -57,7 +57,7 @@ Subagents report only; they do not write user source. Fold any findings into Dec
|
|
|
57
57
|
**Success path** (all verifications passed):
|
|
58
58
|
|
|
59
59
|
10. For each requirement whose status changed in step 9, call `gsd_requirement_update` with the requirement ID and updated `status` and `validation` fields — the tool regenerates `.gsd/REQUIREMENTS.md` automatically. Do this BEFORE completing the milestone so requirement updates are persisted.
|
|
60
|
-
11.
|
|
60
|
+
11. Refresh the project state through `gsd_summary_save` with `artifact_type: "PROJECT"` and the full updated project markdown as `content`; omit `milestone_id`. The tool persists the DB-backed PROJECT artifact and renders `.gsd/PROJECT.md`. Do not write or edit `.gsd/PROJECT.md` directly.
|
|
61
61
|
12. Extract structured learnings from this milestone and persist them to the GSD memory store. Follow the procedure block immediately below — it writes `{{milestoneId}}-LEARNINGS.md` as the audit trail and persists Patterns, Lessons, and Decisions via `capture_thought` (categories: pattern, gotcha/convention, architecture). The memory store is the single source of truth for cross-session durable knowledge (ADR-013).
|
|
62
62
|
|
|
63
63
|
{{extractLearningsSteps}}
|
|
@@ -34,7 +34,7 @@ Use `subagent` only for fresh-context review when useful: reviewer for cross-cut
|
|
|
34
34
|
12. Review the inlined task-summary excerpts for DECISIONS.md and KNOWLEDGE.md-worthy decisions, patterns, and gotchas. Read full `*-SUMMARY.md` files only when an excerpt is absent, truncated, or lacks the specific evidence needed for the slice narrative. Capture significant items with `capture_thought`; do not append knowledge files directly.
|
|
35
35
|
13. When verification passes, call `gsd_slice_complete`. The DB-backed tool is the canonical write path. Do **not** manually write `{{sliceSummaryPath}}`. Do **not** manually write `{{sliceUatPath}}`. Do not edit roadmap checkboxes; the tool renders files and updates projections.
|
|
36
36
|
14. Do not run git commands.
|
|
37
|
-
15.
|
|
37
|
+
15. If the current project state needs refresh, call `gsd_summary_save` with `artifact_type: "PROJECT"` and the full updated project markdown as `content`; omit `milestone_id`. Do not write or edit `.gsd/PROJECT.md` directly.
|
|
38
38
|
|
|
39
39
|
**Autonomous execution:** no human is available. Do not call `ask_user_questions` or `secure_env_collect`; make reasonable assumptions and document them.
|
|
40
40
|
|
|
@@ -106,8 +106,8 @@ Directories use bare IDs. Files use ID-SUFFIX format. Titles live inside content
|
|
|
106
106
|
|
|
107
107
|
In a single pass:
|
|
108
108
|
1. `mkdir -p .gsd/milestones/{{milestoneId}}/slices`
|
|
109
|
-
2.
|
|
110
|
-
3.
|
|
109
|
+
2. Call `gsd_summary_save` with `artifact_type: "PROJECT"` and full Project template content. The tool persists the DB-backed PROJECT artifact and renders `.gsd/PROJECT.md`. Describe what the project is, its current state, and list the milestone sequence.
|
|
110
|
+
3. Persist requirements with `gsd_requirement_save` or `gsd_requirement_update`, then call `gsd_summary_save` with `artifact_type: "REQUIREMENTS"` so the tool renders `.gsd/REQUIREMENTS.md` from DB rows. Confirm states, ownership, and traceability before roadmap creation.
|
|
111
111
|
|
|
112
112
|
**Depth-Preservation Guidance for context.md:** Preserve the specification's exact terminology, emphasis, and framing. Do not flatten domain-specific language into generics. CONTEXT.md is downstream agents' only window into this spec.
|
|
113
113
|
|
|
@@ -120,8 +120,8 @@ In a single pass:
|
|
|
120
120
|
|
|
121
121
|
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
122
122
|
|
|
123
|
-
- [ ]
|
|
124
|
-
- [ ]
|
|
123
|
+
- [ ] Called `gsd_summary_save` for the PROJECT artifact (step 2)
|
|
124
|
+
- [ ] Persisted requirements and called `gsd_summary_save` for the REQUIREMENTS artifact (step 3)
|
|
125
125
|
- [ ] Written `{{contextPath}}` (step 4)
|
|
126
126
|
- [ ] Called `gsd_plan_milestone` (step 5)
|
|
127
127
|
|
|
@@ -145,8 +145,8 @@ Next steps:
|
|
|
145
145
|
#### Phase 1: Shared artifacts
|
|
146
146
|
|
|
147
147
|
1. For each milestone, call `gsd_milestone_generate_id`; never invent IDs. Then `mkdir -p .gsd/milestones/<ID>/slices`.
|
|
148
|
-
2.
|
|
149
|
-
3.
|
|
148
|
+
2. Call `gsd_summary_save` with `artifact_type: "PROJECT"` and full Project template content so the tool persists the DB-backed PROJECT artifact and renders `.gsd/PROJECT.md`.
|
|
149
|
+
3. Persist requirements with `gsd_requirement_save` or `gsd_requirement_update`, then call `gsd_summary_save` with `artifact_type: "REQUIREMENTS"` so the tool renders `.gsd/REQUIREMENTS.md` from DB rows. Capture Active, Deferred, Out of Scope, and any already Validated requirements. Later milestones may have provisional ownership where slice plans do not exist yet.
|
|
150
150
|
4. For any architectural or pattern decisions, call `gsd_decision_save` — the tool auto-assigns IDs and regenerates `.gsd/DECISIONS.md` automatically.
|
|
151
151
|
|
|
152
152
|
#### Phase 2: Primary milestone
|
|
@@ -214,8 +214,8 @@ For single-milestone projects, do NOT write this file.
|
|
|
214
214
|
|
|
215
215
|
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
216
216
|
|
|
217
|
-
- [ ]
|
|
218
|
-
- [ ]
|
|
217
|
+
- [ ] Called `gsd_summary_save` for the PROJECT artifact
|
|
218
|
+
- [ ] Persisted requirements and called `gsd_summary_save` for the REQUIREMENTS artifact
|
|
219
219
|
- [ ] Written the primary milestone `CONTEXT.md`
|
|
220
220
|
- [ ] Called `gsd_plan_milestone` for the primary milestone
|
|
221
221
|
- [ ] Written `.gsd/DISCUSSION-MANIFEST.json` with `gates_completed === total`
|