gsd-pi 2.81.0 → 2.82.0-dev.c22380fc3
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 +60 -30
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
- package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
- package/dist/resources/extensions/gsd/auto/loop.js +111 -8
- package/dist/resources/extensions/gsd/auto/orchestrator.js +113 -6
- package/dist/resources/extensions/gsd/auto/phases.js +199 -97
- package/dist/resources/extensions/gsd/auto/run-unit.js +66 -3
- package/dist/resources/extensions/gsd/auto/session.js +9 -0
- package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +43 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +182 -178
- package/dist/resources/extensions/gsd/auto-dispatch.js +14 -11
- package/dist/resources/extensions/gsd/auto-post-unit.js +7 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +11 -3
- package/dist/resources/extensions/gsd/auto-recovery.js +6 -181
- package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -0
- package/dist/resources/extensions/gsd/auto-start.js +20 -23
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +33 -5
- package/dist/resources/extensions/gsd/auto-verification.js +12 -6
- package/dist/resources/extensions/gsd/auto-worktree.js +8 -0
- package/dist/resources/extensions/gsd/auto.js +371 -106
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +13 -6
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +13 -2
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +4 -8
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -1
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +4 -10
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +9 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
- package/dist/resources/extensions/gsd/context-store.js +112 -0
- package/dist/resources/extensions/gsd/db-writer.js +150 -84
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
- package/dist/resources/extensions/gsd/git-service.js +2 -1
- package/dist/resources/extensions/gsd/gsd-db.js +7 -23
- package/dist/resources/extensions/gsd/health-widget-core.js +1 -1
- package/dist/resources/extensions/gsd/health-widget.js +4 -10
- package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
- package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
- package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
- package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +6 -96
- package/dist/resources/extensions/gsd/md-importer.js +1 -1
- package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
- package/dist/resources/extensions/gsd/migrate/command.js +5 -0
- package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
- package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
- package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +14 -14
- package/dist/resources/extensions/gsd/notification-overlay.js +35 -40
- package/dist/resources/extensions/gsd/parallel-merge.js +53 -30
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +25 -33
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +14 -12
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +20 -2
- package/dist/resources/extensions/gsd/prompts/system.md +2 -2
- package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
- package/dist/resources/extensions/gsd/recovery-classification.js +15 -1
- package/dist/resources/extensions/gsd/session-lock.js +40 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +131 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +247 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +50 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +87 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +50 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +124 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +32 -0
- package/dist/resources/extensions/gsd/state-reconciliation/errors.js +41 -0
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +99 -0
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +24 -0
- package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +43 -0
- package/dist/resources/extensions/gsd/state-reconciliation/types.js +3 -0
- package/dist/resources/extensions/gsd/state-reconciliation.js +5 -26
- package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/tui/render-kit.js +74 -0
- package/dist/resources/extensions/gsd/watch/header-renderer.js +92 -69
- package/dist/resources/extensions/gsd/watch/splash-palette.js +10 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +743 -318
- package/dist/resources/extensions/gsd/worktree-telemetry.js +3 -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 +12 -12
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +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_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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- 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/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.d.ts +0 -7
- package/dist/welcome-screen.js +60 -69
- package/package.json +3 -2
- 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 +14 -3
- 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-parity.test.ts +244 -0
- package/packages/mcp-server/src/workflow-tools.test.ts +22 -0
- 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/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -2
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -1
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/index.ts +7 -2
- package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js +47 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +76 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +30 -29
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +10 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +13 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +58 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +12 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.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 +14 -41
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +86 -82
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts +35 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js +152 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts +16 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js +73 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +12 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +105 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +27 -26
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +9 -6
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/assistant-message-design.test.ts +56 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +113 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/user-message-design.test.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +10 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +43 -42
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +14 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +64 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +13 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +15 -42
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +84 -104
- package/packages/pi-coding-agent/src/modes/interactive/components/transcript-design.ts +196 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tui-style-kit.ts +94 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +14 -9
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-highlight.test.ts +23 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +106 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +27 -26
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +9 -6
- package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +14 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.js +9 -6
- package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +5 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +20 -1
- package/packages/pi-tui/src/overlay-layout.ts +10 -7
- package/packages/pi-tui/src/tui.ts +6 -0
- 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/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +105 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +27 -26
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
- package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +46 -11
- package/src/resources/extensions/gsd/auto/loop-deps.ts +9 -5
- package/src/resources/extensions/gsd/auto/loop.ts +113 -9
- package/src/resources/extensions/gsd/auto/orchestrator.ts +118 -6
- package/src/resources/extensions/gsd/auto/phases.ts +158 -19
- package/src/resources/extensions/gsd/auto/run-unit.ts +69 -4
- package/src/resources/extensions/gsd/auto/session.ts +10 -0
- package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +82 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +230 -183
- package/src/resources/extensions/gsd/auto-dispatch.ts +15 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +7 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +11 -3
- package/src/resources/extensions/gsd/auto-recovery.ts +7 -209
- package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
- package/src/resources/extensions/gsd/auto-start.ts +22 -22
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +51 -0
- package/src/resources/extensions/gsd/auto-verification.ts +12 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +8 -0
- package/src/resources/extensions/gsd/auto.ts +411 -106
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -6
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -2
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +5 -8
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -1
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +4 -10
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +12 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/context-store.ts +120 -1
- package/src/resources/extensions/gsd/db-writer.ts +167 -84
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/git-service.ts +2 -0
- package/src/resources/extensions/gsd/gsd-db.ts +7 -23
- package/src/resources/extensions/gsd/health-widget-core.ts +1 -1
- package/src/resources/extensions/gsd/health-widget.ts +6 -10
- package/src/resources/extensions/gsd/journal.ts +2 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
- package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
- package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
- package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +10 -96
- package/src/resources/extensions/gsd/md-importer.ts +1 -1
- package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
- package/src/resources/extensions/gsd/migrate/command.ts +5 -0
- package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
- package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
- package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +14 -13
- package/src/resources/extensions/gsd/notification-overlay.ts +50 -46
- package/src/resources/extensions/gsd/parallel-merge.ts +61 -34
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +33 -35
- package/src/resources/extensions/gsd/prompts/complete-slice.md +14 -12
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +20 -2
- package/src/resources/extensions/gsd/prompts/system.md +2 -2
- package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
- package/src/resources/extensions/gsd/recovery-classification.ts +18 -1
- package/src/resources/extensions/gsd/session-lock.ts +41 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +172 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +337 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +69 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +109 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +68 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +185 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +46 -0
- package/src/resources/extensions/gsd/state-reconciliation/errors.ts +67 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +142 -0
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +27 -0
- package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +60 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +83 -0
- package/src/resources/extensions/gsd/state-reconciliation.ts +21 -53
- package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +729 -176
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +408 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +292 -4
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +20 -5
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +28 -1
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +20 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/header-renderer.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +14 -4
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
- package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +116 -24
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
- package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
- package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +46 -11
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +78 -41
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +12 -217
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +38 -6
- package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +71 -58
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +952 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +158 -58
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +597 -118
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +18 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
- package/src/resources/extensions/gsd/tui/render-kit.ts +109 -0
- package/src/resources/extensions/gsd/watch/header-renderer.ts +121 -79
- package/src/resources/extensions/gsd/watch/splash-palette.ts +11 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +1171 -526
- package/src/resources/extensions/gsd/worktree-telemetry.ts +7 -2
- package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -1544
- /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → Wop3A7KRGyR06H3rla_1-}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → Wop3A7KRGyR06H3rla_1-}/_ssgManifest.js +0 -0
|
@@ -7,6 +7,16 @@ function now(): number {
|
|
|
7
7
|
return Date.now();
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Size of the dispatch-decision ring buffer used by the Auto Orchestration
|
|
12
|
+
* module's stuck-loop detector. When the same `${unitType}:${unitId}` key
|
|
13
|
+
* fills the window, advance() blocks with `action: "stop"`.
|
|
14
|
+
*
|
|
15
|
+
* Mirrors the legacy `STUCK_WINDOW_SIZE` in auto/phases.ts so behaviour is
|
|
16
|
+
* preserved across the eventual cutover (issue #5791).
|
|
17
|
+
*/
|
|
18
|
+
export const STUCK_WINDOW_SIZE = 6;
|
|
19
|
+
|
|
10
20
|
export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
11
21
|
private status: AutoStatus = {
|
|
12
22
|
phase: "idle",
|
|
@@ -14,6 +24,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
14
24
|
};
|
|
15
25
|
private readonly deps: AutoOrchestratorDeps;
|
|
16
26
|
private lastAdvanceKey: string | null = null;
|
|
27
|
+
private dispatchKeyWindow: string[] = [];
|
|
17
28
|
|
|
18
29
|
public constructor(deps: AutoOrchestratorDeps) {
|
|
19
30
|
this.deps = deps;
|
|
@@ -21,6 +32,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
21
32
|
|
|
22
33
|
public async start(_sessionContext: AutoSessionContext): Promise<AutoAdvanceResult> {
|
|
23
34
|
this.lastAdvanceKey = null;
|
|
35
|
+
this.dispatchKeyWindow = [];
|
|
24
36
|
this.status.phase = "running";
|
|
25
37
|
this.bumpTransition();
|
|
26
38
|
await this.deps.runtime.journalTransition({ name: "start" });
|
|
@@ -31,19 +43,72 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
31
43
|
public async advance(): Promise<AutoAdvanceResult> {
|
|
32
44
|
try {
|
|
33
45
|
await this.deps.runtime.ensureLockOwnership();
|
|
46
|
+
|
|
47
|
+
const staleMsg = this.deps.health.checkResourcesStale();
|
|
48
|
+
if (staleMsg) {
|
|
49
|
+
await this.deps.uokGate.emit({
|
|
50
|
+
gateId: "resource-version-guard",
|
|
51
|
+
gateType: "policy",
|
|
52
|
+
outcome: "fail",
|
|
53
|
+
failureClass: "policy",
|
|
54
|
+
rationale: "resource version guard blocked dispatch",
|
|
55
|
+
findings: staleMsg,
|
|
56
|
+
});
|
|
57
|
+
const blocked: AutoAdvanceResult = { kind: "blocked", reason: staleMsg, action: "stop" };
|
|
58
|
+
await this.deps.runtime.journalTransition({ name: "advance-blocked", reason: blocked.reason });
|
|
59
|
+
await this.deps.health.postAdvanceRecord(blocked);
|
|
60
|
+
return blocked;
|
|
61
|
+
}
|
|
62
|
+
await this.deps.uokGate.emit({
|
|
63
|
+
gateId: "resource-version-guard",
|
|
64
|
+
gateType: "policy",
|
|
65
|
+
outcome: "pass",
|
|
66
|
+
failureClass: "none",
|
|
67
|
+
rationale: "resource version guard passed",
|
|
68
|
+
});
|
|
69
|
+
|
|
34
70
|
const gate = await this.deps.health.preAdvanceGate();
|
|
35
|
-
if (
|
|
36
|
-
|
|
71
|
+
if (gate.kind === "fail") {
|
|
72
|
+
await this.deps.uokGate.emit({
|
|
73
|
+
gateId: "pre-dispatch-health-gate",
|
|
74
|
+
gateType: "execution",
|
|
75
|
+
outcome: "manual-attention",
|
|
76
|
+
failureClass: "manual-attention",
|
|
77
|
+
rationale: "pre-dispatch health gate blocked dispatch",
|
|
78
|
+
findings: gate.reason,
|
|
79
|
+
});
|
|
80
|
+
const blocked: AutoAdvanceResult = { kind: "blocked", reason: gate.reason, action: "pause" };
|
|
37
81
|
await this.deps.runtime.journalTransition({ name: "advance-blocked", reason: blocked.reason });
|
|
38
82
|
await this.deps.health.postAdvanceRecord(blocked);
|
|
39
83
|
return blocked;
|
|
40
84
|
}
|
|
85
|
+
if (gate.kind === "threw") {
|
|
86
|
+
await this.deps.uokGate.emit({
|
|
87
|
+
gateId: "pre-dispatch-health-gate",
|
|
88
|
+
gateType: "execution",
|
|
89
|
+
outcome: "manual-attention",
|
|
90
|
+
failureClass: "manual-attention",
|
|
91
|
+
rationale: "pre-dispatch health gate threw unexpectedly",
|
|
92
|
+
findings: String(gate.error),
|
|
93
|
+
});
|
|
94
|
+
// intentional fall-through: matches runPreDispatch behaviour
|
|
95
|
+
} else {
|
|
96
|
+
await this.deps.uokGate.emit({
|
|
97
|
+
gateId: "pre-dispatch-health-gate",
|
|
98
|
+
gateType: "execution",
|
|
99
|
+
outcome: "pass",
|
|
100
|
+
failureClass: "none",
|
|
101
|
+
rationale: "pre-dispatch health gate passed",
|
|
102
|
+
findings: gate.fixesApplied?.join(", ") ?? "",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
41
105
|
|
|
42
106
|
const reconciliation = await this.deps.stateReconciliation.reconcileBeforeDispatch();
|
|
43
107
|
if (!reconciliation.ok || !reconciliation.stateSnapshot) {
|
|
44
108
|
const blocked: AutoAdvanceResult = {
|
|
45
109
|
kind: "blocked",
|
|
46
|
-
reason: reconciliation.reason,
|
|
110
|
+
reason: reconciliation.reason ?? "state reconciliation produced no snapshot",
|
|
111
|
+
action: "pause",
|
|
47
112
|
stateSnapshot: reconciliation.stateSnapshot,
|
|
48
113
|
};
|
|
49
114
|
await this.deps.runtime.journalTransition({ name: "advance-blocked", reason: blocked.reason });
|
|
@@ -57,6 +122,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
57
122
|
this.status.phase = "stopped";
|
|
58
123
|
this.status.activeUnit = undefined;
|
|
59
124
|
this.lastAdvanceKey = null;
|
|
125
|
+
this.dispatchKeyWindow = [];
|
|
60
126
|
this.bumpTransition();
|
|
61
127
|
await this.deps.runtime.journalTransition({ name: "advance-stopped", reason: stopped.reason });
|
|
62
128
|
await this.deps.health.postAdvanceRecord(stopped);
|
|
@@ -64,8 +130,45 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
64
130
|
}
|
|
65
131
|
|
|
66
132
|
const nextKey = `${decision.unitType}:${decision.unitId}`;
|
|
67
|
-
|
|
68
|
-
|
|
133
|
+
|
|
134
|
+
// Record every dispatch decision in the ring buffer before pre-flight
|
|
135
|
+
// checks so the stuck-loop detector observes the full decision history
|
|
136
|
+
// (including decisions that idempotency would otherwise short-circuit).
|
|
137
|
+
// The ring is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
|
|
138
|
+
this.dispatchKeyWindow.push(nextKey);
|
|
139
|
+
if (this.dispatchKeyWindow.length > STUCK_WINDOW_SIZE) {
|
|
140
|
+
this.dispatchKeyWindow.shift();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Idempotency: same key as immediately previous successful advance.
|
|
144
|
+
// This is the soft, fast-path block kept from #5786. It only fires when
|
|
145
|
+
// the ring is NOT yet saturated for this key — once the ring is full of
|
|
146
|
+
// `nextKey`, the stuck-loop verdict takes precedence (see below). Both
|
|
147
|
+
// checks coexist: idempotency for the common immediate-repeat case,
|
|
148
|
+
// stuck-loop for the saturated-window case.
|
|
149
|
+
const matchingCount = this.dispatchKeyWindow.filter((k) => k === nextKey).length;
|
|
150
|
+
if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
|
|
151
|
+
const blocked: AutoAdvanceResult = { kind: "blocked", reason: "idempotent advance: unit already active", action: "stop" };
|
|
152
|
+
await this.deps.runtime.journalTransition({
|
|
153
|
+
name: "advance-blocked",
|
|
154
|
+
reason: blocked.reason,
|
|
155
|
+
unitType: decision.unitType,
|
|
156
|
+
unitId: decision.unitId,
|
|
157
|
+
});
|
|
158
|
+
await this.deps.health.postAdvanceRecord(blocked);
|
|
159
|
+
return blocked;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Stuck-loop detection: when the ring is saturated with copies of
|
|
163
|
+
// `nextKey` (count >= STUCK_WINDOW_SIZE), the orchestrator has been
|
|
164
|
+
// picking the same unit across the whole window and must hard-stop with
|
|
165
|
+
// a diagnosable reason.
|
|
166
|
+
if (matchingCount >= STUCK_WINDOW_SIZE) {
|
|
167
|
+
const blocked: AutoAdvanceResult = {
|
|
168
|
+
kind: "blocked",
|
|
169
|
+
reason: `stuck-loop: ${nextKey} picked ${matchingCount} times`,
|
|
170
|
+
action: "stop",
|
|
171
|
+
};
|
|
69
172
|
await this.deps.runtime.journalTransition({
|
|
70
173
|
name: "advance-blocked",
|
|
71
174
|
reason: blocked.reason,
|
|
@@ -81,6 +184,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
81
184
|
const blocked: AutoAdvanceResult = {
|
|
82
185
|
kind: "blocked",
|
|
83
186
|
reason: contract.reason,
|
|
187
|
+
action: "pause",
|
|
84
188
|
stateSnapshot: reconciliation.stateSnapshot,
|
|
85
189
|
};
|
|
86
190
|
await this.deps.runtime.journalTransition({
|
|
@@ -98,6 +202,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
98
202
|
const blocked: AutoAdvanceResult = {
|
|
99
203
|
kind: "blocked",
|
|
100
204
|
reason: worktree.reason,
|
|
205
|
+
action: "pause",
|
|
101
206
|
stateSnapshot: reconciliation.stateSnapshot,
|
|
102
207
|
};
|
|
103
208
|
await this.deps.runtime.journalTransition({
|
|
@@ -123,7 +228,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
123
228
|
});
|
|
124
229
|
await this.deps.worktree.syncAfterUnit(decision.unitType, decision.unitId);
|
|
125
230
|
|
|
126
|
-
const advanced: AutoAdvanceResult = {
|
|
231
|
+
const advanced: AutoAdvanceResult = {
|
|
232
|
+
kind: "advanced",
|
|
233
|
+
unit: { unitType: decision.unitType, unitId: decision.unitId },
|
|
234
|
+
stateSnapshot: reconciliation.stateSnapshot,
|
|
235
|
+
};
|
|
127
236
|
await this.deps.health.postAdvanceRecord(advanced);
|
|
128
237
|
return advanced;
|
|
129
238
|
} catch (error) {
|
|
@@ -148,6 +257,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
148
257
|
|
|
149
258
|
if (result.kind === "stopped") {
|
|
150
259
|
this.lastAdvanceKey = null;
|
|
260
|
+
this.dispatchKeyWindow = [];
|
|
151
261
|
this.status.activeUnit = undefined;
|
|
152
262
|
}
|
|
153
263
|
this.bumpTransition();
|
|
@@ -173,6 +283,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
173
283
|
|
|
174
284
|
public async resume(): Promise<AutoAdvanceResult> {
|
|
175
285
|
this.lastAdvanceKey = null;
|
|
286
|
+
this.dispatchKeyWindow = [];
|
|
176
287
|
this.status.phase = "running";
|
|
177
288
|
this.bumpTransition();
|
|
178
289
|
await this.deps.runtime.journalTransition({ name: "resume" });
|
|
@@ -188,6 +299,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
188
299
|
this.status.phase = "stopped";
|
|
189
300
|
this.status.activeUnit = undefined;
|
|
190
301
|
this.lastAdvanceKey = null;
|
|
302
|
+
this.dispatchKeyWindow = [];
|
|
191
303
|
this.bumpTransition();
|
|
192
304
|
await this.deps.runtime.journalTransition({ name: "stop", reason });
|
|
193
305
|
await this.deps.notifications.notifyLifecycle({ name: "stop", detail: reason });
|
|
@@ -58,6 +58,7 @@ import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "
|
|
|
58
58
|
import { getEligibleSlices } from "../slice-parallel-eligibility.js";
|
|
59
59
|
import { startSliceParallel } from "../slice-parallel-orchestrator.js";
|
|
60
60
|
import { isDbAvailable, getMilestoneSlices } from "../gsd-db.js";
|
|
61
|
+
import { reconcileBeforeSpawn } from "../state-reconciliation.js";
|
|
61
62
|
import type { MinimalModelRegistry } from "../context-budget.js";
|
|
62
63
|
import type { PostflightResult, PreflightResult } from "../clean-root-preflight.js";
|
|
63
64
|
import { ensurePlanV2Graph, isEmptyPlanV2GraphResult, isMissingFinalizedContextResult } from "../uok/plan-v2.js";
|
|
@@ -74,6 +75,8 @@ import {
|
|
|
74
75
|
} from "../workflow-mcp.js";
|
|
75
76
|
import { resolveManifest } from "../unit-context-manifest.js";
|
|
76
77
|
import { createWorktreeSafetyModule, type WorktreeSafetyResult } from "../worktree-safety.js";
|
|
78
|
+
import { isSuspiciousGhostCompletion } from "../auto-unit-closeout.js";
|
|
79
|
+
import { decideVerificationRetry, verificationRetryKey } from "./verification-retry-policy.js";
|
|
77
80
|
|
|
78
81
|
// ─── Path Comparison Helper ───────────────────────────────────────────────
|
|
79
82
|
/** Compare two paths for physical identity, tolerating trailing slashes and symlinks. */
|
|
@@ -81,6 +84,56 @@ function isSamePathLocal(a: string, b: string): boolean {
|
|
|
81
84
|
return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
|
|
82
85
|
}
|
|
83
86
|
|
|
87
|
+
async function applyVerificationRetryPolicy(
|
|
88
|
+
ic: IterationContext,
|
|
89
|
+
unitType: string | undefined,
|
|
90
|
+
phase: "artifact-verification-retry" | "verification-retry",
|
|
91
|
+
): Promise<PhaseResult | null> {
|
|
92
|
+
const { ctx, pi, s, deps } = ic;
|
|
93
|
+
const retryInfo = s.pendingVerificationRetry;
|
|
94
|
+
const key = unitType && retryInfo
|
|
95
|
+
? verificationRetryKey(unitType, retryInfo.unitId)
|
|
96
|
+
: undefined;
|
|
97
|
+
const decision = decideVerificationRetry({
|
|
98
|
+
unitType,
|
|
99
|
+
retryInfo,
|
|
100
|
+
previousFailureHash: key ? s.verificationRetryFailureHashes.get(key) : undefined,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (decision.action === "pause") {
|
|
104
|
+
s.pendingVerificationRetry = null;
|
|
105
|
+
debugLog("autoLoop", {
|
|
106
|
+
phase: `${phase}-paused`,
|
|
107
|
+
reason: decision.reason,
|
|
108
|
+
unitType,
|
|
109
|
+
unitId: retryInfo?.unitId,
|
|
110
|
+
failureHash: decision.failureHash,
|
|
111
|
+
});
|
|
112
|
+
ctx.ui.notify(
|
|
113
|
+
decision.reason === "duplicate-failure-context"
|
|
114
|
+
? `Verification retry for ${unitType ?? "unit"} ${retryInfo?.unitId ?? "unknown"} produced the same failure context. Pausing auto-mode instead of re-dispatching.`
|
|
115
|
+
: "Verification retry requested without retry context. Pausing auto-mode instead of re-dispatching.",
|
|
116
|
+
"warning",
|
|
117
|
+
);
|
|
118
|
+
await deps.pauseAuto(ctx, pi);
|
|
119
|
+
return { action: "break", reason: decision.reason };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
s.verificationRetryFailureHashes.set(decision.key, decision.failureHash);
|
|
123
|
+
debugLog("autoLoop", {
|
|
124
|
+
phase: `${phase}-backoff`,
|
|
125
|
+
iteration: ic.iteration,
|
|
126
|
+
unitType,
|
|
127
|
+
unitId: retryInfo?.unitId,
|
|
128
|
+
attempt: retryInfo?.attempt,
|
|
129
|
+
delayMs: decision.delayMs,
|
|
130
|
+
baseDelayMs: decision.baseDelayMs,
|
|
131
|
+
failureHash: decision.failureHash,
|
|
132
|
+
});
|
|
133
|
+
await new Promise<void>((resolve) => setTimeout(resolve, decision.delayMs));
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
84
137
|
export function shouldDegradeEmptyWorktreeToProjectRoot(
|
|
85
138
|
worktreeClassification: ReturnType<typeof classifyProject>,
|
|
86
139
|
projectRootClassification: ReturnType<typeof classifyProject>,
|
|
@@ -826,6 +879,16 @@ export async function runPreDispatch(
|
|
|
826
879
|
`Slice-parallel: dispatching ${eligible.length} eligible slices for ${mid}.`,
|
|
827
880
|
"info",
|
|
828
881
|
);
|
|
882
|
+
// ADR-017 #5707: reconcile before spawning so each worker doesn't
|
|
883
|
+
// independently race on the same drift. Failure aborts the spawn.
|
|
884
|
+
const spawnGate = await reconcileBeforeSpawn(s.basePath);
|
|
885
|
+
if (!spawnGate.ok) {
|
|
886
|
+
ctx.ui.notify(
|
|
887
|
+
`Slice-parallel: aborting spawn — ${spawnGate.reason}`,
|
|
888
|
+
"error",
|
|
889
|
+
);
|
|
890
|
+
return { action: "break", reason: `slice-parallel-reconciliation-failed: ${spawnGate.reason}` };
|
|
891
|
+
}
|
|
829
892
|
const result = await startSliceParallel(
|
|
830
893
|
s.basePath,
|
|
831
894
|
mid,
|
|
@@ -1008,7 +1071,13 @@ export async function runPreDispatch(
|
|
|
1008
1071
|
"All milestones complete.",
|
|
1009
1072
|
"success",
|
|
1010
1073
|
);
|
|
1011
|
-
await deps.stopAuto(ctx, pi, "All milestones complete"
|
|
1074
|
+
await deps.stopAuto(ctx, pi, "All milestones complete", {
|
|
1075
|
+
completionWidget: {
|
|
1076
|
+
milestoneId: s.currentMilestoneId,
|
|
1077
|
+
milestoneTitle: midTitle,
|
|
1078
|
+
allMilestonesComplete: true,
|
|
1079
|
+
},
|
|
1080
|
+
});
|
|
1012
1081
|
} else if (incomplete.length === 0 && state.registry.length === 0) {
|
|
1013
1082
|
// Empty registry — no milestones visible, likely a path resolution bug
|
|
1014
1083
|
const diag = `basePath=${s.basePath}, phase=${state.phase}`;
|
|
@@ -1103,7 +1172,23 @@ export async function runPreDispatch(
|
|
|
1103
1172
|
`Milestone ${mid} complete.`,
|
|
1104
1173
|
"success",
|
|
1105
1174
|
);
|
|
1106
|
-
|
|
1175
|
+
if (s.currentUnit) {
|
|
1176
|
+
await deps.closeoutUnit(
|
|
1177
|
+
ctx,
|
|
1178
|
+
s.basePath,
|
|
1179
|
+
s.currentUnit.type,
|
|
1180
|
+
s.currentUnit.id,
|
|
1181
|
+
s.currentUnit.startedAt,
|
|
1182
|
+
deps.buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id),
|
|
1183
|
+
);
|
|
1184
|
+
s.currentUnit = null;
|
|
1185
|
+
}
|
|
1186
|
+
await deps.stopAuto(ctx, pi, `Milestone ${mid} complete`, {
|
|
1187
|
+
completionWidget: {
|
|
1188
|
+
milestoneId: mid,
|
|
1189
|
+
milestoneTitle: midTitle,
|
|
1190
|
+
},
|
|
1191
|
+
});
|
|
1107
1192
|
debugLog("autoLoop", { phase: "exit", reason: "milestone-complete" });
|
|
1108
1193
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "terminal", data: { reason: "milestone-complete", milestoneId: mid } });
|
|
1109
1194
|
return { action: "break", reason: "milestone-complete" };
|
|
@@ -1266,16 +1351,14 @@ export async function runDispatch(
|
|
|
1266
1351
|
// ── Sliding-window stuck detection with graduated recovery ──
|
|
1267
1352
|
const derivedKey = `${unitType}/${unitId}`;
|
|
1268
1353
|
|
|
1269
|
-
// Always record this dispatch in the sliding window
|
|
1270
|
-
//
|
|
1271
|
-
//
|
|
1272
|
-
// (#2007). Only the *response* to a stuck signal is suppressed during retries.
|
|
1354
|
+
// Always record this dispatch in the sliding window and run detection so
|
|
1355
|
+
// Rules 1/3/4 can catch retry loops with repeated failure content (#5719).
|
|
1356
|
+
// Rules 2/2b suppress legitimate retry backoff through the dispatch ledger.
|
|
1273
1357
|
loopState.recentUnits.push({ key: derivedKey });
|
|
1274
1358
|
if (loopState.recentUnits.length > STUCK_WINDOW_SIZE) loopState.recentUnits.shift();
|
|
1275
1359
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
if (stuckSignal) {
|
|
1360
|
+
const stuckSignal = detectStuck(loopState.recentUnits);
|
|
1361
|
+
if (stuckSignal) {
|
|
1279
1362
|
debugLog("autoLoop", {
|
|
1280
1363
|
phase: "stuck-check",
|
|
1281
1364
|
unitType,
|
|
@@ -1391,16 +1474,15 @@ export async function runDispatch(
|
|
|
1391
1474
|
);
|
|
1392
1475
|
return { action: "break", reason: "stuck-detected" };
|
|
1393
1476
|
}
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
}
|
|
1477
|
+
} else {
|
|
1478
|
+
// Progress detected — reset recovery counter
|
|
1479
|
+
if (loopState.stuckRecoveryAttempts > 0) {
|
|
1480
|
+
debugLog("autoLoop", {
|
|
1481
|
+
phase: "stuck-counter-reset",
|
|
1482
|
+
from: loopState.recentUnits[loopState.recentUnits.length - 2]?.key ?? "",
|
|
1483
|
+
to: derivedKey,
|
|
1484
|
+
});
|
|
1485
|
+
loopState.stuckRecoveryAttempts = 0;
|
|
1404
1486
|
}
|
|
1405
1487
|
}
|
|
1406
1488
|
|
|
@@ -1984,6 +2066,33 @@ export async function runUnitPhase(
|
|
|
1984
2066
|
status: unitResult.status,
|
|
1985
2067
|
});
|
|
1986
2068
|
|
|
2069
|
+
if (
|
|
2070
|
+
unitResult.status === "completed" &&
|
|
2071
|
+
s.currentUnit &&
|
|
2072
|
+
(unitResult.event?.messages?.length ?? 0) === 0 &&
|
|
2073
|
+
isSuspiciousGhostCompletion(ctx, unitResult.requestDispatchedAt ?? s.currentUnit.startedAt)
|
|
2074
|
+
) {
|
|
2075
|
+
const message =
|
|
2076
|
+
`${unitType} ${unitId} completed without assistant output or tool calls; treating as a stale ghost completion.`;
|
|
2077
|
+
debugLog("autoLoop", {
|
|
2078
|
+
phase: "ghost-completion",
|
|
2079
|
+
iteration: ic.iteration,
|
|
2080
|
+
unitType,
|
|
2081
|
+
unitId,
|
|
2082
|
+
elapsedMs: Date.now() - (unitResult.requestDispatchedAt ?? s.currentUnit.startedAt),
|
|
2083
|
+
});
|
|
2084
|
+
logWarning("engine", message);
|
|
2085
|
+
ctx.ui.notify(`${message} Pausing auto-mode before closeout side effects.`, "warning");
|
|
2086
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, {
|
|
2087
|
+
message,
|
|
2088
|
+
category: "unknown",
|
|
2089
|
+
isTransient: true,
|
|
2090
|
+
});
|
|
2091
|
+
s.currentUnit = null;
|
|
2092
|
+
await deps.pauseAuto(ctx, pi);
|
|
2093
|
+
return { action: "break", reason: "ghost-completion" };
|
|
2094
|
+
}
|
|
2095
|
+
|
|
1987
2096
|
// Now that runUnit has called newSession(), the session file path is correct.
|
|
1988
2097
|
const sessionFile = deps.getSessionFile(ctx);
|
|
1989
2098
|
deps.updateSessionLock(
|
|
@@ -2124,6 +2233,20 @@ export async function runUnitPhase(
|
|
|
2124
2233
|
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
2125
2234
|
return { action: "break", reason: "session-timeout" };
|
|
2126
2235
|
}
|
|
2236
|
+
if (
|
|
2237
|
+
unitResult.errorContext?.isTransient &&
|
|
2238
|
+
errorCategory === "aborted"
|
|
2239
|
+
) {
|
|
2240
|
+
ctx.ui.notify(
|
|
2241
|
+
`Unit ${unitType} ${unitId} was aborted by the user. Pausing auto-mode (recoverable).`,
|
|
2242
|
+
"warning",
|
|
2243
|
+
);
|
|
2244
|
+
debugLog("autoLoop", { phase: "unit-aborted-transient-pause", unitType, unitId, category: errorCategory });
|
|
2245
|
+
await deps.pauseAuto(ctx, pi);
|
|
2246
|
+
await deps.autoCommitUnit?.(s.basePath, unitType, unitId, ctx);
|
|
2247
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
2248
|
+
return { action: "break", reason: "unit-aborted-pause" };
|
|
2249
|
+
}
|
|
2127
2250
|
// All other cancelled states (structural errors, non-transient failures): hard stop
|
|
2128
2251
|
if (s.currentUnit) {
|
|
2129
2252
|
await deps.closeoutUnit(
|
|
@@ -2364,6 +2487,14 @@ export async function runFinalize(
|
|
|
2364
2487
|
attempt: retryInfo?.attempt,
|
|
2365
2488
|
},
|
|
2366
2489
|
});
|
|
2490
|
+
const retryPolicyResult = await applyVerificationRetryPolicy(
|
|
2491
|
+
ic,
|
|
2492
|
+
preUnitSnapshot?.type,
|
|
2493
|
+
"artifact-verification-retry",
|
|
2494
|
+
);
|
|
2495
|
+
if (retryPolicyResult) {
|
|
2496
|
+
return retryPolicyResult;
|
|
2497
|
+
}
|
|
2367
2498
|
// Continue the loop — next iteration will inject the retry context into the prompt.
|
|
2368
2499
|
debugLog("autoLoop", { phase: "artifact-verification-retry", iteration: ic.iteration });
|
|
2369
2500
|
return { action: "continue" };
|
|
@@ -2401,6 +2532,14 @@ export async function runFinalize(
|
|
|
2401
2532
|
debugLog("autoLoop", { phase: "sidecar-verification-retry-skipped", iteration: ic.iteration });
|
|
2402
2533
|
} else {
|
|
2403
2534
|
// s.pendingVerificationRetry was set by runPostUnitVerification.
|
|
2535
|
+
const retryPolicyResult = await applyVerificationRetryPolicy(
|
|
2536
|
+
ic,
|
|
2537
|
+
iterData.unitType,
|
|
2538
|
+
"verification-retry",
|
|
2539
|
+
);
|
|
2540
|
+
if (retryPolicyResult) {
|
|
2541
|
+
return retryPolicyResult;
|
|
2542
|
+
}
|
|
2404
2543
|
// Continue the loop — next iteration will inject the retry context into the prompt.
|
|
2405
2544
|
debugLog("autoLoop", { phase: "verification-retry", iteration: ic.iteration });
|
|
2406
2545
|
return { action: "continue" };
|
|
@@ -26,6 +26,31 @@ import { debugLog } from "../debug-logger.js";
|
|
|
26
26
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
27
27
|
import { resolveAutoSupervisorConfig } from "../preferences.js";
|
|
28
28
|
import { formatAutoUnitWorkingMessage } from "../working-output-messages.js";
|
|
29
|
+
import { readUnitRuntimeRecord, type AutoUnitRuntimeRecord } from "../unit-runtime.js";
|
|
30
|
+
|
|
31
|
+
const UNIT_FAILSAFE_BUFFER_MS = 30_000;
|
|
32
|
+
const UNIT_FAILSAFE_RECHECK_MS = 30_000;
|
|
33
|
+
|
|
34
|
+
export function shouldDeferUnitFailsafeTimeout(
|
|
35
|
+
runtime: AutoUnitRuntimeRecord | null,
|
|
36
|
+
opts: {
|
|
37
|
+
nowMs: number;
|
|
38
|
+
currentUnitStartedAt?: number;
|
|
39
|
+
freshProgressMs: number;
|
|
40
|
+
},
|
|
41
|
+
): boolean {
|
|
42
|
+
if (!runtime) return false;
|
|
43
|
+
if (opts.currentUnitStartedAt === undefined) return false;
|
|
44
|
+
if (runtime.startedAt !== opts.currentUnitStartedAt) return false;
|
|
45
|
+
if (runtime.lastProgressAt <= 0) return false;
|
|
46
|
+
const progressAgeMs = opts.nowMs - runtime.lastProgressAt;
|
|
47
|
+
if (progressAgeMs < 0) return false;
|
|
48
|
+
if (progressAgeMs > opts.freshProgressMs) return false;
|
|
49
|
+
if (runtime.phase === "recovered") return true;
|
|
50
|
+
if (runtime.lastProgressKind.includes("recovery")) return true;
|
|
51
|
+
if (runtime.recoveryAttempts && runtime.recoveryAttempts > 0) return true;
|
|
52
|
+
return progressAgeMs >= 0 && progressAgeMs <= opts.freshProgressMs;
|
|
53
|
+
}
|
|
29
54
|
|
|
30
55
|
// Tracks the latest session-switch attempt so a late timeout settlement from an
|
|
31
56
|
// older runUnit() call cannot clear the guard for a newer one.
|
|
@@ -192,8 +217,12 @@ export async function runUnit(
|
|
|
192
217
|
// Without this, a crashed agent that never emits agent_end hangs the loop (#3161).
|
|
193
218
|
const supervisor = resolveAutoSupervisorConfig();
|
|
194
219
|
const UNIT_HARD_TIMEOUT_MS = Math.max(
|
|
195
|
-
|
|
196
|
-
((supervisor.hard_timeout_minutes ?? 30) * 60 * 1000) +
|
|
220
|
+
UNIT_FAILSAFE_BUFFER_MS,
|
|
221
|
+
((supervisor.hard_timeout_minutes ?? 30) * 60 * 1000) + UNIT_FAILSAFE_BUFFER_MS,
|
|
222
|
+
);
|
|
223
|
+
const freshProgressMs = Math.max(
|
|
224
|
+
UNIT_FAILSAFE_BUFFER_MS,
|
|
225
|
+
((supervisor.idle_timeout_minutes ?? 10) * 60 * 1000) + UNIT_FAILSAFE_BUFFER_MS,
|
|
197
226
|
);
|
|
198
227
|
let unitTimeoutHandle: ReturnType<typeof setTimeout> | undefined;
|
|
199
228
|
let result: UnitResult;
|
|
@@ -205,9 +234,45 @@ export async function runUnit(
|
|
|
205
234
|
|
|
206
235
|
debugLog("runUnit", { phase: "awaiting-agent-end", unitType, unitId });
|
|
207
236
|
const timeoutResult = new Promise<UnitResult>((resolve) => {
|
|
208
|
-
|
|
237
|
+
const settleOrDefer = () => {
|
|
238
|
+
let runtime: AutoUnitRuntimeRecord | null;
|
|
239
|
+
try {
|
|
240
|
+
runtime = readUnitRuntimeRecord(s.basePath, unitType, unitId);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
debugLog("runUnit", {
|
|
243
|
+
phase: "unit-failsafe-runtime-read-failed",
|
|
244
|
+
unitType,
|
|
245
|
+
unitId,
|
|
246
|
+
error: error instanceof Error ? error.message : String(error),
|
|
247
|
+
});
|
|
248
|
+
resolve({
|
|
249
|
+
status: "cancelled",
|
|
250
|
+
errorContext: {
|
|
251
|
+
message: "Unit hard timeout — supervision may have failed; runtime progress could not be read",
|
|
252
|
+
category: "timeout",
|
|
253
|
+
isTransient: true,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (shouldDeferUnitFailsafeTimeout(runtime, {
|
|
259
|
+
nowMs: Date.now(),
|
|
260
|
+
currentUnitStartedAt: s.currentUnit?.startedAt,
|
|
261
|
+
freshProgressMs,
|
|
262
|
+
})) {
|
|
263
|
+
debugLog("runUnit", {
|
|
264
|
+
phase: "unit-failsafe-deferred",
|
|
265
|
+
unitType,
|
|
266
|
+
unitId,
|
|
267
|
+
runtimePhase: runtime?.phase,
|
|
268
|
+
lastProgressKind: runtime?.lastProgressKind,
|
|
269
|
+
});
|
|
270
|
+
unitTimeoutHandle = setTimeout(settleOrDefer, UNIT_FAILSAFE_RECHECK_MS);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
209
273
|
resolve({ status: "cancelled", errorContext: { message: "Unit hard timeout — supervision may have failed", category: "timeout", isTransient: true } });
|
|
210
|
-
}
|
|
274
|
+
};
|
|
275
|
+
unitTimeoutHandle = setTimeout(settleOrDefer, UNIT_HARD_TIMEOUT_MS);
|
|
211
276
|
});
|
|
212
277
|
result = await runWithTurnGeneration(capturedTurnGen, () =>
|
|
213
278
|
Promise.race([unitPromise, timeoutResult]),
|
|
@@ -88,6 +88,7 @@ export class AutoSession {
|
|
|
88
88
|
// ── Lifecycle ────────────────────────────────────────────────────────────
|
|
89
89
|
active = false;
|
|
90
90
|
paused = false;
|
|
91
|
+
completionStopInProgress = false;
|
|
91
92
|
stepMode = false;
|
|
92
93
|
verbose = false;
|
|
93
94
|
activeEngineId: string | null = null;
|
|
@@ -158,6 +159,7 @@ export class AutoSession {
|
|
|
158
159
|
pendingCrashRecovery: string | null = null;
|
|
159
160
|
pendingVerificationRetry: PendingVerificationRetry | null = null;
|
|
160
161
|
readonly verificationRetryCount = new Map<string, number>();
|
|
162
|
+
readonly verificationRetryFailureHashes = new Map<string, string>();
|
|
161
163
|
pausedSessionFile: string | null = null;
|
|
162
164
|
pausedUnitType: string | null = null;
|
|
163
165
|
pausedUnitId: string | null = null;
|
|
@@ -286,6 +288,7 @@ export class AutoSession {
|
|
|
286
288
|
// Lifecycle
|
|
287
289
|
this.active = false;
|
|
288
290
|
this.paused = false;
|
|
291
|
+
this.completionStopInProgress = false;
|
|
289
292
|
this.stepMode = false;
|
|
290
293
|
this.verbose = false;
|
|
291
294
|
this.activeEngineId = null;
|
|
@@ -334,6 +337,7 @@ export class AutoSession {
|
|
|
334
337
|
this.pendingCrashRecovery = null;
|
|
335
338
|
this.pendingVerificationRetry = null;
|
|
336
339
|
this.verificationRetryCount.clear();
|
|
340
|
+
this.verificationRetryFailureHashes.clear();
|
|
337
341
|
this.pausedSessionFile = null;
|
|
338
342
|
this.pausedUnitType = null;
|
|
339
343
|
this.pausedUnitId = null;
|
|
@@ -372,6 +376,12 @@ export class AutoSession {
|
|
|
372
376
|
// Loop promise state lives in auto-loop.ts module scope
|
|
373
377
|
}
|
|
374
378
|
|
|
379
|
+
resetAfterStop(options: { preserveCompletionSurface?: boolean } = {}): void {
|
|
380
|
+
const completionStopInProgress = options.preserveCompletionSurface ? this.completionStopInProgress : false;
|
|
381
|
+
this.reset();
|
|
382
|
+
this.completionStopInProgress = completionStopInProgress;
|
|
383
|
+
}
|
|
384
|
+
|
|
375
385
|
toJSON(): Record<string, unknown> {
|
|
376
386
|
const orchestrationStatus = this.orchestration?.getStatus();
|
|
377
387
|
return {
|