@opengsd/gsd-pi 1.2.0-dev.fbdca60b → 1.3.0-dev.65546769

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.
Files changed (835) hide show
  1. package/README.md +13 -7
  2. package/dist/cli.js +28 -1
  3. package/dist/headless-context.js +0 -1
  4. package/dist/headless-events.d.ts +16 -1
  5. package/dist/headless-events.js +19 -2
  6. package/dist/headless.js +8 -1
  7. package/dist/help-text.js +29 -0
  8. package/dist/hermes-integration-install.d.ts +17 -0
  9. package/dist/hermes-integration-install.js +199 -0
  10. package/dist/jiti-workspace-aliases.d.ts +11 -2
  11. package/dist/jiti-workspace-aliases.js +19 -3
  12. package/dist/onboarding.js +9 -4
  13. package/dist/provider-migrations.d.ts +23 -0
  14. package/dist/provider-migrations.js +41 -0
  15. package/dist/read-cli.d.ts +23 -0
  16. package/dist/read-cli.js +90 -0
  17. package/dist/resource-loader.d.ts +3 -3
  18. package/dist/resource-loader.js +4 -13
  19. package/dist/resources/.managed-resources-content-hash +1 -1
  20. package/dist/resources/GSD-WORKFLOW.md +22 -22
  21. package/dist/resources/extensions/claude-code-cli/index.js +7 -1
  22. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +73 -20
  23. package/dist/resources/extensions/google-cli/stream-adapter.js +16 -1
  24. package/dist/resources/extensions/gsd/auto/dispatch-history.js +6 -1
  25. package/dist/resources/extensions/gsd/auto/loop.js +67 -2
  26. package/dist/resources/extensions/gsd/auto/orchestrator.js +50 -10
  27. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +8 -0
  28. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +15 -1
  29. package/dist/resources/extensions/gsd/auto-artifact-paths.js +81 -19
  30. package/dist/resources/extensions/gsd/auto-closeout-messaging.js +90 -0
  31. package/dist/resources/extensions/gsd/auto-dashboard.js +255 -431
  32. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +15 -3
  33. package/dist/resources/extensions/gsd/auto-dispatch.js +47 -8
  34. package/dist/resources/extensions/gsd/auto-model-selection.js +14 -8
  35. package/dist/resources/extensions/gsd/auto-post-unit.js +39 -29
  36. package/dist/resources/extensions/gsd/auto-prompts.js +44 -30
  37. package/dist/resources/extensions/gsd/auto-recovery.js +118 -40
  38. package/dist/resources/extensions/gsd/auto-runtime-state.js +13 -0
  39. package/dist/resources/extensions/gsd/auto-start.js +58 -31
  40. package/dist/resources/extensions/gsd/auto-verification.js +5 -2
  41. package/dist/resources/extensions/gsd/auto-worktree.js +149 -91
  42. package/dist/resources/extensions/gsd/auto.js +97 -31
  43. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +42 -54
  44. package/dist/resources/extensions/gsd/bootstrap/fallback-continuation.js +25 -0
  45. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +24 -2
  46. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +108 -9
  47. package/dist/resources/extensions/gsd/bootstrap/system-context.js +164 -44
  48. package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +22 -3
  49. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +113 -27
  50. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +92 -4
  51. package/dist/resources/extensions/gsd/closeout-wizard.js +8 -3
  52. package/dist/resources/extensions/gsd/codebase-generator.js +5 -8
  53. package/dist/resources/extensions/gsd/commands/catalog.js +6 -0
  54. package/dist/resources/extensions/gsd/commands/dispatcher.js +3 -0
  55. package/dist/resources/extensions/gsd/commands/gsd-core-aliases-handler.js +39 -0
  56. package/dist/resources/extensions/gsd/commands/gsd-core-aliases.js +44 -0
  57. package/dist/resources/extensions/gsd/commands/handlers/core.js +52 -8
  58. package/dist/resources/extensions/gsd/commands/handlers/ops.js +227 -3
  59. package/dist/resources/extensions/gsd/commands-cmux.js +3 -1
  60. package/dist/resources/extensions/gsd/commands-gsd-core.js +868 -0
  61. package/dist/resources/extensions/gsd/commands-handlers.js +67 -1
  62. package/dist/resources/extensions/gsd/commands-maintenance.js +79 -2
  63. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +14 -1
  64. package/dist/resources/extensions/gsd/commands-verdict.js +17 -11
  65. package/dist/resources/extensions/gsd/compat/compat-marker.js +172 -0
  66. package/dist/resources/extensions/gsd/compat/index.js +3 -0
  67. package/dist/resources/extensions/gsd/compat/planning-compat.js +142 -0
  68. package/dist/resources/extensions/gsd/config-overlay.js +11 -8
  69. package/dist/resources/extensions/gsd/consent-question.js +12 -0
  70. package/dist/resources/extensions/gsd/consent-verdict.js +10 -0
  71. package/dist/resources/extensions/gsd/dashboard-overlay.js +39 -3
  72. package/dist/resources/extensions/gsd/db/engine.js +27 -0
  73. package/dist/resources/extensions/gsd/db/queries.js +54 -0
  74. package/dist/resources/extensions/gsd/db/unit-dispatches.js +22 -1
  75. package/dist/resources/extensions/gsd/db/writers/reconcile.js +19 -1
  76. package/dist/resources/extensions/gsd/db-workspace.js +13 -1
  77. package/dist/resources/extensions/gsd/discussion-handoff.js +9 -5
  78. package/dist/resources/extensions/gsd/doctor-git-checks.js +30 -4
  79. package/dist/resources/extensions/gsd/doctor-providers.js +1 -1
  80. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -24
  81. package/dist/resources/extensions/gsd/doctor.js +28 -7
  82. package/dist/resources/extensions/gsd/error-classifier.js +13 -1
  83. package/dist/resources/extensions/gsd/escalation.js +11 -4
  84. package/dist/resources/extensions/gsd/export-html.js +10 -3
  85. package/dist/resources/extensions/gsd/export.js +73 -0
  86. package/dist/resources/extensions/gsd/file-lock.js +1 -1
  87. package/dist/resources/extensions/gsd/flat-phase-migration.js +176 -0
  88. package/dist/resources/extensions/gsd/forensics.js +2 -1
  89. package/dist/resources/extensions/gsd/git-service.js +7 -4
  90. package/dist/resources/extensions/gsd/gitignore.js +6 -2
  91. package/dist/resources/extensions/gsd/guidance.js +7 -7
  92. package/dist/resources/extensions/gsd/guided-flow.js +11 -6
  93. package/dist/resources/extensions/gsd/layout-policy.js +75 -0
  94. package/dist/resources/extensions/gsd/markdown-renderer.js +391 -116
  95. package/dist/resources/extensions/gsd/mcp-filter.js +44 -10
  96. package/dist/resources/extensions/gsd/md-importer.js +153 -51
  97. package/dist/resources/extensions/gsd/metrics.js +19 -11
  98. package/dist/resources/extensions/gsd/migrate/layout-detect.js +32 -0
  99. package/dist/resources/extensions/gsd/migrate/planning-writer.js +203 -0
  100. package/dist/resources/extensions/gsd/migrate-external.js +51 -6
  101. package/dist/resources/extensions/gsd/migration-auto-check.js +5 -14
  102. package/dist/resources/extensions/gsd/milestone-actions.js +5 -3
  103. package/dist/resources/extensions/gsd/milestone-closeout.js +12 -2
  104. package/dist/resources/extensions/gsd/milestone-ids.js +50 -19
  105. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +8 -0
  106. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +7 -4
  107. package/dist/resources/extensions/gsd/model-router.js +79 -20
  108. package/dist/resources/extensions/gsd/notification-store.js +22 -29
  109. package/dist/resources/extensions/gsd/notifications.js +36 -7
  110. package/dist/resources/extensions/gsd/observability-validator.js +12 -4
  111. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +133 -35
  112. package/dist/resources/extensions/gsd/parsers-legacy.js +40 -14
  113. package/dist/resources/extensions/gsd/paths.js +356 -44
  114. package/dist/resources/extensions/gsd/planning-depth.js +2 -1
  115. package/dist/resources/extensions/gsd/post-execution-checks.js +26 -3
  116. package/dist/resources/extensions/gsd/preferences-models.js +34 -14
  117. package/dist/resources/extensions/gsd/preferences.js +148 -13
  118. package/dist/resources/extensions/gsd/prompts/ai-integration-phase.md +28 -0
  119. package/dist/resources/extensions/gsd/prompts/audit-fix.md +39 -0
  120. package/dist/resources/extensions/gsd/prompts/audit-milestone.md +26 -0
  121. package/dist/resources/extensions/gsd/prompts/audit-uat.md +24 -0
  122. package/dist/resources/extensions/gsd/prompts/autonomous.md +31 -0
  123. package/dist/resources/extensions/gsd/prompts/code-review.md +37 -0
  124. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +8 -2
  125. package/dist/resources/extensions/gsd/prompts/complete-slice.md +24 -15
  126. package/dist/resources/extensions/gsd/prompts/discuss-phase.md +31 -0
  127. package/dist/resources/extensions/gsd/prompts/docs-update.md +13 -0
  128. package/dist/resources/extensions/gsd/prompts/execute-phase.md +33 -0
  129. package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -1
  130. package/dist/resources/extensions/gsd/prompts/explore.md +58 -0
  131. package/dist/resources/extensions/gsd/prompts/graphify.md +27 -0
  132. package/dist/resources/extensions/gsd/prompts/health.md +37 -0
  133. package/dist/resources/extensions/gsd/prompts/import.md +30 -0
  134. package/dist/resources/extensions/gsd/prompts/inbox.md +27 -0
  135. package/dist/resources/extensions/gsd/prompts/ingest-docs.md +30 -0
  136. package/dist/resources/extensions/gsd/prompts/manager.md +21 -0
  137. package/dist/resources/extensions/gsd/prompts/map-codebase.md +42 -0
  138. package/dist/resources/extensions/gsd/prompts/milestone-summary.md +27 -0
  139. package/dist/resources/extensions/gsd/prompts/mvp-phase.md +23 -0
  140. package/dist/resources/extensions/gsd/prompts/pause-work.md +24 -0
  141. package/dist/resources/extensions/gsd/prompts/phase.md +22 -0
  142. package/dist/resources/extensions/gsd/prompts/plan-phase.md +34 -0
  143. package/dist/resources/extensions/gsd/prompts/plan-review-convergence.md +34 -0
  144. package/dist/resources/extensions/gsd/prompts/profile-user.md +28 -0
  145. package/dist/resources/extensions/gsd/prompts/progress.md +30 -0
  146. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  147. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +2 -2
  148. package/dist/resources/extensions/gsd/prompts/resume-work.md +20 -0
  149. package/dist/resources/extensions/gsd/prompts/review-backlog.md +21 -0
  150. package/dist/resources/extensions/gsd/prompts/review.md +27 -0
  151. package/dist/resources/extensions/gsd/prompts/run-uat.md +5 -1
  152. package/dist/resources/extensions/gsd/prompts/secure-phase.md +24 -0
  153. package/dist/resources/extensions/gsd/prompts/settings.md +24 -0
  154. package/dist/resources/extensions/gsd/prompts/sketch.md +59 -0
  155. package/dist/resources/extensions/gsd/prompts/spec-phase.md +29 -0
  156. package/dist/resources/extensions/gsd/prompts/spike.md +59 -0
  157. package/dist/resources/extensions/gsd/prompts/stats.md +43 -0
  158. package/dist/resources/extensions/gsd/prompts/surface.md +25 -0
  159. package/dist/resources/extensions/gsd/prompts/thread.md +24 -0
  160. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  161. package/dist/resources/extensions/gsd/prompts/ui-phase.md +29 -0
  162. package/dist/resources/extensions/gsd/prompts/ui-review.md +29 -0
  163. package/dist/resources/extensions/gsd/prompts/ultraplan-phase.md +24 -0
  164. package/dist/resources/extensions/gsd/prompts/validate-phase.md +26 -0
  165. package/dist/resources/extensions/gsd/prompts/verify-work.md +24 -0
  166. package/dist/resources/extensions/gsd/prompts/workspace.md +22 -0
  167. package/dist/resources/extensions/gsd/prompts/workstreams.md +24 -0
  168. package/dist/resources/extensions/gsd/provider-error-guidance.js +24 -0
  169. package/dist/resources/extensions/gsd/queue-order.js +3 -2
  170. package/dist/resources/extensions/gsd/recovery-classification.js +8 -0
  171. package/dist/resources/extensions/gsd/roadmap-slices.js +1 -1
  172. package/dist/resources/extensions/gsd/safety/content-validator.js +2 -1
  173. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +43 -1
  174. package/dist/resources/extensions/gsd/service-tier.js +2 -1
  175. package/dist/resources/extensions/gsd/session-lock.js +11 -9
  176. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +3 -0
  177. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +51 -0
  178. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +51 -10
  179. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +24 -3
  180. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +82 -0
  181. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +142 -0
  182. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +19 -6
  183. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +2 -2
  184. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +95 -19
  185. package/dist/resources/extensions/gsd/state-reconciliation/index.js +36 -3
  186. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +12 -0
  187. package/dist/resources/extensions/gsd/state.js +48 -17
  188. package/dist/resources/extensions/gsd/sync-lock.js +11 -18
  189. package/dist/resources/extensions/gsd/tool-surface-readiness.js +205 -16
  190. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
  191. package/dist/resources/extensions/gsd/tools/complete-slice.js +12 -2
  192. package/dist/resources/extensions/gsd/tools/complete-task.js +15 -1
  193. package/dist/resources/extensions/gsd/tools/exec-tool.js +2 -109
  194. package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -3
  195. package/dist/resources/extensions/gsd/tools/plan-task.js +16 -1
  196. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +9 -3
  197. package/dist/resources/extensions/gsd/tools/validate-milestone.js +8 -3
  198. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +44 -5
  199. package/dist/resources/extensions/gsd/triage-resolution.js +14 -7
  200. package/dist/resources/extensions/gsd/tui/render-kit.js +38 -13
  201. package/dist/resources/extensions/gsd/undo.js +8 -9
  202. package/dist/resources/extensions/gsd/unit-registry.js +27 -3
  203. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +58 -2
  204. package/dist/resources/extensions/gsd/validation-block-guard.js +45 -0
  205. package/dist/resources/extensions/gsd/visualizer-data.js +35 -0
  206. package/dist/resources/extensions/gsd/visualizer-views.js +21 -2
  207. package/dist/resources/extensions/gsd/workflow-logger.js +4 -0
  208. package/dist/resources/extensions/gsd/workflow-mcp.js +9 -1
  209. package/dist/resources/extensions/gsd/workflow-projections.js +25 -4
  210. package/dist/resources/extensions/gsd/worktree-command.js +6 -6
  211. package/dist/resources/extensions/gsd/worktree-health.js +6 -3
  212. package/dist/resources/extensions/gsd/worktree-manager.js +109 -16
  213. package/dist/resources/extensions/gsd/worktree-safety.js +20 -11
  214. package/dist/resources/extensions/gsd/worktree-shell-guard.js +113 -0
  215. package/dist/resources/extensions/mcp-client/manager.js +3 -3
  216. package/dist/resources/extensions/search-the-web/index.js +41 -9
  217. package/dist/resources/extensions/search-the-web/native-search.js +18 -4
  218. package/dist/resources/extensions/shared/gsd-browser-cli.js +40 -2
  219. package/dist/resources/extensions/subagent/index.js +20 -15
  220. package/dist/resources/extensions/subagent/worktree-cwd.js +31 -0
  221. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  222. package/dist/update-check.js +15 -4
  223. package/dist/web/standalone/.next/BUILD_ID +1 -1
  224. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  225. package/dist/web/standalone/.next/build-manifest.json +3 -3
  226. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  227. package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
  228. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  229. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  230. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  231. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  232. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  233. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  234. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  235. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  236. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  237. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  238. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  239. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  240. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  241. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  242. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  243. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  244. package/dist/web/standalone/.next/server/app/index.html +1 -1
  245. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  246. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  247. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  248. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  249. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  250. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  251. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  252. package/dist/web/standalone/.next/server/chunks/1128.js +1 -1
  253. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  254. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  255. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  256. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  257. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  258. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  259. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  260. package/dist/web/standalone/.next/static/chunks/{4283.e4873b058df143a1.js → 4283.8e446784528ed9dc.js} +2 -2
  261. package/dist/web/standalone/.next/static/chunks/8785.481aa5869991b760.js +1 -0
  262. package/dist/web/standalone/.next/static/chunks/{webpack-f0285ce91d4ec9ef.js → webpack-f46ea08200a0227e.js} +1 -1
  263. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  264. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  265. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  266. package/dist/web-mode.d.ts +3 -1
  267. package/dist/web-mode.js +7 -5
  268. package/integrations/hermes/README.md +48 -0
  269. package/integrations/hermes/docs/setup.md +272 -0
  270. package/integrations/hermes/docs/upstream-hermes-pr.md +40 -0
  271. package/integrations/hermes/open_gsd_hermes/__init__.py +105 -0
  272. package/integrations/hermes/open_gsd_hermes/binding.py +107 -0
  273. package/integrations/hermes/open_gsd_hermes/commands.py +186 -0
  274. package/integrations/hermes/open_gsd_hermes/config.py +59 -0
  275. package/integrations/hermes/open_gsd_hermes/credentials.py +51 -0
  276. package/integrations/hermes/open_gsd_hermes/cron.py +85 -0
  277. package/integrations/hermes/open_gsd_hermes/formatting.py +13 -0
  278. package/integrations/hermes/open_gsd_hermes/gsd_client.py +269 -0
  279. package/integrations/hermes/open_gsd_hermes/inject.py +31 -0
  280. package/integrations/hermes/open_gsd_hermes/memory.py +66 -0
  281. package/integrations/hermes/open_gsd_hermes/notifications.py +71 -0
  282. package/integrations/hermes/open_gsd_hermes/snapshot.py +42 -0
  283. package/integrations/hermes/open_gsd_hermes/supervisor.py +180 -0
  284. package/integrations/hermes/open_gsd_hermes/types.py +100 -0
  285. package/integrations/hermes/plugin.yaml +38 -0
  286. package/integrations/hermes/pyproject.toml +32 -0
  287. package/integrations/hermes/scripts/preflight.sh +92 -0
  288. package/integrations/hermes/tests/fixtures/minimal-project/.gsd/STATE.md +17 -0
  289. package/integrations/hermes/tests/golden/memory_prefetch.txt +5 -0
  290. package/integrations/hermes/tests/golden/snapshot.txt +8 -0
  291. package/integrations/hermes/tests/test_binding.py +103 -0
  292. package/integrations/hermes/tests/test_config.py +36 -0
  293. package/integrations/hermes/tests/test_cron.py +34 -0
  294. package/integrations/hermes/tests/test_gsd_client_cache.py +120 -0
  295. package/integrations/hermes/tests/test_memory.py +59 -0
  296. package/integrations/hermes/tests/test_read_cli_contract.py +50 -0
  297. package/integrations/hermes/tests/test_register.py +56 -0
  298. package/integrations/hermes/tests/test_snapshot.py +53 -0
  299. package/integrations/hermes/tests/test_supervisor_fsm.py +581 -0
  300. package/package.json +8 -7
  301. package/packages/cloud-mcp-gateway/dist/runtime-registry.d.ts +8 -0
  302. package/packages/cloud-mcp-gateway/dist/runtime-registry.d.ts.map +1 -1
  303. package/packages/cloud-mcp-gateway/dist/runtime-registry.js +19 -2
  304. package/packages/cloud-mcp-gateway/dist/runtime-registry.js.map +1 -1
  305. package/packages/cloud-mcp-gateway/dist/runtime-registry.test.js +71 -2
  306. package/packages/cloud-mcp-gateway/dist/runtime-registry.test.js.map +1 -1
  307. package/packages/cloud-mcp-gateway/package.json +2 -2
  308. package/packages/contracts/package.json +1 -1
  309. package/packages/daemon/package.json +4 -4
  310. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  311. package/packages/gsd-agent-core/dist/sdk.js +6 -2
  312. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  313. package/packages/gsd-agent-core/package.json +5 -5
  314. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts +5 -5
  315. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  316. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js +12 -24
  317. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js.map +1 -1
  318. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.js +5 -5
  319. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.js.map +1 -1
  320. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.d.ts +3 -3
  321. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  322. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.js +20 -11
  323. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  324. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.d.ts +4 -3
  325. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.d.ts.map +1 -1
  326. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.js +5 -54
  327. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.js.map +1 -1
  328. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -4
  329. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  330. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.js +2 -4
  331. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  332. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.d.ts +2 -0
  333. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  334. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.js +4 -0
  335. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.js.map +1 -1
  336. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.d.ts +9 -12
  337. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.d.ts.map +1 -1
  338. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.js +100 -166
  339. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.js.map +1 -1
  340. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.d.ts +2 -0
  341. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.d.ts.map +1 -0
  342. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.js +4 -0
  343. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.js.map +1 -0
  344. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.d.ts +23 -0
  345. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.d.ts.map +1 -0
  346. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.js +178 -0
  347. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.js.map +1 -0
  348. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +8 -0
  349. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  350. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +21 -9
  351. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
  352. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -3
  353. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  354. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.js +2 -3
  355. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  356. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +3 -0
  357. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  358. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +37 -15
  359. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  360. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +69 -3
  361. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  362. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +223 -32
  363. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  364. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.d.ts +3 -3
  365. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  366. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.js +19 -19
  367. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.js.map +1 -1
  368. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -0
  369. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  370. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -10
  371. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  372. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.d.ts.map +1 -1
  373. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.js +12 -1
  374. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
  375. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  376. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +5 -0
  377. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  378. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  379. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js +3 -1
  380. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  381. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  382. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +3 -5
  383. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  384. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -2
  385. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  386. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts +1 -0
  387. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  388. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +25 -0
  389. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  390. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.d.ts.map +1 -1
  391. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.js +1 -0
  392. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.js.map +1 -1
  393. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.d.ts +1 -0
  394. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.d.ts.map +1 -1
  395. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.js +20 -49
  396. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.js.map +1 -1
  397. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +4 -0
  398. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  399. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  400. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +9 -2
  401. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  402. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +31 -6
  403. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  404. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.d.ts.map +1 -1
  405. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.js +0 -1
  406. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.js.map +1 -1
  407. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  408. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -0
  409. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  410. package/packages/gsd-agent-modes/package.json +7 -7
  411. package/packages/mcp-server/README.md +10 -0
  412. package/packages/mcp-server/dist/cli-errors.d.ts +11 -0
  413. package/packages/mcp-server/dist/cli-errors.d.ts.map +1 -1
  414. package/packages/mcp-server/dist/cli-errors.js +12 -0
  415. package/packages/mcp-server/dist/cli-errors.js.map +1 -1
  416. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
  417. package/packages/mcp-server/dist/cli-runner.js +33 -0
  418. package/packages/mcp-server/dist/cli-runner.js.map +1 -1
  419. package/packages/mcp-server/dist/cli.d.ts +1 -0
  420. package/packages/mcp-server/dist/cli.d.ts.map +1 -1
  421. package/packages/mcp-server/dist/cli.js +1 -0
  422. package/packages/mcp-server/dist/cli.js.map +1 -1
  423. package/packages/mcp-server/dist/server.d.ts +29 -0
  424. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  425. package/packages/mcp-server/dist/server.js +82 -3
  426. package/packages/mcp-server/dist/server.js.map +1 -1
  427. package/packages/mcp-server/package.json +21 -5
  428. package/packages/native/package.json +1 -1
  429. package/packages/pi-agent-core/dist/agent-loop.js +9 -0
  430. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  431. package/packages/pi-agent-core/package.json +1 -1
  432. package/packages/pi-ai/package.json +1 -1
  433. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +28 -2
  434. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  435. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  436. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  437. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  438. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  439. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -1
  440. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  441. package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -1
  442. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  443. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  444. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  445. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  446. package/packages/pi-coding-agent/package.json +8 -8
  447. package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
  448. package/packages/pi-tui/dist/autocomplete.js +6 -1
  449. package/packages/pi-tui/dist/autocomplete.js.map +1 -1
  450. package/packages/pi-tui/dist/components/input.js +1 -1
  451. package/packages/pi-tui/dist/components/input.js.map +1 -1
  452. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  453. package/packages/pi-tui/dist/components/loader.js +1 -0
  454. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  455. package/packages/pi-tui/dist/components/select-list.d.ts.map +1 -1
  456. package/packages/pi-tui/dist/components/select-list.js +8 -2
  457. package/packages/pi-tui/dist/components/select-list.js.map +1 -1
  458. package/packages/pi-tui/package.json +2 -2
  459. package/packages/rpc-client/package.json +2 -2
  460. package/pkg/package.json +1 -1
  461. package/src/resources/GSD-WORKFLOW.md +22 -22
  462. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +80 -0
  463. package/src/resources/extensions/claude-code-cli/index.ts +8 -1
  464. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +83 -20
  465. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +47 -0
  466. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +182 -10
  467. package/src/resources/extensions/google-cli/stream-adapter.ts +22 -1
  468. package/src/resources/extensions/gsd/auto/dispatch-history.ts +19 -1
  469. package/src/resources/extensions/gsd/auto/loop.ts +69 -2
  470. package/src/resources/extensions/gsd/auto/orchestrator.ts +63 -10
  471. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +13 -1
  472. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +25 -3
  473. package/src/resources/extensions/gsd/auto-artifact-paths.ts +83 -20
  474. package/src/resources/extensions/gsd/auto-closeout-messaging.ts +90 -0
  475. package/src/resources/extensions/gsd/auto-dashboard.ts +310 -454
  476. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +15 -2
  477. package/src/resources/extensions/gsd/auto-dispatch.ts +57 -12
  478. package/src/resources/extensions/gsd/auto-model-selection.ts +27 -5
  479. package/src/resources/extensions/gsd/auto-post-unit.ts +52 -31
  480. package/src/resources/extensions/gsd/auto-prompts.ts +45 -30
  481. package/src/resources/extensions/gsd/auto-recovery.ts +126 -37
  482. package/src/resources/extensions/gsd/auto-runtime-state.ts +13 -0
  483. package/src/resources/extensions/gsd/auto-start.ts +82 -36
  484. package/src/resources/extensions/gsd/auto-verification.ts +5 -7
  485. package/src/resources/extensions/gsd/auto-worktree.ts +83 -15
  486. package/src/resources/extensions/gsd/auto.ts +133 -32
  487. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +45 -61
  488. package/src/resources/extensions/gsd/bootstrap/fallback-continuation.ts +31 -0
  489. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +23 -2
  490. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +123 -9
  491. package/src/resources/extensions/gsd/bootstrap/system-context.ts +185 -46
  492. package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +21 -3
  493. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +138 -29
  494. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +107 -3
  495. package/src/resources/extensions/gsd/closeout-wizard.ts +11 -2
  496. package/src/resources/extensions/gsd/codebase-generator.ts +6 -9
  497. package/src/resources/extensions/gsd/commands/catalog.ts +6 -0
  498. package/src/resources/extensions/gsd/commands/dispatcher.ts +3 -0
  499. package/src/resources/extensions/gsd/commands/gsd-core-aliases-handler.ts +48 -0
  500. package/src/resources/extensions/gsd/commands/gsd-core-aliases.ts +63 -0
  501. package/src/resources/extensions/gsd/commands/handlers/core.ts +58 -8
  502. package/src/resources/extensions/gsd/commands/handlers/ops.ts +230 -3
  503. package/src/resources/extensions/gsd/commands-cmux.ts +3 -0
  504. package/src/resources/extensions/gsd/commands-gsd-core.ts +1142 -0
  505. package/src/resources/extensions/gsd/commands-handlers.ts +76 -1
  506. package/src/resources/extensions/gsd/commands-maintenance.ts +98 -2
  507. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +13 -0
  508. package/src/resources/extensions/gsd/commands-verdict.ts +16 -15
  509. package/src/resources/extensions/gsd/compat/compat-marker.ts +210 -0
  510. package/src/resources/extensions/gsd/compat/index.ts +12 -0
  511. package/src/resources/extensions/gsd/compat/planning-compat.ts +168 -0
  512. package/src/resources/extensions/gsd/config-overlay.ts +24 -9
  513. package/src/resources/extensions/gsd/consent-question.ts +11 -1
  514. package/src/resources/extensions/gsd/consent-verdict.ts +30 -1
  515. package/src/resources/extensions/gsd/dashboard-overlay.ts +41 -4
  516. package/src/resources/extensions/gsd/db/engine.ts +26 -0
  517. package/src/resources/extensions/gsd/db/queries.ts +78 -0
  518. package/src/resources/extensions/gsd/db/unit-dispatches.ts +24 -0
  519. package/src/resources/extensions/gsd/db/writers/reconcile.ts +24 -1
  520. package/src/resources/extensions/gsd/db-workspace.ts +15 -0
  521. package/src/resources/extensions/gsd/discussion-handoff.ts +9 -5
  522. package/src/resources/extensions/gsd/doctor-git-checks.ts +28 -3
  523. package/src/resources/extensions/gsd/doctor-providers.ts +1 -1
  524. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +12 -25
  525. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  526. package/src/resources/extensions/gsd/doctor.ts +30 -7
  527. package/src/resources/extensions/gsd/error-classifier.ts +14 -1
  528. package/src/resources/extensions/gsd/escalation.ts +9 -4
  529. package/src/resources/extensions/gsd/export-html.ts +11 -4
  530. package/src/resources/extensions/gsd/export.ts +88 -1
  531. package/src/resources/extensions/gsd/file-lock.ts +1 -1
  532. package/src/resources/extensions/gsd/flat-phase-migration.ts +205 -0
  533. package/src/resources/extensions/gsd/forensics.ts +2 -1
  534. package/src/resources/extensions/gsd/git-constants.ts +1 -1
  535. package/src/resources/extensions/gsd/git-service.ts +7 -2
  536. package/src/resources/extensions/gsd/gitignore.ts +7 -3
  537. package/src/resources/extensions/gsd/guidance.ts +7 -7
  538. package/src/resources/extensions/gsd/guided-flow.ts +11 -6
  539. package/src/resources/extensions/gsd/layout-policy.ts +85 -0
  540. package/src/resources/extensions/gsd/markdown-renderer.ts +404 -104
  541. package/src/resources/extensions/gsd/mcp-filter.ts +59 -10
  542. package/src/resources/extensions/gsd/md-importer.ts +215 -65
  543. package/src/resources/extensions/gsd/metrics.ts +23 -10
  544. package/src/resources/extensions/gsd/migrate/layout-detect.ts +38 -0
  545. package/src/resources/extensions/gsd/migrate/planning-writer.ts +259 -0
  546. package/src/resources/extensions/gsd/migrate-external.ts +49 -6
  547. package/src/resources/extensions/gsd/migration-auto-check.ts +4 -13
  548. package/src/resources/extensions/gsd/milestone-actions.ts +5 -2
  549. package/src/resources/extensions/gsd/milestone-closeout.ts +13 -2
  550. package/src/resources/extensions/gsd/milestone-ids.ts +49 -19
  551. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +8 -0
  552. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +7 -9
  553. package/src/resources/extensions/gsd/model-router.ts +98 -18
  554. package/src/resources/extensions/gsd/notification-store.ts +17 -28
  555. package/src/resources/extensions/gsd/notifications.ts +37 -6
  556. package/src/resources/extensions/gsd/observability-validator.ts +12 -4
  557. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +151 -31
  558. package/src/resources/extensions/gsd/parsers-legacy.ts +42 -15
  559. package/src/resources/extensions/gsd/paths.ts +348 -39
  560. package/src/resources/extensions/gsd/planning-depth.ts +2 -1
  561. package/src/resources/extensions/gsd/post-execution-checks.ts +43 -3
  562. package/src/resources/extensions/gsd/preferences-models.ts +47 -13
  563. package/src/resources/extensions/gsd/preferences.ts +188 -14
  564. package/src/resources/extensions/gsd/prompts/ai-integration-phase.md +28 -0
  565. package/src/resources/extensions/gsd/prompts/audit-fix.md +39 -0
  566. package/src/resources/extensions/gsd/prompts/audit-milestone.md +26 -0
  567. package/src/resources/extensions/gsd/prompts/audit-uat.md +24 -0
  568. package/src/resources/extensions/gsd/prompts/autonomous.md +31 -0
  569. package/src/resources/extensions/gsd/prompts/code-review.md +37 -0
  570. package/src/resources/extensions/gsd/prompts/complete-milestone.md +8 -2
  571. package/src/resources/extensions/gsd/prompts/complete-slice.md +24 -15
  572. package/src/resources/extensions/gsd/prompts/discuss-phase.md +31 -0
  573. package/src/resources/extensions/gsd/prompts/docs-update.md +13 -0
  574. package/src/resources/extensions/gsd/prompts/execute-phase.md +33 -0
  575. package/src/resources/extensions/gsd/prompts/execute-task.md +5 -1
  576. package/src/resources/extensions/gsd/prompts/explore.md +58 -0
  577. package/src/resources/extensions/gsd/prompts/graphify.md +27 -0
  578. package/src/resources/extensions/gsd/prompts/health.md +37 -0
  579. package/src/resources/extensions/gsd/prompts/import.md +30 -0
  580. package/src/resources/extensions/gsd/prompts/inbox.md +27 -0
  581. package/src/resources/extensions/gsd/prompts/ingest-docs.md +30 -0
  582. package/src/resources/extensions/gsd/prompts/manager.md +21 -0
  583. package/src/resources/extensions/gsd/prompts/map-codebase.md +42 -0
  584. package/src/resources/extensions/gsd/prompts/milestone-summary.md +27 -0
  585. package/src/resources/extensions/gsd/prompts/mvp-phase.md +23 -0
  586. package/src/resources/extensions/gsd/prompts/pause-work.md +24 -0
  587. package/src/resources/extensions/gsd/prompts/phase.md +22 -0
  588. package/src/resources/extensions/gsd/prompts/plan-phase.md +34 -0
  589. package/src/resources/extensions/gsd/prompts/plan-review-convergence.md +34 -0
  590. package/src/resources/extensions/gsd/prompts/profile-user.md +28 -0
  591. package/src/resources/extensions/gsd/prompts/progress.md +30 -0
  592. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  593. package/src/resources/extensions/gsd/prompts/reactive-execute.md +2 -2
  594. package/src/resources/extensions/gsd/prompts/resume-work.md +20 -0
  595. package/src/resources/extensions/gsd/prompts/review-backlog.md +21 -0
  596. package/src/resources/extensions/gsd/prompts/review.md +27 -0
  597. package/src/resources/extensions/gsd/prompts/run-uat.md +5 -1
  598. package/src/resources/extensions/gsd/prompts/secure-phase.md +24 -0
  599. package/src/resources/extensions/gsd/prompts/settings.md +24 -0
  600. package/src/resources/extensions/gsd/prompts/sketch.md +59 -0
  601. package/src/resources/extensions/gsd/prompts/spec-phase.md +29 -0
  602. package/src/resources/extensions/gsd/prompts/spike.md +59 -0
  603. package/src/resources/extensions/gsd/prompts/stats.md +43 -0
  604. package/src/resources/extensions/gsd/prompts/surface.md +25 -0
  605. package/src/resources/extensions/gsd/prompts/thread.md +24 -0
  606. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  607. package/src/resources/extensions/gsd/prompts/ui-phase.md +29 -0
  608. package/src/resources/extensions/gsd/prompts/ui-review.md +29 -0
  609. package/src/resources/extensions/gsd/prompts/ultraplan-phase.md +24 -0
  610. package/src/resources/extensions/gsd/prompts/validate-phase.md +26 -0
  611. package/src/resources/extensions/gsd/prompts/verify-work.md +24 -0
  612. package/src/resources/extensions/gsd/prompts/workspace.md +22 -0
  613. package/src/resources/extensions/gsd/prompts/workstreams.md +24 -0
  614. package/src/resources/extensions/gsd/provider-error-guidance.ts +32 -0
  615. package/src/resources/extensions/gsd/queue-order.ts +3 -2
  616. package/src/resources/extensions/gsd/recovery-classification.ts +7 -0
  617. package/src/resources/extensions/gsd/roadmap-slices.ts +1 -1
  618. package/src/resources/extensions/gsd/safety/content-validator.ts +2 -1
  619. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +45 -1
  620. package/src/resources/extensions/gsd/service-tier.ts +2 -0
  621. package/src/resources/extensions/gsd/session-lock.ts +15 -13
  622. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +3 -0
  623. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +51 -0
  624. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +58 -14
  625. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +22 -2
  626. package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +105 -0
  627. package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +180 -0
  628. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +19 -6
  629. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +2 -2
  630. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +98 -26
  631. package/src/resources/extensions/gsd/state-reconciliation/index.ts +36 -3
  632. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +12 -0
  633. package/src/resources/extensions/gsd/state-reconciliation/types.ts +19 -0
  634. package/src/resources/extensions/gsd/state.ts +57 -15
  635. package/src/resources/extensions/gsd/sync-lock.ts +11 -20
  636. package/src/resources/extensions/gsd/tests/__fixtures__/flat-phase/.gsd/phases/01-foundation/01-01-PLAN.md +13 -0
  637. package/src/resources/extensions/gsd/tests/__fixtures__/flat-phase/.gsd/phases/01-foundation/01-ROADMAP.md +8 -0
  638. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/m001-basic/.gsd/milestones/M001/M001-ROADMAP.md +13 -0
  639. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/m001-basic/.gsd/milestones/M001/slices/S01/S01-PLAN.md +5 -0
  640. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/planning-flat-phases/.planning/PROJECT.md +1 -0
  641. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/planning-flat-phases/.planning/ROADMAP.md +5 -0
  642. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/planning-flat-phases/.planning/STATE.md +10 -0
  643. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/planning-flat-phases/.planning/phases/01-foundation/01-01-PLAN.md +13 -0
  644. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +322 -1
  645. package/src/resources/extensions/gsd/tests/auto-closeout-messaging.test.ts +71 -0
  646. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +68 -116
  647. package/src/resources/extensions/gsd/tests/auto-direct-dispatch-parse.test.ts +33 -0
  648. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +104 -0
  649. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +32 -1
  650. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +7 -2
  651. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +10 -0
  652. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +28 -22
  653. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +11 -2
  654. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +19 -2
  655. package/src/resources/extensions/gsd/tests/auto-verification.test.ts +36 -0
  656. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +17 -0
  657. package/src/resources/extensions/gsd/tests/blocker-placeholder-logs.test.ts +218 -0
  658. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +15 -11
  659. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +89 -0
  660. package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +37 -1
  661. package/src/resources/extensions/gsd/tests/commands-eval-review.test.ts +31 -30
  662. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +862 -0
  663. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +1 -1
  664. package/src/resources/extensions/gsd/tests/compat-health-line.test.ts +102 -0
  665. package/src/resources/extensions/gsd/tests/compat-marker-invalidation.test.ts +51 -0
  666. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +105 -0
  667. package/src/resources/extensions/gsd/tests/complete-milestone-prompt-rendering.test.ts +6 -2
  668. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +82 -0
  669. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -7
  670. package/src/resources/extensions/gsd/tests/complete-task.test.ts +7 -7
  671. package/src/resources/extensions/gsd/tests/consent-question.test.ts +45 -0
  672. package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +1 -0
  673. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +37 -0
  674. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +1 -1
  675. package/src/resources/extensions/gsd/tests/db-engine-logs.test.ts +207 -0
  676. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +63 -1
  677. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +49 -5
  678. package/src/resources/extensions/gsd/tests/discuss-cold-start-db-open.test.ts +10 -27
  679. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +20 -1
  680. package/src/resources/extensions/gsd/tests/dispatch-db-degradation-logs.test.ts +98 -0
  681. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +102 -0
  682. package/src/resources/extensions/gsd/tests/dispatch-logs.test.ts +103 -0
  683. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +38 -49
  684. package/src/resources/extensions/gsd/tests/dispatch-reactive-logs.test.ts +98 -0
  685. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +7 -0
  686. package/src/resources/extensions/gsd/tests/doctor-git-checks-autoresolve.test.ts +149 -0
  687. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +6 -4
  688. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +17 -10
  689. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +95 -0
  690. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +25 -0
  691. package/src/resources/extensions/gsd/tests/export-memory.test.ts +179 -0
  692. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +53 -0
  693. package/src/resources/extensions/gsd/tests/external-markdown-edit.test.ts +137 -0
  694. package/src/resources/extensions/gsd/tests/external-planning-edit.test.ts +199 -0
  695. package/src/resources/extensions/gsd/tests/fallback-continuation.test.ts +36 -0
  696. package/src/resources/extensions/gsd/tests/file-lock.test.ts +43 -0
  697. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +114 -0
  698. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +83 -0
  699. package/src/resources/extensions/gsd/tests/flat-phase-round-trip.test.ts +72 -0
  700. package/src/resources/extensions/gsd/tests/flat-phase-validation-integration.test.ts +120 -0
  701. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +74 -0
  702. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -1
  703. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +40 -7
  704. package/src/resources/extensions/gsd/tests/gsd-core-parity-routing.test.ts +183 -0
  705. package/src/resources/extensions/gsd/tests/guidance.test.ts +25 -0
  706. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +19 -11
  707. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +75 -0
  708. package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +6 -2
  709. package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +55 -0
  710. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +4 -3
  711. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +11 -7
  712. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -0
  713. package/src/resources/extensions/gsd/tests/knowledge-cold-start.test.ts +372 -0
  714. package/src/resources/extensions/gsd/tests/layout-policy.test.ts +59 -0
  715. package/src/resources/extensions/gsd/tests/loop.test.ts +60 -0
  716. package/src/resources/extensions/gsd/tests/markdown-renderer-parse-cache.test.ts +1 -1
  717. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +214 -82
  718. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +74 -1
  719. package/src/resources/extensions/gsd/tests/metrics-ledger-cap.test.ts +239 -0
  720. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +7 -2
  721. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +6 -1
  722. package/src/resources/extensions/gsd/tests/model-router.test.ts +343 -7
  723. package/src/resources/extensions/gsd/tests/notification-store.test.ts +23 -0
  724. package/src/resources/extensions/gsd/tests/notifications.test.ts +33 -0
  725. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +13 -1
  726. package/src/resources/extensions/gsd/tests/observability-validator-boundary.test.ts +194 -0
  727. package/src/resources/extensions/gsd/tests/orchestrator-legacy-parity.test.ts +1 -1
  728. package/src/resources/extensions/gsd/tests/orchestrator-logs.test.ts +339 -0
  729. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +52 -1
  730. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +91 -0
  731. package/src/resources/extensions/gsd/tests/plan-milestone-boundary-map-preservation.test.ts +7 -2
  732. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +7 -2
  733. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +9 -6
  734. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +58 -23
  735. package/src/resources/extensions/gsd/tests/plan-task.test.ts +4 -4
  736. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +19 -0
  737. package/src/resources/extensions/gsd/tests/planning-layout-detect.test.ts +84 -0
  738. package/src/resources/extensions/gsd/tests/planning-marker.test.ts +107 -0
  739. package/src/resources/extensions/gsd/tests/planning-projection-hook.test.ts +123 -0
  740. package/src/resources/extensions/gsd/tests/planning-round-trip-property.test.ts +164 -0
  741. package/src/resources/extensions/gsd/tests/planning-writer.test.ts +82 -0
  742. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +48 -1
  743. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -1
  744. package/src/resources/extensions/gsd/tests/prefs-missing-models-crash.test.ts +35 -4
  745. package/src/resources/extensions/gsd/tests/progress-strip-test-helpers.ts +79 -0
  746. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +2 -0
  747. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +16 -0
  748. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +15 -0
  749. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +107 -0
  750. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +22 -13
  751. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +9 -8
  752. package/src/resources/extensions/gsd/tests/reconcile-logs.test.ts +244 -0
  753. package/src/resources/extensions/gsd/tests/recovery-finalize-logs.test.ts +119 -0
  754. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +428 -0
  755. package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +25 -0
  756. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +79 -4
  757. package/src/resources/extensions/gsd/tests/replan-handler.test.ts +4 -4
  758. package/src/resources/extensions/gsd/tests/resume-missing-worktree-warning.test.ts +5 -5
  759. package/src/resources/extensions/gsd/tests/round-trip-property.test.ts +137 -0
  760. package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +28 -2
  761. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +68 -0
  762. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +3 -0
  763. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +1 -0
  764. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +7 -1
  765. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +155 -58
  766. package/src/resources/extensions/gsd/tests/stop-backtrack.test.ts +6 -2
  767. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +85 -0
  768. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +23 -0
  769. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +29 -1
  770. package/src/resources/extensions/gsd/tests/terminal-tool-surface-classification.test.ts +80 -0
  771. package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +1 -1
  772. package/src/resources/extensions/gsd/tests/tool-schema-model-fallback.test.ts +64 -0
  773. package/src/resources/extensions/gsd/tests/tool-search-shim.test.ts +71 -0
  774. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +26 -7
  775. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +23 -0
  776. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +40 -86
  777. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +44 -6
  778. package/src/resources/extensions/gsd/tests/undo.test.ts +39 -37
  779. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +22 -0
  780. package/src/resources/extensions/gsd/tests/unmerged-milestone-guard.test.ts +62 -0
  781. package/src/resources/extensions/gsd/tests/uok-audit.test.ts +194 -0
  782. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +72 -1
  783. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +9 -1
  784. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +51 -0
  785. package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +34 -6
  786. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +90 -0
  787. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +87 -0
  788. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +27 -0
  789. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +51 -0
  790. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +133 -0
  791. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +34 -8
  792. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +3 -4
  793. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +64 -8
  794. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +43 -3
  795. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +62 -0
  796. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +39 -18
  797. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +75 -3
  798. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +4 -1
  799. package/src/resources/extensions/gsd/tests/write-gate.test.ts +103 -0
  800. package/src/resources/extensions/gsd/tool-surface-readiness.ts +226 -16
  801. package/src/resources/extensions/gsd/tools/complete-milestone.ts +4 -7
  802. package/src/resources/extensions/gsd/tools/complete-slice.ts +12 -9
  803. package/src/resources/extensions/gsd/tools/complete-task.ts +15 -1
  804. package/src/resources/extensions/gsd/tools/exec-tool.ts +2 -118
  805. package/src/resources/extensions/gsd/tools/plan-slice.ts +1 -3
  806. package/src/resources/extensions/gsd/tools/plan-task.ts +17 -1
  807. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +9 -10
  808. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -13
  809. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +43 -4
  810. package/src/resources/extensions/gsd/triage-resolution.ts +14 -7
  811. package/src/resources/extensions/gsd/tui/render-kit.ts +56 -13
  812. package/src/resources/extensions/gsd/undo.ts +8 -9
  813. package/src/resources/extensions/gsd/unit-registry.ts +27 -3
  814. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +60 -1
  815. package/src/resources/extensions/gsd/validation-block-guard.ts +46 -0
  816. package/src/resources/extensions/gsd/visualizer-data.ts +55 -0
  817. package/src/resources/extensions/gsd/visualizer-views.ts +27 -2
  818. package/src/resources/extensions/gsd/workflow-logger.ts +5 -0
  819. package/src/resources/extensions/gsd/workflow-mcp.ts +12 -1
  820. package/src/resources/extensions/gsd/workflow-projections.ts +24 -4
  821. package/src/resources/extensions/gsd/worktree-command.ts +6 -6
  822. package/src/resources/extensions/gsd/worktree-health.ts +6 -3
  823. package/src/resources/extensions/gsd/worktree-manager.ts +122 -16
  824. package/src/resources/extensions/gsd/worktree-safety.ts +31 -11
  825. package/src/resources/extensions/gsd/worktree-shell-guard.ts +123 -0
  826. package/src/resources/extensions/mcp-client/manager.ts +3 -3
  827. package/src/resources/extensions/search-the-web/index.ts +45 -9
  828. package/src/resources/extensions/search-the-web/native-search.ts +16 -4
  829. package/src/resources/extensions/shared/gsd-browser-cli.ts +41 -2
  830. package/src/resources/extensions/subagent/index.ts +20 -15
  831. package/src/resources/extensions/subagent/tests/worktree-cwd.test.ts +57 -0
  832. package/src/resources/extensions/subagent/worktree-cwd.ts +35 -0
  833. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +0 -1
  834. /package/dist/web/standalone/.next/static/{2T9IOdiiM3o3gZ4UbPi8E → BTKtGFF1Y-hvVJEGhBRo9}/_buildManifest.js +0 -0
  835. /package/dist/web/standalone/.next/static/{2T9IOdiiM3o3gZ4UbPi8E → BTKtGFF1Y-hvVJEGhBRo9}/_ssgManifest.js +0 -0
