@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
|
@@ -116,7 +116,8 @@ import {
|
|
|
116
116
|
} from "./auto-tool-tracking.js";
|
|
117
117
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
118
118
|
import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
|
|
119
|
-
import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
|
|
119
|
+
import { selectAndApplyModel, resolveModelId, clearToolBaseline, isModelUnavailable, applyThinkingLevelForModel } from "./auto-model-selection.js";
|
|
120
|
+
import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
|
|
120
121
|
import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
|
|
121
122
|
import {
|
|
122
123
|
checkPostUnitHooks,
|
|
@@ -127,6 +128,7 @@ import {
|
|
|
127
128
|
runPreDispatchHooks,
|
|
128
129
|
persistHookState,
|
|
129
130
|
restoreHookState,
|
|
131
|
+
reconcileRestoredHookDispatch,
|
|
130
132
|
clearPersistedHookState,
|
|
131
133
|
} from "./post-unit-hooks.js";
|
|
132
134
|
import { runGSDDoctor, rebuildState } from "./doctor.js";
|
|
@@ -177,24 +179,19 @@ import {
|
|
|
177
179
|
import { GitServiceImpl } from "./git-service.js";
|
|
178
180
|
import { nativeCheckoutBranch } from "./native-git-bridge.js";
|
|
179
181
|
import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
|
|
180
|
-
import {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
syncWorktreeStateBack,
|
|
191
|
-
readResourceVersion,
|
|
192
|
-
checkResourcesStale,
|
|
193
|
-
escapeStaleWorktree,
|
|
194
|
-
} from "./auto-worktree.js";
|
|
182
|
+
import { autoWorktreeBranch, enterBranchModeForMilestone } from "./auto-worktree-branch-lifecycle.js";
|
|
183
|
+
import { createAutoWorktree } from "./auto-worktree-creation.js";
|
|
184
|
+
import { enterAutoWorktree, isInAutoWorktree } from "./auto-worktree-entry.js";
|
|
185
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
186
|
+
import { checkResourcesStale, readResourceVersion } from "./auto-worktree-resource-version.js";
|
|
187
|
+
import { escapeStaleWorktree } from "./auto-worktree-runtime-cleanup.js";
|
|
188
|
+
import { teardownWarmedBrowserDaemons } from "./browser-daemon-auto-prep.js";
|
|
189
|
+
import { getAutoWorktreeOriginalBase } from "./auto-worktree-session-registry.js";
|
|
190
|
+
import { syncWorktreeStateBack } from "./auto-worktree-sync.js";
|
|
191
|
+
import { teardownAutoWorktree } from "./auto-worktree-teardown.js";
|
|
195
192
|
import { pruneQueueOrder } from "./queue-order.js";
|
|
196
193
|
import { startCommandPolling as _startCommandPolling, isRemoteConfigured } from "../remote-questions/manager.js";
|
|
197
|
-
import {
|
|
194
|
+
import { createDefaultMilestoneMergeTransaction } from "./milestone-merge-transaction.js";
|
|
198
195
|
|
|
199
196
|
import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
|
|
200
197
|
import {
|
|
@@ -621,11 +618,27 @@ export function startAutoDetached(
|
|
|
621
618
|
milestoneLock?: string | null;
|
|
622
619
|
},
|
|
623
620
|
): void {
|
|
624
|
-
void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch((err) => {
|
|
621
|
+
void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch(async (err) => {
|
|
625
622
|
const message = getErrorMessage(err);
|
|
626
623
|
ctx.ui.notify(`Auto-start failed: ${message}`, "error");
|
|
627
624
|
logWarning("engine", `auto start error: ${message}`, { file: "auto.ts" });
|
|
628
625
|
debugLog("auto-start-failed", { error: message });
|
|
626
|
+
// Backstop cleanup (#1235): if startAuto threw after auto-mode was activated
|
|
627
|
+
// (e.g. an exception during bootstrap, before the loop's try/finally could
|
|
628
|
+
// run cleanupAfterLoopExit), s.active and the on-disk auto lock leak, so the
|
|
629
|
+
// re-entry guard silently no-ops every later /gsd auto until restart. Clear
|
|
630
|
+
// the leaked activation here so a failed start is always recoverable.
|
|
631
|
+
if (s.active) {
|
|
632
|
+
try {
|
|
633
|
+
await cleanupAfterLoopExit(ctx);
|
|
634
|
+
} catch (cleanupErr) {
|
|
635
|
+
logWarning(
|
|
636
|
+
"engine",
|
|
637
|
+
`auto start cleanup failed: ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}`,
|
|
638
|
+
{ file: "auto.ts" },
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
629
642
|
});
|
|
630
643
|
}
|
|
631
644
|
|
|
@@ -1478,6 +1491,17 @@ export async function cleanupAfterLoopExit(ctx: ExtensionContext): Promise<void>
|
|
|
1478
1491
|
logWarning("session", `lock cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1479
1492
|
}
|
|
1480
1493
|
|
|
1494
|
+
// Symmetric teardown for the browser-UAT warm-up preflight (#1259): stop any
|
|
1495
|
+
// gsd-browser daemon this session started so the Chrome process does not
|
|
1496
|
+
// linger after the loop exits. Re-warms on the next browser-backed run-uat.
|
|
1497
|
+
try {
|
|
1498
|
+
for (const { projectRoot, error } of teardownWarmedBrowserDaemons()) {
|
|
1499
|
+
logWarning("session", `gsd-browser daemon stop failed for ${projectRoot}: ${error}`, { file: "auto.ts" });
|
|
1500
|
+
}
|
|
1501
|
+
} catch (err) {
|
|
1502
|
+
logWarning("session", `browser daemon teardown failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1481
1505
|
// A transient provider-error pause intentionally leaves the paused badge
|
|
1482
1506
|
// visible so the user still has a resumable auto-mode signal on screen.
|
|
1483
1507
|
if (!s.paused) {
|
|
@@ -2326,7 +2350,7 @@ export function buildWorktreeLifecycleDeps(): WorktreeLifecycleDeps {
|
|
|
2326
2350
|
return new GitServiceImpl(basePath, gitConfig);
|
|
2327
2351
|
},
|
|
2328
2352
|
worktreeProjection: new WorktreeStateProjection(),
|
|
2329
|
-
mergeMilestone:
|
|
2353
|
+
mergeMilestone: createDefaultMilestoneMergeTransaction(),
|
|
2330
2354
|
};
|
|
2331
2355
|
}
|
|
2332
2356
|
|
|
@@ -2833,6 +2857,10 @@ export async function startAuto(
|
|
|
2833
2857
|
"info",
|
|
2834
2858
|
);
|
|
2835
2859
|
restoreHookState(s.basePath);
|
|
2860
|
+
// A restored activeHook has no live dispatch (the sidecar queue is not
|
|
2861
|
+
// persisted); re-enqueue it so the hook runs instead of blocking the next
|
|
2862
|
+
// unrelated unit's close-out (#1246).
|
|
2863
|
+
reconcileRestoredHookDispatch(s.basePath, s.sidecarQueue);
|
|
2836
2864
|
// Re-sync managed resources on resume so long-lived auto sessions pick up
|
|
2837
2865
|
// bundled extension updates before resume-time verification/state logic runs.
|
|
2838
2866
|
// GSD_PKG_ROOT is set by loader.ts and points to the gsd-pi package root.
|
|
@@ -2901,15 +2929,18 @@ export async function startAuto(
|
|
|
2901
2929
|
debugLog("resume-orchestration-resume", { error: err instanceof Error ? err.message : String(err) });
|
|
2902
2930
|
}
|
|
2903
2931
|
startAutoCommandPolling(s.basePath);
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2932
|
+
try {
|
|
2933
|
+
await runAutoLoopWithUok({
|
|
2934
|
+
ctx,
|
|
2935
|
+
pi,
|
|
2936
|
+
s,
|
|
2937
|
+
deps: loopDeps,
|
|
2938
|
+
runKernelLoop: runUokKernelLoop,
|
|
2939
|
+
runLegacyLoop: runLegacyAutoLoop,
|
|
2940
|
+
});
|
|
2941
|
+
} finally {
|
|
2942
|
+
await cleanupAfterLoopExit(ctx);
|
|
2943
|
+
}
|
|
2913
2944
|
return;
|
|
2914
2945
|
}
|
|
2915
2946
|
|
|
@@ -2937,7 +2968,15 @@ export async function startAuto(
|
|
|
2937
2968
|
bootstrapDeps,
|
|
2938
2969
|
freshStartAssessment,
|
|
2939
2970
|
);
|
|
2940
|
-
if (!ready)
|
|
2971
|
+
if (!ready) {
|
|
2972
|
+
// bootstrapAutoSession sets s.active = true (auto-start.ts) before several
|
|
2973
|
+
// post-activation bail-outs return false without a loop ever running (e.g.
|
|
2974
|
+
// the SQLite-unavailable gate). Without this, s.active and the auto lock
|
|
2975
|
+
// leak and every later /gsd auto silently no-ops via the re-entry guard
|
|
2976
|
+
// (#1235). Run the canonical cleanup so a failed bootstrap stays recoverable.
|
|
2977
|
+
if (s.active) await cleanupAfterLoopExit(ctx);
|
|
2978
|
+
return;
|
|
2979
|
+
}
|
|
2941
2980
|
|
|
2942
2981
|
// Build scope after bootstrap has populated s.basePath / s.originalBasePath /
|
|
2943
2982
|
// s.currentMilestoneId (including worktree setup inside bootstrapAutoSession).
|
|
@@ -2963,15 +3002,18 @@ export async function startAuto(
|
|
|
2963
3002
|
startAutoCommandPolling(s.basePath);
|
|
2964
3003
|
|
|
2965
3004
|
// Dispatch the first unit
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
3005
|
+
try {
|
|
3006
|
+
await runAutoLoopWithUok({
|
|
3007
|
+
ctx,
|
|
3008
|
+
pi,
|
|
3009
|
+
s,
|
|
3010
|
+
deps: loopDeps,
|
|
3011
|
+
runKernelLoop: runUokKernelLoop,
|
|
3012
|
+
runLegacyLoop: runLegacyAutoLoop,
|
|
3013
|
+
});
|
|
3014
|
+
} finally {
|
|
3015
|
+
await cleanupAfterLoopExit(ctx);
|
|
3016
|
+
}
|
|
2975
3017
|
}
|
|
2976
3018
|
|
|
2977
3019
|
// describeNextUnit is imported from auto-dashboard.ts and re-exported
|
|
@@ -3129,19 +3171,56 @@ export async function dispatchHookUnit(
|
|
|
3129
3171
|
workspaceRoot: s.basePath,
|
|
3130
3172
|
});
|
|
3131
3173
|
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3174
|
+
// Resolve the hook's model honoring the configured `fallbacks[]` chain
|
|
3175
|
+
// (#1229). The manual trigger path bypasses selectAndApplyModel, so resolve
|
|
3176
|
+
// the primary→fallbacks order here and apply the first candidate available in
|
|
3177
|
+
// the registry — a blocked or unconfigured primary then transparently drops
|
|
3178
|
+
// to a fallback instead of silently reverting to the session model.
|
|
3179
|
+
const availableModels = ctx.modelRegistry.getAvailable();
|
|
3180
|
+
const availableModelIds = availableModels.map(
|
|
3181
|
+
(m: { provider: string; id: string }) => `${m.provider}/${m.id}`,
|
|
3182
|
+
);
|
|
3183
|
+
const hookModelConfig = resolveModelWithFallbacksForUnit(
|
|
3184
|
+
hookUnitType,
|
|
3185
|
+
targetBasePath,
|
|
3186
|
+
availableModelIds,
|
|
3187
|
+
);
|
|
3188
|
+
const modelCandidates = hookModelConfig
|
|
3189
|
+
? [hookModelConfig.primary, ...hookModelConfig.fallbacks]
|
|
3190
|
+
: hookModel
|
|
3191
|
+
? [hookModel]
|
|
3192
|
+
: [];
|
|
3193
|
+
if (modelCandidates.length > 0) {
|
|
3194
|
+
let applied = false;
|
|
3195
|
+
for (const candidate of modelCandidates) {
|
|
3196
|
+
const match = resolveModelId(candidate, availableModels, ctx.model?.provider);
|
|
3197
|
+
if (!match) continue;
|
|
3198
|
+
// Skip models the runtime has marked blocked or temporarily unavailable
|
|
3199
|
+
// (e.g. a primary that just tripped a provider limit) so the configured
|
|
3200
|
+
// fallbacks[] chain actually engages — parity with auto-mode's
|
|
3201
|
+
// selectAndApplyModel, which consults the same blocked-models store (#1229).
|
|
3202
|
+
if (isModelUnavailable(targetBasePath, match.provider, match.id)) continue;
|
|
3136
3203
|
try {
|
|
3137
|
-
await pi.setModel(match)
|
|
3204
|
+
if (await pi.setModel(match)) {
|
|
3205
|
+
// The manual trigger path bypasses selectAndApplyModel, so apply the
|
|
3206
|
+
// hook's per-field `thinking` (from `post_unit_hooks[].model`'s object
|
|
3207
|
+
// form) here against the just-set model rather than leaving the hook at
|
|
3208
|
+
// the session level (#1269). Absent → session level, unchanged.
|
|
3209
|
+
if (hookModelConfig?.thinking) {
|
|
3210
|
+
applyThinkingLevelForModel(pi, hookModelConfig.thinking, match, ctx);
|
|
3211
|
+
}
|
|
3212
|
+
applied = true;
|
|
3213
|
+
break;
|
|
3214
|
+
}
|
|
3138
3215
|
} catch (err) {
|
|
3139
|
-
/* non-fatal */
|
|
3140
|
-
logWarning("dispatch", `hook model set failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
3216
|
+
/* non-fatal — try the next fallback */
|
|
3217
|
+
logWarning("dispatch", `hook model set failed for ${candidate}: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
3141
3218
|
}
|
|
3142
|
-
}
|
|
3219
|
+
}
|
|
3220
|
+
if (!applied) {
|
|
3143
3221
|
ctx.ui.notify(
|
|
3144
|
-
`Hook model
|
|
3222
|
+
`Hook model${modelCandidates.length > 1 ? "s" : ""} "${modelCandidates.join(", ")}" not available. ` +
|
|
3223
|
+
`Falling back to current session model. ` +
|
|
3145
3224
|
`Ensure the model is defined in models.json and has auth configured.`,
|
|
3146
3225
|
"warning",
|
|
3147
3226
|
);
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
type WorkflowDatabaseOpenResult,
|
|
15
15
|
type WorkflowDatabaseStatus,
|
|
16
16
|
} from "../db-workspace.js";
|
|
17
|
-
import { getAutoWorktreePath } from "../auto-worktree.js";
|
|
17
|
+
import { getAutoWorktreePath } from "../auto-worktree-path-resolution.js";
|
|
18
18
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
19
19
|
import { worktreesDirs } from "../worktree-placement.js";
|
|
20
20
|
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
} from "../auto-tool-tracking.js";
|
|
41
41
|
import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
|
|
42
42
|
|
|
43
|
-
import { checkToolCallLoop, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
43
|
+
import { checkToolCallLoop, configureToolCallLoopGuard, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
44
44
|
import { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
|
|
45
45
|
import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
|
|
46
46
|
import { saveActivityLog } from "../activity-log.js";
|
|
@@ -594,6 +594,22 @@ async function applyCompactionThresholdOverride(ctx: ExtensionContext): Promise<
|
|
|
594
594
|
}
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
+
/**
|
|
598
|
+
* Apply user-tunable tool-call loop guard thresholds (#1198) from GSD
|
|
599
|
+
* preferences plus GSD_TOOL_LOOP_* env overrides. Runs at session boundaries
|
|
600
|
+
* so both interactive sessions and `/gsd auto` pick up the configuration.
|
|
601
|
+
* Non-fatal: falls back to built-in defaults when preferences cannot be loaded.
|
|
602
|
+
*/
|
|
603
|
+
async function applyToolCallLoopGuardConfig(basePath: string): Promise<void> {
|
|
604
|
+
try {
|
|
605
|
+
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
606
|
+
const prefs = loadEffectiveGSDPreferences(basePath);
|
|
607
|
+
configureToolCallLoopGuard(prefs?.preferences.tool_call_loop_guard);
|
|
608
|
+
} catch {
|
|
609
|
+
configureToolCallLoopGuard(null);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
597
613
|
function clearDeferredApprovalGate(basePath?: string): void {
|
|
598
614
|
if (!basePath) {
|
|
599
615
|
deferredApprovalGates.clear();
|
|
@@ -996,6 +1012,7 @@ export function registerHooks(
|
|
|
996
1012
|
}
|
|
997
1013
|
resetWriteGateState(basePath);
|
|
998
1014
|
resetToolCallLoopGuard();
|
|
1015
|
+
await applyToolCallLoopGuardConfig(basePath);
|
|
999
1016
|
approvalQuestionAbortInFlight = false;
|
|
1000
1017
|
clearDeferredApprovalGate();
|
|
1001
1018
|
await resetAskUserQuestionsTurnCache();
|
|
@@ -1087,6 +1104,7 @@ export function registerHooks(
|
|
|
1087
1104
|
initSessionNotifications(ctx);
|
|
1088
1105
|
resetWriteGateState(basePath);
|
|
1089
1106
|
resetToolCallLoopGuard();
|
|
1107
|
+
await applyToolCallLoopGuardConfig(basePath);
|
|
1090
1108
|
clearDeferredApprovalGate();
|
|
1091
1109
|
await resetAskUserQuestionsTurnCache();
|
|
1092
1110
|
clearDiscussionFlowState(basePath);
|
|
@@ -1707,7 +1725,7 @@ export function registerHooks(
|
|
|
1707
1725
|
}
|
|
1708
1726
|
}
|
|
1709
1727
|
if (!event.isError) {
|
|
1710
|
-
recordToolCallLoopMutation(toolName);
|
|
1728
|
+
recordToolCallLoopMutation(toolName, event.details);
|
|
1711
1729
|
refreshSourceObservationAfterMutation(toolName, event.input, ctx);
|
|
1712
1730
|
clearSourceObservationsAfterShell(toolName);
|
|
1713
1731
|
}
|
|
@@ -14,7 +14,7 @@ import { resolveModelWithFallbacksForUnit } from "../preferences-models.js";
|
|
|
14
14
|
import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
|
|
15
15
|
import { extractIntroAndRules } from "../knowledge-parser.js";
|
|
16
16
|
import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
|
|
17
|
-
import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
|
|
17
|
+
import { getActiveAutoWorktreeContext } from "../auto-worktree-session-registry.js";
|
|
18
18
|
import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-session-state.js";
|
|
19
19
|
import { deriveState } from "../state.js";
|
|
20
20
|
import { formatOverridesSection, formatShortcut, loadActiveOverrides, loadFile, parseContinue, parseSummary } from "../files.js";
|
|
@@ -14,13 +14,21 @@
|
|
|
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
|
|
|
26
34
|
import { createHash } from "node:crypto";
|
|
@@ -28,26 +36,189 @@ import { INHERENTLY_REPEATABLE_TOOL_SET } from "./core-session-tools.js";
|
|
|
28
36
|
import { hasBrowserContractPrefix } from "../../shared/browser-contract.js";
|
|
29
37
|
import { canonicalToolName } from "../engine-hook-contract.js";
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
/** Built-in defaults. Preserved when preferences/env do not override them. */
|
|
40
|
+
const DEFAULT_MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
|
|
41
|
+
const DEFAULT_PER_TOOL_DEFAULT_CAP = 6;
|
|
42
|
+
const DEFAULT_PER_TOOL_REPEATABLE_CAP = 15;
|
|
43
|
+
const DEFAULT_PER_TOOL_CAP_EXEMPT_TOOLS = ["find", "glob", "grep", "ls", "read", "search_and_read"] as const;
|
|
32
44
|
|
|
33
45
|
/** Interactive/user-facing tools where even 1 duplicate is confusing. */
|
|
34
46
|
const STRICT_LOOP_TOOLS = new Set(["ask_user_questions"]);
|
|
35
47
|
const MAX_CONSECUTIVE_STRICT = 1;
|
|
36
48
|
|
|
49
|
+
const STATE_MUTATING_TOOL_SET = new Set(["edit", "write", "multi_edit", "notebook_edit"]);
|
|
50
|
+
|
|
37
51
|
/**
|
|
38
|
-
*
|
|
52
|
+
* Successful shell/exec calls are state progression too (#1206), not just file
|
|
53
|
+
* mutations. A local model debugging a UAT scenario legitimately restarts
|
|
54
|
+
* servers, runs `npm install`, and curls endpoints via bg_shell / gsd_uat_exec
|
|
55
|
+
* with varied args — productive work that never touches a file, so Guard 2's
|
|
56
|
+
* per-tool cap would otherwise misfire as a false loop. Decaying on these
|
|
57
|
+
* successful calls keeps the guard from aborting a progressing turn.
|
|
39
58
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
59
|
+
* Only successful calls reach {@link recordToolCallLoopMutation}: the
|
|
60
|
+
* tool_result hook skips `isError` results, and the bash tool throws on
|
|
61
|
+
* non-zero exit, so a genuinely stuck improvisation loop of failing commands
|
|
62
|
+
* (#783) never decays and still trips the cap. `async_bash` is excluded
|
|
63
|
+
* because it only registers a background job; command success is reported
|
|
64
|
+
* later via `await_job`. `bg_shell` may return `isError: false` for failed
|
|
65
|
+
* `run`/`start` outcomes, so the hook passes `details` for validation.
|
|
46
66
|
*/
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
const STATE_PROGRESSING_EXEC_TOOL_SET = new Set([
|
|
68
|
+
"bash",
|
|
69
|
+
"bg_shell",
|
|
70
|
+
"shell",
|
|
71
|
+
"powershell",
|
|
72
|
+
"gsd_exec",
|
|
73
|
+
"gsd_uat_exec",
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
function isSuccessfulBgShellLoopProgress(details: unknown): boolean {
|
|
77
|
+
if (!details || typeof details !== "object") return false;
|
|
78
|
+
const record = details as Record<string, unknown>;
|
|
79
|
+
switch (record.action) {
|
|
80
|
+
case "run":
|
|
81
|
+
return record.exitCode === 0 && record.timedOut !== true;
|
|
82
|
+
case "start":
|
|
83
|
+
case "restart": {
|
|
84
|
+
const process = record.process;
|
|
85
|
+
if (!process || typeof process !== "object") return false;
|
|
86
|
+
return (process as Record<string, unknown>).alive === true;
|
|
87
|
+
}
|
|
88
|
+
case "wait_for_ready":
|
|
89
|
+
return record.ready === true;
|
|
90
|
+
case "send_and_wait":
|
|
91
|
+
return record.matched === true;
|
|
92
|
+
default:
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* User-tunable configuration shape for the loop guard (#1198).
|
|
99
|
+
*
|
|
100
|
+
* Mirrors the `tool_call_loop_guard` key in `.gsd/PREFERENCES.md`. All fields
|
|
101
|
+
* are optional; anything omitted falls back to the built-in defaults so that
|
|
102
|
+
* existing installs keep their current behavior.
|
|
103
|
+
*/
|
|
104
|
+
export interface ToolCallLoopGuardConfig {
|
|
105
|
+
enabled?: boolean;
|
|
106
|
+
identical_args?: {
|
|
107
|
+
enabled?: boolean;
|
|
108
|
+
max_consecutive_calls?: number;
|
|
109
|
+
};
|
|
110
|
+
repeated_tool?: {
|
|
111
|
+
enabled?: boolean;
|
|
112
|
+
default_cap?: number;
|
|
113
|
+
repeatable_cap?: number;
|
|
114
|
+
exempt_tools?: string[];
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Active, resolved configuration. Set by {@link configureToolCallLoopGuard}
|
|
120
|
+
* from preferences + environment overrides, and deliberately NOT touched by
|
|
121
|
+
* {@link resetToolCallLoopGuard} so a session's tuning survives turn
|
|
122
|
+
* boundaries.
|
|
123
|
+
*/
|
|
124
|
+
interface ResolvedGuardConfig {
|
|
125
|
+
/** Master switch for both guards. */
|
|
126
|
+
guardEnabled: boolean;
|
|
127
|
+
identicalEnabled: boolean;
|
|
128
|
+
maxConsecutiveIdentical: number;
|
|
129
|
+
repeatedEnabled: boolean;
|
|
130
|
+
perToolDefaultCap: number;
|
|
131
|
+
perToolRepeatableCap: number;
|
|
132
|
+
/** Tool names exempt from Guard 2 (per-tool-name cap). */
|
|
133
|
+
perToolExempt: Set<string>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function defaultGuardConfig(): ResolvedGuardConfig {
|
|
137
|
+
return {
|
|
138
|
+
guardEnabled: true,
|
|
139
|
+
identicalEnabled: true,
|
|
140
|
+
maxConsecutiveIdentical: DEFAULT_MAX_CONSECUTIVE_IDENTICAL_CALLS,
|
|
141
|
+
repeatedEnabled: true,
|
|
142
|
+
perToolDefaultCap: DEFAULT_PER_TOOL_DEFAULT_CAP,
|
|
143
|
+
perToolRepeatableCap: DEFAULT_PER_TOOL_REPEATABLE_CAP,
|
|
144
|
+
perToolExempt: new Set<string>(DEFAULT_PER_TOOL_CAP_EXEMPT_TOOLS),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let config: ResolvedGuardConfig = defaultGuardConfig();
|
|
149
|
+
|
|
150
|
+
/** Parse a positive-integer env var, returning undefined when unset/invalid. */
|
|
151
|
+
function envPositiveInt(name: string): number | undefined {
|
|
152
|
+
const raw = process.env[name];
|
|
153
|
+
if (raw === undefined || raw.trim() === "") return undefined;
|
|
154
|
+
const n = Number(raw);
|
|
155
|
+
return Number.isFinite(n) && n >= 1 ? Math.floor(n) : undefined;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Parse a boolean env var (`true`/`1` vs `false`/`0`), undefined when unset. */
|
|
159
|
+
function envBool(name: string): boolean | undefined {
|
|
160
|
+
const raw = process.env[name];
|
|
161
|
+
if (raw === undefined || raw.trim() === "") return undefined;
|
|
162
|
+
const v = raw.trim().toLowerCase();
|
|
163
|
+
if (v === "true" || v === "1" || v === "yes" || v === "on") return true;
|
|
164
|
+
if (v === "false" || v === "0" || v === "no" || v === "off") return false;
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Parse a comma-separated tool-name list env var. */
|
|
169
|
+
function envToolList(name: string): string[] {
|
|
170
|
+
const raw = process.env[name];
|
|
171
|
+
if (!raw) return [];
|
|
172
|
+
return raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Resolve preferences + environment overrides into the active configuration.
|
|
177
|
+
* Environment variables win over preferences; preferences win over built-in
|
|
178
|
+
* defaults. User-supplied exempt tools are additive to the built-in exempt
|
|
179
|
+
* set so defaults are always preserved.
|
|
180
|
+
*
|
|
181
|
+
* Applied to both interactive sessions and `/gsd auto` (called from the
|
|
182
|
+
* session_start / session_switch hooks).
|
|
183
|
+
*/
|
|
184
|
+
export function configureToolCallLoopGuard(prefs?: ToolCallLoopGuardConfig | null): void {
|
|
185
|
+
const next = defaultGuardConfig();
|
|
186
|
+
|
|
187
|
+
if (prefs) {
|
|
188
|
+
if (typeof prefs.enabled === "boolean") next.guardEnabled = prefs.enabled;
|
|
189
|
+
if (prefs.identical_args) {
|
|
190
|
+
if (typeof prefs.identical_args.enabled === "boolean") next.identicalEnabled = prefs.identical_args.enabled;
|
|
191
|
+
if (typeof prefs.identical_args.max_consecutive_calls === "number" && prefs.identical_args.max_consecutive_calls >= 1) {
|
|
192
|
+
next.maxConsecutiveIdentical = Math.floor(prefs.identical_args.max_consecutive_calls);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (prefs.repeated_tool) {
|
|
196
|
+
if (typeof prefs.repeated_tool.enabled === "boolean") next.repeatedEnabled = prefs.repeated_tool.enabled;
|
|
197
|
+
if (typeof prefs.repeated_tool.default_cap === "number" && prefs.repeated_tool.default_cap >= 1) {
|
|
198
|
+
next.perToolDefaultCap = Math.floor(prefs.repeated_tool.default_cap);
|
|
199
|
+
}
|
|
200
|
+
if (typeof prefs.repeated_tool.repeatable_cap === "number" && prefs.repeated_tool.repeatable_cap >= 1) {
|
|
201
|
+
next.perToolRepeatableCap = Math.floor(prefs.repeated_tool.repeatable_cap);
|
|
202
|
+
}
|
|
203
|
+
for (const tool of prefs.repeated_tool.exempt_tools ?? []) {
|
|
204
|
+
if (typeof tool === "string" && tool.trim()) next.perToolExempt.add(tool.trim());
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Environment overrides (win over preferences).
|
|
210
|
+
const envEnabled = envBool("GSD_TOOL_LOOP_GUARD_ENABLED");
|
|
211
|
+
if (envEnabled !== undefined) next.guardEnabled = envEnabled;
|
|
212
|
+
const envIdenticalMax = envPositiveInt("GSD_TOOL_LOOP_IDENTICAL_MAX");
|
|
213
|
+
if (envIdenticalMax !== undefined) next.maxConsecutiveIdentical = envIdenticalMax;
|
|
214
|
+
const envDefaultCap = envPositiveInt("GSD_TOOL_LOOP_REPEATED_DEFAULT_CAP");
|
|
215
|
+
if (envDefaultCap !== undefined) next.perToolDefaultCap = envDefaultCap;
|
|
216
|
+
const envRepeatableCap = envPositiveInt("GSD_TOOL_LOOP_REPEATED_REPEATABLE_CAP");
|
|
217
|
+
if (envRepeatableCap !== undefined) next.perToolRepeatableCap = envRepeatableCap;
|
|
218
|
+
for (const tool of envToolList("GSD_TOOL_LOOP_EXEMPT_TOOLS")) next.perToolExempt.add(tool);
|
|
219
|
+
|
|
220
|
+
config = next;
|
|
221
|
+
}
|
|
51
222
|
|
|
52
223
|
let consecutiveCount = 0;
|
|
53
224
|
let lastSignature = "";
|
|
@@ -82,17 +253,20 @@ function hashToolCall(toolName: string, args: Record<string, unknown>): string {
|
|
|
82
253
|
* Returns `{ block: true, reason }` when the loop threshold is exceeded.
|
|
83
254
|
*
|
|
84
255
|
* Two independent guards run; whichever trips first blocks:
|
|
85
|
-
* 1. Identical-signature streak (
|
|
256
|
+
* 1. Identical-signature streak (config.maxConsecutiveIdentical, strict for
|
|
86
257
|
* ask_user_questions).
|
|
87
|
-
* 2. Per-tool-name cap (
|
|
258
|
+
* 2. Per-tool-name cap (config.perToolDefaultCap / config.perToolRepeatableCap),
|
|
88
259
|
* independent of args, reset after file-mutation progress — catches
|
|
89
260
|
* improvisation loops (#783).
|
|
261
|
+
*
|
|
262
|
+
* Both guards, their thresholds, and the per-tool exempt set are user-tunable
|
|
263
|
+
* via {@link configureToolCallLoopGuard} (#1198).
|
|
90
264
|
*/
|
|
91
265
|
export function checkToolCallLoop(
|
|
92
266
|
toolName: string,
|
|
93
267
|
args: Record<string, unknown>,
|
|
94
268
|
): { block: boolean; reason?: string; count?: number } {
|
|
95
|
-
if (!enabled) return { block: false, count: 0 };
|
|
269
|
+
if (!enabled || !config.guardEnabled) return { block: false, count: 0 };
|
|
96
270
|
|
|
97
271
|
const sig = hashToolCall(toolName, args);
|
|
98
272
|
|
|
@@ -107,14 +281,16 @@ export function checkToolCallLoop(
|
|
|
107
281
|
// ── Guard 1: identical-signature streak ──
|
|
108
282
|
const threshold = STRICT_LOOP_TOOLS.has(toolName)
|
|
109
283
|
? MAX_CONSECUTIVE_STRICT
|
|
110
|
-
:
|
|
284
|
+
: config.maxConsecutiveIdentical;
|
|
111
285
|
|
|
112
|
-
if (consecutiveCount > threshold) {
|
|
286
|
+
if (config.identicalEnabled && consecutiveCount > threshold) {
|
|
113
287
|
return {
|
|
114
288
|
block: true,
|
|
115
289
|
reason:
|
|
116
290
|
`Tool loop detected (identical args): ${toolName} called ${consecutiveCount} times ` +
|
|
117
|
-
`with identical arguments. Blocking to prevent infinite loop. ` +
|
|
291
|
+
`with identical arguments (max ${threshold}). Blocking to prevent infinite loop. ` +
|
|
292
|
+
`Raise tool_call_loop_guard.identical_args.max_consecutive_calls in .gsd/PREFERENCES.md ` +
|
|
293
|
+
`(or GSD_TOOL_LOOP_IDENTICAL_MAX) if this is expected. ` +
|
|
118
294
|
`Do not retry this tool or call other tools this turn — stop and respond to the user in text.`,
|
|
119
295
|
count: consecutiveCount,
|
|
120
296
|
};
|
|
@@ -139,15 +315,16 @@ export function checkToolCallLoop(
|
|
|
139
315
|
// Guard 1's identical-signature streak still catches a genuinely stuck
|
|
140
316
|
// browser loop.
|
|
141
317
|
if (
|
|
142
|
-
|
|
318
|
+
!config.repeatedEnabled ||
|
|
319
|
+
config.perToolExempt.has(toolName) ||
|
|
143
320
|
hasBrowserContractPrefix(canonicalToolName(toolName))
|
|
144
321
|
) {
|
|
145
322
|
return { block: false, count: consecutiveCount };
|
|
146
323
|
}
|
|
147
324
|
|
|
148
325
|
const perToolCap = INHERENTLY_REPEATABLE_TOOL_SET.has(toolName)
|
|
149
|
-
?
|
|
150
|
-
:
|
|
326
|
+
? config.perToolRepeatableCap
|
|
327
|
+
: config.perToolDefaultCap;
|
|
151
328
|
|
|
152
329
|
if (perToolCount > perToolCap) {
|
|
153
330
|
return {
|
|
@@ -156,6 +333,9 @@ export function checkToolCallLoop(
|
|
|
156
333
|
`Tool loop detected (repeated tool): ${toolName} called ${perToolCount} times ` +
|
|
157
334
|
`this turn (cap ${perToolCap}). Blocking to prevent infinite loop. ` +
|
|
158
335
|
`The tool may be unavailable or failing repeatedly. ` +
|
|
336
|
+
`Raise tool_call_loop_guard.repeated_tool.default_cap/repeatable_cap or add "${toolName}" ` +
|
|
337
|
+
`to tool_call_loop_guard.repeated_tool.exempt_tools in .gsd/PREFERENCES.md ` +
|
|
338
|
+
`(or GSD_TOOL_LOOP_REPEATED_* / GSD_TOOL_LOOP_EXEMPT_TOOLS) if this is expected. ` +
|
|
159
339
|
`Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.`,
|
|
160
340
|
count: perToolCount,
|
|
161
341
|
};
|
|
@@ -164,10 +344,21 @@ export function checkToolCallLoop(
|
|
|
164
344
|
return { block: false, count: consecutiveCount };
|
|
165
345
|
}
|
|
166
346
|
|
|
167
|
-
/**
|
|
168
|
-
|
|
347
|
+
/**
|
|
348
|
+
* Record successful state progress so Guard 2 can decay on the next count.
|
|
349
|
+
* File mutations (edit/write/…) and successful shell/exec calls (bash,
|
|
350
|
+
* bg_shell, gsd_uat_exec, …) both count as progress (#1092, #1206). The caller
|
|
351
|
+
* only invokes this for non-error results, so failing improvisation loops
|
|
352
|
+
* (#783) never decay and still trip the per-tool cap.
|
|
353
|
+
*/
|
|
354
|
+
export function recordToolCallLoopMutation(toolName: string, details?: unknown): void {
|
|
169
355
|
if (!enabled) return;
|
|
170
|
-
if (
|
|
356
|
+
if (STATE_MUTATING_TOOL_SET.has(toolName)) {
|
|
357
|
+
mutationEpoch++;
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (!STATE_PROGRESSING_EXEC_TOOL_SET.has(toolName)) return;
|
|
361
|
+
if (toolName === "bg_shell" && details !== undefined && !isSuccessfulBgShellLoopProgress(details)) return;
|
|
171
362
|
mutationEpoch++;
|
|
172
363
|
}
|
|
173
364
|
|