@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
|
@@ -4,21 +4,67 @@
|
|
|
4
4
|
import { cpSync, existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { renderAllFromDb, renderRoadmapFromDb } from "./markdown-renderer.js";
|
|
7
|
-
import { getAllMilestones, getMilestoneSlices } from "./gsd-db.js";
|
|
7
|
+
import { deleteArtifactsByPathPrefix, getAllMilestones, getMilestoneSlices } from "./gsd-db.js";
|
|
8
8
|
import { migrateFromMarkdown } from "./md-importer.js";
|
|
9
9
|
import { countDbHierarchy } from "./migration-auto-check.js";
|
|
10
10
|
import { logWarning } from "./workflow-logger.js";
|
|
11
11
|
import { LAYOUT_SEGMENTS } from "./layout-policy.js";
|
|
12
|
-
import { canonicalPhaseDirName, milestonesDir, resolveMilestonePath } from "./paths.js";
|
|
12
|
+
import { canonicalPhaseDirName, dirIsContentBearingLegacyMilestone, milestonesDir, resolveMilestonePath, } from "./paths.js";
|
|
13
13
|
const LEGACY_MIGRATING_SEGMENT = "milestones.migrating";
|
|
14
|
+
const RETRYABLE_FS_ERROR_CODES = new Set(["EPERM", "EBUSY", "ENOTEMPTY"]);
|
|
15
|
+
const RM_RETRY_OPTIONS = { recursive: true, force: true, maxRetries: 5, retryDelay: 100 };
|
|
16
|
+
let fsOps = { cpSync, renameSync, rmSync };
|
|
17
|
+
export function _setFlatPhaseMigrationFsOpsForTest(overrides) {
|
|
18
|
+
const previous = fsOps;
|
|
19
|
+
fsOps = { ...fsOps, ...overrides };
|
|
20
|
+
return () => {
|
|
21
|
+
fsOps = previous;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
14
24
|
function legacyMigratingPath(basePath) {
|
|
15
25
|
return join(basePath, ".gsd", LEGACY_MIGRATING_SEGMENT);
|
|
16
26
|
}
|
|
27
|
+
function removePathWithRetries(path) {
|
|
28
|
+
fsOps.rmSync(path, { recursive: true, force: true, maxRetries: RM_RETRY_OPTIONS.maxRetries, retryDelay: RM_RETRY_OPTIONS.retryDelay });
|
|
29
|
+
}
|
|
30
|
+
function isRetryableFsError(err) {
|
|
31
|
+
const code = err?.code;
|
|
32
|
+
return typeof code === "string" && RETRYABLE_FS_ERROR_CODES.has(code);
|
|
33
|
+
}
|
|
34
|
+
function movePathWithCopyDeleteFallback(src, dst) {
|
|
35
|
+
try {
|
|
36
|
+
fsOps.renameSync(src, dst);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if (!isRetryableFsError(err))
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
fsOps.cpSync(src, dst, { recursive: true, force: true });
|
|
45
|
+
removePathWithRetries(src);
|
|
46
|
+
}
|
|
47
|
+
catch (fallbackErr) {
|
|
48
|
+
if (existsSync(src) && existsSync(dst)) {
|
|
49
|
+
try {
|
|
50
|
+
removePathWithRetries(dst);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Leave the original error intact; the next run can pre-clean dst.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
throw fallbackErr;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function expectedPhaseDirs(basePath) {
|
|
60
|
+
return getAllMilestones().map((milestone) => resolveMilestonePath(basePath, milestone.id) ??
|
|
61
|
+
join(milestonesDir(basePath), canonicalPhaseDirName(milestone.id, milestone.title)));
|
|
62
|
+
}
|
|
17
63
|
function hasLegacyMilestoneSubdirs(dirPath) {
|
|
18
64
|
if (!existsSync(dirPath))
|
|
19
65
|
return false;
|
|
20
66
|
try {
|
|
21
|
-
return readdirSync(dirPath).some(e => statSync(join(dirPath, e)).isDirectory());
|
|
67
|
+
return readdirSync(dirPath).some((e) => statSync(join(dirPath, e)).isDirectory() && dirIsContentBearingLegacyMilestone(join(dirPath, e)));
|
|
22
68
|
}
|
|
23
69
|
catch {
|
|
24
70
|
return false;
|
|
@@ -26,19 +72,42 @@ function hasLegacyMilestoneSubdirs(dirPath) {
|
|
|
26
72
|
}
|
|
27
73
|
function rollbackPartialMigration(basePath, backupDir, migratingPath) {
|
|
28
74
|
// Remove the partially-written phases/ dir.
|
|
29
|
-
|
|
75
|
+
try {
|
|
76
|
+
removePathWithRetries(join(basePath, ".gsd", LAYOUT_SEGMENTS.level1));
|
|
77
|
+
}
|
|
78
|
+
catch (removeErr) {
|
|
79
|
+
logWarning("migration", `rollback: could not remove partial ${LAYOUT_SEGMENTS.level1}/: ${removeErr.message}`);
|
|
80
|
+
}
|
|
81
|
+
// Only the standalone .gsd-backups/migrate-<ts>/ copy is disposable once the
|
|
82
|
+
// restore succeeds. When resuming an interrupted migration, backupDir IS the
|
|
83
|
+
// preserved migrating tree (the sole surviving data source) and must never be
|
|
84
|
+
// removed here. Deleting the backup after a successful rollback keeps the gate
|
|
85
|
+
// from leaking one .gsd-backups/migrate-<ts>/ per session_start.
|
|
86
|
+
const isDisposableBackup = Boolean(backupDir) && backupDir !== migratingPath;
|
|
87
|
+
const cleanupBackup = () => {
|
|
88
|
+
if (!isDisposableBackup || !existsSync(backupDir))
|
|
89
|
+
return;
|
|
90
|
+
try {
|
|
91
|
+
removePathWithRetries(backupDir);
|
|
92
|
+
}
|
|
93
|
+
catch (cleanupErr) {
|
|
94
|
+
logWarning("migration", `rollback: could not clean backup ${backupDir}: ${cleanupErr.message}`);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
30
97
|
// Restore milestones/ — prefer renaming the preserved migrating copy back.
|
|
31
98
|
const milestonesPath = join(basePath, ".gsd", "milestones");
|
|
32
99
|
try {
|
|
33
100
|
if (migratingPath && existsSync(migratingPath) && !existsSync(milestonesPath)) {
|
|
34
|
-
|
|
101
|
+
movePathWithCopyDeleteFallback(migratingPath, milestonesPath);
|
|
102
|
+
cleanupBackup();
|
|
35
103
|
return;
|
|
36
104
|
}
|
|
37
105
|
if (existsSync(backupDir)) {
|
|
38
106
|
cpSync(backupDir, milestonesPath, { recursive: true });
|
|
107
|
+
cleanupBackup();
|
|
39
108
|
}
|
|
40
109
|
if (migratingPath && existsSync(migratingPath)) {
|
|
41
|
-
|
|
110
|
+
removePathWithRetries(migratingPath);
|
|
42
111
|
}
|
|
43
112
|
}
|
|
44
113
|
catch (restoreErr) {
|
|
@@ -112,7 +181,8 @@ export function pruneStaleFlatPhaseBackups(basePath) {
|
|
|
112
181
|
* 2. Rename .gsd/milestones/ aside so path resolvers target phases/
|
|
113
182
|
* 3. Render flat-phase from the DB (which already has the data)
|
|
114
183
|
* 4. Verify counts match
|
|
115
|
-
* 5.
|
|
184
|
+
* 5. Prune legacy milestones/ artifact rows
|
|
185
|
+
* 6. Remove the renamed legacy tree
|
|
116
186
|
*
|
|
117
187
|
* Idempotent: if .gsd/milestones/ doesn't exist, returns immediately.
|
|
118
188
|
*/
|
|
@@ -146,20 +216,29 @@ export async function migrateToFlatPhase(basePath) {
|
|
|
146
216
|
logWarning("migration", `flat-phase migration backup failed: ${err.message}`);
|
|
147
217
|
throw err;
|
|
148
218
|
}
|
|
219
|
+
if (existsSync(migratingPath)) {
|
|
220
|
+
removePathWithRetries(migratingPath);
|
|
221
|
+
}
|
|
149
222
|
// 3. Rename legacy tree aside before rendering so path resolvers target
|
|
150
223
|
// phases/ instead of writing back into the nested milestones/ layout.
|
|
151
224
|
// Keep the full tree on disk until render+verify succeed (unlike rmSync).
|
|
152
225
|
try {
|
|
153
|
-
|
|
226
|
+
movePathWithCopyDeleteFallback(milestonesPath, migratingPath);
|
|
154
227
|
}
|
|
155
228
|
catch (err) {
|
|
156
229
|
logWarning("migration", `failed to rename legacy milestones/ before render: ${err.message}`);
|
|
157
230
|
throw err;
|
|
158
231
|
}
|
|
159
232
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
233
|
+
// Clear any stale or partially-rendered flat projection before this run
|
|
234
|
+
// writes. Verification below checks the current DB render, not leftovers.
|
|
235
|
+
try {
|
|
236
|
+
removePathWithRetries(phasesPath);
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
logWarning("migration", `failed to clear stale phases/ before render: ${err.message}`);
|
|
240
|
+
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
241
|
+
throw err;
|
|
163
242
|
}
|
|
164
243
|
// 4. Render flat-phase from DB
|
|
165
244
|
let renderResult;
|
|
@@ -191,29 +270,30 @@ export async function migrateToFlatPhase(basePath) {
|
|
|
191
270
|
throw new Error(`flat-phase migration render failed: ${renderResult.errors.slice(0, 3).join("; ")}`);
|
|
192
271
|
}
|
|
193
272
|
const db = countDbHierarchy();
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
// whose dirs start with "100-slug" are counted correctly.
|
|
198
|
-
renderedDirCount = readdirSync(phasesPath, { withFileTypes: true })
|
|
199
|
-
.filter((entry) => entry.isDirectory() && /^\d+-/.test(entry.name)).length;
|
|
200
|
-
}
|
|
201
|
-
catch {
|
|
202
|
-
// phases/ doesn't exist or is unreadable — same as zero dirs
|
|
203
|
-
}
|
|
204
|
-
if (db.milestones > 0 && renderedDirCount !== db.milestones) {
|
|
205
|
-
logWarning("migration", `phases/ dir count mismatch: expected ${db.milestones}, found ${renderedDirCount}`);
|
|
273
|
+
const missingPhaseDirs = expectedPhaseDirs(basePath).filter((phaseDir) => !existsSync(phaseDir));
|
|
274
|
+
if (db.milestones > 0 && missingPhaseDirs.length > 0) {
|
|
275
|
+
logWarning("migration", `flat-phase migration missing ${missingPhaseDirs.length} expected phase dir(s): ${missingPhaseDirs.join(", ")}`);
|
|
206
276
|
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
207
|
-
throw new Error("flat-phase migration verification failed:
|
|
277
|
+
throw new Error("flat-phase migration verification failed: missing rendered phase directories");
|
|
208
278
|
}
|
|
209
279
|
if (db.slices > 0 && renderResult.rendered === 0) {
|
|
210
280
|
logWarning("migration", "flat-phase migration verification failed: render produced no artifacts for populated DB");
|
|
211
281
|
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
212
282
|
throw new Error("flat-phase migration verification failed: no artifacts rendered");
|
|
213
283
|
}
|
|
214
|
-
// 6. Verified —
|
|
284
|
+
// 6. Verified — prune legacy artifact rows now that renderAllFromDb has
|
|
285
|
+
// re-inserted flat-phase rows for artifacts that still have files.
|
|
286
|
+
try {
|
|
287
|
+
deleteArtifactsByPathPrefix("milestones/");
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
logWarning("migration", `flat-phase migration could not prune legacy artifact rows: ${err.message}`);
|
|
291
|
+
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
292
|
+
throw err;
|
|
293
|
+
}
|
|
294
|
+
// 7. Remove the renamed legacy tree (backup already on disk).
|
|
215
295
|
try {
|
|
216
|
-
|
|
296
|
+
removePathWithRetries(migratingPath);
|
|
217
297
|
}
|
|
218
298
|
catch (err) {
|
|
219
299
|
logWarning("migration", `flat-phase migration succeeded but could not remove ${LEGACY_MIGRATING_SEGMENT}: ${err.message}`);
|
|
@@ -24,7 +24,7 @@ import { loadPrompt } from "./prompt-loader.js";
|
|
|
24
24
|
import { gsdRoot } from "./paths.js";
|
|
25
25
|
import { isDbAvailable, getHierarchyCompletionCounts } from "./gsd-db.js";
|
|
26
26
|
import { formatDuration } from "../shared/format-utils.js";
|
|
27
|
-
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
27
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
28
28
|
import { clearGSDPreferencesCache, loadEffectiveGSDPreferences, loadGlobalGSDPreferences, getGlobalGSDPreferencesPath } from "./preferences.js";
|
|
29
29
|
import { showNextAction } from "../shared/tui.js";
|
|
30
30
|
import { isInteractiveCommandContext, notifyForensicsNeedsInteractiveMenu, } from "./command-feedback.js";
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// File Purpose: Shared auto-resolution of safe merge conflict paths.
|
|
3
3
|
import { logWarning } from "./workflow-logger.js";
|
|
4
4
|
import { nativeAddPaths, nativeCheckoutTheirs, nativeRmForce, } from "./native-git-bridge.js";
|
|
5
|
-
import { isSafeToAutoResolve } from "./auto-worktree.js";
|
|
6
|
-
export { isSafeToAutoResolve } from "./auto-worktree.js";
|
|
5
|
+
import { isSafeToAutoResolve } from "./auto-worktree-conflict-auto-resolve.js";
|
|
6
|
+
export { isSafeToAutoResolve } from "./auto-worktree-conflict-auto-resolve.js";
|
|
7
7
|
/**
|
|
8
8
|
* Auto-resolve paths that are safe to accept from the milestone side
|
|
9
9
|
* (.gsd/ state and build artifacts).
|
|
@@ -16,7 +16,7 @@ import { gsdRoot } from "./paths.js";
|
|
|
16
16
|
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
17
17
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
18
18
|
import { logWarning } from "./workflow-logger.js";
|
|
19
|
-
import { createRepositoryRegistryFromPreferences } from "./repository-registry.js";
|
|
19
|
+
import { createRepositoryRegistryFromPreferences, defaultRepositoryTargets } from "./repository-registry.js";
|
|
20
20
|
import { isGsdGitignored } from "./gitignore.js";
|
|
21
21
|
import { detectWorktreeName, } from "./worktree.js";
|
|
22
22
|
import { SLICE_BRANCH_RE, QUICK_BRANCH_RE, WORKFLOW_BRANCH_RE } from "./branch-patterns.js";
|
|
@@ -519,6 +519,51 @@ export function runGit(basePath, args, options = {}) {
|
|
|
519
519
|
throw new GSDError(GSD_GIT_ERROR, `git ${args.join(" ")} failed in ${basePath}: ${filterGitSvnNoise(message)}`);
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* Arguments for creating a task/workflow branch.
|
|
524
|
+
*
|
|
525
|
+
* When the current branch is a leftover GSD task branch (workflow template,
|
|
526
|
+
* quick task, or slice), the new branch starts from `baseBranch` — the
|
|
527
|
+
* caller's resolved integration branch, normally `GitServiceImpl.getMainBranch()`
|
|
528
|
+
* so `main_branch` preference, milestone integration branch, and worktree base
|
|
529
|
+
* all take priority over repo-default detection. Branching from HEAD there
|
|
530
|
+
* silently stacks consecutive workflow branches on top of each other, so every
|
|
531
|
+
* new gsd/* branch (and its eventual PR) drags along the previous workflow's
|
|
532
|
+
* commits.
|
|
533
|
+
*
|
|
534
|
+
* On any other branch (a user's feature branch, a worktree base, the main
|
|
535
|
+
* branch itself) the legacy branch-from-HEAD behavior is kept: basing new work
|
|
536
|
+
* on the branch the user chose to stand on is intentional there.
|
|
537
|
+
*
|
|
538
|
+
* Falls back to branch-from-HEAD, with a logged warning, when the base branch
|
|
539
|
+
* has no local ref or the working tree is still dirty (a start point that
|
|
540
|
+
* changes the tree would abort the checkout or strand in-flight changes).
|
|
541
|
+
* The base is the local ref — deliberately no fetch, so branch creation stays
|
|
542
|
+
* offline-safe even if the local base is behind its remote.
|
|
543
|
+
*/
|
|
544
|
+
export function taskBranchArgs(basePath, branchName, currentBranch, baseBranch) {
|
|
545
|
+
const args = ["checkout", "-b", branchName];
|
|
546
|
+
const onTaskBranch = WORKFLOW_BRANCH_RE.test(currentBranch) ||
|
|
547
|
+
QUICK_BRANCH_RE.test(currentBranch) ||
|
|
548
|
+
SLICE_BRANCH_RE.test(currentBranch);
|
|
549
|
+
if (!onTaskBranch || !baseBranch || baseBranch === currentBranch)
|
|
550
|
+
return args;
|
|
551
|
+
try {
|
|
552
|
+
if (!nativeBranchExists(basePath, baseBranch)) {
|
|
553
|
+
logWarning("engine", `taskBranchArgs: base branch "${baseBranch}" has no local ref — branching ${branchName} from HEAD (${currentBranch})`, { file: "git-service.ts" });
|
|
554
|
+
return args;
|
|
555
|
+
}
|
|
556
|
+
if (nativeHasChanges(basePath)) {
|
|
557
|
+
logWarning("engine", `taskBranchArgs: working tree still dirty after auto-commit — branching ${branchName} from HEAD (${currentBranch}) to preserve in-flight changes`, { file: "git-service.ts" });
|
|
558
|
+
return args;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
catch {
|
|
562
|
+
return args;
|
|
563
|
+
}
|
|
564
|
+
args.push(baseBranch);
|
|
565
|
+
return args;
|
|
566
|
+
}
|
|
522
567
|
// ─── Commit Type Inference ─────────────────────────────────────────────────
|
|
523
568
|
/**
|
|
524
569
|
* Keyword-to-commit-type mapping. Order matters — first match wins.
|
|
@@ -1024,28 +1069,25 @@ export function handleTurnGitActionError(action, err) {
|
|
|
1024
1069
|
error: errorWithStreams.stderr?.trim() || errorWithStreams.message || getErrorMessage(err),
|
|
1025
1070
|
};
|
|
1026
1071
|
}
|
|
1072
|
+
export function isRepositoryDirty(repoRoot) {
|
|
1073
|
+
try {
|
|
1074
|
+
return runGit(repoRoot, ["status", "--porcelain"]).length > 0;
|
|
1075
|
+
}
|
|
1076
|
+
catch {
|
|
1077
|
+
// Fallback preserves legacy behavior if explicit status probing fails.
|
|
1078
|
+
return nativeHasChanges(repoRoot);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1027
1081
|
function collectRepositoryDirtyStatus(basePath) {
|
|
1028
1082
|
const preferences = loadEffectiveGSDPreferences(basePath)?.preferences;
|
|
1029
1083
|
const registry = createRepositoryRegistryFromPreferences(basePath, preferences);
|
|
1030
1084
|
const dirtyByRepository = {};
|
|
1031
1085
|
const registeredRoots = new Set(registry.repositories.map((repo) => resolve(repo.root)));
|
|
1032
1086
|
for (const repo of registry.repositories) {
|
|
1033
|
-
|
|
1034
|
-
dirtyByRepository[repo.id] = runGit(repo.root, ["status", "--porcelain"]).length > 0;
|
|
1035
|
-
}
|
|
1036
|
-
catch {
|
|
1037
|
-
// Fallback preserves legacy behavior if explicit status probing fails.
|
|
1038
|
-
dirtyByRepository[repo.id] = nativeHasChanges(repo.root);
|
|
1039
|
-
}
|
|
1087
|
+
dirtyByRepository[repo.id] = isRepositoryDirty(repo.root);
|
|
1040
1088
|
}
|
|
1041
1089
|
for (const repoRoot of findUndeclaredNestedGitRepositories(registry.projectRoot, registeredRoots)) {
|
|
1042
|
-
|
|
1043
|
-
try {
|
|
1044
|
-
dirty = runGit(repoRoot, ["status", "--porcelain"]).length > 0;
|
|
1045
|
-
}
|
|
1046
|
-
catch {
|
|
1047
|
-
dirty = nativeHasChanges(repoRoot);
|
|
1048
|
-
}
|
|
1090
|
+
const dirty = isRepositoryDirty(repoRoot);
|
|
1049
1091
|
if (!dirty)
|
|
1050
1092
|
continue;
|
|
1051
1093
|
const relPath = relative(registry.projectRoot, repoRoot).split(sep).join("/") || repoRoot;
|
|
@@ -1098,7 +1140,7 @@ function findUndeclaredNestedGitRepositories(projectRoot, registeredRoots) {
|
|
|
1098
1140
|
function runPerRepositoryCommitAction(args) {
|
|
1099
1141
|
const preferences = loadEffectiveGSDPreferences(args.basePath)?.preferences;
|
|
1100
1142
|
const registry = createRepositoryRegistryFromPreferences(args.basePath, preferences);
|
|
1101
|
-
const repoIds = args.targetRepositories?.length ? args.targetRepositories :
|
|
1143
|
+
const repoIds = args.targetRepositories?.length ? args.targetRepositories : defaultRepositoryTargets(registry);
|
|
1102
1144
|
const gitPrefs = preferences?.git ?? {};
|
|
1103
1145
|
const commitMessages = {};
|
|
1104
1146
|
const commitErrors = {};
|
|
@@ -1166,8 +1208,7 @@ export function runTurnGitAction(args) {
|
|
|
1166
1208
|
skippedRepositories: repoCommitResult.skippedRepositories,
|
|
1167
1209
|
};
|
|
1168
1210
|
}
|
|
1169
|
-
const primaryMessage = repoCommitResult.commitMessages[
|
|
1170
|
-
?? Object.values(repoCommitResult.commitMessages)[0];
|
|
1211
|
+
const primaryMessage = Object.values(repoCommitResult.commitMessages)[0];
|
|
1171
1212
|
return {
|
|
1172
1213
|
action: args.action,
|
|
1173
1214
|
status: "ok",
|
|
@@ -352,17 +352,17 @@ export function insertTask(t) {
|
|
|
352
352
|
ON CONFLICT(milestone_id, slice_id, id) DO UPDATE SET
|
|
353
353
|
title = CASE WHEN NULLIF(:title, '') IS NOT NULL THEN :title ELSE tasks.title END,
|
|
354
354
|
status = :status,
|
|
355
|
-
one_liner = :one_liner,
|
|
356
|
-
narrative = :narrative,
|
|
357
|
-
verification_result = :verification_result,
|
|
358
|
-
duration = :duration,
|
|
359
|
-
completed_at = :completed_at,
|
|
360
|
-
blocker_discovered = :blocker_discovered,
|
|
361
|
-
deviations = :deviations,
|
|
362
|
-
known_issues = :known_issues,
|
|
363
|
-
key_files = :key_files,
|
|
364
|
-
key_decisions = :key_decisions,
|
|
365
|
-
full_summary_md = :full_summary_md,
|
|
355
|
+
one_liner = CASE WHEN :preserve_completion = 1 AND NULLIF(:one_liner, '') IS NULL THEN tasks.one_liner ELSE :one_liner END,
|
|
356
|
+
narrative = CASE WHEN :preserve_completion = 1 AND NULLIF(:narrative, '') IS NULL THEN tasks.narrative ELSE :narrative END,
|
|
357
|
+
verification_result = CASE WHEN :preserve_completion = 1 AND NULLIF(:verification_result, '') IS NULL THEN tasks.verification_result ELSE :verification_result END,
|
|
358
|
+
duration = CASE WHEN :preserve_completion = 1 AND NULLIF(:duration, '') IS NULL THEN tasks.duration ELSE :duration END,
|
|
359
|
+
completed_at = CASE WHEN :preserve_completion = 1 AND tasks.completed_at IS NOT NULL THEN tasks.completed_at ELSE :completed_at END,
|
|
360
|
+
blocker_discovered = CASE WHEN :preserve_completion = 1 AND :blocker_discovered = 0 THEN tasks.blocker_discovered ELSE :blocker_discovered END,
|
|
361
|
+
deviations = CASE WHEN :preserve_completion = 1 AND NULLIF(:deviations, '') IS NULL THEN tasks.deviations ELSE :deviations END,
|
|
362
|
+
known_issues = CASE WHEN :preserve_completion = 1 AND NULLIF(:known_issues, '') IS NULL THEN tasks.known_issues ELSE :known_issues END,
|
|
363
|
+
key_files = CASE WHEN :preserve_completion = 1 AND NULLIF(:key_files, '[]') IS NULL THEN tasks.key_files ELSE :key_files END,
|
|
364
|
+
key_decisions = CASE WHEN :preserve_completion = 1 AND NULLIF(:key_decisions, '[]') IS NULL THEN tasks.key_decisions ELSE :key_decisions END,
|
|
365
|
+
full_summary_md = CASE WHEN :preserve_completion = 1 AND NULLIF(:full_summary_md, '') IS NULL THEN tasks.full_summary_md ELSE :full_summary_md END,
|
|
366
366
|
description = CASE WHEN NULLIF(:description, '') IS NOT NULL THEN :description ELSE tasks.description END,
|
|
367
367
|
estimate = CASE WHEN NULLIF(:estimate, '') IS NOT NULL THEN :estimate ELSE tasks.estimate END,
|
|
368
368
|
files = CASE WHEN NULLIF(:files, '[]') IS NOT NULL THEN :files ELSE tasks.files END,
|
|
@@ -401,6 +401,7 @@ export function insertTask(t) {
|
|
|
401
401
|
":observability_impact": t.planning?.observabilityImpact ?? "",
|
|
402
402
|
":full_plan_md": t.planning?.fullPlanMd ?? "",
|
|
403
403
|
":sequence": t.sequence ?? 0,
|
|
404
|
+
":preserve_completion": t.preserveCompletionMetadata && (t.status === "complete" || t.status === "done") ? 1 : 0,
|
|
404
405
|
":target_repositories": JSON.stringify(t.planning?.targetRepositories ?? []),
|
|
405
406
|
":raw_target_repositories": t.planning && "targetRepositories" in t.planning
|
|
406
407
|
? JSON.stringify(t.planning.targetRepositories ?? [])
|
|
@@ -410,6 +411,58 @@ export function insertTask(t) {
|
|
|
410
411
|
export function updateTaskStatus(milestoneId, sliceId, taskId, status, completedAt) {
|
|
411
412
|
applyStatusTransition({ entity: "task", milestoneId, sliceId, taskId, status, completedAt });
|
|
412
413
|
}
|
|
414
|
+
export function repairTaskCompletionFromSummary(t) {
|
|
415
|
+
const db = getDbOrNull();
|
|
416
|
+
if (!db)
|
|
417
|
+
throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
418
|
+
transaction(() => {
|
|
419
|
+
const seq = db.prepare(`SELECT COALESCE(MAX(sequence), 0) + 1 AS next_sequence
|
|
420
|
+
FROM tasks
|
|
421
|
+
WHERE milestone_id = :mid AND slice_id = :sid`).get({ ":mid": t.milestoneId, ":sid": t.sliceId });
|
|
422
|
+
db.prepare(`INSERT INTO tasks (
|
|
423
|
+
milestone_id, slice_id, id, title, status, one_liner, narrative,
|
|
424
|
+
verification_result, duration, completed_at, blocker_discovered,
|
|
425
|
+
deviations, known_issues, key_files, key_decisions, full_summary_md,
|
|
426
|
+
sequence
|
|
427
|
+
) VALUES (
|
|
428
|
+
:milestone_id, :slice_id, :id, :title, 'complete', :one_liner, :narrative,
|
|
429
|
+
:verification_result, :duration, :completed_at, :blocker_discovered,
|
|
430
|
+
:deviations, :known_issues, :key_files, :key_decisions, :full_summary_md,
|
|
431
|
+
:sequence
|
|
432
|
+
)
|
|
433
|
+
ON CONFLICT(milestone_id, slice_id, id) DO UPDATE SET
|
|
434
|
+
title = CASE WHEN NULLIF(:title, '') IS NOT NULL THEN :title ELSE tasks.title END,
|
|
435
|
+
status = 'complete',
|
|
436
|
+
one_liner = CASE WHEN NULLIF(:one_liner, '') IS NOT NULL THEN :one_liner ELSE tasks.one_liner END,
|
|
437
|
+
narrative = CASE WHEN NULLIF(:narrative, '') IS NOT NULL THEN :narrative ELSE tasks.narrative END,
|
|
438
|
+
verification_result = :verification_result,
|
|
439
|
+
duration = CASE WHEN NULLIF(:duration, '') IS NOT NULL THEN :duration ELSE tasks.duration END,
|
|
440
|
+
completed_at = :completed_at,
|
|
441
|
+
blocker_discovered = :blocker_discovered,
|
|
442
|
+
deviations = CASE WHEN NULLIF(:deviations, '') IS NOT NULL THEN :deviations ELSE tasks.deviations END,
|
|
443
|
+
known_issues = CASE WHEN NULLIF(:known_issues, '') IS NOT NULL THEN :known_issues ELSE tasks.known_issues END,
|
|
444
|
+
key_files = :key_files,
|
|
445
|
+
key_decisions = :key_decisions,
|
|
446
|
+
full_summary_md = :full_summary_md`).run({
|
|
447
|
+
":milestone_id": t.milestoneId,
|
|
448
|
+
":slice_id": t.sliceId,
|
|
449
|
+
":id": t.taskId,
|
|
450
|
+
":title": t.title ?? "",
|
|
451
|
+
":one_liner": t.oneLiner ?? "",
|
|
452
|
+
":narrative": t.narrative ?? "",
|
|
453
|
+
":verification_result": t.verificationResult,
|
|
454
|
+
":duration": t.duration ?? "",
|
|
455
|
+
":completed_at": t.completedAt,
|
|
456
|
+
":blocker_discovered": t.blockerDiscovered ? 1 : 0,
|
|
457
|
+
":deviations": t.deviations ?? "",
|
|
458
|
+
":known_issues": t.knownIssues ?? "",
|
|
459
|
+
":key_files": JSON.stringify(t.keyFiles ?? []),
|
|
460
|
+
":key_decisions": JSON.stringify(t.keyDecisions ?? []),
|
|
461
|
+
":full_summary_md": t.fullSummaryMd,
|
|
462
|
+
":sequence": seq?.next_sequence ?? 1,
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
}
|
|
413
466
|
export function setTaskBlockerDiscovered(milestoneId, sliceId, taskId, discovered) {
|
|
414
467
|
if (!getDbOrNull())
|
|
415
468
|
return;
|
|
@@ -948,6 +1001,17 @@ export function deleteArtifactByPath(path) {
|
|
|
948
1001
|
throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
949
1002
|
getDbOrNull().prepare("DELETE FROM artifacts WHERE path = :path").run({ ":path": path });
|
|
950
1003
|
}
|
|
1004
|
+
/** Delete artifact rows whose paths share a DB-relative prefix. */
|
|
1005
|
+
export function deleteArtifactsByPathPrefix(prefix) {
|
|
1006
|
+
if (!getDbOrNull())
|
|
1007
|
+
throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
1008
|
+
return transaction(() => {
|
|
1009
|
+
const likePrefix = `${prefix}%`;
|
|
1010
|
+
const countRow = getDbOrNull().prepare("SELECT COUNT(*) AS count FROM artifacts WHERE path LIKE :prefix").get({ ":prefix": likePrefix });
|
|
1011
|
+
getDbOrNull().prepare("DELETE FROM artifacts WHERE path LIKE :prefix").run({ ":prefix": likePrefix });
|
|
1012
|
+
return Number(countRow?.["count"] ?? 0);
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
951
1015
|
/**
|
|
952
1016
|
* Drop hierarchy rows in dependency order inside a transaction. Used by
|
|
953
1017
|
* `gsd recover --confirm` to rebuild engine state from markdown.
|
|
@@ -151,6 +151,7 @@ const DOCTOR_FIX_HINTS = {
|
|
|
151
151
|
state_file_stale: "Run `/gsd doctor fix` to rebuild the projection from the database.",
|
|
152
152
|
state_file_missing: "Run `/gsd doctor fix` to rebuild the projection from the database.",
|
|
153
153
|
projection_drift: "Run `/gsd doctor fix` to rebuild markdown projections from the database (DB is the source of truth).",
|
|
154
|
+
artifact_user_content_missing: "Doctor cannot recreate user-authored content from the database. Re-run `/gsd discuss` for CONTEXT artifacts or `/gsd auto` for RESEARCH artifacts in that milestone.",
|
|
154
155
|
uat_retry_exhausted: "Review the failing UAT criteria via `/gsd status`, fix the issue, then re-run `/gsd auto`.",
|
|
155
156
|
};
|
|
156
157
|
export function doctorFixHint(code) {
|
|
@@ -20,15 +20,15 @@ import { assessInterruptedSession, formatInterruptedSessionRunningMessage, forma
|
|
|
20
20
|
import { listUnitRuntimeRecords, clearUnitRuntimeRecord, isInFlightRuntimePhase } from "./unit-runtime.js";
|
|
21
21
|
import { resolveExpectedArtifactPath } from "./auto.js";
|
|
22
22
|
import { gsdHome } from "./gsd-home.js";
|
|
23
|
-
import { gsdRoot, milestonesDir, legacyMilestonesDir, resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveGsdRootFile, relGsdRootFile, relMilestoneFile, relSliceFile, } from "./paths.js";
|
|
23
|
+
import { gsdRoot, milestonesDir, legacyMilestonesDir, resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveGsdRootFile, relGsdRootFile, relMilestoneFile, relSliceFile, clearPathCache, } from "./paths.js";
|
|
24
24
|
import { join } from "node:path";
|
|
25
25
|
import { readFileSync, existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
|
|
26
26
|
import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.js";
|
|
27
27
|
import { nativeAddAll, nativeCommit, nativeHasCommittedHead, nativeIsRepo, nativeInit } from "./native-git-bridge.js";
|
|
28
28
|
import { isInheritedRepo } from "./repo-identity.js";
|
|
29
29
|
import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitignore.js";
|
|
30
|
-
import { getIsolationMode, loadEffectiveGSDPreferences } from "./preferences.js";
|
|
31
|
-
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
30
|
+
import { getIsolationMode, loadEffectiveGSDPreferences, renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
31
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
32
32
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
33
33
|
import { ensurePlanV2Graph, isMissingFinalizedContextResult } from "./uok/plan-v2.js";
|
|
34
34
|
import { detectProjectState, hasGsdBootstrapArtifacts } from "./detection.js";
|
|
@@ -50,9 +50,10 @@ import { getCachedWorkflowMcpProbe, probeAndCacheWorkflowMcp, warmWorkflowMcpPro
|
|
|
50
50
|
import { probeCoversRequiredWorkflowTools } from "./tool-surface-readiness.js";
|
|
51
51
|
import { getRequiredWorkflowToolsForUnit } from "./unit-tool-contracts.js";
|
|
52
52
|
import { isWorkflowToolSurfaceName } from "./workflow-tool-surface.js";
|
|
53
|
-
import {
|
|
53
|
+
import { getUnitWorkflowDispatchReadinessErrorForModel } from "./tool-contract.js";
|
|
54
54
|
import { runPreparation, formatCodebaseBrief, formatPriorContextBrief, } from "./preparation.js";
|
|
55
55
|
import { verifyExpectedArtifact } from "./auto-recovery.js";
|
|
56
|
+
import { countPlanMilestoneRoadmapSlices } from "./artifact-verification.js";
|
|
56
57
|
import { clearPendingGate, extractDepthVerificationMilestoneId, getPendingGate } from "./bootstrap/write-gate.js";
|
|
57
58
|
import { _getPendingAutoStart, deletePendingAutoStart, hasPendingAutoStart, setPendingAutoStart, } from "./pending-auto-start.js";
|
|
58
59
|
import { clearGuidedUnitContext, setGuidedUnitContext } from "./guided-unit-context.js";
|
|
@@ -78,20 +79,57 @@ export const _scheduleAutoStartAfterIdleForTest = scheduleAutoStartAfterIdle;
|
|
|
78
79
|
// These thin wrappers accept a MilestoneScope so callers that already hold a
|
|
79
80
|
// pinned scope never have to re-derive (basePath, milestoneId) separately.
|
|
80
81
|
// The underlying implementations in auto-recovery.ts / auto-artifact-paths.ts /
|
|
81
|
-
// state.ts
|
|
82
|
+
// state.ts remain the default for non-scope-specific units.
|
|
82
83
|
/**
|
|
83
84
|
* Scope-based overload of verifyExpectedArtifact.
|
|
84
85
|
* Uses scope.workspace.projectRoot as the authoritative base path, making
|
|
85
86
|
* the check immune to cwd-drift and worktree-path divergence.
|
|
86
87
|
*/
|
|
87
88
|
export function verifyExpectedArtifactForScope(scope, unitType, unitId) {
|
|
89
|
+
if (unitId === scope.milestoneId &&
|
|
90
|
+
(unitType === "discuss-milestone" || unitType === "plan-milestone")) {
|
|
91
|
+
// Layout-aware scope paths use resolveMilestoneFile; clear stale dir listings
|
|
92
|
+
// primed before discuss/plan wrote CONTEXT.md or ROADMAP.md (see checkAutoStartAfterDiscuss).
|
|
93
|
+
clearPathCache();
|
|
94
|
+
}
|
|
95
|
+
if (unitId === scope.milestoneId &&
|
|
96
|
+
unitType === "discuss-milestone") {
|
|
97
|
+
const path = resolveExpectedArtifactPathForScope(scope, unitType, unitId);
|
|
98
|
+
return path ? existsSync(path) : false;
|
|
99
|
+
}
|
|
100
|
+
if (unitId === scope.milestoneId && unitType === "plan-milestone") {
|
|
101
|
+
const path = resolveExpectedArtifactPathForScope(scope, unitType, unitId);
|
|
102
|
+
return verifyScopedPlanMilestoneArtifact(path, unitType, unitId);
|
|
103
|
+
}
|
|
88
104
|
return verifyExpectedArtifact(unitType, unitId, scope.workspace.projectRoot);
|
|
89
105
|
}
|
|
106
|
+
function verifyScopedPlanMilestoneArtifact(path, unitType, unitId) {
|
|
107
|
+
if (!path || !existsSync(path))
|
|
108
|
+
return false;
|
|
109
|
+
try {
|
|
110
|
+
const roadmapContent = readFileSync(path, "utf-8");
|
|
111
|
+
if (countPlanMilestoneRoadmapSlices(roadmapContent) === 0) {
|
|
112
|
+
logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap has zero slices at ${path}`);
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
logWarning("recovery", `plan-milestone roadmap verification failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
90
122
|
/**
|
|
91
123
|
* Scope-based overload of resolveExpectedArtifactPath.
|
|
92
124
|
* Returns the canonical absolute path (or null) using the scope's projectRoot.
|
|
93
125
|
*/
|
|
94
126
|
export function resolveExpectedArtifactPathForScope(scope, unitType, unitId) {
|
|
127
|
+
if (unitId === scope.milestoneId) {
|
|
128
|
+
if (unitType === "discuss-milestone")
|
|
129
|
+
return scope.contextFile();
|
|
130
|
+
if (unitType === "plan-milestone")
|
|
131
|
+
return scope.roadmapFile();
|
|
132
|
+
}
|
|
95
133
|
return resolveExpectedArtifactPath(unitType, unitId, scope.workspace.projectRoot);
|
|
96
134
|
}
|
|
97
135
|
async function runQuickTaskChoice(ctx, pi) {
|
|
@@ -453,7 +491,7 @@ async function dispatchWorkflow(pi, note, customType = "gsd-run", ctx, unitType,
|
|
|
453
491
|
const loadPreferences = resolvedOptions.deps?.loadPreferences ?? loadEffectiveGSDPreferences;
|
|
454
492
|
const selectModel = resolvedOptions.deps?.selectModel ?? selectAndApplyModel;
|
|
455
493
|
const getDispatchReadinessError = resolvedOptions.deps?.getDispatchReadinessError
|
|
456
|
-
??
|
|
494
|
+
?? getUnitWorkflowDispatchReadinessErrorForModel;
|
|
457
495
|
// Route through the dynamic routing pipeline (complexity classification,
|
|
458
496
|
// tier downgrade, fallback chains) — same path as auto-mode dispatches (#2958).
|
|
459
497
|
if (ctx && unitType) {
|
|
@@ -468,16 +506,12 @@ async function dispatchWorkflow(pi, note, customType = "gsd-run", ctx, unitType,
|
|
|
468
506
|
});
|
|
469
507
|
}
|
|
470
508
|
const compatibilityError = getDispatchReadinessError({
|
|
471
|
-
|
|
509
|
+
model: result.appliedModel,
|
|
510
|
+
fallbackModel: ctx.model,
|
|
511
|
+
getProviderAuthMode: (provider) => ctx.modelRegistry.getProviderAuthMode(provider),
|
|
472
512
|
projectRoot,
|
|
473
513
|
surface: "guided flow",
|
|
474
514
|
unitType,
|
|
475
|
-
authMode: result.appliedModel?.provider
|
|
476
|
-
? ctx.modelRegistry.getProviderAuthMode(result.appliedModel.provider)
|
|
477
|
-
: ctx.model?.provider
|
|
478
|
-
? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider)
|
|
479
|
-
: undefined,
|
|
480
|
-
baseUrl: result.appliedModel?.baseUrl ?? ctx.model?.baseUrl,
|
|
481
515
|
// Guided flow starts the MCP workflow server as part of dispatch, so the
|
|
482
516
|
// parent session's activeTools doesn't include MCP tools yet. The MCP
|
|
483
517
|
// launch config check (detectWorkflowMcpLaunchConfig) is the right gate
|
|
@@ -608,7 +642,7 @@ function resolveAvailableModel(modelId, availableModels, currentProvider) {
|
|
|
608
642
|
* Build the discuss-and-plan prompt for a new milestone.
|
|
609
643
|
* Used by all three "new milestone" paths (first ever, no active, all complete).
|
|
610
644
|
*/
|
|
611
|
-
function buildDiscussPrompt(nextId, preamble,
|
|
645
|
+
function buildDiscussPrompt(nextId, preamble, basePath, pi, ctx, preparationContext) {
|
|
612
646
|
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
613
647
|
const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
|
|
614
648
|
const inlinedTemplates = [
|
|
@@ -618,7 +652,7 @@ function buildDiscussPrompt(nextId, preamble, _basePath, pi, ctx, preparationCon
|
|
|
618
652
|
inlineTemplate("roadmap", "Roadmap"),
|
|
619
653
|
inlineTemplate("decisions", "Decisions"),
|
|
620
654
|
].join("\n\n---\n\n");
|
|
621
|
-
return loadPrompt("discuss", {
|
|
655
|
+
return prependLanguageDirective(basePath, loadPrompt("discuss", {
|
|
622
656
|
milestoneId: nextId,
|
|
623
657
|
preamble,
|
|
624
658
|
preparationContext: preparationContext ?? "",
|
|
@@ -628,13 +662,22 @@ function buildDiscussPrompt(nextId, preamble, _basePath, pi, ctx, preparationCon
|
|
|
628
662
|
inlinedTemplates,
|
|
629
663
|
commitInstruction: buildDocsCommitInstruction(`docs(${nextId}): context, requirements, and roadmap`),
|
|
630
664
|
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
631
|
-
});
|
|
665
|
+
}));
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Prepend the configured response-language directive to a dispatched discuss
|
|
669
|
+
* prompt so the discuss/QA conversation is held in the language set in
|
|
670
|
+
* PREFERENCES.md (#1210). No-op when no language is configured.
|
|
671
|
+
*/
|
|
672
|
+
function prependLanguageDirective(basePath, prompt) {
|
|
673
|
+
const directive = renderLanguageDirectiveForPrompt(loadEffectiveGSDPreferences(basePath)?.preferences);
|
|
674
|
+
return directive ? `${directive}\n\n${prompt}` : prompt;
|
|
632
675
|
}
|
|
633
676
|
/**
|
|
634
677
|
* Build the discuss prompt for headless milestone creation.
|
|
635
678
|
* Uses the discuss-headless prompt template with seed context injected.
|
|
636
679
|
*/
|
|
637
|
-
function buildHeadlessDiscussPrompt(nextId, seedContext,
|
|
680
|
+
function buildHeadlessDiscussPrompt(nextId, seedContext, basePath) {
|
|
638
681
|
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
639
682
|
const inlinedTemplates = [
|
|
640
683
|
inlineTemplate("project", "Project"),
|
|
@@ -643,7 +686,7 @@ function buildHeadlessDiscussPrompt(nextId, seedContext, _basePath) {
|
|
|
643
686
|
inlineTemplate("roadmap", "Roadmap"),
|
|
644
687
|
inlineTemplate("decisions", "Decisions"),
|
|
645
688
|
].join("\n\n---\n\n");
|
|
646
|
-
return loadPrompt("discuss-headless", {
|
|
689
|
+
return prependLanguageDirective(basePath, loadPrompt("discuss-headless", {
|
|
647
690
|
milestoneId: nextId,
|
|
648
691
|
seedContext,
|
|
649
692
|
contextPath: `${milestoneRel}/${nextId}-CONTEXT.md`,
|
|
@@ -651,7 +694,7 @@ function buildHeadlessDiscussPrompt(nextId, seedContext, _basePath) {
|
|
|
651
694
|
inlinedTemplates,
|
|
652
695
|
commitInstruction: buildDocsCommitInstruction(`docs(${nextId}): context, requirements, and roadmap`),
|
|
653
696
|
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
654
|
-
});
|
|
697
|
+
}));
|
|
655
698
|
}
|
|
656
699
|
/**
|
|
657
700
|
* Run preparation phase if enabled, then build the discuss prompt.
|