@@ -935,13 +935,20 @@ export function renderKnowledgeView(
935
935
  ): string[] {
936
936
  const lines: string[] = [];
937
937
  const knowledge = data.knowledge;
938
+ const memories = data.memories;
938
939
 
939
- if (!knowledge.exists) {
940
+ if (!knowledge.exists && memories.entries.length === 0) {
940
941
  lines.push(th.fg("dim", "No KNOWLEDGE.md found"));
941
942
  return lines;
942
943
  }
943
944
 
944
- if (knowledge.rules.length === 0 && knowledge.patterns.length === 0 && knowledge.lessons.length === 0) {
945
+ if (
946
+ knowledge.exists &&
947
+ knowledge.rules.length === 0 &&
948
+ knowledge.patterns.length === 0 &&
949
+ knowledge.lessons.length === 0 &&
950
+ memories.entries.length === 0
951
+ ) {
945
952
  lines.push(th.fg("dim", "KNOWLEDGE.md exists but is empty"));
946
953
  return lines;
947
954
  }
@@ -985,6 +992,24 @@ export function renderKnowledgeView(
985
992
  lines.push("");
986
993
  }
987
994
 
995
+ if (memories.entries.length > 0) {
996
+ const countLabel = memories.totalCount > memories.entries.length
997
+ ? `${memories.entries.length}/${memories.totalCount}`
998
+ : `${memories.totalCount}`;
999
+ lines.push(th.fg("accent", th.bold(`Memories (${countLabel})`)));
1000
+ lines.push("");
1001
+ for (const memory of memories.entries) {
1002
+ const scope = memory.scope && memory.scope !== "project" ? ` ${th.fg("dim", `[${memory.scope}]`)}` : "";
1003
+ const tags = memory.tags.length > 0 ? ` ${th.fg("dim", `#${memory.tags.join(" #")}`)}` : "";
1004
+ lines.push(truncateToWidth(
1005
+ ` ${th.fg("accent", memory.id)} (${memory.category}, ${memory.confidence.toFixed(2)}, hits ${memory.hitCount})${scope}${tags}`,
1006
+ width,
1007
+ ));
1008
+ lines.push(truncateToWidth(` ${memory.content}`, width));
1009
+ }
1010
+ lines.push("");
1011
+ }
1012
+
988
1013
  return lines;
989
1014
  }
990
1015
 
@@ -109,6 +109,11 @@ export function setStderrLoggingEnabled(enabled: boolean): boolean {
109
109
  return previous;
110
110
  }
111
111
 
112
+ /** Whether GSD extension diagnostics may write directly to process.stderr. */
113
+ export function isGsdExtensionStderrEnabled(): boolean {
114
+ return _stderrEnabled;
115
+ }
116
+
112
117
  // ─── Public API ─────────────────────────────────────────────────────────
113
118
 
114
119
  /**
@@ -85,6 +85,8 @@ function lookupCommand(command: string, platform: NodeJS.Platform = process.plat
85
85
  }
86
86
  }
87
87
 
88
+ const gsdPiRepoRootCache = new Map<string, string | null>();
89
+
88
90
  function findGsdPiRepoRoot(startPath: string): string | null {
89
91
  let current: string;
90
92
  try {
@@ -93,15 +95,24 @@ function findGsdPiRepoRoot(startPath: string): string | null {
93
95
  current = resolve(startPath);
94
96
  }
95
97
 
98
+ const cacheKey = current;
99
+ if (gsdPiRepoRootCache.has(cacheKey)) {
100
+ return gsdPiRepoRootCache.get(cacheKey) ?? null;
101
+ }
102
+
96
103
  while (true) {
97
104
  const distCli = resolve(current, "packages", "mcp-server", "dist", "cli.js");
98
- if (existsSync(distCli)) return current;
105
+ if (existsSync(distCli)) {
106
+ gsdPiRepoRootCache.set(cacheKey, current);
107
+ return current;
108
+ }
99
109
 
100
110
  const parent = dirname(current);
101
111
  if (parent === current) break;
102
112
  current = parent;
103
113
  }
104
114
 
115
+ gsdPiRepoRootCache.set(cacheKey, null);
105
116
  return null;
106
117
  }
107
118
 
@@ -26,7 +26,7 @@ import { deriveState } from "./state.js";
26
26
  import type { GSDState } from "./types.js";
27
27
  import { renderPlanFromDb, renderRoadmapFromDb } from "./markdown-renderer.js";
28
28
  import { readManifest } from "./workflow-manifest.js";
29
- import { gsdRoot } from "./paths.js";
29
+ import { gsdRoot, resolveSliceFile, resolveMilestonePath, resolveSlicePath, gsdProjectionRoot } from "./paths.js";
30
30
 
31
31
  // ─── Helpers ─────────────────────────────────────────────────────────────
32
32
 
@@ -328,7 +328,23 @@ export function renderSummaryProjection(basePath: string, milestoneId: string, s
328
328
 
329
329
  const evidenceRows = getVerificationEvidence(milestoneId, sliceId, taskId);
330
330
  const content = renderSummaryContent(taskRow, sliceId, milestoneId, evidenceRows);
331
- const dir = join(basePath, ".gsd", "milestones", milestoneId, "slices", sliceId, "tasks");
331
+
332
+ // Layout-aware: avoid creating a milestones/ directory as a side effect for
333
+ // flat-phase projects. If milestonesDir() sees a freshly-created milestones/
334
+ // dir it treats the project as legacy, breaking all subsequent path resolution.
335
+ const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
336
+ const phaseDir = resolveMilestonePath(basePath, milestoneId);
337
+ let dir: string;
338
+ if (slicePath && phaseDir && slicePath !== phaseDir) {
339
+ // Legacy layout: slice has its own slices/SID/ subdir → tasks/ subdir
340
+ dir = join(slicePath, "tasks");
341
+ } else if (phaseDir) {
342
+ // Flat-phase: task summaries go in the phase dir (no tasks/ subdir needed)
343
+ dir = phaseDir;
344
+ } else {
345
+ // Fallback: legacy hardcoded path (milestone dir not on disk yet)
346
+ dir = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
347
+ }
332
348
  mkdirSync(dir, { recursive: true });
333
349
  atomicWriteSync(join(dir, `${taskId}-SUMMARY.md`), content);
334
350
  }
@@ -509,7 +525,9 @@ export async function regenerateIfMissing(
509
525
 
510
526
  switch (fileType) {
511
527
  case "PLAN":
512
- filePath = join(basePath, ".gsd", "milestones", milestoneId, "slices", sliceId, `${sliceId}-PLAN.md`);
528
+ // Use resolveSliceFile so both flat-phase and legacy layouts are detected.
529
+ // Falls back to "" (non-existent) when the file hasn't been rendered yet.
530
+ filePath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN") ?? "";
513
531
  break;
514
532
  case "ROADMAP":
515
533
  filePath = join(basePath, ".gsd", "milestones", milestoneId, `${milestoneId}-ROADMAP.md`);
@@ -562,7 +580,9 @@ export async function regenerateIfMissing(
562
580
  switch (fileType) {
563
581
  case "PLAN":
564
582
  await renderPlanFromDb(basePath, milestoneId, sliceId);
565
- return existsSync(filePath);
583
+ // Re-resolve after render: the rendered file may be at a different path
584
+ // from the pre-check (flat-phase vs legacy). resolveSliceFile finds it.
585
+ return !!(resolveSliceFile(basePath, milestoneId, sliceId, "PLAN"));
566
586
  case "ROADMAP":
567
587
  await renderRoadmapFromDb(basePath, milestoneId);
568
588
  return existsSync(filePath);
@@ -570,11 +570,11 @@ async function handleMerge(
570
570
  }
571
571
 
572
572
  // Gather merge context — full repo diff, not just .gsd/
573
- const diffSummary = diffWorktreeAll(basePath, name);
574
- const numstat = diffWorktreeNumstat(basePath, name);
575
- const gsdDiff = getWorktreeGSDDiff(basePath, name);
576
- const codeDiff = getWorktreeCodeDiff(basePath, name);
577
- const commitLog = getWorktreeLog(basePath, name);
573
+ const diffSummary = diffWorktreeAll(basePath, name, undefined, mainBranch);
574
+ const numstat = diffWorktreeNumstat(basePath, name, undefined, mainBranch);
575
+ const gsdDiff = getWorktreeGSDDiff(basePath, name, mainBranch);
576
+ const codeDiff = getWorktreeCodeDiff(basePath, name, mainBranch);
577
+ const commitLog = getWorktreeLog(basePath, name, mainBranch);
578
578
 
579
579
  const totalChanges = diffSummary.added.length + diffSummary.modified.length + diffSummary.removed.length;
580
580
  if (totalChanges === 0 && !commitLog.trim()) {
@@ -662,7 +662,7 @@ async function handleMerge(
662
662
  }
663
663
 
664
664
  try {
665
- mergeWorktreeToMain(basePath, name, commitMessage);
665
+ mergeWorktreeToMain(basePath, name, commitMessage, undefined, mainBranch);
666
666
  ctx.ui.notify(
667
667
  [
668
668
  `${CLR.ok("✓")} Merged ${CLR.name(name)} → ${CLR.branch(mainBranch)} ${CLR.muted("(deterministic squash)")}`,
@@ -54,14 +54,14 @@ const DEFAULT_STALE_DAYS = 14;
54
54
  * @param basePath — the main project root (not the worktree path)
55
55
  * @param wt — worktree info from listWorktrees()
56
56
  * @param staleDays — days without commits to consider stale (default: 14)
57
+ * @param mainBranch — pre-detected main branch for batched health checks
57
58
  */
58
59
  export function getWorktreeHealth(
59
60
  basePath: string,
60
61
  wt: WorktreeInfo,
61
62
  staleDays = DEFAULT_STALE_DAYS,
63
+ mainBranch = nativeDetectMainBranch(basePath),
62
64
  ): WorktreeHealthStatus {
63
- const mainBranch = nativeDetectMainBranch(basePath);
64
-
65
65
  // Merge status: is the worktree branch fully contained in main?
66
66
  let mergedIntoMain = false;
67
67
  try {
@@ -131,7 +131,10 @@ export function getAllWorktreeHealth(
131
131
  staleDays = DEFAULT_STALE_DAYS,
132
132
  ): WorktreeHealthStatus[] {
133
133
  const worktrees = listWorktrees(basePath);
134
- return worktrees.map(wt => getWorktreeHealth(basePath, wt, staleDays));
134
+ if (worktrees.length === 0) return [];
135
+
136
+ const mainBranch = nativeDetectMainBranch(basePath);
137
+ return worktrees.map(wt => getWorktreeHealth(basePath, wt, staleDays, mainBranch));
135
138
  }
136
139
 
137
140
  /**
@@ -19,7 +19,7 @@
19
19
  * 4. remove() — git worktree remove + branch cleanup
20
20
  */
21
21
 
22
- import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync } from "node:fs";
22
+ import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, statSync } from "node:fs";
23
23
  import { execFileSync } from "node:child_process";
24
24
  import { join, resolve, sep } from "node:path";
25
25
  import { GSDError, GSD_PARSE_ERROR, GSD_STALE_STATE, GSD_LOCK_HELD, GSD_GIT_ERROR, GSD_MERGE_CONFLICT } from "./errors.js";
@@ -49,6 +49,7 @@ import {
49
49
  normalizeWorktreePathForCompare,
50
50
  resolveWorktreeProjectRoot,
51
51
  } from "./worktree-root.js";
52
+ import { MILESTONE_ID_RE } from "./milestone-ids.js";
52
53
  import { canonicalWorktreesDir, worktreePathFor, worktreesDirs } from "./worktree-placement.js";
53
54
 
54
55
  // ─── Types ─────────────────────────────────────────────────────────────────
@@ -197,7 +198,96 @@ function isRegisteredGitWorktreeAtPath(basePath: string, wtPath: string): boolea
197
198
  }
198
199
  }
