@opengsd/gsd-pi 1.5.0 → 1.6.0
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 +4 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +29 -117
- package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
- package/dist/resources/extensions/gsd/auto-start.js +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 +106 -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/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/rule-registry.js +106 -10
- 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 +13 -5
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
- package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
- package/dist/resources/extensions/gsd/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 +29 -0
- package/dist/resources/extensions/shared/interview-ui.js +62 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +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/orchestrator-agent.d.ts +21 -0
- package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
- package/packages/daemon/dist/orchestrator-agent.js +113 -0
- package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
- package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
- package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
- package/packages/daemon/dist/orchestrator-tools.js +137 -0
- package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
- package/packages/daemon/dist/orchestrator.d.ts +4 -56
- package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
- package/packages/daemon/dist/orchestrator.js +13 -303
- package/packages/daemon/dist/orchestrator.js.map +1 -1
- package/packages/daemon/dist/orchestrator.test.js +11 -1
- package/packages/daemon/dist/orchestrator.test.js.map +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/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/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 +25 -0
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
- package/src/resources/extensions/gsd/activity-log.ts +1 -1
- package/src/resources/extensions/gsd/auto/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 +4 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +53 -113
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
- package/src/resources/extensions/gsd/auto-start.ts +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 +114 -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/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/rule-registry.ts +111 -9
- 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/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-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/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 +13 -5
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
- package/src/resources/extensions/gsd/types.ts +23 -4
- package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
- package/src/resources/extensions/gsd/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 +29 -0
- package/src/resources/extensions/shared/interview-ui.ts +58 -11
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
- /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → 6xYMOzxVhsQgryneJ5KRc}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → 6xYMOzxVhsQgryneJ5KRc}/_ssgManifest.js +0 -0
|
@@ -63,18 +63,20 @@ import {
|
|
|
63
63
|
detectWorktreeName,
|
|
64
64
|
setActiveMilestoneId,
|
|
65
65
|
} from "./worktree.js";
|
|
66
|
-
import {
|
|
66
|
+
import { isInAutoWorktree } from "./auto-worktree-entry.js";
|
|
67
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
67
68
|
import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
|
|
68
|
-
import {
|
|
69
|
+
import { cleanStaleRuntimeUnits } from "./auto-worktree-runtime-cleanup.js";
|
|
70
|
+
import { readResourceVersion } from "./auto-worktree-resource-version.js";
|
|
69
71
|
import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
|
|
70
72
|
import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
|
|
71
73
|
import { queryJournal } from "./journal.js";
|
|
72
74
|
import { initMetrics } from "./metrics.js";
|
|
73
75
|
import { initRoutingHistory } from "./routing-history.js";
|
|
74
|
-
import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
|
|
76
|
+
import { restoreHookState, resetHookState, reconcileRestoredHookDispatch } from "./post-unit-hooks.js";
|
|
75
77
|
import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
|
|
76
78
|
import { snapshotSkills } from "./skill-discovery.js";
|
|
77
|
-
import { isDbAvailable, getMilestone, getAllMilestones, insertMilestone, updateMilestoneStatus } from "./gsd-db.js";
|
|
79
|
+
import { isDbAvailable, probeDbWritable, getMilestone, getAllMilestones, insertMilestone, updateMilestoneStatus } from "./gsd-db.js";
|
|
78
80
|
import {
|
|
79
81
|
getWorkflowDatabaseStatus,
|
|
80
82
|
openExistingWorkflowDatabase,
|
|
@@ -203,35 +205,43 @@ export function reconcileProjectMilestonesFromDisk(basePath: string): number {
|
|
|
203
205
|
export function reconcileMergedMilestonesFromJournal(basePath: string): number {
|
|
204
206
|
if (!isDbAvailable()) return 0;
|
|
205
207
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
let closed = 0;
|
|
219
|
-
for (const [milestoneId, completedAt] of mergedAtByMilestone) {
|
|
220
|
-
const existing = getMilestone(milestoneId);
|
|
221
|
-
if (!existing) {
|
|
222
|
-
insertMilestone({ id: milestoneId, title: milestoneId, status: "complete" });
|
|
223
|
-
updateMilestoneStatus(milestoneId, "complete", completedAt);
|
|
224
|
-
closed++;
|
|
225
|
-
continue;
|
|
208
|
+
try {
|
|
209
|
+
const mergedAtByMilestone = new Map<string, string>();
|
|
210
|
+
for (const entry of queryJournal(basePath, { eventType: "worktree-merged" })) {
|
|
211
|
+
const data = entry.data ?? {};
|
|
212
|
+
const milestoneId = typeof data.milestoneId === "string" ? data.milestoneId : null;
|
|
213
|
+
if (!milestoneId) continue;
|
|
214
|
+
if (data.conflict === true) continue;
|
|
215
|
+
|
|
216
|
+
const endedAt = typeof data.endedAt === "string" ? data.endedAt : entry.ts;
|
|
217
|
+
const previous = mergedAtByMilestone.get(milestoneId);
|
|
218
|
+
if (!previous || endedAt > previous) mergedAtByMilestone.set(milestoneId, endedAt);
|
|
226
219
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
220
|
+
|
|
221
|
+
let closed = 0;
|
|
222
|
+
for (const [milestoneId, completedAt] of mergedAtByMilestone) {
|
|
223
|
+
const existing = getMilestone(milestoneId);
|
|
224
|
+
if (!existing) {
|
|
225
|
+
insertMilestone({ id: milestoneId, title: milestoneId, status: "complete" });
|
|
226
|
+
updateMilestoneStatus(milestoneId, "complete", completedAt);
|
|
227
|
+
closed++;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (!isClosedStatus(existing.status)) {
|
|
231
|
+
updateMilestoneStatus(milestoneId, "complete", completedAt);
|
|
232
|
+
closed++;
|
|
233
|
+
}
|
|
230
234
|
}
|
|
231
|
-
}
|
|
232
235
|
|
|
233
|
-
|
|
234
|
-
|
|
236
|
+
if (closed > 0) invalidateAllCaches();
|
|
237
|
+
return closed;
|
|
238
|
+
} catch (err) {
|
|
239
|
+
logWarning(
|
|
240
|
+
"bootstrap",
|
|
241
|
+
`merged-milestone journal reconciliation failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
242
|
+
);
|
|
243
|
+
return 0;
|
|
244
|
+
}
|
|
235
245
|
}
|
|
236
246
|
|
|
237
247
|
/**
|
|
@@ -1622,6 +1632,10 @@ export async function bootstrapAutoSession(
|
|
|
1622
1632
|
s.unitLifetimeDispatches.clear();
|
|
1623
1633
|
resetHookState();
|
|
1624
1634
|
restoreHookState(base);
|
|
1635
|
+
// A restored activeHook has no live dispatch (the sidecar queue is not
|
|
1636
|
+
// persisted); re-enqueue it so the hook runs instead of blocking the next
|
|
1637
|
+
// unrelated unit's close-out (#1246).
|
|
1638
|
+
reconcileRestoredHookDispatch(base, s.sidecarQueue);
|
|
1625
1639
|
resetProactiveHealing();
|
|
1626
1640
|
// Notify user on health level transitions (green→yellow→red and back)
|
|
1627
1641
|
setLevelChangeCallback((_from, to, summary) => {
|
|
@@ -1776,6 +1790,23 @@ export async function bootstrapAutoSession(
|
|
|
1776
1790
|
return releaseLockAndReturn();
|
|
1777
1791
|
}
|
|
1778
1792
|
|
|
1793
|
+
// Gate: confirm the handle is actually writable, not just open. A
|
|
1794
|
+
// schema-current DB does zero writes during open, so a read-only /
|
|
1795
|
+
// DBMOVED handle otherwise passes the check above and only fails much
|
|
1796
|
+
// later at the first authoritative write (the uok-kernel-enter audit)
|
|
1797
|
+
// with an opaque "readonly database" error (#1234).
|
|
1798
|
+
if (existsSync(gsdDbPath) && isDbAvailable()) {
|
|
1799
|
+
const writable = probeDbWritable();
|
|
1800
|
+
if (!writable.ok) {
|
|
1801
|
+
const detail = writable.detail ? ` (${writable.detail})` : "";
|
|
1802
|
+
ctx.ui.notify(
|
|
1803
|
+
`SQLite database is not writable: ${gsdDbPath}.${detail} Check file/WAL permissions or reopen a stale handle before running auto-mode.`,
|
|
1804
|
+
"error",
|
|
1805
|
+
);
|
|
1806
|
+
return releaseLockAndReturn();
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1779
1810
|
// Initialize metrics
|
|
1780
1811
|
initMetrics(s.basePath);
|
|
1781
1812
|
|
|
@@ -1813,7 +1844,7 @@ export async function bootstrapAutoSession(
|
|
|
1813
1844
|
|
|
1814
1845
|
// Snapshot installed skills
|
|
1815
1846
|
if (resolveSkillDiscoveryMode(base) !== "off") {
|
|
1816
|
-
snapshotSkills();
|
|
1847
|
+
snapshotSkills({ cwd: s.basePath });
|
|
1817
1848
|
}
|
|
1818
1849
|
|
|
1819
1850
|
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
@@ -21,6 +21,8 @@ import { existsSync } from "node:fs";
|
|
|
21
21
|
|
|
22
22
|
import { bumpAndResolveSynthetic } from "./auto/resolve.js";
|
|
23
23
|
import { finalizeProjectResearchTimeout } from "./project-research-policy.js";
|
|
24
|
+
import { applySupervisorModelIfConfigured } from "./auto-model-selection.js";
|
|
25
|
+
import { getInFlightToolCount } from "./auto-tool-tracking.js";
|
|
24
26
|
|
|
25
27
|
export interface RecoveryContext {
|
|
26
28
|
basePath: string;
|
|
@@ -122,13 +124,17 @@ export async function recoverTimedOutUnit(
|
|
|
122
124
|
"If full completion is impossible, write the partial artifact/state needed for recovery and make the blocker explicit.",
|
|
123
125
|
];
|
|
124
126
|
|
|
127
|
+
const recoveryTrigger = getInFlightToolCount() === 0;
|
|
128
|
+
if (recoveryTrigger) {
|
|
129
|
+
await applySupervisorModelIfConfigured(ctx, pi, basePath);
|
|
130
|
+
}
|
|
125
131
|
pi.sendMessage(
|
|
126
132
|
{
|
|
127
133
|
customType: "gsd-auto-timeout-recovery",
|
|
128
134
|
display: verbose,
|
|
129
135
|
content: steeringLines.join("\n"),
|
|
130
136
|
},
|
|
131
|
-
{ triggerTurn:
|
|
137
|
+
{ triggerTurn: recoveryTrigger, deliverAs: "steer" },
|
|
132
138
|
);
|
|
133
139
|
ctx.ui.notify(
|
|
134
140
|
`${reason === "idle" ? "Idle" : "Timeout"} recovery: steering ${unitType} ${unitId} to finish durable output (attempt ${attemptNumber}, session ${recoveryAttempts + 1}/${maxRecoveryAttempts}).`,
|
|
@@ -249,13 +255,17 @@ export async function recoverTimedOutUnit(
|
|
|
249
255
|
"If blocked, write the partial artifact and explicitly record the blocker instead of going silent.",
|
|
250
256
|
];
|
|
251
257
|
|
|
258
|
+
const recoveryTrigger = getInFlightToolCount() === 0;
|
|
259
|
+
if (recoveryTrigger) {
|
|
260
|
+
await applySupervisorModelIfConfigured(ctx, pi, basePath);
|
|
261
|
+
}
|
|
252
262
|
pi.sendMessage(
|
|
253
263
|
{
|
|
254
264
|
customType: "gsd-auto-timeout-recovery",
|
|
255
265
|
display: verbose,
|
|
256
266
|
content: steeringLines.join("\n"),
|
|
257
267
|
},
|
|
258
|
-
{ triggerTurn:
|
|
268
|
+
{ triggerTurn: recoveryTrigger, deliverAs: "steer" },
|
|
259
269
|
);
|
|
260
270
|
ctx.ui.notify(
|
|
261
271
|
`${reason === "idle" ? "Idle" : "Timeout"} recovery: steering ${unitType} ${unitId} to produce ${expected} (attempt ${attemptNumber}, session ${recoveryAttempts + 1}/${maxRecoveryAttempts}).`,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
hasInteractiveToolInFlight,
|
|
20
20
|
} from "./auto-tool-tracking.js";
|
|
21
21
|
import { detectWorkingTreeActivity } from "./auto-supervisor.js";
|
|
22
|
+
import { applySupervisorModelIfConfigured } from "./auto-model-selection.js";
|
|
22
23
|
import { closeoutUnit, type CloseoutOptions } from "./auto-unit-closeout.js";
|
|
23
24
|
import { saveActivityLog } from "./activity-log.js";
|
|
24
25
|
import { recoverTimedOutUnit, type RecoveryContext } from "./auto-timeout-recovery.js";
|
|
@@ -158,7 +159,7 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
158
159
|
: idleTimeoutMs;
|
|
159
160
|
|
|
160
161
|
// ── 1. Soft timeout warning ──
|
|
161
|
-
s.wrapupWarningHandle = setTimeout(() => {
|
|
162
|
+
s.wrapupWarningHandle = setTimeout(async () => {
|
|
162
163
|
s.wrapupWarningHandle = null;
|
|
163
164
|
if (!s.active || !s.currentUnit) return;
|
|
164
165
|
writeUnitRuntimeRecord(s.basePath, unitType, unitId, s.currentUnit.startedAt, {
|
|
@@ -169,6 +170,9 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
169
170
|
// Triggering during active tool calls causes tool results to be skipped
|
|
170
171
|
// with "Skipped due to queued user message", leading to provider errors (#3512).
|
|
171
172
|
const softTrigger = getInFlightToolCount() === 0;
|
|
173
|
+
if (softTrigger) {
|
|
174
|
+
await applySupervisorModelIfConfigured(ctx, pi, s.basePath);
|
|
175
|
+
}
|
|
172
176
|
pi.sendMessage(
|
|
173
177
|
{
|
|
174
178
|
customType: "gsd-auto-wrapup",
|
|
@@ -351,7 +355,7 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
351
355
|
ctx.model?.provider,
|
|
352
356
|
);
|
|
353
357
|
const continueHereThreshold = computeBudgets(executorContextWindow).continueThresholdPercent;
|
|
354
|
-
s.continueHereHandle = setInterval(() => {
|
|
358
|
+
s.continueHereHandle = setInterval(async () => {
|
|
355
359
|
if (!s.active || !s.currentUnit || !s.cmdCtx) return;
|
|
356
360
|
const runtime = readUnitRuntimeRecord(s.basePath, unitType, unitId);
|
|
357
361
|
if (runtime?.continueHereFired) return;
|
|
@@ -382,6 +386,9 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
382
386
|
|
|
383
387
|
// Only trigger a new turn if no tools are currently in flight (#3512).
|
|
384
388
|
const contextTrigger = getInFlightToolCount() === 0;
|
|
389
|
+
if (contextTrigger) {
|
|
390
|
+
await applySupervisorModelIfConfigured(ctx, pi, s.basePath);
|
|
391
|
+
}
|
|
385
392
|
pi.sendMessage(
|
|
386
393
|
{
|
|
387
394
|
customType: "gsd-auto-wrapup",
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// gsd-pi — Auto-worktree branch lifecycle module.
|
|
2
|
+
//
|
|
3
|
+
// Owns milestone branch naming, branch-mode entry, and safe fast-forward of
|
|
4
|
+
// reused milestone branches. Worktree creation/merge code imports this module
|
|
5
|
+
// instead of keeping branch policy inside the legacy auto-worktree barrel.
|
|
6
|
+
|
|
7
|
+
import { GSDError, GSD_GIT_ERROR } from "./errors.js";
|
|
8
|
+
import { readIntegrationBranch } from "./git-service.js";
|
|
9
|
+
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
10
|
+
import { debugLog } from "./debug-logger.js";
|
|
11
|
+
import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
|
|
12
|
+
import {
|
|
13
|
+
nativeBranchExists,
|
|
14
|
+
nativeBranchForceReset,
|
|
15
|
+
nativeDetectMainBranch,
|
|
16
|
+
nativeIsAncestor,
|
|
17
|
+
nativeUpdateRef,
|
|
18
|
+
nativeWorktreeList,
|
|
19
|
+
} from "./native-git-bridge.js";
|
|
20
|
+
|
|
21
|
+
/** Returns the git branch name for a milestone worktree (`milestone/<MID>`). */
|
|
22
|
+
export function autoWorktreeBranch(milestoneId: string): string {
|
|
23
|
+
return `milestone/${milestoneId}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function _resolveAutoWorktreeStartPoint(
|
|
27
|
+
integrationBranch: string | null | undefined,
|
|
28
|
+
gitMainBranch: string | null | undefined,
|
|
29
|
+
branchExists: (branch: string) => boolean,
|
|
30
|
+
): string | undefined {
|
|
31
|
+
if (integrationBranch) return integrationBranch;
|
|
32
|
+
return gitMainBranch &&
|
|
33
|
+
typeof gitMainBranch === "string" &&
|
|
34
|
+
gitMainBranch.length > 0 &&
|
|
35
|
+
branchExists(gitMainBranch)
|
|
36
|
+
? gitMainBranch
|
|
37
|
+
: undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Enter branch isolation mode for a milestone.
|
|
42
|
+
*
|
|
43
|
+
* Creates `milestone/<MID>` from the integration branch (if it doesn't
|
|
44
|
+
* exist yet) and checks out to it. No worktree directory is created — the
|
|
45
|
+
* project root is the working copy; only HEAD changes.
|
|
46
|
+
*
|
|
47
|
+
* Uses the same 3-tier integration-branch fallback as createAutoWorktree:
|
|
48
|
+
* 1. META.json recorded integration branch
|
|
49
|
+
* 2. git.main_branch preference
|
|
50
|
+
* 3. nativeDetectMainBranch (origin/HEAD auto-detection)
|
|
51
|
+
*/
|
|
52
|
+
export function enterBranchModeForMilestone(
|
|
53
|
+
basePath: string,
|
|
54
|
+
milestoneId: string,
|
|
55
|
+
): void {
|
|
56
|
+
const branch = autoWorktreeBranch(milestoneId);
|
|
57
|
+
const branchExists = nativeBranchExists(basePath, branch);
|
|
58
|
+
|
|
59
|
+
if (!branchExists) {
|
|
60
|
+
// Create the milestone branch from the integration branch start-point.
|
|
61
|
+
const integrationBranch =
|
|
62
|
+
readIntegrationBranch(basePath, milestoneId) ?? undefined;
|
|
63
|
+
const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
64
|
+
const startPoint =
|
|
65
|
+
_resolveAutoWorktreeStartPoint(
|
|
66
|
+
integrationBranch,
|
|
67
|
+
gitPrefs?.main_branch,
|
|
68
|
+
(branchName) => nativeBranchExists(basePath, branchName),
|
|
69
|
+
) ??
|
|
70
|
+
nativeDetectMainBranch(basePath);
|
|
71
|
+
|
|
72
|
+
// TOCTOU ancestry guard (Issue #4980 HIGH-3).
|
|
73
|
+
//
|
|
74
|
+
// The outer `branchExists` check is racy: a concurrent process
|
|
75
|
+
// (parallel-orchestrator worker, side-by-side `gsd` instance, or manual
|
|
76
|
+
// `git branch` invocation) may have created the branch with real commits
|
|
77
|
+
// between that check and this point. `nativeBranchForceReset` does
|
|
78
|
+
// `git branch -f`, which silently overwrites the branch ref — orphaning
|
|
79
|
+
// any commits not reachable from `startPoint`. Re-check immediately
|
|
80
|
+
// before the destructive call and refuse if the branch suddenly exists
|
|
81
|
+
// with non-ancestor commits.
|
|
82
|
+
const concurrentlyCreated = nativeBranchExists(basePath, branch);
|
|
83
|
+
if (
|
|
84
|
+
concurrentlyCreated &&
|
|
85
|
+
!nativeIsAncestor(basePath, branch, startPoint)
|
|
86
|
+
) {
|
|
87
|
+
throw new GSDError(
|
|
88
|
+
GSD_GIT_ERROR,
|
|
89
|
+
`Branch "${branch}" was created concurrently with commits not reachable from "${startPoint}". ` +
|
|
90
|
+
`Refusing to force-reset — would orphan prior work. ` +
|
|
91
|
+
`Resume the existing milestone or run \`git branch -D ${branch}\` to discard.`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
// nativeBranchForceReset creates (or resets) branch at startPoint,
|
|
95
|
+
// then checkout switches HEAD to it.
|
|
96
|
+
nativeBranchForceReset(basePath, branch, startPoint);
|
|
97
|
+
debugLog("auto-worktree", {
|
|
98
|
+
action: "enterBranchMode",
|
|
99
|
+
milestoneId,
|
|
100
|
+
branch,
|
|
101
|
+
startPoint,
|
|
102
|
+
created: true,
|
|
103
|
+
});
|
|
104
|
+
} else {
|
|
105
|
+
debugLog("auto-worktree", {
|
|
106
|
+
action: "enterBranchMode",
|
|
107
|
+
milestoneId,
|
|
108
|
+
branch,
|
|
109
|
+
reused: true,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
checkoutBranchWithStashGuard(
|
|
114
|
+
basePath,
|
|
115
|
+
branch,
|
|
116
|
+
`enter-branch-mode:${milestoneId}`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* True when `branch` is checked out in any worktree listed by
|
|
122
|
+
* `git worktree list --porcelain`. Used to gate ref updates that would
|
|
123
|
+
* otherwise leave a concurrent worktree's HEAD inconsistent with its
|
|
124
|
+
* index/working tree (Codex peer-review of #5538-followup).
|
|
125
|
+
*
|
|
126
|
+
* Best-effort: a `nativeWorktreeList` failure returns true so we err on
|
|
127
|
+
* the side of NOT moving the ref. Better to skip a fast-forward than to
|
|
128
|
+
* silently corrupt another worktree.
|
|
129
|
+
*/
|
|
130
|
+
export function _isBranchCheckedOutElsewhere(
|
|
131
|
+
basePath: string,
|
|
132
|
+
branch: string,
|
|
133
|
+
): boolean {
|
|
134
|
+
try {
|
|
135
|
+
const entries = nativeWorktreeList(basePath);
|
|
136
|
+
return entries.some((entry) => entry.branch === branch);
|
|
137
|
+
} catch {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Resolve the integration branch using the same 3-tier fallback as the
|
|
144
|
+
* fresh-create path: META.json → git.main_branch preference → detected
|
|
145
|
+
* main branch. Returns null when no usable target exists.
|
|
146
|
+
*/
|
|
147
|
+
function resolveIntegrationBranchForReuse(
|
|
148
|
+
basePath: string,
|
|
149
|
+
milestoneId: string,
|
|
150
|
+
): string | null {
|
|
151
|
+
const fromMeta = readIntegrationBranch(basePath, milestoneId);
|
|
152
|
+
if (fromMeta) return fromMeta;
|
|
153
|
+
|
|
154
|
+
const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
155
|
+
const fromPref = gitPrefs?.main_branch &&
|
|
156
|
+
typeof gitPrefs.main_branch === "string" &&
|
|
157
|
+
gitPrefs.main_branch.length > 0 &&
|
|
158
|
+
nativeBranchExists(basePath, gitPrefs.main_branch)
|
|
159
|
+
? gitPrefs.main_branch
|
|
160
|
+
: null;
|
|
161
|
+
if (fromPref) return fromPref;
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
return nativeDetectMainBranch(basePath);
|
|
165
|
+
} catch {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* When reusing an existing milestone branch, fast-forward it onto the
|
|
172
|
+
* integration branch when that's safe (branch is a strict ancestor of
|
|
173
|
+
* integration — no commits would be lost). Skips when the branch has its
|
|
174
|
+
* own commits ahead of integration, when the integration branch can't be
|
|
175
|
+
* resolved, or when any git operation fails — the merge gate at milestone
|
|
176
|
+
* completion will surface real divergence as a conflict.
|
|
177
|
+
*
|
|
178
|
+
* The previous behavior re-attached the worktree to whatever stale tip
|
|
179
|
+
* the branch held, which caused new milestone work to fork from a base
|
|
180
|
+
* missing prior milestones' merges (#5538-followup).
|
|
181
|
+
*/
|
|
182
|
+
export function fastForwardReusedMilestoneBranchIfSafe(
|
|
183
|
+
basePath: string,
|
|
184
|
+
milestoneId: string,
|
|
185
|
+
branch: string,
|
|
186
|
+
): void {
|
|
187
|
+
try {
|
|
188
|
+
const integrationBranch = resolveIntegrationBranchForReuse(
|
|
189
|
+
basePath,
|
|
190
|
+
milestoneId,
|
|
191
|
+
);
|
|
192
|
+
if (!integrationBranch || integrationBranch === branch) return;
|
|
193
|
+
if (!nativeBranchExists(basePath, integrationBranch)) return;
|
|
194
|
+
|
|
195
|
+
// Pure fast-forward only: branch must be a strict ancestor of integration.
|
|
196
|
+
// If the branch has its own commits ahead, leave it alone.
|
|
197
|
+
if (!nativeIsAncestor(basePath, branch, integrationBranch)) {
|
|
198
|
+
debugLog("createAutoWorktree", {
|
|
199
|
+
phase: "skip-ff-branch-not-ancestor",
|
|
200
|
+
milestoneId,
|
|
201
|
+
branch,
|
|
202
|
+
integration: integrationBranch,
|
|
203
|
+
});
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Codex peer-review: `nativeUpdateRef` succeeds even when the branch is
|
|
208
|
+
// currently checked out in another worktree, leaving that worktree's HEAD
|
|
209
|
+
// inconsistent with its index/work tree. Skip the fast-forward if any
|
|
210
|
+
// listed worktree has this branch checked out — the merge gate at
|
|
211
|
+
// milestone-completion will surface stale-base divergence as a conflict
|
|
212
|
+
// instead of silently corrupting the other worktree's state.
|
|
213
|
+
if (_isBranchCheckedOutElsewhere(basePath, branch)) {
|
|
214
|
+
debugLog("createAutoWorktree", {
|
|
215
|
+
phase: "skip-ff-branch-checked-out-elsewhere",
|
|
216
|
+
milestoneId,
|
|
217
|
+
branch,
|
|
218
|
+
});
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
nativeUpdateRef(basePath, `refs/heads/${branch}`, integrationBranch);
|
|
223
|
+
debugLog("createAutoWorktree", {
|
|
224
|
+
phase: "fast-forward-reused-branch",
|
|
225
|
+
milestoneId,
|
|
226
|
+
branch,
|
|
227
|
+
integration: integrationBranch,
|
|
228
|
+
});
|
|
229
|
+
} catch (err) {
|
|
230
|
+
debugLog("createAutoWorktree", {
|
|
231
|
+
phase: "fast-forward-reused-branch-failed",
|
|
232
|
+
milestoneId,
|
|
233
|
+
branch,
|
|
234
|
+
error: err instanceof Error ? err.message : String(err),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// gsd-pi — Auto-worktree cleanup helpers.
|
|
2
|
+
//
|
|
3
|
+
// Owns shared cleanup primitives used by teardown and merge cleanup paths:
|
|
4
|
+
// same-file DB reconciliation checks, transient project-root state removal,
|
|
5
|
+
// git pathspec conversion for externally-rooted .gsd paths, and expected
|
|
6
|
+
// unlink error classification.
|
|
7
|
+
|
|
8
|
+
import { execFileSync } from "node:child_process";
|
|
9
|
+
import { existsSync, realpathSync, unlinkSync } from "node:fs";
|
|
10
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
11
|
+
|
|
12
|
+
import { gsdRoot } from "./paths.js";
|
|
13
|
+
import { logWarning } from "./workflow-logger.js";
|
|
14
|
+
|
|
15
|
+
function isSamePath(a: string, b: string): boolean {
|
|
16
|
+
try {
|
|
17
|
+
return realpathSync(a) === realpathSync(b);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
if ((e as NodeJS.ErrnoException).code === "ENOENT") return false;
|
|
20
|
+
logWarning("worktree", `isSamePath failed: ${(e as Error).message}`);
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function _isSamePath(a: string, b: string): boolean {
|
|
26
|
+
return isSamePath(a, b);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function _shouldReconcileWorktreeDb(
|
|
30
|
+
worktreeDbPath: string,
|
|
31
|
+
mainDbPath: string,
|
|
32
|
+
pathExists: (path: string) => boolean = existsSync,
|
|
33
|
+
samePath: (a: string, b: string) => boolean = isSamePath,
|
|
34
|
+
): boolean {
|
|
35
|
+
return pathExists(worktreeDbPath) && !samePath(worktreeDbPath, mainDbPath);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function _isExpectedWorktreeUnlinkError(
|
|
39
|
+
code: string | undefined,
|
|
40
|
+
): boolean {
|
|
41
|
+
return code === "ENOENT" || code === "EISDIR";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function gitPathspecForWorktreePath(
|
|
45
|
+
basePath: string,
|
|
46
|
+
targetPath: string,
|
|
47
|
+
): string | null {
|
|
48
|
+
let base = basePath;
|
|
49
|
+
let target = targetPath;
|
|
50
|
+
try {
|
|
51
|
+
base = execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
52
|
+
cwd: basePath,
|
|
53
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
54
|
+
encoding: "utf-8",
|
|
55
|
+
}).trim() || basePath;
|
|
56
|
+
} catch {
|
|
57
|
+
/* keep original */
|
|
58
|
+
void base;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
base = realpathSync.native(base);
|
|
62
|
+
} catch {
|
|
63
|
+
/* keep original */
|
|
64
|
+
void base;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
target = realpathSync.native(targetPath);
|
|
68
|
+
} catch {
|
|
69
|
+
/* keep original */
|
|
70
|
+
void target;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const rel = relative(base, target);
|
|
74
|
+
if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) return null;
|
|
75
|
+
return rel.replaceAll("\\", "/");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function _gitPathspecForWorktreePath(
|
|
79
|
+
basePath: string,
|
|
80
|
+
targetPath: string,
|
|
81
|
+
): string | null {
|
|
82
|
+
return gitPathspecForWorktreePath(basePath, targetPath);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function clearProjectRootStateFiles(
|
|
86
|
+
basePath: string,
|
|
87
|
+
milestoneId: string,
|
|
88
|
+
): void {
|
|
89
|
+
const gsdDir = gsdRoot(basePath);
|
|
90
|
+
// Phase C pt 2: auto.lock removed from this list — the file is gone
|
|
91
|
+
// (migrated to the workers + unit_dispatches + runtime_kv tables). The
|
|
92
|
+
// remaining transient files (STATE.md, {MID}-META.json) are still
|
|
93
|
+
// worth removing on teardown.
|
|
94
|
+
const transientFiles = [
|
|
95
|
+
join(gsdDir, "STATE.md"),
|
|
96
|
+
join(gsdDir, "milestones", milestoneId, `${milestoneId}-META.json`),
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
for (const file of transientFiles) {
|
|
100
|
+
try {
|
|
101
|
+
unlinkSync(file);
|
|
102
|
+
} catch (err) {
|
|
103
|
+
// ENOENT is expected — file may not exist (#3597)
|
|
104
|
+
if ((err as NodeJS.ErrnoException).code !== "ENOENT") {
|
|
105
|
+
logWarning(
|
|
106
|
+
"worktree",
|
|
107
|
+
`file unlink failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Clean up legacy synced milestone directories and runtime/units.
|
|
114
|
+
// Older versions copied these into the project root during execution.
|
|
115
|
+
// If they remain as untracked files when we attempt
|
|
116
|
+
// `git merge --squash`, git rejects the merge with "local changes would
|
|
117
|
+
// be overwritten", causing silent data loss (#1738).
|
|
118
|
+
const syncedDirs = [
|
|
119
|
+
join(gsdDir, "milestones", milestoneId),
|
|
120
|
+
join(gsdDir, "runtime", "units"),
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
for (const dir of syncedDirs) {
|
|
124
|
+
try {
|
|
125
|
+
if (!existsSync(dir)) continue;
|
|
126
|
+
|
|
127
|
+
const pathspec = gitPathspecForWorktreePath(basePath, dir);
|
|
128
|
+
if (!pathspec) continue;
|
|
129
|
+
|
|
130
|
+
// Only remove files that are untracked by git — tracked files are
|
|
131
|
+
// managed by the branch checkout and should not be deleted.
|
|
132
|
+
const untrackedOutput = execFileSync(
|
|
133
|
+
"git",
|
|
134
|
+
["ls-files", "--others", "--exclude-standard", pathspec],
|
|
135
|
+
{
|
|
136
|
+
cwd: basePath,
|
|
137
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
138
|
+
encoding: "utf-8",
|
|
139
|
+
},
|
|
140
|
+
).trim();
|
|
141
|
+
if (!untrackedOutput) continue;
|
|
142
|
+
|
|
143
|
+
for (const f of untrackedOutput.split("\n").filter(Boolean)) {
|
|
144
|
+
try {
|
|
145
|
+
unlinkSync(join(basePath, f));
|
|
146
|
+
} catch (err) {
|
|
147
|
+
// ENOENT/EISDIR are expected for already-removed or
|
|
148
|
+
// directory entries (#3597).
|
|
149
|
+
const code = (err as NodeJS.ErrnoException).code;
|
|
150
|
+
if (!_isExpectedWorktreeUnlinkError(code)) {
|
|
151
|
+
logWarning(
|
|
152
|
+
"worktree",
|
|
153
|
+
`untracked file unlink failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} catch (err) {
|
|
159
|
+
/* non-fatal — git command may fail if not in repo */
|
|
160
|
+
logWarning(
|
|
161
|
+
"worktree",
|
|
162
|
+
`untracked file cleanup failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// gsd-pi — Conflict auto-resolve policy for auto-worktree merges.
|
|
2
|
+
//
|
|
3
|
+
// Owns the pure path policy for conflict paths that are safe to resolve
|
|
4
|
+
// mechanically. Git mutation stays in git-conflict-resolve.ts.
|
|
5
|
+
|
|
6
|
+
/** Patterns for machine-generated build artifacts that can be safely
|
|
7
|
+
* auto-resolved by accepting --theirs during merge. These files are
|
|
8
|
+
* regenerable and never contain meaningful manual edits. */
|
|
9
|
+
export const SAFE_AUTO_RESOLVE_PATTERNS: RegExp[] = [
|
|
10
|
+
/\.tsbuildinfo$/,
|
|
11
|
+
/\.pyc$/,
|
|
12
|
+
/\/__pycache__\//,
|
|
13
|
+
/\.DS_Store$/,
|
|
14
|
+
/\.map$/,
|
|
15
|
+
// Regenerable dependency lockfiles. These are fully derivable from their
|
|
16
|
+
// manifests by the package manager, so accepting the merge side during
|
|
17
|
+
// auto-resolve clears the conflict markers without losing meaningful edits —
|
|
18
|
+
// and stops auto-mode from hard-pausing on a lockfile conflict (issue #828).
|
|
19
|
+
/(?:^|\/)pnpm-lock\.yaml$/,
|
|
20
|
+
/(?:^|\/)package-lock\.json$/,
|
|
21
|
+
/(?:^|\/)npm-shrinkwrap\.json$/,
|
|
22
|
+
/(?:^|\/)yarn\.lock$/,
|
|
23
|
+
/(?:^|\/)bun\.lockb?$/,
|
|
24
|
+
/(?:^|\/)Cargo\.lock$/,
|
|
25
|
+
/(?:^|\/)composer\.lock$/,
|
|
26
|
+
/(?:^|\/)Gemfile\.lock$/,
|
|
27
|
+
/(?:^|\/)Pipfile\.lock$/,
|
|
28
|
+
/(?:^|\/)poetry\.lock$/,
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
/** Returns true if the file path is safe to auto-resolve during merge.
|
|
32
|
+
* Covers `.gsd/` state files, common build artifacts, and regenerable
|
|
33
|
+
* dependency lockfiles. */
|
|
34
|
+
export function isSafeToAutoResolve(filePath: string): boolean {
|
|
35
|
+
return filePath.startsWith(".gsd/")
|
|
36
|
+
|| SAFE_AUTO_RESOLVE_PATTERNS.some((re) => re.test(filePath));
|
|
37
|
+
}
|