@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
|
@@ -32,6 +32,18 @@ interface ManagedConnection {
|
|
|
32
32
|
launch: GsdBrowserMcpLaunchConfig;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
type ConnectManagedGsdBrowser = (
|
|
36
|
+
launch: GsdBrowserMcpLaunchConfig,
|
|
37
|
+
signal?: AbortSignal,
|
|
38
|
+
) => Promise<ManagedConnection>;
|
|
39
|
+
|
|
40
|
+
type CloseManagedGsdBrowserConnection = (connection: ManagedConnection) => Promise<void>;
|
|
41
|
+
|
|
42
|
+
interface PendingManagedConnection {
|
|
43
|
+
promise: Promise<ManagedConnection>;
|
|
44
|
+
abortController: AbortController;
|
|
45
|
+
}
|
|
46
|
+
|
|
35
47
|
interface McpContentItem {
|
|
36
48
|
type: string;
|
|
37
49
|
text?: string;
|
|
@@ -69,8 +81,6 @@ interface ManagedBrowserToolSpec {
|
|
|
69
81
|
compatibility?: { producesImages?: boolean };
|
|
70
82
|
}
|
|
71
83
|
|
|
72
|
-
const connections = new Map<string, ManagedConnection>();
|
|
73
|
-
const pendingConnections = new Map<string, Promise<ManagedConnection>>();
|
|
74
84
|
const DEFAULT_MAX_LINES = 2_000;
|
|
75
85
|
const DEFAULT_MAX_BYTES = 50 * 1024;
|
|
76
86
|
const MCP_CALL_TIMEOUT_MS = 60_000;
|
|
@@ -368,6 +378,120 @@ function buildConnectionKey(launch: GsdBrowserMcpLaunchConfig): string {
|
|
|
368
378
|
});
|
|
369
379
|
}
|
|
370
380
|
|
|
381
|
+
function combineAbortSignals(
|
|
382
|
+
poolSignal: AbortSignal,
|
|
383
|
+
callerSignal?: AbortSignal,
|
|
384
|
+
): AbortSignal {
|
|
385
|
+
if (!callerSignal) return poolSignal;
|
|
386
|
+
if (typeof AbortSignal.any === "function") {
|
|
387
|
+
return AbortSignal.any([poolSignal, callerSignal]);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const controller = new AbortController();
|
|
391
|
+
const abort = (): void => {
|
|
392
|
+
if (!controller.signal.aborted) controller.abort();
|
|
393
|
+
};
|
|
394
|
+
if (poolSignal.aborted || callerSignal.aborted) {
|
|
395
|
+
abort();
|
|
396
|
+
} else {
|
|
397
|
+
poolSignal.addEventListener("abort", abort, { once: true });
|
|
398
|
+
callerSignal.addEventListener("abort", abort, { once: true });
|
|
399
|
+
}
|
|
400
|
+
return controller.signal;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export class ManagedGsdBrowserConnectionPool {
|
|
404
|
+
private readonly connections = new Map<string, ManagedConnection>();
|
|
405
|
+
private readonly pendingConnections = new Map<string, PendingManagedConnection>();
|
|
406
|
+
private readonly connect: ConnectManagedGsdBrowser;
|
|
407
|
+
private readonly closeConnection: CloseManagedGsdBrowserConnection;
|
|
408
|
+
private generation = 0;
|
|
409
|
+
private closing = false;
|
|
410
|
+
|
|
411
|
+
constructor(
|
|
412
|
+
connect: ConnectManagedGsdBrowser,
|
|
413
|
+
closeConnection: CloseManagedGsdBrowserConnection,
|
|
414
|
+
) {
|
|
415
|
+
this.connect = connect;
|
|
416
|
+
this.closeConnection = closeConnection;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
get activeCount(): number {
|
|
420
|
+
return this.connections.size;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
get pendingCount(): number {
|
|
424
|
+
return this.pendingConnections.size;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
getOrConnect(
|
|
428
|
+
launch: GsdBrowserMcpLaunchConfig,
|
|
429
|
+
signal?: AbortSignal,
|
|
430
|
+
): Promise<ManagedConnection> {
|
|
431
|
+
if (this.closing) {
|
|
432
|
+
return Promise.reject(new Error("gsd-browser connection pool is closing"));
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const key = buildConnectionKey(launch);
|
|
436
|
+
const existing = this.connections.get(key);
|
|
437
|
+
if (existing) return Promise.resolve(existing);
|
|
438
|
+
|
|
439
|
+
const pending = this.pendingConnections.get(key);
|
|
440
|
+
if (pending) return pending.promise;
|
|
441
|
+
|
|
442
|
+
const generation = this.generation;
|
|
443
|
+
const abortController = new AbortController();
|
|
444
|
+
const connectionSignal = combineAbortSignals(abortController.signal, signal);
|
|
445
|
+
const connectionPromise = this.connect(launch, connectionSignal)
|
|
446
|
+
.then(async (connection) => {
|
|
447
|
+
if (this.closing || this.generation !== generation) {
|
|
448
|
+
await this.closeConnection(connection);
|
|
449
|
+
throw new Error("gsd-browser connection closed during startup");
|
|
450
|
+
}
|
|
451
|
+
this.connections.set(key, connection);
|
|
452
|
+
return connection;
|
|
453
|
+
})
|
|
454
|
+
.finally(() => {
|
|
455
|
+
if (this.pendingConnections.get(key)?.promise === connectionPromise) {
|
|
456
|
+
this.pendingConnections.delete(key);
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
this.pendingConnections.set(key, { promise: connectionPromise, abortController });
|
|
461
|
+
return connectionPromise;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
async closeAll(): Promise<void> {
|
|
465
|
+
this.closing = true;
|
|
466
|
+
this.generation += 1;
|
|
467
|
+
|
|
468
|
+
const activeConnections = Array.from(this.connections.values());
|
|
469
|
+
const pendingConnections = Array.from(this.pendingConnections.values());
|
|
470
|
+
this.connections.clear();
|
|
471
|
+
this.pendingConnections.clear();
|
|
472
|
+
for (const pending of pendingConnections) {
|
|
473
|
+
pending.abortController.abort();
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const closingActive = activeConnections.map((connection) => this.closeConnection(connection));
|
|
477
|
+
const closingPending = pendingConnections.map(async (pending) => {
|
|
478
|
+
try {
|
|
479
|
+
const connection = await pending.promise;
|
|
480
|
+
await this.closeConnection(connection);
|
|
481
|
+
} catch {
|
|
482
|
+
// Failed or invalidated connection attempts have already cleaned up.
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
try {
|
|
487
|
+
await Promise.allSettled([...closingActive, ...closingPending]);
|
|
488
|
+
} finally {
|
|
489
|
+
this.closing = false;
|
|
490
|
+
this.generation += 1;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
371
495
|
async function connectManagedGsdBrowser(
|
|
372
496
|
launch: GsdBrowserMcpLaunchConfig,
|
|
373
497
|
signal?: AbortSignal,
|
|
@@ -399,6 +523,24 @@ async function connectManagedGsdBrowser(
|
|
|
399
523
|
}
|
|
400
524
|
}
|
|
401
525
|
|
|
526
|
+
async function closeManagedGsdBrowserConnection(connection: ManagedConnection): Promise<void> {
|
|
527
|
+
try {
|
|
528
|
+
await connection.client.close();
|
|
529
|
+
} catch {
|
|
530
|
+
// Best-effort cleanup.
|
|
531
|
+
}
|
|
532
|
+
try {
|
|
533
|
+
await connection.transport.close();
|
|
534
|
+
} catch {
|
|
535
|
+
// Best-effort cleanup.
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const connectionPool = new ManagedGsdBrowserConnectionPool(
|
|
540
|
+
connectManagedGsdBrowser,
|
|
541
|
+
closeManagedGsdBrowserConnection,
|
|
542
|
+
);
|
|
543
|
+
|
|
402
544
|
async function getOrConnectManagedGsdBrowser(
|
|
403
545
|
ctx?: ExtensionContext,
|
|
404
546
|
signal?: AbortSignal,
|
|
@@ -406,22 +548,7 @@ async function getOrConnectManagedGsdBrowser(
|
|
|
406
548
|
const launch = resolveGsdBrowserMcpLaunchConfig(resolveProjectRoot(ctx), process.env, {
|
|
407
549
|
sessionSuffix: resolveManagedSessionSuffix(ctx),
|
|
408
550
|
});
|
|
409
|
-
|
|
410
|
-
const existing = connections.get(key);
|
|
411
|
-
if (existing) return existing;
|
|
412
|
-
|
|
413
|
-
const pending = pendingConnections.get(key);
|
|
414
|
-
if (pending) return pending;
|
|
415
|
-
|
|
416
|
-
const connectionPromise = connectManagedGsdBrowser(launch, signal);
|
|
417
|
-
pendingConnections.set(key, connectionPromise);
|
|
418
|
-
try {
|
|
419
|
-
const connection = await connectionPromise;
|
|
420
|
-
connections.set(key, connection);
|
|
421
|
-
return connection;
|
|
422
|
-
} finally {
|
|
423
|
-
pendingConnections.delete(key);
|
|
424
|
-
}
|
|
551
|
+
return connectionPool.getOrConnect(launch, signal);
|
|
425
552
|
}
|
|
426
553
|
|
|
427
554
|
function isUnknownMcpToolError(error: unknown): boolean {
|
|
@@ -743,21 +870,7 @@ export function registerManagedGsdBrowserTools(pi: ExtensionAPI): void {
|
|
|
743
870
|
}
|
|
744
871
|
|
|
745
872
|
export async function closeManagedGsdBrowser(): Promise<void> {
|
|
746
|
-
|
|
747
|
-
try {
|
|
748
|
-
await connection.client.close();
|
|
749
|
-
} catch {
|
|
750
|
-
// Best-effort cleanup.
|
|
751
|
-
}
|
|
752
|
-
try {
|
|
753
|
-
await connection.transport.close();
|
|
754
|
-
} catch {
|
|
755
|
-
// Best-effort cleanup.
|
|
756
|
-
}
|
|
757
|
-
connections.delete(key);
|
|
758
|
-
});
|
|
759
|
-
await Promise.allSettled(closing);
|
|
760
|
-
pendingConnections.clear();
|
|
873
|
+
await connectionPool.closeAll();
|
|
761
874
|
}
|
|
762
875
|
|
|
763
876
|
export async function _resetManagedGsdBrowserForTest(): Promise<void> {
|
|
@@ -9,6 +9,7 @@ import { dirname, join } from "node:path";
|
|
|
9
9
|
const {
|
|
10
10
|
resolveBundledGsdBrowserCliPath,
|
|
11
11
|
resolveGsdBrowserDaemonStartInvocation,
|
|
12
|
+
resolveGsdBrowserDaemonStopInvocation,
|
|
12
13
|
resolveGsdBrowserMcpLaunchConfig,
|
|
13
14
|
} = await import("../../shared/gsd-browser-cli.ts");
|
|
14
15
|
|
|
@@ -55,6 +56,31 @@ describe("resolveGsdBrowserMcpLaunchConfig identity flags", () => {
|
|
|
55
56
|
assert.equal(args[1], "mcp");
|
|
56
57
|
});
|
|
57
58
|
|
|
59
|
+
it("appends GSD_BROWSER_MCP_EXTRA_ARGS after the identity flags (string form)", () => {
|
|
60
|
+
const { args } = resolveGsdBrowserMcpLaunchConfig("/tmp/example-project", {
|
|
61
|
+
GSD_BROWSER_MCP_EXTRA_ARGS: "--stealth --browser-path /usr/bin/chromium",
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Managed flags stay intact and the extra flags trail them.
|
|
65
|
+
assert.ok(args.indexOf("--identity-project") >= 0);
|
|
66
|
+
assert.deepEqual(args.slice(-3), ["--stealth", "--browser-path", "/usr/bin/chromium"]);
|
|
67
|
+
assert.ok(args.indexOf("--stealth") > args.indexOf("--identity-project"));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("accepts GSD_BROWSER_MCP_EXTRA_ARGS as a JSON array", () => {
|
|
71
|
+
const { args } = resolveGsdBrowserMcpLaunchConfig("/tmp/example-project", {
|
|
72
|
+
GSD_BROWSER_MCP_EXTRA_ARGS: '["--stealth"]',
|
|
73
|
+
});
|
|
74
|
+
assert.equal(args[args.length - 1], "--stealth");
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("forwards GSD_BROWSER_MCP_EXTRA_ARGS to the daemon-start invocation", () => {
|
|
78
|
+
const env = { GSD_BROWSER_MCP_EXTRA_ARGS: "--stealth" };
|
|
79
|
+
const daemon = resolveGsdBrowserDaemonStartInvocation("/tmp/example-project", env);
|
|
80
|
+
assert.equal(daemon.args[daemon.args.length - 1], "--stealth");
|
|
81
|
+
assert.ok(daemon.args.indexOf("daemon") >= 0 && daemon.args.indexOf("start") >= 0);
|
|
82
|
+
});
|
|
83
|
+
|
|
58
84
|
it("uses a path-safe identity-project identifier", () => {
|
|
59
85
|
const { args } = resolveGsdBrowserMcpLaunchConfig("/tmp/example/project", {});
|
|
60
86
|
const projectId = args[args.indexOf("--identity-project") + 1];
|
|
@@ -154,3 +180,21 @@ describe("resolveGsdBrowserDaemonStartInvocation", () => {
|
|
|
154
180
|
);
|
|
155
181
|
});
|
|
156
182
|
});
|
|
183
|
+
|
|
184
|
+
describe("resolveGsdBrowserDaemonStopInvocation", () => {
|
|
185
|
+
it("mirrors MCP session and identity flags with daemon stop", () => {
|
|
186
|
+
const launch = resolveGsdBrowserMcpLaunchConfig("/tmp/example-project", {});
|
|
187
|
+
const daemon = resolveGsdBrowserDaemonStopInvocation("/tmp/example-project", {});
|
|
188
|
+
|
|
189
|
+
assert.equal(daemon.command, launch.command);
|
|
190
|
+
assert.equal(daemon.cwd, launch.cwd);
|
|
191
|
+
assert.deepEqual(
|
|
192
|
+
daemon.args.slice(daemon.args.indexOf("--session")),
|
|
193
|
+
launch.args.slice(launch.args.indexOf("--session")),
|
|
194
|
+
);
|
|
195
|
+
assert.deepEqual(
|
|
196
|
+
daemon.args.slice(0, daemon.args.indexOf("--session")),
|
|
197
|
+
[...launch.args.slice(0, launch.args.indexOf("mcp")), "daemon", "stop"],
|
|
198
|
+
);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -4,6 +4,7 @@ import assert from "node:assert/strict";
|
|
|
4
4
|
const {
|
|
5
5
|
MANAGED_BROWSER_TOOL_SPECS,
|
|
6
6
|
MANAGED_GSD_BROWSER_TOOL_NAMES,
|
|
7
|
+
ManagedGsdBrowserConnectionPool,
|
|
7
8
|
findMissingContractCoverage,
|
|
8
9
|
normalizeManagedArgs,
|
|
9
10
|
registerManagedGsdBrowserTools,
|
|
@@ -29,6 +30,17 @@ const GSD_BROWSER_SERVED_TOOLS = [
|
|
|
29
30
|
"browser_act",
|
|
30
31
|
];
|
|
31
32
|
|
|
33
|
+
function makeLaunchConfig() {
|
|
34
|
+
return {
|
|
35
|
+
command: "gsd-browser",
|
|
36
|
+
args: ["mcp"],
|
|
37
|
+
cwd: "/tmp/example-project",
|
|
38
|
+
projectRoot: "/tmp/example-project",
|
|
39
|
+
serverName: "gsd-browser",
|
|
40
|
+
sessionName: "test-session",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
32
44
|
describe("registerManagedGsdBrowserTools", () => {
|
|
33
45
|
it("registers the curated Pi browser contract", () => {
|
|
34
46
|
const tools = [];
|
|
@@ -72,6 +84,87 @@ describe("findMissingContractCoverage", () => {
|
|
|
72
84
|
});
|
|
73
85
|
});
|
|
74
86
|
|
|
87
|
+
describe("ManagedGsdBrowserConnectionPool", () => {
|
|
88
|
+
it("closes a pending connection that resolves after the pool is closed", async () => {
|
|
89
|
+
const closed = [];
|
|
90
|
+
let resolveConnect;
|
|
91
|
+
const pool = new ManagedGsdBrowserConnectionPool(async () => {
|
|
92
|
+
return new Promise((resolve) => {
|
|
93
|
+
resolveConnect = resolve;
|
|
94
|
+
});
|
|
95
|
+
}, async (connection) => {
|
|
96
|
+
closed.push(connection.id);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const launch = makeLaunchConfig();
|
|
100
|
+
|
|
101
|
+
const pending = pool.getOrConnect(launch);
|
|
102
|
+
const closedPool = pool.closeAll();
|
|
103
|
+
resolveConnect({ id: "late-connection" });
|
|
104
|
+
|
|
105
|
+
await assert.rejects(
|
|
106
|
+
pending,
|
|
107
|
+
/closed during startup/,
|
|
108
|
+
"pending callers must not receive a reusable connection after close",
|
|
109
|
+
);
|
|
110
|
+
await closedPool;
|
|
111
|
+
|
|
112
|
+
assert.deepEqual(closed, ["late-connection"]);
|
|
113
|
+
assert.equal(pool.activeCount, 0);
|
|
114
|
+
assert.equal(pool.pendingCount, 0);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("aborts pending connection attempts when the pool is closed", async () => {
|
|
118
|
+
let receivedSignal;
|
|
119
|
+
const pool = new ManagedGsdBrowserConnectionPool(async (_launch, signal) => {
|
|
120
|
+
receivedSignal = signal;
|
|
121
|
+
return new Promise((_resolve, reject) => {
|
|
122
|
+
signal.addEventListener("abort", () => reject(new Error("connect aborted")), { once: true });
|
|
123
|
+
});
|
|
124
|
+
}, async () => {});
|
|
125
|
+
|
|
126
|
+
const pending = pool.getOrConnect(makeLaunchConfig());
|
|
127
|
+
const closedPool = pool.closeAll();
|
|
128
|
+
|
|
129
|
+
await assert.rejects(pending, /connect aborted/);
|
|
130
|
+
await closedPool;
|
|
131
|
+
|
|
132
|
+
assert.equal(receivedSignal?.aborted, true);
|
|
133
|
+
assert.equal(pool.activeCount, 0);
|
|
134
|
+
assert.equal(pool.pendingCount, 0);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("rejects new connection attempts started while the pool is closing", async () => {
|
|
138
|
+
let resolveConnect;
|
|
139
|
+
let connectCount = 0;
|
|
140
|
+
const pool = new ManagedGsdBrowserConnectionPool(async () => {
|
|
141
|
+
connectCount += 1;
|
|
142
|
+
return new Promise((resolve) => {
|
|
143
|
+
resolveConnect = resolve;
|
|
144
|
+
});
|
|
145
|
+
}, async () => {});
|
|
146
|
+
|
|
147
|
+
const pending = pool.getOrConnect(makeLaunchConfig());
|
|
148
|
+
const closedPool = pool.closeAll();
|
|
149
|
+
|
|
150
|
+
// A caller that arrives during the in-flight closeAll must not open a new
|
|
151
|
+
// connection that could survive shutdown.
|
|
152
|
+
await assert.rejects(
|
|
153
|
+
pool.getOrConnect(makeLaunchConfig()),
|
|
154
|
+
/closing/,
|
|
155
|
+
"getOrConnect must reject while the pool is closing",
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
resolveConnect({ id: "pending-connection" });
|
|
159
|
+
await assert.rejects(pending, /closed during startup/);
|
|
160
|
+
await closedPool;
|
|
161
|
+
|
|
162
|
+
assert.equal(connectCount, 1, "no second connection is started during shutdown");
|
|
163
|
+
assert.equal(pool.activeCount, 0);
|
|
164
|
+
assert.equal(pool.pendingCount, 0);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
75
168
|
describe("contract tool translations", () => {
|
|
76
169
|
it("translates browser_click into a single-step batch call", () => {
|
|
77
170
|
const calls = MANAGED_BROWSER_TOOL_SPECS.browser_click.translate.build({ selector: "#save" });
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
import { importExtensionModule, type ExtensionAPI, type ExtensionContext } from "@gsd/pi-coding-agent";
|
|
5
5
|
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
6
8
|
import { join, basename } from "node:path";
|
|
7
|
-
import { existsSync, cpSync } from "node:fs";
|
|
9
|
+
import { existsSync, cpSync, readFileSync } from "node:fs";
|
|
8
10
|
import type { AutoSession } from "./session.js";
|
|
9
11
|
import type { LoopDeps } from "./loop-deps.js";
|
|
10
12
|
import type { GSDState } from "../types.js";
|
|
@@ -16,7 +18,7 @@ import { getIsolationMode } from "../preferences.js";
|
|
|
16
18
|
import { isDbAvailable, getMilestone } from "../gsd-db.js";
|
|
17
19
|
import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
|
|
18
20
|
import { isClosedStatus } from "../status-guards.js";
|
|
19
|
-
import { gsdRoot } from "../paths.js";
|
|
21
|
+
import { gsdRoot, PLANNING_ARTIFACT_SUFFIXES } from "../paths.js";
|
|
20
22
|
import { atomicWriteSync } from "../atomic-write.js";
|
|
21
23
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
22
24
|
import { debugLog } from "../debug-logger.js";
|
|
@@ -98,7 +100,15 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
98
100
|
): Promise<{ action: "break"; reason: string } | null> {
|
|
99
101
|
const { ctx, pi, s, deps } = ic;
|
|
100
102
|
|
|
101
|
-
|
|
103
|
+
// Resolve the project root once, before the merge can flip session path
|
|
104
|
+
// pointers (worktree teardown mutates s.basePath / s.scope). The guarded
|
|
105
|
+
// merge's preflight/postflight stash restore, the pre-merge ignored-markdown
|
|
106
|
+
// snapshot, the dirty-projection check, and the rebuild must all target this
|
|
107
|
+
// same tree; otherwise `.gsd` markdown restored on one tree can be silently
|
|
108
|
+
// overwritten by a rebuild on another. canonicalProjectRoot is the
|
|
109
|
+
// authoritative `.gsd`/DB writer path (see AutoSession.canonicalProjectRoot).
|
|
110
|
+
const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
111
|
+
const ignoredProjectionSnapshot = snapshotIgnoredGsdMarkdownProjections(projectRoot);
|
|
102
112
|
const mergeResult = deps.lifecycle.exitMilestone(
|
|
103
113
|
milestoneId,
|
|
104
114
|
{
|
|
@@ -113,12 +123,12 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
113
123
|
);
|
|
114
124
|
|
|
115
125
|
if (mergeResult.ok) {
|
|
116
|
-
await markMilestoneMergedAndRebuild(s);
|
|
126
|
+
await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
|
|
117
127
|
return null;
|
|
118
128
|
}
|
|
119
129
|
|
|
120
130
|
if (mergeResult.reason === "postflight-stash-restore-failed") {
|
|
121
|
-
await markMilestoneMergedAndRebuild(s);
|
|
131
|
+
await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
|
|
122
132
|
}
|
|
123
133
|
|
|
124
134
|
if (mergeResult.reason === "preflight-dirty-overlap" || mergeResult.reason === "preflight-unmerged-conflicts") {
|
|
@@ -180,10 +190,23 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
180
190
|
return null;
|
|
181
191
|
}
|
|
182
192
|
|
|
183
|
-
|
|
193
|
+
type GsdMarkdownSnapshot = Map<string, string>;
|
|
194
|
+
|
|
195
|
+
async function markMilestoneMergedAndRebuild(
|
|
196
|
+
s: AutoSession,
|
|
197
|
+
rebuildBasePath: string,
|
|
198
|
+
ignoredProjectionSnapshot: GsdMarkdownSnapshot | null,
|
|
199
|
+
): Promise<void> {
|
|
184
200
|
s.milestoneMergedInPhases = true;
|
|
201
|
+
if (hasDirtyGsdMarkdownProjections(rebuildBasePath, ignoredProjectionSnapshot)) {
|
|
202
|
+
logWarning(
|
|
203
|
+
"engine",
|
|
204
|
+
"skipping markdown projection rebuild after milestone merge because restored .gsd edits are dirty",
|
|
205
|
+
);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
185
209
|
try {
|
|
186
|
-
const rebuildBasePath = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
187
210
|
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
|
|
188
211
|
await rebuildMarkdownProjectionsFromDb(rebuildBasePath);
|
|
189
212
|
} catch (err) {
|
|
@@ -194,6 +217,90 @@ async function markMilestoneMergedAndRebuild(s: AutoSession): Promise<void> {
|
|
|
194
217
|
}
|
|
195
218
|
}
|
|
196
219
|
|
|
220
|
+
function hasDirtyGsdMarkdownProjections(
|
|
221
|
+
basePath: string,
|
|
222
|
+
ignoredProjectionSnapshot: GsdMarkdownSnapshot | null,
|
|
223
|
+
): boolean {
|
|
224
|
+
try {
|
|
225
|
+
const output = execFileSync(
|
|
226
|
+
"git",
|
|
227
|
+
["status", "--porcelain", "-z", "--untracked-files=all", "--", ".gsd"],
|
|
228
|
+
{ cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] },
|
|
229
|
+
);
|
|
230
|
+
const entries = output.split("\0").filter(Boolean);
|
|
231
|
+
for (let i = 0; i < entries.length; i++) {
|
|
232
|
+
const entry = entries[i];
|
|
233
|
+
if (entry.length <= 3) continue;
|
|
234
|
+
const status = entry.slice(0, 2);
|
|
235
|
+
const path = entry.slice(3);
|
|
236
|
+
if (isGeneratedGsdMarkdownProjection(path)) return true;
|
|
237
|
+
if ((status === "R " || status === "C ") && i + 1 < entries.length) {
|
|
238
|
+
const dest = entries[++i];
|
|
239
|
+
if (isGeneratedGsdMarkdownProjection(dest)) return true;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
} catch (err) {
|
|
243
|
+
void err;
|
|
244
|
+
// Fall through to ignored-file snapshot comparison below.
|
|
245
|
+
}
|
|
246
|
+
return ignoredGsdMarkdownProjectionSnapshotChanged(basePath, ignoredProjectionSnapshot);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function isGeneratedGsdMarkdownProjection(path: string): boolean {
|
|
250
|
+
const normalized = path.replace(/\\/g, "/");
|
|
251
|
+
if (normalized === ".gsd/DECISIONS.md") return true;
|
|
252
|
+
if (!normalized.startsWith(".gsd/milestones/") && !normalized.startsWith(".gsd/phases/")) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
return isGeneratedPlanningArtifactFileName(basename(normalized));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function isGeneratedPlanningArtifactFileName(fileName: string): boolean {
|
|
259
|
+
if (!fileName.endsWith(".md")) return false;
|
|
260
|
+
const stem = fileName.slice(0, -".md".length).toUpperCase();
|
|
261
|
+
for (const suffix of PLANNING_ARTIFACT_SUFFIXES) {
|
|
262
|
+
if (!stem.endsWith(`-${suffix}`)) continue;
|
|
263
|
+
const idPrefix = stem.slice(0, -suffix.length - 1);
|
|
264
|
+
return /^(?:[MST]\d+|\d{2,})(?:-[A-Z0-9]+)*$/.test(idPrefix);
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function snapshotIgnoredGsdMarkdownProjections(basePath: string): GsdMarkdownSnapshot | null {
|
|
270
|
+
try {
|
|
271
|
+
const output = execFileSync(
|
|
272
|
+
"git",
|
|
273
|
+
["ls-files", "--others", "--ignored", "--exclude-standard", "-z", "--", ".gsd"],
|
|
274
|
+
{ cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] },
|
|
275
|
+
);
|
|
276
|
+
const snapshot: GsdMarkdownSnapshot = new Map();
|
|
277
|
+
for (const path of output.split("\0")) {
|
|
278
|
+
if (!isGeneratedGsdMarkdownProjection(path)) continue;
|
|
279
|
+
snapshot.set(path, hashFile(join(basePath, path)));
|
|
280
|
+
}
|
|
281
|
+
return snapshot;
|
|
282
|
+
} catch {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function hashFile(path: string): string {
|
|
288
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function ignoredGsdMarkdownProjectionSnapshotChanged(
|
|
292
|
+
basePath: string,
|
|
293
|
+
before: GsdMarkdownSnapshot | null,
|
|
294
|
+
): boolean {
|
|
295
|
+
if (!before) return true;
|
|
296
|
+
const after = snapshotIgnoredGsdMarkdownProjections(basePath);
|
|
297
|
+
if (!after || after.size !== before.size) return true;
|
|
298
|
+
for (const [path, hash] of before) {
|
|
299
|
+
if (after.get(path) !== hash) return true;
|
|
300
|
+
}
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
|
|
197
304
|
export async function _runMilestoneMergeOnceWithStashRestore(
|
|
198
305
|
ic: IterationContext,
|
|
199
306
|
milestoneId: string,
|
|
@@ -34,7 +34,8 @@ import {
|
|
|
34
34
|
preDispatchHealthGate,
|
|
35
35
|
recordHealthSnapshot,
|
|
36
36
|
} from "../doctor-proactive.js";
|
|
37
|
-
import {
|
|
37
|
+
import { autoWorktreeBranch } from "../auto-worktree-branch-lifecycle.js";
|
|
38
|
+
import { checkResourcesStale } from "../auto-worktree-resource-version.js";
|
|
38
39
|
import { getSessionLockStatus } from "../session-lock.js";
|
|
39
40
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
40
41
|
import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
|
|
@@ -49,7 +50,7 @@ import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
|
|
|
49
50
|
import { GitServiceImpl } from "../git-service.js";
|
|
50
51
|
import { WorktreeStateProjection } from "../worktree-state-projection.js";
|
|
51
52
|
import { WorktreeLifecycle } from "../worktree-lifecycle.js";
|
|
52
|
-
import {
|
|
53
|
+
import { createDefaultMilestoneMergeTransaction } from "../milestone-merge-transaction.js";
|
|
53
54
|
import { createWorkspace, scopeMilestone } from "../workspace.js";
|
|
54
55
|
import { supportsStructuredQuestions } from "../workflow-mcp.js";
|
|
55
56
|
import { getRegisteredToolSnapshot, getToolBaselineSnapshot } from "../auto-model-selection.js";
|
|
@@ -731,7 +732,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
731
732
|
return new GitServiceImpl(basePath, gitConfig);
|
|
732
733
|
},
|
|
733
734
|
worktreeProjection: new WorktreeStateProjection(),
|
|
734
|
-
mergeMilestone:
|
|
735
|
+
mergeMilestone: createDefaultMilestoneMergeTransaction(),
|
|
735
736
|
});
|
|
736
737
|
}
|
|
737
738
|
|
|
@@ -1195,17 +1196,23 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1195
1196
|
return skipped;
|
|
1196
1197
|
}
|
|
1197
1198
|
|
|
1198
|
-
// Stuck-loop detection:
|
|
1199
|
-
//
|
|
1200
|
-
//
|
|
1201
|
-
//
|
|
1202
|
-
//
|
|
1203
|
-
//
|
|
1204
|
-
//
|
|
1205
|
-
//
|
|
1206
|
-
//
|
|
1207
|
-
|
|
1208
|
-
|
|
1199
|
+
// Stuck-loop detection: consult the Dispatch History module's full
|
|
1200
|
+
// detect-stuck rule set once the window is *full* — not only when a
|
|
1201
|
+
// single key saturates it. Gating on a single key's saturation count
|
|
1202
|
+
// (matchingCount >= STUCK_WINDOW_SIZE) let two-unit oscillations slip
|
|
1203
|
+
// through forever: an execute-task ↔ complete-slice loop (a slice gate
|
|
1204
|
+
// that keeps reopening the same task, #1225) fills the window with two
|
|
1205
|
+
// alternating keys, so neither key ever reaches the saturation count and
|
|
1206
|
+
// detect-stuck's oscillation/repeat rules were never even invoked. Firing
|
|
1207
|
+
// on window saturation instead covers both shapes. Consecutive same-key
|
|
1208
|
+
// re-advances (the benign pause/resume churn the old count gate guarded
|
|
1209
|
+
// against) are already short-circuited above by the idempotency skip, and
|
|
1210
|
+
// legitimate retry backoff is still suppressed inside detect-stuck via the
|
|
1211
|
+
// dispatch ledger — a saturated window with no verdict means we are inside
|
|
1212
|
+
// the unit's retry-backoff budget, so let the retry proceed.
|
|
1213
|
+
const windowSaturated =
|
|
1214
|
+
this.dispatchHistory.getRecentWindow().length >= STUCK_WINDOW_SIZE;
|
|
1215
|
+
const stuckVerdict = windowSaturated ? this.dispatchHistory.detectStuck() : null;
|
|
1209
1216
|
if (stuckVerdict) {
|
|
1210
1217
|
// #442: before declaring a stuck loop, verify the unit didn't actually
|
|
1211
1218
|
// complete on disk (stale DB) and recover if so — legacy graduated
|
|
@@ -440,7 +440,8 @@ export async function runPreDispatch(
|
|
|
440
440
|
if (stop) return stop;
|
|
441
441
|
}
|
|
442
442
|
|
|
443
|
-
// PR creation (auto_pr) is handled
|
|
443
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
444
|
+
// the milestone merge transaction (#2302).
|
|
444
445
|
|
|
445
446
|
deps.invalidateAllCaches();
|
|
446
447
|
|
|
@@ -551,7 +552,8 @@ export async function runPreDispatch(
|
|
|
551
552
|
// #2909 / #5538-followup: preflight stash + always-on postflight pop.
|
|
552
553
|
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
553
554
|
if (stop) return stop;
|
|
554
|
-
// PR creation (auto_pr) is handled
|
|
555
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
556
|
+
// the milestone merge transaction (#2302).
|
|
555
557
|
}
|
|
556
558
|
const unmappedActive = countUnmappedActiveRequirements();
|
|
557
559
|
const completionStopReason = formatCompletePhaseNextAction(unmappedActive);
|
|
@@ -654,7 +656,8 @@ export async function runPreDispatch(
|
|
|
654
656
|
// #2909 / #5538-followup: preflight stash + always-on postflight pop.
|
|
655
657
|
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
656
658
|
if (stop) return stop;
|
|
657
|
-
// PR creation (auto_pr) is handled
|
|
659
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
660
|
+
// the milestone merge transaction (#2302).
|
|
658
661
|
}
|
|
659
662
|
deps.sendDesktopNotification(
|
|
660
663
|
"GSD",
|