199
200
 
200
- function removeStaleWorktreeDirectory(wtPath: string, name: string): void {
201
+ /** True when `wtPath` has a git worktree checkout marker (`.git` file with gitdir pointer). */
202
+ export function isLiveGitWorktreeCheckout(wtPath: string): boolean {
203
+ const gitPath = join(wtPath, ".git");
204
+ if (!existsSync(gitPath)) return false;
205
+ try {
206
+ return lstatSync(gitPath).isFile();
207
+ } catch {
208
+ return false;
209
+ }
210
+ }
211
+
212
+ /** True when a worktree directory should count toward idle milestone residue detection. */
213
+ export function isMilestoneWorktreeResidueCandidate(basePath: string, wtPath: string): boolean {
214
+ return isRegisteredGitWorktreeAtPath(basePath, wtPath) || isLiveGitWorktreeCheckout(wtPath);
215
+ }
216
+
217
+ const EPHEMERAL_GHOST_WORKTREE_ENTRIES = new Set([".bg-shell", ".DS_Store"]);
218
+
219
+ function isEphemeralGhostWorktreeContents(dirPath: string): boolean {
220
+ let entries: string[];
221
+ try {
222
+ entries = readdirSync(dirPath);
223
+ } catch {
224
+ return false;
225
+ }
226
+ if (entries.length === 0) return true;
227
+ for (const entry of entries) {
228
+ if (EPHEMERAL_GHOST_WORKTREE_ENTRIES.has(entry)) continue;
229
+ if (entry === ".gsd") {
230
+ try {
231
+ const gsdEntries = readdirSync(join(dirPath, ".gsd"));
232
+ if (gsdEntries.length <= 1 && gsdEntries.every((e) => e === "doctor-history.jsonl")) {
233
+ continue;
234
+ }
235
+ } catch {
236
+ return false;
237
+ }
238
+ continue;
239
+ }
240
+ return false;
241
+ }
242
+ return true;
243
+ }
244
+
245
+ /**
246
+ * Remove milestone worktree directories that are not registered with git and
247
+ * contain only ephemeral runtime content (e.g. bg-shell manifests recreated
248
+ * after teardown). Returns removed directory paths.
249
+ */
250
+ export function pruneEphemeralGhostWorktreeDirectories(basePath: string): string[] {
251
+ const removed: string[] = [];
252
+ for (const container of allWorktreesDirs(basePath)) {
253
+ if (!existsSync(container)) continue;
254
+ let entries: string[];
255
+ try {
256
+ entries = readdirSync(container);
257
+ } catch {
258
+ continue;
259
+ }
260
+ for (const entry of entries) {
261
+ if (!MILESTONE_ID_RE.test(entry)) continue;
262
+ const fullPath = join(container, entry);
263
+ try {
264
+ if (!statSync(fullPath).isDirectory()) continue;
265
+ } catch {
266
+ continue;
267
+ }
268
+ if (isRegisteredGitWorktreeAtPath(basePath, fullPath)) continue;
269
+ if (isLiveGitWorktreeCheckout(fullPath)) continue;
270
+ if (!isEphemeralGhostWorktreeContents(fullPath)) continue;
271
+ try {
272
+ rmSync(fullPath, { recursive: true, force: true });
273
+ logWarning(
274
+ "reconcile",
275
+ `Removed ephemeral ghost worktree directory (not registered with git): ${fullPath}`,
276
+ { worktree: entry },
277
+ );
278
+ removed.push(fullPath);
279
+ } catch (err) {
280
+ logWarning(
281
+ "worktree",
282
+ `ghost worktree directory removal failed for ${fullPath}: ${err instanceof Error ? err.message : String(err)}`,
283
+ );
284
+ }
285
+ }
286
+ }
287
+ return removed;
288
+ }
289
+
290
+ export function removeStaleWorktreeDirectory(wtPath: string, name: string): void {
201
291
  logWarning(
202
292
  "reconcile",
203
293
  `Removing stale worktree directory (not registered with git): ${wtPath}`,
@@ -874,11 +964,11 @@ function parseDiffNameStatus(entries: { status: string; path: string }[]): Workt
874
964
  * Diff the .gsd/ directory between the worktree branch and main branch.
875
965
  * Returns a summary of added, modified, and removed GSD artifacts.
876
966
  */
877
- export function diffWorktreeGSD(basePath: string, name: string): WorktreeDiffSummary {
967
+ export function diffWorktreeGSD(basePath: string, name: string, mainBranchOverride?: string): WorktreeDiffSummary {
878
968
  basePath = normalizeBasePathForWorktreeOps(basePath);
879
969
 
880
970
  const branch = worktreeBranchName(name);
881
- const mainBranch = nativeDetectMainBranch(basePath);
971
+ const mainBranch = mainBranchOverride ?? nativeDetectMainBranch(basePath);
882
972
 
883
973
  const entries = nativeDiffNameStatus(basePath, mainBranch, branch, ".gsd/", true);
884
974
 
@@ -891,11 +981,16 @@ export function diffWorktreeGSD(basePath: string, name: string): WorktreeDiffSum
891
981
  * on main when the merge is applied. If both branches have identical
892
982
  * content, this correctly returns an empty diff.
893
983
  */
894
- export function diffWorktreeAll(basePath: string, name: string, branchOverride?: string): WorktreeDiffSummary {
984
+ export function diffWorktreeAll(
985
+ basePath: string,
986
+ name: string,
987
+ branchOverride?: string,
988
+ mainBranchOverride?: string,
989
+ ): WorktreeDiffSummary {
895
990
  basePath = normalizeBasePathForWorktreeOps(basePath);
896
991
 
897
992
  const branch = branchOverride ?? worktreeBranchName(name);
898
- const mainBranch = nativeDetectMainBranch(basePath);
993
+ const mainBranch = mainBranchOverride ?? nativeDetectMainBranch(basePath);
899
994
 
900
995
  const entries = nativeDiffNameStatus(basePath, mainBranch, branch);
901
996
 
@@ -906,11 +1001,16 @@ export function diffWorktreeAll(basePath: string, name: string, branchOverride?:
906
1001
  * Get per-file line addition/deletion stats for what will change on main.
907
1002
  * Uses direct diff (not merge-base) so the preview matches the actual merge outcome.
908
1003
  */
909
- export function diffWorktreeNumstat(basePath: string, name: string, branchOverride?: string): FileLineStat[] {
1004
+ export function diffWorktreeNumstat(
1005
+ basePath: string,
1006
+ name: string,
1007
+ branchOverride?: string,
1008
+ mainBranchOverride?: string,
1009
+ ): FileLineStat[] {
910
1010
  basePath = normalizeBasePathForWorktreeOps(basePath);
911
1011
 
912
1012
  const branch = branchOverride ?? worktreeBranchName(name);
913
- const mainBranch = nativeDetectMainBranch(basePath);
1013
+ const mainBranch = mainBranchOverride ?? nativeDetectMainBranch(basePath);
914
1014
 
915
1015
  const rawStats = nativeDiffNumstat(basePath, mainBranch, branch);
916
1016
 
@@ -926,11 +1026,11 @@ export function diffWorktreeNumstat(basePath: string, name: string, branchOverri
926
1026
  * Get the full diff content for .gsd/ between the worktree branch and main.
927
1027
  * Returns the raw unified diff for LLM consumption.
928
1028
  */
929
- export function getWorktreeGSDDiff(basePath: string, name: string): string {
1029
+ export function getWorktreeGSDDiff(basePath: string, name: string, mainBranchOverride?: string): string {
930
1030
  basePath = normalizeBasePathForWorktreeOps(basePath);
931
1031
 
932
1032
  const branch = worktreeBranchName(name);
933
- const mainBranch = nativeDetectMainBranch(basePath);
1033
+ const mainBranch = mainBranchOverride ?? nativeDetectMainBranch(basePath);
934
1034
 
935
1035
  return nativeDiffContent(basePath, mainBranch, branch, ".gsd/", undefined, true);
936
1036
  }
@@ -939,11 +1039,11 @@ export function getWorktreeGSDDiff(basePath: string, name: string): string {
939
1039
  * Get the full diff content for non-.gsd/ files between the worktree branch and main.
940
1040
  * Returns the raw unified diff for LLM consumption.
941
1041
  */
942
- export function getWorktreeCodeDiff(basePath: string, name: string): string {
1042
+ export function getWorktreeCodeDiff(basePath: string, name: string, mainBranchOverride?: string): string {
943
1043
  basePath = normalizeBasePathForWorktreeOps(basePath);
944
1044
 
945
1045
  const branch = worktreeBranchName(name);
946
- const mainBranch = nativeDetectMainBranch(basePath);
1046
+ const mainBranch = mainBranchOverride ?? nativeDetectMainBranch(basePath);
947
1047
 
948
1048
  return nativeDiffContent(basePath, mainBranch, branch, undefined, ".gsd/", true);
949
1049
  }
@@ -951,11 +1051,11 @@ export function getWorktreeCodeDiff(basePath: string, name: string): string {
951
1051
  /**
952
1052
  * Get commit log for the worktree branch since it diverged from main.
953
1053
  */
954
- export function getWorktreeLog(basePath: string, name: string): string {
1054
+ export function getWorktreeLog(basePath: string, name: string, mainBranchOverride?: string): string {
955
1055
  basePath = normalizeBasePathForWorktreeOps(basePath);
956
1056
 
957
1057
  const branch = worktreeBranchName(name);
958
- const mainBranch = nativeDetectMainBranch(basePath);
1058
+ const mainBranch = mainBranchOverride ?? nativeDetectMainBranch(basePath);
959
1059
 
960
1060
  const entries = nativeLogOneline(basePath, mainBranch, branch);
961
1061
 
@@ -967,11 +1067,17 @@ export function getWorktreeLog(basePath: string, name: string): string {
967
1067
  * Must be called from the main working tree (not the worktree itself).
968
1068
  * Returns the merge commit message.
969
1069
  */
970
- export function mergeWorktreeToMain(basePath: string, name: string, commitMessage: string, branchOverride?: string): string {
1070
+ export function mergeWorktreeToMain(
1071
+ basePath: string,
1072
+ name: string,
1073
+ commitMessage: string,
1074
+ branchOverride?: string,
1075
+ mainBranchOverride?: string,
1076
+ ): string {
971
1077
  basePath = normalizeBasePathForWorktreeOps(basePath);
972
1078
 
973
1079
  const branch = branchOverride ?? worktreeBranchName(name);
974
- const mainBranch = nativeDetectMainBranch(basePath);
1080
+ const mainBranch = mainBranchOverride ?? nativeDetectMainBranch(basePath);
975
1081
  const current = nativeGetCurrentBranch(basePath);
976
1082
 
977
1083
  if (current !== mainBranch) {
@@ -7,7 +7,7 @@ import { join, resolve } from "node:path";
7
7
 
8
8
  import { normalizeWorktreePathForCompare } from "./worktree-root.js";
9
9
  import { worktreesDirs } from "./worktree-placement.js";
10
- import { listWorktrees } from "./worktree-manager.js";
10
+ import { listWorktrees, removeStaleWorktreeDirectory } from "./worktree-manager.js";
11
11
  import { getCurrentBranch } from "./worktree.js";
12
12
 
13
13
  export type WorktreeSafetyWriteScope = "planning-only" | "source-writing";
@@ -74,6 +74,7 @@ export interface WorktreeSafetyDeps {
74
74
  lstatSync(path: string): Pick<Stats, "isFile">;
75
75
  listRegisteredWorktrees?(projectRoot: string): readonly RegisteredWorktree[];
76
76
  pruneRegisteredWorktrees?(projectRoot: string): void;
77
+ removeStaleWorktreeDirectory?(unitRoot: string, milestoneId: string): void;
77
78
  getCurrentBranch?(unitRoot: string): string;
78
79
  }
79
80
 
@@ -100,6 +101,7 @@ const defaultDeps: WorktreeSafetyDeps = {
100
101
  stdio: "pipe",
101
102
  });
102
103
  },
104
+ removeStaleWorktreeDirectory,
103
105
  getCurrentBranch,
104
106
  };
105
107
 
@@ -127,8 +129,6 @@ function errorMessage(error: unknown): string {
127
129
  export function createWorktreeSafetyModule(
128
130
  deps: WorktreeSafetyDeps = defaultDeps,
129
131
  ): WorktreeSafetyModule {
130
- const unregisteredRecoveryFailed = new Set<string>();
131
-
132
132
  return {
133
133
  validateUnitRoot(input) {
134
134
  if (input.writeScope === "planning-only") {
@@ -230,22 +230,17 @@ export function createWorktreeSafetyModule(
230
230
  );
231
231
  }
232
232
  if (registered && !registered.some((worktree) => samePath(worktree.path, unitRoot))) {
233
- const wasPreviouslyTracked = unregisteredRecoveryFailed.has(unitRoot);
234
233
  let attemptedPrune = false;
235
234
 
236
- if (!wasPreviouslyTracked && deps.pruneRegisteredWorktrees) {
235
+ if (deps.pruneRegisteredWorktrees) {
237
236
  attemptedPrune = true;
238
237
  try {
239
238
  deps.pruneRegisteredWorktrees(projectRoot);
240
239
  const rechecked = deps.listRegisteredWorktrees?.(projectRoot);
241
240
  if (rechecked?.some((worktree) => samePath(worktree.path, unitRoot))) {
242
- unregisteredRecoveryFailed.delete(unitRoot);
243
241
  registered = rechecked;
244
- } else {
245
- unregisteredRecoveryFailed.add(unitRoot);
246
242
  }
247
243
  } catch (error) {
248
- unregisteredRecoveryFailed.add(unitRoot);
249
244
  return failure(
250
245
  "worktree-git-probe-failed",
251
246
  `Unable to recover unregistered worktree root ${unitRoot}.`,
@@ -256,13 +251,38 @@ export function createWorktreeSafetyModule(
256
251
  }
257
252
 
258
253
  if (!registered?.some((worktree) => samePath(worktree.path, unitRoot))) {
254
+ // The directory exists on disk with a .git marker but git no longer
255
+ // tracks it as a worktree (e.g. a prior removeWorktree crash left the
256
+ // directory while `git worktree prune` cleaned the registry). Remove
257
+ // the orphaned directory — the same cleanup createWorktree performs —
258
+ // so the next dispatch recreates the milestone worktree from scratch
259
+ // instead of looping forever on worktree-unregistered (#803, #590).
260
+ if (deps.removeStaleWorktreeDirectory) {
261
+ try {
262
+ deps.removeStaleWorktreeDirectory(unitRoot, milestoneId);
263
+ return failure(
264
+ "worktree-missing",
265
+ `Worktree root ${unitRoot} was not registered with git; removed the orphaned directory so it can be recreated.`,
266
+ "Recreate the milestone worktree before dispatching the source-writing Unit. Auto-mode recreates it automatically on the next dispatch.",
267
+ { unitRoot, attemptedPrune, removedStaleDirectory: true },
268
+ );
269
+ } catch (error) {
270
+ return failure(
271
+ "worktree-unregistered",
272
+ `Worktree root ${unitRoot} is not registered with git worktree list and the orphaned directory could not be removed.`,
273
+ "Remove the orphaned worktree directory manually (it may be locked by another process), then recreate or re-register the milestone worktree before dispatching the source-writing Unit.",
274
+ { unitRoot, attemptedPrune, removedStaleDirectory: false, error: errorMessage(error) },
275
+ );
276
+ }
277
+ }
278
+
259
279
  return failure(
260
280
  "worktree-unregistered",
261
281
  `Worktree root ${unitRoot} is not registered with git worktree list.`,
262
- attemptedPrune || wasPreviouslyTracked
282
+ attemptedPrune
263
283
  ? "Worktree recovery was attempted but the root is still unregistered. Recreate or re-register the milestone worktree before dispatching the source-writing Unit."
264
284
  : "Run 'git worktree prune'. If still unregistered, recreate or re-register the milestone worktree before dispatching the source-writing Unit.",
265
- { unitRoot, attemptedPrune, trackedAsFailed: unregisteredRecoveryFailed.has(unitRoot) },
285
+ { unitRoot, attemptedPrune },
266
286
  );
267
287
  }
268
288
  }
@@ -0,0 +1,123 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Detect shell commands that reference the project root from a milestone worktree.
3
+
4
+ import { realpathSync } from "node:fs";
5
+ import path from "node:path";
6
+
7
+ import { projectRootFromWorktreePath } from "./worktree-root.js";
8
+
9
+ function escapeRegExp(value: string): string {
10
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11
+ }
12
+
13
+ function normalizeScanPath(value: string): string {
14
+ const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
15
+ return normalized.startsWith("/private/var/")
16
+ ? normalized.slice("/private".length)
17
+ : normalized;
18
+ }
19
+
20
+ function parseWorktreeBase(baseDir: string): { originalRoot: string; worktreeRoot: string } | null {
21
+ const normalizedBase = normalizeScanPath(baseDir);
22
+ const originalRoot = projectRootFromWorktreePath(normalizedBase);
23
+ if (!originalRoot) return null;
24
+ return { originalRoot, worktreeRoot: normalizedBase };
25
+ }
26
+
27
+ function pathInside(parent: string, target: string): boolean {
28
+ const parentWithSep = parent.endsWith("/") ? parent : `${parent}/`;
29
+ return target === parent || target.startsWith(parentWithSep);
30
+ }
31
+
32
+ function comparablePathVariants(value: string): string[] {
33
+ const variants = new Set<string>();
34
+ const normalized = normalizeScanPath(path.resolve(value));
35
+ variants.add(normalized);
36
+ try {
37
+ variants.add(normalizeScanPath(realpathSync(normalized)));
38
+ } catch {
39
+ // Nonexistent paths are still compared lexically.
40
+ }
41
+ if (normalized.startsWith("/private/var/")) {
42
+ variants.add(normalized.replace(/^\/private\/var\//, "/var/"));
43
+ } else if (normalized.startsWith("/var/")) {
44
+ variants.add(`/private${normalized}`);
45
+ }
46
+ return [...variants];
47
+ }
48
+
49
+ function pathInsideAny(parents: readonly string[], targets: readonly string[]): boolean {
50
+ return targets.some((target) => parents.some((parent) => pathInside(parent, target)));
51
+ }
52
+
53
+ function stripWrappingQuotes(value: string): string {
54
+ const trimmed = value.trim();
55
+ if (trimmed.length < 2) return trimmed;
56
+ const first = trimmed[0];
57
+ const last = trimmed[trimmed.length - 1];
58
+ if ((first === "'" || first === '"' || first === "`") && last === first) {
59
+ return trimmed.slice(1, -1).trim();
60
+ }
61
+ return trimmed;
62
+ }
63
+
64
+ function extractPathLikeValues(script: string): string[] {
65
+ const values: string[] = [];
66
+ const push = (candidate: string) => {
67
+ const cleaned = stripWrappingQuotes(candidate).trim();
68
+ if (!cleaned) return;
69
+ values.push(cleaned);
70
+ };
71
+ const pushQuotedLiterals = (source: string, depth = 0) => {
72
+ for (const match of source.matchAll(/(["'`])((?:\\.|(?!\1).)*)\1/g)) {
73
+ push(match[2]);
74
+ if (depth < 2 && /["'`]/.test(match[2])) {
75
+ pushQuotedLiterals(match[2], depth + 1);
76
+ }
77
+ }
78
+ };
79
+
80
+ for (const match of script.matchAll(/(?:^|[;\n\r]|\&\&|\|\|)\s*cd\s+([^\n\r;|&]+)/g)) {
81
+ push(match[1]);
82
+ }
83
+ for (const match of script.matchAll(/process\.chdir\(\s*([^\n\r;]+?)\s*\)/g)) {
84
+ push(match[1]);
85
+ pushQuotedLiterals(match[1]);
86
+ }
87
+ pushQuotedLiterals(script);
88
+ return values;
89
+ }
90
+
91
+ export function resolvesToOriginalRootOutsideWorktree(script: string, baseDir: string): boolean {
92
+ const parsed = parseWorktreeBase(baseDir);
93
+ if (!parsed) return false;
94
+
95
+ const normalizedWorktree = normalizeScanPath(path.resolve(parsed.worktreeRoot));
96
+ const normalizedOriginalRoot = normalizeScanPath(path.resolve(parsed.originalRoot));
97
+ const worktreeRoots = comparablePathVariants(normalizedWorktree);
98
+ const originalRoots = comparablePathVariants(normalizedOriginalRoot);
99
+ for (const value of extractPathLikeValues(script)) {
100
+ const resolved = comparablePathVariants(path.resolve(normalizedWorktree, value));
101
+ if (pathInsideAny(originalRoots, resolved) && !pathInsideAny(worktreeRoots, resolved)) {
102
+ return true;
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+
108
+ export function scriptReferencesOriginalRootFromWorktree(script: string, baseDir: string): boolean {
109
+ const parsed = parseWorktreeBase(baseDir);
110
+ if (!parsed) return false;
111
+ const normalizedScript = script.replace(/\\/g, "/");
112
+ return comparablePathVariants(parsed.originalRoot).some((originalRoot) => {
113
+ const originalRootPattern = new RegExp(
114
+ `${escapeRegExp(originalRoot)}(?=$|[\\s'"\\\`;)&|<>]|/(?!\\.gsd(?:-worktrees|/worktrees)(?:/|$)))`,
115
+ );
116
+ return originalRootPattern.test(normalizedScript);
117
+ });
118
+ }
119
+
120
+ export function bashReferencesProjectRootOutsideWorktree(script: string, baseDir: string): boolean {
121
+ return resolvesToOriginalRootOutsideWorktree(script, baseDir)
122
+ || scriptReferencesOriginalRootFromWorktree(script, baseDir);
123
+ }