@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
@@ -10,10 +10,15 @@
10
10
 
11
11
  import { createHash } from "node:crypto";
12
12
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
13
- import { join, dirname, extname } from "node:path";
13
+ import { join, dirname, extname, relative, sep } from "node:path";
14
14
 
15
15
  import { execSync } from "node:child_process";
16
16
  import { gsdRoot } from "./paths.js";
17
+ import {
18
+ createRepositoryRegistryFromPreferences,
19
+ type RepositoryRegistry,
20
+ } from "./repository-registry.js";
21
+ import { loadEffectiveGSDPreferences } from "./preferences.js";
17
22
 
18
23
  // ─── Types ───────────────────────────────────────────────────────────────────
19
24
 
@@ -28,6 +33,8 @@ export interface CodebaseMapMetadata {
28
33
  fingerprint: string;
29
34
  fileCount: number;
30
35
  truncated: boolean;
36
+ /** Repo ids whose files appear in a workspace-aware map (parent mode only). */
37
+ repositories?: string[];
31
38
  }
32
39
 
33
40
  export interface EnsureCodebaseMapOptions {
@@ -48,12 +55,16 @@ export interface EnsureCodebaseMapResult {
48
55
  interface FileEntry {
49
56
  path: string;
50
57
  description: string;
58
+ /** Declaring repo id for workspace-aware maps (parent mode); undefined otherwise. */
59
+ repo?: string;
51
60
  }
52
61
 
53
62
  interface DirectoryGroup {
54
63
  path: string;
55
64
  files: FileEntry[];
56
65
  collapsed: boolean;
66
+ /** Repo id this group belongs to for workspace-aware maps; undefined otherwise. */
67
+ repo?: string;
57
68
  }
58
69
 
59
70
  interface ResolvedCodebaseMapOptions {
@@ -66,6 +77,8 @@ interface ResolvedCodebaseMapOptions {
66
77
  interface EnumeratedFiles {
67
78
  files: string[];
68
79
  truncated: boolean;
80
+ /** Per-file repo labels aligned with `files` (workspace-aware maps only). */
81
+ repos?: string[];
69
82
  }
70
83
 
71
84
  // ─── Defaults ────────────────────────────────────────────────────────────────
@@ -209,13 +222,99 @@ function lsFiles(basePath: string): string[] {
209
222
  * Enumerate tracked files, applying exclusions and the maxFiles cap.
210
223
  * Returns both the file list and whether truncation occurred.
211
224
  */
212
- function enumerateFiles(basePath: string, excludes: string[], maxFiles: number): { files: string[]; truncated: boolean } {
225
+ function enumerateFiles(basePath: string, excludes: string[], maxFiles: number): EnumeratedFiles {
213
226
  const allFiles = lsFiles(basePath);
214
227
  const filtered = allFiles.filter((f) => !shouldExclude(f, excludes));
215
228
  const truncated = filtered.length > maxFiles;
216
229
  return { files: truncated ? filtered.slice(0, maxFiles) : filtered, truncated };
217
230
  }
218
231
 
232
+ /**
233
+ * Build a workspace-aware registry for parent mode, or null when the project is
234
+ * single-repo (no declared child repositories). Returns null so the caller falls
235
+ * back to the legacy single-root enumeration and produces byte-identical output.
236
+ */
237
+ function loadWorkspaceRegistry(basePath: string): RepositoryRegistry | null {
238
+ const preferences = loadEffectiveGSDPreferences(basePath)?.preferences;
239
+ const workspace = preferences?.workspace;
240
+ const mode = workspace?.mode ?? "project";
241
+ // Parent mode is only meaningful with at least one declared child repo; the
242
+ // implicit "project" repo is always present, so require a declared non-project id.
243
+ const hasDeclaredChildRepo = workspace?.repositories
244
+ ? Object.keys(workspace.repositories).some((id) => id !== "project")
245
+ : false;
246
+ if (mode !== "parent" || !hasDeclaredChildRepo) {
247
+ return null;
248
+ }
249
+ return createRepositoryRegistryFromPreferences(basePath, preferences);
250
+ }
251
+
252
+ /** Stable key fragment for workspace-aware enumeration inputs (mode + declared repos). */
253
+ function workspaceEnumerationSignature(basePath: string): string {
254
+ const registry = loadWorkspaceRegistry(basePath);
255
+ if (!registry) return "single-root";
256
+ return JSON.stringify({
257
+ mode: registry.mode,
258
+ repositories: registry.repositories
259
+ .map((repo) => ({ id: repo.id, root: repo.root }))
260
+ .sort((a, b) => a.id.localeCompare(b.id)),
261
+ });
262
+ }
263
+
264
+ /**
265
+ * Enumerate tracked files across every declared repository in a parent workspace.
266
+ * Child-repo paths are rewritten to be workspace-relative (e.g. `frontend/src/x`)
267
+ * and tagged with their declaring repo id so the map can render repo-labelled
268
+ * sections. The maxFiles cap is applied across the union of all repositories.
269
+ */
270
+ function enumerateWorkspaceFiles(
271
+ registry: RepositoryRegistry,
272
+ excludes: string[],
273
+ maxFiles: number,
274
+ ): EnumeratedFiles {
275
+ type WorkspaceEntry = { workspacePath: string; repoId: string };
276
+ const perRepo: WorkspaceEntry[][] = [];
277
+ const seen = new Set<string>();
278
+ let totalEligible = 0;
279
+
280
+ for (const repo of registry.repositories) {
281
+ const rawFiles = lsFiles(repo.root);
282
+ const repoPrefix = relative(registry.projectRoot, repo.root).split(sep).join("/");
283
+ const repoEntries: WorkspaceEntry[] = [];
284
+
285
+ for (const file of rawFiles) {
286
+ // Rewrite before exclusion so workspace-relative patterns (e.g. frontend/…) apply.
287
+ const workspacePath = repoPrefix ? `${repoPrefix}/${file}` : file;
288
+ if (shouldExclude(workspacePath, excludes)) continue;
289
+ if (seen.has(workspacePath)) continue;
290
+ seen.add(workspacePath);
291
+ totalEligible++;
292
+ repoEntries.push({ workspacePath, repoId: repo.id });
293
+ }
294
+ perRepo.push(repoEntries);
295
+ }
296
+
297
+ const files: string[] = [];
298
+ const repos: string[] = [];
299
+ const indices = new Array(perRepo.length).fill(0);
300
+
301
+ while (files.length < maxFiles) {
302
+ let progressed = false;
303
+ for (let i = 0; i < perRepo.length; i++) {
304
+ if (indices[i] < perRepo[i].length) {
305
+ const entry = perRepo[i][indices[i]++];
306
+ files.push(entry.workspacePath);
307
+ repos.push(entry.repoId);
308
+ progressed = true;
309
+ if (files.length >= maxFiles) break;
310
+ }
311
+ }
312
+ if (!progressed) break;
313
+ }
314
+
315
+ return { files, repos, truncated: totalEligible > files.length };
316
+ }
317
+
219
318
  function resolveGeneratorOptions(options?: CodebaseMapOptions): ResolvedCodebaseMapOptions {
220
319
  const excludes = [...DEFAULT_EXCLUDES, ...(options?.excludePatterns ?? [])];
221
320
  const maxFiles = options?.maxFiles ?? DEFAULT_MAX_FILES;
@@ -236,10 +335,12 @@ function computeCodebaseFingerprint(
236
335
  files: string[],
237
336
  resolved: ResolvedCodebaseMapOptions,
238
337
  truncated: boolean,
338
+ repos?: string[],
239
339
  ): string {
240
340
  return createHash("sha1")
241
341
  .update(JSON.stringify({
242
342
  files,
343
+ ...(repos ? { repos } : {}),
243
344
  truncated,
244
345
  optionSignature: resolved.optionSignature,
245
346
  }))
@@ -252,32 +353,61 @@ function groupByDirectory(
252
353
  files: string[],
253
354
  descriptions: Map<string, string>,
254
355
  collapseThreshold: number,
356
+ repos?: string[],
255
357
  ): DirectoryGroup[] {
256
358
  const dirMap = new Map<string, FileEntry[]>();
257
359
 
258
- for (const file of files) {
360
+ for (let i = 0; i < files.length; i++) {
361
+ const file = files[i];
259
362
  const dir = dirname(file);
260
- const dirKey = dir === "." ? "" : dir;
261
- if (!dirMap.has(dirKey)) {
262
- dirMap.set(dirKey, []);
363
+ const dirPath = dir === "." ? "" : dir;
364
+ const repoId = repos?.[i];
365
+ const groupKey = repoId !== undefined ? `${repoId}\0${dirPath}` : dirPath;
366
+ if (!dirMap.has(groupKey)) {
367
+ dirMap.set(groupKey, []);
263
368
  }
264
- dirMap.get(dirKey)!.push({
369
+ dirMap.get(groupKey)!.push({
265
370
  path: file,
266
371
  description: descriptions.get(file) ?? "",
372
+ repo: repoId,
267
373
  });
268
374
  }
269
375
 
270
376
  const groups: DirectoryGroup[] = [];
271
- const sortedDirs = [...dirMap.keys()].sort();
377
+ const repoOrder = new Map<string, number>();
378
+ if (repos) {
379
+ for (let i = 0; i < repos.length; i++) {
380
+ if (!repoOrder.has(repos[i])) {
381
+ repoOrder.set(repos[i], repoOrder.size);
382
+ }
383
+ }
384
+ }
385
+ const sortedDirs = [...dirMap.keys()].sort((a, b) => {
386
+ // Single-repo (project) mode must stay byte-identical to the pre-workspace
387
+ // output, which ordered directories with a bare `.sort()` (UTF-16 code-unit
388
+ // order, so uppercase sorts before lowercase). localeCompare would diverge
389
+ // for mixed-case names (e.g. "Zoo" before "apple" flips), so preserve
390
+ // code-unit ordering here; only the repo-partitioning key is added on top.
391
+ if (!repos) return a < b ? -1 : a > b ? 1 : 0;
392
+ const repoA = dirMap.get(a)![0]?.repo ?? "";
393
+ const repoB = dirMap.get(b)![0]?.repo ?? "";
394
+ const orderA = repoOrder.get(repoA) ?? 0;
395
+ const orderB = repoOrder.get(repoB) ?? 0;
396
+ if (orderA !== orderB) return orderA - orderB;
397
+ return a.localeCompare(b);
398
+ });
272
399
 
273
- for (const dir of sortedDirs) {
274
- const dirFiles = dirMap.get(dir)!;
400
+ for (const groupKey of sortedDirs) {
401
+ const dirFiles = dirMap.get(groupKey)!;
275
402
  dirFiles.sort((a, b) => a.path.localeCompare(b.path));
403
+ const dirPath = repos ? groupKey.slice(groupKey.indexOf("\0") + 1) : groupKey;
276
404
 
277
405
  groups.push({
278
- path: dir,
406
+ path: dirPath,
279
407
  files: dirFiles,
280
408
  collapsed: dirFiles.length > collapseThreshold,
409
+ // Each group is scoped to one repo in workspace-aware mode.
410
+ repo: dirFiles[0]?.repo,
281
411
  });
282
412
  }
283
413
 
@@ -304,7 +434,19 @@ function renderCodebaseMap(
304
434
  }
305
435
  lines.push("");
306
436
 
437
+ let emittedRepo: string | undefined;
307
438
  for (const group of groups) {
439
+ // In a workspace-aware map, partition directories under their declaring
440
+ // repository. `## [repo-id]` headings are used (not `###`) so they never
441
+ // collide with the per-directory `### <dir>/` headings or the
442
+ // `parseCodebaseMap` list-item regexes. Groups are sorted by declaring
443
+ // repo (enumeration order) then directory path so each repo is contiguous.
444
+ if (group.repo && group.repo !== emittedRepo) {
445
+ emittedRepo = group.repo;
446
+ lines.push(`## [${group.repo}]`);
447
+ lines.push("");
448
+ }
449
+
308
450
  const heading = group.path || "(root)";
309
451
  lines.push(`### ${heading}/`);
310
452
 
@@ -361,13 +503,15 @@ function buildCodebaseMap(
361
503
  } {
362
504
  const listed = enumerated ?? enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
363
505
  const descriptions = existingDescriptions ?? new Map<string, string>();
364
- const groups = groupByDirectory(listed.files, descriptions, resolved.collapseThreshold);
506
+ const groups = groupByDirectory(listed.files, descriptions, resolved.collapseThreshold, listed.repos);
365
507
  const generatedAt = new Date().toISOString().split(".")[0] + "Z";
508
+ const repoIds = listed.repos ? Array.from(new Set(listed.repos)) : undefined;
366
509
  const metadata: CodebaseMapMetadata = {
367
510
  generatedAt,
368
- fingerprint: computeCodebaseFingerprint(listed.files, resolved, listed.truncated),
511
+ fingerprint: computeCodebaseFingerprint(listed.files, resolved, listed.truncated, listed.repos),
369
512
  fileCount: listed.files.length,
370
513
  truncated: listed.truncated,
514
+ ...(repoIds ? { repositories: repoIds } : {}),
371
515
  };
372
516
  const content = renderCodebaseMap(groups, listed.files.length, listed.truncated, metadata);
373
517
 
@@ -387,13 +531,28 @@ function buildCodebaseMap(
387
531
  * Generate a fresh CODEBASE.md from scratch.
388
532
  * Preserves existing descriptions if `existingDescriptions` is provided.
389
533
  */
534
+ /**
535
+ * Resolve workspace-aware enumeration for parent mode, or undefined to fall
536
+ * back to the legacy single-root enumeration. Centralized so all three public
537
+ * entry points (generate/update/ensure) share one discovery path.
538
+ */
539
+ function resolveWorkspaceEnumeration(
540
+ basePath: string,
541
+ resolved: ResolvedCodebaseMapOptions,
542
+ ): EnumeratedFiles | undefined {
543
+ const registry = loadWorkspaceRegistry(basePath);
544
+ if (!registry) return undefined;
545
+ return enumerateWorkspaceFiles(registry, resolved.excludes, resolved.maxFiles);
546
+ }
547
+
390
548
  export function generateCodebaseMap(
391
549
  basePath: string,
392
550
  options?: CodebaseMapOptions,
393
551
  existingDescriptions?: Map<string, string>,
394
552
  ): { content: string; fileCount: number; truncated: boolean; files: string[]; fingerprint: string; generatedAt: string } {
395
553
  const resolved = resolveGeneratorOptions(options);
396
- return buildCodebaseMap(basePath, resolved, existingDescriptions);
554
+ const enumerated = resolveWorkspaceEnumeration(basePath, resolved);
555
+ return buildCodebaseMap(basePath, resolved, existingDescriptions, enumerated);
397
556
  }
398
557
 
399
558
  /**
@@ -427,7 +586,8 @@ export function updateCodebaseMap(
427
586
 
428
587
  // Generate new map preserving descriptions — reuse the returned file list
429
588
  // to avoid a second enumeration (prevents race between content and stats).
430
- const result = buildCodebaseMap(basePath, resolved, existingDescriptions);
589
+ const enumerated = resolveWorkspaceEnumeration(basePath, resolved);
590
+ const result = buildCodebaseMap(basePath, resolved, existingDescriptions, enumerated);
431
591
  const currentSet = new Set(result.files);
432
592
 
433
593
  // Count changes
@@ -467,7 +627,7 @@ export function ensureCodebaseMapFresh(
467
627
  ensureOptions?: EnsureCodebaseMapOptions,
468
628
  ): EnsureCodebaseMapResult {
469
629
  const resolved = resolveGeneratorOptions(options);
470
- const cacheKey = `${basePath}::${resolved.optionSignature}`;
630
+ const cacheKey = `${basePath}::${resolved.optionSignature}::${workspaceEnumerationSignature(basePath)}`;
471
631
  const ttlMs = ensureOptions?.ttlMs ?? DEFAULT_REFRESH_TTL_MS;
472
632
  const force = ensureOptions?.force === true;
473
633
  const now = Date.now();
@@ -481,8 +641,9 @@ export function ensureCodebaseMapFresh(
481
641
  }
482
642
 
483
643
  const existing = readCodebaseMap(basePath);
484
- const listed = enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
485
- const fingerprint = computeCodebaseFingerprint(listed.files, resolved, listed.truncated);
644
+ const listed = resolveWorkspaceEnumeration(basePath, resolved)
645
+ ?? enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
646
+ const fingerprint = computeCodebaseFingerprint(listed.files, resolved, listed.truncated, listed.repos);
486
647
 
487
648
  const cacheAndReturn = (result: EnsureCodebaseMapResult): EnsureCodebaseMapResult => {
488
649
  freshnessCache.set(cacheKey, { checkedAt: now, result });
@@ -200,7 +200,7 @@ export async function handleAutoCommand(trimmed: string, ctx: ExtensionCommandCo
200
200
  }
201
201
  return true;
202
202
  }
203
- await pauseAuto(ctx, pi);
203
+ await pauseAuto(ctx, pi, undefined, { abortActiveTurn: true });
204
204
  return true;
205
205
  }
206
206
 
@@ -4,7 +4,9 @@ import type { GSDState } from "../../types.js";
4
4
  import { createRequire } from "node:module";
5
5
 
6
6
  import { computeProgressScore, formatProgressLine } from "../../progress-score.js";
7
+ import { isRepositoryDirty } from "../../git-service.js";
7
8
  import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath, getProjectGSDPreferencesPath, availableModelIdsFromRegistry, modelIdsForProfileResolution, resolveProfileAnchorProvider, resolveDisabledModelProvidersFromPreferences } from "../../preferences.js";
9
+ import { createRepositoryRegistryFromPreferences } from "../../repository-registry.js";
8
10
  import { ensurePreferencesFile, handlePrefs, handlePrefsMode, handlePrefsWizard, handleLanguage } from "../../commands-prefs-wizard.js";
9
11
  import { runEnvironmentChecks } from "../../doctor-environment.js";
10
12
  import { deriveState } from "../../state.js";
@@ -220,7 +222,7 @@ export async function handleStatus(ctx: ExtensionCommandContext): Promise<void>
220
222
  );
221
223
 
222
224
  if (result === undefined) {
223
- ctx.ui.notify(formatTextStatus(state), "info");
225
+ ctx.ui.notify(formatTextStatus(state, basePath), "info");
224
226
  }
225
227
  }
226
228
 
@@ -610,7 +612,8 @@ export async function handleCoreCommand(
610
612
  return false;
611
613
  }
612
614
 
613
- export function formatTextStatus(state: GSDState): string {
615
+ export function formatTextStatus(state: GSDState, basePath?: string): string {
616
+ const root = basePath ?? projectRoot();
614
617
  const lines: string[] = ["GSD Status\n"];
615
618
  lines.push(formatProgressLine(computeProgressScore()));
616
619
  lines.push("");
@@ -653,7 +656,7 @@ export function formatTextStatus(state: GSDState): string {
653
656
  }
654
657
  }
655
658
 
656
- const envResults = runEnvironmentChecks(projectRoot());
659
+ const envResults = runEnvironmentChecks(root);
657
660
  const envIssues = envResults.filter((result) => result.status !== "ok");
658
661
  if (envIssues.length > 0) {
659
662
  lines.push("");
@@ -663,5 +666,38 @@ export function formatTextStatus(state: GSDState): string {
663
666
  }
664
667
  }
665
668
 
669
+ // Parent-workspace per-repository git health (#818). No-op for single-repo
670
+ // projects; surfaces which declared child repos have uncommitted changes.
671
+ const repoBlock = buildWorkspaceRepoStatusBlock(root);
672
+ if (repoBlock) {
673
+ lines.push("");
674
+ lines.push("Repositories:");
675
+ lines.push(repoBlock);
676
+ }
677
+
666
678
  return lines.join("\n");
667
679
  }
680
+
681
+ /**
682
+ * Build a per-repository dirty/clean summary for parent-workspace status.
683
+ * Returns "" for single-repo (project-mode) projects so the status output is
684
+ * unchanged; otherwise one line per declared child repository.
685
+ */
686
+ function buildWorkspaceRepoStatusBlock(basePath: string): string {
687
+ let registry;
688
+ try {
689
+ registry = createRepositoryRegistryFromPreferences(basePath, loadEffectiveGSDPreferences(basePath)?.preferences);
690
+ } catch {
691
+ return "";
692
+ }
693
+ if (registry.mode !== "parent") return "";
694
+ const childRepos = registry.repositories.filter((repo) => repo.id !== "project");
695
+ if (childRepos.length === 0) return "";
696
+
697
+ return childRepos
698
+ .map((repo) => {
699
+ const dirty = isRepositoryDirty(repo.root);
700
+ return ` ${dirty ? "✗" : "✓"} ${repo.id}${repo.role ? ` — ${repo.role}` : ""}${dirty ? " (uncommitted changes)" : " (clean)"}`;
701
+ })
702
+ .join("\n");
703
+ }
@@ -551,6 +551,17 @@ export function buildCategorySummaries(prefs: Record<string, unknown>): Record<s
551
551
  if (parts.length > 0) integrationsSummary = parts.join(", ");
552
552
  }
553
553
 
554
+ // Workspace (parent-workspace multi-repo)
555
+ const workspace = prefs.workspace as Record<string, unknown> | undefined;
556
+ const workspaceRepos = workspace?.repositories as Record<string, unknown> | undefined;
557
+ let workspaceSummary = "(single-repo)";
558
+ {
559
+ const parts: string[] = [];
560
+ if (workspace?.mode) parts.push(`mode: ${workspace.mode}`);
561
+ if (workspaceRepos && Object.keys(workspaceRepos).length > 0) parts.push(`${Object.keys(workspaceRepos).length} repo(s)`);
562
+ if (parts.length > 0) workspaceSummary = parts.join(", ");
563
+ }
564
+
554
565
  return {
555
566
  mode: modeSummary,
556
567
  models: modelsSummary,
@@ -568,6 +579,7 @@ export function buildCategorySummaries(prefs: Record<string, unknown>): Record<s
568
579
  hooks: hooksSummary,
569
580
  uok: uokSummary,
570
581
  integrations: integrationsSummary,
582
+ workspace: workspaceSummary,
571
583
  };
572
584
  }
573
585
 
@@ -758,7 +770,10 @@ async function configureDynamicRouting(ctx: ExtensionCommandContext, prefs: Reco
758
770
  const hooks = await promptBoolean(ctx, "Route hook sessions dynamically", dr.hooks, true);
759
771
  if (hooks !== undefined) dr.hooks = hooks;
760
772
 
761
- const flatRate = await promptBoolean(ctx, "Allow dynamic routing for flat-rate providers", dr.allow_flat_rate_providers, false);
773
+ // Opt-out flag (#1115): routing is allowed for flat-rate providers by
774
+ // default; only an explicit `false` suppresses it. The default hint reflects
775
+ // that allow-by-default behavior.
776
+ const flatRate = await promptBoolean(ctx, "Allow dynamic routing for flat-rate providers", dr.allow_flat_rate_providers, true);
762
777
  if (flatRate !== undefined) dr.allow_flat_rate_providers = flatRate;
763
778
 
764
779
  // tier_models.light / standard / heavy — optional model IDs
@@ -968,6 +983,114 @@ async function configureSkills(ctx: ExtensionCommandContext, prefs: Record<strin
968
983
  applyNumber(prefs, "skill_staleness_days", staleness);
969
984
  }
970
985
 
986
+ async function configureWorkspace(ctx: ExtensionCommandContext, prefs: Record<string, unknown>): Promise<void> {
987
+ type RepoConfig = { path: string; role?: string; verification?: string[]; commit_policy?: "auto" | "skip" };
988
+ let workspace = (prefs.workspace ?? {}) as { mode?: "project" | "parent"; repositories?: Record<string, RepoConfig> };
989
+
990
+ // Mode
991
+ const mode = await promptEnum(ctx, "Workspace mode", workspace.mode, ["project", "parent"]);
992
+ if (mode !== undefined) workspace = { ...workspace, mode: mode as "project" | "parent" };
993
+
994
+ if (workspace.mode !== "parent") {
995
+ // Single-repo mode: drop any declared repositories and persist.
996
+ if (workspace.repositories && Object.keys(workspace.repositories).length > 0) {
997
+ const clear = await promptBoolean(ctx, "Clear declared repositories (switch to single-repo)?", false, false);
998
+ if (clear) workspace = { mode: workspace.mode };
999
+ }
1000
+ persistWorkspace(prefs, workspace);
1001
+ return;
1002
+ }
1003
+
1004
+ // Parent mode — edit child repositories via a sub-menu.
1005
+ let repositories = { ...(workspace.repositories ?? {}) };
1006
+ while (true) {
1007
+ const ids = Object.keys(repositories).sort();
1008
+ const summary = ids.length === 0 ? "(no repositories — parent mode requires at least one)" : `${ids.length} repo(s)`;
1009
+ const listLabels = ids.map((id) => {
1010
+ const r = repositories[id];
1011
+ const roleStr = r.role ? ` — ${r.role}` : "";
1012
+ const policyStr = r.commit_policy === "skip" ? " [skip]" : "";
1013
+ return `${id} (${r.path})${roleStr}${policyStr}`;
1014
+ });
1015
+ const choice = await ctx.ui.select(`Declared repositories — ${summary}`, [...listLabels, "Add repository", "Done"]);
1016
+ const pick = typeof choice === "string" ? choice : "";
1017
+ if (!pick || pick === "Done") break;
1018
+ if (pick === "Add repository") {
1019
+ const idInput = await ctx.ui.input("Repository id (letters, digits, . _ -; 'project' is reserved):", "");
1020
+ const id = typeof idInput === "string" ? idInput.trim() : "";
1021
+ if (!id || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id)) {
1022
+ ctx.ui.notify("Invalid repository id — must match ^[A-Za-z0-9][A-Za-z0-9._-]*$ and cannot be 'project'.", "warning");
1023
+ continue;
1024
+ }
1025
+ if (id === "project" || repositories[id]) {
1026
+ ctx.ui.notify(`Repository id "${id}" is reserved or already declared.`, "warning");
1027
+ continue;
1028
+ }
1029
+ const pathInput = await ctx.ui.input("Repository path (relative to project root, e.g. frontend):", "");
1030
+ const path = typeof pathInput === "string" ? pathInput.trim() : "";
1031
+ if (!path) { ctx.ui.notify("Repository path is required.", "warning"); continue; }
1032
+ const repo: RepoConfig = { path };
1033
+ const roleInput = await ctx.ui.input("Role/label (optional):", "");
1034
+ if (typeof roleInput === "string" && roleInput.trim()) repo.role = roleInput.trim();
1035
+ const verifyInput = await ctx.ui.input("Verification commands (comma- or newline-separated, optional):", "");
1036
+ if (typeof verifyInput === "string" && verifyInput.trim()) {
1037
+ const cmds = parseStringList(verifyInput);
1038
+ if (cmds.length > 0) repo.verification = cmds;
1039
+ }
1040
+ const policy = await promptEnum(ctx, "Commit policy", undefined, ["auto", "skip"]);
1041
+ if (policy === "skip") repo.commit_policy = "skip";
1042
+ repositories[id] = repo;
1043
+ } else {
1044
+ // Edit/delete an existing repo (the first token is the id).
1045
+ const id = pick.split(" ")[0];
1046
+ if (!repositories[id]) continue;
1047
+ const editChoice = await ctx.ui.select(
1048
+ `Repository ${id}`,
1049
+ ["Edit path", "Edit role", "Edit verification", "Edit commit policy", "Delete repository", "Cancel"],
1050
+ );
1051
+ const ec = typeof editChoice === "string" ? editChoice : "";
1052
+ if (!ec || ec === "Cancel") continue;
1053
+ if (ec === "Delete repository") {
1054
+ delete repositories[id];
1055
+ } else if (ec === "Edit path") {
1056
+ const v = await ctx.ui.input("Repository path:", repositories[id].path);
1057
+ if (typeof v === "string" && v.trim()) repositories[id] = { ...repositories[id], path: v.trim() };
1058
+ } else if (ec === "Edit role") {
1059
+ const v = await ctx.ui.input("Role/label (blank to clear):", repositories[id].role ?? "");
1060
+ if (typeof v === "string" && v.trim()) repositories[id] = { ...repositories[id], role: v.trim() };
1061
+ else if (typeof v === "string") { const { role, ...rest } = repositories[id]; void role; repositories[id] = rest; }
1062
+ } else if (ec === "Edit verification") {
1063
+ const v = await ctx.ui.input("Verification commands (blank to clear):", (repositories[id].verification ?? []).join(", "));
1064
+ if (typeof v === "string" && v.trim()) {
1065
+ const cmds = parseStringList(v);
1066
+ if (cmds.length > 0) repositories[id] = { ...repositories[id], verification: cmds };
1067
+ } else if (typeof v === "string") {
1068
+ const { verification, ...rest } = repositories[id]; void verification; repositories[id] = rest;
1069
+ }
1070
+ } else if (ec === "Edit commit policy") {
1071
+ const policy = await promptEnum(ctx, "Commit policy", repositories[id].commit_policy, ["auto", "skip"]);
1072
+ if (policy === "skip") repositories[id] = { ...repositories[id], commit_policy: "skip" };
1073
+ else { const { commit_policy, ...rest } = repositories[id]; void commit_policy; repositories[id] = rest; }
1074
+ }
1075
+ }
1076
+ }
1077
+
1078
+ if (Object.keys(repositories).length === 0) {
1079
+ ctx.ui.notify("Parent mode requires at least one repository — mode not saved.", "warning");
1080
+ return;
1081
+ }
1082
+ persistWorkspace(prefs, { mode: "parent", repositories });
1083
+ }
1084
+
1085
+ /** Persist the workspace config onto prefs, dropping it entirely when empty. */
1086
+ function persistWorkspace(prefs: Record<string, unknown>, workspace: { mode?: string; repositories?: Record<string, unknown> }): void {
1087
+ if (!workspace.mode && (!workspace.repositories || Object.keys(workspace.repositories).length === 0)) {
1088
+ delete prefs.workspace;
1089
+ return;
1090
+ }
1091
+ prefs.workspace = workspace;
1092
+ }
1093
+
971
1094
  async function configureSkillRules(ctx: ExtensionCommandContext, prefs: Record<string, unknown>): Promise<void> {
972
1095
  type Rule = { when: string; use?: string[]; prefer?: string[]; avoid?: string[] };
973
1096
  let rules: Rule[] = Array.isArray(prefs.skill_rules) ? [...prefs.skill_rules as Rule[]] : [];
@@ -1176,6 +1299,14 @@ async function configureVerification(ctx: ExtensionCommandContext, prefs: Record
1176
1299
  const maxRetries = await promptInteger(ctx, "Verification max retries", prefs.verification_max_retries, "2");
1177
1300
  applyNumber(prefs, "verification_max_retries", maxRetries);
1178
1301
 
1302
+ const perUnitCap = await promptNumber(
1303
+ ctx,
1304
+ "Per-unit cost cap (USD; retry cost ceiling, blank = clear to default)",
1305
+ prefs.per_unit_cost_cap_usd,
1306
+ "5.0",
1307
+ );
1308
+ applyNumber(prefs, "per_unit_cost_cap_usd", perUnitCap);
1309
+
1179
1310
  const ev = await promptBoolean(ctx, "Enhanced verification (master toggle)", prefs.enhanced_verification, true);
1180
1311
  if (ev !== undefined) prefs.enhanced_verification = ev;
1181
1312
  const evPre = await promptBoolean(ctx, "Enhanced verification — pre-execution checks", prefs.enhanced_verification_pre, true);
@@ -1228,7 +1359,7 @@ async function configureContextCodebase(ctx: ExtensionCommandContext, prefs: Rec
1228
1359
  const maskTurns = await promptInteger(ctx, "Observation mask turns (1–50)", cm.observation_mask_turns, "8");
1229
1360
  if (maskTurns !== undefined && maskTurns !== "clear") cm.observation_mask_turns = maskTurns;
1230
1361
  else if (maskTurns === "clear") delete cm.observation_mask_turns;
1231
- const thresh = await promptNumber(ctx, "Compaction threshold percent (0.5–0.95)", cm.compaction_threshold_percent, "0.60");
1362
+ const thresh = await promptNumber(ctx, "Soft context warning threshold percent (0.5–0.95)", cm.compaction_threshold_percent, "0.60");
1232
1363
  if (thresh !== undefined && thresh !== "clear") cm.compaction_threshold_percent = thresh;
1233
1364
  else if (thresh === "clear") delete cm.compaction_threshold_percent;
1234
1365
  const toolMax = await promptInteger(ctx, "Tool result max chars (200–10000)", cm.tool_result_max_chars, "800");
@@ -1621,6 +1752,7 @@ export async function handlePrefsWizard(
1621
1752
  `Hooks ${summaries.hooks}`,
1622
1753
  `UoK ${summaries.uok}`,
1623
1754
  `Integrations ${summaries.integrations}`,
1755
+ `Workspace ${summaries.workspace}`,
1624
1756
  `Advanced ${summaries.advanced}`,
1625
1757
  `── Save & Exit ──`,
1626
1758
  ];
@@ -1644,6 +1776,7 @@ export async function handlePrefsWizard(
1644
1776
  else if (choice.startsWith("Hooks")) await configureHooks(ctx, prefs);
1645
1777
  else if (choice.startsWith("UoK")) await configureUoK(ctx, prefs);
1646
1778
  else if (choice.startsWith("Integrations")) await configureIntegrations(ctx, prefs);
1779
+ else if (choice.startsWith("Workspace")) await configureWorkspace(ctx, prefs);
1647
1780
  else if (choice.startsWith("Advanced")) await configureAdvanced(ctx, prefs);
1648
1781
  }
1649
1782
 
@@ -1780,6 +1913,7 @@ export function serializePreferencesToFrontmatter(prefs: Record<string, unknown>
1780
1913
  "reactive_execution", "gate_evaluation",
1781
1914
  "auto_visualize", "auto_report",
1782
1915
  "verification_commands", "verification_auto_fix", "verification_max_retries",
1916
+ "per_unit_cost_cap_usd",
1783
1917
  "enhanced_verification", "enhanced_verification_pre",
1784
1918
  "enhanced_verification_post", "enhanced_verification_strict",
1785
1919
  "safety_harness",
@@ -112,7 +112,7 @@ function formatThresholdLines(): string[] {
112
112
 
113
113
  const compactionThreshold = prefs?.context_management?.compaction_threshold_percent;
114
114
  if (typeof compactionThreshold === "number") {
115
- lines.push(`Compaction: ${Math.round(compactionThreshold * 100)}%`);
115
+ lines.push(`Soft context warning: ${Math.round(compactionThreshold * 100)}%`);
116
116
  }
117
117
 
118
118
  return lines;
@@ -315,8 +315,19 @@ async function handleRemove(args: string, ctx: ExtensionCommandContext): Promise
315
315
  }
316
316
 
317
317
  try {
318
- removeWorktree(basePath, name, { deleteBranch: true });
319
- ctx.ui.notify(`Removed worktree ${name}.`, "info");
318
+ const removed = removeWorktree(basePath, name, { deleteBranch: true });
319
+ if (removed) {
320
+ ctx.ui.notify(`Removed worktree ${name}.`, "info");
321
+ } else {
322
+ ctx.ui.notify(
323
+ [
324
+ `Worktree removal aborted for "${name}" to preserve uncommitted changes.`,
325
+ "",
326
+ "Manual quarantine recovery may be needed before retrying removal.",
327
+ ].join("\n"),
328
+ "warning",
329
+ );
330
+ }
320
331
  } catch (err) {
321
332
  const msg = err instanceof Error ? err.message : String(err);
322
333
  ctx.ui.notify(
@@ -47,7 +47,11 @@ import {
47
47
  applyMigrationV28MemoryLastHitAt,
48
48
  applyMigrationV29RepositoryTargets,
49
49
  } from "../db-migration-steps.js";
50
- import { isMemoriesFtsAvailableSchema, tryCreateMemoriesFtsSchema } from "../db-memory-fts-schema.js";
50
+ import {
51
+ isMemoriesFtsAvailableSchema,
52
+ rebuildMemoriesFtsSchemaOnce,
53
+ tryCreateMemoriesFtsSchema,
54
+ } from "../db-memory-fts-schema.js";
51
55
  import { createDbOpenState, type DbOpenPhase } from "../db-open-state.js";
52
56
  import { createRuntimeKvTableV25 } from "../db-runtime-kv-schema.js";
53
57
  import { getCurrentSchemaVersion, recordSchemaVersion } from "../db-schema-metadata.js";
@@ -134,6 +138,9 @@ function initSchema(db: DbAdapter, fileBacked: boolean, dbPath: string | null):
134
138
  }
135
139
 
136
140
  migrateSchema(db, dbPath);
141
+ rebuildMemoriesFtsSchemaOnce(db, {
142
+ onRebuildFailed: (message) => logWarning("db", message),
143
+ });
137
144
  }
138
145
 
139
146
  export function _isLikelyWslDrvFsPathForTest(dbPath: string | null): boolean {