gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.04f5ccf82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -18
- package/dist/cli.js +20 -9
- package/dist/headless-ui.js +13 -6
- package/dist/headless.js +9 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +1 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +122 -40
- package/dist/resources/extensions/gsd/auto/orchestrator.js +15 -4
- package/dist/resources/extensions/gsd/auto/phases.js +146 -49
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
- package/dist/resources/extensions/gsd/auto-budget.js +9 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +72 -5
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +185 -30
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +329 -137
- package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
- package/dist/resources/extensions/gsd/auto-recovery.js +82 -16
- package/dist/resources/extensions/gsd/auto-start.js +99 -16
- package/dist/resources/extensions/gsd/auto-timers.js +11 -3
- package/dist/resources/extensions/gsd/auto-verification.js +146 -34
- package/dist/resources/extensions/gsd/auto-worktree.js +185 -26
- package/dist/resources/extensions/gsd/auto.js +135 -74
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +65 -10
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +13 -10
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +14 -4
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
- package/dist/resources/extensions/gsd/clean-root-preflight.js +267 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +16 -4
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +55 -7
- package/dist/resources/extensions/gsd/db/auto-workers.js +30 -0
- package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
- package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
- package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +74 -3
- package/dist/resources/extensions/gsd/doctor-proactive.js +14 -2
- 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 +10 -3
- package/dist/resources/extensions/gsd/git-conflict-state.js +21 -0
- package/dist/resources/extensions/gsd/git-service.js +152 -15
- package/dist/resources/extensions/gsd/gsd-db.js +76 -33
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +110 -117
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/init-wizard.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
- package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +121 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
- package/dist/resources/extensions/gsd/pre-execution-checks.js +54 -19
- package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
- package/dist/resources/extensions/gsd/preferences-models.js +6 -4
- package/dist/resources/extensions/gsd/preferences-types.js +3 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +147 -0
- package/dist/resources/extensions/gsd/preferences.js +35 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/repo-identity.js +39 -22
- package/dist/resources/extensions/gsd/repository-registry.js +44 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
- package/dist/resources/extensions/gsd/session-lock.js +15 -2
- package/dist/resources/extensions/gsd/slice-parallel-conflict.js +2 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +84 -5
- 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 +28 -7
- package/dist/resources/extensions/gsd/status-guards.js +14 -2
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/dist/resources/extensions/gsd/templates/plan.md +9 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -9
- package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -10
- package/dist/resources/extensions/gsd/tools/exec-tool.js +87 -5
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +32 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +185 -40
- package/dist/resources/extensions/gsd/tui/render-kit.js +33 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +142 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/watch/header-renderer.js +34 -25
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +86 -19
- package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
- package/dist/resources/extensions/gsd/worktree-safety.js +43 -4
- package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
- package/dist/resources/extensions/gsd/worktree-telemetry.js +32 -0
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/shared/interview-ui.js +6 -4
- package/dist/resources/extensions/shared/next-action-ui.js +13 -5
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- package/dist/resources/skills/forensics/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- 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 +8 -8
- package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
- package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.js +7 -8
- package/package.json +4 -4
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +13 -4
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/src/__tests__/stream-process.test.mjs +32 -12
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +16 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.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/components/tool-execution.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.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 +82 -97
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +20 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +91 -102
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/loader.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/loader.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/loader.test.js +24 -0
- package/packages/pi-tui/dist/__tests__/loader.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +72 -4
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/loader.js +3 -0
- package/packages/pi-tui/dist/components/loader.js.map +1 -1
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +1 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +117 -33
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/loader.test.ts +30 -0
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +90 -4
- package/packages/pi-tui/src/components/loader.ts +3 -0
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/src/tui.ts +116 -33
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +10 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +19 -6
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +1 -0
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +123 -40
- package/src/resources/extensions/gsd/auto/orchestrator.ts +15 -4
- package/src/resources/extensions/gsd/auto/phases.ts +172 -60
- package/src/resources/extensions/gsd/auto/session.ts +16 -0
- package/src/resources/extensions/gsd/auto/types.ts +3 -0
- package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
- package/src/resources/extensions/gsd/auto-budget.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +78 -5
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +208 -29
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +369 -148
- package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
- package/src/resources/extensions/gsd/auto-recovery.ts +86 -13
- package/src/resources/extensions/gsd/auto-start.ts +109 -14
- package/src/resources/extensions/gsd/auto-timers.ts +10 -3
- package/src/resources/extensions/gsd/auto-verification.ts +174 -42
- package/src/resources/extensions/gsd/auto-worktree.ts +202 -30
- package/src/resources/extensions/gsd/auto.ts +172 -81
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +66 -10
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -10
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -4
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
- package/src/resources/extensions/gsd/clean-root-preflight.ts +284 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +17 -4
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- package/src/resources/extensions/gsd/crash-recovery.ts +55 -6
- package/src/resources/extensions/gsd/db/auto-workers.ts +37 -0
- package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
- package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
- package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +73 -3
- package/src/resources/extensions/gsd/doctor-proactive.ts +18 -2
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +2 -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 +9 -3
- package/src/resources/extensions/gsd/git-conflict-state.ts +23 -0
- package/src/resources/extensions/gsd/git-service.ts +182 -16
- package/src/resources/extensions/gsd/gsd-db.ts +80 -31
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +142 -134
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/init-wizard.ts +17 -2
- package/src/resources/extensions/gsd/journal.ts +8 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
- package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +139 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
- package/src/resources/extensions/gsd/pre-execution-checks.ts +67 -19
- package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
- package/src/resources/extensions/gsd/preferences-models.ts +6 -4
- package/src/resources/extensions/gsd/preferences-types.ts +35 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +154 -0
- package/src/resources/extensions/gsd/preferences.ts +39 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/repo-identity.ts +45 -25
- package/src/resources/extensions/gsd/repository-registry.ts +77 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
- package/src/resources/extensions/gsd/session-lock.ts +15 -2
- package/src/resources/extensions/gsd/slice-parallel-conflict.ts +2 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +75 -3
- 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 +33 -7
- package/src/resources/extensions/gsd/status-guards.ts +16 -2
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/src/resources/extensions/gsd/templates/plan.md +9 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
- 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 +775 -34
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +245 -28
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +136 -13
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-workers.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +170 -3
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +55 -2
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +60 -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 +104 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +139 -1
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +140 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +99 -1
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +15 -1
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +36 -1
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +226 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +5 -21
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
- package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +21 -40
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +59 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/prefs-missing-models-crash.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +28 -1
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +59 -1
- package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +112 -1
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +94 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +188 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +153 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +73 -2
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +18 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +57 -10
- package/src/resources/extensions/gsd/tools/exec-tool.ts +98 -5
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +31 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +166 -17
- package/src/resources/extensions/gsd/tui/render-kit.ts +44 -0
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +170 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/watch/header-renderer.ts +35 -24
- package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +98 -20
- package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
- package/src/resources/extensions/gsd/worktree-safety.ts +57 -10
- package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
- package/src/resources/extensions/gsd/worktree-telemetry.ts +39 -0
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/shared/interview-ui.ts +6 -4
- package/src/resources/extensions/shared/next-action-ui.ts +11 -5
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
- package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +32 -0
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/src/resources/skills/forensics/SKILL.md +1 -1
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → w_ikFkx_-OHxisG9xjz4u}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → w_ikFkx_-OHxisG9xjz4u}/_ssgManifest.js +0 -0
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Split into two functions called sequentially by auto-loop with
|
|
9
9
|
* the verification gate between them:
|
|
10
|
-
* 1. postUnitPreVerification() —
|
|
11
|
-
* 2. postUnitPostVerification() — DB dual-write, hooks, triage, quick-tasks
|
|
10
|
+
* 1. postUnitPreVerification() — closeout git for non-task units, doctor, state rebuild, worktree sync, artifact verification
|
|
11
|
+
* 2. postUnitPostVerification() — post-verified task git, DB dual-write, hooks, triage, quick-tasks
|
|
12
12
|
*
|
|
13
13
|
* Extracted from the pre-loop agent_end handler in auto.ts.
|
|
14
14
|
*/
|
|
@@ -41,12 +41,13 @@ import {
|
|
|
41
41
|
resolveExpectedArtifactPath,
|
|
42
42
|
writeBlockerPlaceholder,
|
|
43
43
|
diagnoseExpectedArtifact,
|
|
44
|
+
diagnoseWorktreeIntegrityFailure,
|
|
44
45
|
} from "./auto-recovery.js";
|
|
45
46
|
import { regenerateIfMissing } from "./workflow-projections.js";
|
|
46
47
|
import { WorktreeStateProjection } from "./worktree-state-projection.js";
|
|
47
48
|
import { createWorkspace, scopeMilestone } from "./workspace.js";
|
|
48
49
|
import { normalizeWorktreePathForCompare } from "./worktree-root.js";
|
|
49
|
-
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter, getVerificationEvidence } from "./gsd-db.js";
|
|
50
|
+
import { isDbAvailable, getDbPath, refreshOpenDatabaseFromDisk, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter, getVerificationEvidence } from "./gsd-db.js";
|
|
50
51
|
import { renderPlanCheckboxes } from "./markdown-renderer.js";
|
|
51
52
|
import { consumeSignal } from "./session-status-io.js";
|
|
52
53
|
import {
|
|
@@ -62,8 +63,7 @@ import { runSafely } from "./auto-utils.js";
|
|
|
62
63
|
import type { AutoSession, SidecarItem } from "./auto/session.js";
|
|
63
64
|
import { getEvidence, clearEvidenceFromDisk } from "./safety/evidence-collector.js";
|
|
64
65
|
import { validateFileChanges } from "./safety/file-change-validator.js";
|
|
65
|
-
|
|
66
|
-
// import { crossReferenceEvidence, type ClaimedEvidence } from "./safety/evidence-cross-ref.js";
|
|
66
|
+
import { crossReferenceEvidence, type ClaimedEvidence } from "./safety/evidence-cross-ref.js";
|
|
67
67
|
import { validateContent } from "./safety/content-validator.js";
|
|
68
68
|
import { resolveSafetyHarnessConfig } from "./safety/safety-harness.js";
|
|
69
69
|
import { resolveExpectedArtifactPath as resolveArtifactForContent } from "./auto-artifact-paths.js";
|
|
@@ -84,6 +84,8 @@ import {
|
|
|
84
84
|
} from "./project-research-policy.js";
|
|
85
85
|
import { validateArtifact } from "./schemas/validate.js";
|
|
86
86
|
import { verificationRetryKey } from "./auto/verification-retry-policy.js";
|
|
87
|
+
import { getLedger } from "./metrics.js";
|
|
88
|
+
import { getUnitCostSpikeAction } from "./auto-budget.js";
|
|
87
89
|
|
|
88
90
|
// ─── Path Comparison Helper ───────────────────────────────────────────────
|
|
89
91
|
/** Compare two paths for physical identity, tolerating trailing slashes and symlinks. */
|
|
@@ -109,6 +111,40 @@ function formatPreExecutionCheckDetail(check: PreExecutionCheckJSON): string {
|
|
|
109
111
|
|
|
110
112
|
const COMPLETE_MILESTONE_DB_SETTLE_MS = 1500;
|
|
111
113
|
const COMPLETE_MILESTONE_DB_SETTLE_POLL_MS = 100;
|
|
114
|
+
const GIT_ACTION_FAILURE_LOG_REL_PATH = ".gsd/git-action-failures.log";
|
|
115
|
+
const DEFAULT_PER_UNIT_COST_CAP_USD = 5.0;
|
|
116
|
+
|
|
117
|
+
function getCurrentUnitCostStats(unitId: string): { unitCostUsd: number; rollingAvgUsd: number } {
|
|
118
|
+
const ledger = getLedger();
|
|
119
|
+
if (!ledger || !Array.isArray(ledger.units) || ledger.units.length === 0) {
|
|
120
|
+
return { unitCostUsd: 0, rollingAvgUsd: 0 };
|
|
121
|
+
}
|
|
122
|
+
let unitCostUsd = 0;
|
|
123
|
+
let totalCost = 0;
|
|
124
|
+
let totalUnits = 0;
|
|
125
|
+
for (const unit of ledger.units) {
|
|
126
|
+
const cost = typeof unit?.cost === "number" ? unit.cost : 0;
|
|
127
|
+
if (!Number.isFinite(cost) || cost < 0) continue;
|
|
128
|
+
totalCost += cost;
|
|
129
|
+
totalUnits++;
|
|
130
|
+
if (unit?.id === unitId) unitCostUsd += cost;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
unitCostUsd,
|
|
134
|
+
rollingAvgUsd: totalUnits > 0 ? totalCost / totalUnits : 0,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function persistGitActionFailure(basePath: string, action: TurnGitActionMode, message: string): string {
|
|
139
|
+
const logPath = join(basePath, GIT_ACTION_FAILURE_LOG_REL_PATH);
|
|
140
|
+
const logDir = join(basePath, ".gsd");
|
|
141
|
+
const timestamp = new Date().toISOString();
|
|
142
|
+
const body = message.trim() || "unknown git failure";
|
|
143
|
+
const entry = `[${timestamp}] action=${action}\n${body}\n\n`;
|
|
144
|
+
mkdirSync(logDir, { recursive: true });
|
|
145
|
+
appendFileSync(logPath, entry, "utf-8");
|
|
146
|
+
return logPath;
|
|
147
|
+
}
|
|
112
148
|
|
|
113
149
|
function stripKnownIdPrefix(value: string | undefined | null, id: string): string | undefined {
|
|
114
150
|
const raw = String(value ?? "").trim();
|
|
@@ -164,7 +200,12 @@ async function buildTaskCommitContextForUnit(
|
|
|
164
200
|
sliceTitle: stripKnownIdPrefix(slice?.title, sid),
|
|
165
201
|
oneLiner: summary?.oneLiner || task?.one_liner || undefined,
|
|
166
202
|
keyFiles:
|
|
167
|
-
summary?.frontmatter.key_files?.filter(f =>
|
|
203
|
+
summary?.frontmatter.key_files?.filter((f) => {
|
|
204
|
+
const normalized = f.trim();
|
|
205
|
+
return normalized.length > 0 &&
|
|
206
|
+
!normalized.includes("{{") &&
|
|
207
|
+
!/^(?:\(none\)|none\.?|n\/a)$/i.test(normalized);
|
|
208
|
+
}) ??
|
|
168
209
|
task?.key_files ??
|
|
169
210
|
undefined,
|
|
170
211
|
issueNumber: ghIssueNumber,
|
|
@@ -222,6 +263,10 @@ export function _shouldDispatchQuickTaskForTest(
|
|
|
222
263
|
state.currentUnit.type !== "quick-task";
|
|
223
264
|
}
|
|
224
265
|
|
|
266
|
+
export function shouldDeferCloseoutGitAction(unitType: string): boolean {
|
|
267
|
+
return unitType === "execute-task";
|
|
268
|
+
}
|
|
269
|
+
|
|
225
270
|
/** Unit types that only touch `.gsd/` internal state files (no code changes).
|
|
226
271
|
* Auto-commit is skipped for these — their state files are picked up by the
|
|
227
272
|
* next actual task commit via `smartStage()`. */
|
|
@@ -237,7 +282,7 @@ import {
|
|
|
237
282
|
unitVerb,
|
|
238
283
|
describeNextUnit,
|
|
239
284
|
} from "./auto-dashboard.js";
|
|
240
|
-
import { existsSync, unlinkSync } from "node:fs";
|
|
285
|
+
import { appendFileSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
|
|
241
286
|
import { join, relative } from "node:path";
|
|
242
287
|
import { _resetHasChangesCache } from "./native-git-bridge.js";
|
|
243
288
|
import { autoCommitCurrentBranch } from "./worktree.js";
|
|
@@ -367,7 +412,7 @@ export function detectRogueFileWrites(
|
|
|
367
412
|
export const MAX_ARTIFACT_VERIFICATION_RETRIES = 3;
|
|
368
413
|
|
|
369
414
|
export const STEP_COMPLETE_FALLBACK_MESSAGE =
|
|
370
|
-
"Step complete. Run /clear, then /gsd to continue (or /gsd auto to run continuously).";
|
|
415
|
+
"Step complete. Run /clear if you want a clean view, then /gsd next to continue one step (or /gsd auto to run continuously).";
|
|
371
416
|
|
|
372
417
|
export function buildStepCompleteMessage(nextState: import("./types.js").GSDState): string {
|
|
373
418
|
if (nextState.phase === "complete") {
|
|
@@ -375,7 +420,24 @@ export function buildStepCompleteMessage(nextState: import("./types.js").GSDStat
|
|
|
375
420
|
}
|
|
376
421
|
const next = describeNextUnit(nextState);
|
|
377
422
|
return `Step complete. Next: ${next.label}\n`
|
|
378
|
-
+ `Run /clear, then /gsd to continue (or /gsd auto to run continuously).`;
|
|
423
|
+
+ `Run /clear if you want a clean view, then /gsd next to continue one step (or /gsd auto to run continuously).`;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Decide whether step mode should stop at the step wizard after a unit finishes.
|
|
428
|
+
*
|
|
429
|
+
* @param currentUnitType The just-finished unit type, such as "execute-task" or
|
|
430
|
+
* "complete-milestone"; may be null/undefined when no current unit is known.
|
|
431
|
+
* @param phaseAfterUnit The freshly derived next phase, such as "executing" or
|
|
432
|
+
* "complete"; may be null/undefined if state derivation failed.
|
|
433
|
+
* @returns true to show the step wizard; false to keep the loop running so
|
|
434
|
+
* terminal milestone completion can reach the merge/finalization path.
|
|
435
|
+
*/
|
|
436
|
+
export function shouldReturnStepWizardAfterUnit(
|
|
437
|
+
currentUnitType: string | null | undefined,
|
|
438
|
+
phaseAfterUnit: string | null | undefined,
|
|
439
|
+
): boolean {
|
|
440
|
+
return currentUnitType !== "complete-milestone" && phaseAfterUnit !== "complete";
|
|
379
441
|
}
|
|
380
442
|
|
|
381
443
|
export interface PreVerificationOpts {
|
|
@@ -410,6 +472,11 @@ function artifactValidationKind(unitType: string): "project" | "requirements" |
|
|
|
410
472
|
}
|
|
411
473
|
|
|
412
474
|
function describeArtifactVerificationFailure(unitType: string, unitId: string, basePath: string): string {
|
|
475
|
+
const worktreeFailure = diagnoseWorktreeIntegrityFailure(basePath);
|
|
476
|
+
if (worktreeFailure) {
|
|
477
|
+
return `${worktreeFailure} Unit: ${unitType} ${unitId}.`;
|
|
478
|
+
}
|
|
479
|
+
|
|
413
480
|
const artifactPath = resolveExpectedArtifactPath(unitType, unitId, basePath);
|
|
414
481
|
if (!artifactPath) {
|
|
415
482
|
return `Artifact verification failed: ${unitType} "${unitId}" has no resolvable artifact path.`;
|
|
@@ -466,6 +533,178 @@ export async function autoCommitUnit(
|
|
|
466
533
|
}
|
|
467
534
|
}
|
|
468
535
|
|
|
536
|
+
/**
|
|
537
|
+
* Execute the turn-level git action (commit, snapshot, or status-only).
|
|
538
|
+
*
|
|
539
|
+
* @param opts.softFailure - Defaults to false. When true, retry git failures,
|
|
540
|
+
* warn, and continue without pausing auto-mode; use for best-effort deferred
|
|
541
|
+
* closeout work where a git failure should not block the run.
|
|
542
|
+
*/
|
|
543
|
+
async function runCloseoutGitAction(
|
|
544
|
+
pctx: PostUnitContext,
|
|
545
|
+
unit: NonNullable<AutoSession["currentUnit"]>,
|
|
546
|
+
opts?: { softFailure?: boolean },
|
|
547
|
+
): Promise<"continue" | "dispatched"> {
|
|
548
|
+
const { s, ctx, pi, pauseAuto } = pctx;
|
|
549
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences;
|
|
550
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
551
|
+
const turnAction: TurnGitActionMode = uokFlags.gitops ? uokFlags.gitopsTurnAction : "commit";
|
|
552
|
+
const traceId = s.currentTraceId ?? `turn:${unit.startedAt}`;
|
|
553
|
+
const turnId = s.currentTurnId ?? `${unit.type}/${unit.id}/${unit.startedAt}`;
|
|
554
|
+
|
|
555
|
+
s.lastGitActionFailure = null;
|
|
556
|
+
s.lastGitActionStatus = null;
|
|
557
|
+
|
|
558
|
+
try {
|
|
559
|
+
let taskContext: TaskCommitContext | undefined;
|
|
560
|
+
let targetRepositories: string[] | undefined;
|
|
561
|
+
|
|
562
|
+
if (turnAction === "commit" && unit.type === "execute-task") {
|
|
563
|
+
taskContext = await buildTaskCommitContextForUnit(s.basePath, unit.id);
|
|
564
|
+
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unit.id);
|
|
565
|
+
if (mid && sid && tid && isDbAvailable()) {
|
|
566
|
+
targetRepositories = getTask(mid, sid, tid)?.target_repositories;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// Invalidate the nativeHasChanges cache before auto-commit (#1853).
|
|
571
|
+
// The cache has a 10-second TTL and is keyed by basePath. A stale
|
|
572
|
+
// `false` result causes autoCommit to skip staging entirely.
|
|
573
|
+
_resetHasChangesCache();
|
|
574
|
+
|
|
575
|
+
const skipLifecycleCommit =
|
|
576
|
+
turnAction === "commit" && LIFECYCLE_ONLY_UNITS.has(unit.type);
|
|
577
|
+
|
|
578
|
+
if (skipLifecycleCommit) {
|
|
579
|
+
debugLog("postUnit", {
|
|
580
|
+
phase: "git-action-skipped",
|
|
581
|
+
reason: "lifecycle-only-unit",
|
|
582
|
+
unitType: unit.type,
|
|
583
|
+
unitId: unit.id,
|
|
584
|
+
});
|
|
585
|
+
} else {
|
|
586
|
+
const maxAttempts = opts?.softFailure ? 3 : 1;
|
|
587
|
+
let gitResult = runTurnGitAction({
|
|
588
|
+
basePath: s.basePath,
|
|
589
|
+
action: turnAction,
|
|
590
|
+
unitType: unit.type,
|
|
591
|
+
unitId: unit.id,
|
|
592
|
+
taskContext,
|
|
593
|
+
targetRepositories,
|
|
594
|
+
});
|
|
595
|
+
for (let attempt = 1; gitResult.status === "failed" && attempt < maxAttempts; attempt++) {
|
|
596
|
+
await new Promise((resolve) => setTimeout(resolve, 250 * attempt));
|
|
597
|
+
gitResult = runTurnGitAction({
|
|
598
|
+
basePath: s.basePath,
|
|
599
|
+
action: turnAction,
|
|
600
|
+
unitType: unit.type,
|
|
601
|
+
unitId: unit.id,
|
|
602
|
+
taskContext,
|
|
603
|
+
targetRepositories,
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
if (uokFlags.gitops) {
|
|
608
|
+
writeTurnGitTransaction({
|
|
609
|
+
basePath: s.basePath,
|
|
610
|
+
traceId,
|
|
611
|
+
turnId,
|
|
612
|
+
unitType: unit.type,
|
|
613
|
+
unitId: unit.id,
|
|
614
|
+
stage: "publish",
|
|
615
|
+
action: turnAction,
|
|
616
|
+
push: uokFlags.gitopsTurnPush,
|
|
617
|
+
status: gitResult.status,
|
|
618
|
+
error: gitResult.error,
|
|
619
|
+
metadata: {
|
|
620
|
+
dirty: gitResult.dirty,
|
|
621
|
+
dirtyRepositories: gitResult.dirtyRepositories,
|
|
622
|
+
commitMessage: gitResult.commitMessage,
|
|
623
|
+
commitMessages: gitResult.commitMessages,
|
|
624
|
+
commitErrors: gitResult.commitErrors,
|
|
625
|
+
skippedRepositories: gitResult.skippedRepositories,
|
|
626
|
+
snapshotLabel: gitResult.snapshotLabel,
|
|
627
|
+
},
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
if (gitResult.status === "failed") {
|
|
632
|
+
s.lastGitActionFailure = gitResult.error ?? `git ${turnAction} failed`;
|
|
633
|
+
s.lastGitActionStatus = "failed";
|
|
634
|
+
const fullError = gitResult.error ?? "unknown error";
|
|
635
|
+
const failureLogPath = persistGitActionFailure(s.basePath, turnAction, fullError);
|
|
636
|
+
if (uokFlags.gitops && uokFlags.gates) {
|
|
637
|
+
const parsed = parseUnitId(unit.id);
|
|
638
|
+
const gateRunner = new UokGateRunner();
|
|
639
|
+
gateRunner.register({
|
|
640
|
+
id: "closeout-git-action",
|
|
641
|
+
type: "closeout",
|
|
642
|
+
execute: async () => ({
|
|
643
|
+
outcome: "fail",
|
|
644
|
+
failureClass: "git",
|
|
645
|
+
rationale: `turn git action "${turnAction}" failed`,
|
|
646
|
+
findings: fullError,
|
|
647
|
+
}),
|
|
648
|
+
});
|
|
649
|
+
await gateRunner.run("closeout-git-action", {
|
|
650
|
+
basePath: s.basePath,
|
|
651
|
+
traceId,
|
|
652
|
+
turnId,
|
|
653
|
+
milestoneId: parsed.milestone ?? undefined,
|
|
654
|
+
sliceId: parsed.slice ?? undefined,
|
|
655
|
+
taskId: parsed.task ?? undefined,
|
|
656
|
+
unitType: unit.type,
|
|
657
|
+
unitId: unit.id,
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const failureMsg = `Git ${turnAction} failed: ${fullError.split("\n")[0]} (full details: ${failureLogPath})`;
|
|
662
|
+
ctx.ui.notify(failureMsg, opts?.softFailure ? "warning" : "error");
|
|
663
|
+
debugLog("postUnit", {
|
|
664
|
+
phase: opts?.softFailure ? "git-action-failed-soft" : "git-action-failed-blocking",
|
|
665
|
+
action: turnAction,
|
|
666
|
+
error: fullError,
|
|
667
|
+
failureLogPath,
|
|
668
|
+
});
|
|
669
|
+
if (opts?.softFailure) {
|
|
670
|
+
return "continue";
|
|
671
|
+
}
|
|
672
|
+
await pauseAuto(ctx, pi);
|
|
673
|
+
return "dispatched";
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
s.lastGitActionStatus = "ok";
|
|
677
|
+
|
|
678
|
+
if (turnAction === "commit" && gitResult.commitMessage) {
|
|
679
|
+
ctx.ui.notify(`Committed: ${gitResult.commitMessage.split("\n")[0]}`, "info");
|
|
680
|
+
} else if (turnAction === "snapshot" && gitResult.snapshotLabel) {
|
|
681
|
+
ctx.ui.notify(`Snapshot recorded: ${gitResult.snapshotLabel}`, "info");
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
} catch (e) {
|
|
685
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
686
|
+
s.lastGitActionFailure = message;
|
|
687
|
+
s.lastGitActionStatus = "failed";
|
|
688
|
+
debugLog("postUnit", { phase: "git-action", error: message, action: turnAction });
|
|
689
|
+
ctx.ui.notify(`Git ${turnAction} failed: ${message.split("\n")[0]}`, opts?.softFailure ? "warning" : "error");
|
|
690
|
+
if (opts?.softFailure) {
|
|
691
|
+
return "continue";
|
|
692
|
+
}
|
|
693
|
+
if (uokFlags.gitops) {
|
|
694
|
+
await pauseAuto(ctx, pi);
|
|
695
|
+
return "dispatched";
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// GitHub sync (non-blocking, opt-in)
|
|
700
|
+
await runSafely("postUnit", "github-sync", async () => {
|
|
701
|
+
const { runGitHubSync } = await import("../github-sync/sync.js");
|
|
702
|
+
await runGitHubSync(s.basePath, unit.type, unit.id);
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
return "continue";
|
|
706
|
+
}
|
|
707
|
+
|
|
469
708
|
/**
|
|
470
709
|
* Pre-verification processing: parallel worker signal check, cache invalidation,
|
|
471
710
|
* auto-commit, doctor run, state rebuild, worktree sync, artifact verification.
|
|
@@ -476,7 +715,7 @@ export async function autoCommitUnit(
|
|
|
476
715
|
* - "retry" — artifact verification failed, s.pendingVerificationRetry set for loop re-iteration
|
|
477
716
|
*/
|
|
478
717
|
export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreVerificationOpts): Promise<"dispatched" | "continue" | "retry"> {
|
|
479
|
-
const { s, ctx, pi,
|
|
718
|
+
const { s, ctx, pi, stopAuto, pauseAuto } = pctx;
|
|
480
719
|
|
|
481
720
|
// ── Parallel worker signal check ──
|
|
482
721
|
const milestoneLock = process.env.GSD_MILESTONE_LOCK;
|
|
@@ -502,135 +741,30 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
502
741
|
await new Promise(r => setTimeout(r, 100));
|
|
503
742
|
}
|
|
504
743
|
|
|
505
|
-
const
|
|
506
|
-
|
|
744
|
+
const dbPath = getDbPath();
|
|
745
|
+
if (isDbAvailable() && dbPath && dbPath !== ":memory:") {
|
|
746
|
+
const refreshed = refreshOpenDatabaseFromDisk();
|
|
747
|
+
if (!refreshed) {
|
|
748
|
+
logWarning("db", "post-unit database refresh failed; derived state may be stale");
|
|
749
|
+
}
|
|
750
|
+
}
|
|
507
751
|
|
|
508
752
|
// Turn-level git action (commit | snapshot | status-only)
|
|
509
753
|
if (s.currentUnit) {
|
|
510
754
|
const unit = s.currentUnit;
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (
|
|
520
|
-
taskContext = await buildTaskCommitContextForUnit(s.basePath, s.currentUnit.id);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// Invalidate the nativeHasChanges cache before auto-commit (#1853).
|
|
524
|
-
// The cache has a 10-second TTL and is keyed by basePath. A stale
|
|
525
|
-
// `false` result causes autoCommit to skip staging entirely, leaving
|
|
526
|
-
// code files only in the working tree where they are destroyed by
|
|
527
|
-
// `git worktree remove --force` during teardown.
|
|
528
|
-
_resetHasChangesCache();
|
|
529
|
-
|
|
530
|
-
const skipLifecycleCommit =
|
|
531
|
-
turnAction === "commit" && LIFECYCLE_ONLY_UNITS.has(s.currentUnit.type);
|
|
532
|
-
|
|
533
|
-
if (skipLifecycleCommit) {
|
|
534
|
-
debugLog("postUnit", {
|
|
535
|
-
phase: "git-action-skipped",
|
|
536
|
-
reason: "lifecycle-only-unit",
|
|
537
|
-
unitType: s.currentUnit.type,
|
|
538
|
-
unitId: s.currentUnit.id,
|
|
539
|
-
});
|
|
540
|
-
} else {
|
|
541
|
-
const gitResult = runTurnGitAction({
|
|
542
|
-
basePath: s.basePath,
|
|
543
|
-
action: turnAction,
|
|
544
|
-
unitType: s.currentUnit.type,
|
|
545
|
-
unitId: s.currentUnit.id,
|
|
546
|
-
taskContext,
|
|
547
|
-
});
|
|
548
|
-
|
|
549
|
-
if (uokFlags.gitops) {
|
|
550
|
-
writeTurnGitTransaction({
|
|
551
|
-
basePath: s.basePath,
|
|
552
|
-
traceId,
|
|
553
|
-
turnId,
|
|
554
|
-
unitType: unit.type,
|
|
555
|
-
unitId: unit.id,
|
|
556
|
-
stage: "publish",
|
|
557
|
-
action: turnAction,
|
|
558
|
-
push: uokFlags.gitopsTurnPush,
|
|
559
|
-
status: gitResult.status,
|
|
560
|
-
error: gitResult.error,
|
|
561
|
-
metadata: {
|
|
562
|
-
dirty: gitResult.dirty,
|
|
563
|
-
commitMessage: gitResult.commitMessage,
|
|
564
|
-
snapshotLabel: gitResult.snapshotLabel,
|
|
565
|
-
},
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
if (gitResult.status === "failed") {
|
|
570
|
-
s.lastGitActionFailure = gitResult.error ?? `git ${turnAction} failed`;
|
|
571
|
-
s.lastGitActionStatus = "failed";
|
|
572
|
-
if (uokFlags.gitops && uokFlags.gates) {
|
|
573
|
-
const parsed = parseUnitId(unit.id);
|
|
574
|
-
const gateRunner = new UokGateRunner();
|
|
575
|
-
gateRunner.register({
|
|
576
|
-
id: "closeout-git-action",
|
|
577
|
-
type: "closeout",
|
|
578
|
-
execute: async () => ({
|
|
579
|
-
outcome: "fail",
|
|
580
|
-
failureClass: "git",
|
|
581
|
-
rationale: `turn git action "${turnAction}" failed`,
|
|
582
|
-
findings: gitResult.error ?? "unknown git failure",
|
|
583
|
-
}),
|
|
584
|
-
});
|
|
585
|
-
await gateRunner.run("closeout-git-action", {
|
|
586
|
-
basePath: s.basePath,
|
|
587
|
-
traceId,
|
|
588
|
-
turnId,
|
|
589
|
-
milestoneId: parsed.milestone ?? undefined,
|
|
590
|
-
sliceId: parsed.slice ?? undefined,
|
|
591
|
-
taskId: parsed.task ?? undefined,
|
|
592
|
-
unitType: unit.type,
|
|
593
|
-
unitId: unit.id,
|
|
594
|
-
});
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
const failureMsg = `Git ${turnAction} failed: ${(gitResult.error ?? "unknown error").split("\n")[0]}`;
|
|
598
|
-
ctx.ui.notify(failureMsg, "error");
|
|
599
|
-
debugLog("postUnit", {
|
|
600
|
-
phase: "git-action-failed-blocking",
|
|
601
|
-
action: turnAction,
|
|
602
|
-
error: gitResult.error ?? "unknown error",
|
|
603
|
-
});
|
|
604
|
-
await pauseAuto(ctx, pi);
|
|
605
|
-
return "dispatched";
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
s.lastGitActionStatus = "ok";
|
|
609
|
-
|
|
610
|
-
if (turnAction === "commit" && gitResult.commitMessage) {
|
|
611
|
-
ctx.ui.notify(`Committed: ${gitResult.commitMessage.split("\n")[0]}`, "info");
|
|
612
|
-
} else if (turnAction === "snapshot" && gitResult.snapshotLabel) {
|
|
613
|
-
ctx.ui.notify(`Snapshot recorded: ${gitResult.snapshotLabel}`, "info");
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
} catch (e) {
|
|
617
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
618
|
-
s.lastGitActionFailure = message;
|
|
619
|
-
s.lastGitActionStatus = "failed";
|
|
620
|
-
debugLog("postUnit", { phase: "git-action", error: message, action: turnAction });
|
|
621
|
-
ctx.ui.notify(`Git ${turnAction} failed: ${message.split("\n")[0]}`, uokFlags.gitops ? "error" : "warning");
|
|
622
|
-
if (uokFlags.gitops) {
|
|
623
|
-
await pauseAuto(ctx, pi);
|
|
755
|
+
if (shouldDeferCloseoutGitAction(unit.type)) {
|
|
756
|
+
debugLog("postUnit", {
|
|
757
|
+
phase: "git-action-deferred-until-verification",
|
|
758
|
+
unitType: unit.type,
|
|
759
|
+
unitId: unit.id,
|
|
760
|
+
});
|
|
761
|
+
} else {
|
|
762
|
+
const gitActionResult = await runCloseoutGitAction(pctx, unit);
|
|
763
|
+
if (gitActionResult === "dispatched") {
|
|
624
764
|
return "dispatched";
|
|
625
765
|
}
|
|
626
766
|
}
|
|
627
767
|
|
|
628
|
-
// GitHub sync (non-blocking, opt-in)
|
|
629
|
-
await runSafely("postUnit", "github-sync", async () => {
|
|
630
|
-
const { runGitHubSync } = await import("../github-sync/sync.js");
|
|
631
|
-
await runGitHubSync(s.basePath, unit.type, unit.id);
|
|
632
|
-
});
|
|
633
|
-
|
|
634
768
|
// Prune dead bg-shell processes
|
|
635
769
|
await runSafely("postUnit", "prune-bg-shell", async () => {
|
|
636
770
|
const { pruneDeadProcesses } = await import("../bg-shell/process-manager.js");
|
|
@@ -866,7 +1000,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
866
1000
|
if (safetyConfig.enabled) {
|
|
867
1001
|
const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
|
|
868
1002
|
|
|
869
|
-
// File change validation (execute-task only, after
|
|
1003
|
+
// File change validation (execute-task only, after unit execution)
|
|
870
1004
|
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid && isDbAvailable()) {
|
|
871
1005
|
try {
|
|
872
1006
|
const taskRow = getTask(sMid, sSid, sTid);
|
|
@@ -902,15 +1036,43 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
902
1036
|
const bashCalls = actual.filter(e => e.kind === "bash");
|
|
903
1037
|
if (sMid && sSid && sTid && isDbAvailable()) {
|
|
904
1038
|
const taskRow = getTask(sMid, sSid, sTid);
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1039
|
+
if (taskRow?.status === "complete") {
|
|
1040
|
+
const claimedEvidence: ClaimedEvidence[] = getVerificationEvidence(sMid, sSid, sTid)
|
|
1041
|
+
.map((row) => ({
|
|
1042
|
+
command: row.command,
|
|
1043
|
+
exitCode: row.exit_code,
|
|
1044
|
+
verdict: row.verdict,
|
|
1045
|
+
createdAt: row.created_at,
|
|
1046
|
+
}))
|
|
1047
|
+
.filter((row) => typeof row.command === "string" && row.command.trim().length > 0);
|
|
1048
|
+
const mismatches = crossReferenceEvidence(claimedEvidence, actual);
|
|
1049
|
+
|
|
1050
|
+
for (const mismatch of mismatches) {
|
|
1051
|
+
const logMessage = `evidence-xref: ${mismatch.reason}`;
|
|
1052
|
+
if (mismatch.severity === "error") {
|
|
1053
|
+
logError("safety", logMessage);
|
|
1054
|
+
} else {
|
|
1055
|
+
logWarning("safety", logMessage);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
if (claimedEvidence.length > 0 && bashCalls.length === 0) {
|
|
1060
|
+
logWarning("safety", "task claimed verification command evidence but no execution tool calls were recorded");
|
|
1061
|
+
ctx.ui.notify(
|
|
1062
|
+
`Safety: task ${sTid} claimed command evidence but no execution tool calls were recorded`,
|
|
1063
|
+
"warning",
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
const blockingMismatch = mismatches.find((mismatch) => mismatch.severity === "error");
|
|
1068
|
+
if (blockingMismatch) {
|
|
1069
|
+
ctx.ui.notify(
|
|
1070
|
+
`Safety: task ${sTid} claimed passing verification that failed in recorded execution`,
|
|
1071
|
+
"error",
|
|
1072
|
+
);
|
|
1073
|
+
await pauseAuto(ctx, pi);
|
|
1074
|
+
return "dispatched";
|
|
1075
|
+
}
|
|
914
1076
|
}
|
|
915
1077
|
}
|
|
916
1078
|
} catch (e) {
|
|
@@ -1079,10 +1241,28 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1079
1241
|
s.verificationRetryFailureHashes.delete(retryKey);
|
|
1080
1242
|
writeBlockerPlaceholder(s.currentUnit.type, s.currentUnit.id, s.basePath, reason);
|
|
1081
1243
|
ctx.ui.notify(
|
|
1082
|
-
`${s.currentUnit.type} ${s.currentUnit.id} — deterministic policy rejection, wrote blocker placeholder (no retries)
|
|
1244
|
+
`${s.currentUnit.type} ${s.currentUnit.id} — deterministic policy rejection, wrote blocker placeholder (no retries)`,
|
|
1083
1245
|
"warning",
|
|
1084
1246
|
);
|
|
1085
1247
|
// Fall through to "continue" — do NOT enter the retry or db-unavailable paths.
|
|
1248
|
+
} else if (!triggerArtifactVerified && diagnoseWorktreeIntegrityFailure(s.basePath)) {
|
|
1249
|
+
const retryKey = `${s.currentUnit.type}:${s.currentUnit.id}`;
|
|
1250
|
+
const worktreeFailure = diagnoseWorktreeIntegrityFailure(s.basePath)!;
|
|
1251
|
+
s.pendingVerificationRetry = null;
|
|
1252
|
+
s.verificationRetryCount.delete(retryKey);
|
|
1253
|
+
s.verificationRetryFailureHashes.delete(retryKey);
|
|
1254
|
+
debugLog("postUnit", {
|
|
1255
|
+
phase: "worktree-integrity-failure",
|
|
1256
|
+
unitType: s.currentUnit.type,
|
|
1257
|
+
unitId: s.currentUnit.id,
|
|
1258
|
+
basePath: s.basePath,
|
|
1259
|
+
});
|
|
1260
|
+
ctx.ui.notify(
|
|
1261
|
+
`${worktreeFailure} Retry ${s.currentUnit.id} after repair.`,
|
|
1262
|
+
"error",
|
|
1263
|
+
);
|
|
1264
|
+
await pauseAuto(ctx, pi);
|
|
1265
|
+
return "dispatched";
|
|
1086
1266
|
} else if (!triggerArtifactVerified && !isDbAvailable()) {
|
|
1087
1267
|
debugLog("postUnit", { phase: "artifact-verify-skip-db-unavailable", unitType: s.currentUnit.type, unitId: s.currentUnit.id });
|
|
1088
1268
|
const dbSkipDiag = diagnoseExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
@@ -1106,6 +1286,34 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1106
1286
|
const hasExpectedArtifact = resolveExpectedArtifactPath(s.currentUnit.type, s.currentUnit.id, s.basePath) !== null;
|
|
1107
1287
|
if (hasExpectedArtifact) {
|
|
1108
1288
|
const retryKey = `${s.currentUnit.type}:${s.currentUnit.id}`;
|
|
1289
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences;
|
|
1290
|
+
const perUnitCapUsd =
|
|
1291
|
+
typeof prefs?.per_unit_cost_cap_usd === "number" && Number.isFinite(prefs.per_unit_cost_cap_usd) && prefs.per_unit_cost_cap_usd > 0
|
|
1292
|
+
? prefs.per_unit_cost_cap_usd
|
|
1293
|
+
: DEFAULT_PER_UNIT_COST_CAP_USD;
|
|
1294
|
+
const { unitCostUsd, rollingAvgUsd } = getCurrentUnitCostStats(s.currentUnit.id);
|
|
1295
|
+
if (unitCostUsd >= perUnitCapUsd) {
|
|
1296
|
+
s.pendingVerificationRetry = null;
|
|
1297
|
+
s.verificationRetryCount.delete(retryKey);
|
|
1298
|
+
s.verificationRetryFailureHashes.delete(retryKey);
|
|
1299
|
+
ctx.ui.notify(
|
|
1300
|
+
`Unit ${s.currentUnit.id} hit per-unit cap $${perUnitCapUsd.toFixed(2)} — pausing auto-mode.`,
|
|
1301
|
+
"error",
|
|
1302
|
+
);
|
|
1303
|
+
await pauseAuto(ctx, pi);
|
|
1304
|
+
return "dispatched";
|
|
1305
|
+
}
|
|
1306
|
+
if (getUnitCostSpikeAction(unitCostUsd, rollingAvgUsd, 3.0) === "pause") {
|
|
1307
|
+
s.pendingVerificationRetry = null;
|
|
1308
|
+
s.verificationRetryCount.delete(retryKey);
|
|
1309
|
+
s.verificationRetryFailureHashes.delete(retryKey);
|
|
1310
|
+
ctx.ui.notify(
|
|
1311
|
+
`Unit ${s.currentUnit.id} cost spike detected (${unitCostUsd.toFixed(2)} vs avg ${rollingAvgUsd.toFixed(2)}) — pausing auto-mode.`,
|
|
1312
|
+
"error",
|
|
1313
|
+
);
|
|
1314
|
+
await pauseAuto(ctx, pi);
|
|
1315
|
+
return "dispatched";
|
|
1316
|
+
}
|
|
1109
1317
|
const attempt = (s.verificationRetryCount.get(retryKey) ?? 0) + 1;
|
|
1110
1318
|
const failureDetails = describeArtifactVerificationFailure(
|
|
1111
1319
|
s.currentUnit.type,
|
|
@@ -1169,6 +1377,13 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1169
1377
|
const { s, ctx, pi, buildSnapshotOpts, lockBase, stopAuto, pauseAuto, updateProgressWidget } = pctx;
|
|
1170
1378
|
|
|
1171
1379
|
if (s.currentUnit) {
|
|
1380
|
+
if (shouldDeferCloseoutGitAction(s.currentUnit.type)) {
|
|
1381
|
+
const gitActionResult = await runCloseoutGitAction(pctx, s.currentUnit, { softFailure: true });
|
|
1382
|
+
if (gitActionResult === "dispatched") {
|
|
1383
|
+
return "stopped";
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1172
1387
|
try {
|
|
1173
1388
|
const codebasePrefs = loadEffectiveGSDPreferences()?.preferences?.codebase;
|
|
1174
1389
|
const refresh = ensureCodebaseMapFresh(
|
|
@@ -1371,7 +1586,9 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1371
1586
|
// s.canonicalProjectRoot is the project root and lacks files that a
|
|
1372
1587
|
// prior slice wrote to the worktree but hasn't merged to main yet.
|
|
1373
1588
|
const preExecutionBasePath = s.basePath;
|
|
1374
|
-
const result: PreExecutionResult = await runPreExecutionChecks(tasks, preExecutionBasePath
|
|
1589
|
+
const result: PreExecutionResult = await runPreExecutionChecks(tasks, preExecutionBasePath, {
|
|
1590
|
+
additionalRoots: [s.canonicalProjectRoot],
|
|
1591
|
+
});
|
|
1375
1592
|
|
|
1376
1593
|
// Log summary to stderr in existing verification output format
|
|
1377
1594
|
const emoji = result.status === "pass" ? "✅" : result.status === "warn" ? "⚠️" : "❌";
|
|
@@ -1388,12 +1605,12 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1388
1605
|
}
|
|
1389
1606
|
|
|
1390
1607
|
// Write evidence JSON to slice artifacts directory
|
|
1391
|
-
const slicePath = resolveSlicePath(
|
|
1608
|
+
const slicePath = resolveSlicePath(s.canonicalProjectRoot, mid, sid);
|
|
1392
1609
|
const evidenceFileName = `${sid}-PRE-EXEC-VERIFY.json`;
|
|
1393
1610
|
let evidencePath = join(".gsd", "milestones", mid, "slices", sid, evidenceFileName);
|
|
1394
1611
|
if (slicePath) {
|
|
1395
1612
|
writePreExecutionEvidence(result, slicePath, mid, sid);
|
|
1396
|
-
evidencePath = relative(
|
|
1613
|
+
evidencePath = relative(s.canonicalProjectRoot, join(slicePath, evidenceFileName)) || evidenceFileName;
|
|
1397
1614
|
}
|
|
1398
1615
|
|
|
1399
1616
|
if (uokFlags.gates) {
|
|
@@ -1608,17 +1825,21 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1608
1825
|
}
|
|
1609
1826
|
|
|
1610
1827
|
// Step mode → show wizard instead of dispatch.
|
|
1611
|
-
// Without this notify(), /gsd
|
|
1612
|
-
//
|
|
1828
|
+
// Without this notify(), /gsd next finishes a unit and silently exits the
|
|
1829
|
+
// loop, leaving the user with no next-step command.
|
|
1613
1830
|
if (s.stepMode) {
|
|
1831
|
+
let phaseAfterUnit: string | null = null;
|
|
1614
1832
|
try {
|
|
1615
1833
|
const nextState = await deriveState(s.canonicalProjectRoot);
|
|
1834
|
+
phaseAfterUnit = nextState.phase;
|
|
1616
1835
|
ctx.ui.notify(buildStepCompleteMessage(nextState), "info");
|
|
1617
1836
|
} catch (e) {
|
|
1618
1837
|
debugLog("postUnit", { phase: "step-wizard-notify", error: String(e) });
|
|
1619
1838
|
ctx.ui.notify(STEP_COMPLETE_FALLBACK_MESSAGE, "info");
|
|
1620
1839
|
}
|
|
1621
|
-
return
|
|
1840
|
+
return shouldReturnStepWizardAfterUnit(s.currentUnit?.type, phaseAfterUnit)
|
|
1841
|
+
? "step-wizard"
|
|
1842
|
+
: "continue";
|
|
1622
1843
|
}
|
|
1623
1844
|
|
|
1624
1845
|
return "continue";
|