@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.0-dev.5fc22c6f

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 (550) hide show
  1. package/README.md +11 -11
  2. package/dist/cli.js +17 -4
  3. package/dist/headless-answers.js +1 -1
  4. package/dist/headless-ui.d.ts +1 -1
  5. package/dist/headless-ui.js +1 -1
  6. package/dist/headless.js +1 -1
  7. package/dist/onboarding.js +11 -0
  8. package/dist/resources/.managed-resources-content-hash +1 -1
  9. package/dist/resources/GSD-WORKFLOW.md +20 -25
  10. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  11. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +61 -50
  12. package/dist/resources/extensions/cursor-cli/index.js +16 -0
  13. package/dist/resources/extensions/cursor-cli/models.js +63 -0
  14. package/dist/resources/extensions/cursor-cli/package.json +11 -0
  15. package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
  16. package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
  17. package/dist/resources/extensions/gsd/activity-log.js +4 -1
  18. package/dist/resources/extensions/gsd/artifact-verification.js +431 -0
  19. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  20. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  22. package/dist/resources/extensions/gsd/auto-budget.js +5 -1
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +32 -11
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
  26. package/dist/resources/extensions/gsd/auto-prompts.js +83 -25
  27. package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
  28. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  29. package/dist/resources/extensions/gsd/auto-start.js +4 -3
  30. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +7 -3
  31. package/dist/resources/extensions/gsd/auto-verification.js +5 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +38 -11
  33. package/dist/resources/extensions/gsd/auto.js +32 -10
  34. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +8 -4
  36. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  37. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +147 -23
  38. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +56 -36
  39. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +29 -5
  40. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
  41. package/dist/resources/extensions/gsd/codebase-generator.js +157 -19
  42. package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
  43. package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
  44. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +154 -2
  45. package/dist/resources/extensions/gsd/commands-usage.js +1 -1
  46. package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
  47. package/dist/resources/extensions/gsd/db/engine.js +4 -1
  48. package/dist/resources/extensions/gsd/db/queries.js +39 -0
  49. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
  50. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  51. package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
  52. package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
  53. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -4
  54. package/dist/resources/extensions/gsd/doctor-engine-checks.js +227 -5
  55. package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
  56. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
  57. package/dist/resources/extensions/gsd/doctor.js +93 -3
  58. package/dist/resources/extensions/gsd/exec-sandbox.js +14 -4
  59. package/dist/resources/extensions/gsd/flat-phase-migration.js +119 -23
  60. package/dist/resources/extensions/gsd/git-service.js +61 -8
  61. package/dist/resources/extensions/gsd/gitignore.js +4 -1
  62. package/dist/resources/extensions/gsd/guidance.js +1 -0
  63. package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
  64. package/dist/resources/extensions/gsd/guided-flow.js +40 -2
  65. package/dist/resources/extensions/gsd/json-persistence.js +20 -0
  66. package/dist/resources/extensions/gsd/key-manager.js +1 -0
  67. package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
  68. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  69. package/dist/resources/extensions/gsd/markdown-renderer.js +27 -15
  70. package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
  71. package/dist/resources/extensions/gsd/metrics.js +4 -4
  72. package/dist/resources/extensions/gsd/migrate-external.js +22 -5
  73. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  74. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  75. package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
  76. package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
  77. package/dist/resources/extensions/gsd/preferences-models.js +6 -4
  78. package/dist/resources/extensions/gsd/preferences-validation.js +25 -2
  79. package/dist/resources/extensions/gsd/preferences.js +29 -2
  80. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  81. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  82. package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
  83. package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
  84. package/dist/resources/extensions/gsd/repository-registry.js +6 -1
  85. package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
  86. package/dist/resources/extensions/gsd/safe-fs.js +23 -2
  87. package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
  88. package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
  89. package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
  90. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  91. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
  92. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  93. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  94. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  95. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  96. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  97. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
  98. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  99. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  100. package/dist/resources/extensions/gsd/state.js +12 -611
  101. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
  102. package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
  103. package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
  104. package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
  105. package/dist/resources/extensions/gsd/tools/plan-task.js +103 -12
  106. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
  107. package/dist/resources/extensions/gsd/undo.js +43 -6
  108. package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
  109. package/dist/resources/extensions/gsd/unit-registry.js +11 -3
  110. package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
  111. package/dist/resources/extensions/gsd/verification-gate.js +7 -0
  112. package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
  113. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  114. package/dist/resources/extensions/gsd/workspace.js +26 -8
  115. package/dist/resources/extensions/gsd/worktree-manager.js +140 -5
  116. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  117. package/dist/web/standalone/.next/BUILD_ID +1 -1
  118. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  119. package/dist/web/standalone/.next/build-manifest.json +3 -3
  120. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  121. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  122. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/index.html +1 -1
  142. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  144. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  145. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  150. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  151. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  154. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  155. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  156. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  157. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  158. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  159. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  160. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  161. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  162. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  163. package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
  164. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  165. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  166. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  167. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  168. package/dist/wizard.d.ts +8 -0
  169. package/dist/wizard.js +8 -1
  170. package/integrations/hermes/__init__.py +31 -0
  171. package/integrations/hermes/tests/test_directory_loader.py +37 -0
  172. package/package.json +8 -8
  173. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
  174. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
  175. package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
  176. package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
  177. package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
  178. package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
  179. package/packages/cloud-mcp-gateway/package.json +2 -2
  180. package/packages/contracts/package.json +1 -1
  181. package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
  182. package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
  183. package/packages/daemon/dist/cloud-runtime.js +25 -1
  184. package/packages/daemon/dist/cloud-runtime.js.map +1 -1
  185. package/packages/daemon/dist/cloud-runtime.test.js +51 -0
  186. package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
  187. package/packages/daemon/dist/message-batcher.d.ts +7 -0
  188. package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
  189. package/packages/daemon/dist/message-batcher.js +13 -0
  190. package/packages/daemon/dist/message-batcher.js.map +1 -1
  191. package/packages/daemon/dist/message-batcher.test.js +48 -0
  192. package/packages/daemon/dist/message-batcher.test.js.map +1 -1
  193. package/packages/daemon/package.json +5 -5
  194. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  195. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  196. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  197. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  198. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
  199. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  200. package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
  201. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  202. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  203. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  204. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  205. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  206. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  207. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  208. package/packages/gsd-agent-core/dist/index.js +2 -0
  209. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  210. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  211. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  212. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  213. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  214. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  215. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  216. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  217. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  218. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  219. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  220. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  221. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  222. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  223. package/packages/gsd-agent-core/package.json +5 -5
  224. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  225. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  226. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  227. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  228. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  229. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  230. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  231. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  232. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  233. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  234. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -841
  235. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  237. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  238. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  239. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  240. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  241. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  242. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  243. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  244. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  245. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  246. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +259 -0
  247. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  248. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  249. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  250. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  251. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  252. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  253. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  254. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  261. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  262. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  263. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  264. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  265. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  266. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  267. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  268. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  269. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  270. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  271. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  272. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
  273. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  274. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +24 -6
  275. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  276. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  277. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  278. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  279. package/packages/gsd-agent-modes/package.json +7 -7
  280. package/packages/mcp-server/dist/workflow-tools.js +1 -1
  281. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  282. package/packages/mcp-server/package.json +4 -4
  283. package/packages/native/package.json +1 -1
  284. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  285. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  286. package/packages/pi-agent-core/package.json +1 -1
  287. package/packages/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  288. package/packages/pi-ai/dist/env-api-keys.js +3 -0
  289. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  290. package/packages/pi-ai/dist/models.generated.d.ts +46 -0
  291. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  292. package/packages/pi-ai/dist/models.generated.js +38 -0
  293. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  294. package/packages/pi-ai/dist/types.d.ts +2 -2
  295. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  296. package/packages/pi-ai/dist/types.js.map +1 -1
  297. package/packages/pi-ai/package.json +1 -1
  298. package/packages/pi-coding-agent/README.md +3 -2
  299. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  301. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  303. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  305. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  307. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  308. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  309. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  310. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  311. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  312. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  313. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  314. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  315. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  316. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  317. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  318. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  319. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  320. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  321. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  323. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  324. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  325. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  328. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  329. package/packages/pi-coding-agent/package.json +7 -7
  330. package/packages/pi-tui/package.json +2 -2
  331. package/packages/rpc-client/dist/rpc-client.js +1 -1
  332. package/packages/rpc-client/dist/rpc-client.js.map +1 -1
  333. package/packages/rpc-client/package.json +2 -2
  334. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  335. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  336. package/pkg/dist/theme/theme-schema.js +1 -1
  337. package/pkg/dist/theme/theme-schema.js.map +1 -1
  338. package/pkg/dist/theme/theme.d.ts.map +1 -1
  339. package/pkg/dist/theme/theme.js +11 -7
  340. package/pkg/dist/theme/theme.js.map +1 -1
  341. package/pkg/package.json +1 -1
  342. package/scripts/link-workspace-packages.cjs +14 -4
  343. package/src/resources/GSD-WORKFLOW.md +20 -25
  344. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  345. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +67 -49
  346. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
  347. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +159 -0
  348. package/src/resources/extensions/cursor-cli/index.ts +18 -0
  349. package/src/resources/extensions/cursor-cli/models.ts +65 -0
  350. package/src/resources/extensions/cursor-cli/package.json +11 -0
  351. package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
  352. package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
  353. package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
  354. package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
  355. package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
  356. package/src/resources/extensions/gsd/activity-log.ts +4 -1
  357. package/src/resources/extensions/gsd/artifact-verification.ts +468 -0
  358. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  359. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  360. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
  361. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  362. package/src/resources/extensions/gsd/auto-budget.ts +12 -1
  363. package/src/resources/extensions/gsd/auto-dispatch.ts +34 -12
  364. package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
  365. package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
  366. package/src/resources/extensions/gsd/auto-prompts.ts +80 -25
  367. package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
  368. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  369. package/src/resources/extensions/gsd/auto-start.ts +4 -3
  370. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +7 -2
  371. package/src/resources/extensions/gsd/auto-verification.ts +5 -1
  372. package/src/resources/extensions/gsd/auto-worktree.ts +50 -11
  373. package/src/resources/extensions/gsd/auto.ts +36 -8
  374. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
  375. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +8 -4
  376. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  377. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +171 -23
  378. package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
  379. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +60 -37
  380. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +39 -5
  381. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
  382. package/src/resources/extensions/gsd/codebase-generator.ts +179 -18
  383. package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
  384. package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
  385. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +136 -2
  386. package/src/resources/extensions/gsd/commands-usage.ts +1 -1
  387. package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
  388. package/src/resources/extensions/gsd/db/engine.ts +8 -1
  389. package/src/resources/extensions/gsd/db/queries.ts +40 -0
  390. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
  391. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  392. package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
  393. package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
  394. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -4
  395. package/src/resources/extensions/gsd/doctor-engine-checks.ts +275 -5
  396. package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
  397. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
  398. package/src/resources/extensions/gsd/doctor-types.ts +8 -1
  399. package/src/resources/extensions/gsd/doctor.ts +95 -3
  400. package/src/resources/extensions/gsd/exec-sandbox.ts +13 -4
  401. package/src/resources/extensions/gsd/flat-phase-migration.ts +142 -22
  402. package/src/resources/extensions/gsd/git-service.ts +70 -9
  403. package/src/resources/extensions/gsd/gitignore.ts +4 -1
  404. package/src/resources/extensions/gsd/guidance.ts +2 -0
  405. package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
  406. package/src/resources/extensions/gsd/guided-flow.ts +45 -2
  407. package/src/resources/extensions/gsd/json-persistence.ts +20 -0
  408. package/src/resources/extensions/gsd/key-manager.ts +1 -0
  409. package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
  410. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  411. package/src/resources/extensions/gsd/markdown-renderer.ts +27 -17
  412. package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
  413. package/src/resources/extensions/gsd/metrics.ts +4 -4
  414. package/src/resources/extensions/gsd/migrate-external.ts +17 -4
  415. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  416. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  417. package/src/resources/extensions/gsd/model-router.ts +4 -5
  418. package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
  419. package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
  420. package/src/resources/extensions/gsd/preferences-models.ts +6 -3
  421. package/src/resources/extensions/gsd/preferences-validation.ts +28 -2
  422. package/src/resources/extensions/gsd/preferences.ts +38 -4
  423. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  424. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  425. package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
  426. package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
  427. package/src/resources/extensions/gsd/repository-registry.ts +7 -1
  428. package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
  429. package/src/resources/extensions/gsd/safe-fs.ts +22 -2
  430. package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
  431. package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
  432. package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
  433. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  434. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
  435. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  436. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  437. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  438. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  439. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  440. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
  441. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  442. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  443. package/src/resources/extensions/gsd/state.ts +32 -732
  444. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
  445. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  446. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
  447. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
  448. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
  449. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
  450. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
  451. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
  452. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
  453. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
  454. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
  455. package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
  456. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
  457. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
  458. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +8 -0
  459. package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
  460. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
  461. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +365 -0
  462. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  463. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
  464. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
  465. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
  466. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
  467. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
  468. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
  469. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
  470. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
  471. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +296 -2
  472. package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
  473. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
  474. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
  475. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +74 -2
  476. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
  477. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
  478. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
  479. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
  480. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
  481. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  482. package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
  483. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
  484. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
  485. package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
  486. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
  487. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
  488. package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
  489. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
  490. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  491. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
  492. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
  493. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
  494. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +27 -0
  495. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
  496. package/src/resources/extensions/gsd/tests/plan-task.test.ts +307 -1
  497. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
  498. package/src/resources/extensions/gsd/tests/preferences.test.ts +150 -0
  499. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +142 -0
  500. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  501. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
  502. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
  503. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
  504. package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
  505. package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
  506. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +378 -0
  507. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
  508. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
  509. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
  510. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
  511. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +105 -0
  512. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
  513. package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
  514. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
  515. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +203 -0
  516. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
  517. package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
  518. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
  519. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
  520. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +90 -0
  521. package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
  522. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
  523. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
  524. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
  525. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
  526. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +214 -6
  527. package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
  528. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  529. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +31 -1
  530. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
  531. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  532. package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
  533. package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
  534. package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
  535. package/src/resources/extensions/gsd/tools/plan-task.ts +135 -12
  536. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
  537. package/src/resources/extensions/gsd/undo.ts +47 -6
  538. package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
  539. package/src/resources/extensions/gsd/unit-registry.ts +11 -3
  540. package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
  541. package/src/resources/extensions/gsd/verification-gate.ts +8 -0
  542. package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
  543. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  544. package/src/resources/extensions/gsd/workspace.ts +42 -8
  545. package/src/resources/extensions/gsd/worktree-manager.ts +183 -5
  546. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  547. package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
  548. package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
  549. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_buildManifest.js +0 -0
  550. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_ssgManifest.js +0 -0
