@opengsd/gsd-pi 1.5.0 → 1.6.0-dev.aa7f94e8
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 +10 -10
- 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/closeout.js +97 -5
- package/dist/resources/extensions/gsd/auto/orchestrator.js +20 -13
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
- package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -5
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
- 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 +23 -6
- package/dist/resources/extensions/gsd/auto-prompts.js +49 -117
- package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
- package/dist/resources/extensions/gsd/auto-start.js +57 -33
- 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-worktree-branch-lifecycle.js +189 -0
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
- package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
- package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
- package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
- package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
- package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
- package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +20 -2073
- package/dist/resources/extensions/gsd/auto.js +118 -34
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +20 -2
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +185 -27
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +68 -2
- package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
- 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/queries.js +9 -9
- 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/doctor-engine-checks.js +93 -11
- package/dist/resources/extensions/gsd/flat-phase-migration.js +32 -3
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
- package/dist/resources/extensions/gsd/git-service.js +45 -0
- package/dist/resources/extensions/gsd/gsd-db.js +23 -11
- package/dist/resources/extensions/gsd/guided-flow.js +22 -17
- package/dist/resources/extensions/gsd/journal.js +1 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +34 -79
- 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/milestone-merge-transaction.js +11 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
- 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-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +148 -10
- package/dist/resources/extensions/gsd/preferences.js +20 -0
- package/dist/resources/extensions/gsd/prompts/system.md +6 -6
- package/dist/resources/extensions/gsd/quick.js +12 -3
- package/dist/resources/extensions/gsd/reopen-reason.js +98 -0
- package/dist/resources/extensions/gsd/rule-registry.js +106 -10
- package/dist/resources/extensions/gsd/session-status-io.js +31 -0
- package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
- package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
- 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/tool-contract.js +14 -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 +28 -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/unit-registry.js +12 -2
- package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
- 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/validation-block-guard.js +2 -1
- 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-git-preflight.js +2 -2
- package/dist/resources/extensions/gsd/workspace.js +5 -14
- package/dist/resources/extensions/gsd/worktree-command.js +1 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +14 -9
- package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
- package/dist/resources/extensions/shared/gsd-browser-cli.js +51 -5
- 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 +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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/mcp-connections/route.js +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/mcp-connections/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.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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 +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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/{1128.js → 1991.js} +1 -1
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- 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-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- 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/server.js +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 +25 -36
- package/integrations/hermes/pyproject.toml +1 -1
- package/integrations/hermes/tests/test_gsd_client_timeout.py +4 -4
- package/package.json +6 -6
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-cli.d.ts +1 -1
- package/packages/daemon/dist/cloud-cli.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-cli.js +42 -2
- package/packages/daemon/dist/cloud-cli.js.map +1 -1
- package/packages/daemon/dist/cloud-config.d.ts +1 -0
- package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-config.js +1 -1
- package/packages/daemon/dist/cloud-config.js.map +1 -1
- package/packages/daemon/dist/device-flow.d.ts +24 -0
- package/packages/daemon/dist/device-flow.d.ts.map +1 -0
- package/packages/daemon/dist/device-flow.js +128 -0
- package/packages/daemon/dist/device-flow.js.map +1 -0
- package/packages/daemon/dist/device-flow.test.d.ts +2 -0
- package/packages/daemon/dist/device-flow.test.d.ts.map +1 -0
- package/packages/daemon/dist/device-flow.test.js +172 -0
- package/packages/daemon/dist/device-flow.test.js.map +1 -0
- 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 +5 -5
- package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/README.md +34 -0
- package/packages/gsd-cloud/bin/gsd-cloud.js +27 -0
- package/packages/gsd-cloud/package.json +38 -0
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +14 -9
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
- package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
- package/packages/pi-ai/dist/tool-result-content.js +62 -0
- package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +8 -20
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +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/dist/core/export-html/template.js +53 -4
- 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 +44 -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/closeout.ts +114 -7
- package/src/resources/extensions/gsd/auto/orchestrator.ts +21 -14
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
- package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -4
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
- 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 +26 -5
- package/src/resources/extensions/gsd/auto-prompts.ts +73 -113
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
- package/src/resources/extensions/gsd/auto-start.ts +62 -31
- 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-worktree-branch-lifecycle.ts +237 -0
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
- package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
- package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
- package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
- package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
- package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
- package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
- package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
- package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
- package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +69 -2429
- package/src/resources/extensions/gsd/auto.ts +126 -47
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +20 -2
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +218 -27
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +77 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
- 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/queries.ts +9 -9
- 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/doctor-engine-checks.ts +109 -10
- package/src/resources/extensions/gsd/flat-phase-migration.ts +34 -3
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +53 -0
- package/src/resources/extensions/gsd/gsd-db.ts +33 -11
- package/src/resources/extensions/gsd/guided-flow.ts +26 -18
- package/src/resources/extensions/gsd/journal.ts +1 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +52 -91
- 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/milestone-merge-transaction.ts +15 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
- 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 +54 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +146 -9
- package/src/resources/extensions/gsd/preferences.ts +20 -0
- package/src/resources/extensions/gsd/prompts/system.md +6 -6
- package/src/resources/extensions/gsd/quick.ts +11 -3
- package/src/resources/extensions/gsd/reopen-reason.ts +109 -0
- package/src/resources/extensions/gsd/rule-registry.ts +111 -9
- package/src/resources/extensions/gsd/session-status-io.ts +34 -0
- package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
- 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-loop-no-copy-artifacts.test.ts +2 -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-clean-runtime-db-gated.test.ts +1 -1
- 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/auto-warning-noise-regression.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +26 -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/completed-units-metrics-sync.test.ts +1 -1
- 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/derive-state-db.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +46 -1
- package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
- package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
- package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
- 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/milestone-merge-stash-restore.test.ts +439 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -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-worktree-sync.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +5 -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-reason.test.ts +117 -0
- 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/runtime-invariant-modules.test.ts +20 -0
- 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/stale-worktree-cwd.test.ts +3 -5
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
- 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/sync-worktree-skip-current.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +26 -1
- 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/worker-resume-wait.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
- package/src/resources/extensions/gsd/tool-contract.ts +29 -0
- 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 +28 -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/unit-registry.ts +16 -2
- package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
- 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/validation-block-guard.ts +2 -1
- 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-git-preflight.ts +2 -2
- package/src/resources/extensions/gsd/workspace.ts +5 -21
- package/src/resources/extensions/gsd/worktree-command.ts +1 -1
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +19 -15
- package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
- package/src/resources/extensions/shared/gsd-browser-cli.ts +64 -7
- 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/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → XFuMvz26Zb_lrrR-8dvkd}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → XFuMvz26Zb_lrrR-8dvkd}/_ssgManifest.js +0 -0
|
@@ -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";
|
|
@@ -51,10 +52,17 @@ import { atomicWriteSync } from "./atomic-write.js";
|
|
|
51
52
|
import { captureIntegrationBranch, detectWorktreeName, getCurrentBranch, getMainBranch, setActiveMilestoneId, } from "./worktree.js";
|
|
52
53
|
import { GitServiceImpl } from "./git-service.js";
|
|
53
54
|
import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
|
|
54
|
-
import {
|
|
55
|
+
import { autoWorktreeBranch } from "./auto-worktree-branch-lifecycle.js";
|
|
56
|
+
import { createAutoWorktree } from "./auto-worktree-creation.js";
|
|
57
|
+
import { isInAutoWorktree } from "./auto-worktree-entry.js";
|
|
58
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
59
|
+
import { checkResourcesStale } from "./auto-worktree-resource-version.js";
|
|
60
|
+
import { escapeStaleWorktree } from "./auto-worktree-runtime-cleanup.js";
|
|
61
|
+
import { teardownWarmedBrowserDaemons } from "./browser-daemon-auto-prep.js";
|
|
62
|
+
import { teardownAutoWorktree } from "./auto-worktree-teardown.js";
|
|
55
63
|
import { pruneQueueOrder } from "./queue-order.js";
|
|
56
64
|
import { startCommandPolling as _startCommandPolling, isRemoteConfigured } from "../remote-questions/manager.js";
|
|
57
|
-
import {
|
|
65
|
+
import { createDefaultMilestoneMergeTransaction } from "./milestone-merge-transaction.js";
|
|
58
66
|
import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
|
|
59
67
|
import { reconcileMergeState, verifyExpectedArtifact, } from "./auto-recovery.js";
|
|
60
68
|
import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
|
|
@@ -326,11 +334,24 @@ function withDetachedAutoKeepalive(run) {
|
|
|
326
334
|
}
|
|
327
335
|
export const _withDetachedAutoKeepaliveForTest = withDetachedAutoKeepalive;
|
|
328
336
|
export function startAutoDetached(ctx, pi, base, verboseMode, options) {
|
|
329
|
-
void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch((err) => {
|
|
337
|
+
void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch(async (err) => {
|
|
330
338
|
const message = getErrorMessage(err);
|
|
331
339
|
ctx.ui.notify(`Auto-start failed: ${message}`, "error");
|
|
332
340
|
logWarning("engine", `auto start error: ${message}`, { file: "auto.ts" });
|
|
333
341
|
debugLog("auto-start-failed", { error: message });
|
|
342
|
+
// Backstop cleanup (#1235): if startAuto threw after auto-mode was activated
|
|
343
|
+
// (e.g. an exception during bootstrap, before the loop's try/finally could
|
|
344
|
+
// run cleanupAfterLoopExit), s.active and the on-disk auto lock leak, so the
|
|
345
|
+
// re-entry guard silently no-ops every later /gsd auto until restart. Clear
|
|
346
|
+
// the leaked activation here so a failed start is always recoverable.
|
|
347
|
+
if (s.active) {
|
|
348
|
+
try {
|
|
349
|
+
await cleanupAfterLoopExit(ctx);
|
|
350
|
+
}
|
|
351
|
+
catch (cleanupErr) {
|
|
352
|
+
logWarning("engine", `auto start cleanup failed: ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}`, { file: "auto.ts" });
|
|
353
|
+
}
|
|
354
|
+
}
|
|
334
355
|
});
|
|
335
356
|
}
|
|
336
357
|
/** Returns true if the project is configured for `isolation:worktree` mode. */
|
|
@@ -983,6 +1004,17 @@ export async function cleanupAfterLoopExit(ctx) {
|
|
|
983
1004
|
/* best-effort — mirror stopAuto cleanup */
|
|
984
1005
|
logWarning("session", `lock cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
985
1006
|
}
|
|
1007
|
+
// Symmetric teardown for the browser-UAT warm-up preflight (#1259): stop any
|
|
1008
|
+
// gsd-browser daemon this session started so the Chrome process does not
|
|
1009
|
+
// linger after the loop exits. Re-warms on the next browser-backed run-uat.
|
|
1010
|
+
try {
|
|
1011
|
+
for (const { projectRoot, error } of teardownWarmedBrowserDaemons()) {
|
|
1012
|
+
logWarning("session", `gsd-browser daemon stop failed for ${projectRoot}: ${error}`, { file: "auto.ts" });
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
catch (err) {
|
|
1016
|
+
logWarning("session", `browser daemon teardown failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1017
|
+
}
|
|
986
1018
|
// A transient provider-error pause intentionally leaves the paused badge
|
|
987
1019
|
// visible so the user still has a resumable auto-mode signal on screen.
|
|
988
1020
|
if (!s.paused) {
|
|
@@ -1746,7 +1778,7 @@ export function buildWorktreeLifecycleDeps() {
|
|
|
1746
1778
|
return new GitServiceImpl(basePath, gitConfig);
|
|
1747
1779
|
},
|
|
1748
1780
|
worktreeProjection: new WorktreeStateProjection(),
|
|
1749
|
-
mergeMilestone:
|
|
1781
|
+
mergeMilestone: createDefaultMilestoneMergeTransaction(),
|
|
1750
1782
|
};
|
|
1751
1783
|
}
|
|
1752
1784
|
function buildLifecycle() {
|
|
@@ -2169,6 +2201,10 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2169
2201
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
2170
2202
|
ctx.ui.notify(s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "info");
|
|
2171
2203
|
restoreHookState(s.basePath);
|
|
2204
|
+
// A restored activeHook has no live dispatch (the sidecar queue is not
|
|
2205
|
+
// persisted); re-enqueue it so the hook runs instead of blocking the next
|
|
2206
|
+
// unrelated unit's close-out (#1246).
|
|
2207
|
+
reconcileRestoredHookDispatch(s.basePath, s.sidecarQueue);
|
|
2172
2208
|
// Re-sync managed resources on resume so long-lived auto sessions pick up
|
|
2173
2209
|
// bundled extension updates before resume-time verification/state logic runs.
|
|
2174
2210
|
// GSD_PKG_ROOT is set by loader.ts and points to the gsd-pi package root.
|
|
@@ -2222,15 +2258,19 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2222
2258
|
debugLog("resume-orchestration-resume", { error: err instanceof Error ? err.message : String(err) });
|
|
2223
2259
|
}
|
|
2224
2260
|
startAutoCommandPolling(s.basePath);
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2261
|
+
try {
|
|
2262
|
+
await runAutoLoopWithUok({
|
|
2263
|
+
ctx,
|
|
2264
|
+
pi,
|
|
2265
|
+
s,
|
|
2266
|
+
deps: loopDeps,
|
|
2267
|
+
runKernelLoop: runUokKernelLoop,
|
|
2268
|
+
runLegacyLoop: runLegacyAutoLoop,
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
finally {
|
|
2272
|
+
await cleanupAfterLoopExit(ctx);
|
|
2273
|
+
}
|
|
2234
2274
|
return;
|
|
2235
2275
|
}
|
|
2236
2276
|
// ── Fresh start path — delegated to auto-start.ts ──
|
|
@@ -2246,8 +2286,16 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2246
2286
|
// for crash-recovery fidelity (#5405).
|
|
2247
2287
|
registerAutoWorkerForSession(s, base);
|
|
2248
2288
|
const ready = await bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, bootstrapDeps, freshStartAssessment);
|
|
2249
|
-
if (!ready)
|
|
2289
|
+
if (!ready) {
|
|
2290
|
+
// bootstrapAutoSession sets s.active = true (auto-start.ts) before several
|
|
2291
|
+
// post-activation bail-outs return false without a loop ever running (e.g.
|
|
2292
|
+
// the SQLite-unavailable gate). Without this, s.active and the auto lock
|
|
2293
|
+
// leak and every later /gsd auto silently no-ops via the re-entry guard
|
|
2294
|
+
// (#1235). Run the canonical cleanup so a failed bootstrap stays recoverable.
|
|
2295
|
+
if (s.active)
|
|
2296
|
+
await cleanupAfterLoopExit(ctx);
|
|
2250
2297
|
return;
|
|
2298
|
+
}
|
|
2251
2299
|
// Build scope after bootstrap has populated s.basePath / s.originalBasePath /
|
|
2252
2300
|
// s.currentMilestoneId (including worktree setup inside bootstrapAutoSession).
|
|
2253
2301
|
rebuildScope(s.basePath, s.currentMilestoneId);
|
|
@@ -2271,15 +2319,19 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2271
2319
|
}
|
|
2272
2320
|
startAutoCommandPolling(s.basePath);
|
|
2273
2321
|
// Dispatch the first unit
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2322
|
+
try {
|
|
2323
|
+
await runAutoLoopWithUok({
|
|
2324
|
+
ctx,
|
|
2325
|
+
pi,
|
|
2326
|
+
s,
|
|
2327
|
+
deps: loopDeps,
|
|
2328
|
+
runKernelLoop: runUokKernelLoop,
|
|
2329
|
+
runLegacyLoop: runLegacyAutoLoop,
|
|
2330
|
+
});
|
|
2331
|
+
}
|
|
2332
|
+
finally {
|
|
2333
|
+
await cleanupAfterLoopExit(ctx);
|
|
2334
|
+
}
|
|
2283
2335
|
}
|
|
2284
2336
|
// describeNextUnit is imported from auto-dashboard.ts and re-exported
|
|
2285
2337
|
export { describeNextUnit } from "./auto-dashboard.js";
|
|
@@ -2396,20 +2448,52 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
2396
2448
|
startedAt: hookStartedAt,
|
|
2397
2449
|
workspaceRoot: s.basePath,
|
|
2398
2450
|
});
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2451
|
+
// Resolve the hook's model honoring the configured `fallbacks[]` chain
|
|
2452
|
+
// (#1229). The manual trigger path bypasses selectAndApplyModel, so resolve
|
|
2453
|
+
// the primary→fallbacks order here and apply the first candidate available in
|
|
2454
|
+
// the registry — a blocked or unconfigured primary then transparently drops
|
|
2455
|
+
// to a fallback instead of silently reverting to the session model.
|
|
2456
|
+
const availableModels = ctx.modelRegistry.getAvailable();
|
|
2457
|
+
const availableModelIds = availableModels.map((m) => `${m.provider}/${m.id}`);
|
|
2458
|
+
const hookModelConfig = resolveModelWithFallbacksForUnit(hookUnitType, targetBasePath, availableModelIds);
|
|
2459
|
+
const modelCandidates = hookModelConfig
|
|
2460
|
+
? [hookModelConfig.primary, ...hookModelConfig.fallbacks]
|
|
2461
|
+
: hookModel
|
|
2462
|
+
? [hookModel]
|
|
2463
|
+
: [];
|
|
2464
|
+
if (modelCandidates.length > 0) {
|
|
2465
|
+
let applied = false;
|
|
2466
|
+
for (const candidate of modelCandidates) {
|
|
2467
|
+
const match = resolveModelId(candidate, availableModels, ctx.model?.provider);
|
|
2468
|
+
if (!match)
|
|
2469
|
+
continue;
|
|
2470
|
+
// Skip models the runtime has marked blocked or temporarily unavailable
|
|
2471
|
+
// (e.g. a primary that just tripped a provider limit) so the configured
|
|
2472
|
+
// fallbacks[] chain actually engages — parity with auto-mode's
|
|
2473
|
+
// selectAndApplyModel, which consults the same blocked-models store (#1229).
|
|
2474
|
+
if (isModelUnavailable(targetBasePath, match.provider, match.id))
|
|
2475
|
+
continue;
|
|
2403
2476
|
try {
|
|
2404
|
-
await pi.setModel(match)
|
|
2477
|
+
if (await pi.setModel(match)) {
|
|
2478
|
+
// The manual trigger path bypasses selectAndApplyModel, so apply the
|
|
2479
|
+
// hook's per-field `thinking` (from `post_unit_hooks[].model`'s object
|
|
2480
|
+
// form) here against the just-set model rather than leaving the hook at
|
|
2481
|
+
// the session level (#1269). Absent → session level, unchanged.
|
|
2482
|
+
if (hookModelConfig?.thinking) {
|
|
2483
|
+
applyThinkingLevelForModel(pi, hookModelConfig.thinking, match, ctx);
|
|
2484
|
+
}
|
|
2485
|
+
applied = true;
|
|
2486
|
+
break;
|
|
2487
|
+
}
|
|
2405
2488
|
}
|
|
2406
2489
|
catch (err) {
|
|
2407
|
-
/* non-fatal */
|
|
2408
|
-
logWarning("dispatch", `hook model set failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
2490
|
+
/* non-fatal — try the next fallback */
|
|
2491
|
+
logWarning("dispatch", `hook model set failed for ${candidate}: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
2409
2492
|
}
|
|
2410
2493
|
}
|
|
2411
|
-
|
|
2412
|
-
ctx.ui.notify(`Hook model
|
|
2494
|
+
if (!applied) {
|
|
2495
|
+
ctx.ui.notify(`Hook model${modelCandidates.length > 1 ? "s" : ""} "${modelCandidates.join(", ")}" not available. ` +
|
|
2496
|
+
`Falling back to current session model. ` +
|
|
2413
2497
|
`Ensure the model is defined in models.json and has auth configured.`, "warning");
|
|
2414
2498
|
}
|
|
2415
2499
|
}
|
|
@@ -6,7 +6,7 @@ import { join } from "node:path";
|
|
|
6
6
|
import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@gsd/pi-coding-agent";
|
|
7
7
|
import { logWarning } from "../workflow-logger.js";
|
|
8
8
|
import { getWorkflowDatabaseStatus, openWorkflowDatabase, } from "../db-workspace.js";
|
|
9
|
-
import { getAutoWorktreePath } from "../auto-worktree.js";
|
|
9
|
+
import { getAutoWorktreePath } from "../auto-worktree-path-resolution.js";
|
|
10
10
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
11
11
|
import { worktreesDirs } from "../worktree-placement.js";
|
|
12
12
|
export function safeWorkspaceCwd() {
|
|
@@ -15,7 +15,7 @@ import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
|
15
15
|
import { clearAutoCompletionStopInProgress, clearToolInvocationError, getAutoRuntimeSnapshot, getSourceObservationStore, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, isInteractiveElicitationInFlight, markToolEnd, markToolStart, recordAutoToolSurfaceSnapshot, recordToolInvocationError, } from "../auto-runtime-state.js";
|
|
16
16
|
import { isDeterministicPolicyError, isQueuedUserMessageSkip, isToolInvocationError, isToolUnavailableError, } from "../auto-tool-tracking.js";
|
|
17
17
|
import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
|
|
18
|
-
import { checkToolCallLoop, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
18
|
+
import { checkToolCallLoop, configureToolCallLoopGuard, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
19
19
|
import { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
|
|
20
20
|
import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
|
|
21
21
|
import { saveActivityLog } from "../activity-log.js";
|
|
@@ -432,6 +432,22 @@ async function applyCompactionThresholdOverride(ctx) {
|
|
|
432
432
|
ctx.setCompactionThresholdOverride?.(0.6);
|
|
433
433
|
}
|
|
434
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* Apply user-tunable tool-call loop guard thresholds (#1198) from GSD
|
|
437
|
+
* preferences plus GSD_TOOL_LOOP_* env overrides. Runs at session boundaries
|
|
438
|
+
* so both interactive sessions and `/gsd auto` pick up the configuration.
|
|
439
|
+
* Non-fatal: falls back to built-in defaults when preferences cannot be loaded.
|
|
440
|
+
*/
|
|
441
|
+
async function applyToolCallLoopGuardConfig(basePath) {
|
|
442
|
+
try {
|
|
443
|
+
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
444
|
+
const prefs = loadEffectiveGSDPreferences(basePath);
|
|
445
|
+
configureToolCallLoopGuard(prefs?.preferences.tool_call_loop_guard);
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
configureToolCallLoopGuard(null);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
435
451
|
function clearDeferredApprovalGate(basePath) {
|
|
436
452
|
if (!basePath) {
|
|
437
453
|
deferredApprovalGates.clear();
|
|
@@ -779,6 +795,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
779
795
|
}
|
|
780
796
|
resetWriteGateState(basePath);
|
|
781
797
|
resetToolCallLoopGuard();
|
|
798
|
+
await applyToolCallLoopGuardConfig(basePath);
|
|
782
799
|
approvalQuestionAbortInFlight = false;
|
|
783
800
|
clearDeferredApprovalGate();
|
|
784
801
|
await resetAskUserQuestionsTurnCache();
|
|
@@ -864,6 +881,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
864
881
|
initSessionNotifications(ctx);
|
|
865
882
|
resetWriteGateState(basePath);
|
|
866
883
|
resetToolCallLoopGuard();
|
|
884
|
+
await applyToolCallLoopGuardConfig(basePath);
|
|
867
885
|
clearDeferredApprovalGate();
|
|
868
886
|
await resetAskUserQuestionsTurnCache();
|
|
869
887
|
clearDiscussionFlowState(basePath);
|
|
@@ -1389,7 +1407,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1389
1407
|
}
|
|
1390
1408
|
}
|
|
1391
1409
|
if (!event.isError) {
|
|
1392
|
-
recordToolCallLoopMutation(toolName);
|
|
1410
|
+
recordToolCallLoopMutation(toolName, event.details);
|
|
1393
1411
|
refreshSourceObservationAfterMutation(toolName, event.input, ctx);
|
|
1394
1412
|
clearSourceObservationsAfterShell(toolName);
|
|
1395
1413
|
}
|
|
@@ -11,7 +11,7 @@ import { resolveModelWithFallbacksForUnit } from "../preferences-models.js";
|
|
|
11
11
|
import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
|
|
12
12
|
import { extractIntroAndRules } from "../knowledge-parser.js";
|
|
13
13
|
import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
|
|
14
|
-
import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
|
|
14
|
+
import { getActiveAutoWorktreeContext } from "../auto-worktree-session-registry.js";
|
|
15
15
|
import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-session-state.js";
|
|
16
16
|
import { deriveState } from "../state.js";
|
|
17
17
|
import { formatOverridesSection, formatShortcut, loadActiveOverrides, loadFile, parseContinue, parseSummary } from "../files.js";
|
|
@@ -14,36 +14,173 @@
|
|
|
14
14
|
* to stop tooling for the rest of that turn and answer in text.
|
|
15
15
|
*
|
|
16
16
|
* The per-tool-name check (#783 Brief C) tracks call counts within a
|
|
17
|
-
* turn regardless of args, decaying after successful state-
|
|
17
|
+
* turn regardless of args, decaying after successful state-progressing tools.
|
|
18
18
|
* This catches improvisation
|
|
19
19
|
* loops where the model attempts the same missing workflow tool through
|
|
20
20
|
* varied surfaces (bash → `node -e` → CLI), each with a different
|
|
21
21
|
* signature, so the identical-args streak never trips, while allowing
|
|
22
|
-
* tool-heavy turns that are making
|
|
23
|
-
*
|
|
22
|
+
* tool-heavy turns that are making progress. Progress means a successful file
|
|
23
|
+
* mutation (edit/write) or a successful shell/exec call (bg_shell,
|
|
24
|
+
* gsd_uat_exec, …) — so a local model running a legitimate iterative
|
|
25
|
+
* debugging loop (restart server, npm install, curl an endpoint) is not
|
|
26
|
+
* blocked as a false loop (#1206). Whichever guard trips first blocks.
|
|
27
|
+
*
|
|
28
|
+
* Thresholds, exempt tools, and enable flags are user-tunable (#1198) via the
|
|
29
|
+
* `tool_call_loop_guard` key in `.gsd/PREFERENCES.md` and `GSD_TOOL_LOOP_*`
|
|
30
|
+
* environment variables, applied through {@link configureToolCallLoopGuard}.
|
|
31
|
+
* Defaults preserve the original hardcoded behavior.
|
|
24
32
|
*/
|
|
25
33
|
import { createHash } from "node:crypto";
|
|
26
34
|
import { INHERENTLY_REPEATABLE_TOOL_SET } from "./core-session-tools.js";
|
|
27
35
|
import { hasBrowserContractPrefix } from "../../shared/browser-contract.js";
|
|
28
36
|
import { canonicalToolName } from "../engine-hook-contract.js";
|
|
29
|
-
|
|
37
|
+
/** Built-in defaults. Preserved when preferences/env do not override them. */
|
|
38
|
+
const DEFAULT_MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
|
|
39
|
+
const DEFAULT_PER_TOOL_DEFAULT_CAP = 6;
|
|
40
|
+
const DEFAULT_PER_TOOL_REPEATABLE_CAP = 15;
|
|
41
|
+
const DEFAULT_PER_TOOL_CAP_EXEMPT_TOOLS = ["find", "glob", "grep", "ls", "read", "search_and_read"];
|
|
30
42
|
/** Interactive/user-facing tools where even 1 duplicate is confusing. */
|
|
31
43
|
const STRICT_LOOP_TOOLS = new Set(["ask_user_questions"]);
|
|
32
44
|
const MAX_CONSECUTIVE_STRICT = 1;
|
|
45
|
+
const STATE_MUTATING_TOOL_SET = new Set(["edit", "write", "multi_edit", "notebook_edit"]);
|
|
33
46
|
/**
|
|
34
|
-
*
|
|
47
|
+
* Successful shell/exec calls are state progression too (#1206), not just file
|
|
48
|
+
* mutations. A local model debugging a UAT scenario legitimately restarts
|
|
49
|
+
* servers, runs `npm install`, and curls endpoints via bg_shell / gsd_uat_exec
|
|
50
|
+
* with varied args — productive work that never touches a file, so Guard 2's
|
|
51
|
+
* per-tool cap would otherwise misfire as a false loop. Decaying on these
|
|
52
|
+
* successful calls keeps the guard from aborting a progressing turn.
|
|
35
53
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
54
|
+
* Only successful calls reach {@link recordToolCallLoopMutation}: the
|
|
55
|
+
* tool_result hook skips `isError` results, and the bash tool throws on
|
|
56
|
+
* non-zero exit, so a genuinely stuck improvisation loop of failing commands
|
|
57
|
+
* (#783) never decays and still trips the cap. `async_bash` is excluded
|
|
58
|
+
* because it only registers a background job; command success is reported
|
|
59
|
+
* later via `await_job`. `bg_shell` may return `isError: false` for failed
|
|
60
|
+
* `run`/`start` outcomes, so the hook passes `details` for validation.
|
|
42
61
|
*/
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
const STATE_PROGRESSING_EXEC_TOOL_SET = new Set([
|
|
63
|
+
"bash",
|
|
64
|
+
"bg_shell",
|
|
65
|
+
"shell",
|
|
66
|
+
"powershell",
|
|
67
|
+
"gsd_exec",
|
|
68
|
+
"gsd_uat_exec",
|
|
69
|
+
]);
|
|
70
|
+
function isSuccessfulBgShellLoopProgress(details) {
|
|
71
|
+
if (!details || typeof details !== "object")
|
|
72
|
+
return false;
|
|
73
|
+
const record = details;
|
|
74
|
+
switch (record.action) {
|
|
75
|
+
case "run":
|
|
76
|
+
return record.exitCode === 0 && record.timedOut !== true;
|
|
77
|
+
case "start":
|
|
78
|
+
case "restart": {
|
|
79
|
+
const process = record.process;
|
|
80
|
+
if (!process || typeof process !== "object")
|
|
81
|
+
return false;
|
|
82
|
+
return process.alive === true;
|
|
83
|
+
}
|
|
84
|
+
case "wait_for_ready":
|
|
85
|
+
return record.ready === true;
|
|
86
|
+
case "send_and_wait":
|
|
87
|
+
return record.matched === true;
|
|
88
|
+
default:
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function defaultGuardConfig() {
|
|
93
|
+
return {
|
|
94
|
+
guardEnabled: true,
|
|
95
|
+
identicalEnabled: true,
|
|
96
|
+
maxConsecutiveIdentical: DEFAULT_MAX_CONSECUTIVE_IDENTICAL_CALLS,
|
|
97
|
+
repeatedEnabled: true,
|
|
98
|
+
perToolDefaultCap: DEFAULT_PER_TOOL_DEFAULT_CAP,
|
|
99
|
+
perToolRepeatableCap: DEFAULT_PER_TOOL_REPEATABLE_CAP,
|
|
100
|
+
perToolExempt: new Set(DEFAULT_PER_TOOL_CAP_EXEMPT_TOOLS),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
let config = defaultGuardConfig();
|
|
104
|
+
/** Parse a positive-integer env var, returning undefined when unset/invalid. */
|
|
105
|
+
function envPositiveInt(name) {
|
|
106
|
+
const raw = process.env[name];
|
|
107
|
+
if (raw === undefined || raw.trim() === "")
|
|
108
|
+
return undefined;
|
|
109
|
+
const n = Number(raw);
|
|
110
|
+
return Number.isFinite(n) && n >= 1 ? Math.floor(n) : undefined;
|
|
111
|
+
}
|
|
112
|
+
/** Parse a boolean env var (`true`/`1` vs `false`/`0`), undefined when unset. */
|
|
113
|
+
function envBool(name) {
|
|
114
|
+
const raw = process.env[name];
|
|
115
|
+
if (raw === undefined || raw.trim() === "")
|
|
116
|
+
return undefined;
|
|
117
|
+
const v = raw.trim().toLowerCase();
|
|
118
|
+
if (v === "true" || v === "1" || v === "yes" || v === "on")
|
|
119
|
+
return true;
|
|
120
|
+
if (v === "false" || v === "0" || v === "no" || v === "off")
|
|
121
|
+
return false;
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
/** Parse a comma-separated tool-name list env var. */
|
|
125
|
+
function envToolList(name) {
|
|
126
|
+
const raw = process.env[name];
|
|
127
|
+
if (!raw)
|
|
128
|
+
return [];
|
|
129
|
+
return raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Resolve preferences + environment overrides into the active configuration.
|
|
133
|
+
* Environment variables win over preferences; preferences win over built-in
|
|
134
|
+
* defaults. User-supplied exempt tools are additive to the built-in exempt
|
|
135
|
+
* set so defaults are always preserved.
|
|
136
|
+
*
|
|
137
|
+
* Applied to both interactive sessions and `/gsd auto` (called from the
|
|
138
|
+
* session_start / session_switch hooks).
|
|
139
|
+
*/
|
|
140
|
+
export function configureToolCallLoopGuard(prefs) {
|
|
141
|
+
const next = defaultGuardConfig();
|
|
142
|
+
if (prefs) {
|
|
143
|
+
if (typeof prefs.enabled === "boolean")
|
|
144
|
+
next.guardEnabled = prefs.enabled;
|
|
145
|
+
if (prefs.identical_args) {
|
|
146
|
+
if (typeof prefs.identical_args.enabled === "boolean")
|
|
147
|
+
next.identicalEnabled = prefs.identical_args.enabled;
|
|
148
|
+
if (typeof prefs.identical_args.max_consecutive_calls === "number" && prefs.identical_args.max_consecutive_calls >= 1) {
|
|
149
|
+
next.maxConsecutiveIdentical = Math.floor(prefs.identical_args.max_consecutive_calls);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (prefs.repeated_tool) {
|
|
153
|
+
if (typeof prefs.repeated_tool.enabled === "boolean")
|
|
154
|
+
next.repeatedEnabled = prefs.repeated_tool.enabled;
|
|
155
|
+
if (typeof prefs.repeated_tool.default_cap === "number" && prefs.repeated_tool.default_cap >= 1) {
|
|
156
|
+
next.perToolDefaultCap = Math.floor(prefs.repeated_tool.default_cap);
|
|
157
|
+
}
|
|
158
|
+
if (typeof prefs.repeated_tool.repeatable_cap === "number" && prefs.repeated_tool.repeatable_cap >= 1) {
|
|
159
|
+
next.perToolRepeatableCap = Math.floor(prefs.repeated_tool.repeatable_cap);
|
|
160
|
+
}
|
|
161
|
+
for (const tool of prefs.repeated_tool.exempt_tools ?? []) {
|
|
162
|
+
if (typeof tool === "string" && tool.trim())
|
|
163
|
+
next.perToolExempt.add(tool.trim());
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Environment overrides (win over preferences).
|
|
168
|
+
const envEnabled = envBool("GSD_TOOL_LOOP_GUARD_ENABLED");
|
|
169
|
+
if (envEnabled !== undefined)
|
|
170
|
+
next.guardEnabled = envEnabled;
|
|
171
|
+
const envIdenticalMax = envPositiveInt("GSD_TOOL_LOOP_IDENTICAL_MAX");
|
|
172
|
+
if (envIdenticalMax !== undefined)
|
|
173
|
+
next.maxConsecutiveIdentical = envIdenticalMax;
|
|
174
|
+
const envDefaultCap = envPositiveInt("GSD_TOOL_LOOP_REPEATED_DEFAULT_CAP");
|
|
175
|
+
if (envDefaultCap !== undefined)
|
|
176
|
+
next.perToolDefaultCap = envDefaultCap;
|
|
177
|
+
const envRepeatableCap = envPositiveInt("GSD_TOOL_LOOP_REPEATED_REPEATABLE_CAP");
|
|
178
|
+
if (envRepeatableCap !== undefined)
|
|
179
|
+
next.perToolRepeatableCap = envRepeatableCap;
|
|
180
|
+
for (const tool of envToolList("GSD_TOOL_LOOP_EXEMPT_TOOLS"))
|
|
181
|
+
next.perToolExempt.add(tool);
|
|
182
|
+
config = next;
|
|
183
|
+
}
|
|
47
184
|
let consecutiveCount = 0;
|
|
48
185
|
let lastSignature = "";
|
|
49
186
|
let lastToolName = "";
|
|
@@ -72,14 +209,17 @@ function hashToolCall(toolName, args) {
|
|
|
72
209
|
* Returns `{ block: true, reason }` when the loop threshold is exceeded.
|
|
73
210
|
*
|
|
74
211
|
* Two independent guards run; whichever trips first blocks:
|
|
75
|
-
* 1. Identical-signature streak (
|
|
212
|
+
* 1. Identical-signature streak (config.maxConsecutiveIdentical, strict for
|
|
76
213
|
* ask_user_questions).
|
|
77
|
-
* 2. Per-tool-name cap (
|
|
214
|
+
* 2. Per-tool-name cap (config.perToolDefaultCap / config.perToolRepeatableCap),
|
|
78
215
|
* independent of args, reset after file-mutation progress — catches
|
|
79
216
|
* improvisation loops (#783).
|
|
217
|
+
*
|
|
218
|
+
* Both guards, their thresholds, and the per-tool exempt set are user-tunable
|
|
219
|
+
* via {@link configureToolCallLoopGuard} (#1198).
|
|
80
220
|
*/
|
|
81
221
|
export function checkToolCallLoop(toolName, args) {
|
|
82
|
-
if (!enabled)
|
|
222
|
+
if (!enabled || !config.guardEnabled)
|
|
83
223
|
return { block: false, count: 0 };
|
|
84
224
|
const sig = hashToolCall(toolName, args);
|
|
85
225
|
if (sig === lastSignature) {
|
|
@@ -93,12 +233,14 @@ export function checkToolCallLoop(toolName, args) {
|
|
|
93
233
|
// ── Guard 1: identical-signature streak ──
|
|
94
234
|
const threshold = STRICT_LOOP_TOOLS.has(toolName)
|
|
95
235
|
? MAX_CONSECUTIVE_STRICT
|
|
96
|
-
:
|
|
97
|
-
if (consecutiveCount > threshold) {
|
|
236
|
+
: config.maxConsecutiveIdentical;
|
|
237
|
+
if (config.identicalEnabled && consecutiveCount > threshold) {
|
|
98
238
|
return {
|
|
99
239
|
block: true,
|
|
100
240
|
reason: `Tool loop detected (identical args): ${toolName} called ${consecutiveCount} times ` +
|
|
101
|
-
`with identical arguments. Blocking to prevent infinite loop. ` +
|
|
241
|
+
`with identical arguments (max ${threshold}). Blocking to prevent infinite loop. ` +
|
|
242
|
+
`Raise tool_call_loop_guard.identical_args.max_consecutive_calls in .gsd/PREFERENCES.md ` +
|
|
243
|
+
`(or GSD_TOOL_LOOP_IDENTICAL_MAX) if this is expected. ` +
|
|
102
244
|
`Do not retry this tool or call other tools this turn — stop and respond to the user in text.`,
|
|
103
245
|
count: consecutiveCount,
|
|
104
246
|
};
|
|
@@ -119,30 +261,46 @@ export function checkToolCallLoop(toolName, args) {
|
|
|
119
261
|
// so the arg-independent per-tool cap misfires on legitimate verification;
|
|
120
262
|
// Guard 1's identical-signature streak still catches a genuinely stuck
|
|
121
263
|
// browser loop.
|
|
122
|
-
if (
|
|
264
|
+
if (!config.repeatedEnabled ||
|
|
265
|
+
config.perToolExempt.has(toolName) ||
|
|
123
266
|
hasBrowserContractPrefix(canonicalToolName(toolName))) {
|
|
124
267
|
return { block: false, count: consecutiveCount };
|
|
125
268
|
}
|
|
126
269
|
const perToolCap = INHERENTLY_REPEATABLE_TOOL_SET.has(toolName)
|
|
127
|
-
?
|
|
128
|
-
:
|
|
270
|
+
? config.perToolRepeatableCap
|
|
271
|
+
: config.perToolDefaultCap;
|
|
129
272
|
if (perToolCount > perToolCap) {
|
|
130
273
|
return {
|
|
131
274
|
block: true,
|
|
132
275
|
reason: `Tool loop detected (repeated tool): ${toolName} called ${perToolCount} times ` +
|
|
133
276
|
`this turn (cap ${perToolCap}). Blocking to prevent infinite loop. ` +
|
|
134
277
|
`The tool may be unavailable or failing repeatedly. ` +
|
|
278
|
+
`Raise tool_call_loop_guard.repeated_tool.default_cap/repeatable_cap or add "${toolName}" ` +
|
|
279
|
+
`to tool_call_loop_guard.repeated_tool.exempt_tools in .gsd/PREFERENCES.md ` +
|
|
280
|
+
`(or GSD_TOOL_LOOP_REPEATED_* / GSD_TOOL_LOOP_EXEMPT_TOOLS) if this is expected. ` +
|
|
135
281
|
`Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.`,
|
|
136
282
|
count: perToolCount,
|
|
137
283
|
};
|
|
138
284
|
}
|
|
139
285
|
return { block: false, count: consecutiveCount };
|
|
140
286
|
}
|
|
141
|
-
/**
|
|
142
|
-
|
|
287
|
+
/**
|
|
288
|
+
* Record successful state progress so Guard 2 can decay on the next count.
|
|
289
|
+
* File mutations (edit/write/…) and successful shell/exec calls (bash,
|
|
290
|
+
* bg_shell, gsd_uat_exec, …) both count as progress (#1092, #1206). The caller
|
|
291
|
+
* only invokes this for non-error results, so failing improvisation loops
|
|
292
|
+
* (#783) never decay and still trip the per-tool cap.
|
|
293
|
+
*/
|
|
294
|
+
export function recordToolCallLoopMutation(toolName, details) {
|
|
143
295
|
if (!enabled)
|
|
144
296
|
return;
|
|
145
|
-
if (
|
|
297
|
+
if (STATE_MUTATING_TOOL_SET.has(toolName)) {
|
|
298
|
+
mutationEpoch++;
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (!STATE_PROGRESSING_EXEC_TOOL_SET.has(toolName))
|
|
302
|
+
return;
|
|
303
|
+
if (toolName === "bg_shell" && details !== undefined && !isSuccessfulBgShellLoopProgress(details))
|
|
146
304
|
return;
|
|
147
305
|
mutationEpoch++;
|
|
148
306
|
}
|