@opengsd/gsd-pi 1.4.0 → 1.5.0-dev.4fb2d460
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 +11 -11
- package/dist/onboarding.js +11 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +20 -25
- package/dist/resources/extensions/ask-user-questions.js +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +118 -53
- package/dist/resources/extensions/cursor-cli/index.js +16 -0
- package/dist/resources/extensions/cursor-cli/models.js +63 -0
- package/dist/resources/extensions/cursor-cli/package.json +11 -0
- package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
- package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
- package/dist/resources/extensions/gsd/activity-log.js +4 -1
- package/dist/resources/extensions/gsd/artifact-verification.js +25 -9
- package/dist/resources/extensions/gsd/auto/closeout.js +137 -42
- package/dist/resources/extensions/gsd/auto/finalize.js +9 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -3
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
- package/dist/resources/extensions/gsd/auto/run-unit.js +5 -2
- package/dist/resources/extensions/gsd/auto/schedule-wakeup.js +3 -0
- package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +12 -3
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
- package/dist/resources/extensions/gsd/auto-dispatch.js +31 -7
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
- package/dist/resources/extensions/gsd/auto-prompts.js +76 -2
- package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
- package/dist/resources/extensions/gsd/auto-start.js +8 -6
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
- package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
- package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
- package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
- package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
- package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
- package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +20 -2046
- package/dist/resources/extensions/gsd/auto.js +31 -5
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -0
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +134 -7
- package/dist/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.js +58 -9
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +194 -28
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +14 -1
- package/dist/resources/extensions/gsd/codebase-generator.js +164 -20
- package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +153 -1
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
- package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
- package/dist/resources/extensions/gsd/db/queries.js +48 -9
- package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
- package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -2
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +292 -18
- package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
- package/dist/resources/extensions/gsd/doctor.js +93 -3
- package/dist/resources/extensions/gsd/exec-sandbox.js +6 -2
- package/dist/resources/extensions/gsd/flat-phase-migration.js +106 -26
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
- package/dist/resources/extensions/gsd/git-service.js +59 -18
- package/dist/resources/extensions/gsd/gsd-db.js +75 -11
- package/dist/resources/extensions/gsd/guidance.js +1 -0
- package/dist/resources/extensions/gsd/guided-flow.js +62 -19
- package/dist/resources/extensions/gsd/key-manager.js +1 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +40 -11
- package/dist/resources/extensions/gsd/md-importer.js +89 -23
- package/dist/resources/extensions/gsd/migrate-external.js +24 -7
- package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +14 -3
- package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
- package/dist/resources/extensions/gsd/paths.js +17 -3
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
- package/dist/resources/extensions/gsd/preferences-models.js +6 -4
- package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +107 -2
- package/dist/resources/extensions/gsd/preferences.js +49 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/system.md +6 -6
- package/dist/resources/extensions/gsd/quick.js +12 -3
- package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
- package/dist/resources/extensions/gsd/repo-identity.js +16 -0
- package/dist/resources/extensions/gsd/repository-registry.js +6 -1
- package/dist/resources/extensions/gsd/root-write-leak-guard.js +4 -2
- package/dist/resources/extensions/gsd/safe-fs.js +23 -2
- package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
- package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
- package/dist/resources/extensions/gsd/tool-contract.js +14 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +76 -8
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
- package/dist/resources/extensions/gsd/unit-registry.js +37 -2
- package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
- package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
- package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
- package/dist/resources/extensions/gsd/workspace.js +26 -8
- package/dist/resources/extensions/gsd/worktree-command.js +1 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +81 -14
- package/dist/resources/extensions/gsd/worktree-manager.js +97 -4
- package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
- package/dist/resources/extensions/shared/interview-ui.js +62 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/wizard.d.ts +8 -0
- package/dist/wizard.js +8 -1
- package/integrations/hermes/CONTEXT.md +47 -0
- package/integrations/hermes/README.md +21 -0
- package/integrations/hermes/__init__.py +31 -0
- package/integrations/hermes/docs/issue-1162-grilling.md +197 -0
- package/integrations/hermes/docs/setup.md +4 -0
- package/integrations/hermes/open_gsd_hermes/commands.py +141 -0
- package/integrations/hermes/open_gsd_hermes/config.py +2 -0
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +591 -39
- package/integrations/hermes/open_gsd_hermes/notifications.py +10 -1
- package/integrations/hermes/plugin.yaml +4 -0
- package/integrations/hermes/tests/test_config.py +6 -0
- package/integrations/hermes/tests/test_directory_loader.py +37 -0
- package/integrations/hermes/tests/test_gsd_client_cache.py +3 -0
- package/integrations/hermes/tests/test_gsd_client_execute.py +35 -0
- package/integrations/hermes/tests/test_gsd_client_process_cwd.py +22 -0
- package/integrations/hermes/tests/test_gsd_client_timeout.py +98 -0
- package/integrations/hermes/tests/test_milestone_client.py +447 -0
- package/integrations/hermes/tests/test_new_milestone_command.py +313 -0
- package/integrations/hermes/tests/test_supervisor_fsm.py +40 -0
- package/package.json +8 -8
- package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
- package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
- package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
- package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-runtime.js +25 -1
- package/packages/daemon/dist/cloud-runtime.js.map +1 -1
- package/packages/daemon/dist/cloud-runtime.test.js +51 -0
- package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
- package/packages/daemon/dist/message-batcher.d.ts +7 -0
- package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
- package/packages/daemon/dist/message-batcher.js +13 -0
- package/packages/daemon/dist/message-batcher.js.map +1 -1
- package/packages/daemon/dist/message-batcher.test.js +48 -0
- package/packages/daemon/dist/message-batcher.test.js.map +1 -1
- package/packages/daemon/dist/session-manager.js +1 -1
- package/packages/daemon/dist/session-manager.js.map +1 -1
- package/packages/daemon/package.json +5 -5
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.js +4 -1
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +18 -5
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +46 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +1 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +14 -9
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/env-api-keys.d.ts.map +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +3 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
- package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
- package/packages/pi-ai/dist/tool-result-content.js +62 -0
- package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +10 -22
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +3 -0
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +4 -1
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/dist/rpc-client.js +1 -1
- package/packages/rpc-client/dist/rpc-client.js.map +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/core/export-html/template.js +53 -4
- package/pkg/package.json +1 -1
- package/scripts/link-workspace-packages.cjs +14 -4
- package/src/resources/GSD-WORKFLOW.md +20 -25
- package/src/resources/extensions/ask-user-questions.ts +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +130 -51
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +371 -39
- package/src/resources/extensions/cursor-cli/index.ts +18 -0
- package/src/resources/extensions/cursor-cli/models.ts +65 -0
- package/src/resources/extensions/cursor-cli/package.json +11 -0
- package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
- package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
- package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
- package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
- package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
- package/src/resources/extensions/gsd/activity-log.ts +4 -1
- package/src/resources/extensions/gsd/artifact-verification.ts +25 -9
- package/src/resources/extensions/gsd/auto/closeout.ts +163 -58
- package/src/resources/extensions/gsd/auto/finalize.ts +8 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -3
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +5 -2
- package/src/resources/extensions/gsd/auto/schedule-wakeup.ts +8 -0
- package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +12 -3
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +35 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
- package/src/resources/extensions/gsd/auto-prompts.ts +73 -2
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
- package/src/resources/extensions/gsd/auto-start.ts +9 -6
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
- package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
- package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
- package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
- package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
- package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
- package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
- package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
- package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
- package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +69 -2390
- package/src/resources/extensions/gsd/auto.ts +32 -19
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -0
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +148 -7
- package/src/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.ts +80 -12
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +229 -28
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +23 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +186 -19
- package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +135 -1
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
- package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
- package/src/resources/extensions/gsd/db/queries.ts +49 -9
- package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
- package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -2
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +372 -22
- package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
- package/src/resources/extensions/gsd/doctor-types.ts +5 -1
- package/src/resources/extensions/gsd/doctor.ts +95 -3
- package/src/resources/extensions/gsd/exec-sandbox.ts +6 -2
- package/src/resources/extensions/gsd/flat-phase-migration.ts +132 -25
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +67 -17
- package/src/resources/extensions/gsd/gsd-db.ts +105 -11
- package/src/resources/extensions/gsd/guidance.ts +2 -0
- package/src/resources/extensions/gsd/guided-flow.ts +71 -20
- package/src/resources/extensions/gsd/key-manager.ts +1 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +40 -10
- package/src/resources/extensions/gsd/md-importer.ts +93 -22
- package/src/resources/extensions/gsd/migrate-external.ts +23 -6
- package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +19 -4
- package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
- package/src/resources/extensions/gsd/model-router.ts +4 -5
- package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/paths.ts +21 -3
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
- package/src/resources/extensions/gsd/preferences-models.ts +6 -3
- package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
- package/src/resources/extensions/gsd/preferences-types.ts +30 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +97 -2
- package/src/resources/extensions/gsd/preferences.ts +58 -4
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/system.md +6 -6
- package/src/resources/extensions/gsd/quick.ts +11 -3
- package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
- package/src/resources/extensions/gsd/repo-identity.ts +17 -0
- package/src/resources/extensions/gsd/repository-registry.ts +7 -1
- package/src/resources/extensions/gsd/root-write-leak-guard.ts +3 -2
- package/src/resources/extensions/gsd/safe-fs.ts +22 -2
- package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -5
- package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +111 -0
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +387 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +571 -5
- package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +109 -2
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
- package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +592 -23
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +50 -6
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +264 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/preferences.test.ts +169 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +31 -9
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/schedule-wakeup-tool.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +259 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +208 -1
- package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +36 -3
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
- package/src/resources/extensions/gsd/tool-contract.ts +29 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +107 -9
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
- package/src/resources/extensions/gsd/unit-registry.ts +48 -2
- package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
- package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
- package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
- package/src/resources/extensions/gsd/workspace.ts +42 -8
- package/src/resources/extensions/gsd/worktree-command.ts +1 -1
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +154 -26
- package/src/resources/extensions/gsd/worktree-manager.ts +143 -5
- package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
- package/src/resources/extensions/shared/interview-ui.ts +58 -11
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → gXoWec4UNqcR0tkuHwYCr}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → gXoWec4UNqcR0tkuHwYCr}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// gsd-pi — Milestone merge pre-teardown safety guard.
|
|
2
|
+
//
|
|
3
|
+
// Owns the final data-loss check before deleting a merged milestone worktree:
|
|
4
|
+
// if the milestone worktree still has uncommitted work, abort teardown so the
|
|
5
|
+
// milestone branch remains a recovery ref.
|
|
6
|
+
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
|
|
9
|
+
import { debugLog } from "./debug-logger.js";
|
|
10
|
+
import { GSDError, GSD_GIT_ERROR } from "./errors.js";
|
|
11
|
+
import {
|
|
12
|
+
nativeGetCurrentBranch,
|
|
13
|
+
nativeWorkingTreeStatus,
|
|
14
|
+
} from "./native-git-bridge.js";
|
|
15
|
+
|
|
16
|
+
export interface PreTeardownSafetyRequest {
|
|
17
|
+
milestoneBranch: string;
|
|
18
|
+
previousCwd: string;
|
|
19
|
+
worktreeCwd: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface PreTeardownSafetyDeps {
|
|
23
|
+
chdir: typeof process.chdir;
|
|
24
|
+
debugLog: typeof debugLog;
|
|
25
|
+
existsSync: typeof existsSync;
|
|
26
|
+
nativeGetCurrentBranch: typeof nativeGetCurrentBranch;
|
|
27
|
+
nativeWorkingTreeStatus: typeof nativeWorkingTreeStatus;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const defaultDeps: PreTeardownSafetyDeps = {
|
|
31
|
+
chdir: process.chdir.bind(process),
|
|
32
|
+
debugLog,
|
|
33
|
+
existsSync,
|
|
34
|
+
nativeGetCurrentBranch,
|
|
35
|
+
nativeWorkingTreeStatus,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
let deps: PreTeardownSafetyDeps = defaultDeps;
|
|
39
|
+
|
|
40
|
+
export function _setPreTeardownSafetyDepsForTests(
|
|
41
|
+
overrides: Partial<PreTeardownSafetyDeps>,
|
|
42
|
+
): void {
|
|
43
|
+
deps = { ...defaultDeps, ...overrides };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function _resetPreTeardownSafetyDepsForTests(): void {
|
|
47
|
+
deps = defaultDeps;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Abort teardown when the milestone worktree still has uncommitted changes.
|
|
52
|
+
*
|
|
53
|
+
* The guard is intentionally scoped to worktree paths that are still on the
|
|
54
|
+
* milestone branch. In branch-mode or parallel merge paths, `worktreeCwd` can
|
|
55
|
+
* point at the integration branch; blocking on that dirty state would conflate
|
|
56
|
+
* unrelated milestones and preserve the wrong recovery ref.
|
|
57
|
+
*/
|
|
58
|
+
export function assertMilestoneWorktreeCleanBeforeTeardown(
|
|
59
|
+
request: PreTeardownSafetyRequest,
|
|
60
|
+
): void {
|
|
61
|
+
const { milestoneBranch, previousCwd, worktreeCwd } = request;
|
|
62
|
+
if (!deps.existsSync(worktreeCwd)) return;
|
|
63
|
+
|
|
64
|
+
let preTeardownBranch: string | null = null;
|
|
65
|
+
try {
|
|
66
|
+
preTeardownBranch = deps.nativeGetCurrentBranch(worktreeCwd);
|
|
67
|
+
} catch (err) {
|
|
68
|
+
deps.debugLog("mergeMilestoneToMain", {
|
|
69
|
+
phase: "pre-teardown-branch-detect-failed",
|
|
70
|
+
error: String(err),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (preTeardownBranch !== milestoneBranch) return;
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const dirtyCheck = deps.nativeWorkingTreeStatus(worktreeCwd);
|
|
78
|
+
if (!dirtyCheck) return;
|
|
79
|
+
|
|
80
|
+
deps.chdir(previousCwd);
|
|
81
|
+
throw new GSDError(
|
|
82
|
+
GSD_GIT_ERROR,
|
|
83
|
+
`Milestone worktree still has uncommitted changes after squash merge. ` +
|
|
84
|
+
`Aborting teardown to preserve ${milestoneBranch}. Status:\n${dirtyCheck}`,
|
|
85
|
+
);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
if (err instanceof GSDError) throw err;
|
|
88
|
+
deps.debugLog("mergeMilestoneToMain", {
|
|
89
|
+
phase: "pre-teardown-dirty-check-error",
|
|
90
|
+
error: String(err),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// gsd-pi — Pre-merge stash handling for auto-worktree merge closeout.
|
|
2
|
+
//
|
|
3
|
+
// Owns the local-work protection around milestone merge: stash before merge,
|
|
4
|
+
// DB handle cycling for Windows, restoring on merge failures, and post-commit
|
|
5
|
+
// stash-pop conflict recovery.
|
|
6
|
+
|
|
7
|
+
import { execFileSync } from "node:child_process";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
closeWorkflowDatabase,
|
|
12
|
+
getWorkflowDatabasePath,
|
|
13
|
+
openWorkflowDatabasePath,
|
|
14
|
+
} from "./db-workspace.js";
|
|
15
|
+
import {
|
|
16
|
+
nativeAddPaths,
|
|
17
|
+
nativeConflictFiles,
|
|
18
|
+
nativeLsFiles,
|
|
19
|
+
nativeRmForce,
|
|
20
|
+
} from "./native-git-bridge.js";
|
|
21
|
+
import {
|
|
22
|
+
gsdJsonlFilesWithConflictMarkers,
|
|
23
|
+
hasConflictMarkers,
|
|
24
|
+
popStashByRef,
|
|
25
|
+
stashAlreadyExistsFilesFromError,
|
|
26
|
+
stashRefFromError,
|
|
27
|
+
} from "./worktree-git-recovery.js";
|
|
28
|
+
import { logWarning } from "./workflow-logger.js";
|
|
29
|
+
|
|
30
|
+
export interface PreMergeStash {
|
|
31
|
+
stash(): void;
|
|
32
|
+
reopenDbAfterMerge(): void;
|
|
33
|
+
restoreForMergeFailure(): void;
|
|
34
|
+
restoreAfterCommit(): void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function createPreMergeStash(
|
|
38
|
+
basePath: string,
|
|
39
|
+
milestoneId: string,
|
|
40
|
+
cycleDbHandles: boolean,
|
|
41
|
+
): PreMergeStash {
|
|
42
|
+
let stashed = false;
|
|
43
|
+
let marker: string | null = null;
|
|
44
|
+
const dbPathToReopen = cycleDbHandles ? getWorkflowDatabasePath() : null;
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
stash(): void {
|
|
48
|
+
closeDbBeforeStashIfNeeded(cycleDbHandles);
|
|
49
|
+
try {
|
|
50
|
+
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
51
|
+
cwd: basePath,
|
|
52
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
53
|
+
encoding: "utf-8",
|
|
54
|
+
}).trim();
|
|
55
|
+
if (!status) return;
|
|
56
|
+
|
|
57
|
+
marker = createStashMarker(milestoneId);
|
|
58
|
+
execFileSync(
|
|
59
|
+
"git",
|
|
60
|
+
["stash", "push", "--include-untracked", "-m", `gsd: pre-merge stash for ${milestoneId} [${marker}]`],
|
|
61
|
+
{ cwd: basePath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
|
|
62
|
+
);
|
|
63
|
+
stashed = true;
|
|
64
|
+
} catch (err) {
|
|
65
|
+
// Stash failure is non-fatal — proceed without stash and let the merge
|
|
66
|
+
// report the dirty tree if it fails.
|
|
67
|
+
logWarning("worktree", `git stash failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
reopenDbAfterMerge(): void {
|
|
72
|
+
if (!cycleDbHandles || !dbPathToReopen) return;
|
|
73
|
+
try {
|
|
74
|
+
openWorkflowDatabasePath(dbPathToReopen);
|
|
75
|
+
} catch (err) {
|
|
76
|
+
logWarning("worktree", `post-merge db reopen failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
restoreForMergeFailure(): void {
|
|
81
|
+
if (!stashed) return;
|
|
82
|
+
try {
|
|
83
|
+
popStashByRef(basePath, marker);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
logWarning("worktree", `git stash pop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
restoreAfterCommit(): void {
|
|
90
|
+
if (!stashed) return;
|
|
91
|
+
restoreStashAfterCommit(basePath, marker);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function closeDbBeforeStashIfNeeded(cycleDbHandles: boolean): void {
|
|
97
|
+
if (!cycleDbHandles) return;
|
|
98
|
+
try {
|
|
99
|
+
closeWorkflowDatabase();
|
|
100
|
+
} catch (err) {
|
|
101
|
+
logWarning("worktree", `pre-stash db close failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function createStashMarker(milestoneId: string): string {
|
|
106
|
+
return `gsd-pre-merge:${milestoneId}:${process.pid}:${Date.now()}:${process.hrtime.bigint().toString(36)}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function restoreStashAfterCommit(basePath: string, marker: string | null): void {
|
|
110
|
+
let stashRefForDrop: string | null = null;
|
|
111
|
+
try {
|
|
112
|
+
stashRefForDrop = popStashByRef(basePath, marker);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
stashRefForDrop = stashRefFromError(e);
|
|
115
|
+
logWarning("worktree", `git stash pop failed, attempting conflict resolution: ${(e as Error).message}`);
|
|
116
|
+
resolveStashPopConflict(basePath, e, stashRefForDrop);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function resolveStashPopConflict(basePath: string, error: unknown, stashRefForDrop: string | null): void {
|
|
121
|
+
const uu = nativeConflictFiles(basePath);
|
|
122
|
+
const gsdUU = uu.filter((f) => f.startsWith(".gsd/"));
|
|
123
|
+
const nonGsdUU = uu.filter((f) => !f.startsWith(".gsd/"));
|
|
124
|
+
const stashPopMessage = error instanceof Error ? error.message : String(error);
|
|
125
|
+
const isUntrackedRestoreFailure = stashPopMessage.includes("could not restore untracked files from stash");
|
|
126
|
+
const gsdContentConflicts: string[] = [];
|
|
127
|
+
const alreadyExists = stashAlreadyExistsFilesFromError(error);
|
|
128
|
+
|
|
129
|
+
if (isUntrackedRestoreFailure) {
|
|
130
|
+
gsdContentConflicts.push(...gsdJsonlFilesWithConflictMarkers(basePath));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const gsdConflictFiles = [...new Set([...gsdUU, ...gsdContentConflicts])];
|
|
134
|
+
resolveGsdConflictFiles(basePath, gsdConflictFiles);
|
|
135
|
+
|
|
136
|
+
if (gsdConflictFiles.length > 0 && nonGsdUU.length === 0) {
|
|
137
|
+
dropStashIfNoNonGsdConflictsRemain(basePath, stashRefForDrop);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (gsdUU.length === 0 && nonGsdUU.length === 0 && alreadyExists.length > 0) {
|
|
142
|
+
dropRecordedStash(basePath, stashRefForDrop);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (nonGsdUU.length > 0) {
|
|
147
|
+
logWarning("reconcile", "Stash pop conflict on non-.gsd files after merge", {
|
|
148
|
+
files: nonGsdUU.join(", "),
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
logWarning(
|
|
154
|
+
"worktree",
|
|
155
|
+
"git stash pop failed without resolvable conflict files; leaving stash for manual recovery",
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function resolveGsdConflictFiles(basePath: string, conflictFiles: string[]): void {
|
|
160
|
+
for (const file of conflictFiles) {
|
|
161
|
+
try {
|
|
162
|
+
// Accept the committed (HEAD) version of the state file.
|
|
163
|
+
execFileSync("git", ["checkout", "HEAD", "--", file], {
|
|
164
|
+
cwd: basePath,
|
|
165
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
166
|
+
encoding: "utf-8",
|
|
167
|
+
});
|
|
168
|
+
nativeAddPaths(basePath, [file]);
|
|
169
|
+
} catch (err) {
|
|
170
|
+
// Last resort: remove the conflicted state file.
|
|
171
|
+
logWarning("worktree", `checkout HEAD failed for ${file}, removing: ${(err as Error).message}`);
|
|
172
|
+
nativeRmForce(basePath, [file]);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function dropStashIfNoNonGsdConflictsRemain(basePath: string, stashRefForDrop: string | null): void {
|
|
178
|
+
const remainingUnmerged = nativeConflictFiles(basePath);
|
|
179
|
+
const nonGsdUnmerged = remainingUnmerged.filter((f) => !f.startsWith(".gsd/"));
|
|
180
|
+
const markerCandidates = Array.from(new Set([
|
|
181
|
+
...nonGsdUnmerged,
|
|
182
|
+
...nativeLsFiles(basePath, "."),
|
|
183
|
+
])).filter((f) => !f.startsWith(".gsd/"));
|
|
184
|
+
const nonGsdMarkerConflicts = markerCandidates.filter((f) =>
|
|
185
|
+
hasConflictMarkers(join(basePath, f)),
|
|
186
|
+
);
|
|
187
|
+
const hasRemainingNonGsdConflicts = nonGsdUnmerged.length > 0 || nonGsdMarkerConflicts.length > 0;
|
|
188
|
+
if (hasRemainingNonGsdConflicts) {
|
|
189
|
+
const files = Array.from(new Set([...nonGsdUnmerged, ...nonGsdMarkerConflicts]));
|
|
190
|
+
logWarning("reconcile", "Leaving stash because non-.gsd conflicts remain after auto-resolution", {
|
|
191
|
+
files: files.join(", "),
|
|
192
|
+
});
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
dropRecordedStash(basePath, stashRefForDrop);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function dropRecordedStash(basePath: string, stashRefForDrop: string | null): void {
|
|
200
|
+
if (!stashRefForDrop) {
|
|
201
|
+
logWarning("worktree", "recorded stash entry could not be resolved; skipping automatic drop");
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
execFileSync("git", ["stash", "drop", stashRefForDrop], {
|
|
206
|
+
cwd: basePath,
|
|
207
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
208
|
+
encoding: "utf-8",
|
|
209
|
+
});
|
|
210
|
+
} catch (err) {
|
|
211
|
+
logWarning("worktree", `git stash drop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
// gsd-pi — Auto-worktree merge module.
|
|
2
|
+
//
|
|
3
|
+
// Owns milestone merge/closeout for auto-worktrees: dirty-state capture, DB
|
|
4
|
+
// reconciliation, integration-branch merge, stash/shelter recovery, publication,
|
|
5
|
+
// and safe teardown.
|
|
6
|
+
|
|
7
|
+
import { atomicWriteSync } from "./atomic-write.js";
|
|
8
|
+
import { debugLog } from "./debug-logger.js";
|
|
9
|
+
import { GSDError, GSD_GIT_ERROR } from "./errors.js";
|
|
10
|
+
import { autoResolveSafeConflictPaths } from "./git-conflict-resolve.js";
|
|
11
|
+
import {
|
|
12
|
+
MergeConflictError,
|
|
13
|
+
RUNTIME_EXCLUSION_PATHS,
|
|
14
|
+
} from "./git-service.js";
|
|
15
|
+
import {
|
|
16
|
+
getMilestone,
|
|
17
|
+
isDbAvailable,
|
|
18
|
+
} from "./gsd-db.js";
|
|
19
|
+
import {
|
|
20
|
+
nativeAddAllWithExclusions,
|
|
21
|
+
nativeCommit,
|
|
22
|
+
nativeConflictFiles,
|
|
23
|
+
nativeGetCurrentBranch,
|
|
24
|
+
nativeMergeRegular,
|
|
25
|
+
nativeMergeSquash,
|
|
26
|
+
nativeWorkingTreeStatus,
|
|
27
|
+
} from "./native-git-bridge.js";
|
|
28
|
+
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
29
|
+
import { publishMilestone } from "./publication.js";
|
|
30
|
+
import {
|
|
31
|
+
autoWorktreeBranch,
|
|
32
|
+
} from "./auto-worktree-branch-lifecycle.js";
|
|
33
|
+
import { createMilestoneDirectoryShelter } from "./auto-worktree-milestone-shelter.js";
|
|
34
|
+
import { getActiveWorkspace } from "./auto-worktree-session-registry.js";
|
|
35
|
+
import {
|
|
36
|
+
assertNoUnanchoredCodeChangesAfterEmptyMerge,
|
|
37
|
+
detectMergedCodeFilesChanged,
|
|
38
|
+
} from "./auto-worktree-merge-code-changes.js";
|
|
39
|
+
import { reconcileMilestoneBranchHead } from "./auto-worktree-merge-branch-head.js";
|
|
40
|
+
import { finalizeAlreadyMergedMilestoneIfReachable } from "./auto-worktree-merge-already-merged.js";
|
|
41
|
+
import { cleanupMergedMilestoneWorktree } from "./auto-worktree-merge-cleanup.js";
|
|
42
|
+
import { assertMilestoneDbReadyForMerge } from "./auto-worktree-merge-db-ready.js";
|
|
43
|
+
import { prepareIntegrationBranchForMilestoneMerge } from "./auto-worktree-merge-integration-branch.js";
|
|
44
|
+
import { buildMilestoneMergeMessage } from "./auto-worktree-merge-message.js";
|
|
45
|
+
import { assertMilestoneWorktreeCleanBeforeTeardown } from "./auto-worktree-merge-pre-teardown.js";
|
|
46
|
+
import { createPreMergeStash } from "./auto-worktree-merge-stash.js";
|
|
47
|
+
import {
|
|
48
|
+
cleanupConflictState,
|
|
49
|
+
removeMergeStateFiles,
|
|
50
|
+
} from "./worktree-git-recovery.js";
|
|
51
|
+
import { logError, logWarning } from "./workflow-logger.js";
|
|
52
|
+
|
|
53
|
+
export { _setRestoreEntryFnForTests } from "./auto-worktree-milestone-shelter.js";
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
// ─── Merge Milestone -> Main ───────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Auto-commit any dirty (uncommitted) state in the given directory.
|
|
60
|
+
* Returns true if a commit was made, false if working tree was clean.
|
|
61
|
+
*/
|
|
62
|
+
function autoCommitDirtyState(cwd: string): boolean {
|
|
63
|
+
try {
|
|
64
|
+
const status = nativeWorkingTreeStatus(cwd);
|
|
65
|
+
if (!status) return false;
|
|
66
|
+
nativeAddAllWithExclusions(cwd, RUNTIME_EXCLUSION_PATHS);
|
|
67
|
+
const result = nativeCommit(
|
|
68
|
+
cwd,
|
|
69
|
+
"chore: auto-commit before milestone merge",
|
|
70
|
+
);
|
|
71
|
+
return result !== null;
|
|
72
|
+
} catch (e) {
|
|
73
|
+
debugLog("autoCommitDirtyState", { error: String(e) });
|
|
74
|
+
throw new GSDError(
|
|
75
|
+
GSD_GIT_ERROR,
|
|
76
|
+
`Failed to auto-commit dirty worktree state before milestone merge: ${e instanceof Error ? e.message : String(e)}`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Squash-merge the milestone branch into main with a rich commit message
|
|
83
|
+
* listing all completed slices, then tear down the worktree.
|
|
84
|
+
*
|
|
85
|
+
* Sequence:
|
|
86
|
+
* 1. Auto-commit dirty worktree state
|
|
87
|
+
* 2. chdir to originalBasePath
|
|
88
|
+
* 3. git checkout main
|
|
89
|
+
* 4. git merge --squash milestone/<MID>
|
|
90
|
+
* 5. git commit with rich message
|
|
91
|
+
* 6. Auto-push if enabled
|
|
92
|
+
* 7. Delete milestone branch
|
|
93
|
+
* 8. Remove worktree directory
|
|
94
|
+
* 9. Clear originalBase
|
|
95
|
+
*
|
|
96
|
+
* On merge conflict: throws MergeConflictError.
|
|
97
|
+
* On "nothing to commit" after squash: safe only if milestone work is already
|
|
98
|
+
* on the integration branch. Throws if unanchored code changes would be lost.
|
|
99
|
+
*
|
|
100
|
+
* @internal **Do not call directly.** This is the inner squash-merge primitive
|
|
101
|
+
* for the Worktree Lifecycle Module (ADR-016 phase 2 / A3, issue #5619).
|
|
102
|
+
* Production callers must go through `WorktreeLifecycle.mergeMilestoneStandalone`
|
|
103
|
+
* or `WorktreeLifecycle.exitMilestone({ merge: true })`. The export keyword
|
|
104
|
+
* is preserved for legacy tests and the default transaction adapter; production
|
|
105
|
+
* wiring depends on `createDefaultMilestoneMergeTransaction()` instead.
|
|
106
|
+
*/
|
|
107
|
+
export function mergeMilestoneToMain(
|
|
108
|
+
originalBasePath_: string,
|
|
109
|
+
milestoneId: string,
|
|
110
|
+
roadmapContent: string,
|
|
111
|
+
): { commitMessage: string; pushed: boolean; prCreated: boolean; codeFilesChanged: boolean } {
|
|
112
|
+
const worktreeCwd = process.cwd();
|
|
113
|
+
const milestoneBranch = autoWorktreeBranch(milestoneId);
|
|
114
|
+
|
|
115
|
+
// 1. Auto-commit dirty state before leaving.
|
|
116
|
+
// Guard: when we entered through an auto-worktree (originalBase is set),
|
|
117
|
+
// only auto-commit when cwd is on the milestone branch. In parallel mode,
|
|
118
|
+
// cwd may be on the integration branch after a prior merge's
|
|
119
|
+
// MergeConflictError left cwd unrestored. Auto-committing on the
|
|
120
|
+
// integration branch captures dirty files from OTHER milestones under a
|
|
121
|
+
// misleading commit message, contaminating the main branch (#2929).
|
|
122
|
+
//
|
|
123
|
+
// When activeWorkspace is null (branch mode, no worktree), autoCommitDirtyState
|
|
124
|
+
// runs unconditionally — the caller is responsible for cwd placement.
|
|
125
|
+
{
|
|
126
|
+
let shouldAutoCommit = true;
|
|
127
|
+
if (getActiveWorkspace() !== null) {
|
|
128
|
+
try {
|
|
129
|
+
const currentBranch = nativeGetCurrentBranch(worktreeCwd);
|
|
130
|
+
shouldAutoCommit = currentBranch === milestoneBranch;
|
|
131
|
+
} catch {
|
|
132
|
+
// If we can't determine the branch, skip the auto-commit to be safe
|
|
133
|
+
shouldAutoCommit = false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (shouldAutoCommit) {
|
|
137
|
+
autoCommitDirtyState(worktreeCwd);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Reconcile DB state and prove closeout before leaving worktree context.
|
|
142
|
+
assertMilestoneDbReadyForMerge({
|
|
143
|
+
milestoneId,
|
|
144
|
+
projectRoot: originalBasePath_,
|
|
145
|
+
worktreeCwd,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// 2. Build completed-slice summaries and rich commit message.
|
|
149
|
+
const { commitMessage, milestoneTitle, sliceSummaries } = buildMilestoneMergeMessage({
|
|
150
|
+
milestoneId,
|
|
151
|
+
milestoneBranch,
|
|
152
|
+
roadmapContent,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// 3. chdir to original base
|
|
156
|
+
// Note: previousCwd captures the cwd at this point — i.e. the worktree cwd
|
|
157
|
+
// entering the function. Subsequent throws restore to previousCwd, leaving
|
|
158
|
+
// the caller in worktree-cwd; callers (worktree-resolver) are responsible
|
|
159
|
+
// for any further cwd movement on the error path.
|
|
160
|
+
const previousCwd = process.cwd();
|
|
161
|
+
process.chdir(originalBasePath_);
|
|
162
|
+
|
|
163
|
+
// 4/5. Resolve and prepare the integration branch. The integration-branch
|
|
164
|
+
// module owns stale metadata fallback, self-merge fail-closed behavior,
|
|
165
|
+
// detached HEAD protection, transient state cleanup, and checkout.
|
|
166
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences?.git ?? {};
|
|
167
|
+
const { mainBranch } = prepareIntegrationBranchForMilestoneMerge({
|
|
168
|
+
milestoneBranch,
|
|
169
|
+
milestoneId,
|
|
170
|
+
prefs,
|
|
171
|
+
previousCwd,
|
|
172
|
+
projectRoot: originalBasePath_,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// 6b. Reconcile worktree HEAD with milestone branch ref (#1846).
|
|
176
|
+
// The branch-head module owns the data-loss guard: fast-forward stale
|
|
177
|
+
// branch refs to detached worktree commits, and fail loudly on divergence.
|
|
178
|
+
reconcileMilestoneBranchHead({
|
|
179
|
+
projectRoot: originalBasePath_,
|
|
180
|
+
worktreeCwd,
|
|
181
|
+
milestoneBranch,
|
|
182
|
+
previousCwd,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Already regular-merged milestones can skip the squash path and proceed to cleanup (#5831).
|
|
186
|
+
const alreadyMerged = finalizeAlreadyMergedMilestoneIfReachable({
|
|
187
|
+
projectRoot: originalBasePath_,
|
|
188
|
+
milestoneId,
|
|
189
|
+
milestoneBranch,
|
|
190
|
+
mainBranch,
|
|
191
|
+
previousCwd,
|
|
192
|
+
commitMessage,
|
|
193
|
+
});
|
|
194
|
+
if (alreadyMerged) return alreadyMerged;
|
|
195
|
+
|
|
196
|
+
// 7. Shelter queued milestone directories before the squash merge (#2505).
|
|
197
|
+
// MUST run before the pre-merge stash so queued CONTEXT files are not swept
|
|
198
|
+
// into a stash that may later fail to pop and strand user work.
|
|
199
|
+
const milestoneDirectoryShelter = createMilestoneDirectoryShelter(
|
|
200
|
+
originalBasePath_,
|
|
201
|
+
milestoneId,
|
|
202
|
+
getMilestone(milestoneId)?.title,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// 7a. Stash pre-existing dirty files so the squash merge is not blocked by
|
|
206
|
+
// unrelated local changes (#2151). The stash module also owns Windows DB
|
|
207
|
+
// handle cycling and later stash-pop conflict recovery.
|
|
208
|
+
const preMergeStash = createPreMergeStash(
|
|
209
|
+
originalBasePath_,
|
|
210
|
+
milestoneId,
|
|
211
|
+
process.platform === "win32" && isDbAvailable(),
|
|
212
|
+
);
|
|
213
|
+
preMergeStash.stash();
|
|
214
|
+
|
|
215
|
+
// 7b. Clean up stale merge state before attempting the merge (#2912).
|
|
216
|
+
// A leftover MERGE_HEAD (from a previous failed merge, libgit2 native path,
|
|
217
|
+
// or interrupted operation) causes git merge to refuse with
|
|
218
|
+
// "fatal: You have not concluded your merge (MERGE_HEAD exists)".
|
|
219
|
+
// Defensively remove merge artifacts before starting.
|
|
220
|
+
removeMergeStateFiles(originalBasePath_, "pre-merge");
|
|
221
|
+
|
|
222
|
+
// 8. Merge — respect merge_strategy preference (#549).
|
|
223
|
+
// "squash" (default): stages changes without a merge commit; caller commits.
|
|
224
|
+
// "merge": --no-ff --no-commit so caller can supply the commit message while
|
|
225
|
+
// git records a real merge commit (MERGE_HEAD present when nativeCommit runs).
|
|
226
|
+
const effectiveStrategy = prefs.merge_strategy === "merge" ? "merge" : "squash";
|
|
227
|
+
const mergeResult = effectiveStrategy === "merge"
|
|
228
|
+
? nativeMergeRegular(originalBasePath_, milestoneBranch)
|
|
229
|
+
: nativeMergeSquash(originalBasePath_, milestoneBranch);
|
|
230
|
+
preMergeStash.reopenDbAfterMerge();
|
|
231
|
+
|
|
232
|
+
if (!mergeResult.success) {
|
|
233
|
+
// Dirty working tree — the merge was rejected before it started (e.g.
|
|
234
|
+
// untracked .gsd/ files left by syncStateToProjectRoot). Preserve the
|
|
235
|
+
// milestone branch so commits are not lost.
|
|
236
|
+
if (mergeResult.conflicts.includes("__dirty_working_tree__")) {
|
|
237
|
+
// Defensively clean merge state — the native path may leave MERGE_HEAD
|
|
238
|
+
// even when the merge is rejected (#2912).
|
|
239
|
+
removeMergeStateFiles(originalBasePath_, "dirty-tree rejection");
|
|
240
|
+
|
|
241
|
+
// Pop stash before throwing so local work is not lost.
|
|
242
|
+
preMergeStash.restoreForMergeFailure();
|
|
243
|
+
milestoneDirectoryShelter.restore();
|
|
244
|
+
// Restore cwd so the caller is not stranded on the integration branch
|
|
245
|
+
process.chdir(previousCwd);
|
|
246
|
+
// Surface the actual dirty filenames from git stderr instead of
|
|
247
|
+
// generically blaming .gsd/ (#2151).
|
|
248
|
+
const fileList = mergeResult.dirtyFiles?.length
|
|
249
|
+
? `Dirty files:\n${mergeResult.dirtyFiles.map((f) => ` ${f}`).join("\n")}`
|
|
250
|
+
: `Check \`git status\` in the project root for details.`;
|
|
251
|
+
throw new GSDError(
|
|
252
|
+
GSD_GIT_ERROR,
|
|
253
|
+
`${effectiveStrategy === "merge" ? "Merge" : "Squash merge"} of ${milestoneBranch} rejected: working tree has dirty or untracked files ` +
|
|
254
|
+
`that conflict with the merge. ${fileList}`,
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Check for conflicts — use merge result first, fall back to nativeConflictFiles
|
|
259
|
+
const conflictedFiles =
|
|
260
|
+
mergeResult.conflicts.length > 0
|
|
261
|
+
? mergeResult.conflicts
|
|
262
|
+
: nativeConflictFiles(originalBasePath_);
|
|
263
|
+
|
|
264
|
+
if (conflictedFiles.length > 0) {
|
|
265
|
+
// Separate auto-resolvable conflicts (GSD state files + build artifacts)
|
|
266
|
+
// from real code conflicts. GSD state files diverge between branches
|
|
267
|
+
// during normal operation. Build artifacts are machine-generated and
|
|
268
|
+
// regenerable. Both are safe to accept from the milestone branch.
|
|
269
|
+
const { resolved: autoResolved, remaining: codeConflicts } = autoResolveSafeConflictPaths(
|
|
270
|
+
originalBasePath_,
|
|
271
|
+
conflictedFiles,
|
|
272
|
+
);
|
|
273
|
+
if (autoResolved.length > 0) {
|
|
274
|
+
logWarning("worktree", `auto-resolved safe merge conflicts: ${autoResolved.join(", ")}`);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// If there are still real code conflicts, escalate
|
|
278
|
+
if (codeConflicts.length > 0) {
|
|
279
|
+
cleanupConflictState(originalBasePath_);
|
|
280
|
+
|
|
281
|
+
// Pop stash before throwing so local work is not lost (#2151).
|
|
282
|
+
preMergeStash.restoreForMergeFailure();
|
|
283
|
+
milestoneDirectoryShelter.restore();
|
|
284
|
+
// Restore cwd so the caller is not stranded on the integration branch.
|
|
285
|
+
// Without this, the next mergeMilestoneToMain call in a parallel merge
|
|
286
|
+
// sequence uses process.cwd() (now the project root) as worktreeCwd,
|
|
287
|
+
// causing autoCommitDirtyState to commit unrelated milestone files to
|
|
288
|
+
// the integration branch (#2929).
|
|
289
|
+
process.chdir(previousCwd);
|
|
290
|
+
throw new MergeConflictError(
|
|
291
|
+
codeConflicts,
|
|
292
|
+
effectiveStrategy,
|
|
293
|
+
milestoneBranch,
|
|
294
|
+
mainBranch,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// No conflicts detected — possibly "already up to date", fall through to commit
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// 9. Commit (handle nothing-to-commit gracefully)
|
|
302
|
+
const commitResult = nativeCommit(originalBasePath_, commitMessage);
|
|
303
|
+
const nothingToCommit = commitResult === null;
|
|
304
|
+
|
|
305
|
+
// 9a. Clean up merge state files left by git merge --squash (#1853, #2912).
|
|
306
|
+
// git only removes SQUASH_MSG when the commit reads it directly (plain
|
|
307
|
+
// `git commit`). nativeCommit uses `-F -` (stdin) or libgit2, neither
|
|
308
|
+
// of which trigger git's SQUASH_MSG cleanup. MERGE_HEAD is created by
|
|
309
|
+
// libgit2's merge even in squash mode and is not removed by nativeCommit.
|
|
310
|
+
// If left on disk, doctor reports `corrupt_merge_state` on every subsequent run.
|
|
311
|
+
removeMergeStateFiles(originalBasePath_, "post-commit");
|
|
312
|
+
|
|
313
|
+
// 9a-ii. Restore stashed files now that the merge+commit is complete (#2151).
|
|
314
|
+
preMergeStash.restoreAfterCommit();
|
|
315
|
+
|
|
316
|
+
// 9a-iii. Restore sheltered queued milestone directories (#2505).
|
|
317
|
+
milestoneDirectoryShelter.restore();
|
|
318
|
+
|
|
319
|
+
// 9b. Safety check (#1792): if nothing was committed, verify the milestone
|
|
320
|
+
// work is already on the integration branch before allowing teardown.
|
|
321
|
+
try {
|
|
322
|
+
assertNoUnanchoredCodeChangesAfterEmptyMerge(
|
|
323
|
+
originalBasePath_,
|
|
324
|
+
mainBranch,
|
|
325
|
+
milestoneBranch,
|
|
326
|
+
effectiveStrategy,
|
|
327
|
+
nothingToCommit,
|
|
328
|
+
);
|
|
329
|
+
} catch (err) {
|
|
330
|
+
process.chdir(previousCwd);
|
|
331
|
+
throw err;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// 9c. Detect whether any non-.gsd/ code files were actually merged (#1906).
|
|
335
|
+
const codeFilesChanged = detectMergedCodeFilesChanged(originalBasePath_, nothingToCommit);
|
|
336
|
+
|
|
337
|
+
const finalizeMilestoneCleanup = (): void => {
|
|
338
|
+
cleanupMergedMilestoneWorktree({
|
|
339
|
+
projectRoot: originalBasePath_,
|
|
340
|
+
milestoneId,
|
|
341
|
+
milestoneBranch,
|
|
342
|
+
previousCwd,
|
|
343
|
+
chdirWarningContext: "after merge",
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
let shouldCleanup = false;
|
|
348
|
+
try {
|
|
349
|
+
// 10/9b. Publication (auto-push / draft PR) — Publication module seam (ADR-034).
|
|
350
|
+
const publication = publishMilestone({
|
|
351
|
+
basePath: originalBasePath_,
|
|
352
|
+
milestoneId,
|
|
353
|
+
milestoneTitle,
|
|
354
|
+
integrationBranch: mainBranch,
|
|
355
|
+
milestoneBranch,
|
|
356
|
+
sliceSummaries,
|
|
357
|
+
nothingToCommit,
|
|
358
|
+
prefs: {
|
|
359
|
+
autoPush: prefs.auto_push === true,
|
|
360
|
+
autoPr: prefs.auto_pr === true,
|
|
361
|
+
remote: prefs.remote,
|
|
362
|
+
prTargetBranch: prefs.pr_target_branch,
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
const { pushed, prCreated } = publication;
|
|
366
|
+
|
|
367
|
+
// 11. Guard removed — step 9b (#1792) now handles this with a smarter check:
|
|
368
|
+
// throws only when the milestone has unanchored code changes, passes
|
|
369
|
+
// through when the code is genuinely already on the integration branch.
|
|
370
|
+
|
|
371
|
+
// 11a. Pre-teardown safety net (#1853): preserve the milestone branch if
|
|
372
|
+
// the source worktree still has uncommitted changes after the merge commit.
|
|
373
|
+
assertMilestoneWorktreeCleanBeforeTeardown({
|
|
374
|
+
milestoneBranch,
|
|
375
|
+
previousCwd,
|
|
376
|
+
worktreeCwd,
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
shouldCleanup = true;
|
|
380
|
+
return { commitMessage, pushed, prCreated, codeFilesChanged };
|
|
381
|
+
} finally {
|
|
382
|
+
if (shouldCleanup) {
|
|
383
|
+
finalizeMilestoneCleanup();
|
|
384
|
+
} else {
|
|
385
|
+
logWarning(
|
|
386
|
+
"worktree",
|
|
387
|
+
`Skipping worktree cleanup for ${milestoneBranch}; merge did not reach safe-cleanup point and milestone work is preserved for manual recovery.`,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|