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
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
formatWidgetTokens,
|
|
14
14
|
estimateTimeRemaining,
|
|
15
15
|
extractUatSliceId,
|
|
16
|
+
buildPhaseHandoffOutcome,
|
|
16
17
|
updateProgressWidget,
|
|
17
18
|
setAutoOutcomeWidget,
|
|
18
19
|
getRoadmapSlicesSync,
|
|
@@ -255,6 +256,76 @@ test("setAutoOutcomeWidget renders a durable next-action handoff", () => {
|
|
|
255
256
|
assert.match(output, /\/gsd auto/);
|
|
256
257
|
});
|
|
257
258
|
|
|
259
|
+
test("buildPhaseHandoffOutcome summarizes the last phase result", () => {
|
|
260
|
+
const snapshot = buildPhaseHandoffOutcome({
|
|
261
|
+
unitType: "plan-slice",
|
|
262
|
+
unitId: "M005/S01",
|
|
263
|
+
agentEndMessages: [
|
|
264
|
+
{ message: { role: "assistant", content: "Planned S01 with category-aware filtering and validation steps." } },
|
|
265
|
+
],
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
assert.equal(snapshot.status, "complete");
|
|
269
|
+
assert.equal(snapshot.title, "PLAN complete");
|
|
270
|
+
assert.match(snapshot.detail ?? "", /category-aware filtering/);
|
|
271
|
+
assert.equal(snapshot.unitLabel, "planning M005/S01");
|
|
272
|
+
assert.match(snapshot.nextAction, /next phase/);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("buildPhaseHandoffOutcome ignores non-assistant trailing messages", () => {
|
|
276
|
+
const snapshot = buildPhaseHandoffOutcome({
|
|
277
|
+
unitType: "plan-slice",
|
|
278
|
+
unitId: "M005/S01",
|
|
279
|
+
agentEndMessages: [
|
|
280
|
+
{ message: { role: "assistant", content: "Assistant summary to hand off." } },
|
|
281
|
+
{ role: "tool", content: "Tool output should not be shown." },
|
|
282
|
+
{ role: "user", content: "User follow-up should not be shown." },
|
|
283
|
+
],
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
assert.match(snapshot.detail ?? "", /Assistant summary/);
|
|
287
|
+
assert.doesNotMatch(snapshot.detail ?? "", /Tool output/);
|
|
288
|
+
assert.doesNotMatch(snapshot.detail ?? "", /User follow-up/);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
test("updateProgressWidget preserves the phase handoff during session switching", () => {
|
|
292
|
+
const calls: Array<[string, unknown]> = [];
|
|
293
|
+
updateProgressWidget(
|
|
294
|
+
{
|
|
295
|
+
hasUI: true,
|
|
296
|
+
ui: {
|
|
297
|
+
setWidget(key: string, factory: unknown) {
|
|
298
|
+
calls.push([key, factory]);
|
|
299
|
+
},
|
|
300
|
+
setHeader() {},
|
|
301
|
+
setStatus() {},
|
|
302
|
+
},
|
|
303
|
+
} as any,
|
|
304
|
+
"execute-task",
|
|
305
|
+
"M005/S01/T01",
|
|
306
|
+
{
|
|
307
|
+
phase: "executing",
|
|
308
|
+
activeSlice: { id: "S01", title: "Filter chip bar" },
|
|
309
|
+
activeTask: { id: "T01", title: "Add category filter" },
|
|
310
|
+
} as any,
|
|
311
|
+
{
|
|
312
|
+
getAutoStartTime: () => Date.now(),
|
|
313
|
+
isStepMode: () => false,
|
|
314
|
+
getCmdCtx: () => null,
|
|
315
|
+
getBasePath: () => "",
|
|
316
|
+
isVerbose: () => false,
|
|
317
|
+
isSessionSwitching: () => true,
|
|
318
|
+
getCurrentDispatchedModelId: () => null,
|
|
319
|
+
},
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
assert.ok(calls.some(([key]) => key === "gsd-progress"));
|
|
323
|
+
assert.ok(
|
|
324
|
+
!calls.some(([key, value]) => key === "gsd-outcome" && value === undefined),
|
|
325
|
+
"handoff widget should stay visible until the next progress frame renders",
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
|
|
258
329
|
test("shouldRenderRoadmapProgress hides pre-roadmap zero-slice progress", () => {
|
|
259
330
|
assert.equal(shouldRenderRoadmapProgress(null), false);
|
|
260
331
|
assert.equal(shouldRenderRoadmapProgress({ done: 0, total: 0, activeSliceTasks: null } as any), false);
|
package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts
CHANGED
|
@@ -42,6 +42,20 @@ function makeTmpBase(): string {
|
|
|
42
42
|
return base;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
function makeBrokenIsolatedWorktree(): string {
|
|
46
|
+
const root = mkdtempSync(join(tmpdir(), `gsd-test-5848-${randomUUID().slice(0, 8)}-`));
|
|
47
|
+
tmpDirs.push(root);
|
|
48
|
+
const base = join(root, ".gsd", "projects", "project-id", "worktrees", "M003");
|
|
49
|
+
mkdirSync(join(base, ".gsd", "milestones", "M003", "slices", "S03"), { recursive: true });
|
|
50
|
+
return base;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function makeBrokenIsolatedWorktreeRevParse(): string {
|
|
54
|
+
const base = makeBrokenIsolatedWorktree();
|
|
55
|
+
mkdirSync(join(base, ".git"));
|
|
56
|
+
return base;
|
|
57
|
+
}
|
|
58
|
+
|
|
45
59
|
function resetAutoState(): void {
|
|
46
60
|
_setAutoActiveForTest(false);
|
|
47
61
|
}
|
|
@@ -231,6 +245,108 @@ describe("Test 5 — postUnitPreVerification short-circuits on deterministic err
|
|
|
231
245
|
});
|
|
232
246
|
});
|
|
233
247
|
|
|
248
|
+
describe("Test 5b — broken isolated worktree short-circuits artifact retry (#5848)", () => {
|
|
249
|
+
test("pauses with worktree integrity failure instead of setting pendingVerificationRetry", async () => {
|
|
250
|
+
const { postUnitPreVerification } = await import("../auto-post-unit.ts");
|
|
251
|
+
|
|
252
|
+
const base = makeBrokenIsolatedWorktree();
|
|
253
|
+
const s = new AutoSession();
|
|
254
|
+
s.active = true;
|
|
255
|
+
s.basePath = base;
|
|
256
|
+
s.currentUnit = { type: "research-slice", id: "M003/S03", startedAt: Date.now() };
|
|
257
|
+
s.verificationRetryCount.set("research-slice:M003/S03", 2);
|
|
258
|
+
|
|
259
|
+
const notifications: string[] = [];
|
|
260
|
+
let pauseCalled = false;
|
|
261
|
+
const pctx = {
|
|
262
|
+
s,
|
|
263
|
+
ctx: {
|
|
264
|
+
ui: {
|
|
265
|
+
notify: (message: string) => {
|
|
266
|
+
notifications.push(message);
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
pi: {},
|
|
271
|
+
buildSnapshotOpts: () => ({}) as any,
|
|
272
|
+
lockBase: () => base,
|
|
273
|
+
stopAuto: async () => {},
|
|
274
|
+
pauseAuto: async () => {
|
|
275
|
+
pauseCalled = true;
|
|
276
|
+
},
|
|
277
|
+
updateProgressWidget: () => {},
|
|
278
|
+
} as any;
|
|
279
|
+
|
|
280
|
+
const result = await postUnitPreVerification(pctx, {
|
|
281
|
+
skipSettleDelay: true,
|
|
282
|
+
skipWorktreeSync: true,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
assert.strictEqual(result, "dispatched", "worktree integrity failure must pause instead of retrying");
|
|
286
|
+
assert.strictEqual(pauseCalled, true, "pauseAuto must be called for a broken isolated worktree");
|
|
287
|
+
assert.strictEqual(s.pendingVerificationRetry, null, "pendingVerificationRetry must NOT be set");
|
|
288
|
+
assert.strictEqual(s.verificationRetryCount.has("research-slice:M003/S03"), false, "stale retry count must be cleared");
|
|
289
|
+
assert.ok(
|
|
290
|
+
notifications.some((message) => message.includes("Worktree integrity failure") && message.includes(".git missing")),
|
|
291
|
+
`expected worktree integrity notification, got: ${notifications.join("\n")}`,
|
|
292
|
+
);
|
|
293
|
+
assert.ok(
|
|
294
|
+
notifications.every((message) => !message.includes("Artifact verification failed")),
|
|
295
|
+
`must not surface artifact retry messaging, got: ${notifications.join("\n")}`,
|
|
296
|
+
);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test("pauses when git rev-parse cannot validate an isolated worktree", async () => {
|
|
300
|
+
const { postUnitPreVerification } = await import("../auto-post-unit.ts");
|
|
301
|
+
|
|
302
|
+
const base = makeBrokenIsolatedWorktreeRevParse();
|
|
303
|
+
const s = new AutoSession();
|
|
304
|
+
s.active = true;
|
|
305
|
+
s.basePath = base;
|
|
306
|
+
s.currentUnit = { type: "research-slice", id: "M003/S03", startedAt: Date.now() };
|
|
307
|
+
s.verificationRetryCount.set("research-slice:M003/S03", 2);
|
|
308
|
+
|
|
309
|
+
const notifications: string[] = [];
|
|
310
|
+
let pauseCalled = false;
|
|
311
|
+
const pctx = {
|
|
312
|
+
s,
|
|
313
|
+
ctx: {
|
|
314
|
+
ui: {
|
|
315
|
+
notify: (message: string) => {
|
|
316
|
+
notifications.push(message);
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
pi: {},
|
|
321
|
+
buildSnapshotOpts: () => ({}) as any,
|
|
322
|
+
lockBase: () => base,
|
|
323
|
+
stopAuto: async () => {},
|
|
324
|
+
pauseAuto: async () => {
|
|
325
|
+
pauseCalled = true;
|
|
326
|
+
},
|
|
327
|
+
updateProgressWidget: () => {},
|
|
328
|
+
} as any;
|
|
329
|
+
|
|
330
|
+
const result = await postUnitPreVerification(pctx, {
|
|
331
|
+
skipSettleDelay: true,
|
|
332
|
+
skipWorktreeSync: true,
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
assert.strictEqual(result, "dispatched", "worktree integrity failure must pause instead of retrying");
|
|
336
|
+
assert.strictEqual(pauseCalled, true, "pauseAuto must be called for a broken isolated worktree");
|
|
337
|
+
assert.strictEqual(s.pendingVerificationRetry, null, "pendingVerificationRetry must NOT be set");
|
|
338
|
+
assert.strictEqual(s.verificationRetryCount.has("research-slice:M003/S03"), false, "stale retry count must be cleared");
|
|
339
|
+
assert.ok(
|
|
340
|
+
notifications.some((message) => message.includes("Worktree integrity failure") && message.includes("git rev-parse")),
|
|
341
|
+
`expected git rev-parse worktree integrity notification, got: ${notifications.join("\n")}`,
|
|
342
|
+
);
|
|
343
|
+
assert.ok(
|
|
344
|
+
notifications.every((message) => !message.includes("Artifact verification failed")),
|
|
345
|
+
`must not surface artifact retry messaging, got: ${notifications.join("\n")}`,
|
|
346
|
+
);
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
|
|
234
350
|
// ─── Test 6: Model-quality failures use standard retry path ──────────────────
|
|
235
351
|
|
|
236
352
|
describe("Test 6 — non-deterministic failures use standard retry; tier escalates once (#4973)", () => {
|
|
@@ -129,6 +129,8 @@ function makeMockPi() {
|
|
|
129
129
|
setModelCalls.push(args);
|
|
130
130
|
return true;
|
|
131
131
|
},
|
|
132
|
+
getThinkingLevel: () => "off",
|
|
133
|
+
setThinkingLevel: () => {},
|
|
132
134
|
calls,
|
|
133
135
|
setModelCalls,
|
|
134
136
|
} as any;
|
|
@@ -3353,6 +3355,60 @@ test("runDispatch runs stuck detection while artifact verification retry is pend
|
|
|
3353
3355
|
);
|
|
3354
3356
|
});
|
|
3355
3357
|
|
|
3358
|
+
test("runDispatch falls back to main when dispatch guard cannot read main branch (#5530)", async (t) => {
|
|
3359
|
+
_resetPendingResolve();
|
|
3360
|
+
|
|
3361
|
+
const ctx = makeMockCtx();
|
|
3362
|
+
const pi = makeMockPi();
|
|
3363
|
+
const basePath = mkdtempSync(join(tmpdir(), "gsd-5530-main-branch-fallback-"));
|
|
3364
|
+
t.after(() => rmSync(basePath, { recursive: true, force: true }));
|
|
3365
|
+
|
|
3366
|
+
let guardBranch: string | null = null;
|
|
3367
|
+
const s = makeLoopSession({ basePath });
|
|
3368
|
+
const deps = makeMockDeps({
|
|
3369
|
+
getMainBranch: () => {
|
|
3370
|
+
throw new Error("fatal: detected dubious ownership");
|
|
3371
|
+
},
|
|
3372
|
+
getPriorSliceCompletionBlocker: (_basePath, mainBranch) => {
|
|
3373
|
+
guardBranch = mainBranch;
|
|
3374
|
+
return null;
|
|
3375
|
+
},
|
|
3376
|
+
});
|
|
3377
|
+
|
|
3378
|
+
const result = await runDispatch(
|
|
3379
|
+
{
|
|
3380
|
+
ctx,
|
|
3381
|
+
pi,
|
|
3382
|
+
s,
|
|
3383
|
+
deps,
|
|
3384
|
+
prefs: undefined,
|
|
3385
|
+
iteration: 1,
|
|
3386
|
+
flowId: "test-flow",
|
|
3387
|
+
nextSeq: () => 1,
|
|
3388
|
+
},
|
|
3389
|
+
{
|
|
3390
|
+
state: {
|
|
3391
|
+
phase: "executing",
|
|
3392
|
+
activeMilestone: { id: "M001", title: "Test", status: "active" },
|
|
3393
|
+
activeSlice: { id: "S01", title: "Slice 1" },
|
|
3394
|
+
activeTask: { id: "T01" },
|
|
3395
|
+
registry: [{ id: "M001", status: "active" }],
|
|
3396
|
+
blockers: [],
|
|
3397
|
+
} as any,
|
|
3398
|
+
mid: "M001",
|
|
3399
|
+
midTitle: "Test",
|
|
3400
|
+
},
|
|
3401
|
+
{
|
|
3402
|
+
recentUnits: [],
|
|
3403
|
+
stuckRecoveryAttempts: 0,
|
|
3404
|
+
consecutiveFinalizeTimeouts: 0,
|
|
3405
|
+
},
|
|
3406
|
+
);
|
|
3407
|
+
|
|
3408
|
+
assert.equal(guardBranch, "main");
|
|
3409
|
+
assert.equal(result.action, "next");
|
|
3410
|
+
});
|
|
3411
|
+
|
|
3356
3412
|
test("dispatch Worktree Safety stops unknown unit types with missing Tool Contract", async (t) => {
|
|
3357
3413
|
_resetPendingResolve();
|
|
3358
3414
|
|
|
@@ -288,6 +288,51 @@ test("advance() stops when dispatch has no next unit", async () => {
|
|
|
288
288
|
assert.equal(orchestrator.getStatus().phase, "stopped");
|
|
289
289
|
});
|
|
290
290
|
|
|
291
|
+
test("advance() surfaces dispatch blocker reason instead of generic no remaining units", async () => {
|
|
292
|
+
const { deps, calls } = makeDeps({
|
|
293
|
+
dispatch: {
|
|
294
|
+
async decideNextUnit() {
|
|
295
|
+
return {
|
|
296
|
+
kind: "blocked",
|
|
297
|
+
reason: "Milestone M001 validation verdict is needs-remediation but all slices are complete.",
|
|
298
|
+
action: "pause",
|
|
299
|
+
};
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
304
|
+
|
|
305
|
+
const result = await orchestrator.advance();
|
|
306
|
+
|
|
307
|
+
assert.equal(result.kind, "blocked");
|
|
308
|
+
if (result.kind !== "blocked") return;
|
|
309
|
+
assert.equal(result.reason, "Milestone M001 validation verdict is needs-remediation but all slices are complete.");
|
|
310
|
+
assert.equal(result.action, "pause");
|
|
311
|
+
assert.ok(calls.includes("journal:advance-blocked"));
|
|
312
|
+
assert.ok(!calls.includes("journal:advance-stopped"));
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
test("resume() returns blocked when advance detects a dispatch blocker", async () => {
|
|
316
|
+
const { deps } = makeDeps({
|
|
317
|
+
dispatch: {
|
|
318
|
+
async decideNextUnit() {
|
|
319
|
+
return {
|
|
320
|
+
kind: "blocked",
|
|
321
|
+
reason: "remediation required",
|
|
322
|
+
action: "pause",
|
|
323
|
+
};
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
328
|
+
|
|
329
|
+
const result = await orchestrator.resume();
|
|
330
|
+
|
|
331
|
+
assert.equal(result.kind, "blocked");
|
|
332
|
+
if (result.kind !== "blocked") return;
|
|
333
|
+
assert.equal(result.reason, "remediation required");
|
|
334
|
+
});
|
|
335
|
+
|
|
291
336
|
test("advance() uses recovery on error", async () => {
|
|
292
337
|
const { deps, calls } = makeDeps({
|
|
293
338
|
runtime: {
|
|
@@ -797,7 +842,9 @@ test("wired DispatchAdapter forwards session-derived dispatch inputs identically
|
|
|
797
842
|
assert.equal(adapterCtx.midTitle, directCtx.midTitle);
|
|
798
843
|
|
|
799
844
|
// Dispatch action equality: both flows reach the same dispatch decision.
|
|
800
|
-
|
|
845
|
+
if (!adapterResult || !("unitType" in adapterResult)) {
|
|
846
|
+
assert.fail("expected adapter result to be a dispatch decision");
|
|
847
|
+
}
|
|
801
848
|
assert.equal(adapterResult.unitType, "execute-task");
|
|
802
849
|
assert.equal(adapterResult.unitId, "T01");
|
|
803
850
|
assert.equal(adapterResult.reason, "test-capture");
|
|
@@ -872,3 +919,35 @@ test("wired DispatchAdapter prefers caller-supplied dispatch inputs over ctx-der
|
|
|
872
919
|
resetRegistry();
|
|
873
920
|
}
|
|
874
921
|
});
|
|
922
|
+
|
|
923
|
+
test("wired DispatchAdapter preserves stop reason as a blocked decision", async () => {
|
|
924
|
+
const stateSnapshot = makeState();
|
|
925
|
+
const stopRule: UnifiedRule = {
|
|
926
|
+
name: "test-stop",
|
|
927
|
+
when: "dispatch",
|
|
928
|
+
evaluation: "first-match",
|
|
929
|
+
where: async () => ({
|
|
930
|
+
action: "stop" as const,
|
|
931
|
+
reason: "remediation blocker",
|
|
932
|
+
level: "warning" as const,
|
|
933
|
+
}),
|
|
934
|
+
then: (r: unknown) => r,
|
|
935
|
+
};
|
|
936
|
+
setRegistry(new RuleRegistry([stopRule]));
|
|
937
|
+
|
|
938
|
+
try {
|
|
939
|
+
const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as any;
|
|
940
|
+
const pi = { getActiveTools: () => [] } as any;
|
|
941
|
+
const adapter = createWiredDispatchAdapter(ctx, pi, "/tmp/parity-fixture");
|
|
942
|
+
|
|
943
|
+
const result = await adapter.decideNextUnit({ stateSnapshot });
|
|
944
|
+
|
|
945
|
+
assert.deepEqual(result, {
|
|
946
|
+
kind: "blocked",
|
|
947
|
+
reason: "remediation blocker",
|
|
948
|
+
action: "pause",
|
|
949
|
+
});
|
|
950
|
+
} finally {
|
|
951
|
+
resetRegistry();
|
|
952
|
+
}
|
|
953
|
+
});
|
|
@@ -6,7 +6,7 @@ import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "nod
|
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
|
|
9
|
-
import { cleanupAfterLoopExit, rerootCommandSession, stopAuto } from "../auto.ts";
|
|
9
|
+
import { cleanupAfterLoopExit, pauseAuto, rerootCommandSession, stopAuto } from "../auto.ts";
|
|
10
10
|
import { autoSession } from "../auto-runtime-state.ts";
|
|
11
11
|
import { closeDatabase, insertMilestone, insertSlice, openDatabase } from "../gsd-db.ts";
|
|
12
12
|
import { WorktreeLifecycle } from "../worktree-lifecycle.ts";
|
|
@@ -43,7 +43,7 @@ test("cleanupAfterLoopExit preserves paused auto badge after provider pause", as
|
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
test("cleanupAfterLoopExit clears status without replacing
|
|
46
|
+
test("cleanupAfterLoopExit clears status and progress widget without replacing outcome surface", async () => {
|
|
47
47
|
const statusCalls: unknown[] = [];
|
|
48
48
|
const widgetCalls: unknown[] = [];
|
|
49
49
|
|
|
@@ -64,8 +64,8 @@ test("cleanupAfterLoopExit clears status without replacing the last auto surface
|
|
|
64
64
|
assert.deepEqual(statusCalls, [["gsd-auto", undefined]]);
|
|
65
65
|
assert.equal(
|
|
66
66
|
widgetCalls.some((args) => Array.isArray(args) && args[0] === "gsd-progress" && args[1] === undefined),
|
|
67
|
-
|
|
68
|
-
"cleanup must
|
|
67
|
+
true,
|
|
68
|
+
"cleanup must clear the stale auto progress widget",
|
|
69
69
|
);
|
|
70
70
|
assert.equal(
|
|
71
71
|
widgetCalls.some((args) => Array.isArray(args) && args[0] === "gsd-outcome"),
|
|
@@ -79,7 +79,7 @@ test("cleanupAfterLoopExit clears status without replacing the last auto surface
|
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
test("cleanupAfterLoopExit
|
|
82
|
+
test("cleanupAfterLoopExit clears progress widget after stopAuto reset", async () => {
|
|
83
83
|
const statusCalls: unknown[] = [];
|
|
84
84
|
const widgetCalls: unknown[] = [];
|
|
85
85
|
|
|
@@ -103,8 +103,8 @@ test("cleanupAfterLoopExit preserves completion roll-up after stopAuto reset", a
|
|
|
103
103
|
assert.deepEqual(statusCalls, [["gsd-auto", undefined]]);
|
|
104
104
|
assert.equal(
|
|
105
105
|
widgetCalls.some((args) => Array.isArray(args) && args[0] === "gsd-progress" && args[1] === undefined),
|
|
106
|
-
|
|
107
|
-
"completion cleanup must
|
|
106
|
+
true,
|
|
107
|
+
"completion cleanup must clear the stale progress widget",
|
|
108
108
|
);
|
|
109
109
|
assert.equal(
|
|
110
110
|
widgetCalls.some((args) => Array.isArray(args) && args[0] === "gsd-outcome"),
|
|
@@ -117,6 +117,34 @@ test("cleanupAfterLoopExit preserves completion roll-up after stopAuto reset", a
|
|
|
117
117
|
}
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
+
test("pauseAuto preserves artifact retry counts across pause/resume", async () => {
|
|
121
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-pause-retry-count-"));
|
|
122
|
+
const previousCwd = process.cwd();
|
|
123
|
+
const retryKey = "execute-task:M001/S01/T01";
|
|
124
|
+
|
|
125
|
+
autoSession.reset();
|
|
126
|
+
autoSession.active = true;
|
|
127
|
+
autoSession.verificationRetryCount.set(retryKey, 2);
|
|
128
|
+
autoSession.pendingVerificationRetry = {
|
|
129
|
+
unitId: "M001/S01/T01",
|
|
130
|
+
failureContext: "Missing expected artifact (attempt 2/3).",
|
|
131
|
+
attempt: 2,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
process.chdir(base);
|
|
136
|
+
await pauseAuto();
|
|
137
|
+
|
|
138
|
+
assert.equal(autoSession.paused, true);
|
|
139
|
+
assert.equal(autoSession.pendingVerificationRetry, null);
|
|
140
|
+
assert.equal(autoSession.verificationRetryCount.get(retryKey), 2);
|
|
141
|
+
} finally {
|
|
142
|
+
autoSession.reset();
|
|
143
|
+
process.chdir(previousCwd);
|
|
144
|
+
rmSync(base, { recursive: true, force: true });
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
120
148
|
test("cleanupAfterLoopExit restores project root through lifecycle and preserves chdir", async (t) => {
|
|
121
149
|
const base = mkdtempSync(join(tmpdir(), "gsd-cleanup-lifecycle-"));
|
|
122
150
|
const worktree = join(base, ".gsd", "worktrees", "M001");
|
|
@@ -62,7 +62,11 @@ async function runSuccessfulFinalize(s: AutoSession) {
|
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
async function runFinalizeWithDeps(
|
|
65
|
+
async function runFinalizeWithDeps(
|
|
66
|
+
s: AutoSession,
|
|
67
|
+
depsOverrides: Record<string, unknown>,
|
|
68
|
+
ctxOverride?: Record<string, unknown>,
|
|
69
|
+
) {
|
|
66
70
|
const unit = s.currentUnit;
|
|
67
71
|
assert.ok(unit, "test setup must provide currentUnit");
|
|
68
72
|
|
|
@@ -86,7 +90,7 @@ async function runFinalizeWithDeps(s: AutoSession, depsOverrides: Record<string,
|
|
|
86
90
|
|
|
87
91
|
return runFinalize(
|
|
88
92
|
{
|
|
89
|
-
ctx: { ui: { notify() {} } },
|
|
93
|
+
ctx: ctxOverride ?? { ui: { notify() {} } },
|
|
90
94
|
pi: {},
|
|
91
95
|
s,
|
|
92
96
|
deps,
|
|
@@ -223,3 +227,50 @@ test("runFinalize merges a verified complete-milestone immediately and only once
|
|
|
223
227
|
assert.equal(lifecycleMergeCalls, 1);
|
|
224
228
|
assert.equal(resolverMergeCalls, 0);
|
|
225
229
|
});
|
|
230
|
+
|
|
231
|
+
test("runFinalize does not render next-phase handoff for complete-milestone", async (t) => {
|
|
232
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-finalize-complete-handoff-"));
|
|
233
|
+
t.after(() => {
|
|
234
|
+
rmSync(base, { recursive: true, force: true });
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const s = new AutoSession();
|
|
238
|
+
const widgetCalls: Array<[string, unknown]> = [];
|
|
239
|
+
s.basePath = base;
|
|
240
|
+
s.originalBasePath = base;
|
|
241
|
+
s.currentMilestoneId = "M001";
|
|
242
|
+
s.currentUnit = {
|
|
243
|
+
type: "complete-milestone",
|
|
244
|
+
id: "M001",
|
|
245
|
+
startedAt: Date.now(),
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const result = await runFinalizeWithDeps(
|
|
249
|
+
s,
|
|
250
|
+
{
|
|
251
|
+
preflightCleanRoot: () => ({ stashPushed: false }),
|
|
252
|
+
postflightPopStash: () => ({ needsManualRecovery: false }),
|
|
253
|
+
lifecycle: {
|
|
254
|
+
exitMilestone() {
|
|
255
|
+
return { ok: true, merged: true, codeFilesChanged: false };
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
hasUI: true,
|
|
261
|
+
ui: {
|
|
262
|
+
notify() {},
|
|
263
|
+
setWidget(key: string, value: unknown) {
|
|
264
|
+
widgetCalls.push([key, value]);
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
assert.equal(result.action, "next");
|
|
271
|
+
assert.equal(
|
|
272
|
+
widgetCalls.some(([key]) => key === "gsd-outcome"),
|
|
273
|
+
false,
|
|
274
|
+
"complete-milestone finalize should leave terminal completion UI to stopAuto",
|
|
275
|
+
);
|
|
276
|
+
});
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
import test from "node:test";
|
|
4
4
|
import assert from "node:assert/strict";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
buildStepCompleteMessage,
|
|
8
|
+
shouldReturnStepWizardAfterUnit,
|
|
9
|
+
STEP_COMPLETE_FALLBACK_MESSAGE,
|
|
10
|
+
} from "../auto-post-unit.ts";
|
|
7
11
|
import type { GSDState } from "../types.ts";
|
|
8
12
|
|
|
9
13
|
function makeState(overrides: Partial<GSDState>): GSDState {
|
|
@@ -51,3 +55,10 @@ test("STEP_COMPLETE_FALLBACK_MESSAGE: used when deriveState throws, still points
|
|
|
51
55
|
assert.match(STEP_COMPLETE_FALLBACK_MESSAGE, /\/clear/);
|
|
52
56
|
assert.match(STEP_COMPLETE_FALLBACK_MESSAGE, /\/gsd/);
|
|
53
57
|
});
|
|
58
|
+
|
|
59
|
+
test("shouldReturnStepWizardAfterUnit: terminal milestone completion continues to merge-back path", () => {
|
|
60
|
+
assert.equal(shouldReturnStepWizardAfterUnit("complete-milestone", "complete"), false);
|
|
61
|
+
assert.equal(shouldReturnStepWizardAfterUnit("complete-milestone", null), false);
|
|
62
|
+
assert.equal(shouldReturnStepWizardAfterUnit("execute-task", "complete"), false);
|
|
63
|
+
assert.equal(shouldReturnStepWizardAfterUnit("execute-task", "executing"), true);
|
|
64
|
+
});
|