lsd-pi 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +283 -648
- package/dist/cli-theme.d.ts +1 -1
- package/dist/cli-theme.js +4 -4
- package/dist/cli.js +2 -2
- package/dist/headless.js +4 -6
- package/dist/help-text.js +1 -3
- package/dist/loader.js +8 -7
- package/dist/logo.d.ts +9 -0
- package/dist/logo.js +18 -8
- package/dist/lsd-brand.d.ts +14 -0
- package/dist/lsd-brand.js +42 -0
- package/dist/onboarding.js +51 -0
- package/dist/resource-loader.d.ts +2 -3
- package/dist/resource-loader.js +18 -20
- package/dist/resources/agents/generic.md +29 -0
- package/dist/resources/agents/scout.md +1 -0
- package/dist/resources/extensions/ask-user-questions.js +0 -4
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +6 -0
- package/dist/resources/extensions/get-secrets-from-user.js +2 -3
- package/dist/resources/extensions/memory/auto-extract.js +154 -0
- package/dist/resources/extensions/memory/extension-manifest.json +11 -0
- package/dist/resources/extensions/memory/index.js +223 -0
- package/dist/resources/extensions/memory/memory-age.js +43 -0
- package/dist/resources/extensions/memory/memory-paths.js +49 -0
- package/dist/resources/extensions/memory/memory-recall.js +150 -0
- package/dist/resources/extensions/memory/memory-scan.js +90 -0
- package/dist/resources/extensions/memory/memory-types.js +96 -0
- package/dist/resources/extensions/remote-questions/config.js +3 -3
- package/dist/resources/extensions/remote-questions/extension-manifest.json +1 -1
- package/dist/resources/extensions/remote-questions/index.js +53 -0
- package/dist/resources/extensions/remote-questions/remote-command.js +4 -27
- package/dist/resources/extensions/remote-questions/telegram-adapter.js +6 -13
- package/dist/resources/extensions/remote-questions/telegram-live-relay.js +447 -0
- package/dist/resources/extensions/remote-questions/telegram-update-stream.js +67 -0
- package/dist/resources/extensions/search-the-web/native-search.js +1 -1
- package/dist/resources/extensions/search-the-web/provider.js +4 -12
- package/dist/resources/extensions/shared/debug-logger.js +103 -0
- package/dist/resources/extensions/shared/env-utils.js +17 -0
- package/dist/resources/extensions/shared/paths.js +17 -0
- package/dist/resources/extensions/shared/preferences.js +90 -0
- package/dist/resources/extensions/shared/remote-questions-config.js +27 -0
- package/dist/resources/extensions/shared/rtk-session-stats.js +2 -2
- package/dist/resources/extensions/shared/secrets-manifest.js +115 -0
- package/dist/resources/extensions/slash-commands/extension-manifest.json +2 -1
- package/dist/resources/extensions/slash-commands/index.js +2 -0
- package/dist/resources/extensions/slash-commands/plan.js +284 -0
- package/dist/resources/extensions/subagent/agents.js +1 -1
- package/dist/resources/extensions/subagent/approval-proxy.js +34 -0
- package/dist/resources/extensions/subagent/configured-model.js +9 -0
- package/dist/resources/extensions/subagent/index.js +95 -144
- package/dist/resources/extensions/subagent/model-resolution.js +12 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.js +1 -1
- package/dist/resources/skills/create-skill/SKILL.md +2 -2
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +8 -7
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +6 -5
- package/dist/shared-paths.d.ts +1 -0
- package/dist/shared-paths.js +17 -0
- package/dist/shared-preferences.d.ts +37 -0
- package/dist/shared-preferences.js +102 -0
- package/dist/welcome-screen.js +24 -18
- package/dist/worktree-cli.d.ts +4 -49
- package/dist/worktree-cli.js +197 -113
- package/package.json +6 -6
- package/packages/pi-coding-agent/dist/cli/args.d.ts +1 -1
- package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +13 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +35 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +8 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +12 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +77 -15
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +76 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/keybindings.js +2 -2
- package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +8 -8
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-lsd-md.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-lsd-md.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-lsd-md.test.js +59 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-lsd-md.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +32 -14
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +13 -3
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -6
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +18 -13
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tool-approval.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/tool-approval.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tool-approval.js +2 -0
- package/packages/pi-coding-agent/dist/core/tool-approval.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +1 -1
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +5 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +11 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +11 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +7 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +33 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +129 -57
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +12 -3
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +46 -6
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +28 -20
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/cli/args.ts +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +14 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +30 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +36 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +9 -0
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +87 -0
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +84 -16
- package/packages/pi-coding-agent/src/core/keybindings.ts +2 -2
- package/packages/pi-coding-agent/src/core/package-manager.ts +8 -8
- package/packages/pi-coding-agent/src/core/resource-loader-lsd-md.test.ts +67 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +32 -13
- package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -5
- package/packages/pi-coding-agent/src/core/skills.ts +20 -14
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -1
- package/packages/pi-coding-agent/src/core/tool-approval.js +111 -0
- package/packages/pi-coding-agent/src/core/tool-approval.ts +2 -1
- package/packages/pi-coding-agent/src/index.ts +2 -0
- package/packages/pi-coding-agent/src/main.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +14 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +11 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +40 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +135 -66
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +12 -3
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +70 -6
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +28 -20
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +28 -20
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/agents/generic.md +29 -0
- package/src/resources/agents/scout.md +1 -0
- package/src/resources/extensions/ask-user-questions.ts +0 -3
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +6 -0
- package/src/resources/extensions/cmux/index.ts +29 -10
- package/src/resources/extensions/get-secrets-from-user.ts +2 -4
- package/src/resources/extensions/gsd/tests/test-helpers.ts +44 -44
- package/src/resources/extensions/memory/auto-extract.ts +172 -0
- package/src/resources/extensions/memory/extension-manifest.json +11 -0
- package/src/resources/extensions/memory/index.ts +263 -0
- package/src/resources/extensions/memory/memory-age.ts +43 -0
- package/src/resources/extensions/memory/memory-paths.ts +55 -0
- package/src/resources/extensions/memory/memory-recall.ts +186 -0
- package/src/resources/extensions/memory/memory-scan.ts +118 -0
- package/src/resources/extensions/memory/memory-types.ts +106 -0
- package/src/resources/extensions/memory/tests/auto-extract.test.ts +141 -0
- package/src/resources/extensions/memory/tests/memory-age.test.ts +60 -0
- package/src/resources/extensions/memory/tests/memory-paths.test.ts +89 -0
- package/src/resources/extensions/memory/tests/memory-scan.test.ts +244 -0
- package/src/resources/extensions/remote-questions/config.ts +3 -3
- package/src/resources/extensions/remote-questions/extension-manifest.json +1 -1
- package/src/resources/extensions/remote-questions/index.ts +65 -0
- package/src/resources/extensions/remote-questions/remote-command.ts +4 -30
- package/src/resources/extensions/remote-questions/telegram-adapter.ts +6 -14
- package/src/resources/extensions/remote-questions/telegram-live-relay.ts +471 -0
- package/src/resources/extensions/remote-questions/telegram-update-stream.ts +116 -0
- package/src/resources/extensions/search-the-web/native-search.ts +2 -1
- package/src/resources/extensions/search-the-web/provider.ts +3 -10
- package/src/resources/extensions/shared/debug-logger.ts +102 -0
- package/src/resources/extensions/shared/env-utils.ts +18 -0
- package/src/resources/extensions/shared/paths.ts +15 -0
- package/src/resources/extensions/shared/preferences.ts +122 -0
- package/src/resources/extensions/shared/remote-questions-config.ts +30 -0
- package/src/resources/extensions/shared/rtk-session-stats.ts +2 -2
- package/src/resources/extensions/shared/secrets-manifest.ts +130 -0
- package/src/resources/extensions/slash-commands/extension-manifest.json +2 -1
- package/src/resources/extensions/slash-commands/index.ts +2 -0
- package/src/resources/extensions/slash-commands/plan.ts +328 -0
- package/src/resources/extensions/subagent/agents.ts +1 -1
- package/src/resources/extensions/subagent/approval-proxy.ts +70 -0
- package/src/resources/extensions/subagent/configured-model.ts +15 -0
- package/src/resources/extensions/subagent/index.ts +126 -185
- package/src/resources/extensions/subagent/model-resolution.ts +26 -0
- package/src/resources/extensions/ttsr/ttsr-manager.ts +1 -1
- package/src/resources/skills/create-skill/SKILL.md +2 -2
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +8 -7
- package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +6 -5
- package/dist/resources/extensions/github-sync/cli.js +0 -284
- package/dist/resources/extensions/github-sync/index.js +0 -73
- package/dist/resources/extensions/github-sync/mapping.js +0 -67
- package/dist/resources/extensions/github-sync/sync.js +0 -425
- package/dist/resources/extensions/github-sync/templates.js +0 -118
- package/dist/resources/extensions/github-sync/types.js +0 -7
- package/dist/resources/extensions/gsd/activity-log.js +0 -153
- package/dist/resources/extensions/gsd/atomic-write.js +0 -134
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +0 -49
- package/dist/resources/extensions/gsd/auto/infra-errors.js +0 -49
- package/dist/resources/extensions/gsd/auto/loop-deps.js +0 -6
- package/dist/resources/extensions/gsd/auto/loop.js +0 -256
- package/dist/resources/extensions/gsd/auto/phases.js +0 -942
- package/dist/resources/extensions/gsd/auto/resolve.js +0 -90
- package/dist/resources/extensions/gsd/auto/run-unit.js +0 -106
- package/dist/resources/extensions/gsd/auto/session.js +0 -171
- package/dist/resources/extensions/gsd/auto/types.js +0 -23
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +0 -116
- package/dist/resources/extensions/gsd/auto-budget.js +0 -30
- package/dist/resources/extensions/gsd/auto-dashboard.js +0 -751
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +0 -212
- package/dist/resources/extensions/gsd/auto-dispatch.js +0 -627
- package/dist/resources/extensions/gsd/auto-loop.js +0 -13
- package/dist/resources/extensions/gsd/auto-model-selection.js +0 -192
- package/dist/resources/extensions/gsd/auto-observability.js +0 -54
- package/dist/resources/extensions/gsd/auto-post-unit.js +0 -548
- package/dist/resources/extensions/gsd/auto-prompts.js +0 -1686
- package/dist/resources/extensions/gsd/auto-recovery.js +0 -533
- package/dist/resources/extensions/gsd/auto-start.js +0 -544
- package/dist/resources/extensions/gsd/auto-supervisor.js +0 -73
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +0 -180
- package/dist/resources/extensions/gsd/auto-timers.js +0 -261
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +0 -77
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +0 -30
- package/dist/resources/extensions/gsd/auto-utils.js +0 -20
- package/dist/resources/extensions/gsd/auto-verification.js +0 -163
- package/dist/resources/extensions/gsd/auto-worktree.js +0 -1645
- package/dist/resources/extensions/gsd/auto.js +0 -1087
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +0 -191
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +0 -1207
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +0 -149
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +0 -62
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +0 -18
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +0 -53
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +0 -267
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +0 -45
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +0 -367
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +0 -75
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +0 -105
- package/dist/resources/extensions/gsd/branch-patterns.js +0 -13
- package/dist/resources/extensions/gsd/cache.js +0 -27
- package/dist/resources/extensions/gsd/captures.js +0 -414
- package/dist/resources/extensions/gsd/changelog.js +0 -162
- package/dist/resources/extensions/gsd/claude-import.js +0 -591
- package/dist/resources/extensions/gsd/collision-diagnostics.js +0 -226
- package/dist/resources/extensions/gsd/commands/catalog.js +0 -336
- package/dist/resources/extensions/gsd/commands/context.js +0 -87
- package/dist/resources/extensions/gsd/commands/dispatcher.js +0 -21
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +0 -175
- package/dist/resources/extensions/gsd/commands/handlers/core.js +0 -249
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +0 -207
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +0 -106
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +0 -253
- package/dist/resources/extensions/gsd/commands/index.js +0 -11
- package/dist/resources/extensions/gsd/commands-bootstrap.js +0 -224
- package/dist/resources/extensions/gsd/commands-cmux.js +0 -120
- package/dist/resources/extensions/gsd/commands-config.js +0 -94
- package/dist/resources/extensions/gsd/commands-extensions.js +0 -260
- package/dist/resources/extensions/gsd/commands-handlers.js +0 -318
- package/dist/resources/extensions/gsd/commands-inspect.js +0 -77
- package/dist/resources/extensions/gsd/commands-logs.js +0 -468
- package/dist/resources/extensions/gsd/commands-maintenance.js +0 -485
- package/dist/resources/extensions/gsd/commands-mcp-status.js +0 -187
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +0 -664
- package/dist/resources/extensions/gsd/commands-rate.js +0 -31
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +0 -408
- package/dist/resources/extensions/gsd/commands.js +0 -9
- package/dist/resources/extensions/gsd/complexity-classifier.js +0 -259
- package/dist/resources/extensions/gsd/constants.js +0 -15
- package/dist/resources/extensions/gsd/context-budget.js +0 -179
- package/dist/resources/extensions/gsd/context-injector.js +0 -74
- package/dist/resources/extensions/gsd/context-store.js +0 -166
- package/dist/resources/extensions/gsd/crash-recovery.js +0 -112
- package/dist/resources/extensions/gsd/custom-execution-policy.js +0 -48
- package/dist/resources/extensions/gsd/custom-verification.js +0 -147
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +0 -165
- package/dist/resources/extensions/gsd/dashboard-overlay.js +0 -539
- package/dist/resources/extensions/gsd/db-writer.js +0 -518
- package/dist/resources/extensions/gsd/debug-logger.js +0 -161
- package/dist/resources/extensions/gsd/definition-loader.js +0 -352
- package/dist/resources/extensions/gsd/detection.js +0 -977
- package/dist/resources/extensions/gsd/dev-execution-policy.js +0 -24
- package/dist/resources/extensions/gsd/dev-workflow-engine.js +0 -82
- package/dist/resources/extensions/gsd/diff-context.js +0 -168
- package/dist/resources/extensions/gsd/dispatch-guard.js +0 -114
- package/dist/resources/extensions/gsd/docs/claude-marketplace-import.md +0 -214
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -671
- package/dist/resources/extensions/gsd/doctor-checks.js +0 -5
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +0 -168
- package/dist/resources/extensions/gsd/doctor-environment.js +0 -565
- package/dist/resources/extensions/gsd/doctor-format.js +0 -86
- package/dist/resources/extensions/gsd/doctor-git-checks.js +0 -433
- package/dist/resources/extensions/gsd/doctor-global-checks.js +0 -74
- package/dist/resources/extensions/gsd/doctor-proactive.js +0 -349
- package/dist/resources/extensions/gsd/doctor-providers.js +0 -356
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +0 -601
- package/dist/resources/extensions/gsd/doctor-types.js +0 -15
- package/dist/resources/extensions/gsd/doctor.js +0 -765
- package/dist/resources/extensions/gsd/engine-resolver.js +0 -40
- package/dist/resources/extensions/gsd/engine-types.js +0 -8
- package/dist/resources/extensions/gsd/env-utils.js +0 -29
- package/dist/resources/extensions/gsd/error-classifier.js +0 -108
- package/dist/resources/extensions/gsd/error-utils.js +0 -6
- package/dist/resources/extensions/gsd/errors.js +0 -24
- package/dist/resources/extensions/gsd/execution-policy.js +0 -8
- package/dist/resources/extensions/gsd/exit-command.js +0 -22
- package/dist/resources/extensions/gsd/export-html.js +0 -1271
- package/dist/resources/extensions/gsd/export.js +0 -264
- package/dist/resources/extensions/gsd/extension-manifest.json +0 -33
- package/dist/resources/extensions/gsd/file-watcher.js +0 -80
- package/dist/resources/extensions/gsd/files.js +0 -863
- package/dist/resources/extensions/gsd/forensics.js +0 -996
- package/dist/resources/extensions/gsd/git-constants.js +0 -11
- package/dist/resources/extensions/gsd/git-self-heal.js +0 -113
- package/dist/resources/extensions/gsd/git-service.js +0 -586
- package/dist/resources/extensions/gsd/gitignore.js +0 -285
- package/dist/resources/extensions/gsd/graph.js +0 -225
- package/dist/resources/extensions/gsd/gsd-db.js +0 -1808
- package/dist/resources/extensions/gsd/guided-flow-queue.js +0 -365
- package/dist/resources/extensions/gsd/guided-flow.js +0 -1456
- package/dist/resources/extensions/gsd/health-widget-core.js +0 -89
- package/dist/resources/extensions/gsd/health-widget.js +0 -126
- package/dist/resources/extensions/gsd/history.js +0 -119
- package/dist/resources/extensions/gsd/index.js +0 -5
- package/dist/resources/extensions/gsd/init-wizard.js +0 -487
- package/dist/resources/extensions/gsd/journal.js +0 -85
- package/dist/resources/extensions/gsd/json-persistence.js +0 -70
- package/dist/resources/extensions/gsd/jsonl-utils.js +0 -24
- package/dist/resources/extensions/gsd/key-manager.js +0 -820
- package/dist/resources/extensions/gsd/markdown-renderer.js +0 -891
- package/dist/resources/extensions/gsd/marketplace-discovery.js +0 -356
- package/dist/resources/extensions/gsd/md-importer.js +0 -623
- package/dist/resources/extensions/gsd/memory-extractor.js +0 -302
- package/dist/resources/extensions/gsd/memory-store.js +0 -366
- package/dist/resources/extensions/gsd/metrics.js +0 -419
- package/dist/resources/extensions/gsd/migrate/command.js +0 -157
- package/dist/resources/extensions/gsd/migrate/index.js +0 -7
- package/dist/resources/extensions/gsd/migrate/parser.js +0 -268
- package/dist/resources/extensions/gsd/migrate/parsers.js +0 -477
- package/dist/resources/extensions/gsd/migrate/preview.js +0 -47
- package/dist/resources/extensions/gsd/migrate/transformer.js +0 -278
- package/dist/resources/extensions/gsd/migrate/types.js +0 -4
- package/dist/resources/extensions/gsd/migrate/validator.js +0 -41
- package/dist/resources/extensions/gsd/migrate/writer.js +0 -477
- package/dist/resources/extensions/gsd/migrate-external.js +0 -207
- package/dist/resources/extensions/gsd/milestone-actions.js +0 -130
- package/dist/resources/extensions/gsd/milestone-id-utils.js +0 -28
- package/dist/resources/extensions/gsd/milestone-ids.js +0 -116
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +0 -45
- package/dist/resources/extensions/gsd/model-cost-table.js +0 -66
- package/dist/resources/extensions/gsd/model-router.js +0 -246
- package/dist/resources/extensions/gsd/namespaced-registry.js +0 -322
- package/dist/resources/extensions/gsd/namespaced-resolver.js +0 -176
- package/dist/resources/extensions/gsd/native-git-bridge.js +0 -992
- package/dist/resources/extensions/gsd/native-parser-bridge.js +0 -156
- package/dist/resources/extensions/gsd/notifications.js +0 -105
- package/dist/resources/extensions/gsd/observability-validator.js +0 -422
- package/dist/resources/extensions/gsd/package.json +0 -11
- package/dist/resources/extensions/gsd/parallel-eligibility.js +0 -188
- package/dist/resources/extensions/gsd/parallel-merge.js +0 -194
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +0 -413
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +0 -850
- package/dist/resources/extensions/gsd/parsers-legacy.js +0 -256
- package/dist/resources/extensions/gsd/paths.js +0 -527
- package/dist/resources/extensions/gsd/plugin-importer.js +0 -254
- package/dist/resources/extensions/gsd/post-unit-hooks.js +0 -48
- package/dist/resources/extensions/gsd/preferences-models.js +0 -295
- package/dist/resources/extensions/gsd/preferences-skills.js +0 -160
- package/dist/resources/extensions/gsd/preferences-types.js +0 -82
- package/dist/resources/extensions/gsd/preferences-validation.js +0 -852
- package/dist/resources/extensions/gsd/preferences.js +0 -432
- package/dist/resources/extensions/gsd/progress-score.js +0 -121
- package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +0 -150
- package/dist/resources/extensions/gsd/prompt-loader.js +0 -156
- package/dist/resources/extensions/gsd/prompt-ordering.js +0 -170
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +0 -66
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +0 -40
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +0 -253
- package/dist/resources/extensions/gsd/prompts/discuss.md +0 -290
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +0 -29
- package/dist/resources/extensions/gsd/prompts/execute-task.md +0 -80
- package/dist/resources/extensions/gsd/prompts/forensics.md +0 -196
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +0 -32
- package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +0 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +0 -110
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +0 -62
- package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +0 -3
- package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +0 -30
- package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +0 -3
- package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +0 -15
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +0 -1
- package/dist/resources/extensions/gsd/prompts/heal-skill.md +0 -45
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +0 -108
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +0 -89
- package/dist/resources/extensions/gsd/prompts/queue.md +0 -132
- package/dist/resources/extensions/gsd/prompts/quick-task.md +0 -44
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +0 -44
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +0 -66
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +0 -39
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +0 -47
- package/dist/resources/extensions/gsd/prompts/research-slice.md +0 -57
- package/dist/resources/extensions/gsd/prompts/rethink.md +0 -83
- package/dist/resources/extensions/gsd/prompts/review-migration.md +0 -66
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +0 -31
- package/dist/resources/extensions/gsd/prompts/run-uat.md +0 -89
- package/dist/resources/extensions/gsd/prompts/system.md +0 -220
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +0 -63
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +0 -47
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +0 -28
- package/dist/resources/extensions/gsd/prompts/worktree-merge.md +0 -123
- package/dist/resources/extensions/gsd/provider-error-pause.js +0 -31
- package/dist/resources/extensions/gsd/queue-order.js +0 -178
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +0 -235
- package/dist/resources/extensions/gsd/quick.js +0 -206
- package/dist/resources/extensions/gsd/reactive-graph.js +0 -257
- package/dist/resources/extensions/gsd/repo-identity.js +0 -641
- package/dist/resources/extensions/gsd/reports.js +0 -409
- package/dist/resources/extensions/gsd/rethink.js +0 -120
- package/dist/resources/extensions/gsd/roadmap-mutations.js +0 -110
- package/dist/resources/extensions/gsd/roadmap-slices.js +0 -255
- package/dist/resources/extensions/gsd/routing-history.js +0 -210
- package/dist/resources/extensions/gsd/rtk-status.js +0 -43
- package/dist/resources/extensions/gsd/rule-registry.js +0 -488
- package/dist/resources/extensions/gsd/rule-types.js +0 -6
- package/dist/resources/extensions/gsd/run-manager.js +0 -134
- package/dist/resources/extensions/gsd/safe-fs.js +0 -52
- package/dist/resources/extensions/gsd/service-tier.js +0 -158
- package/dist/resources/extensions/gsd/session-forensics.js +0 -435
- package/dist/resources/extensions/gsd/session-lock.js +0 -554
- package/dist/resources/extensions/gsd/session-status-io.js +0 -134
- package/dist/resources/extensions/gsd/skill-catalog.js +0 -1026
- package/dist/resources/extensions/gsd/skill-discovery.js +0 -122
- package/dist/resources/extensions/gsd/skill-health.js +0 -326
- package/dist/resources/extensions/gsd/skill-telemetry.js +0 -121
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +0 -242
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/answer-injection.md +0 -83
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +0 -64
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/multi-session.md +0 -176
- package/dist/resources/extensions/gsd/state.js +0 -1407
- package/dist/resources/extensions/gsd/status-guards.js +0 -12
- package/dist/resources/extensions/gsd/structured-data-formatter.js +0 -98
- package/dist/resources/extensions/gsd/sync-lock.js +0 -89
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +0 -80
- package/dist/resources/extensions/gsd/templates/context.md +0 -76
- package/dist/resources/extensions/gsd/templates/decisions.md +0 -8
- package/dist/resources/extensions/gsd/templates/knowledge.md +0 -19
- package/dist/resources/extensions/gsd/templates/milestone-summary.md +0 -81
- package/dist/resources/extensions/gsd/templates/milestone-validation.md +0 -74
- package/dist/resources/extensions/gsd/templates/plan.md +0 -148
- package/dist/resources/extensions/gsd/templates/project.md +0 -31
- package/dist/resources/extensions/gsd/templates/reassessment.md +0 -29
- package/dist/resources/extensions/gsd/templates/requirements.md +0 -81
- package/dist/resources/extensions/gsd/templates/research.md +0 -79
- package/dist/resources/extensions/gsd/templates/roadmap.md +0 -131
- package/dist/resources/extensions/gsd/templates/runtime.md +0 -21
- package/dist/resources/extensions/gsd/templates/secrets-manifest.md +0 -22
- package/dist/resources/extensions/gsd/templates/slice-context.md +0 -58
- package/dist/resources/extensions/gsd/templates/slice-summary.md +0 -108
- package/dist/resources/extensions/gsd/templates/state.md +0 -17
- package/dist/resources/extensions/gsd/templates/task-plan.md +0 -87
- package/dist/resources/extensions/gsd/templates/task-summary.md +0 -66
- package/dist/resources/extensions/gsd/templates/uat.md +0 -54
- package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
- package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
- package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
- package/dist/resources/extensions/gsd/token-counter.js +0 -54
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +0 -172
- package/dist/resources/extensions/gsd/tools/complete-slice.js +0 -276
- package/dist/resources/extensions/gsd/tools/complete-task.js +0 -205
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +0 -250
- package/dist/resources/extensions/gsd/tools/plan-slice.js +0 -199
- package/dist/resources/extensions/gsd/tools/plan-task.js +0 -121
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +0 -219
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +0 -87
- package/dist/resources/extensions/gsd/tools/reopen-task.js +0 -91
- package/dist/resources/extensions/gsd/tools/replan-slice.js +0 -188
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +0 -110
- package/dist/resources/extensions/gsd/triage-resolution.js +0 -322
- package/dist/resources/extensions/gsd/triage-ui.js +0 -135
- package/dist/resources/extensions/gsd/types.js +0 -4
- package/dist/resources/extensions/gsd/undo.js +0 -400
- package/dist/resources/extensions/gsd/unit-id.js +0 -7
- package/dist/resources/extensions/gsd/unit-ownership.js +0 -216
- package/dist/resources/extensions/gsd/unit-runtime.js +0 -132
- package/dist/resources/extensions/gsd/validate-directory.js +0 -143
- package/dist/resources/extensions/gsd/validation.js +0 -21
- package/dist/resources/extensions/gsd/verdict-parser.js +0 -96
- package/dist/resources/extensions/gsd/verification-evidence.js +0 -122
- package/dist/resources/extensions/gsd/verification-gate.js +0 -519
- package/dist/resources/extensions/gsd/visualizer-data.js +0 -674
- package/dist/resources/extensions/gsd/visualizer-overlay.js +0 -501
- package/dist/resources/extensions/gsd/visualizer-views.js +0 -945
- package/dist/resources/extensions/gsd/workflow-engine.js +0 -7
- package/dist/resources/extensions/gsd/workflow-events.js +0 -102
- package/dist/resources/extensions/gsd/workflow-logger.js +0 -192
- package/dist/resources/extensions/gsd/workflow-manifest.js +0 -263
- package/dist/resources/extensions/gsd/workflow-migration.js +0 -280
- package/dist/resources/extensions/gsd/workflow-projections.js +0 -405
- package/dist/resources/extensions/gsd/workflow-reconcile.js +0 -441
- package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +0 -87
- package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +0 -74
- package/dist/resources/extensions/gsd/workflow-templates/full-project.md +0 -40
- package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +0 -45
- package/dist/resources/extensions/gsd/workflow-templates/refactor.md +0 -83
- package/dist/resources/extensions/gsd/workflow-templates/registry.json +0 -85
- package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +0 -73
- package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +0 -81
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +0 -69
- package/dist/resources/extensions/gsd/workflow-templates.js +0 -200
- package/dist/resources/extensions/gsd/workspace-index.js +0 -190
- package/dist/resources/extensions/gsd/worktree-command-bootstrap.js +0 -40
- package/dist/resources/extensions/gsd/worktree-command.js +0 -702
- package/dist/resources/extensions/gsd/worktree-health.js +0 -126
- package/dist/resources/extensions/gsd/worktree-manager.js +0 -518
- package/dist/resources/extensions/gsd/worktree-resolver.js +0 -480
- package/dist/resources/extensions/gsd/worktree.js +0 -310
- package/dist/resources/extensions/gsd/write-intercept.js +0 -84
- package/src/resources/extensions/github-sync/cli.ts +0 -364
- package/src/resources/extensions/github-sync/index.ts +0 -93
- package/src/resources/extensions/github-sync/mapping.ts +0 -81
- package/src/resources/extensions/github-sync/sync.ts +0 -557
- package/src/resources/extensions/github-sync/templates.ts +0 -183
- package/src/resources/extensions/github-sync/tests/cli.test.ts +0 -20
- package/src/resources/extensions/github-sync/tests/commit-linking.test.ts +0 -43
- package/src/resources/extensions/github-sync/tests/mapping.test.ts +0 -104
- package/src/resources/extensions/github-sync/tests/templates.test.ts +0 -110
- package/src/resources/extensions/github-sync/types.ts +0 -47
- package/src/resources/extensions/gsd/activity-log.ts +0 -163
- package/src/resources/extensions/gsd/atomic-write.ts +0 -185
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +0 -60
- package/src/resources/extensions/gsd/auto/infra-errors.ts +0 -48
- package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -268
- package/src/resources/extensions/gsd/auto/loop.ts +0 -318
- package/src/resources/extensions/gsd/auto/phases.ts +0 -1327
- package/src/resources/extensions/gsd/auto/resolve.ts +0 -106
- package/src/resources/extensions/gsd/auto/run-unit.ts +0 -136
- package/src/resources/extensions/gsd/auto/session.ts +0 -237
- package/src/resources/extensions/gsd/auto/types.ts +0 -117
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +0 -135
- package/src/resources/extensions/gsd/auto-budget.ts +0 -32
- package/src/resources/extensions/gsd/auto-dashboard.ts +0 -880
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +0 -256
- package/src/resources/extensions/gsd/auto-dispatch.ts +0 -781
- package/src/resources/extensions/gsd/auto-loop.ts +0 -16
- package/src/resources/extensions/gsd/auto-model-selection.ts +0 -251
- package/src/resources/extensions/gsd/auto-observability.ts +0 -72
- package/src/resources/extensions/gsd/auto-post-unit.ts +0 -687
- package/src/resources/extensions/gsd/auto-prompts.ts +0 -1896
- package/src/resources/extensions/gsd/auto-recovery.ts +0 -594
- package/src/resources/extensions/gsd/auto-start.ts +0 -737
- package/src/resources/extensions/gsd/auto-supervisor.ts +0 -79
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +0 -262
- package/src/resources/extensions/gsd/auto-timers.ts +0 -313
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +0 -85
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +0 -48
- package/src/resources/extensions/gsd/auto-utils.ts +0 -25
- package/src/resources/extensions/gsd/auto-verification.ts +0 -225
- package/src/resources/extensions/gsd/auto-worktree.ts +0 -1897
- package/src/resources/extensions/gsd/auto.ts +0 -1477
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +0 -219
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +0 -1286
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +0 -194
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +0 -62
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +0 -53
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +0 -61
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +0 -282
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +0 -56
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +0 -416
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +0 -91
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +0 -126
- package/src/resources/extensions/gsd/branch-patterns.ts +0 -16
- package/src/resources/extensions/gsd/cache.ts +0 -29
- package/src/resources/extensions/gsd/captures.ts +0 -502
- package/src/resources/extensions/gsd/changelog.ts +0 -213
- package/src/resources/extensions/gsd/claude-import.ts +0 -705
- package/src/resources/extensions/gsd/collision-diagnostics.ts +0 -332
- package/src/resources/extensions/gsd/commands/catalog.ts +0 -359
- package/src/resources/extensions/gsd/commands/context.ts +0 -108
- package/src/resources/extensions/gsd/commands/dispatcher.ts +0 -32
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +0 -184
- package/src/resources/extensions/gsd/commands/handlers/core.ts +0 -277
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +0 -210
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +0 -135
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +0 -281
- package/src/resources/extensions/gsd/commands/index.ts +0 -14
- package/src/resources/extensions/gsd/commands-bootstrap.ts +0 -253
- package/src/resources/extensions/gsd/commands-cmux.ts +0 -143
- package/src/resources/extensions/gsd/commands-config.ts +0 -108
- package/src/resources/extensions/gsd/commands-extensions.ts +0 -330
- package/src/resources/extensions/gsd/commands-handlers.ts +0 -404
- package/src/resources/extensions/gsd/commands-inspect.ts +0 -98
- package/src/resources/extensions/gsd/commands-logs.ts +0 -536
- package/src/resources/extensions/gsd/commands-maintenance.ts +0 -535
- package/src/resources/extensions/gsd/commands-mcp-status.ts +0 -247
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +0 -784
- package/src/resources/extensions/gsd/commands-rate.ts +0 -55
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +0 -543
- package/src/resources/extensions/gsd/commands.ts +0 -17
- package/src/resources/extensions/gsd/complexity-classifier.ts +0 -322
- package/src/resources/extensions/gsd/constants.ts +0 -21
- package/src/resources/extensions/gsd/context-budget.ts +0 -256
- package/src/resources/extensions/gsd/context-injector.ts +0 -100
- package/src/resources/extensions/gsd/context-store.ts +0 -196
- package/src/resources/extensions/gsd/crash-recovery.ts +0 -120
- package/src/resources/extensions/gsd/custom-execution-policy.ts +0 -74
- package/src/resources/extensions/gsd/custom-verification.ts +0 -182
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +0 -217
- package/src/resources/extensions/gsd/dashboard-overlay.ts +0 -659
- package/src/resources/extensions/gsd/db-writer.ts +0 -612
- package/src/resources/extensions/gsd/debug-logger.ts +0 -178
- package/src/resources/extensions/gsd/definition-loader.ts +0 -462
- package/src/resources/extensions/gsd/detection.ts +0 -1148
- package/src/resources/extensions/gsd/dev-execution-policy.ts +0 -51
- package/src/resources/extensions/gsd/dev-workflow-engine.ts +0 -110
- package/src/resources/extensions/gsd/diff-context.ts +0 -214
- package/src/resources/extensions/gsd/dispatch-guard.ts +0 -120
- package/src/resources/extensions/gsd/docs/claude-marketplace-import.md +0 -214
- package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -671
- package/src/resources/extensions/gsd/doctor-checks.ts +0 -5
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +0 -182
- package/src/resources/extensions/gsd/doctor-environment.ts +0 -642
- package/src/resources/extensions/gsd/doctor-format.ts +0 -98
- package/src/resources/extensions/gsd/doctor-git-checks.ts +0 -441
- package/src/resources/extensions/gsd/doctor-global-checks.ts +0 -84
- package/src/resources/extensions/gsd/doctor-proactive.ts +0 -431
- package/src/resources/extensions/gsd/doctor-providers.ts +0 -415
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +0 -627
- package/src/resources/extensions/gsd/doctor-types.ts +0 -123
- package/src/resources/extensions/gsd/doctor.ts +0 -808
- package/src/resources/extensions/gsd/engine-resolver.ts +0 -57
- package/src/resources/extensions/gsd/engine-types.ts +0 -71
- package/src/resources/extensions/gsd/env-utils.ts +0 -31
- package/src/resources/extensions/gsd/error-classifier.ts +0 -142
- package/src/resources/extensions/gsd/error-utils.ts +0 -6
- package/src/resources/extensions/gsd/errors.ts +0 -29
- package/src/resources/extensions/gsd/execution-policy.ts +0 -43
- package/src/resources/extensions/gsd/exit-command.ts +0 -30
- package/src/resources/extensions/gsd/export-html.ts +0 -1408
- package/src/resources/extensions/gsd/export.ts +0 -310
- package/src/resources/extensions/gsd/extension-manifest.json +0 -33
- package/src/resources/extensions/gsd/file-watcher.ts +0 -100
- package/src/resources/extensions/gsd/files.ts +0 -971
- package/src/resources/extensions/gsd/forensics.ts +0 -1178
- package/src/resources/extensions/gsd/git-constants.ts +0 -12
- package/src/resources/extensions/gsd/git-self-heal.ts +0 -127
- package/src/resources/extensions/gsd/git-service.ts +0 -755
- package/src/resources/extensions/gsd/gitignore.ts +0 -315
- package/src/resources/extensions/gsd/graph.ts +0 -312
- package/src/resources/extensions/gsd/gsd-db.ts +0 -2205
- package/src/resources/extensions/gsd/guided-flow-queue.ts +0 -439
- package/src/resources/extensions/gsd/guided-flow.ts +0 -1666
- package/src/resources/extensions/gsd/health-widget-core.ts +0 -111
- package/src/resources/extensions/gsd/health-widget.ts +0 -143
- package/src/resources/extensions/gsd/history.ts +0 -144
- package/src/resources/extensions/gsd/index.ts +0 -14
- package/src/resources/extensions/gsd/init-wizard.ts +0 -595
- package/src/resources/extensions/gsd/journal.ts +0 -139
- package/src/resources/extensions/gsd/json-persistence.ts +0 -75
- package/src/resources/extensions/gsd/jsonl-utils.ts +0 -21
- package/src/resources/extensions/gsd/key-manager.ts +0 -987
- package/src/resources/extensions/gsd/markdown-renderer.ts +0 -1132
- package/src/resources/extensions/gsd/marketplace-discovery.ts +0 -508
- package/src/resources/extensions/gsd/md-importer.ts +0 -742
- package/src/resources/extensions/gsd/memory-extractor.ts +0 -360
- package/src/resources/extensions/gsd/memory-store.ts +0 -452
- package/src/resources/extensions/gsd/metrics.ts +0 -575
- package/src/resources/extensions/gsd/migrate/command.ts +0 -219
- package/src/resources/extensions/gsd/migrate/index.ts +0 -42
- package/src/resources/extensions/gsd/migrate/parser.ts +0 -323
- package/src/resources/extensions/gsd/migrate/parsers.ts +0 -539
- package/src/resources/extensions/gsd/migrate/preview.ts +0 -48
- package/src/resources/extensions/gsd/migrate/transformer.ts +0 -346
- package/src/resources/extensions/gsd/migrate/types.ts +0 -370
- package/src/resources/extensions/gsd/migrate/validator.ts +0 -55
- package/src/resources/extensions/gsd/migrate/writer.ts +0 -579
- package/src/resources/extensions/gsd/migrate-external.ts +0 -210
- package/src/resources/extensions/gsd/milestone-actions.ts +0 -143
- package/src/resources/extensions/gsd/milestone-id-utils.ts +0 -32
- package/src/resources/extensions/gsd/milestone-ids.ts +0 -135
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +0 -56
- package/src/resources/extensions/gsd/model-cost-table.ts +0 -84
- package/src/resources/extensions/gsd/model-router.ts +0 -315
- package/src/resources/extensions/gsd/namespaced-registry.ts +0 -467
- package/src/resources/extensions/gsd/namespaced-resolver.ts +0 -307
- package/src/resources/extensions/gsd/native-git-bridge.ts +0 -1197
- package/src/resources/extensions/gsd/native-parser-bridge.ts +0 -267
- package/src/resources/extensions/gsd/notifications.ts +0 -135
- package/src/resources/extensions/gsd/observability-validator.ts +0 -456
- package/src/resources/extensions/gsd/package.json +0 -11
- package/src/resources/extensions/gsd/parallel-eligibility.ts +0 -242
- package/src/resources/extensions/gsd/parallel-merge.ts +0 -240
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +0 -497
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +0 -1013
- package/src/resources/extensions/gsd/parsers-legacy.ts +0 -290
- package/src/resources/extensions/gsd/paths.ts +0 -561
- package/src/resources/extensions/gsd/plugin-importer.ts +0 -411
- package/src/resources/extensions/gsd/post-unit-hooks.ts +0 -86
- package/src/resources/extensions/gsd/preferences-models.ts +0 -330
- package/src/resources/extensions/gsd/preferences-skills.ts +0 -175
- package/src/resources/extensions/gsd/preferences-types.ts +0 -285
- package/src/resources/extensions/gsd/preferences-validation.ts +0 -823
- package/src/resources/extensions/gsd/preferences.ts +0 -539
- package/src/resources/extensions/gsd/progress-score.ts +0 -161
- package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +0 -213
- package/src/resources/extensions/gsd/prompt-loader.ts +0 -169
- package/src/resources/extensions/gsd/prompt-ordering.ts +0 -200
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +0 -66
- package/src/resources/extensions/gsd/prompts/complete-slice.md +0 -40
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +0 -253
- package/src/resources/extensions/gsd/prompts/discuss.md +0 -290
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +0 -29
- package/src/resources/extensions/gsd/prompts/execute-task.md +0 -80
- package/src/resources/extensions/gsd/prompts/forensics.md +0 -196
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +0 -32
- package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +0 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +0 -110
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +0 -62
- package/src/resources/extensions/gsd/prompts/guided-execute-task.md +0 -3
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +0 -30
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +0 -3
- package/src/resources/extensions/gsd/prompts/guided-research-slice.md +0 -15
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +0 -1
- package/src/resources/extensions/gsd/prompts/heal-skill.md +0 -45
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +0 -108
- package/src/resources/extensions/gsd/prompts/plan-slice.md +0 -89
- package/src/resources/extensions/gsd/prompts/queue.md +0 -132
- package/src/resources/extensions/gsd/prompts/quick-task.md +0 -44
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +0 -44
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +0 -66
- package/src/resources/extensions/gsd/prompts/replan-slice.md +0 -39
- package/src/resources/extensions/gsd/prompts/research-milestone.md +0 -47
- package/src/resources/extensions/gsd/prompts/research-slice.md +0 -57
- package/src/resources/extensions/gsd/prompts/rethink.md +0 -83
- package/src/resources/extensions/gsd/prompts/review-migration.md +0 -66
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +0 -31
- package/src/resources/extensions/gsd/prompts/run-uat.md +0 -89
- package/src/resources/extensions/gsd/prompts/system.md +0 -220
- package/src/resources/extensions/gsd/prompts/triage-captures.md +0 -63
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +0 -47
- package/src/resources/extensions/gsd/prompts/workflow-start.md +0 -28
- package/src/resources/extensions/gsd/prompts/worktree-merge.md +0 -123
- package/src/resources/extensions/gsd/provider-error-pause.ts +0 -49
- package/src/resources/extensions/gsd/queue-order.ts +0 -230
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +0 -277
- package/src/resources/extensions/gsd/quick.ts +0 -257
- package/src/resources/extensions/gsd/reactive-graph.ts +0 -319
- package/src/resources/extensions/gsd/repo-identity.ts +0 -657
- package/src/resources/extensions/gsd/reports.ts +0 -504
- package/src/resources/extensions/gsd/rethink.ts +0 -160
- package/src/resources/extensions/gsd/roadmap-mutations.ts +0 -134
- package/src/resources/extensions/gsd/roadmap-slices.ts +0 -273
- package/src/resources/extensions/gsd/routing-history.ts +0 -286
- package/src/resources/extensions/gsd/rtk-status.ts +0 -53
- package/src/resources/extensions/gsd/rule-registry.ts +0 -598
- package/src/resources/extensions/gsd/rule-types.ts +0 -68
- package/src/resources/extensions/gsd/run-manager.ts +0 -180
- package/src/resources/extensions/gsd/safe-fs.ts +0 -47
- package/src/resources/extensions/gsd/service-tier.ts +0 -196
- package/src/resources/extensions/gsd/session-forensics.ts +0 -546
- package/src/resources/extensions/gsd/session-lock.ts +0 -640
- package/src/resources/extensions/gsd/session-status-io.ts +0 -179
- package/src/resources/extensions/gsd/skill-catalog.ts +0 -1085
- package/src/resources/extensions/gsd/skill-discovery.ts +0 -140
- package/src/resources/extensions/gsd/skill-health.ts +0 -418
- package/src/resources/extensions/gsd/skill-telemetry.ts +0 -137
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +0 -242
- package/src/resources/extensions/gsd/skills/gsd-headless/references/answer-injection.md +0 -83
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +0 -64
- package/src/resources/extensions/gsd/skills/gsd-headless/references/multi-session.md +0 -176
- package/src/resources/extensions/gsd/state.ts +0 -1554
- package/src/resources/extensions/gsd/status-guards.ts +0 -13
- package/src/resources/extensions/gsd/structured-data-formatter.ts +0 -146
- package/src/resources/extensions/gsd/sync-lock.ts +0 -94
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +0 -80
- package/src/resources/extensions/gsd/templates/context.md +0 -76
- package/src/resources/extensions/gsd/templates/decisions.md +0 -8
- package/src/resources/extensions/gsd/templates/knowledge.md +0 -19
- package/src/resources/extensions/gsd/templates/milestone-summary.md +0 -81
- package/src/resources/extensions/gsd/templates/milestone-validation.md +0 -74
- package/src/resources/extensions/gsd/templates/plan.md +0 -148
- package/src/resources/extensions/gsd/templates/project.md +0 -31
- package/src/resources/extensions/gsd/templates/reassessment.md +0 -29
- package/src/resources/extensions/gsd/templates/requirements.md +0 -81
- package/src/resources/extensions/gsd/templates/research.md +0 -79
- package/src/resources/extensions/gsd/templates/roadmap.md +0 -131
- package/src/resources/extensions/gsd/templates/runtime.md +0 -21
- package/src/resources/extensions/gsd/templates/secrets-manifest.md +0 -22
- package/src/resources/extensions/gsd/templates/slice-context.md +0 -58
- package/src/resources/extensions/gsd/templates/slice-summary.md +0 -108
- package/src/resources/extensions/gsd/templates/state.md +0 -17
- package/src/resources/extensions/gsd/templates/task-plan.md +0 -87
- package/src/resources/extensions/gsd/templates/task-summary.md +0 -66
- package/src/resources/extensions/gsd/templates/uat.md +0 -54
- package/src/resources/extensions/gsd/tests/active-milestone-id-guard.test.ts +0 -91
- package/src/resources/extensions/gsd/tests/activity-log.test.ts +0 -175
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +0 -143
- package/src/resources/extensions/gsd/tests/atomic-write.test.ts +0 -144
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +0 -50
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +0 -211
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +0 -213
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +0 -2307
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +0 -61
- package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +0 -71
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +0 -209
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +0 -129
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +0 -88
- package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +0 -255
- package/src/resources/extensions/gsd/tests/auto-stale-lock-self-kill.test.ts +0 -87
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +0 -37
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -28
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +0 -218
- package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
- package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +0 -80
- package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +0 -83
- package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -133
- package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +0 -220
- package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +0 -180
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +0 -294
- package/src/resources/extensions/gsd/tests/captures.test.ts +0 -524
- package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +0 -191
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +0 -350
- package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/cmux.test.ts +0 -215
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +0 -506
- package/src/resources/extensions/gsd/tests/collision-diagnostics.test.ts +0 -705
- package/src/resources/extensions/gsd/tests/commands-config.test.ts +0 -24
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +0 -46
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +0 -241
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +0 -283
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +0 -311
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +0 -432
- package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +0 -106
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +0 -454
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +0 -111
- package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +0 -192
- package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +0 -181
- package/src/resources/extensions/gsd/tests/context-budget.test.ts +0 -352
- package/src/resources/extensions/gsd/tests/context-injector.test.ts +0 -313
- package/src/resources/extensions/gsd/tests/context-store.test.ts +0 -454
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +0 -120
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +0 -122
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -535
- package/src/resources/extensions/gsd/tests/custom-verification.test.ts +0 -415
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +0 -339
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +0 -329
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +0 -87
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +0 -131
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +0 -656
- package/src/resources/extensions/gsd/tests/debug-logger.test.ts +0 -185
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +0 -762
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +0 -512
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +0 -121
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +0 -1127
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +0 -641
- package/src/resources/extensions/gsd/tests/derive-state-draft.test.ts +0 -310
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +0 -982
- package/src/resources/extensions/gsd/tests/detection.test.ts +0 -1190
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +0 -314
- package/src/resources/extensions/gsd/tests/diff-context.test.ts +0 -136
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +0 -127
- package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +0 -15
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +0 -281
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +0 -265
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +0 -126
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +0 -172
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +0 -603
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +0 -97
- package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +0 -169
- package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +0 -20
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -74
- package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +0 -271
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +0 -164
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +0 -120
- package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +0 -140
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +0 -101
- package/src/resources/extensions/gsd/tests/export-html-all.test.ts +0 -105
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +0 -379
- package/src/resources/extensions/gsd/tests/extension-selector-separator.test.ts +0 -144
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +0 -18
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +0 -278
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -129
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +0 -121
- package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +0 -43
- package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +0 -232
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +0 -189
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +0 -156
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +0 -593
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +0 -351
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +0 -114
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +0 -440
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +0 -406
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +0 -164
- package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +0 -135
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +0 -97
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +0 -340
- package/src/resources/extensions/gsd/tests/headless-query.test.ts +0 -184
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +0 -179
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +0 -107
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +0 -98
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
- package/src/resources/extensions/gsd/tests/in-flight-tool-tracking.test.ts +0 -32
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +0 -129
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +0 -195
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +0 -248
- package/src/resources/extensions/gsd/tests/integration/atomic-task-closeout.test.ts +0 -72
- package/src/resources/extensions/gsd/tests/integration/auto-preflight.test.ts +0 -38
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +0 -825
- package/src/resources/extensions/gsd/tests/integration/auto-secrets-gate.test.ts +0 -194
- package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +0 -121
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +0 -759
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +0 -348
- package/src/resources/extensions/gsd/tests/integration/continue-here.test.ts +0 -281
- package/src/resources/extensions/gsd/tests/integration/doctor-completion-deferral.test.ts +0 -88
- package/src/resources/extensions/gsd/tests/integration/doctor-delimiter-fix.test.ts +0 -83
- package/src/resources/extensions/gsd/tests/integration/doctor-enhancements.test.ts +0 -243
- package/src/resources/extensions/gsd/tests/integration/doctor-environment-worktree.test.ts +0 -164
- package/src/resources/extensions/gsd/tests/integration/doctor-environment.test.ts +0 -403
- package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +0 -243
- package/src/resources/extensions/gsd/tests/integration/doctor-fixlevel.test.ts +0 -212
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +0 -653
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +0 -325
- package/src/resources/extensions/gsd/tests/integration/doctor-roadmap-summary-atomicity.test.ts +0 -123
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +0 -377
- package/src/resources/extensions/gsd/tests/integration/doctor.test.ts +0 -612
- package/src/resources/extensions/gsd/tests/integration/e2e-workflow-pipeline-integration.test.ts +0 -476
- package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +0 -415
- package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +0 -119
- package/src/resources/extensions/gsd/tests/integration/git-self-heal.test.ts +0 -131
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +0 -1458
- package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +0 -150
- package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +0 -256
- package/src/resources/extensions/gsd/tests/integration/headless-command.ts +0 -534
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +0 -359
- package/src/resources/extensions/gsd/tests/integration/inherited-repo-home-dir.test.ts +0 -191
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +0 -266
- package/src/resources/extensions/gsd/tests/integration/integration-mixed-milestones.test.ts +0 -539
- package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +0 -634
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +0 -360
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -166
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +0 -577
- package/src/resources/extensions/gsd/tests/integration/parallel-workers-multi-milestone-e2e.test.ts +0 -337
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +0 -98
- package/src/resources/extensions/gsd/tests/integration/plugin-importer-live.test.ts +0 -481
- package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +0 -155
- package/src/resources/extensions/gsd/tests/integration/queue-reorder-e2e.test.ts +0 -335
- package/src/resources/extensions/gsd/tests/integration/quick-branch-lifecycle.test.ts +0 -253
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +0 -609
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +0 -959
- package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -364
- package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +0 -237
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +0 -223
- package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +0 -119
- package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +0 -429
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -601
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +0 -147
- package/src/resources/extensions/gsd/tests/journal.test.ts +0 -341
- package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +0 -183
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +0 -429
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +0 -250
- package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +0 -15
- package/src/resources/extensions/gsd/tests/manifest-status.test.ts +0 -274
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +0 -1161
- package/src/resources/extensions/gsd/tests/marketplace-test-fixtures.ts +0 -91
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +0 -103
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +0 -416
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +0 -254
- package/src/resources/extensions/gsd/tests/memory-leak-guards.test.ts +0 -91
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +0 -332
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +0 -66
- package/src/resources/extensions/gsd/tests/metrics.test.ts +0 -384
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +0 -105
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +0 -429
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +0 -748
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +0 -619
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +0 -390
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +0 -295
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +0 -361
- package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +0 -73
- package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +0 -51
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +0 -140
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +0 -130
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +0 -103
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +0 -157
- package/src/resources/extensions/gsd/tests/model-router.test.ts +0 -272
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +0 -220
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +0 -278
- package/src/resources/extensions/gsd/tests/namespaced-registry.test.ts +0 -1027
- package/src/resources/extensions/gsd/tests/namespaced-resolver.test.ts +0 -671
- package/src/resources/extensions/gsd/tests/native-has-changes-cache.test.ts +0 -61
- package/src/resources/extensions/gsd/tests/next-milestone-id.test.ts +0 -23
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +0 -152
- package/src/resources/extensions/gsd/tests/notifications.test.ts +0 -134
- package/src/resources/extensions/gsd/tests/overrides.test.ts +0 -124
- package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +0 -330
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +0 -159
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +0 -284
- package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +0 -150
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +0 -60
- package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +0 -736
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +0 -277
- package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +0 -226
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +0 -199
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +0 -85
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +0 -253
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +0 -354
- package/src/resources/extensions/gsd/tests/parsers.test.ts +0 -1867
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -103
- package/src/resources/extensions/gsd/tests/plan-milestone-queue-context.test.ts +0 -48
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +0 -70
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +0 -231
- package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +0 -474
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +0 -298
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +0 -179
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +0 -145
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +0 -305
- package/src/resources/extensions/gsd/tests/plugin-importer.test.ts +0 -1383
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +0 -171
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +0 -300
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +0 -133
- package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -463
- package/src/resources/extensions/gsd/tests/preflight-context-draft-filter.test.ts +0 -115
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +0 -297
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +0 -174
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +0 -464
- package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +0 -314
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +0 -239
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +0 -387
- package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +0 -178
- package/src/resources/extensions/gsd/tests/prompt-ordering.test.ts +0 -296
- package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +0 -69
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +0 -479
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +0 -347
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +0 -100
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +0 -157
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +0 -192
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +0 -100
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +0 -90
- package/src/resources/extensions/gsd/tests/rate-limit-model-fallback.test.ts +0 -90
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +0 -511
- package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +0 -299
- package/src/resources/extensions/gsd/tests/reassess-detection.test.ts +0 -154
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +0 -442
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +0 -135
- package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +0 -162
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +0 -176
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +0 -281
- package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +0 -59
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +0 -110
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +0 -755
- package/src/resources/extensions/gsd/tests/remote-status.test.ts +0 -99
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +0 -155
- package/src/resources/extensions/gsd/tests/reopen-task.test.ts +0 -165
- package/src/resources/extensions/gsd/tests/replan-handler.test.ts +0 -410
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +0 -606
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +0 -231
- package/src/resources/extensions/gsd/tests/requirements.test.ts +0 -101
- package/src/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
- package/src/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
- package/src/resources/extensions/gsd/tests/retry-diagnostic-reasoning.test.ts +0 -161
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +0 -305
- package/src/resources/extensions/gsd/tests/rewrite-count-persist.test.ts +0 -82
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +0 -399
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +0 -395
- package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +0 -296
- package/src/resources/extensions/gsd/tests/routing-history.test.ts +0 -229
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +0 -411
- package/src/resources/extensions/gsd/tests/run-manager.test.ts +0 -229
- package/src/resources/extensions/gsd/tests/schema-v9-sequence.test.ts +0 -176
- package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +0 -319
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +0 -127
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +0 -166
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +0 -315
- package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +0 -224
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +0 -209
- package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +0 -181
- package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +0 -103
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +0 -233
- package/src/resources/extensions/gsd/tests/skill-catalog.test.ts +0 -193
- package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +0 -126
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +0 -233
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +0 -53
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +0 -123
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +0 -65
- package/src/resources/extensions/gsd/tests/stale-milestone-id-reservation.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +0 -139
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +0 -100
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +0 -125
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +0 -305
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +0 -405
- package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +0 -257
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +0 -1628
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +0 -30
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +0 -67
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +0 -106
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +0 -158
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +0 -366
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +0 -174
- package/src/resources/extensions/gsd/tests/subagent-agent-discovery.test.ts +0 -44
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +0 -221
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +0 -108
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +0 -145
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +0 -122
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +0 -84
- package/src/resources/extensions/gsd/tests/test-utils.ts +0 -165
- package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +0 -118
- package/src/resources/extensions/gsd/tests/token-counter.test.ts +0 -129
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +0 -268
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +0 -166
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +0 -125
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +0 -345
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +0 -563
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +0 -289
- package/src/resources/extensions/gsd/tests/unborn-branch.test.ts +0 -85
- package/src/resources/extensions/gsd/tests/undo.test.ts +0 -462
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +0 -203
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +0 -258
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +0 -257
- package/src/resources/extensions/gsd/tests/update-command.test.ts +0 -67
- package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +0 -115
- package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +0 -154
- package/src/resources/extensions/gsd/tests/validate-directory.test.ts +0 -237
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +0 -115
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +0 -393
- package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +0 -166
- package/src/resources/extensions/gsd/tests/validation.test.ts +0 -72
- package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +0 -156
- package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +0 -601
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +0 -999
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +0 -82
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +0 -143
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +0 -444
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +0 -235
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +0 -716
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +0 -97
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +0 -146
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +0 -205
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +0 -403
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +0 -278
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +0 -173
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +0 -171
- package/src/resources/extensions/gsd/tests/workspace-index.test.ts +0 -38
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +0 -117
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -202
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +0 -140
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +0 -175
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +0 -445
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +0 -142
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +0 -181
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +0 -200
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +0 -220
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +0 -238
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +0 -101
- package/src/resources/extensions/gsd/tests/worktree-post-create-hook.test.ts +0 -165
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +0 -155
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -962
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +0 -65
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +0 -133
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +0 -617
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +0 -204
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +0 -206
- package/src/resources/extensions/gsd/tests/worktree.test.ts +0 -279
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +0 -193
- package/src/resources/extensions/gsd/tests/write-intercept.test.ts +0 -76
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +0 -95
- package/src/resources/extensions/gsd/token-counter.ts +0 -65
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +0 -229
- package/src/resources/extensions/gsd/tools/complete-slice.ts +0 -340
- package/src/resources/extensions/gsd/tools/complete-task.ts +0 -257
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +0 -304
- package/src/resources/extensions/gsd/tools/plan-slice.ts +0 -250
- package/src/resources/extensions/gsd/tools/plan-task.ts +0 -152
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +0 -288
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +0 -126
- package/src/resources/extensions/gsd/tools/reopen-task.ts +0 -130
- package/src/resources/extensions/gsd/tools/replan-slice.ts +0 -243
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +0 -156
- package/src/resources/extensions/gsd/triage-resolution.ts +0 -413
- package/src/resources/extensions/gsd/triage-ui.ts +0 -187
- package/src/resources/extensions/gsd/types.ts +0 -593
- package/src/resources/extensions/gsd/undo.ts +0 -464
- package/src/resources/extensions/gsd/unit-id.ts +0 -14
- package/src/resources/extensions/gsd/unit-ownership.ts +0 -275
- package/src/resources/extensions/gsd/unit-runtime.ts +0 -189
- package/src/resources/extensions/gsd/validate-directory.ts +0 -164
- package/src/resources/extensions/gsd/validation.ts +0 -23
- package/src/resources/extensions/gsd/verdict-parser.ts +0 -110
- package/src/resources/extensions/gsd/verification-evidence.ts +0 -202
- package/src/resources/extensions/gsd/verification-gate.ts +0 -634
- package/src/resources/extensions/gsd/visualizer-data.ts +0 -953
- package/src/resources/extensions/gsd/visualizer-overlay.ts +0 -566
- package/src/resources/extensions/gsd/visualizer-views.ts +0 -1229
- package/src/resources/extensions/gsd/workflow-engine.ts +0 -38
- package/src/resources/extensions/gsd/workflow-events.ts +0 -154
- package/src/resources/extensions/gsd/workflow-logger.ts +0 -244
- package/src/resources/extensions/gsd/workflow-manifest.ts +0 -351
- package/src/resources/extensions/gsd/workflow-migration.ts +0 -345
- package/src/resources/extensions/gsd/workflow-projections.ts +0 -458
- package/src/resources/extensions/gsd/workflow-reconcile.ts +0 -532
- package/src/resources/extensions/gsd/workflow-templates/bugfix.md +0 -87
- package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +0 -74
- package/src/resources/extensions/gsd/workflow-templates/full-project.md +0 -40
- package/src/resources/extensions/gsd/workflow-templates/hotfix.md +0 -45
- package/src/resources/extensions/gsd/workflow-templates/refactor.md +0 -83
- package/src/resources/extensions/gsd/workflow-templates/registry.json +0 -85
- package/src/resources/extensions/gsd/workflow-templates/security-audit.md +0 -73
- package/src/resources/extensions/gsd/workflow-templates/small-feature.md +0 -81
- package/src/resources/extensions/gsd/workflow-templates/spike.md +0 -69
- package/src/resources/extensions/gsd/workflow-templates.ts +0 -252
- package/src/resources/extensions/gsd/workspace-index.ts +0 -272
- package/src/resources/extensions/gsd/worktree-command-bootstrap.ts +0 -46
- package/src/resources/extensions/gsd/worktree-command.ts +0 -846
- package/src/resources/extensions/gsd/worktree-health.ts +0 -178
- package/src/resources/extensions/gsd/worktree-manager.ts +0 -630
- package/src/resources/extensions/gsd/worktree-resolver.ts +0 -640
- package/src/resources/extensions/gsd/worktree.ts +0 -336
- package/src/resources/extensions/gsd/write-intercept.ts +0 -90
|
@@ -1,1897 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GSD Auto-Worktree -- lifecycle management for auto-mode worktrees.
|
|
3
|
-
*
|
|
4
|
-
* Auto-mode creates worktrees with `milestone/<MID>` branches (distinct from
|
|
5
|
-
* manual `/worktree` which uses `worktree/<name>` branches). This module
|
|
6
|
-
* manages create, enter, detect, and teardown for auto-mode worktrees.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
existsSync,
|
|
11
|
-
cpSync,
|
|
12
|
-
readFileSync,
|
|
13
|
-
readdirSync,
|
|
14
|
-
mkdirSync,
|
|
15
|
-
realpathSync,
|
|
16
|
-
rmSync,
|
|
17
|
-
unlinkSync,
|
|
18
|
-
statSync,
|
|
19
|
-
lstatSync as lstatSyncFn,
|
|
20
|
-
} from "node:fs";
|
|
21
|
-
import { isAbsolute, join, sep as pathSep } from "node:path";
|
|
22
|
-
import { homedir } from "node:os";
|
|
23
|
-
import { GSDError, GSD_IO_ERROR, GSD_GIT_ERROR } from "./errors.js";
|
|
24
|
-
import {
|
|
25
|
-
reconcileWorktreeDb,
|
|
26
|
-
isDbAvailable,
|
|
27
|
-
getMilestone,
|
|
28
|
-
getMilestoneSlices,
|
|
29
|
-
} from "./gsd-db.js";
|
|
30
|
-
import { atomicWriteSync } from "./atomic-write.js";
|
|
31
|
-
import { execFileSync } from "node:child_process";
|
|
32
|
-
import { safeCopy, safeCopyRecursive } from "./safe-fs.js";
|
|
33
|
-
import { gsdRoot } from "./paths.js";
|
|
34
|
-
import {
|
|
35
|
-
createWorktree,
|
|
36
|
-
removeWorktree,
|
|
37
|
-
resolveGitDir,
|
|
38
|
-
worktreePath,
|
|
39
|
-
} from "./worktree-manager.js";
|
|
40
|
-
import {
|
|
41
|
-
detectWorktreeName,
|
|
42
|
-
resolveGitHeadPath,
|
|
43
|
-
nudgeGitBranchCache,
|
|
44
|
-
} from "./worktree.js";
|
|
45
|
-
import { MergeConflictError, readIntegrationBranch, RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
|
|
46
|
-
import { debugLog } from "./debug-logger.js";
|
|
47
|
-
import { logWarning } from "./workflow-logger.js";
|
|
48
|
-
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
49
|
-
import {
|
|
50
|
-
nativeGetCurrentBranch,
|
|
51
|
-
nativeDetectMainBranch,
|
|
52
|
-
nativeWorkingTreeStatus,
|
|
53
|
-
nativeAddAllWithExclusions,
|
|
54
|
-
nativeCommit,
|
|
55
|
-
nativeCheckoutBranch,
|
|
56
|
-
nativeMergeSquash,
|
|
57
|
-
nativeConflictFiles,
|
|
58
|
-
nativeCheckoutTheirs,
|
|
59
|
-
nativeAddPaths,
|
|
60
|
-
nativeRmForce,
|
|
61
|
-
nativeBranchDelete,
|
|
62
|
-
nativeBranchExists,
|
|
63
|
-
nativeDiffNumstat,
|
|
64
|
-
nativeUpdateRef,
|
|
65
|
-
nativeIsAncestor,
|
|
66
|
-
nativeMergeAbort,
|
|
67
|
-
} from "./native-git-bridge.js";
|
|
68
|
-
|
|
69
|
-
const gsdHome = process.env.LSD_HOME || join(homedir(), ".lsd");
|
|
70
|
-
const PROJECT_PREFERENCES_FILE = "PREFERENCES.md";
|
|
71
|
-
const LEGACY_PROJECT_PREFERENCES_FILE = "preferences.md";
|
|
72
|
-
|
|
73
|
-
// ─── Shared Constants & Helpers ─────────────────────────────────────────────
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Root-level .gsd/ state files synced between worktree and project root.
|
|
77
|
-
* Single source of truth — used by syncGsdStateToWorktree, syncWorktreeStateBack,
|
|
78
|
-
* and the dispatch-level sync functions.
|
|
79
|
-
*/
|
|
80
|
-
const ROOT_STATE_FILES = [
|
|
81
|
-
"DECISIONS.md",
|
|
82
|
-
"REQUIREMENTS.md",
|
|
83
|
-
"PROJECT.md",
|
|
84
|
-
"KNOWLEDGE.md",
|
|
85
|
-
"OVERRIDES.md",
|
|
86
|
-
"QUEUE.md",
|
|
87
|
-
"completed-units.json",
|
|
88
|
-
"metrics.json",
|
|
89
|
-
"mcp.json",
|
|
90
|
-
// NOTE: project preferences are intentionally NOT in ROOT_STATE_FILES.
|
|
91
|
-
// Forward-sync (main → worktree) is handled explicitly in syncGsdStateToWorktree().
|
|
92
|
-
// Back-sync (worktree → main) must NEVER overwrite the project root's copy
|
|
93
|
-
// because the project root is authoritative for preferences (#2684).
|
|
94
|
-
] as const;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Check if two filesystem paths resolve to the same real location.
|
|
98
|
-
* Returns false if either path cannot be resolved (e.g. doesn't exist).
|
|
99
|
-
*/
|
|
100
|
-
function isSamePath(a: string, b: string): boolean {
|
|
101
|
-
try {
|
|
102
|
-
return realpathSync(a) === realpathSync(b);
|
|
103
|
-
} catch {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// ─── ASSESSMENT Force-Sync Helper (#2821) ─────────────────────────────────
|
|
109
|
-
|
|
110
|
-
/** Regex matching YAML frontmatter `verdict:` field. */
|
|
111
|
-
const VERDICT_RE = /verdict:\s*[\w-]+/i;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Walk a milestone directory and force-overwrite ASSESSMENT files in the
|
|
115
|
-
* destination when the source copy contains a `verdict:` field.
|
|
116
|
-
*
|
|
117
|
-
* This is the targeted fix for the UAT stuck-loop (#2821): the main
|
|
118
|
-
* safeCopyRecursive uses force:false to protect worktree-authoritative
|
|
119
|
-
* files (#1886), but ASSESSMENT files written by run-uat must be
|
|
120
|
-
* forward-synced when the project root has a verdict. Without this,
|
|
121
|
-
* the worktree retains a stale FAIL or missing ASSESSMENT and
|
|
122
|
-
* checkNeedsRunUat re-dispatches run-uat indefinitely.
|
|
123
|
-
*
|
|
124
|
-
* Only overwrites when the source has a verdict — never clobbers a
|
|
125
|
-
* worktree ASSESSMENT with a verdictless project-root copy.
|
|
126
|
-
*/
|
|
127
|
-
function forceOverwriteAssessmentsWithVerdict(
|
|
128
|
-
srcMilestoneDir: string,
|
|
129
|
-
dstMilestoneDir: string,
|
|
130
|
-
): void {
|
|
131
|
-
if (!existsSync(srcMilestoneDir)) return;
|
|
132
|
-
|
|
133
|
-
// Walk slices/<SID>/ looking for *-ASSESSMENT.md files
|
|
134
|
-
const slicesDir = join(srcMilestoneDir, "slices");
|
|
135
|
-
if (!existsSync(slicesDir)) return;
|
|
136
|
-
|
|
137
|
-
try {
|
|
138
|
-
for (const sliceEntry of readdirSync(slicesDir, { withFileTypes: true })) {
|
|
139
|
-
if (!sliceEntry.isDirectory()) continue;
|
|
140
|
-
const srcSliceDir = join(slicesDir, sliceEntry.name);
|
|
141
|
-
const dstSliceDir = join(dstMilestoneDir, "slices", sliceEntry.name);
|
|
142
|
-
|
|
143
|
-
try {
|
|
144
|
-
for (const fileEntry of readdirSync(srcSliceDir, { withFileTypes: true })) {
|
|
145
|
-
if (!fileEntry.isFile()) continue;
|
|
146
|
-
if (!fileEntry.name.endsWith("-ASSESSMENT.md")) continue;
|
|
147
|
-
|
|
148
|
-
const srcFile = join(srcSliceDir, fileEntry.name);
|
|
149
|
-
try {
|
|
150
|
-
const srcContent = readFileSync(srcFile, "utf-8");
|
|
151
|
-
if (!VERDICT_RE.test(srcContent)) continue; // no verdict in source — skip
|
|
152
|
-
|
|
153
|
-
// Source has a verdict — force-copy into worktree
|
|
154
|
-
mkdirSync(dstSliceDir, { recursive: true });
|
|
155
|
-
safeCopy(srcFile, join(dstSliceDir, fileEntry.name), { force: true });
|
|
156
|
-
} catch {
|
|
157
|
-
/* non-fatal per file */
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
} catch {
|
|
161
|
-
/* non-fatal per slice */
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
} catch {
|
|
165
|
-
/* non-fatal */
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// ─── Module State ──────────────────────────────────────────────────────────
|
|
170
|
-
|
|
171
|
-
/** Original project root before chdir into auto-worktree. */
|
|
172
|
-
let originalBase: string | null = null;
|
|
173
|
-
|
|
174
|
-
function clearProjectRootStateFiles(basePath: string, milestoneId: string): void {
|
|
175
|
-
const gsdDir = gsdRoot(basePath);
|
|
176
|
-
const transientFiles = [
|
|
177
|
-
join(gsdDir, "STATE.md"),
|
|
178
|
-
join(gsdDir, "auto.lock"),
|
|
179
|
-
join(gsdDir, "milestones", milestoneId, `${milestoneId}-META.json`),
|
|
180
|
-
];
|
|
181
|
-
|
|
182
|
-
for (const file of transientFiles) {
|
|
183
|
-
try {
|
|
184
|
-
unlinkSync(file);
|
|
185
|
-
} catch {
|
|
186
|
-
/* non-fatal — file may not exist */
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Clean up entire synced milestone directory and runtime/units.
|
|
191
|
-
// syncStateToProjectRoot() copies these into the project root during
|
|
192
|
-
// execution. If they remain as untracked files when we attempt
|
|
193
|
-
// `git merge --squash`, git rejects the merge with "local changes would
|
|
194
|
-
// be overwritten", causing silent data loss (#1738).
|
|
195
|
-
const syncedDirs = [
|
|
196
|
-
join(gsdDir, "milestones", milestoneId),
|
|
197
|
-
join(gsdDir, "runtime", "units"),
|
|
198
|
-
];
|
|
199
|
-
|
|
200
|
-
for (const dir of syncedDirs) {
|
|
201
|
-
try {
|
|
202
|
-
if (existsSync(dir)) {
|
|
203
|
-
// Only remove files that are untracked by git — tracked files are
|
|
204
|
-
// managed by the branch checkout and should not be deleted.
|
|
205
|
-
const untrackedOutput = execFileSync(
|
|
206
|
-
"git",
|
|
207
|
-
["ls-files", "--others", "--exclude-standard", dir],
|
|
208
|
-
{ cwd: basePath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
|
|
209
|
-
).trim();
|
|
210
|
-
if (untrackedOutput) {
|
|
211
|
-
for (const f of untrackedOutput.split("\n").filter(Boolean)) {
|
|
212
|
-
try {
|
|
213
|
-
unlinkSync(join(basePath, f));
|
|
214
|
-
} catch {
|
|
215
|
-
/* non-fatal */
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
} catch {
|
|
221
|
-
/* non-fatal — git command may fail if not in repo */
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// ─── Build Artifact Auto-Resolve ─────────────────────────────────────────────
|
|
227
|
-
|
|
228
|
-
/** Patterns for machine-generated build artifacts that can be safely
|
|
229
|
-
* auto-resolved by accepting --theirs during merge. These files are
|
|
230
|
-
* regenerable and never contain meaningful manual edits. */
|
|
231
|
-
export const SAFE_AUTO_RESOLVE_PATTERNS: RegExp[] = [
|
|
232
|
-
/\.tsbuildinfo$/,
|
|
233
|
-
/\.pyc$/,
|
|
234
|
-
/\/__pycache__\//,
|
|
235
|
-
/\.DS_Store$/,
|
|
236
|
-
/\.map$/,
|
|
237
|
-
];
|
|
238
|
-
|
|
239
|
-
/** Returns true if the file path is safe to auto-resolve during merge.
|
|
240
|
-
* Covers `.gsd/` state files and common build artifacts. */
|
|
241
|
-
export const isSafeToAutoResolve = (filePath: string): boolean =>
|
|
242
|
-
filePath.startsWith(".gsd/") ||
|
|
243
|
-
SAFE_AUTO_RESOLVE_PATTERNS.some((re) => re.test(filePath));
|
|
244
|
-
|
|
245
|
-
// ─── Dispatch-Level Sync (project root ↔ worktree) ──────────────────────────
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Sync milestone artifacts from project root INTO worktree before deriveState.
|
|
249
|
-
* Covers the case where the LLM wrote artifacts to the main repo filesystem
|
|
250
|
-
* (e.g. via absolute paths) but the worktree has stale data. Also deletes
|
|
251
|
-
* gsd.db in the worktree so it rebuilds from fresh disk state (#853).
|
|
252
|
-
* Non-fatal — sync failure should never block dispatch.
|
|
253
|
-
*/
|
|
254
|
-
export function syncProjectRootToWorktree(
|
|
255
|
-
projectRoot: string,
|
|
256
|
-
worktreePath_: string,
|
|
257
|
-
milestoneId: string | null,
|
|
258
|
-
): void {
|
|
259
|
-
if (!worktreePath_ || !projectRoot || worktreePath_ === projectRoot) return;
|
|
260
|
-
if (!milestoneId) return;
|
|
261
|
-
|
|
262
|
-
const prGsd = join(projectRoot, ".gsd");
|
|
263
|
-
const wtGsd = join(worktreePath_, ".gsd");
|
|
264
|
-
|
|
265
|
-
// When .gsd is a symlink to the same external directory in both locations,
|
|
266
|
-
// cpSync rejects the copy because source === destination (ERR_FS_CP_EINVAL).
|
|
267
|
-
// Compare realpaths and skip when they resolve to the same physical path (#2184).
|
|
268
|
-
if (isSamePath(prGsd, wtGsd)) return;
|
|
269
|
-
|
|
270
|
-
// Copy milestone directory from project root to worktree — additive only.
|
|
271
|
-
// force:false prevents cpSync from overwriting existing worktree files.
|
|
272
|
-
// Without this, worktree-authoritative files (e.g. VALIDATION.md written
|
|
273
|
-
// by validate-milestone) get clobbered by stale project root copies,
|
|
274
|
-
// causing an infinite re-validation loop (#1886).
|
|
275
|
-
safeCopyRecursive(
|
|
276
|
-
join(prGsd, "milestones", milestoneId),
|
|
277
|
-
join(wtGsd, "milestones", milestoneId),
|
|
278
|
-
{ force: false },
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
// Force-sync ASSESSMENT files that have a verdict from project root (#2821).
|
|
282
|
-
// The additive-only copy above preserves worktree-authoritative files, but
|
|
283
|
-
// ASSESSMENT files are special: after run-uat writes a verdict and post-unit
|
|
284
|
-
// syncs it to the project root, the worktree may retain a stale copy (e.g.
|
|
285
|
-
// verdict:fail while the project root has verdict:pass from a retry). On
|
|
286
|
-
// session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
|
|
287
|
-
// persists, checkNeedsRunUat finds no passing verdict → re-dispatches
|
|
288
|
-
// run-uat indefinitely (stuck-loop ×9).
|
|
289
|
-
forceOverwriteAssessmentsWithVerdict(
|
|
290
|
-
join(prGsd, "milestones", milestoneId),
|
|
291
|
-
join(wtGsd, "milestones", milestoneId),
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
// Forward-sync completed-units.json from project root to worktree.
|
|
295
|
-
// Project root is authoritative for completion state after crash recovery;
|
|
296
|
-
// without this, the worktree re-dispatches already-completed units (#1886).
|
|
297
|
-
safeCopy(
|
|
298
|
-
join(prGsd, "completed-units.json"),
|
|
299
|
-
join(wtGsd, "completed-units.json"),
|
|
300
|
-
{ force: true },
|
|
301
|
-
);
|
|
302
|
-
|
|
303
|
-
// Delete worktree gsd.db ONLY if it is empty (0 bytes).
|
|
304
|
-
// An empty DB is stale/corrupt and should be rebuilt (#853).
|
|
305
|
-
// A non-empty DB was populated by gsd-migrate on respawn and must be
|
|
306
|
-
// preserved — deleting it truncates the file to 0 bytes when
|
|
307
|
-
// openDatabase re-creates it, causing "no such table" failures (#2815).
|
|
308
|
-
try {
|
|
309
|
-
const wtDb = join(wtGsd, "gsd.db");
|
|
310
|
-
if (existsSync(wtDb)) {
|
|
311
|
-
const size = statSync(wtDb).size;
|
|
312
|
-
if (size === 0) {
|
|
313
|
-
unlinkSync(wtDb);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
} catch {
|
|
317
|
-
/* non-fatal */
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Sync dispatch-critical .gsd/ state files from worktree to project root.
|
|
323
|
-
* Only runs when inside an auto-worktree (worktreePath differs from projectRoot).
|
|
324
|
-
* Copies: STATE.md + active milestone directory (roadmap, slice plans, task summaries).
|
|
325
|
-
* Non-fatal — sync failure should never block dispatch.
|
|
326
|
-
*/
|
|
327
|
-
export function syncStateToProjectRoot(
|
|
328
|
-
worktreePath_: string,
|
|
329
|
-
projectRoot: string,
|
|
330
|
-
milestoneId: string | null,
|
|
331
|
-
): void {
|
|
332
|
-
if (!worktreePath_ || !projectRoot || worktreePath_ === projectRoot) return;
|
|
333
|
-
if (!milestoneId) return;
|
|
334
|
-
|
|
335
|
-
const wtGsd = join(worktreePath_, ".gsd");
|
|
336
|
-
const prGsd = join(projectRoot, ".gsd");
|
|
337
|
-
|
|
338
|
-
// When .gsd is a symlink to the same external directory in both locations,
|
|
339
|
-
// cpSync rejects the copy because source === destination (ERR_FS_CP_EINVAL).
|
|
340
|
-
// Compare realpaths and skip when they resolve to the same physical path (#2184).
|
|
341
|
-
if (isSamePath(wtGsd, prGsd)) return;
|
|
342
|
-
|
|
343
|
-
// 1. STATE.md — the quick-glance status used by initial deriveState()
|
|
344
|
-
safeCopy(join(wtGsd, "STATE.md"), join(prGsd, "STATE.md"), { force: true });
|
|
345
|
-
|
|
346
|
-
// 2. Milestone directory — ROADMAP, slice PLANs, task summaries
|
|
347
|
-
// Copy the entire milestone .gsd subtree so deriveState reads current checkboxes
|
|
348
|
-
safeCopyRecursive(
|
|
349
|
-
join(wtGsd, "milestones", milestoneId),
|
|
350
|
-
join(prGsd, "milestones", milestoneId),
|
|
351
|
-
{ force: true },
|
|
352
|
-
);
|
|
353
|
-
|
|
354
|
-
// 3. metrics.json — session cost/token tracking (#2313).
|
|
355
|
-
// Without this, metrics accumulated in the worktree are invisible from the
|
|
356
|
-
// project root and never appear in the dashboard or skill-health reports.
|
|
357
|
-
safeCopy(join(wtGsd, "metrics.json"), join(prGsd, "metrics.json"), { force: true });
|
|
358
|
-
|
|
359
|
-
// 4. Runtime records — unit dispatch state used by selfHealRuntimeRecords().
|
|
360
|
-
// Without this, a crash during a unit leaves the runtime record only in the
|
|
361
|
-
// worktree. If the next session resolves basePath before worktree re-entry,
|
|
362
|
-
// selfHeal can't find or clear the stale record (#769).
|
|
363
|
-
safeCopyRecursive(
|
|
364
|
-
join(wtGsd, "runtime", "units"),
|
|
365
|
-
join(prGsd, "runtime", "units"),
|
|
366
|
-
{ force: true },
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// ─── Resource Staleness ───────────────────────────────────────────────────
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Read the resource version (semver) from the managed-resources manifest.
|
|
374
|
-
* Uses gsdVersion instead of syncedAt so that launching a second session
|
|
375
|
-
* doesn't falsely trigger staleness (#804).
|
|
376
|
-
*/
|
|
377
|
-
export function readResourceVersion(): string | null {
|
|
378
|
-
const agentDir =
|
|
379
|
-
process.env.GSD_CODING_AGENT_DIR || join(gsdHome, "agent");
|
|
380
|
-
const manifestPath = join(agentDir, "managed-resources.json");
|
|
381
|
-
try {
|
|
382
|
-
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
383
|
-
return typeof manifest?.gsdVersion === "string"
|
|
384
|
-
? manifest.gsdVersion
|
|
385
|
-
: null;
|
|
386
|
-
} catch {
|
|
387
|
-
return null;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* Check if managed resources have been updated since session start.
|
|
393
|
-
* Returns a warning message if stale, null otherwise.
|
|
394
|
-
*/
|
|
395
|
-
export function checkResourcesStale(
|
|
396
|
-
versionOnStart: string | null,
|
|
397
|
-
): string | null {
|
|
398
|
-
if (versionOnStart === null) return null;
|
|
399
|
-
const current = readResourceVersion();
|
|
400
|
-
if (current === null) return null;
|
|
401
|
-
if (current !== versionOnStart) {
|
|
402
|
-
return "GSD resources were updated since this session started. Restart gsd to load the new code.";
|
|
403
|
-
}
|
|
404
|
-
return null;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// ─── Stale Worktree Escape ────────────────────────────────────────────────
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Detect and escape a stale worktree cwd (#608).
|
|
411
|
-
*
|
|
412
|
-
* After milestone completion + merge, the worktree directory is removed but
|
|
413
|
-
* the process cwd may still point inside `.gsd/worktrees/<MID>/`.
|
|
414
|
-
* When a new session starts, `process.cwd()` is passed as `base` to startAuto
|
|
415
|
-
* and all subsequent writes land in the wrong directory. This function detects
|
|
416
|
-
* that scenario and chdir back to the project root.
|
|
417
|
-
*
|
|
418
|
-
* Returns the corrected base path.
|
|
419
|
-
*/
|
|
420
|
-
export function escapeStaleWorktree(base: string): string {
|
|
421
|
-
// Direct layout: /.gsd/worktrees/
|
|
422
|
-
const directMarker = `${pathSep}.gsd${pathSep}worktrees${pathSep}`;
|
|
423
|
-
let idx = base.indexOf(directMarker);
|
|
424
|
-
if (idx === -1) {
|
|
425
|
-
// Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/
|
|
426
|
-
const symlinkRe = new RegExp(
|
|
427
|
-
`\\${pathSep}\\.gsd\\${pathSep}projects\\${pathSep}[a-f0-9]+\\${pathSep}worktrees\\${pathSep}`,
|
|
428
|
-
);
|
|
429
|
-
const match = base.match(symlinkRe);
|
|
430
|
-
if (!match || match.index === undefined) return base;
|
|
431
|
-
idx = match.index;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// base is inside .gsd/worktrees/<something> — extract the project root
|
|
435
|
-
const projectRoot = base.slice(0, idx);
|
|
436
|
-
|
|
437
|
-
// Guard: If the candidate project root's .gsd IS the user-level ~/.gsd,
|
|
438
|
-
// the string-slice heuristic matched the wrong /.gsd/ boundary. This happens
|
|
439
|
-
// when .gsd is a symlink into ~/.gsd/projects/<hash> and process.cwd()
|
|
440
|
-
// resolved through the symlink. Returning ~ would be catastrophic (#1676).
|
|
441
|
-
const candidateGsd = join(projectRoot, ".gsd").replaceAll("\\", "/");
|
|
442
|
-
const gsdHomePath = gsdHome.replaceAll("\\", "/");
|
|
443
|
-
if (candidateGsd === gsdHomePath || candidateGsd.startsWith(gsdHomePath + "/")) {
|
|
444
|
-
// Don't chdir to home — return base unchanged.
|
|
445
|
-
// resolveProjectRoot() in worktree.ts has the full git-file-based recovery
|
|
446
|
-
// and will be called by the caller (startAuto → projectRoot()).
|
|
447
|
-
return base;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
try {
|
|
451
|
-
process.chdir(projectRoot);
|
|
452
|
-
} catch {
|
|
453
|
-
// If chdir fails, return the original — caller will handle errors downstream
|
|
454
|
-
return base;
|
|
455
|
-
}
|
|
456
|
-
return projectRoot;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* Clean stale runtime unit files for completed milestones.
|
|
461
|
-
*
|
|
462
|
-
* After restart, stale runtime/units/*.json from prior milestones can
|
|
463
|
-
* cause deriveState to resume the wrong milestone (#887). Removes files
|
|
464
|
-
* for milestones that have a SUMMARY (fully complete).
|
|
465
|
-
*/
|
|
466
|
-
export function cleanStaleRuntimeUnits(
|
|
467
|
-
gsdRootPath: string,
|
|
468
|
-
hasMilestoneSummary: (mid: string) => boolean,
|
|
469
|
-
): number {
|
|
470
|
-
const runtimeUnitsDir = join(gsdRootPath, "runtime", "units");
|
|
471
|
-
if (!existsSync(runtimeUnitsDir)) return 0;
|
|
472
|
-
|
|
473
|
-
let cleaned = 0;
|
|
474
|
-
try {
|
|
475
|
-
for (const file of readdirSync(runtimeUnitsDir)) {
|
|
476
|
-
if (!file.endsWith(".json")) continue;
|
|
477
|
-
const midMatch = file.match(/(M\d+(?:-[a-z0-9]{6})?)/);
|
|
478
|
-
if (!midMatch) continue;
|
|
479
|
-
if (hasMilestoneSummary(midMatch[1])) {
|
|
480
|
-
try {
|
|
481
|
-
unlinkSync(join(runtimeUnitsDir, file));
|
|
482
|
-
cleaned++;
|
|
483
|
-
} catch {
|
|
484
|
-
/* non-fatal */
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
} catch {
|
|
489
|
-
/* non-fatal */
|
|
490
|
-
}
|
|
491
|
-
return cleaned;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
// ─── Worktree ↔ Main Repo Sync (#1311) ──────────────────────────────────────
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Sync .gsd/ state from the main repo into the worktree.
|
|
498
|
-
*
|
|
499
|
-
* When .gsd/ is a symlink to the external state directory, both the main
|
|
500
|
-
* repo and worktree share the same directory — no sync needed.
|
|
501
|
-
*
|
|
502
|
-
* When .gsd/ is a real directory (e.g., git-tracked or manage_gitignore:false),
|
|
503
|
-
* the worktree has its own copy that may be stale. This function copies
|
|
504
|
-
* missing milestones, CONTEXT, ROADMAP, DECISIONS, REQUIREMENTS, and
|
|
505
|
-
* PROJECT files from the main repo's .gsd/ into the worktree's .gsd/.
|
|
506
|
-
*
|
|
507
|
-
* Only adds missing content — never overwrites existing files in the worktree
|
|
508
|
-
* (the worktree's execution state is authoritative for in-progress work).
|
|
509
|
-
*/
|
|
510
|
-
export function syncGsdStateToWorktree(
|
|
511
|
-
mainBasePath: string,
|
|
512
|
-
worktreePath_: string,
|
|
513
|
-
): { synced: string[] } {
|
|
514
|
-
const mainGsd = gsdRoot(mainBasePath);
|
|
515
|
-
const wtGsd = gsdRoot(worktreePath_);
|
|
516
|
-
const synced: string[] = [];
|
|
517
|
-
|
|
518
|
-
// If both resolve to the same directory (symlink), no sync needed
|
|
519
|
-
if (isSamePath(mainGsd, wtGsd)) return { synced };
|
|
520
|
-
|
|
521
|
-
if (!existsSync(mainGsd) || !existsSync(wtGsd)) return { synced };
|
|
522
|
-
|
|
523
|
-
// Sync root-level .gsd/ files (DECISIONS, REQUIREMENTS, PROJECT, KNOWLEDGE, etc.)
|
|
524
|
-
for (const f of ROOT_STATE_FILES) {
|
|
525
|
-
const src = join(mainGsd, f);
|
|
526
|
-
const dst = join(wtGsd, f);
|
|
527
|
-
if (existsSync(src) && !existsSync(dst)) {
|
|
528
|
-
try {
|
|
529
|
-
cpSync(src, dst);
|
|
530
|
-
synced.push(f);
|
|
531
|
-
} catch {
|
|
532
|
-
/* non-fatal */
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
// Forward-sync project preferences from project root to worktree (additive only).
|
|
538
|
-
// Prefer the canonical uppercase file name, but keep the legacy lowercase
|
|
539
|
-
// fallback so older repos still work on case-sensitive filesystems.
|
|
540
|
-
{
|
|
541
|
-
const worktreeHasPreferences = existsSync(join(wtGsd, PROJECT_PREFERENCES_FILE))
|
|
542
|
-
|| existsSync(join(wtGsd, LEGACY_PROJECT_PREFERENCES_FILE));
|
|
543
|
-
if (!worktreeHasPreferences) {
|
|
544
|
-
for (const file of [PROJECT_PREFERENCES_FILE, LEGACY_PROJECT_PREFERENCES_FILE] as const) {
|
|
545
|
-
const src = join(mainGsd, file);
|
|
546
|
-
const dst = join(wtGsd, file);
|
|
547
|
-
if (existsSync(src)) {
|
|
548
|
-
try {
|
|
549
|
-
cpSync(src, dst);
|
|
550
|
-
synced.push(file);
|
|
551
|
-
} catch {
|
|
552
|
-
/* non-fatal */
|
|
553
|
-
}
|
|
554
|
-
break;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
// Sync milestones: copy entire milestone directories that are missing
|
|
561
|
-
const mainMilestonesDir = join(mainGsd, "milestones");
|
|
562
|
-
const wtMilestonesDir = join(wtGsd, "milestones");
|
|
563
|
-
if (existsSync(mainMilestonesDir)) {
|
|
564
|
-
try {
|
|
565
|
-
mkdirSync(wtMilestonesDir, { recursive: true });
|
|
566
|
-
const mainMilestones = readdirSync(mainMilestonesDir, {
|
|
567
|
-
withFileTypes: true,
|
|
568
|
-
})
|
|
569
|
-
.filter((d) => d.isDirectory())
|
|
570
|
-
.map((d) => d.name);
|
|
571
|
-
|
|
572
|
-
for (const mid of mainMilestones) {
|
|
573
|
-
const srcDir = join(mainMilestonesDir, mid);
|
|
574
|
-
const dstDir = join(wtMilestonesDir, mid);
|
|
575
|
-
|
|
576
|
-
if (!existsSync(dstDir)) {
|
|
577
|
-
// Entire milestone missing from worktree — copy it
|
|
578
|
-
try {
|
|
579
|
-
cpSync(srcDir, dstDir, { recursive: true });
|
|
580
|
-
synced.push(`milestones/${mid}/`);
|
|
581
|
-
} catch {
|
|
582
|
-
/* non-fatal */
|
|
583
|
-
}
|
|
584
|
-
} else {
|
|
585
|
-
// Milestone directory exists but may be missing files (stale snapshot).
|
|
586
|
-
// Sync individual top-level milestone files (CONTEXT, ROADMAP, RESEARCH, etc.)
|
|
587
|
-
try {
|
|
588
|
-
const srcFiles = readdirSync(srcDir).filter(
|
|
589
|
-
(f) => f.endsWith(".md") || f.endsWith(".json"),
|
|
590
|
-
);
|
|
591
|
-
for (const f of srcFiles) {
|
|
592
|
-
const srcFile = join(srcDir, f);
|
|
593
|
-
const dstFile = join(dstDir, f);
|
|
594
|
-
if (!existsSync(dstFile)) {
|
|
595
|
-
try {
|
|
596
|
-
const srcStat = lstatSyncFn(srcFile);
|
|
597
|
-
if (srcStat.isFile()) {
|
|
598
|
-
cpSync(srcFile, dstFile);
|
|
599
|
-
synced.push(`milestones/${mid}/${f}`);
|
|
600
|
-
}
|
|
601
|
-
} catch {
|
|
602
|
-
/* non-fatal */
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// Sync slices directory if it exists in main but not in worktree
|
|
608
|
-
const srcSlicesDir = join(srcDir, "slices");
|
|
609
|
-
const dstSlicesDir = join(dstDir, "slices");
|
|
610
|
-
if (existsSync(srcSlicesDir) && !existsSync(dstSlicesDir)) {
|
|
611
|
-
try {
|
|
612
|
-
cpSync(srcSlicesDir, dstSlicesDir, { recursive: true });
|
|
613
|
-
synced.push(`milestones/${mid}/slices/`);
|
|
614
|
-
} catch {
|
|
615
|
-
/* non-fatal */
|
|
616
|
-
}
|
|
617
|
-
} else if (existsSync(srcSlicesDir) && existsSync(dstSlicesDir)) {
|
|
618
|
-
// Both exist — sync missing slice directories
|
|
619
|
-
const srcSlices = readdirSync(srcSlicesDir, {
|
|
620
|
-
withFileTypes: true,
|
|
621
|
-
})
|
|
622
|
-
.filter((d) => d.isDirectory())
|
|
623
|
-
.map((d) => d.name);
|
|
624
|
-
for (const sid of srcSlices) {
|
|
625
|
-
const srcSlice = join(srcSlicesDir, sid);
|
|
626
|
-
const dstSlice = join(dstSlicesDir, sid);
|
|
627
|
-
if (!existsSync(dstSlice)) {
|
|
628
|
-
try {
|
|
629
|
-
cpSync(srcSlice, dstSlice, { recursive: true });
|
|
630
|
-
synced.push(`milestones/${mid}/slices/${sid}/`);
|
|
631
|
-
} catch {
|
|
632
|
-
/* non-fatal */
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
} catch {
|
|
638
|
-
/* non-fatal */
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
} catch {
|
|
643
|
-
/* non-fatal */
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
return { synced };
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
/**
|
|
651
|
-
* Sync milestone artifacts from worktree back to the main external state directory.
|
|
652
|
-
* Called before milestone merge to ensure completion artifacts (SUMMARY, VALIDATION,
|
|
653
|
-
* updated ROADMAP) are visible from the project root (#1412).
|
|
654
|
-
*
|
|
655
|
-
* Syncs:
|
|
656
|
-
* 1. Root-level .gsd/ files (REQUIREMENTS, PROJECT, DECISIONS, KNOWLEDGE,
|
|
657
|
-
* OVERRIDES) — the worktree's versions overwrite main's because the
|
|
658
|
-
* worktree is the authoritative execution context.
|
|
659
|
-
* 2. ALL milestone directories found in the worktree — not just the
|
|
660
|
-
* current milestoneId. The complete-milestone unit may create artifacts
|
|
661
|
-
* for the *next* milestone (CONTEXT, ROADMAP, new requirements) which
|
|
662
|
-
* must survive worktree teardown.
|
|
663
|
-
*
|
|
664
|
-
* History: Originally only synced milestones/<milestoneId>/ and assumed
|
|
665
|
-
* root-level files would be carried by the squash merge. In practice,
|
|
666
|
-
* .gsd/ files are often untracked (gitignored or never committed), so the
|
|
667
|
-
* squash merge carries nothing. This caused next-milestone artifacts and
|
|
668
|
-
* updated REQUIREMENTS/PROJECT to be silently lost on teardown.
|
|
669
|
-
*/
|
|
670
|
-
export function syncWorktreeStateBack(
|
|
671
|
-
mainBasePath: string,
|
|
672
|
-
worktreePath: string,
|
|
673
|
-
milestoneId: string,
|
|
674
|
-
): { synced: string[] } {
|
|
675
|
-
const mainGsd = gsdRoot(mainBasePath);
|
|
676
|
-
const wtGsd = gsdRoot(worktreePath);
|
|
677
|
-
const synced: string[] = [];
|
|
678
|
-
|
|
679
|
-
// If both resolve to the same directory (symlink), no sync needed
|
|
680
|
-
if (isSamePath(mainGsd, wtGsd)) return { synced };
|
|
681
|
-
|
|
682
|
-
if (!existsSync(wtGsd) || !existsSync(mainGsd)) return { synced };
|
|
683
|
-
|
|
684
|
-
// ── 0. Pre-upgrade worktree DB reconciliation ────────────────────────
|
|
685
|
-
// If the worktree has its own gsd.db (copied before the WAL transition),
|
|
686
|
-
// reconcile its hierarchy data into the project root DB before syncing
|
|
687
|
-
// files. This handles in-flight worktrees that were created before the
|
|
688
|
-
// upgrade to shared WAL mode.
|
|
689
|
-
const wtLocalDb = join(wtGsd, "gsd.db");
|
|
690
|
-
const mainDb = join(mainGsd, "gsd.db");
|
|
691
|
-
if (existsSync(wtLocalDb) && existsSync(mainDb)) {
|
|
692
|
-
try {
|
|
693
|
-
reconcileWorktreeDb(mainDb, wtLocalDb);
|
|
694
|
-
synced.push("gsd.db (pre-upgrade reconcile)");
|
|
695
|
-
} catch {
|
|
696
|
-
// Non-fatal — file sync below is the fallback
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
// ── 1. Sync root-level .gsd/ files back ──────────────────────────────
|
|
701
|
-
// The worktree is authoritative — complete-milestone updates REQUIREMENTS,
|
|
702
|
-
// PROJECT, etc. These must overwrite main's copies so they survive teardown.
|
|
703
|
-
// Also includes QUEUE.md, completed-units.json, and metrics.json which are
|
|
704
|
-
// written during milestone closeout and lost on teardown without explicit sync
|
|
705
|
-
// (#1787, #2313).
|
|
706
|
-
for (const f of ROOT_STATE_FILES) {
|
|
707
|
-
const src = join(wtGsd, f);
|
|
708
|
-
const dst = join(mainGsd, f);
|
|
709
|
-
if (existsSync(src)) {
|
|
710
|
-
try {
|
|
711
|
-
cpSync(src, dst, { force: true });
|
|
712
|
-
synced.push(f);
|
|
713
|
-
} catch {
|
|
714
|
-
/* non-fatal */
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// ── 2. Sync ALL milestone directories ────────────────────────────────
|
|
720
|
-
// The complete-milestone unit may create next-milestone artifacts (e.g.
|
|
721
|
-
// M007 setup while closing M006). We must sync every milestone directory
|
|
722
|
-
// in the worktree, not just the current one.
|
|
723
|
-
const wtMilestonesDir = join(wtGsd, "milestones");
|
|
724
|
-
if (!existsSync(wtMilestonesDir)) return { synced };
|
|
725
|
-
|
|
726
|
-
try {
|
|
727
|
-
const wtMilestones = readdirSync(wtMilestonesDir, { withFileTypes: true })
|
|
728
|
-
.filter((d) => d.isDirectory())
|
|
729
|
-
.map((d) => d.name);
|
|
730
|
-
|
|
731
|
-
for (const mid of wtMilestones) {
|
|
732
|
-
syncMilestoneDir(wtGsd, mainGsd, mid, synced);
|
|
733
|
-
}
|
|
734
|
-
} catch {
|
|
735
|
-
/* non-fatal */
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
return { synced };
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
/**
|
|
742
|
-
* Sync a single milestone directory from worktree to main.
|
|
743
|
-
* Copies milestone-level .md files, slice-level files, and task summaries.
|
|
744
|
-
*/
|
|
745
|
-
/** Copy matching files from srcDir to dstDir (non-fatal per file). */
|
|
746
|
-
function syncDirFiles(
|
|
747
|
-
srcDir: string,
|
|
748
|
-
dstDir: string,
|
|
749
|
-
filter: (name: string) => boolean,
|
|
750
|
-
synced: string[],
|
|
751
|
-
prefix: string,
|
|
752
|
-
): void {
|
|
753
|
-
try {
|
|
754
|
-
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
|
|
755
|
-
if (!entry.isFile() || !filter(entry.name)) continue;
|
|
756
|
-
try {
|
|
757
|
-
cpSync(join(srcDir, entry.name), join(dstDir, entry.name), { force: true });
|
|
758
|
-
synced.push(`${prefix}${entry.name}`);
|
|
759
|
-
} catch {
|
|
760
|
-
/* non-fatal */
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
} catch {
|
|
764
|
-
/* non-fatal — srcDir may not be readable */
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
function syncMilestoneDir(
|
|
769
|
-
wtGsd: string,
|
|
770
|
-
mainGsd: string,
|
|
771
|
-
mid: string,
|
|
772
|
-
synced: string[],
|
|
773
|
-
): void {
|
|
774
|
-
const wtMilestoneDir = join(wtGsd, "milestones", mid);
|
|
775
|
-
const mainMilestoneDir = join(mainGsd, "milestones", mid);
|
|
776
|
-
|
|
777
|
-
if (!existsSync(wtMilestoneDir)) return;
|
|
778
|
-
mkdirSync(mainMilestoneDir, { recursive: true });
|
|
779
|
-
|
|
780
|
-
const isMd = (name: string): boolean => name.endsWith(".md");
|
|
781
|
-
|
|
782
|
-
// Sync milestone-level files (SUMMARY, VALIDATION, ROADMAP, CONTEXT)
|
|
783
|
-
syncDirFiles(wtMilestoneDir, mainMilestoneDir, isMd, synced, `milestones/${mid}/`);
|
|
784
|
-
|
|
785
|
-
// Sync slice-level files (summaries, UATs) and task summaries (#1678)
|
|
786
|
-
const wtSlicesDir = join(wtMilestoneDir, "slices");
|
|
787
|
-
const mainSlicesDir = join(mainMilestoneDir, "slices");
|
|
788
|
-
if (!existsSync(wtSlicesDir)) return;
|
|
789
|
-
|
|
790
|
-
try {
|
|
791
|
-
for (const sliceEntry of readdirSync(wtSlicesDir, { withFileTypes: true })) {
|
|
792
|
-
if (!sliceEntry.isDirectory()) continue;
|
|
793
|
-
const sid = sliceEntry.name;
|
|
794
|
-
const wtSliceDir = join(wtSlicesDir, sid);
|
|
795
|
-
const mainSliceDir = join(mainSlicesDir, sid);
|
|
796
|
-
mkdirSync(mainSliceDir, { recursive: true });
|
|
797
|
-
|
|
798
|
-
syncDirFiles(wtSliceDir, mainSliceDir, isMd, synced, `milestones/${mid}/slices/${sid}/`);
|
|
799
|
-
|
|
800
|
-
const wtTasksDir = join(wtSliceDir, "tasks");
|
|
801
|
-
const mainTasksDir = join(mainSliceDir, "tasks");
|
|
802
|
-
if (existsSync(wtTasksDir)) {
|
|
803
|
-
mkdirSync(mainTasksDir, { recursive: true });
|
|
804
|
-
syncDirFiles(wtTasksDir, mainTasksDir, isMd, synced, `milestones/${mid}/slices/${sid}/tasks/`);
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
} catch {
|
|
808
|
-
/* non-fatal */
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
// ─── Worktree Post-Create Hook (#597) ────────────────────────────────────────
|
|
812
|
-
|
|
813
|
-
/**
|
|
814
|
-
* Run the user-configured post-create hook script after worktree creation.
|
|
815
|
-
* The script receives SOURCE_DIR and WORKTREE_DIR as environment variables.
|
|
816
|
-
* Failure is non-fatal — returns the error message or null on success.
|
|
817
|
-
*
|
|
818
|
-
* Reads the hook path from git.worktree_post_create in preferences.
|
|
819
|
-
* Pass hookPath directly to bypass preference loading (useful for testing).
|
|
820
|
-
*/
|
|
821
|
-
export function runWorktreePostCreateHook(
|
|
822
|
-
sourceDir: string,
|
|
823
|
-
worktreeDir: string,
|
|
824
|
-
hookPath?: string,
|
|
825
|
-
): string | null {
|
|
826
|
-
if (hookPath === undefined) {
|
|
827
|
-
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
828
|
-
hookPath = prefs?.worktree_post_create;
|
|
829
|
-
}
|
|
830
|
-
if (!hookPath) return null;
|
|
831
|
-
|
|
832
|
-
// Resolve relative paths against the source project root.
|
|
833
|
-
// On Windows, convert 8.3 short paths (e.g. RUNNER~1) to long paths
|
|
834
|
-
// so execFileSync can locate the file correctly.
|
|
835
|
-
let resolved = isAbsolute(hookPath) ? hookPath : join(sourceDir, hookPath);
|
|
836
|
-
if (!existsSync(resolved)) {
|
|
837
|
-
return `Worktree post-create hook not found: ${resolved}`;
|
|
838
|
-
}
|
|
839
|
-
if (process.platform === "win32") {
|
|
840
|
-
try { resolved = realpathSync.native(resolved); } catch { /* keep original */ }
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
try {
|
|
844
|
-
// .bat/.cmd files on Windows require shell mode — execFileSync cannot
|
|
845
|
-
// spawn them directly (EINVAL).
|
|
846
|
-
const needsShell = process.platform === "win32" && /\.(bat|cmd)$/i.test(resolved);
|
|
847
|
-
execFileSync(resolved, [], {
|
|
848
|
-
cwd: worktreeDir,
|
|
849
|
-
env: {
|
|
850
|
-
...process.env,
|
|
851
|
-
SOURCE_DIR: sourceDir,
|
|
852
|
-
WORKTREE_DIR: worktreeDir,
|
|
853
|
-
},
|
|
854
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
855
|
-
encoding: "utf-8",
|
|
856
|
-
timeout: 30_000, // 30 second timeout
|
|
857
|
-
shell: needsShell,
|
|
858
|
-
});
|
|
859
|
-
return null;
|
|
860
|
-
} catch (err) {
|
|
861
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
862
|
-
return `Worktree post-create hook failed: ${msg}`;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
// ─── Auto-Worktree Branch Naming ───────────────────────────────────────────
|
|
867
|
-
|
|
868
|
-
export function autoWorktreeBranch(milestoneId: string): string {
|
|
869
|
-
return `milestone/${milestoneId}`;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
// ─── Public API ────────────────────────────────────────────────────────────
|
|
873
|
-
|
|
874
|
-
/**
|
|
875
|
-
* Create a new auto-worktree for a milestone, chdir into it, and store
|
|
876
|
-
* the original base path for later teardown.
|
|
877
|
-
*
|
|
878
|
-
* Atomic: chdir + originalBase update happen in the same try block
|
|
879
|
-
* to prevent split-brain.
|
|
880
|
-
*/
|
|
881
|
-
|
|
882
|
-
/**
|
|
883
|
-
* Forward-merge plan checkbox state from the project root into a freshly
|
|
884
|
-
* re-attached worktree (#778).
|
|
885
|
-
*
|
|
886
|
-
* When auto-mode stops via crash (not graceful stop), the milestone branch
|
|
887
|
-
* HEAD may be behind the filesystem state at the project root because
|
|
888
|
-
* syncStateToProjectRoot() runs after every task completion but the final
|
|
889
|
-
* git commit may not have happened before the crash. On restart the worktree
|
|
890
|
-
* is re-attached to the branch HEAD, which has [ ] for the crashed task,
|
|
891
|
-
* causing verifyExpectedArtifact() to fail and triggering an infinite
|
|
892
|
-
* dispatch/skip loop.
|
|
893
|
-
*
|
|
894
|
-
* Fix: after re-attaching, read every *.md plan file in the milestone
|
|
895
|
-
* directory at the project root and apply any [x] checkbox states that are
|
|
896
|
-
* ahead of the worktree version (forward-only: never downgrade [x] → [ ]).
|
|
897
|
-
*
|
|
898
|
-
* This is safe because syncStateToProjectRoot() is the authoritative source
|
|
899
|
-
* of post-task state at the project root — it writes the same [x] the LLM
|
|
900
|
-
* produced, then the auto-commit follows. If the commit never happened, the
|
|
901
|
-
* filesystem copy is still valid and correct.
|
|
902
|
-
*/
|
|
903
|
-
function reconcilePlanCheckboxes(
|
|
904
|
-
projectRoot: string,
|
|
905
|
-
wtPath: string,
|
|
906
|
-
milestoneId: string,
|
|
907
|
-
): void {
|
|
908
|
-
const srcMilestone = join(projectRoot, ".gsd", "milestones", milestoneId);
|
|
909
|
-
const dstMilestone = join(wtPath, ".gsd", "milestones", milestoneId);
|
|
910
|
-
if (!existsSync(srcMilestone) || !existsSync(dstMilestone)) return;
|
|
911
|
-
|
|
912
|
-
// Walk all markdown files in the milestone directory (plans, summaries, etc.)
|
|
913
|
-
function walkMd(dir: string): string[] {
|
|
914
|
-
const results: string[] = [];
|
|
915
|
-
try {
|
|
916
|
-
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
917
|
-
const full = join(dir, entry.name);
|
|
918
|
-
if (entry.isDirectory()) {
|
|
919
|
-
results.push(...walkMd(full));
|
|
920
|
-
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
921
|
-
results.push(full);
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
} catch {
|
|
925
|
-
/* non-fatal */
|
|
926
|
-
}
|
|
927
|
-
return results;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
for (const srcFile of walkMd(srcMilestone)) {
|
|
931
|
-
const rel = srcFile.slice(srcMilestone.length);
|
|
932
|
-
const dstFile = dstMilestone + rel;
|
|
933
|
-
if (!existsSync(dstFile)) continue; // only reconcile existing files
|
|
934
|
-
|
|
935
|
-
let srcContent: string;
|
|
936
|
-
let dstContent: string;
|
|
937
|
-
try {
|
|
938
|
-
srcContent = readFileSync(srcFile, "utf-8");
|
|
939
|
-
dstContent = readFileSync(dstFile, "utf-8");
|
|
940
|
-
} catch {
|
|
941
|
-
continue;
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
if (srcContent === dstContent) continue;
|
|
945
|
-
|
|
946
|
-
// Extract all checked task IDs from the source (project root)
|
|
947
|
-
// Pattern: - [x] **T<id>: or - [x] **S<id>: (case-insensitive x)
|
|
948
|
-
const checkedRe = /^- \[[xX]\] \*\*([TS]\d+):/gm;
|
|
949
|
-
const srcChecked = new Set<string>();
|
|
950
|
-
for (const m of srcContent.matchAll(checkedRe)) srcChecked.add(m[1]);
|
|
951
|
-
|
|
952
|
-
if (srcChecked.size === 0) continue;
|
|
953
|
-
|
|
954
|
-
// Forward-apply: replace [ ] → [x] for any IDs that are checked in src
|
|
955
|
-
let updated = dstContent;
|
|
956
|
-
let changed = false;
|
|
957
|
-
for (const id of srcChecked) {
|
|
958
|
-
const escapedId = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
959
|
-
const uncheckedRe = new RegExp(
|
|
960
|
-
`^(- )\\[ \\]( \\*\\*${escapedId}:)`,
|
|
961
|
-
"gm",
|
|
962
|
-
);
|
|
963
|
-
if (uncheckedRe.test(updated)) {
|
|
964
|
-
updated = updated.replace(
|
|
965
|
-
new RegExp(`^(- )\\[ \\]( \\*\\*${escapedId}:)`, "gm"),
|
|
966
|
-
"$1[x]$2",
|
|
967
|
-
);
|
|
968
|
-
changed = true;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
if (changed) {
|
|
973
|
-
try {
|
|
974
|
-
atomicWriteSync(dstFile, updated, "utf-8");
|
|
975
|
-
} catch {
|
|
976
|
-
/* non-fatal */
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
export function createAutoWorktree(
|
|
983
|
-
basePath: string,
|
|
984
|
-
milestoneId: string,
|
|
985
|
-
): string {
|
|
986
|
-
const branch = autoWorktreeBranch(milestoneId);
|
|
987
|
-
|
|
988
|
-
// Check if the milestone branch already exists — it survives auto-mode
|
|
989
|
-
// stop/pause and contains committed work from prior sessions. If it exists,
|
|
990
|
-
// re-attach the worktree to it WITHOUT resetting. Only create a fresh branch
|
|
991
|
-
// from the integration branch when no prior work exists.
|
|
992
|
-
const branchExists = nativeBranchExists(basePath, branch);
|
|
993
|
-
|
|
994
|
-
let info: { name: string; path: string; branch: string; exists: boolean };
|
|
995
|
-
if (branchExists) {
|
|
996
|
-
// Re-attach worktree to the existing milestone branch (preserving commits)
|
|
997
|
-
info = createWorktree(basePath, milestoneId, {
|
|
998
|
-
branch,
|
|
999
|
-
reuseExistingBranch: true,
|
|
1000
|
-
});
|
|
1001
|
-
} else {
|
|
1002
|
-
// Fresh start — create branch from integration branch
|
|
1003
|
-
const integrationBranch =
|
|
1004
|
-
readIntegrationBranch(basePath, milestoneId) ?? undefined;
|
|
1005
|
-
info = createWorktree(basePath, milestoneId, {
|
|
1006
|
-
branch,
|
|
1007
|
-
startPoint: integrationBranch,
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
// Copy .gsd/ planning artifacts from the source repo into the new worktree.
|
|
1012
|
-
// Worktrees are fresh git checkouts — untracked files don't carry over.
|
|
1013
|
-
// Planning artifacts may be untracked if the project's .gitignore had a
|
|
1014
|
-
// blanket .gsd/ rule (pre-v2.14.0). Without this copy, auto-mode loops
|
|
1015
|
-
// on plan-slice because the plan file doesn't exist in the worktree.
|
|
1016
|
-
//
|
|
1017
|
-
// IMPORTANT: Skip when re-attaching to an existing branch (#759).
|
|
1018
|
-
// The branch checkout already has committed artifacts with correct state
|
|
1019
|
-
// (e.g. [x] for completed slices). Copying from the project root would
|
|
1020
|
-
// overwrite them with stale data ([ ] checkboxes) because the root is
|
|
1021
|
-
// not always fully synced.
|
|
1022
|
-
if (!branchExists) {
|
|
1023
|
-
copyPlanningArtifacts(basePath, info.path);
|
|
1024
|
-
} else {
|
|
1025
|
-
// Re-attaching to an existing branch: forward-merge any plan checkpoint
|
|
1026
|
-
// state from the project root into the worktree (#778).
|
|
1027
|
-
//
|
|
1028
|
-
// If auto-mode stopped via crash, the milestone branch HEAD may lag behind
|
|
1029
|
-
// the project root filesystem because syncStateToProjectRoot() ran after
|
|
1030
|
-
// task completion but the auto-commit never fired. On restart the worktree
|
|
1031
|
-
// is re-created from the branch HEAD (which has [ ] for the crashed task),
|
|
1032
|
-
// causing verifyExpectedArtifact() to return false → stale-key eviction →
|
|
1033
|
-
// infinite dispatch/skip loop. Reconciling here ensures the worktree sees
|
|
1034
|
-
// the same [x] state that syncStateToProjectRoot() wrote to the root.
|
|
1035
|
-
reconcilePlanCheckboxes(basePath, info.path, milestoneId);
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
// Run user-configured post-create hook (#597) — e.g. copy .env, symlink assets
|
|
1039
|
-
const hookError = runWorktreePostCreateHook(basePath, info.path);
|
|
1040
|
-
if (hookError) {
|
|
1041
|
-
// Non-fatal — log but don't prevent worktree usage
|
|
1042
|
-
logWarning("reconcile", hookError, { worktree: info.name });
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
const previousCwd = process.cwd();
|
|
1046
|
-
|
|
1047
|
-
try {
|
|
1048
|
-
process.chdir(info.path);
|
|
1049
|
-
originalBase = basePath;
|
|
1050
|
-
} catch (err) {
|
|
1051
|
-
// If chdir fails, the worktree was created but we couldn't enter it.
|
|
1052
|
-
// Don't store originalBase -- caller can retry or clean up.
|
|
1053
|
-
throw new GSDError(
|
|
1054
|
-
GSD_IO_ERROR,
|
|
1055
|
-
`Auto-worktree created at ${info.path} but chdir failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1056
|
-
);
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
nudgeGitBranchCache(previousCwd);
|
|
1060
|
-
return info.path;
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
/**
|
|
1064
|
-
* Copy .gsd/ planning artifacts from source repo to a new worktree.
|
|
1065
|
-
* Copies milestones/, DECISIONS.md, REQUIREMENTS.md, PROJECT.md, QUEUE.md,
|
|
1066
|
-
* STATE.md, KNOWLEDGE.md, and OVERRIDES.md.
|
|
1067
|
-
* Skips runtime files (auto.lock, metrics.json, etc.) and the worktrees/ dir.
|
|
1068
|
-
* Best-effort — failures are non-fatal since auto-mode can recreate artifacts.
|
|
1069
|
-
*/
|
|
1070
|
-
function copyPlanningArtifacts(srcBase: string, wtPath: string): void {
|
|
1071
|
-
const srcGsd = join(srcBase, ".gsd");
|
|
1072
|
-
const dstGsd = join(wtPath, ".gsd");
|
|
1073
|
-
if (!existsSync(srcGsd)) return;
|
|
1074
|
-
|
|
1075
|
-
// Copy milestones/ directory (planning files, roadmaps, plans, research)
|
|
1076
|
-
safeCopyRecursive(join(srcGsd, "milestones"), join(dstGsd, "milestones"), {
|
|
1077
|
-
force: true,
|
|
1078
|
-
filter: (src) => !src.endsWith("-META.json"),
|
|
1079
|
-
});
|
|
1080
|
-
|
|
1081
|
-
// Copy top-level planning files
|
|
1082
|
-
for (const file of [
|
|
1083
|
-
"DECISIONS.md",
|
|
1084
|
-
"REQUIREMENTS.md",
|
|
1085
|
-
"PROJECT.md",
|
|
1086
|
-
"QUEUE.md",
|
|
1087
|
-
"STATE.md",
|
|
1088
|
-
"KNOWLEDGE.md",
|
|
1089
|
-
"OVERRIDES.md",
|
|
1090
|
-
"mcp.json",
|
|
1091
|
-
]) {
|
|
1092
|
-
safeCopy(join(srcGsd, file), join(dstGsd, file), { force: true });
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
// Seed canonical PREFERENCES.md when available; fall back to legacy lowercase.
|
|
1096
|
-
if (existsSync(join(srcGsd, PROJECT_PREFERENCES_FILE))) {
|
|
1097
|
-
safeCopy(
|
|
1098
|
-
join(srcGsd, PROJECT_PREFERENCES_FILE),
|
|
1099
|
-
join(dstGsd, PROJECT_PREFERENCES_FILE),
|
|
1100
|
-
{ force: true },
|
|
1101
|
-
);
|
|
1102
|
-
} else if (existsSync(join(srcGsd, LEGACY_PROJECT_PREFERENCES_FILE))) {
|
|
1103
|
-
safeCopy(
|
|
1104
|
-
join(srcGsd, LEGACY_PROJECT_PREFERENCES_FILE),
|
|
1105
|
-
join(dstGsd, LEGACY_PROJECT_PREFERENCES_FILE),
|
|
1106
|
-
{ force: true },
|
|
1107
|
-
);
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
// Shared WAL (R012): worktrees use the project root's DB directly.
|
|
1111
|
-
// No longer copy gsd.db into the worktree — the DB path resolver in
|
|
1112
|
-
// ensureDbOpen() detects the worktree location and opens the root DB.
|
|
1113
|
-
// Compat note: reconcileWorktreeDb() in mergeMilestoneToMain handles
|
|
1114
|
-
// worktrees that already have a local gsd.db from before this change.
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
/**
|
|
1118
|
-
* Teardown an auto-worktree: chdir back to original base, then remove
|
|
1119
|
-
* the worktree and its branch.
|
|
1120
|
-
*/
|
|
1121
|
-
export function teardownAutoWorktree(
|
|
1122
|
-
originalBasePath: string,
|
|
1123
|
-
milestoneId: string,
|
|
1124
|
-
opts: { preserveBranch?: boolean } = {},
|
|
1125
|
-
): void {
|
|
1126
|
-
const branch = autoWorktreeBranch(milestoneId);
|
|
1127
|
-
const { preserveBranch = false } = opts;
|
|
1128
|
-
const previousCwd = process.cwd();
|
|
1129
|
-
|
|
1130
|
-
try {
|
|
1131
|
-
process.chdir(originalBasePath);
|
|
1132
|
-
originalBase = null;
|
|
1133
|
-
} catch (err) {
|
|
1134
|
-
throw new GSDError(
|
|
1135
|
-
GSD_IO_ERROR,
|
|
1136
|
-
`Failed to chdir back to ${originalBasePath} during teardown: ${err instanceof Error ? err.message : String(err)}`,
|
|
1137
|
-
);
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
nudgeGitBranchCache(previousCwd);
|
|
1141
|
-
removeWorktree(originalBasePath, milestoneId, {
|
|
1142
|
-
branch,
|
|
1143
|
-
deleteBranch: !preserveBranch,
|
|
1144
|
-
});
|
|
1145
|
-
|
|
1146
|
-
// Verify cleanup succeeded — warn if the worktree directory is still on disk.
|
|
1147
|
-
// On Windows, bash-based cleanup can silently fail when paths contain
|
|
1148
|
-
// backslashes (#1436), leaving ~1 GB+ orphaned directories.
|
|
1149
|
-
const wtDir = worktreePath(originalBasePath, milestoneId);
|
|
1150
|
-
if (existsSync(wtDir)) {
|
|
1151
|
-
logWarning(
|
|
1152
|
-
"reconcile",
|
|
1153
|
-
`Worktree directory still exists after teardown: ${wtDir}. ` +
|
|
1154
|
-
`This is likely an orphaned directory consuming disk space. ` +
|
|
1155
|
-
`Remove it manually with: rm -rf "${wtDir.replaceAll("\\", "/")}"`,
|
|
1156
|
-
{ worktree: milestoneId },
|
|
1157
|
-
);
|
|
1158
|
-
// Attempt a direct filesystem removal as a fallback
|
|
1159
|
-
try {
|
|
1160
|
-
rmSync(wtDir, { recursive: true, force: true });
|
|
1161
|
-
} catch {
|
|
1162
|
-
// Non-fatal — the warning above tells the user how to clean up
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
/**
|
|
1168
|
-
* Detect if the process is currently inside an auto-worktree.
|
|
1169
|
-
* Checks both module state and git branch prefix.
|
|
1170
|
-
*/
|
|
1171
|
-
export function isInAutoWorktree(basePath: string): boolean {
|
|
1172
|
-
if (!originalBase) return false;
|
|
1173
|
-
const cwd = process.cwd();
|
|
1174
|
-
const resolvedBase = existsSync(basePath) ? realpathSync(basePath) : basePath;
|
|
1175
|
-
const wtDir = join(resolvedBase, ".gsd", "worktrees");
|
|
1176
|
-
if (!cwd.startsWith(wtDir)) return false;
|
|
1177
|
-
const branch = nativeGetCurrentBranch(cwd);
|
|
1178
|
-
return branch.startsWith("milestone/");
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
/**
|
|
1182
|
-
* Get the filesystem path for an auto-worktree, or null if it doesn't exist
|
|
1183
|
-
* or is not a valid git worktree.
|
|
1184
|
-
*
|
|
1185
|
-
* Validates that the path is a real git worktree (has a .git file with a
|
|
1186
|
-
* gitdir: pointer) rather than just a stray directory. This prevents
|
|
1187
|
-
* mis-detection of leftover directories as active worktrees (#695).
|
|
1188
|
-
*/
|
|
1189
|
-
export function getAutoWorktreePath(
|
|
1190
|
-
basePath: string,
|
|
1191
|
-
milestoneId: string,
|
|
1192
|
-
): string | null {
|
|
1193
|
-
const p = worktreePath(basePath, milestoneId);
|
|
1194
|
-
if (!existsSync(p)) return null;
|
|
1195
|
-
|
|
1196
|
-
// Validate this is a real git worktree, not a stray directory.
|
|
1197
|
-
// A git worktree has a .git *file* (not directory) containing "gitdir: <path>".
|
|
1198
|
-
const gitPath = join(p, ".git");
|
|
1199
|
-
if (!existsSync(gitPath)) return null;
|
|
1200
|
-
try {
|
|
1201
|
-
const content = readFileSync(gitPath, "utf8").trim();
|
|
1202
|
-
if (!content.startsWith("gitdir: ")) return null;
|
|
1203
|
-
} catch {
|
|
1204
|
-
return null;
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
return p;
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
/**
|
|
1211
|
-
* Enter an existing auto-worktree (chdir into it, store originalBase).
|
|
1212
|
-
* Use for resume -- the worktree already exists from a prior create.
|
|
1213
|
-
*
|
|
1214
|
-
* Atomic: chdir + originalBase update in same try block.
|
|
1215
|
-
*/
|
|
1216
|
-
export function enterAutoWorktree(
|
|
1217
|
-
basePath: string,
|
|
1218
|
-
milestoneId: string,
|
|
1219
|
-
): string {
|
|
1220
|
-
const p = worktreePath(basePath, milestoneId);
|
|
1221
|
-
if (!existsSync(p)) {
|
|
1222
|
-
throw new GSDError(
|
|
1223
|
-
GSD_IO_ERROR,
|
|
1224
|
-
`Auto-worktree for ${milestoneId} does not exist at ${p}`,
|
|
1225
|
-
);
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
// Validate this is a real git worktree, not a stray directory (#695)
|
|
1229
|
-
const gitPath = join(p, ".git");
|
|
1230
|
-
if (!existsSync(gitPath)) {
|
|
1231
|
-
throw new GSDError(
|
|
1232
|
-
GSD_GIT_ERROR,
|
|
1233
|
-
`Auto-worktree path ${p} exists but is not a git worktree (no .git)`,
|
|
1234
|
-
);
|
|
1235
|
-
}
|
|
1236
|
-
try {
|
|
1237
|
-
const content = readFileSync(gitPath, "utf8").trim();
|
|
1238
|
-
if (!content.startsWith("gitdir: ")) {
|
|
1239
|
-
throw new GSDError(
|
|
1240
|
-
GSD_GIT_ERROR,
|
|
1241
|
-
`Auto-worktree path ${p} has a .git but it is not a worktree gitdir pointer`,
|
|
1242
|
-
);
|
|
1243
|
-
}
|
|
1244
|
-
} catch (err) {
|
|
1245
|
-
if (err instanceof Error && err.message.includes("worktree")) throw err;
|
|
1246
|
-
throw new GSDError(
|
|
1247
|
-
GSD_IO_ERROR,
|
|
1248
|
-
`Auto-worktree path ${p} exists but .git is unreadable`,
|
|
1249
|
-
);
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
const previousCwd = process.cwd();
|
|
1253
|
-
|
|
1254
|
-
try {
|
|
1255
|
-
process.chdir(p);
|
|
1256
|
-
originalBase = basePath;
|
|
1257
|
-
} catch (err) {
|
|
1258
|
-
throw new GSDError(
|
|
1259
|
-
GSD_IO_ERROR,
|
|
1260
|
-
`Failed to enter auto-worktree at ${p}: ${err instanceof Error ? err.message : String(err)}`,
|
|
1261
|
-
);
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
nudgeGitBranchCache(previousCwd);
|
|
1265
|
-
return p;
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
/**
|
|
1269
|
-
* Get the original project root stored when entering an auto-worktree.
|
|
1270
|
-
* Returns null if not currently in an auto-worktree.
|
|
1271
|
-
*/
|
|
1272
|
-
export function getAutoWorktreeOriginalBase(): string | null {
|
|
1273
|
-
return originalBase;
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
export function getActiveAutoWorktreeContext(): {
|
|
1277
|
-
originalBase: string;
|
|
1278
|
-
worktreeName: string;
|
|
1279
|
-
branch: string;
|
|
1280
|
-
} | null {
|
|
1281
|
-
if (!originalBase) return null;
|
|
1282
|
-
const cwd = process.cwd();
|
|
1283
|
-
const resolvedBase = existsSync(originalBase)
|
|
1284
|
-
? realpathSync(originalBase)
|
|
1285
|
-
: originalBase;
|
|
1286
|
-
const wtDir = join(resolvedBase, ".gsd", "worktrees");
|
|
1287
|
-
if (!cwd.startsWith(wtDir)) return null;
|
|
1288
|
-
const worktreeName = detectWorktreeName(cwd);
|
|
1289
|
-
if (!worktreeName) return null;
|
|
1290
|
-
const branch = nativeGetCurrentBranch(cwd);
|
|
1291
|
-
if (!branch.startsWith("milestone/")) return null;
|
|
1292
|
-
return {
|
|
1293
|
-
originalBase,
|
|
1294
|
-
worktreeName,
|
|
1295
|
-
branch,
|
|
1296
|
-
};
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
// ─── Merge Milestone -> Main ───────────────────────────────────────────────
|
|
1300
|
-
|
|
1301
|
-
/**
|
|
1302
|
-
* Auto-commit any dirty (uncommitted) state in the given directory.
|
|
1303
|
-
* Returns true if a commit was made, false if working tree was clean.
|
|
1304
|
-
*/
|
|
1305
|
-
function autoCommitDirtyState(cwd: string): boolean {
|
|
1306
|
-
try {
|
|
1307
|
-
const status = nativeWorkingTreeStatus(cwd);
|
|
1308
|
-
if (!status) return false;
|
|
1309
|
-
nativeAddAllWithExclusions(cwd, RUNTIME_EXCLUSION_PATHS);
|
|
1310
|
-
const result = nativeCommit(
|
|
1311
|
-
cwd,
|
|
1312
|
-
"chore: auto-commit before milestone merge",
|
|
1313
|
-
);
|
|
1314
|
-
return result !== null;
|
|
1315
|
-
} catch (e) {
|
|
1316
|
-
debugLog("autoCommitDirtyState", { error: String(e) });
|
|
1317
|
-
return false;
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
/**
|
|
1322
|
-
* Squash-merge the milestone branch into main with a rich commit message
|
|
1323
|
-
* listing all completed slices, then tear down the worktree.
|
|
1324
|
-
*
|
|
1325
|
-
* Sequence:
|
|
1326
|
-
* 1. Auto-commit dirty worktree state
|
|
1327
|
-
* 2. chdir to originalBasePath
|
|
1328
|
-
* 3. git checkout main
|
|
1329
|
-
* 4. git merge --squash milestone/<MID>
|
|
1330
|
-
* 5. git commit with rich message
|
|
1331
|
-
* 6. Auto-push if enabled
|
|
1332
|
-
* 7. Delete milestone branch
|
|
1333
|
-
* 8. Remove worktree directory
|
|
1334
|
-
* 9. Clear originalBase
|
|
1335
|
-
*
|
|
1336
|
-
* On merge conflict: throws MergeConflictError.
|
|
1337
|
-
* On "nothing to commit" after squash: safe only if milestone work is already
|
|
1338
|
-
* on the integration branch. Throws if unanchored code changes would be lost.
|
|
1339
|
-
*/
|
|
1340
|
-
export function mergeMilestoneToMain(
|
|
1341
|
-
originalBasePath_: string,
|
|
1342
|
-
milestoneId: string,
|
|
1343
|
-
roadmapContent: string,
|
|
1344
|
-
): { commitMessage: string; pushed: boolean; prCreated: boolean; codeFilesChanged: boolean } {
|
|
1345
|
-
const worktreeCwd = process.cwd();
|
|
1346
|
-
const milestoneBranch = autoWorktreeBranch(milestoneId);
|
|
1347
|
-
|
|
1348
|
-
// 1. Auto-commit dirty state in worktree before leaving
|
|
1349
|
-
autoCommitDirtyState(worktreeCwd);
|
|
1350
|
-
|
|
1351
|
-
// Reconcile worktree DB into main DB before leaving worktree context.
|
|
1352
|
-
// Skip when both paths resolve to the same physical file (shared WAL /
|
|
1353
|
-
// symlink layout) — ATTACHing a WAL-mode file to itself corrupts the
|
|
1354
|
-
// database (#2823).
|
|
1355
|
-
if (isDbAvailable()) {
|
|
1356
|
-
try {
|
|
1357
|
-
const worktreeDbPath = join(worktreeCwd, ".gsd", "gsd.db");
|
|
1358
|
-
const mainDbPath = join(originalBasePath_, ".gsd", "gsd.db");
|
|
1359
|
-
if (!isSamePath(worktreeDbPath, mainDbPath)) {
|
|
1360
|
-
reconcileWorktreeDb(mainDbPath, worktreeDbPath);
|
|
1361
|
-
}
|
|
1362
|
-
} catch {
|
|
1363
|
-
/* non-fatal */
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
// 2. Get completed slices for commit message
|
|
1368
|
-
let completedSlices: { id: string; title: string }[] = [];
|
|
1369
|
-
if (isDbAvailable()) {
|
|
1370
|
-
completedSlices = getMilestoneSlices(milestoneId)
|
|
1371
|
-
.filter(s => s.status === "complete")
|
|
1372
|
-
.map(s => ({ id: s.id, title: s.title }));
|
|
1373
|
-
}
|
|
1374
|
-
// Fallback: parse roadmap content when DB is unavailable
|
|
1375
|
-
if (completedSlices.length === 0 && roadmapContent) {
|
|
1376
|
-
const sliceRe = /- \[x\] \*\*(\w+):\s*(.+?)\*\*/gi;
|
|
1377
|
-
let m: RegExpExecArray | null;
|
|
1378
|
-
while ((m = sliceRe.exec(roadmapContent)) !== null) {
|
|
1379
|
-
completedSlices.push({ id: m[1], title: m[2] });
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
|
-
// 3. chdir to original base
|
|
1384
|
-
const previousCwd = process.cwd();
|
|
1385
|
-
process.chdir(originalBasePath_);
|
|
1386
|
-
|
|
1387
|
-
// 4. Resolve integration branch — prefer milestone metadata, then preferences,
|
|
1388
|
-
// then auto-detect (origin/HEAD → main → master → current). Never hardcode
|
|
1389
|
-
// "main": repos using "master" or a custom default branch would fail at
|
|
1390
|
-
// checkout and leave the user with a broken merge state (#1668).
|
|
1391
|
-
const prefs = loadEffectiveGSDPreferences()?.preferences?.git ?? {};
|
|
1392
|
-
const integrationBranch = readIntegrationBranch(
|
|
1393
|
-
originalBasePath_,
|
|
1394
|
-
milestoneId,
|
|
1395
|
-
);
|
|
1396
|
-
const mainBranch =
|
|
1397
|
-
integrationBranch ?? prefs.main_branch ?? nativeDetectMainBranch(originalBasePath_);
|
|
1398
|
-
|
|
1399
|
-
// Remove transient project-root state files before any branch or merge
|
|
1400
|
-
// operation. Untracked milestone metadata can otherwise block squash merges.
|
|
1401
|
-
clearProjectRootStateFiles(originalBasePath_, milestoneId);
|
|
1402
|
-
|
|
1403
|
-
// 5. Checkout integration branch (skip if already current — avoids git error
|
|
1404
|
-
// when main is already checked out in the project-root worktree, #757)
|
|
1405
|
-
const currentBranchAtBase = nativeGetCurrentBranch(originalBasePath_);
|
|
1406
|
-
if (currentBranchAtBase !== mainBranch) {
|
|
1407
|
-
nativeCheckoutBranch(originalBasePath_, mainBranch);
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
// 6. Build rich commit message
|
|
1411
|
-
const dbMilestone = getMilestone(milestoneId);
|
|
1412
|
-
let milestoneTitle =
|
|
1413
|
-
(dbMilestone?.title ?? "").replace(/^M\d+:\s*/, "").trim();
|
|
1414
|
-
// Fallback: parse title from roadmap content header (e.g. "# M020: Backend foundation")
|
|
1415
|
-
if (!milestoneTitle && roadmapContent) {
|
|
1416
|
-
const titleMatch = roadmapContent.match(new RegExp(`^#\\s+${milestoneId}:\\s*(.+)`, "m"));
|
|
1417
|
-
if (titleMatch) milestoneTitle = titleMatch[1].trim();
|
|
1418
|
-
}
|
|
1419
|
-
milestoneTitle = milestoneTitle || milestoneId;
|
|
1420
|
-
const subject = `feat: ${milestoneTitle}`;
|
|
1421
|
-
let body = "";
|
|
1422
|
-
if (completedSlices.length > 0) {
|
|
1423
|
-
const sliceLines = completedSlices
|
|
1424
|
-
.map((s) => `- ${s.id}: ${s.title}`)
|
|
1425
|
-
.join("\n");
|
|
1426
|
-
body = `\n\nCompleted slices:\n${sliceLines}\n\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
|
|
1427
|
-
} else {
|
|
1428
|
-
body = `\n\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
|
|
1429
|
-
}
|
|
1430
|
-
const commitMessage = subject + body;
|
|
1431
|
-
|
|
1432
|
-
// 6b. Reconcile worktree HEAD with milestone branch ref (#1846).
|
|
1433
|
-
// When the worktree HEAD detaches and advances past the named branch,
|
|
1434
|
-
// the branch ref becomes stale. Squash-merging the stale ref silently
|
|
1435
|
-
// orphans all commits between the branch ref and the actual worktree HEAD.
|
|
1436
|
-
// Fix: fast-forward the branch ref to the worktree HEAD before merging.
|
|
1437
|
-
// Only applies when merging from an actual worktree (worktreeCwd differs
|
|
1438
|
-
// from originalBasePath_).
|
|
1439
|
-
if (worktreeCwd !== originalBasePath_) {
|
|
1440
|
-
try {
|
|
1441
|
-
const worktreeHead = execFileSync("git", ["rev-parse", "HEAD"], {
|
|
1442
|
-
cwd: worktreeCwd,
|
|
1443
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1444
|
-
encoding: "utf-8",
|
|
1445
|
-
}).trim();
|
|
1446
|
-
const branchHead = execFileSync("git", ["rev-parse", milestoneBranch], {
|
|
1447
|
-
cwd: originalBasePath_,
|
|
1448
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1449
|
-
encoding: "utf-8",
|
|
1450
|
-
}).trim();
|
|
1451
|
-
|
|
1452
|
-
if (worktreeHead && branchHead && worktreeHead !== branchHead) {
|
|
1453
|
-
if (nativeIsAncestor(originalBasePath_, branchHead, worktreeHead)) {
|
|
1454
|
-
// Worktree HEAD is strictly ahead — fast-forward the branch ref
|
|
1455
|
-
nativeUpdateRef(
|
|
1456
|
-
originalBasePath_,
|
|
1457
|
-
`refs/heads/${milestoneBranch}`,
|
|
1458
|
-
worktreeHead,
|
|
1459
|
-
);
|
|
1460
|
-
debugLog("mergeMilestoneToMain", {
|
|
1461
|
-
action: "fast-forward-branch-ref",
|
|
1462
|
-
milestoneBranch,
|
|
1463
|
-
oldRef: branchHead.slice(0, 8),
|
|
1464
|
-
newRef: worktreeHead.slice(0, 8),
|
|
1465
|
-
});
|
|
1466
|
-
} else {
|
|
1467
|
-
// Diverged — fail loudly rather than silently losing commits
|
|
1468
|
-
process.chdir(previousCwd);
|
|
1469
|
-
throw new GSDError(
|
|
1470
|
-
GSD_GIT_ERROR,
|
|
1471
|
-
`Worktree HEAD (${worktreeHead.slice(0, 8)}) diverged from ` +
|
|
1472
|
-
`${milestoneBranch} (${branchHead.slice(0, 8)}). ` +
|
|
1473
|
-
`Manual reconciliation required before merge.`,
|
|
1474
|
-
);
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
} catch (err) {
|
|
1478
|
-
// Re-throw GSDError (divergence); swallow rev-parse failures
|
|
1479
|
-
// (e.g. worktree dir already removed by external cleanup)
|
|
1480
|
-
if (err instanceof GSDError) throw err;
|
|
1481
|
-
debugLog("mergeMilestoneToMain", {
|
|
1482
|
-
action: "reconcile-skipped",
|
|
1483
|
-
reason: String(err),
|
|
1484
|
-
});
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
// 7. Stash any pre-existing dirty files so the squash merge is not
|
|
1489
|
-
// blocked by unrelated local changes (#2151). clearProjectRootStateFiles
|
|
1490
|
-
// only removes untracked .gsd/ files; tracked dirty files elsewhere (e.g.
|
|
1491
|
-
// .planning/work-state.json with stash conflict markers) are invisible to
|
|
1492
|
-
// that cleanup but will cause `git merge --squash` to reject.
|
|
1493
|
-
let stashed = false;
|
|
1494
|
-
try {
|
|
1495
|
-
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
1496
|
-
cwd: originalBasePath_,
|
|
1497
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1498
|
-
encoding: "utf-8",
|
|
1499
|
-
}).trim();
|
|
1500
|
-
if (status) {
|
|
1501
|
-
// Use --include-untracked to stash untracked files that would block
|
|
1502
|
-
// the squash merge, but EXCLUDE .gsd/milestones/ (#2505).
|
|
1503
|
-
// --include-untracked without exclusion sweeps queued milestone
|
|
1504
|
-
// CONTEXT files into the stash. If stash pop later fails, those files
|
|
1505
|
-
// are permanently trapped in the stash entry and lost on the next
|
|
1506
|
-
// stash push or drop.
|
|
1507
|
-
execFileSync(
|
|
1508
|
-
"git",
|
|
1509
|
-
[
|
|
1510
|
-
"stash", "push", "--include-untracked",
|
|
1511
|
-
"-m", `gsd: pre-merge stash for ${milestoneId}`,
|
|
1512
|
-
"--", ":(exclude).gsd/milestones",
|
|
1513
|
-
],
|
|
1514
|
-
{ cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
|
|
1515
|
-
);
|
|
1516
|
-
stashed = true;
|
|
1517
|
-
}
|
|
1518
|
-
} catch {
|
|
1519
|
-
// Stash failure is non-fatal — proceed without stash and let the merge
|
|
1520
|
-
// report the dirty tree if it fails.
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
// 7a. Shelter queued milestone directories before the squash merge (#2505).
|
|
1524
|
-
// The milestone branch may contain copies of queued milestone dirs (via
|
|
1525
|
-
// copyPlanningArtifacts), so `git merge --squash` rejects when those same
|
|
1526
|
-
// files exist as untracked in the working tree. Temporarily move them to
|
|
1527
|
-
// a backup location, then restore after the merge+commit.
|
|
1528
|
-
const milestonesDir = join(gsdRoot(originalBasePath_), "milestones");
|
|
1529
|
-
const shelterDir = join(gsdRoot(originalBasePath_), ".milestone-shelter");
|
|
1530
|
-
const shelteredDirs: string[] = [];
|
|
1531
|
-
|
|
1532
|
-
// Helper: restore sheltered milestone directories (#2505).
|
|
1533
|
-
// Called on both success and error paths to ensure queued CONTEXT files
|
|
1534
|
-
// are never permanently lost.
|
|
1535
|
-
const restoreShelter = (): void => {
|
|
1536
|
-
if (shelteredDirs.length === 0) return;
|
|
1537
|
-
for (const dirName of shelteredDirs) {
|
|
1538
|
-
try {
|
|
1539
|
-
mkdirSync(milestonesDir, { recursive: true });
|
|
1540
|
-
cpSync(join(shelterDir, dirName), join(milestonesDir, dirName), { recursive: true, force: true });
|
|
1541
|
-
} catch { /* best-effort */ }
|
|
1542
|
-
}
|
|
1543
|
-
try { rmSync(shelterDir, { recursive: true, force: true }); } catch { /* best-effort */ }
|
|
1544
|
-
};
|
|
1545
|
-
|
|
1546
|
-
try {
|
|
1547
|
-
if (existsSync(milestonesDir)) {
|
|
1548
|
-
const entries = readdirSync(milestonesDir, { withFileTypes: true });
|
|
1549
|
-
for (const entry of entries) {
|
|
1550
|
-
if (!entry.isDirectory()) continue;
|
|
1551
|
-
// Only shelter directories that do NOT belong to the milestone being merged
|
|
1552
|
-
if (entry.name === milestoneId) continue;
|
|
1553
|
-
const srcDir = join(milestonesDir, entry.name);
|
|
1554
|
-
const dstDir = join(shelterDir, entry.name);
|
|
1555
|
-
try {
|
|
1556
|
-
mkdirSync(shelterDir, { recursive: true });
|
|
1557
|
-
cpSync(srcDir, dstDir, { recursive: true, force: true });
|
|
1558
|
-
rmSync(srcDir, { recursive: true, force: true });
|
|
1559
|
-
shelteredDirs.push(entry.name);
|
|
1560
|
-
} catch {
|
|
1561
|
-
// Non-fatal — if shelter fails, the merge may still succeed
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
} catch {
|
|
1566
|
-
// Non-fatal — proceed with merge; untracked files may block it
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
// 8. Squash merge — auto-resolve .gsd/ state file conflicts (#530)
|
|
1570
|
-
const mergeResult = nativeMergeSquash(originalBasePath_, milestoneBranch);
|
|
1571
|
-
|
|
1572
|
-
if (!mergeResult.success) {
|
|
1573
|
-
// Dirty working tree — the merge was rejected before it started (e.g.
|
|
1574
|
-
// untracked .gsd/ files left by syncStateToProjectRoot). Preserve the
|
|
1575
|
-
// milestone branch so commits are not lost.
|
|
1576
|
-
if (mergeResult.conflicts.includes("__dirty_working_tree__")) {
|
|
1577
|
-
// Defensively clean merge state — the native path may leave MERGE_HEAD
|
|
1578
|
-
// even when the merge is rejected (#2912).
|
|
1579
|
-
try {
|
|
1580
|
-
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1581
|
-
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1582
|
-
const p = join(gitDir_, f);
|
|
1583
|
-
if (existsSync(p)) unlinkSync(p);
|
|
1584
|
-
}
|
|
1585
|
-
} catch { /* best-effort */ }
|
|
1586
|
-
|
|
1587
|
-
// Pop stash before throwing so local work is not lost.
|
|
1588
|
-
if (stashed) {
|
|
1589
|
-
try {
|
|
1590
|
-
execFileSync("git", ["stash", "pop"], {
|
|
1591
|
-
cwd: originalBasePath_,
|
|
1592
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1593
|
-
encoding: "utf-8",
|
|
1594
|
-
});
|
|
1595
|
-
} catch { /* stash pop conflict is non-fatal */ }
|
|
1596
|
-
}
|
|
1597
|
-
restoreShelter();
|
|
1598
|
-
// Restore cwd so the caller is not stranded on the integration branch
|
|
1599
|
-
process.chdir(previousCwd);
|
|
1600
|
-
// Surface the actual dirty filenames from git stderr instead of
|
|
1601
|
-
// generically blaming .gsd/ (#2151).
|
|
1602
|
-
const fileList = mergeResult.dirtyFiles?.length
|
|
1603
|
-
? `Dirty files:\n${mergeResult.dirtyFiles.map((f) => ` ${f}`).join("\n")}`
|
|
1604
|
-
: `Check \`git status\` in the project root for details.`;
|
|
1605
|
-
throw new GSDError(
|
|
1606
|
-
GSD_GIT_ERROR,
|
|
1607
|
-
`Squash merge of ${milestoneBranch} rejected: working tree has dirty or untracked files ` +
|
|
1608
|
-
`that conflict with the merge. ${fileList}`,
|
|
1609
|
-
);
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
// Check for conflicts — use merge result first, fall back to nativeConflictFiles
|
|
1613
|
-
const conflictedFiles =
|
|
1614
|
-
mergeResult.conflicts.length > 0
|
|
1615
|
-
? mergeResult.conflicts
|
|
1616
|
-
: nativeConflictFiles(originalBasePath_);
|
|
1617
|
-
|
|
1618
|
-
if (conflictedFiles.length > 0) {
|
|
1619
|
-
// Separate auto-resolvable conflicts (GSD state files + build artifacts)
|
|
1620
|
-
// from real code conflicts. GSD state files diverge between branches
|
|
1621
|
-
// during normal operation. Build artifacts are machine-generated and
|
|
1622
|
-
// regenerable. Both are safe to accept from the milestone branch.
|
|
1623
|
-
const autoResolvable = conflictedFiles.filter(isSafeToAutoResolve);
|
|
1624
|
-
const codeConflicts = conflictedFiles.filter(
|
|
1625
|
-
(f) => !isSafeToAutoResolve(f),
|
|
1626
|
-
);
|
|
1627
|
-
|
|
1628
|
-
// Auto-resolve safe conflicts by accepting the milestone branch version
|
|
1629
|
-
if (autoResolvable.length > 0) {
|
|
1630
|
-
for (const safeFile of autoResolvable) {
|
|
1631
|
-
try {
|
|
1632
|
-
nativeCheckoutTheirs(originalBasePath_, [safeFile]);
|
|
1633
|
-
nativeAddPaths(originalBasePath_, [safeFile]);
|
|
1634
|
-
} catch {
|
|
1635
|
-
// If checkout --theirs fails, try removing the file from the merge
|
|
1636
|
-
// (it's a runtime file that shouldn't be committed anyway)
|
|
1637
|
-
nativeRmForce(originalBasePath_, [safeFile]);
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
// If there are still real code conflicts, escalate
|
|
1643
|
-
if (codeConflicts.length > 0) {
|
|
1644
|
-
// Abort merge state so MERGE_HEAD is not left on disk (#2912).
|
|
1645
|
-
// libgit2's merge creates MERGE_HEAD even for squash merges; if left
|
|
1646
|
-
// dangling, subsequent merges fail and doctor reports corrupt state.
|
|
1647
|
-
try { nativeMergeAbort(originalBasePath_); } catch { /* best-effort */ }
|
|
1648
|
-
try {
|
|
1649
|
-
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1650
|
-
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1651
|
-
const p = join(gitDir_, f);
|
|
1652
|
-
if (existsSync(p)) unlinkSync(p);
|
|
1653
|
-
}
|
|
1654
|
-
} catch { /* best-effort */ }
|
|
1655
|
-
|
|
1656
|
-
// Pop stash before throwing so local work is not lost (#2151).
|
|
1657
|
-
if (stashed) {
|
|
1658
|
-
try {
|
|
1659
|
-
execFileSync("git", ["stash", "pop"], {
|
|
1660
|
-
cwd: originalBasePath_,
|
|
1661
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1662
|
-
encoding: "utf-8",
|
|
1663
|
-
});
|
|
1664
|
-
} catch { /* stash pop conflict is non-fatal */ }
|
|
1665
|
-
}
|
|
1666
|
-
restoreShelter();
|
|
1667
|
-
throw new MergeConflictError(
|
|
1668
|
-
codeConflicts,
|
|
1669
|
-
"squash",
|
|
1670
|
-
milestoneBranch,
|
|
1671
|
-
mainBranch,
|
|
1672
|
-
);
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
// No conflicts detected — possibly "already up to date", fall through to commit
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
// 9. Commit (handle nothing-to-commit gracefully)
|
|
1679
|
-
const commitResult = nativeCommit(originalBasePath_, commitMessage);
|
|
1680
|
-
const nothingToCommit = commitResult === null;
|
|
1681
|
-
|
|
1682
|
-
// 9a. Clean up merge state files left by git merge --squash (#1853, #2912).
|
|
1683
|
-
// git only removes SQUASH_MSG when the commit reads it directly (plain
|
|
1684
|
-
// `git commit`). nativeCommit uses `-F -` (stdin) or libgit2, neither
|
|
1685
|
-
// of which trigger git's SQUASH_MSG cleanup. MERGE_HEAD is created by
|
|
1686
|
-
// libgit2's merge even in squash mode and is not removed by nativeCommit.
|
|
1687
|
-
// If left on disk, doctor reports `corrupt_merge_state` on every subsequent run.
|
|
1688
|
-
try {
|
|
1689
|
-
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1690
|
-
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1691
|
-
const p = join(gitDir_, f);
|
|
1692
|
-
if (existsSync(p)) unlinkSync(p);
|
|
1693
|
-
}
|
|
1694
|
-
} catch { /* best-effort */ }
|
|
1695
|
-
|
|
1696
|
-
// 9a-ii. Restore stashed files now that the merge+commit is complete (#2151).
|
|
1697
|
-
// Pop after commit so stashed changes do not interfere with the squash merge
|
|
1698
|
-
// or the commit content. Conflict on pop is non-fatal — the stash entry is
|
|
1699
|
-
// preserved and the user can resolve manually with `git stash pop`.
|
|
1700
|
-
if (stashed) {
|
|
1701
|
-
try {
|
|
1702
|
-
execFileSync("git", ["stash", "pop"], {
|
|
1703
|
-
cwd: originalBasePath_,
|
|
1704
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1705
|
-
encoding: "utf-8",
|
|
1706
|
-
});
|
|
1707
|
-
} catch {
|
|
1708
|
-
// Stash pop after squash merge can conflict on .gsd/ state files that
|
|
1709
|
-
// diverged between branches. Left unresolved, these UU entries block
|
|
1710
|
-
// every subsequent merge. Auto-resolve them the same way we handle
|
|
1711
|
-
// .gsd/ conflicts during the merge itself: accept HEAD (the just-committed
|
|
1712
|
-
// version) and drop the now-applied stash.
|
|
1713
|
-
const uu = nativeConflictFiles(originalBasePath_);
|
|
1714
|
-
const gsdUU = uu.filter((f) => f.startsWith(".gsd/"));
|
|
1715
|
-
const nonGsdUU = uu.filter((f) => !f.startsWith(".gsd/"));
|
|
1716
|
-
|
|
1717
|
-
if (gsdUU.length > 0) {
|
|
1718
|
-
for (const f of gsdUU) {
|
|
1719
|
-
try {
|
|
1720
|
-
// Accept the committed (HEAD) version of the state file
|
|
1721
|
-
execFileSync("git", ["checkout", "HEAD", "--", f], {
|
|
1722
|
-
cwd: originalBasePath_,
|
|
1723
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1724
|
-
encoding: "utf-8",
|
|
1725
|
-
});
|
|
1726
|
-
nativeAddPaths(originalBasePath_, [f]);
|
|
1727
|
-
} catch {
|
|
1728
|
-
// Last resort: remove the conflicted state file
|
|
1729
|
-
nativeRmForce(originalBasePath_, [f]);
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1732
|
-
}
|
|
1733
|
-
|
|
1734
|
-
if (nonGsdUU.length === 0) {
|
|
1735
|
-
// All conflicts were .gsd/ files — safe to drop the stash
|
|
1736
|
-
try {
|
|
1737
|
-
execFileSync("git", ["stash", "drop"], {
|
|
1738
|
-
cwd: originalBasePath_,
|
|
1739
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1740
|
-
encoding: "utf-8",
|
|
1741
|
-
});
|
|
1742
|
-
} catch { /* stash may already be consumed */ }
|
|
1743
|
-
} else {
|
|
1744
|
-
// Non-.gsd conflicts remain — leave stash for manual resolution
|
|
1745
|
-
logWarning("reconcile", "Stash pop conflict on non-.gsd files after merge", {
|
|
1746
|
-
files: nonGsdUU.join(", "),
|
|
1747
|
-
});
|
|
1748
|
-
}
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
|
|
1752
|
-
// 9a-iii. Restore sheltered queued milestone directories (#2505).
|
|
1753
|
-
restoreShelter();
|
|
1754
|
-
|
|
1755
|
-
// 9b. Safety check (#1792): if nothing was committed, verify the milestone
|
|
1756
|
-
// work is already on the integration branch before allowing teardown.
|
|
1757
|
-
// Compare only non-.gsd/ paths — .gsd/ state files diverge normally and
|
|
1758
|
-
// are auto-resolved during the squash merge.
|
|
1759
|
-
if (nothingToCommit) {
|
|
1760
|
-
const numstat = nativeDiffNumstat(
|
|
1761
|
-
originalBasePath_,
|
|
1762
|
-
mainBranch,
|
|
1763
|
-
milestoneBranch,
|
|
1764
|
-
);
|
|
1765
|
-
const codeChanges = numstat.filter(
|
|
1766
|
-
(entry) => !entry.path.startsWith(".gsd/"),
|
|
1767
|
-
);
|
|
1768
|
-
if (codeChanges.length > 0) {
|
|
1769
|
-
// Milestone has unanchored code changes — abort teardown.
|
|
1770
|
-
process.chdir(previousCwd);
|
|
1771
|
-
throw new GSDError(
|
|
1772
|
-
GSD_GIT_ERROR,
|
|
1773
|
-
`Squash merge produced nothing to commit but milestone branch "${milestoneBranch}" ` +
|
|
1774
|
-
`has ${codeChanges.length} code file(s) not on "${mainBranch}". ` +
|
|
1775
|
-
`Aborting worktree teardown to prevent data loss.`,
|
|
1776
|
-
);
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
// 9c. Detect whether any non-.gsd/ code files were actually merged (#1906).
|
|
1781
|
-
// When a milestone only produced .gsd/ metadata (summaries, roadmaps) but no
|
|
1782
|
-
// real code, the user sees "milestone complete" but nothing changed in their
|
|
1783
|
-
// codebase. Surface this so the caller can warn the user.
|
|
1784
|
-
let codeFilesChanged = false;
|
|
1785
|
-
if (!nothingToCommit) {
|
|
1786
|
-
try {
|
|
1787
|
-
const mergedFiles = nativeDiffNumstat(
|
|
1788
|
-
originalBasePath_,
|
|
1789
|
-
"HEAD~1",
|
|
1790
|
-
"HEAD",
|
|
1791
|
-
);
|
|
1792
|
-
codeFilesChanged = mergedFiles.some(
|
|
1793
|
-
(entry) => !entry.path.startsWith(".gsd/"),
|
|
1794
|
-
);
|
|
1795
|
-
} catch {
|
|
1796
|
-
// If HEAD~1 doesn't exist (first commit), assume code was changed
|
|
1797
|
-
codeFilesChanged = true;
|
|
1798
|
-
}
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
|
-
// 10. Auto-push if enabled
|
|
1802
|
-
let pushed = false;
|
|
1803
|
-
if (prefs.auto_push === true && !nothingToCommit) {
|
|
1804
|
-
const remote = prefs.remote ?? "origin";
|
|
1805
|
-
try {
|
|
1806
|
-
execFileSync("git", ["push", remote, mainBranch], {
|
|
1807
|
-
cwd: originalBasePath_,
|
|
1808
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1809
|
-
encoding: "utf-8",
|
|
1810
|
-
});
|
|
1811
|
-
pushed = true;
|
|
1812
|
-
} catch {
|
|
1813
|
-
// Push failure is non-fatal
|
|
1814
|
-
}
|
|
1815
|
-
}
|
|
1816
|
-
|
|
1817
|
-
// 9b. Auto-create PR if enabled (#2302: no longer gated on pushed/auto_push)
|
|
1818
|
-
let prCreated = false;
|
|
1819
|
-
if (prefs.auto_pr === true && !nothingToCommit) {
|
|
1820
|
-
const remote = prefs.remote ?? "origin";
|
|
1821
|
-
const prTarget = prefs.pr_target_branch ?? mainBranch;
|
|
1822
|
-
try {
|
|
1823
|
-
// Push the milestone branch to remote first
|
|
1824
|
-
execFileSync("git", ["push", remote, milestoneBranch], {
|
|
1825
|
-
cwd: originalBasePath_,
|
|
1826
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1827
|
-
encoding: "utf-8",
|
|
1828
|
-
});
|
|
1829
|
-
// Create PR via gh CLI with explicit --head and --base (#2302)
|
|
1830
|
-
execFileSync("gh", [
|
|
1831
|
-
"pr", "create", "--draft",
|
|
1832
|
-
"--base", prTarget,
|
|
1833
|
-
"--head", milestoneBranch,
|
|
1834
|
-
"--title", `Milestone ${milestoneId} complete`,
|
|
1835
|
-
"--body", "Auto-created by GSD on milestone completion.",
|
|
1836
|
-
], {
|
|
1837
|
-
cwd: originalBasePath_,
|
|
1838
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1839
|
-
encoding: "utf-8",
|
|
1840
|
-
});
|
|
1841
|
-
prCreated = true;
|
|
1842
|
-
} catch {
|
|
1843
|
-
// PR creation failure is non-fatal — gh may not be installed or authenticated
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1847
|
-
// 11. Guard removed — step 9b (#1792) now handles this with a smarter check:
|
|
1848
|
-
// throws only when the milestone has unanchored code changes, passes
|
|
1849
|
-
// through when the code is genuinely already on the integration branch.
|
|
1850
|
-
|
|
1851
|
-
// 11a. Pre-teardown safety net (#1853): if the worktree still has uncommitted
|
|
1852
|
-
// changes (e.g. nativeHasChanges cache returned stale false, or auto-commit
|
|
1853
|
-
// silently failed), force one final commit so code is not destroyed by
|
|
1854
|
-
// `git worktree remove --force`.
|
|
1855
|
-
if (existsSync(worktreeCwd)) {
|
|
1856
|
-
try {
|
|
1857
|
-
const dirtyCheck = nativeWorkingTreeStatus(worktreeCwd);
|
|
1858
|
-
if (dirtyCheck) {
|
|
1859
|
-
debugLog("mergeMilestoneToMain", {
|
|
1860
|
-
phase: "pre-teardown-dirty",
|
|
1861
|
-
worktreeCwd,
|
|
1862
|
-
status: dirtyCheck.slice(0, 200),
|
|
1863
|
-
});
|
|
1864
|
-
nativeAddAllWithExclusions(worktreeCwd, RUNTIME_EXCLUSION_PATHS);
|
|
1865
|
-
nativeCommit(worktreeCwd, "chore: pre-teardown auto-commit of uncommitted worktree changes");
|
|
1866
|
-
}
|
|
1867
|
-
} catch (e) {
|
|
1868
|
-
debugLog("mergeMilestoneToMain", {
|
|
1869
|
-
phase: "pre-teardown-commit-error",
|
|
1870
|
-
error: String(e),
|
|
1871
|
-
});
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
// 12. Remove worktree directory first (must happen before branch deletion)
|
|
1876
|
-
try {
|
|
1877
|
-
removeWorktree(originalBasePath_, milestoneId, {
|
|
1878
|
-
branch: null as unknown as string,
|
|
1879
|
-
deleteBranch: false,
|
|
1880
|
-
});
|
|
1881
|
-
} catch {
|
|
1882
|
-
// Best-effort -- worktree dir may already be gone
|
|
1883
|
-
}
|
|
1884
|
-
|
|
1885
|
-
// 13. Delete milestone branch (after worktree removal so ref is unlocked)
|
|
1886
|
-
try {
|
|
1887
|
-
nativeBranchDelete(originalBasePath_, milestoneBranch);
|
|
1888
|
-
} catch {
|
|
1889
|
-
// Best-effort
|
|
1890
|
-
}
|
|
1891
|
-
|
|
1892
|
-
// 14. Clear module state
|
|
1893
|
-
originalBase = null;
|
|
1894
|
-
nudgeGitBranchCache(previousCwd);
|
|
1895
|
-
|
|
1896
|
-
return { commitMessage, pushed, prCreated, codeFilesChanged };
|
|
1897
|
-
}
|