@@ -1,24 +1,31 @@
1
1
  /**
2
2
  * Tool-call loop guard.
3
3
  *
4
- * Detects when a model calls the same tool with identical arguments
5
- * repeatedly within a single agent turn. Works in both auto-mode and
6
- * interactive sessions by hooking into the `tool_call` event, which
7
- * fires before execution and can block the call.
4
+ * Detects when a model repeats tool calls within a single Agent Turn.
5
+ * Works in both auto-mode and interactive sessions by hooking into the
6
+ * native engine's `tool_call` event, which fires before execution and can
7
+ * block the call.
8
8
  *
9
- * The guard uses a sliding window: it tracks the last N tool signatures
10
- * and blocks when the same signature appears more than MAX_CONSECUTIVE
11
- * times in a row. Resets on each agent turn (session_start, agent_end)
12
- * and when a different tool call breaks the streak.
9
+ * The guard has two independent checks: a sliding window for identical
10
+ * tool signatures, and a per-tool-name cap for repeated calls with varied
11
+ * arguments. State resets at Agent Turn boundaries (session_start,
12
+ * agent_end) and the identical-signature streak also resets when a
13
+ * different tool call breaks the streak. Block messages instruct the model
14
+ * to stop tooling for the rest of that turn and answer in text.
13
15
  *
14
- * A second, independent check (#783 Brief C) tracks per-tool-name call
15
- * counts within a turn regardless of args. This catches improvisation
16
+ * The per-tool-name check (#783 Brief C) tracks call counts within a
17
+ * turn regardless of args, decaying after successful state-mutating tools.
18
+ * This catches improvisation
16
19
  * loops where the model attempts the same missing workflow tool through
17
20
  * varied surfaces (bash → `node -e` → CLI), each with a different
18
- * signature, so the identical-args streak never trips. Whichever guard
21
+ * signature, so the identical-args streak never trips, while allowing
22
+ * tool-heavy turns that are making file-mutation progress. Whichever guard
19
23
  * trips first blocks.
20
24
  */
