@opengsd/gsd-pi 1.5.0-dev.553dc518 → 1.5.0-dev.c4c8885f
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/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +114 -36
- package/dist/resources/extensions/gsd/activity-log.js +1 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +16 -10
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -5
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +7 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +69 -17
- package/dist/resources/extensions/gsd/auto-model-selection.js +28 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +29 -117
- package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
- package/dist/resources/extensions/gsd/auto-start.js +54 -31
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +12 -2
- package/dist/resources/extensions/gsd/auto-timers.js +9 -2
- package/dist/resources/extensions/gsd/auto.js +97 -31
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +67 -6
- package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
- package/dist/resources/extensions/gsd/compat/compat-marker.js +44 -0
- package/dist/resources/extensions/gsd/config-overlay.js +7 -2
- package/dist/resources/extensions/gsd/db/engine.js +33 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
- package/dist/resources/extensions/gsd/db-adapter.js +30 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +3 -3
- package/dist/resources/extensions/gsd/flat-phase-migration.js +18 -0
- package/dist/resources/extensions/gsd/gsd-db.js +12 -11
- package/dist/resources/extensions/gsd/guided-flow.js +16 -7
- package/dist/resources/extensions/gsd/journal.js +1 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +34 -91
- package/dist/resources/extensions/gsd/md-importer.js +89 -23
- package/dist/resources/extensions/gsd/metrics.js +2 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
- package/dist/resources/extensions/gsd/paths.js +87 -52
- package/dist/resources/extensions/gsd/post-unit-hooks.js +27 -0
- package/dist/resources/extensions/gsd/preferences-models.js +66 -15
- package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
- package/dist/resources/extensions/gsd/preferences-validation.js +66 -10
- package/dist/resources/extensions/gsd/preferences.js +20 -0
- package/dist/resources/extensions/gsd/rule-registry.js +106 -10
- package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +1 -10
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +3 -24
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +10 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -5
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +16 -10
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
- package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
- package/dist/resources/extensions/gsd/uok/audit-toggle.js +31 -2
- package/dist/resources/extensions/gsd/uok/audit.js +3 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +22 -30
- package/dist/resources/extensions/gsd/uok/gitops.js +18 -15
- package/dist/resources/extensions/gsd/uok/kernel.js +120 -46
- package/dist/resources/extensions/gsd/uok/model-policy.js +17 -14
- package/dist/resources/extensions/gsd/workflow-event-ledger.js +1 -1
- package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +9 -26
- package/dist/resources/extensions/gsd/workspace.js +5 -14
- package/dist/resources/extensions/shared/gsd-browser-cli.js +29 -0
- package/dist/resources/extensions/shared/interview-ui.js +62 -9
- 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 +10 -10
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +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/worktree-cli-create.d.ts +10 -0
- package/dist/worktree-cli-create.js +11 -0
- package/dist/worktree-cli-format.d.ts +12 -0
- package/dist/worktree-cli-format.js +38 -0
- package/dist/worktree-cli-plan.d.ts +16 -0
- package/dist/worktree-cli-plan.js +19 -0
- package/dist/worktree-cli-session.d.ts +13 -0
- package/dist/worktree-cli-session.js +18 -0
- package/dist/worktree-cli-status.d.ts +35 -0
- package/dist/worktree-cli-status.js +54 -0
- package/dist/worktree-cli.d.ts +1 -16
- package/dist/worktree-cli.js +28 -122
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/orchestrator-agent.d.ts +21 -0
- package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
- package/packages/daemon/dist/orchestrator-agent.js +113 -0
- package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
- package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
- package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
- package/packages/daemon/dist/orchestrator-tools.js +137 -0
- package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
- package/packages/daemon/dist/orchestrator.d.ts +4 -56
- package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
- package/packages/daemon/dist/orchestrator.js +13 -303
- package/packages/daemon/dist/orchestrator.js.map +1 -1
- package/packages/daemon/dist/orchestrator.test.js +11 -1
- package/packages/daemon/dist/orchestrator.test.js.map +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +4 -1
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +1 -1
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +146 -33
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +25 -0
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
- package/src/resources/extensions/gsd/activity-log.ts +1 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +17 -11
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -4
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +9 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +77 -16
- package/src/resources/extensions/gsd/auto-model-selection.ts +33 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +53 -113
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
- package/src/resources/extensions/gsd/auto-start.ts +58 -29
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -2
- package/src/resources/extensions/gsd/auto-timers.ts +9 -2
- package/src/resources/extensions/gsd/auto.ts +103 -30
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +66 -6
- package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
- package/src/resources/extensions/gsd/compat/compat-marker.ts +47 -0
- package/src/resources/extensions/gsd/config-overlay.ts +7 -1
- package/src/resources/extensions/gsd/db/engine.ts +36 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
- package/src/resources/extensions/gsd/db-adapter.ts +29 -3
- package/src/resources/extensions/gsd/docs/preferences-reference.md +3 -3
- package/src/resources/extensions/gsd/flat-phase-migration.ts +20 -0
- package/src/resources/extensions/gsd/gsd-db.ts +20 -11
- package/src/resources/extensions/gsd/guided-flow.ts +19 -7
- package/src/resources/extensions/gsd/journal.ts +1 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +52 -103
- package/src/resources/extensions/gsd/md-importer.ts +93 -22
- package/src/resources/extensions/gsd/metrics.ts +2 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
- package/src/resources/extensions/gsd/paths.ts +108 -51
- package/src/resources/extensions/gsd/post-unit-hooks.ts +32 -0
- package/src/resources/extensions/gsd/preferences-models.ts +74 -20
- package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
- package/src/resources/extensions/gsd/preferences-types.ts +24 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +77 -9
- package/src/resources/extensions/gsd/preferences.ts +20 -0
- package/src/resources/extensions/gsd/rule-registry.ts +111 -9
- package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +1 -9
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +2 -22
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +14 -0
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +41 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-timeout-recovery-supervisor-inflight-guard.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/db-adapter.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/db-writable-probe.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
- package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +269 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +95 -1
- package/src/resources/extensions/gsd/tests/sibling-model-fallbacks.test.ts +189 -0
- package/src/resources/extensions/gsd/tests/single-field-model-thinking.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/supervisor-model-swap-inflight-guard.test.ts +181 -0
- package/src/resources/extensions/gsd/tests/supervisor-model-swap-thinking-clamp.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +226 -2
- package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +9 -5
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +19 -8
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
- package/src/resources/extensions/gsd/types.ts +23 -4
- package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
- package/src/resources/extensions/gsd/uok/audit-toggle.ts +32 -2
- package/src/resources/extensions/gsd/uok/audit.ts +2 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +26 -36
- package/src/resources/extensions/gsd/uok/gitops.ts +21 -18
- package/src/resources/extensions/gsd/uok/kernel.ts +169 -48
- package/src/resources/extensions/gsd/uok/model-policy.ts +20 -17
- package/src/resources/extensions/gsd/workflow-event-ledger.ts +1 -1
- package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +9 -24
- package/src/resources/extensions/gsd/workspace.ts +5 -21
- package/src/resources/extensions/shared/gsd-browser-cli.ts +29 -0
- package/src/resources/extensions/shared/interview-ui.ts +58 -11
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
- /package/dist/web/standalone/.next/static/{ZpFDazP-38PXBPiI_LdZf → NPMNi2HV8BuK3baQsEUhk}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ZpFDazP-38PXBPiI_LdZf → NPMNi2HV8BuK3baQsEUhk}/_ssgManifest.js +0 -0
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* utility.
|
|
9
9
|
*/
|
|
10
10
|
import { loadFile, parseContinue, parseSummary, loadActiveOverrides, formatOverridesSection } from "./files.js";
|
|
11
|
-
import {
|
|
11
|
+
import { extractVerdict } from "./verdict-parser.js";
|
|
12
12
|
import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
|
|
13
13
|
import { resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveTasksDir, resolveTaskFiles, resolveTaskFile, relMilestoneFile, relSliceFile, relSlicePath, relMilestonePath, relTaskFile, resolveGsdRootFile, relGsdRootFile, resolveRuntimeFile, } from "./paths.js";
|
|
14
14
|
import { resolveInlineLevel, loadEffectiveGSDPreferences } from "./preferences.js";
|
|
@@ -35,7 +35,8 @@ import { debugLog } from "./debug-logger.js";
|
|
|
35
35
|
import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
|
|
36
36
|
import { findMilestoneIds } from "./milestone-ids.js";
|
|
37
37
|
import { buildRunUatPresentationForType, RUN_UAT_TOOL_PRESENTATION_PLAN_ID } from "./tool-presentation-plan.js";
|
|
38
|
-
import { classifyUatContentForRun
|
|
38
|
+
import { classifyUatContentForRun } from "./uat-policy.js";
|
|
39
|
+
import { checkNeedsRunUat as resolveNeedsRunUat } from "./uat-dispatch.js";
|
|
39
40
|
import { buildWebAppUatGuidanceBlock } from "./web-app-uat.js";
|
|
40
41
|
export { buildSkillActivationBlock, buildSkillDiscoveryVars };
|
|
41
42
|
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
@@ -1320,120 +1321,26 @@ export async function checkNeedsReassessment(base, mid, state) {
|
|
|
1320
1321
|
return null;
|
|
1321
1322
|
return { sliceId: lastDone };
|
|
1322
1323
|
}
|
|
1324
|
+
export function getRoadmapCompletedSliceCandidates(roadmapContent) {
|
|
1325
|
+
return parseRoadmap(roadmapContent)
|
|
1326
|
+
.slices.filter((slice) => slice.done)
|
|
1327
|
+
.map((slice) => ({ sliceId: slice.id }))
|
|
1328
|
+
.reverse();
|
|
1329
|
+
}
|
|
1330
|
+
export async function loadRoadmapCompletedSliceCandidates(base, mid) {
|
|
1331
|
+
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
1332
|
+
const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
|
|
1333
|
+
return roadmapContent ? getRoadmapCompletedSliceCandidates(roadmapContent) : [];
|
|
1334
|
+
}
|
|
1323
1335
|
/**
|
|
1324
|
-
*
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1327
|
-
*
|
|
1328
|
-
* - No roadmap or no completed slices
|
|
1329
|
-
* - uat_dispatch is not enabled and the UAT spec does not require runtime/browser evidence
|
|
1330
|
-
* - No UAT file exists for the slice
|
|
1331
|
-
* - UAT result file already exists (idempotent — already ran)
|
|
1332
|
-
*/
|
|
1333
|
-
/**
|
|
1334
|
-
* Resolve the effective UAT mode for the dispatch gate the same way
|
|
1335
|
-
* `buildRunUatPrompt` does: classify the UAT body with the slice's SUMMARY as
|
|
1336
|
-
* supplemental context, so a `browser-executable` UAT whose slice references a
|
|
1337
|
-
* self-contained harness (`npm run test:uat`, `search-uat.mjs`, `npx
|
|
1338
|
-
* playwright test`) is promoted to `runtime-executable` for the gate too.
|
|
1339
|
-
*
|
|
1340
|
-
* Without this, `checkNeedsRunUat` returns `browser-executable` while the
|
|
1341
|
-
* prompt instructs runtime-only execution, causing the dispatch gate to
|
|
1342
|
-
* require browser tools / warm up the browser daemon (or stop dispatch when
|
|
1343
|
-
* browser MCP is unavailable) for UAT runs that never touch the browser. See
|
|
1344
|
-
* cursor[bot] review on PR #696 for the M007/S01 regression.
|
|
1336
|
+
* Back-compat wrapper for callers that import UAT dispatch checks from the
|
|
1337
|
+
* prompt module. UAT dispatch architecture lives in `uat-dispatch.ts`; the
|
|
1338
|
+
* `state` parameter is intentionally ignored because DB/roadmap artifacts are
|
|
1339
|
+
* the source of truth for completed-slice discovery.
|
|
1345
1340
|
*/
|
|
1346
|
-
async function resolveRunUatEffectiveType(base, mid, sliceId, uatContent) {
|
|
1347
|
-
let summaryContent = "";
|
|
1348
|
-
try {
|
|
1349
|
-
const summaryPath = resolveSliceFile(base, mid, sliceId, "SUMMARY");
|
|
1350
|
-
if (summaryPath) {
|
|
1351
|
-
summaryContent = (await loadFile(summaryPath)) ?? "";
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
catch (err) {
|
|
1355
|
-
logWarning("prompt", `resolveRunUatEffectiveType SUMMARY load failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1356
|
-
}
|
|
1357
|
-
return classifyUatContentForRun(uatContent, summaryContent).effectiveType;
|
|
1358
|
-
}
|
|
1359
1341
|
export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
const { isDbAvailable, getMilestoneSlices } = await import("./gsd-db.js");
|
|
1363
|
-
if (isDbAvailable()) {
|
|
1364
|
-
const slices = getMilestoneSlices(mid);
|
|
1365
|
-
if (slices.length > 0) {
|
|
1366
|
-
const completedSlices = slices.filter(s => s.status === "complete");
|
|
1367
|
-
if (completedSlices.length === 0)
|
|
1368
|
-
return null;
|
|
1369
|
-
for (const completed of [...completedSlices].reverse()) {
|
|
1370
|
-
const sid = completed.id;
|
|
1371
|
-
const uatFile = resolveSliceFile(base, mid, sid, "UAT");
|
|
1372
|
-
if (!uatFile)
|
|
1373
|
-
continue;
|
|
1374
|
-
const uatContent = await loadFile(uatFile);
|
|
1375
|
-
if (!uatContent)
|
|
1376
|
-
continue;
|
|
1377
|
-
// If the UAT file already contains a verdict, UAT has been run — skip
|
|
1378
|
-
if (hasVerdict(uatContent))
|
|
1379
|
-
continue;
|
|
1380
|
-
// Also check the ASSESSMENT file — the run-uat prompt writes the verdict
|
|
1381
|
-
// there (via gsd_uat_result_save), not into the
|
|
1382
|
-
// UAT spec file. Without this check the unit re-dispatches indefinitely.
|
|
1383
|
-
const assessmentFile = resolveSliceFile(base, mid, sid, "ASSESSMENT");
|
|
1384
|
-
if (assessmentFile) {
|
|
1385
|
-
const assessmentContent = await loadFile(assessmentFile);
|
|
1386
|
-
if (assessmentContent && hasVerdict(assessmentContent))
|
|
1387
|
-
continue;
|
|
1388
|
-
}
|
|
1389
|
-
if (!shouldDispatchUatForContent(uatContent, prefs))
|
|
1390
|
-
continue;
|
|
1391
|
-
const uatType = await resolveRunUatEffectiveType(base, mid, sid, uatContent);
|
|
1392
|
-
return { sliceId: sid, uatType };
|
|
1393
|
-
}
|
|
1394
|
-
return null;
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
catch (err) {
|
|
1399
|
-
logWarning("prompt", `checkNeedsRunUat DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1400
|
-
}
|
|
1401
|
-
// File-based fallback using roadmap checkboxes
|
|
1402
|
-
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
1403
|
-
if (!roadmapPath)
|
|
1404
|
-
return null;
|
|
1405
|
-
const roadmapContent = await loadFile(roadmapPath);
|
|
1406
|
-
if (!roadmapContent)
|
|
1407
|
-
return null;
|
|
1408
|
-
const parsed = parseRoadmap(roadmapContent);
|
|
1409
|
-
const completedFileSlices = parsed.slices.filter(s => s.done);
|
|
1410
|
-
if (completedFileSlices.length === 0)
|
|
1411
|
-
return null;
|
|
1412
|
-
for (const completed of [...completedFileSlices].reverse()) {
|
|
1413
|
-
const uatSid = completed.id;
|
|
1414
|
-
const uatFileFb = resolveSliceFile(base, mid, uatSid, "UAT");
|
|
1415
|
-
if (!uatFileFb)
|
|
1416
|
-
continue;
|
|
1417
|
-
const uatContentFb = await loadFile(uatFileFb);
|
|
1418
|
-
if (!uatContentFb)
|
|
1419
|
-
continue;
|
|
1420
|
-
// If the UAT file already contains a verdict, UAT has been run — skip
|
|
1421
|
-
if (hasVerdict(uatContentFb))
|
|
1422
|
-
continue;
|
|
1423
|
-
// Also check the ASSESSMENT file for the file-based fallback path (same
|
|
1424
|
-
// reason as the DB path above — verdict lives in ASSESSMENT, not UAT).
|
|
1425
|
-
const assessmentFileFb = resolveSliceFile(base, mid, uatSid, "ASSESSMENT");
|
|
1426
|
-
if (assessmentFileFb) {
|
|
1427
|
-
const assessmentContentFb = await loadFile(assessmentFileFb);
|
|
1428
|
-
if (assessmentContentFb && hasVerdict(assessmentContentFb))
|
|
1429
|
-
continue;
|
|
1430
|
-
}
|
|
1431
|
-
if (!shouldDispatchUatForContent(uatContentFb, prefs))
|
|
1432
|
-
continue;
|
|
1433
|
-
const uatType = await resolveRunUatEffectiveType(base, mid, uatSid, uatContentFb);
|
|
1434
|
-
return { sliceId: uatSid, uatType };
|
|
1435
|
-
}
|
|
1436
|
-
return null;
|
|
1342
|
+
void state;
|
|
1343
|
+
return resolveNeedsRunUat(base, mid, prefs, await loadRoadmapCompletedSliceCandidates(base, mid));
|
|
1437
1344
|
}
|
|
1438
1345
|
export async function buildDiscussMilestoneInlinedContext(mid, base) {
|
|
1439
1346
|
const inlined = [];
|
|
@@ -3401,10 +3308,15 @@ export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId
|
|
|
3401
3308
|
* that instructs the coordinator how to dispatch a `subagent` call. Either or
|
|
3402
3309
|
* both may be absent (ADR-026 / #508).
|
|
3403
3310
|
*/
|
|
3404
|
-
function subagentCallSuffix(model, thinking) {
|
|
3311
|
+
function subagentCallSuffix(model, thinking, fallbacks) {
|
|
3405
3312
|
const parts = [];
|
|
3406
|
-
if (model)
|
|
3407
|
-
|
|
3313
|
+
if (model) {
|
|
3314
|
+
let modelHint = `model: "${model}"`;
|
|
3315
|
+
if (fallbacks && fallbacks.length > 0) {
|
|
3316
|
+
modelHint += ` (fallbacks, in order: ${fallbacks.map((f) => `"${f}"`).join(", ")})`;
|
|
3317
|
+
}
|
|
3318
|
+
parts.push(modelHint);
|
|
3319
|
+
}
|
|
3408
3320
|
if (thinking)
|
|
3409
3321
|
parts.push(`thinking: "${thinking}"`);
|
|
3410
3322
|
return parts.length > 0 ? ` with ${parts.join(" and ")}` : "";
|
|
@@ -3490,7 +3402,7 @@ opts) {
|
|
|
3490
3402
|
"",
|
|
3491
3403
|
`When done, say: "Task ${tid} complete."`,
|
|
3492
3404
|
].join("\n");
|
|
3493
|
-
const modelSuffix = subagentCallSuffix(subagentModel, opts?.subagentThinking);
|
|
3405
|
+
const modelSuffix = subagentCallSuffix(subagentModel, opts?.subagentThinking, opts?.subagentModelFallbacks);
|
|
3494
3406
|
subagentSections.push([
|
|
3495
3407
|
`### ${tid}: ${tTitle}`,
|
|
3496
3408
|
"",
|
|
@@ -149,12 +149,56 @@ export function refreshRecoveryDbForArtifact(unitType, unitId, basePath) {
|
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
151
|
if (!isClosedStatus(task.status)) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
152
|
+
// The artifact was already confirmed on disk by verifyExpectedArtifact
|
|
153
|
+
// upstream (Gate 1 accepts a checked disk checkbox as proof of completion),
|
|
154
|
+
// but the DB task row is still open. A bare refreshWorkflowDatabaseFromDisk
|
|
155
|
+
// never promotes the disk checkbox into task status (the checkbox is
|
|
156
|
+
// rendered *from* the DB, never *into* it), so this divergence can never
|
|
157
|
+
// self-heal. Promote the task to align the DB with disk instead of failing
|
|
158
|
+
// shut — otherwise the lowest-pending derivation re-picks the same task
|
|
159
|
+
// forever and execute-task hard-stops with "state did not advance" (#1204).
|
|
160
|
+
// Mirrors the promotion pattern used by the context-exhaustion and
|
|
161
|
+
// reactive-execute-blocker recovery paths.
|
|
162
|
+
const ts = new Date().toISOString();
|
|
163
|
+
// Only the DB promotion is load-bearing: if it throws, nothing advanced
|
|
164
|
+
// and failing shut is correct. The plan checkbox rewrite and cache clears
|
|
165
|
+
// are best-effort follow-ups — a throw there must NOT abort recovery, or
|
|
166
|
+
// the DB is left complete without ever emitting the stuck-artifact-recovery
|
|
167
|
+
// event (#1221), stranding worktree reconciliation.
|
|
168
|
+
try {
|
|
169
|
+
updateTaskStatus(mid, sid, tid, "complete", ts);
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
return {
|
|
173
|
+
ok: false,
|
|
174
|
+
fatal: true,
|
|
175
|
+
reason: "execute-task-artifact-db-promote-failed",
|
|
176
|
+
message: `Stuck recovery found execute-task ${unitId} artifacts, but promoting the DB task status from '${task.status}' failed: ${getErrorMessage(e)}`,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const artifactBase = resolveArtifactVerificationBase(unitId, basePath);
|
|
181
|
+
const planPath = resolveExpectedArtifactPath("plan-slice", `${mid}/${sid}`, artifactBase);
|
|
182
|
+
if (planPath && existsSync(planPath)) {
|
|
183
|
+
const planContent = readFileSync(planPath, "utf-8");
|
|
184
|
+
const updatedPlan = planContent.replace(new RegExp(`^(\\s*-\\s+)\\[ \\]\\s+\\*\\*${tid}:`, "m"), `$1[x] **${tid}:`);
|
|
185
|
+
if (updatedPlan !== planContent) {
|
|
186
|
+
atomicWriteSync(planPath, updatedPlan);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
clearPathCache();
|
|
190
|
+
clearParseCache();
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
logWarning("recovery", `stuck-artifact plan checkbox sync failed after DB promotion of ${unitId}: ${getErrorMessage(e)}`);
|
|
194
|
+
}
|
|
195
|
+
// Append event so worktree reconciliation can replay this recovery completion.
|
|
196
|
+
try {
|
|
197
|
+
appendEvent(basePath, { cmd: "complete-task", params: { milestoneId: mid, sliceId: sid, taskId: tid }, ts, actor: "system", trigger_reason: "stuck-artifact-recovery" });
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
logWarning("recovery", `appendEvent failed for stuck-artifact task promotion: ${getErrorMessage(e)}`);
|
|
201
|
+
}
|
|
158
202
|
}
|
|
159
203
|
return { ok: true };
|
|
160
204
|
}
|
|
@@ -36,10 +36,10 @@ import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
|
|
|
36
36
|
import { queryJournal } from "./journal.js";
|
|
37
37
|
import { initMetrics } from "./metrics.js";
|
|
38
38
|
import { initRoutingHistory } from "./routing-history.js";
|
|
39
|
-
import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
|
|
39
|
+
import { restoreHookState, resetHookState, reconcileRestoredHookDispatch } from "./post-unit-hooks.js";
|
|
40
40
|
import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
|
|
41
41
|
import { snapshotSkills } from "./skill-discovery.js";
|
|
42
|
-
import { isDbAvailable, getMilestone, getAllMilestones, insertMilestone, updateMilestoneStatus } from "./gsd-db.js";
|
|
42
|
+
import { isDbAvailable, probeDbWritable, getMilestone, getAllMilestones, insertMilestone, updateMilestoneStatus } from "./gsd-db.js";
|
|
43
43
|
import { getWorkflowDatabaseStatus, openExistingWorkflowDatabase, openWorkflowDatabase, resolveProjectRootDbPath, } from "./db-workspace.js";
|
|
44
44
|
import { isClosedStatus } from "./status-guards.js";
|
|
45
45
|
import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
|
|
@@ -119,36 +119,42 @@ export function reconcileProjectMilestonesFromDisk(basePath) {
|
|
|
119
119
|
export function reconcileMergedMilestonesFromJournal(basePath) {
|
|
120
120
|
if (!isDbAvailable())
|
|
121
121
|
return 0;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
122
|
+
try {
|
|
123
|
+
const mergedAtByMilestone = new Map();
|
|
124
|
+
for (const entry of queryJournal(basePath, { eventType: "worktree-merged" })) {
|
|
125
|
+
const data = entry.data ?? {};
|
|
126
|
+
const milestoneId = typeof data.milestoneId === "string" ? data.milestoneId : null;
|
|
127
|
+
if (!milestoneId)
|
|
128
|
+
continue;
|
|
129
|
+
if (data.conflict === true)
|
|
130
|
+
continue;
|
|
131
|
+
const endedAt = typeof data.endedAt === "string" ? data.endedAt : entry.ts;
|
|
132
|
+
const previous = mergedAtByMilestone.get(milestoneId);
|
|
133
|
+
if (!previous || endedAt > previous)
|
|
134
|
+
mergedAtByMilestone.set(milestoneId, endedAt);
|
|
135
|
+
}
|
|
136
|
+
let closed = 0;
|
|
137
|
+
for (const [milestoneId, completedAt] of mergedAtByMilestone) {
|
|
138
|
+
const existing = getMilestone(milestoneId);
|
|
139
|
+
if (!existing) {
|
|
140
|
+
insertMilestone({ id: milestoneId, title: milestoneId, status: "complete" });
|
|
141
|
+
updateMilestoneStatus(milestoneId, "complete", completedAt);
|
|
142
|
+
closed++;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (!isClosedStatus(existing.status)) {
|
|
146
|
+
updateMilestoneStatus(milestoneId, "complete", completedAt);
|
|
147
|
+
closed++;
|
|
148
|
+
}
|
|
147
149
|
}
|
|
150
|
+
if (closed > 0)
|
|
151
|
+
invalidateAllCaches();
|
|
152
|
+
return closed;
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
logWarning("bootstrap", `merged-milestone journal reconciliation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
156
|
+
return 0;
|
|
148
157
|
}
|
|
149
|
-
if (closed > 0)
|
|
150
|
-
invalidateAllCaches();
|
|
151
|
-
return closed;
|
|
152
158
|
}
|
|
153
159
|
export function decideSurvivorAction(hasSurvivorBranch, phase) {
|
|
154
160
|
if (!hasSurvivorBranch)
|
|
@@ -1254,6 +1260,10 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
1254
1260
|
s.unitLifetimeDispatches.clear();
|
|
1255
1261
|
resetHookState();
|
|
1256
1262
|
restoreHookState(base);
|
|
1263
|
+
// A restored activeHook has no live dispatch (the sidecar queue is not
|
|
1264
|
+
// persisted); re-enqueue it so the hook runs instead of blocking the next
|
|
1265
|
+
// unrelated unit's close-out (#1246).
|
|
1266
|
+
reconcileRestoredHookDispatch(base, s.sidecarQueue);
|
|
1257
1267
|
resetProactiveHealing();
|
|
1258
1268
|
// Notify user on health level transitions (green→yellow→red and back)
|
|
1259
1269
|
setLevelChangeCallback((_from, to, summary) => {
|
|
@@ -1377,6 +1387,19 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
1377
1387
|
ctx.ui.notify(`SQLite database exists but failed to open: ${gsdDbPath}. ${phaseHint}${errorDetail}.${providerHint}`, "error");
|
|
1378
1388
|
return releaseLockAndReturn();
|
|
1379
1389
|
}
|
|
1390
|
+
// Gate: confirm the handle is actually writable, not just open. A
|
|
1391
|
+
// schema-current DB does zero writes during open, so a read-only /
|
|
1392
|
+
// DBMOVED handle otherwise passes the check above and only fails much
|
|
1393
|
+
// later at the first authoritative write (the uok-kernel-enter audit)
|
|
1394
|
+
// with an opaque "readonly database" error (#1234).
|
|
1395
|
+
if (existsSync(gsdDbPath) && isDbAvailable()) {
|
|
1396
|
+
const writable = probeDbWritable();
|
|
1397
|
+
if (!writable.ok) {
|
|
1398
|
+
const detail = writable.detail ? ` (${writable.detail})` : "";
|
|
1399
|
+
ctx.ui.notify(`SQLite database is not writable: ${gsdDbPath}.${detail} Check file/WAL permissions or reopen a stale handle before running auto-mode.`, "error");
|
|
1400
|
+
return releaseLockAndReturn();
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1380
1403
|
// Initialize metrics
|
|
1381
1404
|
initMetrics(s.basePath);
|
|
1382
1405
|
// Initialize routing history
|
|
@@ -1410,7 +1433,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
1410
1433
|
}
|
|
1411
1434
|
// Snapshot installed skills
|
|
1412
1435
|
if (resolveSkillDiscoveryMode(base) !== "off") {
|
|
1413
|
-
snapshotSkills();
|
|
1436
|
+
snapshotSkills({ cwd: s.basePath });
|
|
1414
1437
|
}
|
|
1415
1438
|
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
1416
1439
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
@@ -8,6 +8,8 @@ import { resolveExpectedArtifactPath, diagnoseExpectedArtifact, verifyExpectedAr
|
|
|
8
8
|
import { existsSync } from "node:fs";
|
|
9
9
|
import { bumpAndResolveSynthetic } from "./auto/resolve.js";
|
|
10
10
|
import { finalizeProjectResearchTimeout } from "./project-research-policy.js";
|
|
11
|
+
import { applySupervisorModelIfConfigured } from "./auto-model-selection.js";
|
|
12
|
+
import { getInFlightToolCount } from "./auto-tool-tracking.js";
|
|
11
13
|
export async function recoverTimedOutUnit(ctx, pi, unitType, unitId, reason, rctx) {
|
|
12
14
|
// Note on turn epoch: the bump is intentionally NOT unconditional at
|
|
13
15
|
// function entry. Two branches below (the "steering retry" paths) keep
|
|
@@ -79,11 +81,15 @@ export async function recoverTimedOutUnit(ctx, pi, unitType, unitId, reason, rct
|
|
|
79
81
|
"Immediately finish the required durable output for this unit.",
|
|
80
82
|
"If full completion is impossible, write the partial artifact/state needed for recovery and make the blocker explicit.",
|
|
81
83
|
];
|
|
84
|
+
const recoveryTrigger = getInFlightToolCount() === 0;
|
|
85
|
+
if (recoveryTrigger) {
|
|
86
|
+
await applySupervisorModelIfConfigured(ctx, pi, basePath);
|
|
87
|
+
}
|
|
82
88
|
pi.sendMessage({
|
|
83
89
|
customType: "gsd-auto-timeout-recovery",
|
|
84
90
|
display: verbose,
|
|
85
91
|
content: steeringLines.join("\n"),
|
|
86
|
-
}, { triggerTurn:
|
|
92
|
+
}, { triggerTurn: recoveryTrigger, deliverAs: "steer" });
|
|
87
93
|
ctx.ui.notify(`${reason === "idle" ? "Idle" : "Timeout"} recovery: steering ${unitType} ${unitId} to finish durable output (attempt ${attemptNumber}, session ${recoveryAttempts + 1}/${maxRecoveryAttempts}).`, "warning");
|
|
88
94
|
return "recovered";
|
|
89
95
|
}
|
|
@@ -176,11 +182,15 @@ export async function recoverTimedOutUnit(ctx, pi, unitType, unitId, reason, rct
|
|
|
176
182
|
"Write the required artifact now.",
|
|
177
183
|
"If blocked, write the partial artifact and explicitly record the blocker instead of going silent.",
|
|
178
184
|
];
|
|
185
|
+
const recoveryTrigger = getInFlightToolCount() === 0;
|
|
186
|
+
if (recoveryTrigger) {
|
|
187
|
+
await applySupervisorModelIfConfigured(ctx, pi, basePath);
|
|
188
|
+
}
|
|
179
189
|
pi.sendMessage({
|
|
180
190
|
customType: "gsd-auto-timeout-recovery",
|
|
181
191
|
display: verbose,
|
|
182
192
|
content: steeringLines.join("\n"),
|
|
183
|
-
}, { triggerTurn:
|
|
193
|
+
}, { triggerTurn: recoveryTrigger, deliverAs: "steer" });
|
|
184
194
|
ctx.ui.notify(`${reason === "idle" ? "Idle" : "Timeout"} recovery: steering ${unitType} ${unitId} to produce ${expected} (attempt ${attemptNumber}, session ${recoveryAttempts + 1}/${maxRecoveryAttempts}).`, "warning");
|
|
185
195
|
return "recovered";
|
|
186
196
|
}
|
|
@@ -11,6 +11,7 @@ import { resolveAutoSupervisorConfig } from "./preferences.js";
|
|
|
11
11
|
import { computeBudgets, resolveExecutorContextWindow } from "./context-budget.js";
|
|
12
12
|
import { getInFlightToolCount, getOldestInFlightToolStart, clearInFlightTools, hasInteractiveToolInFlight, } from "./auto-tool-tracking.js";
|
|
13
13
|
import { detectWorkingTreeActivity } from "./auto-supervisor.js";
|
|
14
|
+
import { applySupervisorModelIfConfigured } from "./auto-model-selection.js";
|
|
14
15
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
15
16
|
import { saveActivityLog } from "./activity-log.js";
|
|
16
17
|
import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
|
|
@@ -113,7 +114,7 @@ export function startUnitSupervision(sctx) {
|
|
|
113
114
|
? supervisor.stalled_tool_timeout_minutes * 60 * 1000
|
|
114
115
|
: idleTimeoutMs;
|
|
115
116
|
// ── 1. Soft timeout warning ──
|
|
116
|
-
s.wrapupWarningHandle = setTimeout(() => {
|
|
117
|
+
s.wrapupWarningHandle = setTimeout(async () => {
|
|
117
118
|
s.wrapupWarningHandle = null;
|
|
118
119
|
if (!s.active || !s.currentUnit)
|
|
119
120
|
return;
|
|
@@ -125,6 +126,9 @@ export function startUnitSupervision(sctx) {
|
|
|
125
126
|
// Triggering during active tool calls causes tool results to be skipped
|
|
126
127
|
// with "Skipped due to queued user message", leading to provider errors (#3512).
|
|
127
128
|
const softTrigger = getInFlightToolCount() === 0;
|
|
129
|
+
if (softTrigger) {
|
|
130
|
+
await applySupervisorModelIfConfigured(ctx, pi, s.basePath);
|
|
131
|
+
}
|
|
128
132
|
pi.sendMessage({
|
|
129
133
|
customType: "gsd-auto-wrapup",
|
|
130
134
|
display: s.verbose,
|
|
@@ -291,7 +295,7 @@ export function startUnitSupervision(sctx) {
|
|
|
291
295
|
}
|
|
292
296
|
const executorContextWindow = resolveExecutorContextWindow(ctx.modelRegistry, prefs, ctx.model?.contextWindow, ctx.model?.provider);
|
|
293
297
|
const continueHereThreshold = computeBudgets(executorContextWindow).continueThresholdPercent;
|
|
294
|
-
s.continueHereHandle = setInterval(() => {
|
|
298
|
+
s.continueHereHandle = setInterval(async () => {
|
|
295
299
|
if (!s.active || !s.currentUnit || !s.cmdCtx)
|
|
296
300
|
return;
|
|
297
301
|
const runtime = readUnitRuntimeRecord(s.basePath, unitType, unitId);
|
|
@@ -316,6 +320,9 @@ export function startUnitSupervision(sctx) {
|
|
|
316
320
|
}
|
|
317
321
|
// Only trigger a new turn if no tools are currently in flight (#3512).
|
|
318
322
|
const contextTrigger = getInFlightToolCount() === 0;
|
|
323
|
+
if (contextTrigger) {
|
|
324
|
+
await applySupervisorModelIfConfigured(ctx, pi, s.basePath);
|
|
325
|
+
}
|
|
319
326
|
pi.sendMessage({
|
|
320
327
|
customType: "gsd-auto-wrapup",
|
|
321
328
|
display: s.verbose,
|
|
@@ -30,9 +30,10 @@ import { playNotificationBell, sendDesktopNotification } from "./notifications.j
|
|
|
30
30
|
import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, HARD_CONTEXT_REROOT_THRESHOLD_PERCENT, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, shouldWarnStepSessionForContext, } from "./auto-budget.js";
|
|
31
31
|
import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, isToolInvocationError, isQueuedUserMessageSkip, isDeterministicPolicyError, } from "./auto-tool-tracking.js";
|
|
32
32
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
33
|
-
import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
|
|
33
|
+
import { selectAndApplyModel, resolveModelId, clearToolBaseline, isModelUnavailable, applyThinkingLevelForModel } from "./auto-model-selection.js";
|
|
34
|
+
import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
|
|
34
35
|
import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
|
|
35
|
-
import { resetHookState, runPreDispatchHooks, restoreHookState, clearPersistedHookState, } from "./post-unit-hooks.js";
|
|
36
|
+
import { resetHookState, runPreDispatchHooks, restoreHookState, reconcileRestoredHookDispatch, clearPersistedHookState, } from "./post-unit-hooks.js";
|
|
36
37
|
import { runGSDDoctor, rebuildState } from "./doctor.js";
|
|
37
38
|
import { preDispatchHealthGate, resetProactiveHealing, setLevelChangeCallback, } from "./doctor-proactive.js";
|
|
38
39
|
import { clearSkillSnapshot } from "./skill-discovery.js";
|
|
@@ -332,11 +333,24 @@ function withDetachedAutoKeepalive(run) {
|
|
|
332
333
|
}
|
|
333
334
|
export const _withDetachedAutoKeepaliveForTest = withDetachedAutoKeepalive;
|
|
334
335
|
export function startAutoDetached(ctx, pi, base, verboseMode, options) {
|
|
335
|
-
void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch((err) => {
|
|
336
|
+
void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch(async (err) => {
|
|
336
337
|
const message = getErrorMessage(err);
|
|
337
338
|
ctx.ui.notify(`Auto-start failed: ${message}`, "error");
|
|
338
339
|
logWarning("engine", `auto start error: ${message}`, { file: "auto.ts" });
|
|
339
340
|
debugLog("auto-start-failed", { error: message });
|
|
341
|
+
// Backstop cleanup (#1235): if startAuto threw after auto-mode was activated
|
|
342
|
+
// (e.g. an exception during bootstrap, before the loop's try/finally could
|
|
343
|
+
// run cleanupAfterLoopExit), s.active and the on-disk auto lock leak, so the
|
|
344
|
+
// re-entry guard silently no-ops every later /gsd auto until restart. Clear
|
|
345
|
+
// the leaked activation here so a failed start is always recoverable.
|
|
346
|
+
if (s.active) {
|
|
347
|
+
try {
|
|
348
|
+
await cleanupAfterLoopExit(ctx);
|
|
349
|
+
}
|
|
350
|
+
catch (cleanupErr) {
|
|
351
|
+
logWarning("engine", `auto start cleanup failed: ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}`, { file: "auto.ts" });
|
|
352
|
+
}
|
|
353
|
+
}
|
|
340
354
|
});
|
|
341
355
|
}
|
|
342
356
|
/** Returns true if the project is configured for `isolation:worktree` mode. */
|
|
@@ -2175,6 +2189,10 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2175
2189
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
2176
2190
|
ctx.ui.notify(s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "info");
|
|
2177
2191
|
restoreHookState(s.basePath);
|
|
2192
|
+
// A restored activeHook has no live dispatch (the sidecar queue is not
|
|
2193
|
+
// persisted); re-enqueue it so the hook runs instead of blocking the next
|
|
2194
|
+
// unrelated unit's close-out (#1246).
|
|
2195
|
+
reconcileRestoredHookDispatch(s.basePath, s.sidecarQueue);
|
|
2178
2196
|
// Re-sync managed resources on resume so long-lived auto sessions pick up
|
|
2179
2197
|
// bundled extension updates before resume-time verification/state logic runs.
|
|
2180
2198
|
// GSD_PKG_ROOT is set by loader.ts and points to the gsd-pi package root.
|
|
@@ -2228,15 +2246,19 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2228
2246
|
debugLog("resume-orchestration-resume", { error: err instanceof Error ? err.message : String(err) });
|
|
2229
2247
|
}
|
|
2230
2248
|
startAutoCommandPolling(s.basePath);
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2249
|
+
try {
|
|
2250
|
+
await runAutoLoopWithUok({
|
|
2251
|
+
ctx,
|
|
2252
|
+
pi,
|
|
2253
|
+
s,
|
|
2254
|
+
deps: loopDeps,
|
|
2255
|
+
runKernelLoop: runUokKernelLoop,
|
|
2256
|
+
runLegacyLoop: runLegacyAutoLoop,
|
|
2257
|
+
});
|
|
2258
|
+
}
|
|
2259
|
+
finally {
|
|
2260
|
+
await cleanupAfterLoopExit(ctx);
|
|
2261
|
+
}
|
|
2240
2262
|
return;
|
|
2241
2263
|
}
|
|
2242
2264
|
// ── Fresh start path — delegated to auto-start.ts ──
|
|
@@ -2252,8 +2274,16 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2252
2274
|
// for crash-recovery fidelity (#5405).
|
|
2253
2275
|
registerAutoWorkerForSession(s, base);
|
|
2254
2276
|
const ready = await bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, bootstrapDeps, freshStartAssessment);
|
|
2255
|
-
if (!ready)
|
|
2277
|
+
if (!ready) {
|
|
2278
|
+
// bootstrapAutoSession sets s.active = true (auto-start.ts) before several
|
|
2279
|
+
// post-activation bail-outs return false without a loop ever running (e.g.
|
|
2280
|
+
// the SQLite-unavailable gate). Without this, s.active and the auto lock
|
|
2281
|
+
// leak and every later /gsd auto silently no-ops via the re-entry guard
|
|
2282
|
+
// (#1235). Run the canonical cleanup so a failed bootstrap stays recoverable.
|
|
2283
|
+
if (s.active)
|
|
2284
|
+
await cleanupAfterLoopExit(ctx);
|
|
2256
2285
|
return;
|
|
2286
|
+
}
|
|
2257
2287
|
// Build scope after bootstrap has populated s.basePath / s.originalBasePath /
|
|
2258
2288
|
// s.currentMilestoneId (including worktree setup inside bootstrapAutoSession).
|
|
2259
2289
|
rebuildScope(s.basePath, s.currentMilestoneId);
|
|
@@ -2277,15 +2307,19 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2277
2307
|
}
|
|
2278
2308
|
startAutoCommandPolling(s.basePath);
|
|
2279
2309
|
// Dispatch the first unit
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2310
|
+
try {
|
|
2311
|
+
await runAutoLoopWithUok({
|
|
2312
|
+
ctx,
|
|
2313
|
+
pi,
|
|
2314
|
+
s,
|
|
2315
|
+
deps: loopDeps,
|
|
2316
|
+
runKernelLoop: runUokKernelLoop,
|
|
2317
|
+
runLegacyLoop: runLegacyAutoLoop,
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2320
|
+
finally {
|
|
2321
|
+
await cleanupAfterLoopExit(ctx);
|
|
2322
|
+
}
|
|
2289
2323
|
}
|
|
2290
2324
|
// describeNextUnit is imported from auto-dashboard.ts and re-exported
|
|
2291
2325
|
export { describeNextUnit } from "./auto-dashboard.js";
|
|
@@ -2402,20 +2436,52 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
2402
2436
|
startedAt: hookStartedAt,
|
|
2403
2437
|
workspaceRoot: s.basePath,
|
|
2404
2438
|
});
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2439
|
+
// Resolve the hook's model honoring the configured `fallbacks[]` chain
|
|
2440
|
+
// (#1229). The manual trigger path bypasses selectAndApplyModel, so resolve
|
|
2441
|
+
// the primary→fallbacks order here and apply the first candidate available in
|
|
2442
|
+
// the registry — a blocked or unconfigured primary then transparently drops
|
|
2443
|
+
// to a fallback instead of silently reverting to the session model.
|
|
2444
|
+
const availableModels = ctx.modelRegistry.getAvailable();
|
|
2445
|
+
const availableModelIds = availableModels.map((m) => `${m.provider}/${m.id}`);
|
|
2446
|
+
const hookModelConfig = resolveModelWithFallbacksForUnit(hookUnitType, targetBasePath, availableModelIds);
|
|
2447
|
+
const modelCandidates = hookModelConfig
|
|
2448
|
+
? [hookModelConfig.primary, ...hookModelConfig.fallbacks]
|
|
2449
|
+
: hookModel
|
|
2450
|
+
? [hookModel]
|
|
2451
|
+
: [];
|
|
2452
|
+
if (modelCandidates.length > 0) {
|
|
2453
|
+
let applied = false;
|
|
2454
|
+
for (const candidate of modelCandidates) {
|
|
2455
|
+
const match = resolveModelId(candidate, availableModels, ctx.model?.provider);
|
|
2456
|
+
if (!match)
|
|
2457
|
+
continue;
|
|
2458
|
+
// Skip models the runtime has marked blocked or temporarily unavailable
|
|
2459
|
+
// (e.g. a primary that just tripped a provider limit) so the configured
|
|
2460
|
+
// fallbacks[] chain actually engages — parity with auto-mode's
|
|
2461
|
+
// selectAndApplyModel, which consults the same blocked-models store (#1229).
|
|
2462
|
+
if (isModelUnavailable(targetBasePath, match.provider, match.id))
|
|
2463
|
+
continue;
|
|
2409
2464
|
try {
|
|
2410
|
-
await pi.setModel(match)
|
|
2465
|
+
if (await pi.setModel(match)) {
|
|
2466
|
+
// The manual trigger path bypasses selectAndApplyModel, so apply the
|
|
2467
|
+
// hook's per-field `thinking` (from `post_unit_hooks[].model`'s object
|
|
2468
|
+
// form) here against the just-set model rather than leaving the hook at
|
|
2469
|
+
// the session level (#1269). Absent → session level, unchanged.
|
|
2470
|
+
if (hookModelConfig?.thinking) {
|
|
2471
|
+
applyThinkingLevelForModel(pi, hookModelConfig.thinking, match, ctx);
|
|
2472
|
+
}
|
|
2473
|
+
applied = true;
|
|
2474
|
+
break;
|
|
2475
|
+
}
|
|
2411
2476
|
}
|
|
2412
2477
|
catch (err) {
|
|
2413
|
-
/* non-fatal */
|
|
2414
|
-
logWarning("dispatch", `hook model set failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
2478
|
+
/* non-fatal — try the next fallback */
|
|
2479
|
+
logWarning("dispatch", `hook model set failed for ${candidate}: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
2415
2480
|
}
|
|
2416
2481
|
}
|
|
2417
|
-
|
|
2418
|
-
ctx.ui.notify(`Hook model
|
|
2482
|
+
if (!applied) {
|
|
2483
|
+
ctx.ui.notify(`Hook model${modelCandidates.length > 1 ? "s" : ""} "${modelCandidates.join(", ")}" not available. ` +
|
|
2484
|
+
`Falling back to current session model. ` +
|
|
2419
2485
|
`Ensure the model is defined in models.json and has auth configured.`, "warning");
|
|
2420
2486
|
}
|
|
2421
2487
|
}
|