@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
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import { existsSync, realpathSync } from "node:fs";
|
|
3
|
-
import { dirname, resolve, sep } from "node:path";
|
|
3
|
+
import { basename, dirname, resolve, sep } from "node:path";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import { getRequiredWorkflowToolsForUnit } from "./unit-tool-contracts.js";
|
|
6
|
+
import { mcpToolMatchesBaseName } from "./mcp-tool-name.js";
|
|
7
|
+
import {
|
|
8
|
+
supportsStructuredQuestions,
|
|
9
|
+
usesWorkflowMcpTransport,
|
|
10
|
+
} from "./question-transport.js";
|
|
11
|
+
import {
|
|
12
|
+
WORKFLOW_TOOL_SURFACE_NAMES,
|
|
13
|
+
isWorkflowToolSurfaceName,
|
|
14
|
+
} from "./workflow-tool-surface.js";
|
|
15
|
+
|
|
16
|
+
export { supportsStructuredQuestions, usesWorkflowMcpTransport };
|
|
6
17
|
|
|
7
18
|
type WorkflowExecutorsModule = typeof import("./tools/workflow-tool-executors.js");
|
|
8
19
|
|
|
@@ -42,73 +53,9 @@ export function resolveWorkflowMcpProjectRoot(sessionCwd: string): string {
|
|
|
42
53
|
return resolved;
|
|
43
54
|
}
|
|
44
55
|
|
|
45
|
-
const MCP_WORKFLOW_TOOL_SURFACE = new Set([
|
|
46
|
-
"gsd_cancel",
|
|
47
|
-
"gsd_captures",
|
|
48
|
-
"ask_user_questions",
|
|
49
|
-
"gsd_capture_thought",
|
|
50
|
-
"gsd_doctor",
|
|
51
|
-
"gsd_execute",
|
|
52
|
-
"gsd_memory_query",
|
|
53
|
-
"gsd_memory_graph",
|
|
54
|
-
"gsd_decision_save",
|
|
55
|
-
"gsd_exec",
|
|
56
|
-
"gsd_exec_search",
|
|
57
|
-
"gsd_graph",
|
|
58
|
-
"gsd_history",
|
|
59
|
-
"gsd_knowledge",
|
|
60
|
-
"gsd_progress",
|
|
61
|
-
"gsd_query",
|
|
62
|
-
"gsd_resume",
|
|
63
|
-
"gsd_result",
|
|
64
|
-
"gsd_resolve_blocker",
|
|
65
|
-
"gsd_roadmap",
|
|
66
|
-
"gsd_status",
|
|
67
|
-
"gsd_complete_milestone",
|
|
68
|
-
"gsd_complete_task",
|
|
69
|
-
"gsd_complete_slice",
|
|
70
|
-
"gsd_generate_milestone_id",
|
|
71
|
-
"gsd_journal_query",
|
|
72
|
-
"gsd_milestone_complete",
|
|
73
|
-
"gsd_milestone_generate_id",
|
|
74
|
-
"gsd_milestone_reopen",
|
|
75
|
-
"gsd_checkpoint_db",
|
|
76
|
-
"gsd_milestone_plan",
|
|
77
|
-
"gsd_milestone_status",
|
|
78
|
-
"gsd_milestone_validate",
|
|
79
|
-
"gsd_plan_task",
|
|
80
|
-
"gsd_plan_milestone",
|
|
81
|
-
"gsd_plan_slice",
|
|
82
|
-
"gsd_replan_slice",
|
|
83
|
-
"gsd_reassess_roadmap",
|
|
84
|
-
"gsd_reopen_milestone",
|
|
85
|
-
"gsd_reopen_slice",
|
|
86
|
-
"gsd_reopen_task",
|
|
87
|
-
"gsd_requirement_save",
|
|
88
|
-
"gsd_requirement_update",
|
|
89
|
-
"gsd_roadmap_reassess",
|
|
90
|
-
"gsd_save_decision",
|
|
91
|
-
"gsd_save_gate_result",
|
|
92
|
-
"gsd_save_requirement",
|
|
93
|
-
"gsd_save_summary",
|
|
94
|
-
"gsd_skip_slice",
|
|
95
|
-
"gsd_slice_plan",
|
|
96
|
-
"gsd_slice_replan",
|
|
97
|
-
"gsd_slice_complete",
|
|
98
|
-
"gsd_slice_reopen",
|
|
99
|
-
"gsd_summary_save",
|
|
100
|
-
"gsd_task_plan",
|
|
101
|
-
"gsd_task_complete",
|
|
102
|
-
"gsd_task_reopen",
|
|
103
|
-
"gsd_update_requirement",
|
|
104
|
-
"gsd_uat_exec",
|
|
105
|
-
"gsd_uat_result_save",
|
|
106
|
-
"gsd_validate_milestone",
|
|
107
|
-
]);
|
|
108
|
-
|
|
109
56
|
/** Workflow MCP tools are validated by transport compatibility, not pi tool-compat profiles. */
|
|
110
57
|
export function isWorkflowMcpSurfaceTool(toolName: string): boolean {
|
|
111
|
-
return
|
|
58
|
+
return isWorkflowToolSurfaceName(toolName);
|
|
112
59
|
}
|
|
113
60
|
|
|
114
61
|
function parseLookupOutput(output: Buffer | string): string {
|
|
@@ -276,8 +223,12 @@ function getBundledWorkflowWriteGateModulePath(): string | null {
|
|
|
276
223
|
|
|
277
224
|
function getResolveTsHookPath(): string | null {
|
|
278
225
|
const repoRoot = findGsdPiRepoRoot(dirname(fileURLToPath(import.meta.url)));
|
|
226
|
+
const sourceRepoRoot = repoRoot && basename(repoRoot) === "dist-test" ? dirname(repoRoot) : repoRoot;
|
|
279
227
|
return firstExistingPath([
|
|
280
|
-
...(
|
|
228
|
+
...(sourceRepoRoot
|
|
229
|
+
? [resolve(sourceRepoRoot, "src", "resources", "extensions", "gsd", "tests", "resolve-ts.mjs")]
|
|
230
|
+
: []),
|
|
231
|
+
...(repoRoot && repoRoot !== sourceRepoRoot
|
|
281
232
|
? [resolve(repoRoot, "src", "resources", "extensions", "gsd", "tests", "resolve-ts.mjs")]
|
|
282
233
|
: []),
|
|
283
234
|
resolve(fileURLToPath(new URL("./tests/resolve-ts.mjs", import.meta.url))),
|
|
@@ -421,52 +372,13 @@ export function getRequiredWorkflowToolsForAutoUnit(unitType: string): string[]
|
|
|
421
372
|
return getRequiredWorkflowToolsForUnit(unitType);
|
|
422
373
|
}
|
|
423
374
|
|
|
424
|
-
export function usesWorkflowMcpTransport(
|
|
425
|
-
authMode: WorkflowCapabilityOptions["authMode"],
|
|
426
|
-
baseUrl: string | undefined,
|
|
427
|
-
): boolean {
|
|
428
|
-
return authMode === "externalCli" && typeof baseUrl === "string" && baseUrl.startsWith("local://");
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
function hasAskUserQuestionsTool(activeTools: string[]): boolean {
|
|
432
|
-
return activeTools.some((toolName) => {
|
|
433
|
-
if (toolName === "ask_user_questions") return true;
|
|
434
|
-
if (!toolName.startsWith("mcp__")) return false;
|
|
435
|
-
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
436
|
-
return toolSeparator >= 0 && toolName.slice(toolSeparator + 2) === "ask_user_questions";
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
|
|
440
375
|
function hasRequiredTool(requiredTool: string, activeTools: string[]): boolean {
|
|
441
376
|
return activeTools.some((toolName) => {
|
|
442
377
|
if (toolName === requiredTool) return true;
|
|
443
|
-
|
|
444
|
-
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
445
|
-
return toolSeparator >= 0 && toolName.slice(toolSeparator + 2) === requiredTool;
|
|
378
|
+
return mcpToolMatchesBaseName(toolName, requiredTool);
|
|
446
379
|
});
|
|
447
380
|
}
|
|
448
381
|
|
|
449
|
-
function workflowMcpStructuredQuestionsOptIn(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
450
|
-
const value = env.GSD_WORKFLOW_MCP_STRUCTURED_QUESTIONS;
|
|
451
|
-
return value === "1" || value === "true";
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
export function supportsStructuredQuestions(
|
|
455
|
-
activeTools: string[],
|
|
456
|
-
options: Pick<WorkflowCapabilityOptions, "authMode" | "baseUrl" | "env"> = {},
|
|
457
|
-
): boolean {
|
|
458
|
-
if (!hasAskUserQuestionsTool(activeTools)) return false;
|
|
459
|
-
if (usesWorkflowMcpTransport(options.authMode, options.baseUrl)) {
|
|
460
|
-
// Claude Code local workflow-MCP exposes ask_user_questions, but form
|
|
461
|
-
// elicitation can return an immediate cancel outside GSD's chat turn. Keep
|
|
462
|
-
// checkpoints in plain chat unless a caller deliberately opts into testing
|
|
463
|
-
// that transport.
|
|
464
|
-
return workflowMcpStructuredQuestionsOptIn(options.env);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
return true;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
382
|
export function getWorkflowTransportSupportError(
|
|
471
383
|
provider: string | undefined,
|
|
472
384
|
requiredTools: string[],
|
|
@@ -488,13 +400,13 @@ export function getWorkflowTransportSupportError(
|
|
|
488
400
|
|
|
489
401
|
const uniqueRequired = [...new Set(requiredTools)];
|
|
490
402
|
const missing = (options.activeTools && options.activeTools.length > 0)
|
|
491
|
-
? uniqueRequired.filter((tool) => !hasRequiredTool(tool, options.activeTools!))
|
|
492
|
-
: uniqueRequired.filter((tool) => !
|
|
403
|
+
? uniqueRequired.filter((tool) => !isWorkflowToolSurfaceName(tool) && !hasRequiredTool(tool, options.activeTools!))
|
|
404
|
+
: uniqueRequired.filter((tool) => !isWorkflowToolSurfaceName(tool));
|
|
493
405
|
if (missing.length === 0) return null;
|
|
494
406
|
|
|
495
407
|
if (options.activeTools && options.activeTools.length > 0) {
|
|
496
408
|
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the active runtime toolset currently exposes only ${options.activeTools.slice().sort().join(", ")}.`;
|
|
497
409
|
}
|
|
498
410
|
|
|
499
|
-
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the workflow MCP transport currently exposes only ${
|
|
411
|
+
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the workflow MCP transport currently exposes only ${[...WORKFLOW_TOOL_SURFACE_NAMES].sort().join(", ")}.`;
|
|
500
412
|
}
|
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
getMilestoneSlices,
|
|
14
14
|
insertVerificationEvidence,
|
|
15
15
|
upsertDecision,
|
|
16
|
-
openDatabase,
|
|
17
16
|
setTaskBlockerDiscovered,
|
|
18
17
|
insertOrIgnoreSlice,
|
|
19
18
|
insertOrIgnoreTask,
|
|
20
19
|
} from "./gsd-db.js";
|
|
20
|
+
import { openWorkflowDatabasePath } from "./db-workspace.js";
|
|
21
21
|
import { isClosedStatus } from "./status-guards.js";
|
|
22
22
|
import { invalidateStateCache } from "./state.js";
|
|
23
23
|
import { clearPathCache, resolveGsdPathContract } from "./paths.js";
|
|
@@ -500,7 +500,7 @@ function _reconcileWorktreeLogsInner(
|
|
|
500
500
|
atomicWriteSync(join(mainBasePath, ".gsd", "event-log.jsonl"), logContent);
|
|
501
501
|
|
|
502
502
|
// Step 8: Replay into DB (wrapped in a transaction by replayEvents)
|
|
503
|
-
|
|
503
|
+
openWorkflowDatabasePath(resolveGsdPathContract(mainBasePath).projectDb);
|
|
504
504
|
replayEvents(merged);
|
|
505
505
|
|
|
506
506
|
// Step 9: Write manifest
|
|
@@ -655,7 +655,7 @@ export function resolveConflict(
|
|
|
655
655
|
writeEventLog(targetBasePath, targetBaseEvents.concat(rewrittenTargetEvents));
|
|
656
656
|
|
|
657
657
|
// Replay resolved events through the DB (updates DB state)
|
|
658
|
-
|
|
658
|
+
openWorkflowDatabasePath(resolveGsdPathContract(basePath).projectDb);
|
|
659
659
|
replayEvents(eventsToReplay);
|
|
660
660
|
invalidateStateCache();
|
|
661
661
|
clearPathCache();
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Adapts shared workflow tool contracts into the extension runtime surface.
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
CANONICAL_WORKFLOW_TOOL_NAMES as CONTRACT_CANONICAL_WORKFLOW_TOOL_NAMES,
|
|
6
|
+
WORKFLOW_TOOL_ALIAS_NAMES as CONTRACT_WORKFLOW_TOOL_ALIAS_NAMES,
|
|
7
|
+
WORKFLOW_TOOL_CONTRACTS as CONTRACT_WORKFLOW_TOOL_CONTRACTS,
|
|
8
|
+
WORKFLOW_TOOL_NAMES as CONTRACT_WORKFLOW_TOOL_NAMES,
|
|
9
|
+
} from "@opengsd/contracts";
|
|
10
|
+
import { stripMcpToolPrefix } from "./mcp-tool-name.js";
|
|
11
|
+
|
|
12
|
+
export interface WorkflowToolAliasPair {
|
|
13
|
+
canonical: string;
|
|
14
|
+
alias: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const WORKFLOW_TOOL_CONTRACTS = CONTRACT_WORKFLOW_TOOL_CONTRACTS;
|
|
18
|
+
|
|
19
|
+
export const CANONICAL_WORKFLOW_TOOL_NAMES = CONTRACT_CANONICAL_WORKFLOW_TOOL_NAMES;
|
|
20
|
+
export const WORKFLOW_TOOL_ALIAS_NAMES = CONTRACT_WORKFLOW_TOOL_ALIAS_NAMES;
|
|
21
|
+
export const DB_WORKFLOW_TOOL_NAMES = CONTRACT_WORKFLOW_TOOL_NAMES;
|
|
22
|
+
|
|
23
|
+
export const WORKFLOW_TOOL_ALIAS_PAIRS: readonly WorkflowToolAliasPair[] =
|
|
24
|
+
WORKFLOW_TOOL_CONTRACTS.flatMap((tool) =>
|
|
25
|
+
tool.aliases.map((alias) => ({ canonical: tool.canonicalName, alias })),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export const WORKFLOW_TOOL_ALIAS_TO_CANONICAL: Readonly<Record<string, string>> =
|
|
29
|
+
Object.fromEntries(WORKFLOW_TOOL_ALIAS_PAIRS.map(({ alias, canonical }) => [alias, canonical]));
|
|
30
|
+
|
|
31
|
+
const WORKFLOW_MCP_ADAPTER_TOOL_NAMES = [
|
|
32
|
+
"gsd_cancel",
|
|
33
|
+
"gsd_captures",
|
|
34
|
+
"ask_user_questions",
|
|
35
|
+
"gsd_doctor",
|
|
36
|
+
"gsd_execute",
|
|
37
|
+
"gsd_graph",
|
|
38
|
+
"gsd_history",
|
|
39
|
+
"gsd_knowledge",
|
|
40
|
+
"gsd_progress",
|
|
41
|
+
"gsd_query",
|
|
42
|
+
"gsd_result",
|
|
43
|
+
"gsd_resolve_blocker",
|
|
44
|
+
"gsd_roadmap",
|
|
45
|
+
"gsd_status",
|
|
46
|
+
] as const;
|
|
47
|
+
|
|
48
|
+
export const WORKFLOW_TOOL_SURFACE_NAMES = [
|
|
49
|
+
...WORKFLOW_MCP_ADAPTER_TOOL_NAMES,
|
|
50
|
+
...DB_WORKFLOW_TOOL_NAMES,
|
|
51
|
+
] as readonly string[];
|
|
52
|
+
|
|
53
|
+
const WORKFLOW_TOOL_SURFACE_NAME_SET = new Set(WORKFLOW_TOOL_SURFACE_NAMES);
|
|
54
|
+
|
|
55
|
+
export { stripMcpToolPrefix } from "./mcp-tool-name.js";
|
|
56
|
+
|
|
57
|
+
export function canonicalWorkflowSurfaceToolName(toolName: string): string {
|
|
58
|
+
const baseName = stripMcpToolPrefix(toolName);
|
|
59
|
+
return WORKFLOW_TOOL_ALIAS_TO_CANONICAL[baseName] ?? baseName;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function isWorkflowSurfaceAliasTool(toolName: string): boolean {
|
|
63
|
+
const baseName = stripMcpToolPrefix(toolName);
|
|
64
|
+
return WORKFLOW_TOOL_ALIAS_TO_CANONICAL[baseName] !== undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function isWorkflowToolSurfaceName(toolName: string): boolean {
|
|
68
|
+
return WORKFLOW_TOOL_SURFACE_NAME_SET.has(stripMcpToolPrefix(toolName));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function aliasesForWorkflowTool(canonicalName: string): readonly string[] {
|
|
72
|
+
return WORKFLOW_TOOL_CONTRACTS.find((tool) => tool.canonicalName === canonicalName)?.aliases ?? [];
|
|
73
|
+
}
|
|
@@ -14,6 +14,7 @@ export function isWorkspaceGitAllowedCommand(trimmed: string): boolean {
|
|
|
14
14
|
|
|
15
15
|
const [name, subcommand] = command.split(/\s+/, 2);
|
|
16
16
|
if (name === "doctor") return true;
|
|
17
|
+
if (name === "forensics") return true;
|
|
17
18
|
if (name === "closeout" || command.startsWith("closeout")) return true;
|
|
18
19
|
if (name === "dispatch") {
|
|
19
20
|
return subcommand === "complete" || subcommand === "complete-milestone";
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Git checkout/stash/merge-state recovery primitives for worktree operations.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Worktree Git Recovery — the recurring-bug hot spot, in one place.
|
|
6
|
+
*
|
|
7
|
+
* Owns the verbs that recover a repository from interrupted or conflicting
|
|
8
|
+
* git operations during worktree transitions:
|
|
9
|
+
*
|
|
10
|
+
* - `checkoutBranchWithStashGuard` — branch switch with stash protection,
|
|
11
|
+
* including the stash-pop EEXIST collision recovery for `.gsd/` runtime
|
|
12
|
+
* files (force-checkout + targeted stash drop).
|
|
13
|
+
* - `removeMergeStateFiles` — clears SQUASH_MSG / MERGE_HEAD / etc. left by
|
|
14
|
+
* a failed merge so subsequent merges don't fail on stale state.
|
|
15
|
+
* - `cleanupConflictState` — merge-abort + index reset + state-file cleanup
|
|
16
|
+
* after a conflicted (including squash) merge.
|
|
17
|
+
* - stash helpers (`popStashByRef`, `stashRefFromError`,
|
|
18
|
+
* `stashAlreadyExistsFilesFromError`, `gsdJsonlFilesWithConflictMarkers`)
|
|
19
|
+
* used by the merge pipeline in auto-worktree.ts.
|
|
20
|
+
*
|
|
21
|
+
* Extracted from auto-worktree.ts so recovery fixes land here instead of as
|
|
22
|
+
* embedded special cases in a 2,600-line orchestration module, and so the
|
|
23
|
+
* rules can be tested against scripted git states.
|
|
24
|
+
*
|
|
25
|
+
* The State Reconciliation drift repair (`state-reconciliation/drift/
|
|
26
|
+
* merge-state.ts`) keeps its own merge-state primitive by design — drift
|
|
27
|
+
* repairs own their raw primitives (see CONTEXT.md, Drift repair).
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import { execFileSync } from "node:child_process";
|
|
31
|
+
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
32
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
33
|
+
|
|
34
|
+
import { debugLog } from "./debug-logger.js";
|
|
35
|
+
import { logError, logWarning } from "./workflow-logger.js";
|
|
36
|
+
import {
|
|
37
|
+
nativeAddPaths,
|
|
38
|
+
nativeCheckoutBranch,
|
|
39
|
+
nativeConflictFiles,
|
|
40
|
+
nativeLsFiles,
|
|
41
|
+
nativeMergeAbort,
|
|
42
|
+
nativeWorkingTreeStatus,
|
|
43
|
+
} from "./native-git-bridge.js";
|
|
44
|
+
import { resolveGitDir } from "./worktree-manager.js";
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Pop the stash entry created with `stashMarker` in its subject, resolving it
|
|
48
|
+
* to a concrete `stash@{n}` ref first so a concurrent stash push cannot make
|
|
49
|
+
* `git stash pop` grab the wrong entry.
|
|
50
|
+
*
|
|
51
|
+
* If `stashMarker` is null or no longer present in the stash list (e.g. a
|
|
52
|
+
* concurrent process popped/dropped it), leaves the stash list untouched and
|
|
53
|
+
* returns null.
|
|
54
|
+
*
|
|
55
|
+
* Throws on pop failure so callers can handle conflict cases the same way
|
|
56
|
+
* they would with the prior `git stash pop` form. When throwing after a
|
|
57
|
+
* targeted pop attempt, the error is annotated with the targeted stash ref.
|
|
58
|
+
*
|
|
59
|
+
* (Issue #4980 HIGH-6)
|
|
60
|
+
*/
|
|
61
|
+
export function popStashByRef(basePath: string, stashMarker: string | null): string | null {
|
|
62
|
+
let popArg: string | null = null;
|
|
63
|
+
if (stashMarker) {
|
|
64
|
+
try {
|
|
65
|
+
const list = execFileSync("git", ["stash", "list", "--format=%gd%x00%s"], {
|
|
66
|
+
cwd: basePath,
|
|
67
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
68
|
+
encoding: "utf-8",
|
|
69
|
+
}).trim().split("\n").filter(Boolean);
|
|
70
|
+
for (const entry of list) {
|
|
71
|
+
const [ref, subject] = entry.split("\0");
|
|
72
|
+
if (ref && subject?.includes(stashMarker)) {
|
|
73
|
+
popArg = ref;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
logWarning("worktree", `stash list lookup failed; leaving stash untouched: ${err instanceof Error ? err.message : String(err)}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (!popArg) {
|
|
82
|
+
logWarning("worktree", "recorded stash entry could not be resolved; skipping automatic pop");
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
execFileSync("git", ["stash", "pop", popArg], {
|
|
87
|
+
cwd: basePath,
|
|
88
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
89
|
+
encoding: "utf-8",
|
|
90
|
+
});
|
|
91
|
+
} catch (err) {
|
|
92
|
+
if (err && typeof err === "object") {
|
|
93
|
+
(err as { stashRef?: string }).stashRef = popArg;
|
|
94
|
+
}
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
return popArg;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Extract a stash ref annotation injected by popStashByRef() when git stash
|
|
102
|
+
* pop fails and we need to conditionally drop the exact stash entry later.
|
|
103
|
+
*/
|
|
104
|
+
export function stashRefFromError(err: unknown): string | null {
|
|
105
|
+
if (!err || typeof err !== "object") return null;
|
|
106
|
+
const stashRef = (err as { stashRef?: unknown }).stashRef;
|
|
107
|
+
return typeof stashRef === "string" && stashRef.length > 0 ? stashRef : null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function stashAlreadyExistsFilesFromError(err: unknown): string[] {
|
|
111
|
+
if (!err || typeof err !== "object") return [];
|
|
112
|
+
const stderr = (err as { stderr?: unknown }).stderr;
|
|
113
|
+
const stderrText = typeof stderr === "string"
|
|
114
|
+
? stderr
|
|
115
|
+
: stderr instanceof Uint8Array
|
|
116
|
+
? Buffer.from(stderr).toString("utf-8")
|
|
117
|
+
: "";
|
|
118
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119
|
+
const text = `${stderrText}\n${message}`;
|
|
120
|
+
const files = new Set<string>();
|
|
121
|
+
for (const line of text.split("\n")) {
|
|
122
|
+
const m = line.match(/^(.*?)\s+already exists, no checkout\s*$/i);
|
|
123
|
+
if (!m) continue;
|
|
124
|
+
const filePath = m[1]?.trim();
|
|
125
|
+
if (filePath) files.add(filePath);
|
|
126
|
+
}
|
|
127
|
+
return [...files];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Detect whether an on-disk file still contains unresolved merge conflict
|
|
132
|
+
* markers from a failed stash-pop or merge attempt.
|
|
133
|
+
*
|
|
134
|
+
* Returns false when the file cannot be read.
|
|
135
|
+
*/
|
|
136
|
+
export function hasConflictMarkers(filePath: string): boolean {
|
|
137
|
+
try {
|
|
138
|
+
const content = readFileSync(filePath, "utf-8");
|
|
139
|
+
return content.includes("<<<<<<<") && content.includes("=======") && content.includes(">>>>>>>");
|
|
140
|
+
} catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function gsdJsonlFilesWithConflictMarkers(basePath: string): string[] {
|
|
146
|
+
return nativeLsFiles(basePath, ".gsd/*.jsonl").filter((f) =>
|
|
147
|
+
hasConflictMarkers(join(basePath, f)),
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function removeMergeStateFiles(basePath: string, contextLabel: string): void {
|
|
152
|
+
try {
|
|
153
|
+
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_MODE", "MERGE_HEAD", "AUTO_MERGE"]) {
|
|
154
|
+
const rawPath = execFileSync("git", ["rev-parse", "--git-path", f], {
|
|
155
|
+
cwd: basePath,
|
|
156
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
157
|
+
encoding: "utf-8",
|
|
158
|
+
}).trim();
|
|
159
|
+
const p = rawPath.length > 0
|
|
160
|
+
? (isAbsolute(rawPath) ? rawPath : resolve(basePath, rawPath))
|
|
161
|
+
: join(resolveGitDir(basePath), f);
|
|
162
|
+
if (existsSync(p)) unlinkSync(p);
|
|
163
|
+
}
|
|
164
|
+
} catch (err) {
|
|
165
|
+
logError("worktree", `${contextLabel} merge state cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function cleanupConflictState(basePath: string): void {
|
|
170
|
+
// Merge conflicts can leave unmerged index entries; merge-abort alone is not
|
|
171
|
+
// enough for squash merges (MERGE_HEAD is never written). Reset the merge
|
|
172
|
+
// index, then remove merge message files that native/libgit2 paths may have
|
|
173
|
+
// created.
|
|
174
|
+
try {
|
|
175
|
+
nativeMergeAbort(basePath);
|
|
176
|
+
} catch (err) {
|
|
177
|
+
// MERGE_HEAD absent (squash merge path) — abort is a no-op, which is fine.
|
|
178
|
+
debugLog("conflict-cleanup:merge-abort-skipped", {
|
|
179
|
+
error: err instanceof Error ? err.message : String(err),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
execFileSync("git", ["reset", "--merge"], {
|
|
184
|
+
cwd: basePath,
|
|
185
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
186
|
+
encoding: "utf-8",
|
|
187
|
+
});
|
|
188
|
+
} catch (err) {
|
|
189
|
+
logError("worktree", `git reset --merge failed after merge conflict: ${err instanceof Error ? err.message : String(err)}`);
|
|
190
|
+
}
|
|
191
|
+
removeMergeStateFiles(basePath, "conflict");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function checkoutBranchWithStashGuard(
|
|
195
|
+
basePath: string,
|
|
196
|
+
branch: string,
|
|
197
|
+
reason: string,
|
|
198
|
+
): void {
|
|
199
|
+
let stashMarker: string | null = null;
|
|
200
|
+
let stashed = false;
|
|
201
|
+
|
|
202
|
+
const status = nativeWorkingTreeStatus(basePath).trim();
|
|
203
|
+
if (status.length > 0) {
|
|
204
|
+
stashMarker = `gsd-checkout-stash:${reason}:${process.pid}:${Date.now()}:${process.hrtime.bigint().toString(36)}`;
|
|
205
|
+
const stashListBefore = execFileSync("git", ["stash", "list"], {
|
|
206
|
+
cwd: basePath,
|
|
207
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
208
|
+
encoding: "utf-8",
|
|
209
|
+
});
|
|
210
|
+
execFileSync(
|
|
211
|
+
"git",
|
|
212
|
+
["stash", "push", "--include-untracked", "-m", `gsd: checkout stash [${stashMarker}]`],
|
|
213
|
+
{
|
|
214
|
+
cwd: basePath,
|
|
215
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
216
|
+
encoding: "utf-8",
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
const stashListAfter = execFileSync("git", ["stash", "list"], {
|
|
220
|
+
cwd: basePath,
|
|
221
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
222
|
+
encoding: "utf-8",
|
|
223
|
+
});
|
|
224
|
+
stashed = stashListAfter !== stashListBefore;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Checkout and stash-restore are split so we can distinguish two failure
|
|
228
|
+
// modes: (a) checkout failed → HEAD did not move, restore stash and rethrow;
|
|
229
|
+
// (b) checkout succeeded but stash pop failed → HEAD moved to `branch` but
|
|
230
|
+
// the working-tree changes remain in the stash list. We surface a distinct
|
|
231
|
+
// error in case (b) so callers don't assume the branch switch was rolled back.
|
|
232
|
+
try {
|
|
233
|
+
nativeCheckoutBranch(basePath, branch);
|
|
234
|
+
} catch (checkoutErr) {
|
|
235
|
+
if (stashed) {
|
|
236
|
+
try {
|
|
237
|
+
popStashByRef(basePath, stashMarker);
|
|
238
|
+
} catch (restoreErr) {
|
|
239
|
+
logWarning("worktree", `git stash pop failed during checkout restore: ${restoreErr instanceof Error ? restoreErr.message : String(restoreErr)}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
throw checkoutErr;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (stashed) {
|
|
246
|
+
try {
|
|
247
|
+
popStashByRef(basePath, stashMarker);
|
|
248
|
+
} catch (popErr) {
|
|
249
|
+
const msg = popErr instanceof Error ? popErr.message : String(popErr);
|
|
250
|
+
const stderr = popErr && typeof popErr === "object"
|
|
251
|
+
? (popErr as { stderr?: unknown }).stderr
|
|
252
|
+
: undefined;
|
|
253
|
+
const stderrText = typeof stderr === "string"
|
|
254
|
+
? stderr
|
|
255
|
+
: stderr instanceof Uint8Array
|
|
256
|
+
? Buffer.from(stderr).toString("utf-8")
|
|
257
|
+
: "";
|
|
258
|
+
const stashPopMessage = `${stderrText}\n${msg}`.trim();
|
|
259
|
+
const alreadyExists = stashAlreadyExistsFilesFromError(popErr);
|
|
260
|
+
const gsdAlreadyExists = alreadyExists.filter((f) => f.startsWith(".gsd/"));
|
|
261
|
+
const nonGsdAlreadyExists = alreadyExists.filter((f) => !f.startsWith(".gsd/"));
|
|
262
|
+
const isUntrackedRestoreFailure = stashPopMessage.includes("could not restore untracked files from stash");
|
|
263
|
+
const stashRefForDrop = stashRefFromError(popErr);
|
|
264
|
+
const nonGsdUnmerged = nativeConflictFiles(basePath).filter((f) => !f.startsWith(".gsd/"));
|
|
265
|
+
const gsdContentConflicts = isUntrackedRestoreFailure
|
|
266
|
+
? gsdJsonlFilesWithConflictMarkers(basePath)
|
|
267
|
+
: [];
|
|
268
|
+
const gsdConflictFiles = [...new Set([...gsdAlreadyExists, ...gsdContentConflicts])];
|
|
269
|
+
|
|
270
|
+
if (
|
|
271
|
+
isUntrackedRestoreFailure &&
|
|
272
|
+
gsdConflictFiles.length > 0 &&
|
|
273
|
+
nonGsdAlreadyExists.length === 0 &&
|
|
274
|
+
nonGsdUnmerged.length === 0
|
|
275
|
+
) {
|
|
276
|
+
for (const f of gsdConflictFiles) {
|
|
277
|
+
execFileSync("git", ["checkout", "HEAD", "--", f], {
|
|
278
|
+
cwd: basePath,
|
|
279
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
280
|
+
encoding: "utf-8",
|
|
281
|
+
});
|
|
282
|
+
nativeAddPaths(basePath, [f]);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (stashRefForDrop) {
|
|
286
|
+
try {
|
|
287
|
+
execFileSync("git", ["stash", "drop", stashRefForDrop], {
|
|
288
|
+
cwd: basePath,
|
|
289
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
290
|
+
encoding: "utf-8",
|
|
291
|
+
});
|
|
292
|
+
} catch (err) { /* stash may already be consumed */
|
|
293
|
+
logWarning("worktree", `git stash drop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
294
|
+
}
|
|
295
|
+
} else {
|
|
296
|
+
logWarning("worktree", "recorded stash entry could not be resolved; skipping automatic drop");
|
|
297
|
+
}
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const wrapped = new Error(
|
|
302
|
+
`checkout to '${branch}' succeeded but stash restore failed; working tree changes remain in the stash list. Original error: ${msg}`,
|
|
303
|
+
);
|
|
304
|
+
if (stashRefForDrop) (wrapped as { stashRef?: string }).stashRef = stashRefForDrop;
|
|
305
|
+
throw wrapped;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
@@ -79,6 +79,7 @@ import {
|
|
|
79
79
|
teardownAutoWorktree,
|
|
80
80
|
} from "./auto-worktree.js";
|
|
81
81
|
import { resolveRoadmapForMilestoneMerge } from "./milestone-merge-roadmap.js";
|
|
82
|
+
import type { MilestoneMergeTransactionRunner } from "./milestone-merge-transaction.js";
|
|
82
83
|
|
|
83
84
|
const recentWorktreeMergeFailures = new Map<string, number>();
|
|
84
85
|
const MERGE_FAILURE_DEDUPE_MS = 60_000;
|
|
@@ -147,25 +148,15 @@ export interface WorktreeLifecycleDeps {
|
|
|
147
148
|
*/
|
|
148
149
|
worktreeProjection: WorktreeStateProjection;
|
|
149
150
|
|
|
150
|
-
// ── Merge
|
|
151
|
+
// ── Merge transaction ────────────────────────────────────────────────
|
|
151
152
|
/**
|
|
152
|
-
*
|
|
153
|
+
* Milestone Merge Transaction Module runner.
|
|
153
154
|
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* merge body through `WorktreeLifecycle.exitMilestone({ merge: true })`,
|
|
158
|
-
* never by calling this dep directly.
|
|
155
|
+
* The field name is preserved for existing test fixtures, but production
|
|
156
|
+
* wiring now supplies the named transaction wrapper rather than the raw
|
|
157
|
+
* squash-merge primitive directly.
|
|
159
158
|
*/
|
|
160
|
-
mergeMilestoneToMain:
|
|
161
|
-
basePath: string,
|
|
162
|
-
milestoneId: string,
|
|
163
|
-
roadmapContent: string,
|
|
164
|
-
) => {
|
|
165
|
-
pushed: boolean;
|
|
166
|
-
codeFilesChanged: boolean;
|
|
167
|
-
commitMessage?: string;
|
|
168
|
-
};
|
|
159
|
+
mergeMilestoneToMain: MilestoneMergeTransactionRunner;
|
|
169
160
|
|
|
170
161
|
// ADR-016 phase 2 / C1 + C2 + C3 + C4 inlined the following fields as
|
|
171
162
|
// direct imports — leaf primitives that did not vary across callers:
|
|
@@ -684,7 +675,16 @@ export function _enterMilestoneCore(
|
|
|
684
675
|
// Handles the case where originalBasePath is falsy and basePath is itself
|
|
685
676
|
// a worktree path — prevents double-nested worktree paths (#3729).
|
|
686
677
|
const basePath = resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
687
|
-
|
|
678
|
+
// A stranded-recovery session that adopted the milestone branch in the
|
|
679
|
+
// project root must keep re-entering in that mode: the root checkout holds
|
|
680
|
+
// the branch, so creating the canonical worktree would fail with "already
|
|
681
|
+
// in use by another worktree". The override clears when the recovered
|
|
682
|
+
// milestone merges (_mergeAndExit), restoring configured isolation for
|
|
683
|
+
// subsequent milestones.
|
|
684
|
+
const mode =
|
|
685
|
+
opts.modeOverride ??
|
|
686
|
+
s.strandedRecoveryIsolationMode ??
|
|
687
|
+
getIsolationMode(basePath);
|
|
688
688
|
|
|
689
689
|
if (s.isolationDegraded) {
|
|
690
690
|
if (mode === "worktree") {
|