@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.955e4da0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-web-branch.d.ts +2 -0
- package/dist/cli-web-branch.js +9 -2
- package/dist/help-text.js +5 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +78 -23
- package/dist/resources/extensions/bg-shell/utilities.js +2 -2
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +92 -230
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
- package/dist/resources/extensions/github-sync/templates.js +3 -3
- package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
- package/dist/resources/extensions/gsd/auto/loop.js +74 -56
- package/dist/resources/extensions/gsd/auto/orchestrator.js +142 -15
- package/dist/resources/extensions/gsd/auto/phases.js +34 -4
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +12 -9
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
- package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
- package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
- package/dist/resources/extensions/gsd/auto-start.js +20 -36
- package/dist/resources/extensions/gsd/auto-timers.js +16 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
- package/dist/resources/extensions/gsd/auto-verification.js +7 -7
- package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +34 -289
- package/dist/resources/extensions/gsd/auto.js +15 -14
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +20 -43
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +131 -140
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +89 -8
- package/dist/resources/extensions/gsd/captures.js +5 -13
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
- package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
- package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
- package/dist/resources/extensions/gsd/db/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +372 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- package/dist/resources/extensions/gsd/db-workspace.js +103 -0
- package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
- package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +8 -10
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +9 -2
- package/dist/resources/extensions/gsd/doctor.js +16 -9
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-db.js +183 -2048
- package/dist/resources/extensions/gsd/guided-flow.js +68 -471
- package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
- package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
- package/dist/resources/extensions/gsd/md-importer.js +4 -3
- package/dist/resources/extensions/gsd/migrate/safety.js +19 -11
- package/dist/resources/extensions/gsd/migration-auto-check.js +27 -5
- package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
- package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
- package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
- package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
- package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +7 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/paths.js +10 -24
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
- package/dist/resources/extensions/gsd/preferences.js +161 -29
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
- package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
- package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
- package/dist/resources/extensions/gsd/question-transport.js +86 -0
- package/dist/resources/extensions/gsd/recovery-classification.js +12 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +13 -5
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- package/dist/resources/extensions/gsd/templates/plan.md +7 -0
- package/dist/resources/extensions/gsd/templates/project.md +1 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/dist/resources/extensions/gsd/templates/uat.md +5 -1
- package/dist/resources/extensions/gsd/tool-contract.js +52 -8
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
- package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -5
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
- package/dist/resources/extensions/gsd/uat-policy.js +16 -10
- package/dist/resources/extensions/gsd/uat-run.js +9 -14
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
- package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
- package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
- package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
- package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +287 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +17 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -10
- package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
- package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
- package/dist/resources/extensions/shared/interview-ui.js +2 -2
- package/dist/resources/shared/claude-runtime-floor.js +182 -0
- package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-cmd.js +20 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- 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/react-loadable-manifest.json +8 -8
- 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 +12 -12
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- 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/middleware-react-loadable-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/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
- package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
- package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +20 -8
- package/dist/worktree-status-banner.js +7 -3
- package/package.json +2 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- 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 +106 -40
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +10 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +8 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +32 -22
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +295 -98
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +309 -154
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/components/input.js +1 -1
- package/packages/pi-tui/dist/components/input.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +39 -30
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +22 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +87 -24
- package/src/resources/extensions/bg-shell/utilities.ts +2 -2
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +114 -281
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +268 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
- package/src/resources/extensions/github-sync/templates.ts +3 -3
- package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
- package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
- package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -1
- package/src/resources/extensions/gsd/auto/loop.ts +83 -61
- package/src/resources/extensions/gsd/auto/orchestrator.ts +164 -17
- package/src/resources/extensions/gsd/auto/phases.ts +45 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
- package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +16 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
- package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
- package/src/resources/extensions/gsd/auto-start.ts +25 -34
- package/src/resources/extensions/gsd/auto-timers.ts +16 -2
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
- package/src/resources/extensions/gsd/auto-verification.ts +7 -8
- package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +53 -306
- package/src/resources/extensions/gsd/auto.ts +27 -17
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +20 -43
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +147 -153
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +132 -6
- package/src/resources/extensions/gsd/captures.ts +5 -14
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
- package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
- package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
- package/src/resources/extensions/gsd/db/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +453 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- package/src/resources/extensions/gsd/db-workspace.ts +170 -0
- package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
- package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +8 -11
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -3
- package/src/resources/extensions/gsd/doctor.ts +15 -5
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-db.ts +185 -2373
- package/src/resources/extensions/gsd/guided-flow.ts +81 -561
- package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
- package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -3
- package/src/resources/extensions/gsd/migrate/safety.ts +17 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +30 -5
- package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
- package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
- package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
- package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
- package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/paths.ts +9 -22
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +191 -28
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
- package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
- package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
- package/src/resources/extensions/gsd/question-transport.ts +138 -0
- package/src/resources/extensions/gsd/recovery-classification.ts +14 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +15 -5
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/templates/plan.md +7 -0
- package/src/resources/extensions/gsd/templates/project.md +1 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/src/resources/extensions/gsd/templates/uat.md +5 -1
- package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +444 -5
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +143 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +185 -1
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +121 -0
- package/src/resources/extensions/gsd/tool-contract.ts +86 -8
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
- package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
- package/src/resources/extensions/gsd/tools/exec-tool.ts +5 -5
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
- package/src/resources/extensions/gsd/uat-policy.ts +19 -10
- package/src/resources/extensions/gsd/uat-run.ts +10 -14
- package/src/resources/extensions/gsd/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
- package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
- package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
- package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +308 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +17 -17
- package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +17 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +12 -10
- package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
- package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
- package/src/resources/extensions/shared/interview-ui.ts +15 -2
- package/src/resources/shared/claude-runtime-floor.ts +248 -0
- package/src/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
- package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
- package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
- package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_ssgManifest.js +0 -0
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* GSD Worktree Manager
|
|
6
6
|
*
|
|
7
|
-
* Creates and manages git worktrees under .gsd
|
|
7
|
+
* Creates and manages git worktrees under .gsd-worktrees/<name>/ (canonical;
|
|
8
|
+
* legacy .gsd/worktrees/<name>/ stays recognized — see worktree-placement.ts).
|
|
8
9
|
* Each worktree gets its own branch (worktree/<name>) and a full
|
|
9
10
|
* working copy of the project, enabling parallel work streams.
|
|
10
11
|
*
|
|
@@ -12,7 +13,7 @@
|
|
|
12
13
|
* the main branch, then dispatches an LLM-guided merge flow.
|
|
13
14
|
*
|
|
14
15
|
* Flow:
|
|
15
|
-
* 1. create() — git worktree add .gsd
|
|
16
|
+
* 1. create() — git worktree add .gsd-worktrees/<name> -b worktree/<name>
|
|
16
17
|
* 2. user works in the worktree (new plans, milestones, etc.)
|
|
17
18
|
* 3. merge() — LLM-guided reconciliation of .gsd/ artifacts back to main
|
|
18
19
|
* 4. remove() — git worktree remove + branch cleanup
|
|
@@ -48,6 +49,7 @@ import {
|
|
|
48
49
|
normalizeWorktreePathForCompare,
|
|
49
50
|
resolveWorktreeProjectRoot,
|
|
50
51
|
} from "./worktree-root.js";
|
|
52
|
+
import { canonicalWorktreesDir, worktreePathFor, worktreesDirs } from "./worktree-placement.js";
|
|
51
53
|
|
|
52
54
|
// ─── Types ─────────────────────────────────────────────────────────────────
|
|
53
55
|
|
|
@@ -138,12 +140,20 @@ export function resolveGitDir(basePath: string): string {
|
|
|
138
140
|
return gitPath;
|
|
139
141
|
}
|
|
140
142
|
|
|
143
|
+
/** Canonical container for new worktrees. For scans that must also see legacy
|
|
144
|
+
* worktrees, use allWorktreesDirs(). */
|
|
141
145
|
export function worktreesDir(basePath: string): string {
|
|
142
|
-
return
|
|
146
|
+
return canonicalWorktreesDir(resolveWorktreeProjectRoot(basePath));
|
|
143
147
|
}
|
|
144
148
|
|
|
149
|
+
/** Every container a GSD worktree may live in (canonical + legacy), canonical first. */
|
|
150
|
+
export function allWorktreesDirs(basePath: string): string[] {
|
|
151
|
+
return worktreesDirs(resolveWorktreeProjectRoot(basePath));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Path for worktree `name` — an existing legacy worktree keeps its location. */
|
|
145
155
|
export function worktreePath(basePath: string, name: string): string {
|
|
146
|
-
return
|
|
156
|
+
return worktreePathFor(resolveWorktreeProjectRoot(basePath), name);
|
|
147
157
|
}
|
|
148
158
|
|
|
149
159
|
export function worktreeBranchName(name: string): string {
|
|
@@ -151,20 +161,22 @@ export function worktreeBranchName(name: string): string {
|
|
|
151
161
|
}
|
|
152
162
|
|
|
153
163
|
/**
|
|
154
|
-
* Validate that a path is inside
|
|
155
|
-
*
|
|
156
|
-
* so that a symlink-resolved
|
|
164
|
+
* Validate that a path is inside a GSD worktrees container (canonical
|
|
165
|
+
* .gsd-worktrees/ or legacy .gsd/worktrees/). Resolves symlinks and
|
|
166
|
+
* normalizes ".." traversals before comparison so that a symlink-resolved
|
|
167
|
+
* or crafted path cannot escape containment.
|
|
157
168
|
*
|
|
158
169
|
* Used as a safety gate before any destructive operation (rmSync,
|
|
159
170
|
* nativeWorktreeRemove --force) to prevent #2365-style data loss.
|
|
160
171
|
*/
|
|
161
172
|
export function isInsideWorktreesDir(basePath: string, targetPath: string): boolean {
|
|
162
|
-
const wtDirPath = worktreesDir(basePath);
|
|
163
|
-
const wtDir = existsSync(wtDirPath) ? realpathSync(wtDirPath) : resolve(wtDirPath);
|
|
164
173
|
const resolved = existsSync(targetPath) ? realpathSync(targetPath) : resolve(targetPath);
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
174
|
+
return allWorktreesDirs(basePath).some((wtDirPath) => {
|
|
175
|
+
const wtDir = existsSync(wtDirPath) ? realpathSync(wtDirPath) : resolve(wtDirPath);
|
|
176
|
+
// The resolved path must start with the worktrees dir followed by a separator,
|
|
177
|
+
// not merely be a prefix match (e.g. ".gsd/worktrees-extra" must not match).
|
|
178
|
+
return resolved === wtDir || resolved.startsWith(wtDir + sep);
|
|
179
|
+
});
|
|
168
180
|
}
|
|
169
181
|
|
|
170
182
|
function isRegisteredGitWorktreeAtPath(basePath: string, wtPath: string): boolean {
|
|
@@ -277,12 +289,12 @@ export function buildManualValidationGuidance(
|
|
|
277
289
|
): string | null {
|
|
278
290
|
if (!milestoneId) return null;
|
|
279
291
|
const validationRoot = resolveCanonicalMilestoneRoot(basePath, milestoneId);
|
|
280
|
-
const inWorktree = validationRoot
|
|
292
|
+
const inWorktree = isGsdWorktreePath(validationRoot);
|
|
281
293
|
const lines: string[] = [`Validate the work here: ${validationRoot}`];
|
|
282
294
|
if (inWorktree) {
|
|
283
295
|
lines.push(
|
|
284
|
-
"This milestone runs in a git worktree, so the code lives under the
|
|
285
|
-
|
|
296
|
+
"This milestone runs in a git worktree, so the code lives under the " +
|
|
297
|
+
`GSD worktrees directory. Open it with: cd "${validationRoot}"`,
|
|
286
298
|
);
|
|
287
299
|
}
|
|
288
300
|
if (opts.uatPath) {
|
|
@@ -307,24 +319,33 @@ export function createWorktree(basePath: string, name: string, opts: { branch?:
|
|
|
307
319
|
throw new GSDError(GSD_PARSE_ERROR, `Invalid worktree name "${name}". Use only letters, numbers, hyphens, and underscores.`);
|
|
308
320
|
}
|
|
309
321
|
|
|
310
|
-
const
|
|
322
|
+
const existingPath = worktreePath(basePath, name);
|
|
311
323
|
const branch = opts.branch ?? worktreeBranchName(name);
|
|
312
324
|
|
|
313
|
-
if (existsSync(
|
|
325
|
+
if (existsSync(existingPath)) {
|
|
314
326
|
// A valid git worktree is registered in `git worktree list` and has a .git
|
|
315
327
|
// *file* with a gitdir: pointer. Leftover directories (no .git, a standalone
|
|
316
328
|
// .git directory from accidental `git init`, or an orphan pointer) block
|
|
317
329
|
// creation unless removed.
|
|
318
|
-
if (isRegisteredGitWorktreeAtPath(basePath,
|
|
319
|
-
throw new GSDError(GSD_STALE_STATE, `Worktree "${name}" already exists at ${
|
|
330
|
+
if (isRegisteredGitWorktreeAtPath(basePath, existingPath)) {
|
|
331
|
+
throw new GSDError(GSD_STALE_STATE, `Worktree "${name}" already exists at ${existingPath}`);
|
|
320
332
|
}
|
|
321
|
-
removeStaleWorktreeDirectory(
|
|
333
|
+
removeStaleWorktreeDirectory(existingPath, name);
|
|
322
334
|
}
|
|
323
335
|
|
|
324
|
-
//
|
|
336
|
+
// New worktrees always land in the canonical container, even when a stale
|
|
337
|
+
// legacy directory was just cleaned up.
|
|
325
338
|
const wtDir = worktreesDir(basePath);
|
|
339
|
+
const wtPath = join(wtDir, name);
|
|
326
340
|
mkdirSync(wtDir, { recursive: true });
|
|
327
341
|
|
|
342
|
+
// When existingPath resolved to a legacy location, the canonical target may
|
|
343
|
+
// still hold a stale directory from a prior aborted creation (no .git marker).
|
|
344
|
+
// Remove it so git worktree add does not fail with "path already exists".
|
|
345
|
+
if (existingPath !== wtPath && existsSync(wtPath) && !isRegisteredGitWorktreeAtPath(basePath, wtPath)) {
|
|
346
|
+
removeStaleWorktreeDirectory(wtPath, name);
|
|
347
|
+
}
|
|
348
|
+
|
|
328
349
|
// Prune any stale worktree entries from a previous removal
|
|
329
350
|
nativeWorktreePrune(basePath);
|
|
330
351
|
|
|
@@ -405,7 +426,8 @@ export function createWorktree(basePath: string, name: string, opts: { branch?:
|
|
|
405
426
|
|
|
406
427
|
/**
|
|
407
428
|
* List all GSD-managed worktrees.
|
|
408
|
-
* Uses native worktree list and filters to those under
|
|
429
|
+
* Uses native worktree list and filters to those under a GSD worktrees
|
|
430
|
+
* container (canonical .gsd-worktrees/ or legacy .gsd/worktrees/).
|
|
409
431
|
*/
|
|
410
432
|
export function listWorktrees(basePath: string): WorktreeInfo[] {
|
|
411
433
|
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
@@ -416,12 +438,8 @@ export function listWorktrees(basePath: string): WorktreeInfo[] {
|
|
|
416
438
|
}
|
|
417
439
|
const seenRoots = new Set<string>();
|
|
418
440
|
const worktreeRoots = baseVariants
|
|
419
|
-
.
|
|
420
|
-
|
|
421
|
-
return {
|
|
422
|
-
normalized: normalizePathForComparison(path),
|
|
423
|
-
};
|
|
424
|
-
})
|
|
441
|
+
.flatMap(baseVariant => worktreesDirs(baseVariant))
|
|
442
|
+
.map(path => ({ normalized: normalizePathForComparison(path) }))
|
|
425
443
|
.filter(root => {
|
|
426
444
|
if (seenRoots.has(root.normalized)) return false;
|
|
427
445
|
seenRoots.add(root.normalized);
|
|
@@ -794,6 +812,7 @@ export function removeWorktree(
|
|
|
794
812
|
* This module uses a split representation (paths/exact/prefixes) for efficient matching.
|
|
795
813
|
*/
|
|
796
814
|
const SKIP_PATHS = [
|
|
815
|
+
".gsd-worktrees/",
|
|
797
816
|
".gsd/worktrees/",
|
|
798
817
|
".gsd/runtime/",
|
|
799
818
|
".gsd/activity/",
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worktree Placement module — owns WHERE GSD worktrees physically live.
|
|
3
|
+
*
|
|
4
|
+
* Canonical placement: `<projectRoot>/.gsd-worktrees/<name>` — a real
|
|
5
|
+
* directory that never crosses the `.gsd` symlink managed by repo-identity.
|
|
6
|
+
* Under the external-state layout (`.gsd → ~/.gsd/projects/<hash>/`), the
|
|
7
|
+
* legacy `.gsd/worktrees/` location materialised worktrees inside the user's
|
|
8
|
+
* home directory behind an opaque hash path; the canonical sibling keeps the
|
|
9
|
+
* working copy at the project root regardless of where `.gsd` state lives.
|
|
10
|
+
*
|
|
11
|
+
* Legacy placement (`<projectRoot>/.gsd/worktrees/<name>`, possibly resolving
|
|
12
|
+
* through the symlink to `~/.gsd/projects/<hash>/worktrees/<name>`) stays
|
|
13
|
+
* recognized so in-flight milestones keep working across upgrades:
|
|
14
|
+
* - creation always uses the canonical location;
|
|
15
|
+
* - resolution prefers an existing legacy worktree for the same name;
|
|
16
|
+
* - containment checks accept membership in either location.
|
|
17
|
+
*
|
|
18
|
+
* Path → project identification lives in worktree-root.ts; this module owns
|
|
19
|
+
* only the forward direction (project + name → physical path).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { existsSync } from "node:fs";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
|
|
25
|
+
/** Directory name of the canonical worktrees container at the project root. */
|
|
26
|
+
export const CANONICAL_WORKTREES_DIRNAME = ".gsd-worktrees";
|
|
27
|
+
|
|
28
|
+
/** Canonical container for newly created worktrees. Never crosses the `.gsd` symlink. */
|
|
29
|
+
export function canonicalWorktreesDir(projectRoot: string): string {
|
|
30
|
+
return join(projectRoot, CANONICAL_WORKTREES_DIRNAME);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Legacy container (`.gsd/worktrees/`) — may resolve through the external-state symlink. */
|
|
34
|
+
export function legacyWorktreesDir(projectRoot: string): string {
|
|
35
|
+
return join(projectRoot, ".gsd", "worktrees");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* All containers a GSD worktree may live in, canonical first.
|
|
40
|
+
* Use for listing, scanning, and containment checks.
|
|
41
|
+
*/
|
|
42
|
+
export function worktreesDirs(projectRoot: string): string[] {
|
|
43
|
+
return [canonicalWorktreesDir(projectRoot), legacyWorktreesDir(projectRoot)];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Physical path for the worktree `name` under `projectRoot`.
|
|
48
|
+
*
|
|
49
|
+
* Canonical wins only when it has a `.git` marker (i.e. is a live worktree).
|
|
50
|
+
* A bare directory with no `.git` — a stale leftover from an aborted create
|
|
51
|
+
* or a partial cleanup — does not shadow an existing legacy worktree, so the
|
|
52
|
+
* legacy path is tried next. The legacy check remains a plain existsSync;
|
|
53
|
+
* callers that need a *registered* worktree validate the `.git` marker
|
|
54
|
+
* themselves (resolveCanonicalMilestoneRoot, getAutoWorktreePath).
|
|
55
|
+
* Falls back to canonical for new-worktree creation when neither path exists.
|
|
56
|
+
*/
|
|
57
|
+
export function worktreePathFor(projectRoot: string, name: string): string {
|
|
58
|
+
const canonical = join(canonicalWorktreesDir(projectRoot), name);
|
|
59
|
+
if (existsSync(canonical) && existsSync(join(canonical, ".git"))) return canonical;
|
|
60
|
+
const legacy = join(legacyWorktreesDir(projectRoot), name);
|
|
61
|
+
if (existsSync(legacy)) return legacy;
|
|
62
|
+
return canonical;
|
|
63
|
+
}
|
|
@@ -10,7 +10,7 @@ import { readdirSync } from "node:fs";
|
|
|
10
10
|
|
|
11
11
|
import { enterAutoWorktree, getAutoWorktreePath } from "./auto-worktree.js";
|
|
12
12
|
import { getIsolationMode } from "./preferences.js";
|
|
13
|
-
import {
|
|
13
|
+
import { allWorktreesDirs } from "./worktree-manager.js";
|
|
14
14
|
import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
|
|
15
15
|
|
|
16
16
|
interface LiveWorktree {
|
|
@@ -19,15 +19,18 @@ interface LiveWorktree {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Enumerate the live (valid git) auto-worktrees
|
|
22
|
+
* Enumerate the live (valid git) auto-worktrees in the project's worktree
|
|
23
|
+
* containers (canonical .gsd-worktrees/ and legacy .gsd/worktrees/).
|
|
23
24
|
* Reuses getAutoWorktreePath's validation so stray directories are ignored.
|
|
24
25
|
*/
|
|
25
26
|
function liveMilestoneWorktrees(projectRoot: string): LiveWorktree[] {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
const names = new Set<string>();
|
|
28
|
+
for (const dir of allWorktreesDirs(projectRoot)) {
|
|
29
|
+
try {
|
|
30
|
+
for (const name of readdirSync(dir)) names.add(name);
|
|
31
|
+
} catch {
|
|
32
|
+
// container absent — skip
|
|
33
|
+
}
|
|
31
34
|
}
|
|
32
35
|
const live: LiveWorktree[] = [];
|
|
33
36
|
for (const id of names) {
|
|
@@ -20,10 +20,17 @@ export function normalizeWorktreePathForCompare(path: string): string {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Find the GSD worktree segment in
|
|
24
|
-
*
|
|
23
|
+
* Find the GSD worktree segment in the canonical layout (.gsd-worktrees/),
|
|
24
|
+
* the legacy direct layout (.gsd/worktrees/), and the symlink-resolved
|
|
25
|
+
* external-state layout used by ~/.gsd/projects/<hash>.
|
|
25
26
|
*/
|
|
26
27
|
export function findWorktreeSegment(normalizedPath: string): WorktreeSegment | null {
|
|
28
|
+
const canonicalMarker = "/.gsd-worktrees/";
|
|
29
|
+
const canonicalIdx = normalizedPath.indexOf(canonicalMarker);
|
|
30
|
+
if (canonicalIdx !== -1) {
|
|
31
|
+
return { gsdIdx: canonicalIdx, afterWorktrees: canonicalIdx + canonicalMarker.length };
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
const directMarker = "/.gsd/worktrees/";
|
|
28
35
|
const directIdx = normalizedPath.indexOf(directMarker);
|
|
29
36
|
if (directIdx !== -1) {
|
|
@@ -72,7 +79,8 @@ export function isGsdWorktreePath(path: string): boolean {
|
|
|
72
79
|
export function resolveExternalStateProjectGsdFromWorktreePath(projectPath: string): string | null {
|
|
73
80
|
const normalized = resolve(projectPath).replaceAll("\\", "/");
|
|
74
81
|
|
|
75
|
-
//
|
|
82
|
+
// Canonical/direct layouts — parent state is resolved via repoIdentity(git root).
|
|
83
|
+
if (normalized.includes("/.gsd-worktrees/")) return null;
|
|
76
84
|
if (normalized.includes("/.gsd/worktrees/") && !normalized.includes("/.gsd/projects/")) {
|
|
77
85
|
return null;
|
|
78
86
|
}
|
|
@@ -139,12 +147,15 @@ function resolveProjectRootFromPath(path: string): string {
|
|
|
139
147
|
return resolveNearestBootstrappedGsdRoot(path) ?? resolveGitWorkingTreeRoot(path) ?? path;
|
|
140
148
|
}
|
|
141
149
|
|
|
150
|
+
// Slice at the first `.gsd` boundary, but never past the worktree segment:
|
|
151
|
+
// in the canonical layout (`<root>/.gsd-worktrees/<MID>/.gsd/...`) the first
|
|
152
|
+
// `/.gsd/` occurrence is the worktree-local projection dir, not the project
|
|
153
|
+
// root's state dir.
|
|
142
154
|
const sepChar = path.includes("\\") ? "\\" : "/";
|
|
143
155
|
const gsdMarker = `${sepChar}.gsd${sepChar}`;
|
|
144
156
|
const markerIdx = path.indexOf(gsdMarker);
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
: path.slice(0, segment.gsdIdx);
|
|
157
|
+
const sliceIdx = markerIdx !== -1 ? Math.min(markerIdx, segment.gsdIdx) : segment.gsdIdx;
|
|
158
|
+
const candidate = path.slice(0, sliceIdx);
|
|
148
159
|
|
|
149
160
|
const gsdHomeNorm = normalizeWorktreePathForCompare(gsdHome());
|
|
150
161
|
const candidateGsdPath = normalizeWorktreePathForCompare(join(candidate, ".gsd"));
|
|
@@ -6,6 +6,7 @@ import { execFileSync } from "node:child_process";
|
|
|
6
6
|
import { join, resolve } from "node:path";
|
|
7
7
|
|
|
8
8
|
import { normalizeWorktreePathForCompare } from "./worktree-root.js";
|
|
9
|
+
import { worktreesDirs } from "./worktree-placement.js";
|
|
9
10
|
import { listWorktrees } from "./worktree-manager.js";
|
|
10
11
|
import { getCurrentBranch } from "./worktree.js";
|
|
11
12
|
|
|
@@ -158,10 +159,12 @@ export function createWorktreeSafetyModule(
|
|
|
158
159
|
const projectRoot = resolve(input.projectRoot);
|
|
159
160
|
const unitRoot = resolve(input.unitRoot);
|
|
160
161
|
const isolationMode = input.isolationMode ?? "worktree";
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
// A milestone worktree may live in the canonical container or the
|
|
163
|
+
// legacy one (pre-placement-change worktrees keep their location).
|
|
164
|
+
const expectedRoots = isolationMode === "worktree"
|
|
165
|
+
? worktreesDirs(projectRoot).map((dir) => join(dir, milestoneId))
|
|
166
|
+
: [projectRoot];
|
|
167
|
+
if (!expectedRoots.some((expectedRoot) => samePath(unitRoot, expectedRoot))) {
|
|
165
168
|
return failure(
|
|
166
169
|
"invalid-root",
|
|
167
170
|
isolationMode === "worktree"
|
|
@@ -170,7 +173,7 @@ export function createWorktreeSafetyModule(
|
|
|
170
173
|
isolationMode === "worktree"
|
|
171
174
|
? "Prepare the Unit in its canonical milestone worktree before allowing source writes."
|
|
172
175
|
: "Run the Unit from the project root when worktree isolation is disabled.",
|
|
173
|
-
{ expectedRoot, unitRoot },
|
|
176
|
+
{ expectedRoot: expectedRoots[0], unitRoot },
|
|
174
177
|
);
|
|
175
178
|
}
|
|
176
179
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// GSD worktree session state
|
|
2
|
+
import { findWorktreeSegment } from "./worktree-root.js";
|
|
3
|
+
|
|
2
4
|
let originalCwd: string | null = null;
|
|
3
5
|
|
|
4
6
|
export function getWorktreeOriginalCwd(): string | null {
|
|
@@ -15,21 +17,21 @@ export function clearWorktreeOriginalCwd(): void {
|
|
|
15
17
|
|
|
16
18
|
export function ensureWorktreeOriginalCwdFromPath(cwd: string = process.cwd()): string | null {
|
|
17
19
|
if (originalCwd) return originalCwd;
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
originalCwd = cwd.slice(0, markerIdx);
|
|
20
|
+
const segment = findWorktreeSegment(cwd.replaceAll("\\", "/"));
|
|
21
|
+
if (segment) {
|
|
22
|
+
originalCwd = cwd.slice(0, segment.gsdIdx);
|
|
22
23
|
}
|
|
23
24
|
return originalCwd;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export function getActiveWorktreeName(): string | null {
|
|
27
28
|
if (!originalCwd) return null;
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
if (!
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
const normalizedCwd = process.cwd().replaceAll("\\", "/");
|
|
30
|
+
const normalizedOriginal = originalCwd.replace(/[\\/]+$/, "").replaceAll("\\", "/");
|
|
31
|
+
const segment = findWorktreeSegment(normalizedCwd);
|
|
32
|
+
if (!segment) return null;
|
|
33
|
+
// Only treat the cwd as an active worktree of OUR project root.
|
|
34
|
+
if (normalizedCwd.slice(0, segment.gsdIdx) !== normalizedOriginal) return null;
|
|
35
|
+
const name = normalizedCwd.slice(segment.afterWorktrees).split("/")[0];
|
|
34
36
|
return name || null;
|
|
35
37
|
}
|
|
@@ -74,6 +74,30 @@ const VERDICT_RE = /verdict:\s*[\w-]+/i;
|
|
|
74
74
|
* Only overwrites when the source has a verdict — never clobbers a
|
|
75
75
|
* worktree ASSESSMENT with a verdictless project-root copy.
|
|
76
76
|
*/
|
|
77
|
+
function forceOverwriteValidationWithVerdict(
|
|
78
|
+
srcMilestoneDir: string,
|
|
79
|
+
dstMilestoneDir: string,
|
|
80
|
+
milestoneId: string,
|
|
81
|
+
): void {
|
|
82
|
+
if (!existsSync(srcMilestoneDir) || !milestoneId) return;
|
|
83
|
+
|
|
84
|
+
const srcFile = join(srcMilestoneDir, `${milestoneId}-VALIDATION.md`);
|
|
85
|
+
if (!existsSync(srcFile)) return;
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const srcContent = readFileSync(srcFile, "utf-8");
|
|
89
|
+
if (!VERDICT_RE.test(srcContent)) return;
|
|
90
|
+
|
|
91
|
+
mkdirSync(dstMilestoneDir, { recursive: true });
|
|
92
|
+
safeCopy(srcFile, join(dstMilestoneDir, `${milestoneId}-VALIDATION.md`), { force: true });
|
|
93
|
+
} catch (err) {
|
|
94
|
+
logWarning(
|
|
95
|
+
"worktree",
|
|
96
|
+
`validation force-copy failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
77
101
|
function forceOverwriteAssessmentsWithVerdict(
|
|
78
102
|
srcMilestoneDir: string,
|
|
79
103
|
dstMilestoneDir: string,
|
|
@@ -260,10 +284,10 @@ export function _projectRootToWorktreeImpl(
|
|
|
260
284
|
// session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
|
|
261
285
|
// persists, checkNeedsRunUat finds no passing verdict → re-dispatches
|
|
262
286
|
// run-uat indefinitely (stuck-loop ×9).
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
);
|
|
287
|
+
const prMilestoneDir = join(prGsd, "milestones", milestoneId);
|
|
288
|
+
const wtMilestoneDir = join(wtGsd, "milestones", milestoneId);
|
|
289
|
+
forceOverwriteValidationWithVerdict(prMilestoneDir, wtMilestoneDir, milestoneId);
|
|
290
|
+
forceOverwriteAssessmentsWithVerdict(prMilestoneDir, wtMilestoneDir);
|
|
267
291
|
|
|
268
292
|
// Forward-sync completed-units.json from project root to worktree.
|
|
269
293
|
// Project root is authoritative for completion state after crash recovery;
|
|
@@ -442,25 +466,41 @@ export class WorktreeStateProjection {
|
|
|
442
466
|
* any Unit dispatches.
|
|
443
467
|
*/
|
|
444
468
|
projectRootToWorktree(scope: MilestoneScope): void {
|
|
445
|
-
|
|
469
|
+
this.projectRootToWorktreePaths(
|
|
446
470
|
scope.workspace.projectRoot,
|
|
447
471
|
scope.workspace.worktreeRoot ?? scope.workspace.projectRoot,
|
|
448
472
|
scope.milestoneId,
|
|
449
473
|
);
|
|
450
474
|
}
|
|
451
475
|
|
|
476
|
+
projectRootToWorktreePaths(
|
|
477
|
+
projectRoot: string,
|
|
478
|
+
worktreePath: string,
|
|
479
|
+
milestoneId: string | null,
|
|
480
|
+
): void {
|
|
481
|
+
_projectRootToWorktreeImpl(projectRoot, worktreePath, milestoneId);
|
|
482
|
+
}
|
|
483
|
+
|
|
452
484
|
/**
|
|
453
485
|
* Project state from the auto-worktree back onto the project root for `scope`.
|
|
454
486
|
* Called by the post-unit pipeline between Units.
|
|
455
487
|
*/
|
|
456
488
|
projectWorktreeToRoot(scope: MilestoneScope): void {
|
|
457
|
-
|
|
489
|
+
this.projectWorktreeToRootPaths(
|
|
458
490
|
scope.workspace.worktreeRoot ?? scope.workspace.projectRoot,
|
|
459
491
|
scope.workspace.projectRoot,
|
|
460
492
|
scope.milestoneId,
|
|
461
493
|
);
|
|
462
494
|
}
|
|
463
495
|
|
|
496
|
+
projectWorktreeToRootPaths(
|
|
497
|
+
worktreePath: string,
|
|
498
|
+
projectRoot: string,
|
|
499
|
+
milestoneId: string | null,
|
|
500
|
+
): void {
|
|
501
|
+
_projectWorktreeToRootImpl(worktreePath, projectRoot, milestoneId);
|
|
502
|
+
}
|
|
503
|
+
|
|
464
504
|
/**
|
|
465
505
|
* Final projection from the auto-worktree to the project root before
|
|
466
506
|
* teardown. Called by Lifecycle's exit path after a successful merge,
|
|
@@ -471,10 +511,18 @@ export class WorktreeStateProjection {
|
|
|
471
511
|
* telemetry on what crossed the boundary.
|
|
472
512
|
*/
|
|
473
513
|
finalizeProjectionForMerge(scope: MilestoneScope): { synced: string[] } {
|
|
474
|
-
return
|
|
514
|
+
return this.finalizeProjectionForMergePaths(
|
|
475
515
|
scope.workspace.projectRoot,
|
|
476
516
|
scope.workspace.worktreeRoot ?? scope.workspace.projectRoot,
|
|
477
517
|
scope.milestoneId,
|
|
478
518
|
);
|
|
479
519
|
}
|
|
520
|
+
|
|
521
|
+
finalizeProjectionForMergePaths(
|
|
522
|
+
projectRoot: string,
|
|
523
|
+
worktreePath: string,
|
|
524
|
+
milestoneId: string,
|
|
525
|
+
): { synced: string[] } {
|
|
526
|
+
return _finalizeProjectionForMergeImpl(projectRoot, worktreePath, milestoneId);
|
|
527
|
+
}
|
|
480
528
|
}
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
import { randomUUID } from "node:crypto";
|
|
23
23
|
import { emitJournalEvent, queryJournal } from "./journal.js";
|
|
24
24
|
import type { JournalEntry } from "./journal.js";
|
|
25
|
+
import type { AutoTerminalOutcome } from "./auto/contracts.js";
|
|
25
26
|
|
|
26
27
|
function now(): string {
|
|
27
28
|
return new Date().toISOString();
|
|
@@ -91,6 +92,21 @@ export function normalizeAutoExitReason(rawReason?: string): AutoExitReason {
|
|
|
91
92
|
: "other";
|
|
92
93
|
}
|
|
93
94
|
|
|
95
|
+
export function autoExitReasonForTerminalOutcome(
|
|
96
|
+
outcome: AutoTerminalOutcome | undefined,
|
|
97
|
+
): AutoExitReason | null {
|
|
98
|
+
switch (outcome?.code) {
|
|
99
|
+
case "all-complete":
|
|
100
|
+
return "all-complete";
|
|
101
|
+
case "settlement-blocked":
|
|
102
|
+
return "blocked";
|
|
103
|
+
case "no-remaining-units":
|
|
104
|
+
return "stop";
|
|
105
|
+
default:
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
94
110
|
// ─── Emitters ────────────────────────────────────────────────────────────
|
|
95
111
|
|
|
96
112
|
export function emitWorktreeCreated(
|
|
@@ -62,6 +62,13 @@ export interface RoundResult {
|
|
|
62
62
|
/** Always false — end is handled by showWrapUpScreen, not per-question */
|
|
63
63
|
endInterview: false;
|
|
64
64
|
answers: Record<string, { selected: string | string[]; notes: string }>;
|
|
65
|
+
/**
|
|
66
|
+
* Set to true only when the round ended because the external AbortSignal
|
|
67
|
+
* fired (e.g. a system/host teardown), as distinct from a deliberate user
|
|
68
|
+
* dismissal. Consumers use this to avoid laundering a system teardown into a
|
|
69
|
+
* clean user-declined cancel. Additive/optional — native consumers ignore it.
|
|
70
|
+
*/
|
|
71
|
+
interrupted?: boolean;
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
export interface WrapUpResult {
|
|
@@ -97,6 +104,12 @@ export interface InterviewRoundOptions {
|
|
|
97
104
|
* Defaults to "end interview".
|
|
98
105
|
*/
|
|
99
106
|
exitLabel?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Render as a floating overlay instead of replacing the editor. Use when the
|
|
109
|
+
* interview must stay visible during an in-flight agent stream (e.g. claude-code-cli
|
|
110
|
+
* MCP elicitation).
|
|
111
|
+
*/
|
|
112
|
+
overlay?: boolean;
|
|
100
113
|
}
|
|
101
114
|
|
|
102
115
|
export interface WrapUpOptions {
|
|
@@ -240,7 +253,7 @@ export async function showInterviewRound(
|
|
|
240
253
|
|
|
241
254
|
// External cancellation (e.g. remote channel won the race)
|
|
242
255
|
if (opts.signal) {
|
|
243
|
-
const onAbort = () => finish({ endInterview: false, answers: {} });
|
|
256
|
+
const onAbort = () => finish({ endInterview: false, answers: {}, interrupted: true });
|
|
244
257
|
if (opts.signal.aborted) { onAbort(); }
|
|
245
258
|
else {
|
|
246
259
|
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
@@ -845,5 +858,5 @@ export async function showInterviewRound(
|
|
|
845
858
|
invalidate: () => { cachedLines = undefined; },
|
|
846
859
|
handleInput,
|
|
847
860
|
};
|
|
848
|
-
});
|
|
861
|
+
}, opts.overlay ? { overlay: true } : undefined);
|
|
849
862
|
}
|