gsd-pi 2.81.0 → 2.82.0-dev.ed17d078d
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 +386 -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/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 +722 -316
- 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 +6 -6
- 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 +6 -6
- 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/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +2 -0
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
- 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/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 +424 -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 +291 -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 +65 -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 +572 -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/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 +1151 -524
- 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 → YEvjuT-fsFfYQhDSWtueS}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → YEvjuT-fsFfYQhDSWtueS}/_ssgManifest.js +0 -0
|
@@ -2,27 +2,31 @@
|
|
|
2
2
|
// File Purpose: Auto Orchestration module interfaces and ADR-015 invariant adapter contracts.
|
|
3
3
|
|
|
4
4
|
import type { GSDState } from "../types.js";
|
|
5
|
+
import type { MinimalModelRegistry } from "../context-budget.js";
|
|
5
6
|
|
|
6
7
|
export interface AutoSessionContext {
|
|
7
8
|
basePath: string;
|
|
8
9
|
trigger: "guided-flow" | "resume" | "auto-loop" | "manual";
|
|
9
10
|
}
|
|
10
11
|
|
|
12
|
+
export interface UnitRef {
|
|
13
|
+
unitType: string;
|
|
14
|
+
unitId: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
export interface AutoStatus {
|
|
12
18
|
phase: "idle" | "running" | "paused" | "stopped" | "error";
|
|
13
|
-
activeUnit?:
|
|
14
|
-
unitType: string;
|
|
15
|
-
unitId: string;
|
|
16
|
-
};
|
|
19
|
+
activeUnit?: UnitRef;
|
|
17
20
|
lastTransitionAt?: number;
|
|
18
21
|
transitionCount: number;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
export
|
|
22
|
-
kind: "advanced"
|
|
23
|
-
reason
|
|
24
|
-
stateSnapshot?: GSDState
|
|
25
|
-
}
|
|
24
|
+
export type AutoAdvanceResult =
|
|
25
|
+
| { kind: "advanced"; unit: UnitRef; stateSnapshot: GSDState }
|
|
26
|
+
| { kind: "blocked"; reason: string; action: "pause" | "stop"; stateSnapshot?: GSDState }
|
|
27
|
+
| { kind: "stopped"; reason: string; stateSnapshot?: GSDState }
|
|
28
|
+
| { kind: "paused"; reason: string }
|
|
29
|
+
| { kind: "error"; reason: string };
|
|
26
30
|
|
|
27
31
|
export interface AutoOrchestrationModule {
|
|
28
32
|
start(sessionContext: AutoSessionContext): Promise<AutoAdvanceResult>;
|
|
@@ -33,7 +37,17 @@ export interface AutoOrchestrationModule {
|
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
export interface DispatchAdapter {
|
|
36
|
-
decideNextUnit(input: {
|
|
40
|
+
decideNextUnit(input: {
|
|
41
|
+
stateSnapshot: GSDState;
|
|
42
|
+
/** Mirrors `DispatchContext.structuredQuestionsAvailable` — "true"/"false" string per the dispatch contract. */
|
|
43
|
+
structuredQuestionsAvailable?: "true" | "false";
|
|
44
|
+
/** Session model context window in tokens, forwarded to the budget engine. */
|
|
45
|
+
sessionContextWindow?: number;
|
|
46
|
+
/** Session model provider, used for provider-specific effective context windows. */
|
|
47
|
+
sessionProvider?: string;
|
|
48
|
+
/** Model registry for executor-model lookups inside the budget engine. */
|
|
49
|
+
modelRegistry?: MinimalModelRegistry;
|
|
50
|
+
}): Promise<{
|
|
37
51
|
unitType: string;
|
|
38
52
|
unitId: string;
|
|
39
53
|
reason: string;
|
|
@@ -70,11 +84,31 @@ export interface WorktreeAdapter {
|
|
|
70
84
|
cleanupOnStop(reason: string): Promise<void>;
|
|
71
85
|
}
|
|
72
86
|
|
|
87
|
+
export type HealthGateResult =
|
|
88
|
+
| { kind: "pass"; fixesApplied?: readonly string[] }
|
|
89
|
+
| { kind: "fail"; reason: string }
|
|
90
|
+
| { kind: "threw"; error: unknown };
|
|
91
|
+
|
|
73
92
|
export interface HealthAdapter {
|
|
74
|
-
|
|
93
|
+
checkResourcesStale(): string | null;
|
|
94
|
+
preAdvanceGate(): Promise<HealthGateResult>;
|
|
75
95
|
postAdvanceRecord(result: AutoAdvanceResult): Promise<void>;
|
|
76
96
|
}
|
|
77
97
|
|
|
98
|
+
export interface UokGateInput {
|
|
99
|
+
gateId: string;
|
|
100
|
+
gateType: "policy" | "execution";
|
|
101
|
+
outcome: "pass" | "fail" | "manual-attention";
|
|
102
|
+
failureClass: "none" | "policy" | "manual-attention";
|
|
103
|
+
rationale: string;
|
|
104
|
+
findings?: string;
|
|
105
|
+
milestoneId?: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface UokGateAdapter {
|
|
109
|
+
emit(input: UokGateInput): Promise<void>;
|
|
110
|
+
}
|
|
111
|
+
|
|
78
112
|
export interface RuntimePersistenceAdapter {
|
|
79
113
|
ensureLockOwnership(): Promise<void>;
|
|
80
114
|
journalTransition(event: {
|
|
@@ -101,4 +135,5 @@ export interface AutoOrchestratorDeps {
|
|
|
101
135
|
health: HealthAdapter;
|
|
102
136
|
runtime: RuntimePersistenceAdapter;
|
|
103
137
|
notifications: NotificationAdapter;
|
|
138
|
+
uokGate: UokGateAdapter;
|
|
104
139
|
}
|
|
@@ -26,6 +26,14 @@ import type { MergeReconcileResult } from "../auto-recovery.js";
|
|
|
26
26
|
import type { UokTurnObserver } from "../uok/contracts.js";
|
|
27
27
|
import type { PostflightResult, PreflightResult } from "../clean-root-preflight.js";
|
|
28
28
|
|
|
29
|
+
export interface StopAutoOptions {
|
|
30
|
+
completionWidget?: {
|
|
31
|
+
milestoneId?: string | null;
|
|
32
|
+
milestoneTitle?: string | null;
|
|
33
|
+
allMilestonesComplete?: boolean;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
29
37
|
type PauseAutoFn = (
|
|
30
38
|
ctx?: ExtensionContext,
|
|
31
39
|
pi?: ExtensionAPI,
|
|
@@ -46,6 +54,7 @@ export interface LoopDeps {
|
|
|
46
54
|
ctx?: ExtensionContext,
|
|
47
55
|
pi?: ExtensionAPI,
|
|
48
56
|
reason?: string,
|
|
57
|
+
options?: StopAutoOptions,
|
|
49
58
|
) => Promise<void>;
|
|
50
59
|
pauseAuto: PauseAutoFn;
|
|
51
60
|
clearUnitTimeout: () => void;
|
|
@@ -107,11 +116,6 @@ export interface LoopDeps {
|
|
|
107
116
|
pruneQueueOrder: (basePath: string, pendingIds: string[]) => void;
|
|
108
117
|
isInAutoWorktree: (basePath: string) => boolean;
|
|
109
118
|
shouldUseWorktreeIsolation: () => boolean;
|
|
110
|
-
mergeMilestoneToMain: (
|
|
111
|
-
basePath: string,
|
|
112
|
-
milestoneId: string,
|
|
113
|
-
roadmapContent: string,
|
|
114
|
-
) => { pushed: boolean; codeFilesChanged: boolean };
|
|
115
119
|
teardownAutoWorktree: (basePath: string, milestoneId: string) => void;
|
|
116
120
|
createAutoWorktree: (basePath: string, milestoneId: string) => string;
|
|
117
121
|
captureIntegrationBranch: (
|
|
@@ -399,6 +399,12 @@ export async function autoLoop(
|
|
|
399
399
|
|
|
400
400
|
let dispatchId: number | null = null;
|
|
401
401
|
let dispatchSettled = false;
|
|
402
|
+
let iterationEndEmitted = false;
|
|
403
|
+
const emitIterationEnd = (details: Record<string, unknown> = {}): void => {
|
|
404
|
+
if (iterationEndEmitted) return;
|
|
405
|
+
iterationEndEmitted = true;
|
|
406
|
+
journalReporter.emit("iteration-end", { iteration, ...details });
|
|
407
|
+
};
|
|
402
408
|
const completeIteration = (): void => {
|
|
403
409
|
completeWorkflowIteration({
|
|
404
410
|
get consecutiveErrors() { return consecutiveErrors; },
|
|
@@ -407,11 +413,15 @@ export async function autoLoop(
|
|
|
407
413
|
set consecutiveCooldowns(value) { consecutiveCooldowns = value; },
|
|
408
414
|
recentErrorMessages,
|
|
409
415
|
}, {
|
|
410
|
-
emitIterationEnd: () =>
|
|
416
|
+
emitIterationEnd: () => emitIterationEnd(),
|
|
411
417
|
saveStuckState: () => saveStuckState(s, loopState),
|
|
412
418
|
logIterationComplete: () => debugLog("autoLoop", { phase: "iteration-complete", iteration }),
|
|
413
419
|
});
|
|
414
420
|
};
|
|
421
|
+
const finishIncompleteIteration = (details: Record<string, unknown>): void => {
|
|
422
|
+
emitIterationEnd(details);
|
|
423
|
+
saveStuckState(s, loopState);
|
|
424
|
+
};
|
|
415
425
|
|
|
416
426
|
try {
|
|
417
427
|
// ── Blanket try/catch: one bad iteration must not kill the session
|
|
@@ -492,6 +502,7 @@ export async function autoLoop(
|
|
|
492
502
|
});
|
|
493
503
|
if (engineState.isComplete) {
|
|
494
504
|
finishTurn("completed");
|
|
505
|
+
emitIterationEnd({ status: "completed", reason: "custom-engine-complete" });
|
|
495
506
|
await deps.stopAuto(ctx, pi, "Workflow complete");
|
|
496
507
|
break;
|
|
497
508
|
}
|
|
@@ -509,16 +520,23 @@ export async function autoLoop(
|
|
|
509
520
|
});
|
|
510
521
|
if (dispatchFlow.action === "break") {
|
|
511
522
|
finishTurn("stopped", "manual-attention", "custom-engine-dispatch-stop");
|
|
523
|
+
finishIncompleteIteration({
|
|
524
|
+
status: "stopped",
|
|
525
|
+
reason: "custom-engine-dispatch-stop",
|
|
526
|
+
failureClass: "manual-attention",
|
|
527
|
+
});
|
|
512
528
|
break;
|
|
513
529
|
}
|
|
514
530
|
if (dispatchFlow.action === "continue") {
|
|
515
531
|
finishTurn("skipped");
|
|
532
|
+
emitIterationEnd({ status: "skipped", reason: "custom-engine-dispatch-skip" });
|
|
516
533
|
continue;
|
|
517
534
|
}
|
|
518
535
|
|
|
519
536
|
// dispatch.action === "dispatch"
|
|
520
537
|
if (dispatch.action !== "dispatch") {
|
|
521
538
|
finishTurn("skipped");
|
|
539
|
+
emitIterationEnd({ status: "skipped", reason: "custom-engine-dispatch-mismatch" });
|
|
522
540
|
continue;
|
|
523
541
|
}
|
|
524
542
|
const step = dispatch.step;
|
|
@@ -547,6 +565,13 @@ export async function autoLoop(
|
|
|
547
565
|
});
|
|
548
566
|
if (guardsResult.action === "break") {
|
|
549
567
|
finishTurn("stopped", "manual-attention", "guard-break");
|
|
568
|
+
finishIncompleteIteration({
|
|
569
|
+
status: "stopped",
|
|
570
|
+
reason: "guard-break",
|
|
571
|
+
unitType: iterData.unitType,
|
|
572
|
+
unitId: iterData.unitId,
|
|
573
|
+
failureClass: "manual-attention",
|
|
574
|
+
});
|
|
550
575
|
break;
|
|
551
576
|
}
|
|
552
577
|
|
|
@@ -578,6 +603,13 @@ export async function autoLoop(
|
|
|
578
603
|
unitId: iterData.unitId,
|
|
579
604
|
});
|
|
580
605
|
if (unitPhaseResult.action === "break") {
|
|
606
|
+
finishIncompleteIteration({
|
|
607
|
+
status: "stopped",
|
|
608
|
+
reason: unitPhaseResult.reason ?? "unit-break",
|
|
609
|
+
unitType: iterData.unitType,
|
|
610
|
+
unitId: iterData.unitId,
|
|
611
|
+
failureClass: "execution",
|
|
612
|
+
});
|
|
581
613
|
finishTurn("stopped", "execution", "unit-break");
|
|
582
614
|
break;
|
|
583
615
|
}
|
|
@@ -596,7 +628,16 @@ export async function autoLoop(
|
|
|
596
628
|
finishTurn,
|
|
597
629
|
},
|
|
598
630
|
});
|
|
599
|
-
if (verifyFlow.action === "break")
|
|
631
|
+
if (verifyFlow.action === "break") {
|
|
632
|
+
finishIncompleteIteration({
|
|
633
|
+
status: "paused",
|
|
634
|
+
reason: "custom-engine-verify-pause",
|
|
635
|
+
unitType: iterData.unitType,
|
|
636
|
+
unitId: iterData.unitId,
|
|
637
|
+
failureClass: "manual-attention",
|
|
638
|
+
});
|
|
639
|
+
break;
|
|
640
|
+
}
|
|
600
641
|
}
|
|
601
642
|
if (verifyResult === "retry") {
|
|
602
643
|
const retryOutcome = await handleCustomEngineVerifyRetry({
|
|
@@ -630,7 +671,22 @@ export async function autoLoop(
|
|
|
630
671
|
finishTurn,
|
|
631
672
|
},
|
|
632
673
|
});
|
|
633
|
-
if (retryFlow.action === "break")
|
|
674
|
+
if (retryFlow.action === "break") {
|
|
675
|
+
finishIncompleteIteration({
|
|
676
|
+
status: retryOutcome.action === "stop" ? "stopped" : "paused",
|
|
677
|
+
reason: retryOutcome.action === "retry" ? "custom-engine-verify-retry" : retryOutcome.turnError,
|
|
678
|
+
unitType: iterData.unitType,
|
|
679
|
+
unitId: iterData.unitId,
|
|
680
|
+
failureClass: "manual-attention",
|
|
681
|
+
});
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
684
|
+
finishIncompleteIteration({
|
|
685
|
+
status: "retry",
|
|
686
|
+
reason: "custom-engine-verify-retry",
|
|
687
|
+
unitType: iterData.unitType,
|
|
688
|
+
unitId: iterData.unitId,
|
|
689
|
+
});
|
|
634
690
|
continue;
|
|
635
691
|
}
|
|
636
692
|
|
|
@@ -841,6 +897,13 @@ export async function autoLoop(
|
|
|
841
897
|
markFailed: markDispatchFailed,
|
|
842
898
|
logWriteFailure: logDispatchLedgerWriteFailure,
|
|
843
899
|
}) || dispatchSettled;
|
|
900
|
+
finishIncompleteIteration({
|
|
901
|
+
status: "stopped",
|
|
902
|
+
reason: unitPhaseResult.reason ?? "unit-break",
|
|
903
|
+
unitType: iterData.unitType,
|
|
904
|
+
unitId: iterData.unitId,
|
|
905
|
+
failureClass: "execution",
|
|
906
|
+
});
|
|
844
907
|
finishTurn("stopped", "execution", "unit-break");
|
|
845
908
|
break;
|
|
846
909
|
}
|
|
@@ -848,12 +911,25 @@ export async function autoLoop(
|
|
|
848
911
|
// ── Phase 5: Finalize ───────────────────────────────────────────────
|
|
849
912
|
|
|
850
913
|
let finalizeResult: Awaited<ReturnType<typeof runFinalize>>;
|
|
914
|
+
journalReporter.emit("post-unit-finalize-start", {
|
|
915
|
+
iteration,
|
|
916
|
+
unitType: iterData.unitType,
|
|
917
|
+
unitId: iterData.unitId,
|
|
918
|
+
});
|
|
851
919
|
try {
|
|
852
920
|
finalizeResult = await runFinalize(ic, iterData, loopState, sidecarItem);
|
|
853
921
|
} catch (err) {
|
|
922
|
+
const error = formatDispatchExceptionSummary({ error: err });
|
|
923
|
+
journalReporter.emit("post-unit-finalize-end", {
|
|
924
|
+
iteration,
|
|
925
|
+
unitType: iterData.unitType,
|
|
926
|
+
unitId: iterData.unitId,
|
|
927
|
+
status: "failed",
|
|
928
|
+
error,
|
|
929
|
+
});
|
|
854
930
|
dispatchSettled = settleDispatchFailed(
|
|
855
931
|
dispatchId,
|
|
856
|
-
|
|
932
|
+
error,
|
|
857
933
|
{
|
|
858
934
|
markFailed: markDispatchFailed,
|
|
859
935
|
logWriteFailure: logDispatchLedgerWriteFailure,
|
|
@@ -865,6 +941,15 @@ export async function autoLoop(
|
|
|
865
941
|
unitType: iterData.unitType,
|
|
866
942
|
unitId: iterData.unitId,
|
|
867
943
|
});
|
|
944
|
+
const finalizeReason = finalizeResult.action === "break" ? finalizeResult.reason : undefined;
|
|
945
|
+
journalReporter.emit("post-unit-finalize-end", {
|
|
946
|
+
iteration,
|
|
947
|
+
unitType: iterData.unitType,
|
|
948
|
+
unitId: iterData.unitId,
|
|
949
|
+
status: finalizeResult.action === "next" ? "completed" : finalizeResult.action === "continue" ? "retry" : "stopped",
|
|
950
|
+
action: finalizeResult.action,
|
|
951
|
+
...(finalizeReason ? { reason: finalizeReason } : {}),
|
|
952
|
+
});
|
|
868
953
|
const finalizeDecision = decideFinalizeResult(
|
|
869
954
|
finalizeResult.action === "break"
|
|
870
955
|
? { action: "break", reason: finalizeResult.reason }
|
|
@@ -877,6 +962,13 @@ export async function autoLoop(
|
|
|
877
962
|
markFailed: markDispatchFailed,
|
|
878
963
|
logWriteFailure: logDispatchLedgerWriteFailure,
|
|
879
964
|
}) || dispatchSettled;
|
|
965
|
+
finishIncompleteIteration({
|
|
966
|
+
status: "stopped",
|
|
967
|
+
reason: finalizeReason ?? "finalize-break",
|
|
968
|
+
unitType: iterData.unitType,
|
|
969
|
+
unitId: iterData.unitId,
|
|
970
|
+
failureClass: finalizeDecision.failureClass,
|
|
971
|
+
});
|
|
880
972
|
finishTurn("stopped", finalizeDecision.failureClass, finalizeDecision.turnError);
|
|
881
973
|
break;
|
|
882
974
|
}
|
|
@@ -885,6 +977,12 @@ export async function autoLoop(
|
|
|
885
977
|
markFailed: markDispatchFailed,
|
|
886
978
|
logWriteFailure: logDispatchLedgerWriteFailure,
|
|
887
979
|
}) || dispatchSettled;
|
|
980
|
+
finishIncompleteIteration({
|
|
981
|
+
status: "retry",
|
|
982
|
+
reason: "finalize-retry",
|
|
983
|
+
unitType: iterData.unitType,
|
|
984
|
+
unitId: iterData.unitId,
|
|
985
|
+
});
|
|
888
986
|
finishTurn("retry");
|
|
889
987
|
continue;
|
|
890
988
|
}
|
|
@@ -909,11 +1007,6 @@ export async function autoLoop(
|
|
|
909
1007
|
) || dispatchSettled;
|
|
910
1008
|
}
|
|
911
1009
|
|
|
912
|
-
// Always emit iteration-end on error so the journal records iteration
|
|
913
|
-
// completion even on failure (#2344). Without this, errors in
|
|
914
|
-
// runFinalize leave the journal incomplete, making diagnosis harder.
|
|
915
|
-
journalReporter.emit("iteration-end", { iteration, error: msg });
|
|
916
|
-
|
|
917
1010
|
// ── Pre-send model-policy block: not a retryable error (#4959 / #4850) ──
|
|
918
1011
|
// The model-policy gate runs before the prompt is sent. When every
|
|
919
1012
|
// candidate model is denied (cross-provider disabled + flat-rate
|
|
@@ -938,6 +1031,12 @@ export async function autoLoop(
|
|
|
938
1031
|
});
|
|
939
1032
|
ctx.ui.notify(policyDecision.notifyMessage, "error");
|
|
940
1033
|
journalReporter.emit("unit-end", policyDecision.journalData);
|
|
1034
|
+
finishIncompleteIteration({
|
|
1035
|
+
status: "blocked",
|
|
1036
|
+
reason: "model-policy-dispatch-blocked",
|
|
1037
|
+
unitType: loopErr.unitType,
|
|
1038
|
+
unitId: loopErr.unitId,
|
|
1039
|
+
});
|
|
941
1040
|
// Carry the blocked unit identity into the turn-result observer:
|
|
942
1041
|
// the throw originated inside dispatch, so observedUnitType/Id were
|
|
943
1042
|
// not assigned by the success path at lines 453/631/647 — but the
|
|
@@ -951,6 +1050,11 @@ export async function autoLoop(
|
|
|
951
1050
|
break;
|
|
952
1051
|
}
|
|
953
1052
|
|
|
1053
|
+
// Always emit iteration-end on error so the journal records iteration
|
|
1054
|
+
// completion even on failure (#2344). Without this, errors in
|
|
1055
|
+
// runFinalize leave the journal incomplete, making diagnosis harder.
|
|
1056
|
+
finishIncompleteIteration({ status: "failed", error: msg });
|
|
1057
|
+
|
|
954
1058
|
// ── Infrastructure errors: immediate stop, no retry ──
|
|
955
1059
|
// These are unrecoverable (disk full, OOM, etc.). Retrying just burns
|
|
956
1060
|
// LLM budget on guaranteed failures.
|
|
@@ -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 });
|