21
25
  import { createHash } from "node:crypto";
26
+ import { INHERENTLY_REPEATABLE_TOOL_SET } from "./core-session-tools.js";
27
+ import { hasBrowserContractPrefix } from "../../shared/browser-contract.js";
28
+ import { canonicalToolName } from "../engine-hook-contract.js";
22
29
  const MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
23
30
  /** Interactive/user-facing tools where even 1 duplicate is confusing. */
24
31
  const STRICT_LOOP_TOOLS = new Set(["ask_user_questions"]);
@@ -35,32 +42,16 @@ const MAX_CONSECUTIVE_STRICT = 1;
35
42
  */
36
43
  const PER_TOOL_DEFAULT_CAP = 6;
37
44
  const PER_TOOL_REPEATABLE_CAP = 15;
38
- /**
39
- * Inherently-repeatable tools: called many times per turn in normal work
40
- * (reading/writing several files, running several commands, searching). These
41
- * get PER_TOOL_REPEATABLE_CAP rather than the default. Keep this list
42
- * conservative — a tool here can be invoked up to PER_TOOL_REPEATABLE_CAP times
43
- * per turn before the guard blocks.
44
- */
45
- const REPEATABLE_TOOLS = new Set([
46
- "read",
47
- "write",
48
- "edit",
49
- "multi_edit",
50
- "bash",
51
- "grep",
52
- "glob",
53
- "search-the-web",
54
- "fetch_page",
55
- "todo_write",
56
- "notebook_edit",
57
- ]);
45
+ const PER_TOOL_CAP_EXEMPT_TOOLS = new Set(["find", "glob", "grep", "ls", "read", "search_and_read"]);
46
+ const STATE_MUTATING_TOOL_SET = new Set(["edit", "write", "multi_edit", "notebook_edit"]);
58
47
  let consecutiveCount = 0;
