gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.8b8d129d7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -18
- package/dist/cli.js +20 -9
- package/dist/headless.js +9 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +110 -37
- package/dist/resources/extensions/gsd/auto/orchestrator.js +12 -1
- package/dist/resources/extensions/gsd/auto/phases.js +97 -38
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +278 -137
- package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
- package/dist/resources/extensions/gsd/auto-recovery.js +79 -14
- package/dist/resources/extensions/gsd/auto-start.js +87 -14
- package/dist/resources/extensions/gsd/auto-timers.js +11 -3
- package/dist/resources/extensions/gsd/auto-verification.js +102 -34
- package/dist/resources/extensions/gsd/auto-worktree.js +178 -11
- package/dist/resources/extensions/gsd/auto.js +98 -54
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +5 -4
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +43 -5
- package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
- package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
- package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor.js +2 -28
- package/dist/resources/extensions/gsd/export-html.js +27 -425
- package/dist/resources/extensions/gsd/forensics.js +8 -3
- package/dist/resources/extensions/gsd/git-service.js +138 -10
- package/dist/resources/extensions/gsd/gsd-db.js +76 -33
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +110 -117
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/init-wizard.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -8
- package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
- package/dist/resources/extensions/gsd/pre-execution-checks.js +38 -11
- package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +138 -0
- package/dist/resources/extensions/gsd/preferences.js +2 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/repository-registry.js +44 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +59 -2
- package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
- package/dist/resources/extensions/gsd/state.js +14 -4
- package/dist/resources/extensions/gsd/status-guards.js +14 -2
- package/dist/resources/extensions/gsd/templates/plan.md +9 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
- package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +36 -17
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +142 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/shared/interview-ui.js +6 -4
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- package/dist/resources/skills/forensics/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -7
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
- package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/package.json +4 -4
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +13 -4
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +106 -27
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/src/tui.ts +108 -27
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +10 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +17 -6
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +111 -38
- package/src/resources/extensions/gsd/auto/orchestrator.ts +12 -1
- package/src/resources/extensions/gsd/auto/phases.ts +115 -49
- package/src/resources/extensions/gsd/auto/session.ts +16 -0
- package/src/resources/extensions/gsd/auto/types.ts +3 -0
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +21 -19
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +312 -148
- package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
- package/src/resources/extensions/gsd/auto-recovery.ts +83 -11
- package/src/resources/extensions/gsd/auto-start.ts +94 -12
- package/src/resources/extensions/gsd/auto-timers.ts +10 -3
- package/src/resources/extensions/gsd/auto-verification.ts +124 -42
- package/src/resources/extensions/gsd/auto-worktree.ts +195 -11
- package/src/resources/extensions/gsd/auto.ts +91 -42
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +5 -4
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- package/src/resources/extensions/gsd/crash-recovery.ts +44 -4
- package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
- package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
- package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -27
- package/src/resources/extensions/gsd/export-html.ts +27 -427
- package/src/resources/extensions/gsd/forensics.ts +7 -3
- package/src/resources/extensions/gsd/git-service.ts +166 -11
- package/src/resources/extensions/gsd/gsd-db.ts +80 -31
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +142 -134
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/init-wizard.ts +17 -2
- package/src/resources/extensions/gsd/journal.ts +8 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +10 -8
- package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
- package/src/resources/extensions/gsd/pre-execution-checks.ts +49 -11
- package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
- package/src/resources/extensions/gsd/preferences-types.ts +33 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +145 -0
- package/src/resources/extensions/gsd/preferences.ts +5 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/repository-registry.ts +77 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +52 -1
- package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
- package/src/resources/extensions/gsd/state.ts +15 -4
- package/src/resources/extensions/gsd/status-guards.ts +16 -2
- package/src/resources/extensions/gsd/templates/plan.md +9 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +300 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +174 -8
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +129 -6
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +86 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +199 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
- package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +72 -1
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +128 -9
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +173 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +51 -18
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +170 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
- package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/shared/interview-ui.ts +6 -4
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/src/resources/skills/forensics/SKILL.md +1 -1
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → _kljR-_Miq_YV1IW0wpRO}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → _kljR-_Miq_YV1IW0wpRO}/_ssgManifest.js +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Main auto-mode execution loop.
|
|
1
3
|
/**
|
|
2
4
|
* auto/loop.ts — Main auto-mode execution loop.
|
|
3
5
|
*
|
|
@@ -35,7 +37,7 @@ import { createWorkflowTurnReporter } from "./workflow-turn-reporter.js";
|
|
|
35
37
|
import { validateWorkflowSessionLock } from "./workflow-session-lock.js";
|
|
36
38
|
import { dequeueSidecarItem } from "./workflow-sidecar-queue.js";
|
|
37
39
|
import { maintainWorkerHeartbeat } from "./workflow-worker-heartbeat.js";
|
|
38
|
-
import { measureMemoryPressure } from "./workflow-memory-pressure.js";
|
|
40
|
+
import { measureMemoryPressure, shouldCheckMemoryPressure, } from "./workflow-memory-pressure.js";
|
|
39
41
|
import { buildSidecarIterationData } from "./workflow-sidecar-iteration.js";
|
|
40
42
|
import { createExecutionGraphUnitDispatchDeps, runUnitPhaseViaContract, } from "./workflow-unit-dispatch.js";
|
|
41
43
|
import { handleCustomEngineDispatchOutcome } from "./workflow-custom-engine-dispatch-outcome.js";
|
|
@@ -130,9 +132,9 @@ function logCustomVerifyRetrySaveFailure(err) {
|
|
|
130
132
|
});
|
|
131
133
|
}
|
|
132
134
|
// ── Memory pressure monitoring (#3331) ──────────────────────────────────
|
|
133
|
-
// Check heap usage every N iterations and trigger
|
|
134
|
-
// the OS OOM killer sends SIGKILL. The threshold is
|
|
135
|
-
// limit (--max-old-space-size or default ~1.5-4GB depending on platform).
|
|
135
|
+
// Check heap usage on session startup, then every N iterations, and trigger
|
|
136
|
+
// graceful shutdown before the OS OOM killer sends SIGKILL. The threshold is
|
|
137
|
+
// 90% of the V8 heap limit (--max-old-space-size or default ~1.5-4GB depending on platform).
|
|
136
138
|
const MEMORY_CHECK_INTERVAL = 5; // check every 5 iterations
|
|
137
139
|
const MAX_CUSTOM_ENGINE_VERIFY_RETRIES = 3;
|
|
138
140
|
async function enforceMinRequestInterval(s, prefs) {
|
|
@@ -184,6 +186,9 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
184
186
|
recentUnits: persisted.recentUnits,
|
|
185
187
|
stuckRecoveryAttempts: persisted.stuckRecoveryAttempts,
|
|
186
188
|
consecutiveFinalizeTimeouts: 0,
|
|
189
|
+
consecutiveDispatchCount: new Map(),
|
|
190
|
+
lastDispatchedKey: null,
|
|
191
|
+
lastDispatchPhase: null,
|
|
187
192
|
};
|
|
188
193
|
let consecutiveErrors = 0;
|
|
189
194
|
let consecutiveCooldowns = 0;
|
|
@@ -262,7 +267,7 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
262
267
|
}
|
|
263
268
|
// ── Memory pressure check (#3331) ──
|
|
264
269
|
// Graceful shutdown before OOM killer sends SIGKILL.
|
|
265
|
-
if (iteration
|
|
270
|
+
if (shouldCheckMemoryPressure(iteration, MEMORY_CHECK_INTERVAL)) {
|
|
266
271
|
const mem = measureMemoryPressure();
|
|
267
272
|
debugLog("autoLoop", { phase: "memory-check", ...mem });
|
|
268
273
|
const memoryDecision = decideMemoryPressure({ ...mem, iteration });
|
|
@@ -307,9 +312,11 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
307
312
|
logIterationComplete: () => debugLog("autoLoop", { phase: "iteration-complete", iteration }),
|
|
308
313
|
});
|
|
309
314
|
};
|
|
315
|
+
let stuckStatePersistedThisIteration = false;
|
|
310
316
|
const finishIncompleteIteration = (details) => {
|
|
311
317
|
emitIterationEnd(details);
|
|
312
318
|
saveStuckState(s, loopState);
|
|
319
|
+
stuckStatePersistedThisIteration = true;
|
|
313
320
|
};
|
|
314
321
|
try {
|
|
315
322
|
// ── Blanket try/catch: one bad iteration must not kill the session
|
|
@@ -596,39 +603,87 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
596
603
|
continue;
|
|
597
604
|
}
|
|
598
605
|
if (!sidecarItem) {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
606
|
+
const orchestration = s.orchestration;
|
|
607
|
+
if (orchestration) {
|
|
608
|
+
const orchestrationResult = await orchestration.advance();
|
|
609
|
+
if (orchestrationResult.kind === "blocked") {
|
|
610
|
+
s.pendingOrchestrationDispatch = null;
|
|
611
|
+
if (orchestrationResult.action === "pause") {
|
|
612
|
+
await deps.pauseAuto(ctx, pi, {
|
|
613
|
+
message: orchestrationResult.reason,
|
|
614
|
+
category: "unknown",
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
await deps.stopAuto(ctx, pi, orchestrationResult.reason);
|
|
619
|
+
}
|
|
620
|
+
finishTurn("stopped", "manual-attention", "orchestration-blocked");
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
623
|
+
if (orchestrationResult.kind === "stopped") {
|
|
624
|
+
s.pendingOrchestrationDispatch = null;
|
|
625
|
+
await deps.stopAuto(ctx, pi, orchestrationResult.reason);
|
|
626
|
+
finishTurn("stopped", "manual-attention", "orchestration-stopped");
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
629
|
+
if (orchestrationResult.kind !== "advanced") {
|
|
630
|
+
s.pendingOrchestrationDispatch = null;
|
|
631
|
+
finishTurn("skipped");
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
const pendingDispatch = s.pendingOrchestrationDispatch;
|
|
635
|
+
iterData = {
|
|
636
|
+
unitType: pendingDispatch?.unitType ?? orchestrationResult.unit.unitType,
|
|
637
|
+
unitId: pendingDispatch?.unitId ?? orchestrationResult.unit.unitId,
|
|
638
|
+
prompt: pendingDispatch?.prompt ?? "",
|
|
639
|
+
finalPrompt: pendingDispatch?.prompt ?? "",
|
|
640
|
+
pauseAfterUatDispatch: pendingDispatch?.pauseAfterUatDispatch ?? false,
|
|
641
|
+
state: pendingDispatch?.state ?? orchestrationResult.stateSnapshot,
|
|
642
|
+
mid: pendingDispatch?.mid ?? s.currentMilestoneId ?? "workflow",
|
|
643
|
+
midTitle: pendingDispatch?.midTitle ?? orchestrationResult.stateSnapshot.activeMilestone?.title ?? "Workflow",
|
|
644
|
+
isRetry: false,
|
|
645
|
+
previousTier: undefined,
|
|
646
|
+
};
|
|
647
|
+
s.pendingOrchestrationDispatch = null;
|
|
648
|
+
phaseReporter.report("dispatch", "next", {
|
|
649
|
+
unitType: iterData.unitType,
|
|
650
|
+
unitId: iterData.unitId,
|
|
651
|
+
});
|
|
652
|
+
observedUnitType = iterData.unitType;
|
|
653
|
+
observedUnitId = iterData.unitId;
|
|
624
654
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
655
|
+
else {
|
|
656
|
+
const preDispatchResult = await runPreDispatch(ic, loopState);
|
|
657
|
+
phaseReporter.report("pre-dispatch", preDispatchResult.action);
|
|
658
|
+
if (preDispatchResult.action === "break") {
|
|
659
|
+
finishTurn("stopped", "manual-attention", "pre-dispatch-break");
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
662
|
+
if (preDispatchResult.action === "continue") {
|
|
663
|
+
finishTurn("skipped");
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
const preData = preDispatchResult.data;
|
|
667
|
+
const guardsResult = await runGuards(ic, preData.mid);
|
|
668
|
+
phaseReporter.report("guard", guardsResult.action);
|
|
669
|
+
if (guardsResult.action === "break") {
|
|
670
|
+
finishTurn("stopped", "manual-attention", "guard-break");
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
const dispatchResult = await runDispatch(ic, preData, loopState);
|
|
674
|
+
phaseReporter.report("dispatch", dispatchResult.action);
|
|
675
|
+
if (dispatchResult.action === "break") {
|
|
676
|
+
finishTurn("stopped", "manual-attention", "dispatch-break");
|
|
677
|
+
break;
|
|
678
|
+
}
|
|
679
|
+
if (dispatchResult.action === "continue") {
|
|
680
|
+
finishTurn("skipped");
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
iterData = dispatchResult.data;
|
|
684
|
+
observedUnitType = iterData.unitType;
|
|
685
|
+
observedUnitId = iterData.unitId;
|
|
628
686
|
}
|
|
629
|
-
iterData = dispatchResult.data;
|
|
630
|
-
observedUnitType = iterData.unitType;
|
|
631
|
-
observedUnitId = iterData.unitId;
|
|
632
687
|
}
|
|
633
688
|
else {
|
|
634
689
|
iterData = await buildSidecarIterationData({
|
|
@@ -789,11 +844,18 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
789
844
|
unitId: iterData.unitId,
|
|
790
845
|
});
|
|
791
846
|
const finalizeReason = finalizeResult.action === "break" ? finalizeResult.reason : undefined;
|
|
847
|
+
const finalizeStatus = finalizeReason === "step-wizard"
|
|
848
|
+
? "completed"
|
|
849
|
+
: finalizeResult.action === "next"
|
|
850
|
+
? "completed"
|
|
851
|
+
: finalizeResult.action === "continue"
|
|
852
|
+
? "retry"
|
|
853
|
+
: "stopped";
|
|
792
854
|
journalReporter.emit("post-unit-finalize-end", {
|
|
793
855
|
iteration,
|
|
794
856
|
unitType: iterData.unitType,
|
|
795
857
|
unitId: iterData.unitId,
|
|
796
|
-
status:
|
|
858
|
+
status: finalizeStatus,
|
|
797
859
|
action: finalizeResult.action,
|
|
798
860
|
...(finalizeReason ? { reason: finalizeReason } : {}),
|
|
799
861
|
});
|
|
@@ -825,6 +887,7 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
825
887
|
finishIncompleteIteration({
|
|
826
888
|
status: "retry",
|
|
827
889
|
reason: "finalize-retry",
|
|
890
|
+
retry: true,
|
|
828
891
|
unitType: iterData.unitType,
|
|
829
892
|
unitId: iterData.unitId,
|
|
830
893
|
});
|
|
@@ -836,7 +899,12 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
836
899
|
logWriteFailure: logDispatchLedgerWriteFailure,
|
|
837
900
|
}) || dispatchSettled;
|
|
838
901
|
completeIteration();
|
|
902
|
+
stuckStatePersistedThisIteration = true;
|
|
839
903
|
finishTurn("completed");
|
|
904
|
+
if (finalizeDecision.action === "complete-and-break") {
|
|
905
|
+
s.preserveStepSurfaceAfterLoopExit = true;
|
|
906
|
+
break;
|
|
907
|
+
}
|
|
840
908
|
}
|
|
841
909
|
catch (loopErr) {
|
|
842
910
|
// ── Blanket catch: absorb unexpected exceptions, apply graduated recovery ──
|
|
@@ -974,6 +1042,11 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
974
1042
|
}
|
|
975
1043
|
finishTurn(errorDecision.turnStatus, "execution", msg);
|
|
976
1044
|
}
|
|
1045
|
+
finally {
|
|
1046
|
+
if (!stuckStatePersistedThisIteration) {
|
|
1047
|
+
saveStuckState(s, loopState);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
977
1050
|
}
|
|
978
1051
|
_clearCurrentResolve();
|
|
979
1052
|
debugLog("autoLoop", { phase: "exit", totalIterations: iteration });
|
|
@@ -45,7 +45,7 @@ export class AutoOrchestrator {
|
|
|
45
45
|
rationale: "resource version guard blocked dispatch",
|
|
46
46
|
findings: staleMsg,
|
|
47
47
|
});
|
|
48
|
-
const blocked = { kind: "blocked", reason: staleMsg, action: "
|
|
48
|
+
const blocked = { kind: "blocked", reason: staleMsg, action: "pause" };
|
|
49
49
|
await this.deps.runtime.journalTransition({ name: "advance-blocked", reason: blocked.reason });
|
|
50
50
|
await this.deps.health.postAdvanceRecord(blocked);
|
|
51
51
|
return blocked;
|
|
@@ -117,6 +117,17 @@ export class AutoOrchestrator {
|
|
|
117
117
|
await this.deps.health.postAdvanceRecord(stopped);
|
|
118
118
|
return stopped;
|
|
119
119
|
}
|
|
120
|
+
if (!("unitType" in decision)) {
|
|
121
|
+
const blocked = {
|
|
122
|
+
kind: "blocked",
|
|
123
|
+
reason: decision.reason,
|
|
124
|
+
action: decision.action,
|
|
125
|
+
stateSnapshot: reconciliation.stateSnapshot,
|
|
126
|
+
};
|
|
127
|
+
await this.deps.runtime.journalTransition({ name: "advance-blocked", reason: blocked.reason });
|
|
128
|
+
await this.deps.health.postAdvanceRecord(blocked);
|
|
129
|
+
return blocked;
|
|
130
|
+
}
|
|
120
131
|
const nextKey = `${decision.unitType}:${decision.unitId}`;
|
|
121
132
|
// Record every dispatch decision in the ring buffer before pre-flight
|
|
122
133
|
// checks so the stuck-loop detector observes the full decision history
|
|
@@ -44,6 +44,8 @@ import { resolveManifest } from "../unit-context-manifest.js";
|
|
|
44
44
|
import { createWorktreeSafetyModule } from "../worktree-safety.js";
|
|
45
45
|
import { isSuspiciousGhostCompletion } from "../auto-unit-closeout.js";
|
|
46
46
|
import { decideVerificationRetry, verificationRetryKey } from "./verification-retry-policy.js";
|
|
47
|
+
import { buildPhaseHandoffOutcome, setAutoOutcomeWidget } from "../auto-dashboard.js";
|
|
48
|
+
import { getConsecutiveDispatchBlocker } from "../dispatch-guard.js";
|
|
47
49
|
// ─── Path Comparison Helper ───────────────────────────────────────────────
|
|
48
50
|
/** Compare two paths for physical identity, tolerating trailing slashes and symlinks. */
|
|
49
51
|
function isSamePathLocal(a, b) {
|
|
@@ -103,6 +105,12 @@ function unitWritesSource(unitType) {
|
|
|
103
105
|
function formatWorktreeSafetyFailure(result) {
|
|
104
106
|
return `Worktree Safety failed (${result.kind}): ${result.reason} ${result.remediation}`;
|
|
105
107
|
}
|
|
108
|
+
function formatWorktreeSafetyStopReason(result) {
|
|
109
|
+
if (result.kind === "empty-worktree-with-project-content") {
|
|
110
|
+
return `Worktree Safety failed (${result.kind}). Run /gsd doctor fix, then /gsd auto.`;
|
|
111
|
+
}
|
|
112
|
+
return `Worktree Safety failed (${result.kind}).`;
|
|
113
|
+
}
|
|
106
114
|
function resolveEmptyWorktreeWithProjectContent(unitRoot, projectRoot) {
|
|
107
115
|
if (isSamePathLocal(unitRoot, projectRoot))
|
|
108
116
|
return false;
|
|
@@ -176,7 +184,7 @@ async function validateSourceWriteWorktreeSafety(ic, unitType, unitId, milestone
|
|
|
176
184
|
projectRoot,
|
|
177
185
|
});
|
|
178
186
|
ctx.ui.notify(msg, "error");
|
|
179
|
-
await deps.stopAuto(ctx, pi,
|
|
187
|
+
await deps.stopAuto(ctx, pi, formatWorktreeSafetyStopReason(result));
|
|
180
188
|
return { action: "break", reason: result.kind };
|
|
181
189
|
}
|
|
182
190
|
// ─── Session timeout auto-resume state ────────────────────────────────────────
|
|
@@ -968,12 +976,25 @@ export async function runDispatch(ic, preData, loopState) {
|
|
|
968
976
|
prompt = preDispatchResult.prompt;
|
|
969
977
|
}
|
|
970
978
|
const guardBasePath = _resolveDispatchGuardBasePath(s);
|
|
971
|
-
|
|
979
|
+
let mainBranch = "main";
|
|
980
|
+
try {
|
|
981
|
+
mainBranch = deps.getMainBranch(guardBasePath);
|
|
982
|
+
}
|
|
983
|
+
catch (err) {
|
|
984
|
+
debugLog("autoLoop", { phase: "getMainBranch-failed", error: String(err) });
|
|
985
|
+
}
|
|
986
|
+
const priorSliceBlocker = deps.getPriorSliceCompletionBlocker(guardBasePath, mainBranch, unitType, unitId);
|
|
972
987
|
if (priorSliceBlocker) {
|
|
973
988
|
await deps.stopAuto(ctx, pi, priorSliceBlocker);
|
|
974
989
|
debugLog("autoLoop", { phase: "exit", reason: "prior-slice-blocker" });
|
|
975
990
|
return { action: "break", reason: "prior-slice-blocker" };
|
|
976
991
|
}
|
|
992
|
+
const consecutiveDispatchBlocker = getConsecutiveDispatchBlocker(loopState, state.phase, unitType, unitId);
|
|
993
|
+
if (consecutiveDispatchBlocker) {
|
|
994
|
+
await deps.stopAuto(ctx, pi, consecutiveDispatchBlocker);
|
|
995
|
+
debugLog("autoLoop", { phase: "exit", reason: "consecutive-dispatch-blocker" });
|
|
996
|
+
return { action: "break", reason: "consecutive-dispatch-blocker" };
|
|
997
|
+
}
|
|
977
998
|
const worktreeSafetyBlock = await validateSourceWriteWorktreeSafety(ic, unitType, unitId, mid, "pre-dispatch");
|
|
978
999
|
if (worktreeSafetyBlock)
|
|
979
1000
|
return worktreeSafetyBlock;
|
|
@@ -1030,7 +1051,6 @@ export async function runDispatch(ic, preData, loopState) {
|
|
|
1030
1051
|
ctx.ui.notify(`Stuck recovery: artifact for ${unitType} ${unitId} found on disk. Invalidating caches.`, "info");
|
|
1031
1052
|
deps.invalidateAllCaches();
|
|
1032
1053
|
loopState.recentUnits.length = 0;
|
|
1033
|
-
loopState.stuckRecoveryAttempts = 0;
|
|
1034
1054
|
return { action: "continue" };
|
|
1035
1055
|
}
|
|
1036
1056
|
ctx.ui.notify(`Stuck on ${unitType} ${unitId} (${stuckSignal.reason}). Invalidating caches and retrying.`, "warning");
|
|
@@ -1324,35 +1344,8 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1324
1344
|
s.currentUnit.type === unitType &&
|
|
1325
1345
|
s.currentUnit.id === unitId);
|
|
1326
1346
|
const previousTier = s.currentUnitRouting?.tier;
|
|
1327
|
-
// Scope workflow-logger buffer to this unit so post-finalize drains are
|
|
1328
|
-
// per-unit. Without this, the module-level _buffer accumulates across every
|
|
1329
|
-
// unit in the same Node process (see workflow-logger.ts module header).
|
|
1330
|
-
_resetLogs();
|
|
1331
1347
|
const dispatchKey = `${unitType}/${unitId}`;
|
|
1332
|
-
|
|
1333
|
-
s.currentUnit = { type: unitType, id: unitId, startedAt: Date.now() };
|
|
1334
|
-
s.lastGitActionFailure = null;
|
|
1335
|
-
s.lastGitActionStatus = null;
|
|
1336
|
-
s.lastUnitAgentEndMessages = null;
|
|
1337
|
-
setCurrentPhase(unitType, {
|
|
1338
|
-
basePath: s.basePath,
|
|
1339
|
-
traceId: ic.flowId,
|
|
1340
|
-
turnId: `iter-${ic.iteration}`,
|
|
1341
|
-
causedBy: "unit-start",
|
|
1342
|
-
});
|
|
1343
|
-
s.lastToolInvocationError = null; // #2883: clear stale error from previous unit
|
|
1344
|
-
const unitStartSeq = ic.nextSeq();
|
|
1345
|
-
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
|
|
1346
|
-
deps.captureAvailableSkills();
|
|
1347
|
-
writeUnitRuntimeRecord(s.basePath, unitType, unitId, s.currentUnit.startedAt, {
|
|
1348
|
-
phase: "dispatched",
|
|
1349
|
-
wrapupWarningSent: false,
|
|
1350
|
-
timeoutAt: null,
|
|
1351
|
-
lastProgressAt: s.currentUnit.startedAt,
|
|
1352
|
-
progressCount: 0,
|
|
1353
|
-
lastProgressKind: "dispatch",
|
|
1354
|
-
recoveryAttempts: 0, // Reset so re-dispatched units get full recovery budget (#2322)
|
|
1355
|
-
});
|
|
1348
|
+
const nextDispatchCount = (s.unitDispatchCount.get(dispatchKey) ?? 0) + 1;
|
|
1356
1349
|
// Status bar (widget + preconditions deferred until after model selection — see #2899)
|
|
1357
1350
|
ctx.ui.setStatus("gsd-auto", "auto");
|
|
1358
1351
|
if (mid)
|
|
@@ -1406,7 +1399,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1406
1399
|
finalPrompt = `${capped}\n\n---\n\n${finalPrompt}`;
|
|
1407
1400
|
s.pendingCrashRecovery = null;
|
|
1408
1401
|
}
|
|
1409
|
-
else if (
|
|
1402
|
+
else if (nextDispatchCount > 1) {
|
|
1410
1403
|
const diagnostic = deps.getDeepDiagnostic(s.basePath);
|
|
1411
1404
|
if (diagnostic) {
|
|
1412
1405
|
const cappedDiag = diagnostic.length > MAX_RECOVERY_CHARS
|
|
@@ -1445,6 +1438,11 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1445
1438
|
logWarning("engine", "Prompt reorder failed", { error: msg });
|
|
1446
1439
|
}
|
|
1447
1440
|
// Select and apply model (with tier escalation on retry — normal units only)
|
|
1441
|
+
const prevUnitRouting = s.currentUnitRouting;
|
|
1442
|
+
const prevUnitModel = s.currentUnitModel;
|
|
1443
|
+
const prevDispatchedModelId = s.currentDispatchedModelId;
|
|
1444
|
+
const prevSessionModel = ctx.model;
|
|
1445
|
+
const prevSessionThinkingLevel = pi.getThinkingLevel();
|
|
1448
1446
|
const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier }, undefined, s.manualSessionModelOverride, s.autoModeStartThinkingLevel);
|
|
1449
1447
|
s.currentUnitRouting =
|
|
1450
1448
|
modelResult.routing;
|
|
@@ -1488,12 +1486,58 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1488
1486
|
? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider)
|
|
1489
1487
|
: undefined,
|
|
1490
1488
|
baseUrl: s.currentUnitModel?.baseUrl ?? ctx.model?.baseUrl,
|
|
1489
|
+
activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
|
|
1491
1490
|
});
|
|
1492
1491
|
if (compatibilityError) {
|
|
1492
|
+
s.currentUnitRouting = prevUnitRouting;
|
|
1493
|
+
s.currentUnitModel = prevUnitModel;
|
|
1494
|
+
s.currentDispatchedModelId = prevDispatchedModelId;
|
|
1495
|
+
if (s.checkpointSha) {
|
|
1496
|
+
cleanupCheckpoint(s.basePath, unitId);
|
|
1497
|
+
s.checkpointSha = null;
|
|
1498
|
+
}
|
|
1499
|
+
if (prevSessionModel) {
|
|
1500
|
+
const ok = await pi.setModel(prevSessionModel, { persist: false });
|
|
1501
|
+
if (!ok) {
|
|
1502
|
+
ctx.ui.notify("Failed to restore previous session model after compatibility check failure.", "warning");
|
|
1503
|
+
}
|
|
1504
|
+
if (prevSessionThinkingLevel) {
|
|
1505
|
+
pi.setThinkingLevel(prevSessionThinkingLevel);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1493
1508
|
ctx.ui.notify(compatibilityError, "error");
|
|
1494
1509
|
await deps.stopAuto(ctx, pi, compatibilityError);
|
|
1495
1510
|
return { action: "break", reason: "workflow-capability" };
|
|
1496
1511
|
}
|
|
1512
|
+
// Scope workflow-logger buffer to this unit so post-finalize drains are
|
|
1513
|
+
// per-unit. Without this, the module-level _buffer accumulates across every
|
|
1514
|
+
// unit in the same Node process (see workflow-logger.ts module header).
|
|
1515
|
+
_resetLogs();
|
|
1516
|
+
const unitStartedAt = Date.now();
|
|
1517
|
+
s.unitDispatchCount.set(dispatchKey, nextDispatchCount);
|
|
1518
|
+
s.currentUnit = { type: unitType, id: unitId, startedAt: unitStartedAt };
|
|
1519
|
+
s.lastGitActionFailure = null;
|
|
1520
|
+
s.lastGitActionStatus = null;
|
|
1521
|
+
s.lastUnitAgentEndMessages = null;
|
|
1522
|
+
setCurrentPhase(unitType, {
|
|
1523
|
+
basePath: s.basePath,
|
|
1524
|
+
traceId: ic.flowId,
|
|
1525
|
+
turnId: `iter-${ic.iteration}`,
|
|
1526
|
+
causedBy: "unit-start",
|
|
1527
|
+
});
|
|
1528
|
+
s.lastToolInvocationError = null; // #2883: clear stale error from previous unit
|
|
1529
|
+
const unitStartSeq = ic.nextSeq();
|
|
1530
|
+
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
|
|
1531
|
+
deps.captureAvailableSkills();
|
|
1532
|
+
writeUnitRuntimeRecord(s.basePath, unitType, unitId, unitStartedAt, {
|
|
1533
|
+
phase: "dispatched",
|
|
1534
|
+
wrapupWarningSent: false,
|
|
1535
|
+
timeoutAt: null,
|
|
1536
|
+
lastProgressAt: unitStartedAt,
|
|
1537
|
+
progressCount: 0,
|
|
1538
|
+
lastProgressKind: "dispatch",
|
|
1539
|
+
recoveryAttempts: 0, // Reset so re-dispatched units get full recovery budget (#2322)
|
|
1540
|
+
});
|
|
1497
1541
|
// Progress widget + preconditions — deferred to after model selection so the
|
|
1498
1542
|
// widget's first render tick shows the correct model (#2899).
|
|
1499
1543
|
deps.updateProgressWidget(ctx, unitType, unitId, state);
|
|
@@ -1720,12 +1764,12 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1720
1764
|
}
|
|
1721
1765
|
}
|
|
1722
1766
|
}
|
|
1723
|
-
if (s.currentUnitRouting) {
|
|
1724
|
-
deps.recordOutcome(unitType, s.currentUnitRouting.tier, true);
|
|
1725
|
-
}
|
|
1726
1767
|
const skipArtifactVerification = unitType.startsWith("hook/") || unitType === "custom-step";
|
|
1727
1768
|
const artifactVerified = skipArtifactVerification ||
|
|
1728
1769
|
verifyExpectedArtifact(unitType, unitId, s.basePath);
|
|
1770
|
+
if (s.currentUnitRouting) {
|
|
1771
|
+
deps.recordOutcome(unitType, s.currentUnitRouting.tier, artifactVerified);
|
|
1772
|
+
}
|
|
1729
1773
|
if (artifactVerified) {
|
|
1730
1774
|
s.unitDispatchCount.delete(dispatchKey);
|
|
1731
1775
|
s.unitRecoveryCount.delete(`${unitType}/${unitId}`);
|
|
@@ -1749,7 +1793,10 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1749
1793
|
logWarning("engine", `phase anchor failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1750
1794
|
}
|
|
1751
1795
|
}
|
|
1752
|
-
|
|
1796
|
+
const unitEndStatus = !artifactVerified && unitResult.status === "completed"
|
|
1797
|
+
? "no-artifact"
|
|
1798
|
+
: unitResult.status;
|
|
1799
|
+
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "unit-end", data: { unitType, unitId, status: unitEndStatus, artifactVerified, ...(unitResult.errorContext ? { errorContext: unitResult.errorContext } : {}) }, causedBy: { flowId: ic.flowId, seq: unitStartSeq } });
|
|
1753
1800
|
// ── Safety harness: checkpoint cleanup or rollback ──
|
|
1754
1801
|
if (s.checkpointSha) {
|
|
1755
1802
|
if (unitResult.status === "error" && safetyConfig.auto_rollback) {
|
|
@@ -1810,6 +1857,8 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1810
1857
|
const preUnitSnapshot = s.currentUnit
|
|
1811
1858
|
? { type: s.currentUnit.type, id: s.currentUnit.id, startedAt: s.currentUnit.startedAt }
|
|
1812
1859
|
: null;
|
|
1860
|
+
s.currentUnit = null;
|
|
1861
|
+
clearCurrentPhase();
|
|
1813
1862
|
const preResultGuard = await withTimeout(deps.postUnitPreVerification(postUnitCtx, preVerificationOpts), FINALIZE_PRE_TIMEOUT_MS, "postUnitPreVerification");
|
|
1814
1863
|
if (preResultGuard.timedOut) {
|
|
1815
1864
|
return failClosedOnFinalizeTimeout(ic, iterData, loopState, "pre", preUnitSnapshot?.startedAt ?? Date.now());
|
|
@@ -1923,9 +1972,19 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1923
1972
|
lastProgressAt: Date.now(),
|
|
1924
1973
|
lastProgressKind: "finalize-success",
|
|
1925
1974
|
});
|
|
1975
|
+
if (!preUnitSnapshot.type.startsWith("hook/") &&
|
|
1976
|
+
preUnitSnapshot.type !== "custom-step" &&
|
|
1977
|
+
preUnitSnapshot.type !== "complete-milestone") {
|
|
1978
|
+
setAutoOutcomeWidget(ctx, {
|
|
1979
|
+
...buildPhaseHandoffOutcome({
|
|
1980
|
+
unitType: preUnitSnapshot.type,
|
|
1981
|
+
unitId: preUnitSnapshot.id,
|
|
1982
|
+
agentEndMessages: s.lastUnitAgentEndMessages,
|
|
1983
|
+
}),
|
|
1984
|
+
startedAt: s.autoStartTime,
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1926
1987
|
}
|
|
1927
|
-
s.currentUnit = null;
|
|
1928
|
-
clearCurrentPhase();
|
|
1929
1988
|
// Surface accumulated workflow-logger issues for this unit to the user.
|
|
1930
1989
|
// Warnings/errors logged during the unit are buffered in the logger and
|
|
1931
1990
|
// drained here so the user sees a single consolidated post-unit alert.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Mutable auto-mode session state container.
|
|
1
3
|
/**
|
|
2
4
|
* AutoSession — encapsulates all mutable auto-mode state into a single instance.
|
|
3
5
|
*
|
|
@@ -26,6 +28,7 @@ export class AutoSession {
|
|
|
26
28
|
active = false;
|
|
27
29
|
paused = false;
|
|
28
30
|
completionStopInProgress = false;
|
|
31
|
+
preserveStepSurfaceAfterLoopExit = false;
|
|
29
32
|
stepMode = false;
|
|
30
33
|
verbose = false;
|
|
31
34
|
activeEngineId = null;
|
|
@@ -159,6 +162,7 @@ export class AutoSession {
|
|
|
159
162
|
commandPollingCleanup = null;
|
|
160
163
|
// ── Orchestration seam ───────────────────────────────────────────────────
|
|
161
164
|
orchestration = null;
|
|
165
|
+
pendingOrchestrationDispatch = null;
|
|
162
166
|
// ── Loop promise state ──────────────────────────────────────────────────
|
|
163
167
|
// Per-unit resolve function and session-switch guard live at module level
|
|
164
168
|
// in auto-loop.ts (_currentResolve, _sessionSwitchInFlight).
|
|
@@ -210,6 +214,7 @@ export class AutoSession {
|
|
|
210
214
|
this.active = false;
|
|
211
215
|
this.paused = false;
|
|
212
216
|
this.completionStopInProgress = false;
|
|
217
|
+
this.preserveStepSurfaceAfterLoopExit = false;
|
|
213
218
|
this.stepMode = false;
|
|
214
219
|
this.verbose = false;
|
|
215
220
|
this.activeEngineId = null;
|
|
@@ -284,6 +289,7 @@ export class AutoSession {
|
|
|
284
289
|
this.commandPollingCleanup = null;
|
|
285
290
|
// Orchestration seam
|
|
286
291
|
this.orchestration = null;
|
|
292
|
+
this.pendingOrchestrationDispatch = null;
|
|
287
293
|
// Loop promise state lives in auto-loop.ts module scope
|
|
288
294
|
}
|
|
289
295
|
resetAfterStop(options = {}) {
|
|
@@ -66,6 +66,9 @@ export function decideEngineDispatch(input) {
|
|
|
66
66
|
export function decideFinalizeResult(input) {
|
|
67
67
|
if (input.action === "break") {
|
|
68
68
|
const reason = input.reason ?? "unknown";
|
|
69
|
+
if (reason === "step-wizard") {
|
|
70
|
+
return { action: "complete-and-break" };
|
|
71
|
+
}
|
|
69
72
|
return {
|
|
70
73
|
action: "stop",
|
|
71
74
|
failureClass: reason === "git-closeout-failure" ? "git" : "closeout",
|
|
@@ -4,6 +4,18 @@ import { createRequire } from "node:module";
|
|
|
4
4
|
const require = createRequire(import.meta.url);
|
|
5
5
|
const DEFAULT_MEMORY_PRESSURE_THRESHOLD = 0.85;
|
|
6
6
|
const DEFAULT_HEAP_LIMIT_MB = 4096;
|
|
7
|
+
/**
|
|
8
|
+
* Returns true on auto-mode startup, then every configured interval.
|
|
9
|
+
*
|
|
10
|
+
* Iteration 1 is checked explicitly so early session memory pressure cannot
|
|
11
|
+
* bypass the periodic interval guard.
|
|
12
|
+
*/
|
|
13
|
+
export function shouldCheckMemoryPressure(iteration, interval) {
|
|
14
|
+
if (!Number.isInteger(interval) || interval <= 0) {
|
|
15
|
+
throw new Error("Memory pressure check interval must be a positive integer");
|
|
16
|
+
}
|
|
17
|
+
return iteration === 1 || iteration % interval === 0;
|
|
18
|
+
}
|
|
7
19
|
function defaultHeapLimitBytes() {
|
|
8
20
|
const v8 = require("node:v8");
|
|
9
21
|
const limit = v8.getHeapStatistics?.().heap_size_limit;
|
|
@@ -27,6 +27,19 @@ export function extractUatSliceId(unitId) {
|
|
|
27
27
|
return slice;
|
|
28
28
|
return null;
|
|
29
29
|
}
|
|
30
|
+
export function buildPhaseHandoffOutcome(input) {
|
|
31
|
+
const phase = unitPhaseLabel(input.unitType);
|
|
32
|
+
const detail = extractLastAssistantSummary(input.agentEndMessages) ??
|
|
33
|
+
`Completed ${unitVerb(input.unitType)} ${input.unitId}.`;
|
|
34
|
+
return {
|
|
35
|
+
status: "complete",
|
|
36
|
+
title: `${phase} complete`,
|
|
37
|
+
detail,
|
|
38
|
+
unitLabel: `${unitVerb(input.unitType)} ${input.unitId}`,
|
|
39
|
+
nextAction: "Preparing the next phase. Review this handoff while the next session starts.",
|
|
40
|
+
commands: ["/gsd status for overview", "/gsd visualize to inspect", "/gsd notifications for history"],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
30
43
|
// ─── Unit Description Helpers ─────────────────────────────────────────────────
|
|
31
44
|
export function unitVerb(unitType) {
|
|
32
45
|
if (unitType.startsWith("hook/"))
|
|
@@ -464,7 +477,6 @@ export function _resetWidgetModeForTests() {
|
|
|
464
477
|
export function updateProgressWidget(ctx, unitType, unitId, state, accessors, tierBadge) {
|
|
465
478
|
if (!ctx.hasUI)
|
|
466
479
|
return;
|
|
467
|
-
ctx.ui.setWidget("gsd-outcome", undefined);
|
|
468
480
|
// Welcome header is a startup-only banner — permanently suppress it once
|
|
469
481
|
// auto-mode activates. The dashboard widget owns all status from here.
|
|
470
482
|
// Note: setHeader(undefined) restores the built-in header (logo +
|
|
@@ -927,3 +939,56 @@ function normalizeRollupText(value) {
|
|
|
927
939
|
return null;
|
|
928
940
|
return clean;
|
|
929
941
|
}
|
|
942
|
+
function isAssistantMessage(value) {
|
|
943
|
+
if (!value || typeof value !== "object")
|
|
944
|
+
return false;
|
|
945
|
+
const record = value;
|
|
946
|
+
if (record.role === "assistant")
|
|
947
|
+
return true;
|
|
948
|
+
const message = record.message;
|
|
949
|
+
if (message && typeof message === "object") {
|
|
950
|
+
return message.role === "assistant";
|
|
951
|
+
}
|
|
952
|
+
return false;
|
|
953
|
+
}
|
|
954
|
+
function extractLastAssistantSummary(messages) {
|
|
955
|
+
if (!messages || messages.length === 0)
|
|
956
|
+
return null;
|
|
957
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
958
|
+
if (!isAssistantMessage(messages[i]))
|
|
959
|
+
continue;
|
|
960
|
+
const text = extractMessageText(messages[i]);
|
|
961
|
+
const clean = normalizeRollupText(text);
|
|
962
|
+
if (clean)
|
|
963
|
+
return truncateToWidth(clean, 220, "…");
|
|
964
|
+
}
|
|
965
|
+
return null;
|
|
966
|
+
}
|
|
967
|
+
function extractMessageText(value) {
|
|
968
|
+
if (typeof value === "string")
|
|
969
|
+
return value;
|
|
970
|
+
if (!value || typeof value !== "object")
|
|
971
|
+
return null;
|
|
972
|
+
const record = value;
|
|
973
|
+
if (typeof record.content === "string")
|
|
974
|
+
return record.content;
|
|
975
|
+
const message = record.message;
|
|
976
|
+
if (message && typeof message === "object") {
|
|
977
|
+
return extractMessageText(message);
|
|
978
|
+
}
|
|
979
|
+
const content = record.content;
|
|
980
|
+
if (Array.isArray(content)) {
|
|
981
|
+
const parts = content
|
|
982
|
+
.map((part) => {
|
|
983
|
+
if (typeof part === "string")
|
|
984
|
+
return part;
|
|
985
|
+
if (!part || typeof part !== "object")
|
|
986
|
+
return "";
|
|
987
|
+
const partRecord = part;
|
|
988
|
+
return typeof partRecord.text === "string" ? partRecord.text : "";
|
|
989
|
+
})
|
|
990
|
+
.filter(Boolean);
|
|
991
|
+
return parts.length > 0 ? parts.join(" ") : null;
|
|
992
|
+
}
|
|
993
|
+
return null;
|
|
994
|
+
}
|
|
@@ -224,6 +224,7 @@ export async function dispatchDirectPhase(ctx, pi, phase, base) {
|
|
|
224
224
|
unitType,
|
|
225
225
|
authMode: ctx.model?.provider ? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider) : undefined,
|
|
226
226
|
baseUrl: ctx.model?.baseUrl,
|
|
227
|
+
activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
|
|
227
228
|
});
|
|
228
229
|
if (compatibilityError) {
|
|
229
230
|
ctx.ui.notify(compatibilityError, "error");
|