59
48
  let lastSignature = "";
60
49
  let lastToolName = "";
61
50
  let enabled = true;
62
51
  /** Per-tool-name call counts within the current turn (#783 Brief C). */
63
52
  const perToolCounts = new Map();
53
+ let mutationEpoch = 0;
54
+ const perToolLastMutationEpoch = new Map();
64
55
  /** Hash tool name + args into a compact signature for comparison. */
65
56
  function hashToolCall(toolName, args) {
66
57
  const h = createHash("sha256");
@@ -84,7 +75,8 @@ function hashToolCall(toolName, args) {
84
75
  * 1. Identical-signature streak (MAX_CONSECUTIVE_IDENTICAL_CALLS, strict for
85
76
  * ask_user_questions).
86
77
  * 2. Per-tool-name cap (PER_TOOL_DEFAULT_CAP / PER_TOOL_REPEATABLE_CAP),
87
- * independent of args catches improvisation loops (#783).
78
+ * independent of args, reset after file-mutation progress — catches
79
+ * improvisation loops (#783).
88
80
  */
89
81
  export function checkToolCallLoop(toolName, args) {
90
82
  if (!enabled)
@@ -107,16 +99,31 @@ export function checkToolCallLoop(toolName, args) {
107
99
  block: true,
108
100
  reason: `Tool loop detected (identical args): ${toolName} called ${consecutiveCount} times ` +
109
101
  `with identical arguments. Blocking to prevent infinite loop. ` +
110
- `Try a different approach or modify your arguments.`,
102
+ `Do not retry this tool or call other tools this turn — stop and respond to the user in text.`,
111
103
  count: consecutiveCount,
112
104
  };
113
105
  }
114
106
  // ── Guard 2: per-tool-name cap, independent of args (#783 Brief C) ──
115
107
  // Catches improvisation loops where the same tool is invoked many times with
116
108
  // varied args (e.g. retrying a missing workflow tool via bash/node -e/CLI).
117
- const perToolCount = (perToolCounts.get(toolName) ?? 0) + 1;
109
+ const priorPerToolCount = (perToolLastMutationEpoch.get(toolName) ?? mutationEpoch) < mutationEpoch
110
+ ? 0
111
+ : (perToolCounts.get(toolName) ?? 0);
112
+ const perToolCount = priorPerToolCount + 1;
118
113
  perToolCounts.set(toolName, perToolCount);
119
- const perToolCap = REPEATABLE_TOOLS.has(toolName)
114
+ perToolLastMutationEpoch.set(toolName, mutationEpoch);
115
+ // Read-only navigation tools are normal context gathering; Guard 1 still
116
+ // catches true reread loops with identical arguments. Browser Automation
117
+ // Contract tools (browser_*) are the same shape: a browser-backed UAT makes
118
+ // many distinct-arg calls (read a message, count edits, inspect a card, …),
119
+ // so the arg-independent per-tool cap misfires on legitimate verification;
120
+ // Guard 1's identical-signature streak still catches a genuinely stuck
121
+ // browser loop.
122
+ if (PER_TOOL_CAP_EXEMPT_TOOLS.has(toolName) ||
123
+ hasBrowserContractPrefix(canonicalToolName(toolName))) {
124
+ return { block: false, count: consecutiveCount };
125
+ }
126
+ const perToolCap = INHERENTLY_REPEATABLE_TOOL_SET.has(toolName)
120
127
  ? PER_TOOL_REPEATABLE_CAP
121
128
  : PER_TOOL_DEFAULT_CAP;
122
129
  if (perToolCount > perToolCap) {
@@ -124,12 +131,21 @@ export function checkToolCallLoop(toolName, args) {
124
131
  block: true,
125
132
  reason: `Tool loop detected (repeated tool): ${toolName} called ${perToolCount} times ` +
126
133
  `this turn (cap ${perToolCap}). Blocking to prevent infinite loop. ` +
127
- `The tool may be unavailable or failing repeatedly try a different approach.`,
134
+ `The tool may be unavailable or failing repeatedly. ` +
135
+ `Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.`,
128
136
  count: perToolCount,
129
137
  };
130
138
  }
131
139
  return { block: false, count: consecutiveCount };
132
140
  }
141
+ /** Record successful mutation progress so Guard 2 can decay on the next count. */
142
+ export function recordToolCallLoopMutation(toolName) {
143
+ if (!enabled)
144
+ return;
145
+ if (!STATE_MUTATING_TOOL_SET.has(toolName))
146
+ return;
147
+ mutationEpoch++;
148
+ }
133
149
  /** Reset the guard state. Call at agent turn boundaries. */
134
150
  export function resetToolCallLoopGuard() {
135
151
  consecutiveCount = 0;
@@ -137,6 +153,8 @@ export function resetToolCallLoopGuard() {
137
153
  lastToolName = "";
138
154
  enabled = true;
139
155
  perToolCounts.clear();
156
+ mutationEpoch = 0;
157
+ perToolLastMutationEpoch.clear();
140
158
  }
141
159
  /** Disable the guard (e.g. during shutdown). */
142
160
  export function disableToolCallLoopGuard() {
@@ -145,6 +163,8 @@ export function disableToolCallLoopGuard() {
145
163
  lastSignature = "";
146
164
  lastToolName = "";
147
165
  perToolCounts.clear();
166
+ mutationEpoch = 0;
167
+ perToolLastMutationEpoch.clear();
148
168
  }
149
169
  /** Get current consecutive count for diagnostics. */
150
170
  export function getToolCallLoopCount() {
@@ -81,8 +81,18 @@ function createEmptyWriteGateState() {
81
81
  };
82
82
  }
83
83
  const writeGateStatesByBasePath = new Map();
84
+ /**
85
+ * Write-gate snapshots are project-scoped, not worktree-scoped. When auto-mode
86
+ * routes MCP tool writes to `.gsd-worktrees/<MID>/`, depth verification still
87
+ * lands in the authoritative project `.gsd/runtime/` tree (or external-state
88
+ * symlink target). Without this canonicalization, `loadWriteGateSnapshot(worktree)`
89
+ * sees an empty snapshot and CONTEXT saves loop forever (#M020 gate loop).
90
+ */
91
+ function resolveWriteGateSnapshotRoot(basePath) {
92
+ return resolve(resolveWorktreeProjectRoot(basePath));
93
+ }
84
94
  function writeGateStateKey(basePath) {
85
- return resolve(basePath);
95
+ return resolveWriteGateSnapshotRoot(basePath);
86
96
  }
87
97
  function getWriteGateState(basePath = process.cwd()) {
88
98
  const key = writeGateStateKey(basePath);
@@ -123,16 +133,17 @@ function shouldPersistWriteGateSnapshot(env = process.env) {
123
133
  return v !== "0" && v !== "false";
124
134
  }
125
135
  function writeGateSnapshotPath(basePath) {
126
- return join(basePath, ".gsd", "runtime", "write-gate-state.json");
136
+ return join(resolveWriteGateSnapshotRoot(basePath), ".gsd", "runtime", "write-gate-state.json");
127
137
  }
128
138
  function ensureWriteGateSnapshotDirectory(basePath) {
129
- const gsdPath = join(basePath, ".gsd");
139
+ const snapshotRoot = resolveWriteGateSnapshotRoot(basePath);
140
+ const gsdPath = join(snapshotRoot, ".gsd");
130
141
  if (!existsSync(gsdPath)) {
131
142
  try {
132
143
  const stat = lstatSync(gsdPath);
133
144
  if (stat.isSymbolicLink()) {
134
145
  const target = readlinkSync(gsdPath);
135
- mkdirSync(isAbsolute(target) ? target : resolve(basePath, target), { recursive: true });
146
+ mkdirSync(isAbsolute(target) ? target : resolve(snapshotRoot, target), { recursive: true });
136
147
  }
137
148
  }
138
149
  catch {
@@ -936,7 +947,7 @@ function allowedPlanningDispatchAgentsList() {
936
947
  return [...ALLOWED_PLANNING_DISPATCH_AGENTS].join(", ");
937
948
  }
938
949
  function allowsControlledSubagentDispatch(policy) {
939
- return ((policy.mode === "planning-dispatch" || policy.mode === "verification") &&
950
+ return ((policy.mode === "planning-dispatch" || policy.mode === "verification" || policy.mode === "workflow-only") &&
940
951
  Array.isArray(policy.allowedSubagents));
941
952
  }
942
953
  function warnMissingControlledDispatchAgentClasses(unitType, mode, toolName) {
@@ -964,6 +975,7 @@ function warnMissingControlledDispatchAgentClasses(unitType, mode, toolName) {
964
975
  const PLANNING_SAFE_TOOLS = new Set([
965
976
  "read", "grep", "find", "ls", "glob",
966
977
  "ask_user_questions",
978
+ "memory_query",
967
979
  "search-the-web", "resolve_library", "get_library_docs", "fetch_page",
968
980
  "search_and_read",
969
981
  ]);
@@ -1020,6 +1032,9 @@ function planningBlock(unitType, mode, what) {
1020
1032
  * → allows Bash for project verification commands, keeps
1021
1033
  * writes restricted to .gsd/, and permits subagent dispatch
1022
1034
  * only when the manifest declares allowedSubagents.
1035
+ * - "workflow-only"
1036
+ * → allows reads, GSD workflow tools, and declared read-only
1037
+ * subagents; blocks generic Bash and direct file writes.
1023
1038
  *
1024
1039
  * `pathOrCommand` is the file path for write/edit-shaped tools and the
1025
1040
  * shell command for bash. Other tools ignore this argument.
@@ -1090,6 +1105,15 @@ export function shouldBlockPlanningUnit(toolName, pathOrCommand, basePath, unitT
1090
1105
  }
1091
1106
  return planningBlock(unitType, policy.mode, "subagent dispatch is not permitted in planning units");
1092
1107
  }
1108
+ if (policy.mode === "workflow-only") {
1109
+ if (tool === "bash") {
1110
+ return planningBlock(unitType, policy.mode, `bash is not permitted; use the unit's dedicated GSD workflow tools for durable validation output`);
1111
+ }
1112
+ if (PLANNING_WRITE_TOOLS.has(tool)) {
1113
+ return planningBlock(unitType, policy.mode, `cannot ${tool} "${pathOrCommand}" — direct artifact writes are disabled; call the required GSD workflow tool instead`);
1114
+ }
1115
+ return planningBlock(unitType, policy.mode, `tool "${tool}" is not on the workflow-only allowlist`);
1116
+ }
1093
1117
  if (tool === "bash") {
1094
1118
  if (policy.mode === "verification") {
1095
1119
  if (BASH_VERIFICATION_RE.test(pathOrCommand) || BASH_READ_ONLY_RE.test(pathOrCommand))
@@ -4,7 +4,7 @@ import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join } from "node:path";
5
5
  import { getLatestAssessmentByScope, getMilestone, getMilestoneSlices, getPendingGates, getSliceTasks, insertAssessment, isDbAvailable, transaction, } from "./gsd-db.js";
6
6
  import { getWorkflowDatabasePath, refreshWorkflowDatabaseFromDisk, } from "./db-workspace.js";
7
- import { isClosedStatus } from "./status-guards.js";
7
+ import { isClosedStatus, isDeferredStatus } from "./status-guards.js";
8
8
  import { closeQualityGatesFromEvidence } from "./quality-gate-closure.js";
9
9
  import { insertMilestoneValidationGates } from "./milestone-validation-gates.js";
10
10
  import { relMilestoneFile, resolveSliceFile } from "./paths.js";
@@ -144,6 +144,8 @@ export function checkCloseoutConsistencyGate(milestoneId, options = {}) {
144
144
  });
145
145
  }
146
146
  for (const slice of slices) {
147
+ if (isDeferredStatus(slice.status))
148
+ continue;
147
149
  if (!isClosedStatus(slice.status)) {
148
150
  return blocked("slice-open", `Closeout consistency blocked for ${milestoneId}: slice ${slice.id} status is "${slice.status}".`);
149
151
  }
@@ -9,9 +9,11 @@
9
9
  */
10
10
  import { createHash } from "node:crypto";
11
11
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
12
- import { join, dirname, extname } from "node:path";
12
+ import { join, dirname, extname, relative, sep } from "node:path";
13
13
  import { execSync } from "node:child_process";
14
14
  import { gsdRoot } from "./paths.js";
15
+ import { createRepositoryRegistryFromPreferences, } from "./repository-registry.js";
16
+ import { loadEffectiveGSDPreferences } from "./preferences.js";
15
17
  // ─── Defaults ────────────────────────────────────────────────────────────────
16
18
  const DEFAULT_EXCLUDES = [
17
19
  // ── AI / tooling meta ──
@@ -144,6 +146,84 @@ function enumerateFiles(basePath, excludes, maxFiles) {
144
146
  const truncated = filtered.length > maxFiles;
145
147
  return { files: truncated ? filtered.slice(0, maxFiles) : filtered, truncated };
146
148
  }
149
+ /**
150
+ * Build a workspace-aware registry for parent mode, or null when the project is
151
+ * single-repo (no declared child repositories). Returns null so the caller falls
152
+ * back to the legacy single-root enumeration and produces byte-identical output.
153
+ */
154
+ function loadWorkspaceRegistry(basePath) {
155
+ const preferences = loadEffectiveGSDPreferences(basePath)?.preferences;
156
+ const workspace = preferences?.workspace;
157
+ const mode = workspace?.mode ?? "project";
158
+ // Parent mode is only meaningful with at least one declared child repo; the
159
+ // implicit "project" repo is always present, so require a declared non-project id.
160
+ const hasDeclaredChildRepo = workspace?.repositories
161
+ ? Object.keys(workspace.repositories).some((id) => id !== "project")
162
+ : false;
163
+ if (mode !== "parent" || !hasDeclaredChildRepo) {
164
+ return null;
165
+ }
166
+ return createRepositoryRegistryFromPreferences(basePath, preferences);
167
+ }
168
+ /** Stable key fragment for workspace-aware enumeration inputs (mode + declared repos). */
169
+ function workspaceEnumerationSignature(basePath) {
170
+ const registry = loadWorkspaceRegistry(basePath);
171
+ if (!registry)
172
+ return "single-root";
173
+ return JSON.stringify({
174
+ mode: registry.mode,
175
+ repositories: registry.repositories
176
+ .map((repo) => ({ id: repo.id, root: repo.root }))
177
+ .sort((a, b) => a.id.localeCompare(b.id)),
178
+ });
179
+ }
180
+ /**
181
+ * Enumerate tracked files across every declared repository in a parent workspace.
182
+ * Child-repo paths are rewritten to be workspace-relative (e.g. `frontend/src/x`)
183
+ * and tagged with their declaring repo id so the map can render repo-labelled
184
+ * sections. The maxFiles cap is applied across the union of all repositories.
185
+ */
186
+ function enumerateWorkspaceFiles(registry, excludes, maxFiles) {
187
+ const perRepo = [];
188
+ const seen = new Set();
189
+ let totalEligible = 0;
190
+ for (const repo of registry.repositories) {
191
+ const rawFiles = lsFiles(repo.root);
192
+ const repoPrefix = relative(registry.projectRoot, repo.root).split(sep).join("/");
193
+ const repoEntries = [];
194
+ for (const file of rawFiles) {
195
+ // Rewrite before exclusion so workspace-relative patterns (e.g. frontend/…) apply.
196
+ const workspacePath = repoPrefix ? `${repoPrefix}/${file}` : file;
197
+ if (shouldExclude(workspacePath, excludes))
198
+ continue;
199
+ if (seen.has(workspacePath))
200
+ continue;
201
+ seen.add(workspacePath);
202
+ totalEligible++;
203
+ repoEntries.push({ workspacePath, repoId: repo.id });
204
+ }
205
+ perRepo.push(repoEntries);
206
+ }
207
+ const files = [];
208
+ const repos = [];
209
+ const indices = new Array(perRepo.length).fill(0);
210
+ while (files.length < maxFiles) {
211
+ let progressed = false;
212
+ for (let i = 0; i < perRepo.length; i++) {
213
+ if (indices[i] < perRepo[i].length) {
214
+ const entry = perRepo[i][indices[i]++];
215
+ files.push(entry.workspacePath);
216
+ repos.push(entry.repoId);
217
+ progressed = true;
218
+ if (files.length >= maxFiles)
219
+ break;
220
+ }
221
+ }
222
+ if (!progressed)
223
+ break;
224
+ }
225
+ return { files, repos, truncated: totalEligible > files.length };
226
+ }
147
227
  function resolveGeneratorOptions(options) {
148
228
  const excludes = [...DEFAULT_EXCLUDES, ...(options?.excludePatterns ?? [])];
149
229
  const maxFiles = options?.maxFiles ?? DEFAULT_MAX_FILES;
@@ -159,38 +239,69 @@ function resolveGeneratorOptions(options) {
159
239
  }),
160
240
  };
161
241
  }
162
- function computeCodebaseFingerprint(files, resolved, truncated) {
242
+ function computeCodebaseFingerprint(files, resolved, truncated, repos) {
163
243
  return createHash("sha1")
164
244
  .update(JSON.stringify({
165
245
  files,
246
+ ...(repos ? { repos } : {}),
166
247
  truncated,
167
248
  optionSignature: resolved.optionSignature,
168
249
  }))
169
250
  .digest("hex");
170
251
  }
171
252
  // ─── Grouping ────────────────────────────────────────────────────────────────
172
- function groupByDirectory(files, descriptions, collapseThreshold) {
253
+ function groupByDirectory(files, descriptions, collapseThreshold, repos) {
173
254
  const dirMap = new Map();
174
- for (const file of files) {
255
+ for (let i = 0; i < files.length; i++) {
256
+ const file = files[i];
175
257
  const dir = dirname(file);
176
- const dirKey = dir === "." ? "" : dir;
177
- if (!dirMap.has(dirKey)) {
178
- dirMap.set(dirKey, []);
258
+ const dirPath = dir === "." ? "" : dir;
259
+ const repoId = repos?.[i];
260
+ const groupKey = repoId !== undefined ? `${repoId}\0${dirPath}` : dirPath;
261
+ if (!dirMap.has(groupKey)) {
262
+ dirMap.set(groupKey, []);
179
263
  }
180
- dirMap.get(dirKey).push({
264
+ dirMap.get(groupKey).push({
181
265
  path: file,
182
266
  description: descriptions.get(file) ?? "",
267
+ repo: repoId,
183
268
  });
184
269
  }
185
270
  const groups = [];
186
- const sortedDirs = [...dirMap.keys()].sort();
187
- for (const dir of sortedDirs) {
188
- const dirFiles = dirMap.get(dir);
271
+ const repoOrder = new Map();
272
+ if (repos) {
273
+ for (let i = 0; i < repos.length; i++) {
274
+ if (!repoOrder.has(repos[i])) {
275
+ repoOrder.set(repos[i], repoOrder.size);
276
+ }
277
+ }
278
+ }
279
+ const sortedDirs = [...dirMap.keys()].sort((a, b) => {
280
+ // Single-repo (project) mode must stay byte-identical to the pre-workspace
281
+ // output, which ordered directories with a bare `.sort()` (UTF-16 code-unit
282
+ // order, so uppercase sorts before lowercase). localeCompare would diverge
283
+ // for mixed-case names (e.g. "Zoo" before "apple" flips), so preserve
284
+ // code-unit ordering here; only the repo-partitioning key is added on top.
285
+ if (!repos)
286
+ return a < b ? -1 : a > b ? 1 : 0;
287
+ const repoA = dirMap.get(a)[0]?.repo ?? "";
288
+ const repoB = dirMap.get(b)[0]?.repo ?? "";
289
+ const orderA = repoOrder.get(repoA) ?? 0;
290
+ const orderB = repoOrder.get(repoB) ?? 0;
291
+ if (orderA !== orderB)
292
+ return orderA - orderB;
293
+ return a.localeCompare(b);
294
+ });
295
+ for (const groupKey of sortedDirs) {
296
+ const dirFiles = dirMap.get(groupKey);
189
297
  dirFiles.sort((a, b) => a.path.localeCompare(b.path));
298
+ const dirPath = repos ? groupKey.slice(groupKey.indexOf("\0") + 1) : groupKey;
190
299
  groups.push({
191
- path: dir,
300
+ path: dirPath,
192
301
  files: dirFiles,
193
302
  collapsed: dirFiles.length > collapseThreshold,
303
+ // Each group is scoped to one repo in workspace-aware mode.
304
+ repo: dirFiles[0]?.repo,
194
305
  });
195
306
  }
196
307
  return groups;
@@ -207,7 +318,18 @@ function renderCodebaseMap(groups, totalFiles, truncated, metadata) {
207
318
  lines.push(`Note: Truncated to first ${totalFiles} files. Run with higher --max-files to include all.`);
208
319
  }
209
320
  lines.push("");
321
+ let emittedRepo;
210
322
  for (const group of groups) {
323
+ // In a workspace-aware map, partition directories under their declaring
324
+ // repository. `## [repo-id]` headings are used (not `###`) so they never
325
+ // collide with the per-directory `### <dir>/` headings or the
326
+ // `parseCodebaseMap` list-item regexes. Groups are sorted by declaring
327
+ // repo (enumeration order) then directory path so each repo is contiguous.
328
+ if (group.repo && group.repo !== emittedRepo) {
329
+ emittedRepo = group.repo;
330
+ lines.push(`## [${group.repo}]`);
331
+ lines.push("");
332
+ }
211
333
  const heading = group.path || "(root)";
212
334
  lines.push(`### ${heading}/`);
213
335
  if (group.collapsed) {
@@ -250,13 +372,15 @@ function renderCodebaseMap(groups, totalFiles, truncated, metadata) {
250
372
  function buildCodebaseMap(basePath, resolved, existingDescriptions, enumerated) {
251
373
  const listed = enumerated ?? enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
252
374
  const descriptions = existingDescriptions ?? new Map();
253
- const groups = groupByDirectory(listed.files, descriptions, resolved.collapseThreshold);
375
+ const groups = groupByDirectory(listed.files, descriptions, resolved.collapseThreshold, listed.repos);
254
376
  const generatedAt = new Date().toISOString().split(".")[0] + "Z";
377
+ const repoIds = listed.repos ? Array.from(new Set(listed.repos)) : undefined;
255
378
  const metadata = {
256
379
  generatedAt,
257
- fingerprint: computeCodebaseFingerprint(listed.files, resolved, listed.truncated),
380
+ fingerprint: computeCodebaseFingerprint(listed.files, resolved, listed.truncated, listed.repos),
258
381
  fileCount: listed.files.length,
259
382
  truncated: listed.truncated,
383
+ ...(repoIds ? { repositories: repoIds } : {}),
260
384
  };
261
385
  const content = renderCodebaseMap(groups, listed.files.length, listed.truncated, metadata);
262
386
  return {
@@ -273,9 +397,21 @@ function buildCodebaseMap(basePath, resolved, existingDescriptions, enumerated)
273
397
  * Generate a fresh CODEBASE.md from scratch.
274
398
  * Preserves existing descriptions if `existingDescriptions` is provided.
275
399
  */
400
+ /**
401
+ * Resolve workspace-aware enumeration for parent mode, or undefined to fall
402
+ * back to the legacy single-root enumeration. Centralized so all three public
403
+ * entry points (generate/update/ensure) share one discovery path.
404
+ */
405
+ function resolveWorkspaceEnumeration(basePath, resolved) {
406
+ const registry = loadWorkspaceRegistry(basePath);
407
+ if (!registry)
408
+ return undefined;
409
+ return enumerateWorkspaceFiles(registry, resolved.excludes, resolved.maxFiles);
410
+ }
276
411
  export function generateCodebaseMap(basePath, options, existingDescriptions) {
277
412
  const resolved = resolveGeneratorOptions(options);
278
- return buildCodebaseMap(basePath, resolved, existingDescriptions);
413
+ const enumerated = resolveWorkspaceEnumeration(basePath, resolved);
414
+ return buildCodebaseMap(basePath, resolved, existingDescriptions, enumerated);
279
415
  }
280
416
  /**
281
417
  * Incremental update: re-scan files, preserve existing descriptions,
@@ -293,7 +429,8 @@ export function updateCodebaseMap(basePath, options) {
293
429
  const existingFiles = new Set(existingDescriptions.keys());
294
430
  // Generate new map preserving descriptions — reuse the returned file list
295
431
  // to avoid a second enumeration (prevents race between content and stats).
296
- const result = buildCodebaseMap(basePath, resolved, existingDescriptions);
432
+ const enumerated = resolveWorkspaceEnumeration(basePath, resolved);
433
+ const result = buildCodebaseMap(basePath, resolved, existingDescriptions, enumerated);
297
434
  const currentSet = new Set(result.files);
298
435
  // Count changes
299
436
  let added = 0;
@@ -326,7 +463,7 @@ function clearFreshnessCache(basePath) {
326
463
  }
327
464
  export function ensureCodebaseMapFresh(basePath, options, ensureOptions) {
328
465
  const resolved = resolveGeneratorOptions(options);
329
- const cacheKey = `${basePath}::${resolved.optionSignature}`;
466
+ const cacheKey = `${basePath}::${resolved.optionSignature}::${workspaceEnumerationSignature(basePath)}`;
330
467
  const ttlMs = ensureOptions?.ttlMs ?? DEFAULT_REFRESH_TTL_MS;
331
468
  const force = ensureOptions?.force === true;
332
469
  const now = Date.now();
@@ -338,8 +475,9 @@ export function ensureCodebaseMapFresh(basePath, options, ensureOptions) {
338
475
  }
339
476
  }
340
477
  const existing = readCodebaseMap(basePath);
341
- const listed = enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
342
- const fingerprint = computeCodebaseFingerprint(listed.files, resolved, listed.truncated);
478
+ const listed = resolveWorkspaceEnumeration(basePath, resolved)
479
+ ?? enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
480
+ const fingerprint = computeCodebaseFingerprint(listed.files, resolved, listed.truncated, listed.repos);
343
481
  const cacheAndReturn = (result) => {
344
482
  freshnessCache.set(cacheKey, { checkedAt: now, result });
345
483
  return result;
@@ -190,7 +190,7 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
190
190
  }
191
191
  return true;
192
192
  }
193
- await pauseAuto(ctx, pi);
193
+ await pauseAuto(ctx, pi, undefined, { abortActiveTurn: true });
194
194
  return true;
195
195
  }
196
196
  if (trimmed === "rate" || trimmed.startsWith("rate ")) {
@@ -1,6 +1,8 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { computeProgressScore, formatProgressLine } from "../../progress-score.js";
3
- import { getGlobalGSDPreferencesPath, getProjectGSDPreferencesPath, modelIdsForProfileResolution, resolveProfileAnchorProvider, resolveDisabledModelProvidersFromPreferences } from "../../preferences.js";
3
+ import { isRepositoryDirty } from "../../git-service.js";
4
+ import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath, getProjectGSDPreferencesPath, modelIdsForProfileResolution, resolveProfileAnchorProvider, resolveDisabledModelProvidersFromPreferences } from "../../preferences.js";
5
+ import { createRepositoryRegistryFromPreferences } from "../../repository-registry.js";
4
6
  import { ensurePreferencesFile, handlePrefs, handlePrefsMode, handlePrefsWizard, handleLanguage } from "../../commands-prefs-wizard.js";
5
7
  import { runEnvironmentChecks } from "../../doctor-environment.js";
6
8
  import { deriveState } from "../../state.js";
@@ -206,7 +208,7 @@ export async function handleStatus(ctx) {
206
208
  },
207
209
  });
208
210
  if (result === undefined) {
209
- ctx.ui.notify(formatTextStatus(state), "info");
211
+ ctx.ui.notify(formatTextStatus(state, basePath), "info");
210
212
  }
211
213
  }
212
214
  export async function fireStatusViaCommand(ctx) {
@@ -539,7 +541,8 @@ export async function handleCoreCommand(trimmed, ctx, pi) {
539
541
  }
540
542
  return false;
541
543
  }
542
- export function formatTextStatus(state) {
544
+ export function formatTextStatus(state, basePath) {
545
+ const root = basePath ?? projectRoot();
543
546
  const lines = ["GSD Status\n"];
544
547
  lines.push(formatProgressLine(computeProgressScore()));
545
548
  lines.push("");
@@ -582,7 +585,7 @@ export function formatTextStatus(state) {
582
585
  lines.push(` ${icon} ${milestone.id}: ${milestone.title} (${milestone.status})`);
583
586
  }
584
587
  }
585
- const envResults = runEnvironmentChecks(projectRoot());
588
+ const envResults = runEnvironmentChecks(root);
586
589
  const envIssues = envResults.filter((result) => result.status !== "ok");
587
590
  if (envIssues.length > 0) {
588
591
  lines.push("");
@@ -591,5 +594,38 @@ export function formatTextStatus(state) {
591
594
  lines.push(` ${issue.status === "error" ? "✗" : "⚠"} ${issue.message}`);
592
595
  }
593
596
  }
597
+ // Parent-workspace per-repository git health (#818). No-op for single-repo
598
+ // projects; surfaces which declared child repos have uncommitted changes.
599
+ const repoBlock = buildWorkspaceRepoStatusBlock(root);
600
+ if (repoBlock) {
601
+ lines.push("");
602
+ lines.push("Repositories:");
603
+ lines.push(repoBlock);
604
+ }
594
605
  return lines.join("\n");
595
606
  }
607
+ /**
608
+ * Build a per-repository dirty/clean summary for parent-workspace status.
609
+ * Returns "" for single-repo (project-mode) projects so the status output is
610
+ * unchanged; otherwise one line per declared child repository.
611
+ */
612
+ function buildWorkspaceRepoStatusBlock(basePath) {
613
+ let registry;
614
+ try {
615
+ registry = createRepositoryRegistryFromPreferences(basePath, loadEffectiveGSDPreferences(basePath)?.preferences);
616
+ }
617
+ catch {
618
+ return "";
619
+ }
620
+ if (registry.mode !== "parent")
621
+ return "";
622
+ const childRepos = registry.repositories.filter((repo) => repo.id !== "project");
623
+ if (childRepos.length === 0)
624
+ return "";
625
+ return childRepos
626
+ .map((repo) => {
627
+ const dirty = isRepositoryDirty(repo.root);
628
+ return ` ${dirty ? "✗" : "✓"} ${repo.id}${repo.role ? ` — ${repo.role}` : ""}${dirty ? " (uncommitted changes)" : " (clean)"}`;
629
+ })
630
+ .join("\n");
631
+ }