gsd-pi 2.57.0 → 2.58.0-dev.394cb18

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 (834) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +58 -35
  3. package/dist/headless-ui.d.ts +17 -0
  4. package/dist/headless-ui.js +97 -3
  5. package/dist/headless.js +67 -6
  6. package/dist/help-text.js +1 -0
  7. package/dist/onboarding.js +44 -0
  8. package/dist/resource-loader.js +16 -1
  9. package/dist/resources/agents/researcher.md +1 -1
  10. package/dist/resources/extensions/ask-user-questions.js +16 -3
  11. package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
  12. package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
  13. package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
  14. package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
  16. package/dist/resources/extensions/context7/extension-manifest.json +1 -1
  17. package/dist/resources/extensions/get-secrets-from-user.js +8 -5
  18. package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
  19. package/dist/resources/extensions/google-search/index.js +2 -1
  20. package/dist/resources/extensions/gsd/auto/infra-errors.js +4 -0
  21. package/dist/resources/extensions/gsd/auto/phases.js +25 -21
  22. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  23. package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
  24. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -5
  25. package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
  26. package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
  27. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  28. package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
  29. package/dist/resources/extensions/gsd/auto-start.js +35 -22
  30. package/dist/resources/extensions/gsd/auto-worktree.js +206 -14
  31. package/dist/resources/extensions/gsd/auto.js +4 -0
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -9
  34. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
  35. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +42 -34
  36. package/dist/resources/extensions/gsd/bootstrap/system-context.js +66 -12
  37. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
  38. package/dist/resources/extensions/gsd/captures.js +56 -4
  39. package/dist/resources/extensions/gsd/codebase-generator.js +279 -0
  40. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  41. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  42. package/dist/resources/extensions/gsd/commands-codebase.js +115 -0
  43. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +41 -4
  44. package/dist/resources/extensions/gsd/complexity-classifier.js +8 -6
  45. package/dist/resources/extensions/gsd/db-writer.js +116 -8
  46. package/dist/resources/extensions/gsd/dispatch-guard.js +11 -1
  47. package/dist/resources/extensions/gsd/doctor-git-checks.js +76 -1
  48. package/dist/resources/extensions/gsd/doctor-proactive.js +34 -1
  49. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  50. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
  51. package/dist/resources/extensions/gsd/doctor.js +3 -1
  52. package/dist/resources/extensions/gsd/error-classifier.js +12 -10
  53. package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
  54. package/dist/resources/extensions/gsd/forensics.js +123 -20
  55. package/dist/resources/extensions/gsd/git-service.js +105 -2
  56. package/dist/resources/extensions/gsd/gitignore.js +33 -0
  57. package/dist/resources/extensions/gsd/gsd-db.js +44 -10
  58. package/dist/resources/extensions/gsd/guided-flow.js +106 -44
  59. package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
  60. package/dist/resources/extensions/gsd/health-widget.js +17 -0
  61. package/dist/resources/extensions/gsd/index.js +1 -1
  62. package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
  63. package/dist/resources/extensions/gsd/migrate-external.js +8 -1
  64. package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
  65. package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
  66. package/dist/resources/extensions/gsd/model-router.js +35 -1
  67. package/dist/resources/extensions/gsd/native-git-bridge.js +39 -0
  68. package/dist/resources/extensions/gsd/notifications.js +16 -1
  69. package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
  70. package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
  71. package/dist/resources/extensions/gsd/parallel-orchestrator.js +23 -6
  72. package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
  73. package/dist/resources/extensions/gsd/paths.js +45 -0
  74. package/dist/resources/extensions/gsd/preferences-models.js +14 -1
  75. package/dist/resources/extensions/gsd/preferences-types.js +3 -1
  76. package/dist/resources/extensions/gsd/preferences.js +42 -31
  77. package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
  78. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  80. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
  83. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  84. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  86. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  87. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  88. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  89. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  90. package/dist/resources/extensions/gsd/repo-identity.js +205 -11
  91. package/dist/resources/extensions/gsd/rethink.js +5 -0
  92. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
  93. package/dist/resources/extensions/gsd/state.js +85 -27
  94. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  95. package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
  96. package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
  97. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
  98. package/dist/resources/extensions/gsd/tools/validate-milestone.js +18 -3
  99. package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
  100. package/dist/resources/extensions/gsd/undo.js +2 -2
  101. package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
  102. package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
  103. package/dist/resources/extensions/gsd/watch/header-renderer.js +241 -0
  104. package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
  105. package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
  106. package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
  107. package/dist/resources/extensions/gsd/workspace-index.js +24 -0
  108. package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
  109. package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
  110. package/dist/resources/extensions/mcp-client/index.js +11 -7
  111. package/dist/resources/extensions/ollama/index.js +112 -0
  112. package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
  113. package/dist/resources/extensions/ollama/ollama-client.js +168 -0
  114. package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
  115. package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
  116. package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
  117. package/dist/resources/extensions/ollama/types.js +2 -0
  118. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  119. package/dist/resources/extensions/shared/interview-ui.js +11 -1
  120. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
  121. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  122. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  123. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  124. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  125. package/dist/startup-model-validation.d.ts +39 -0
  126. package/dist/startup-model-validation.js +50 -0
  127. package/dist/web/standalone/.next/BUILD_ID +1 -1
  128. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  129. package/dist/web/standalone/.next/build-manifest.json +4 -4
  130. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  131. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  132. package/dist/web/standalone/.next/required-server-files.json +3 -3
  133. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  134. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  136. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  144. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  146. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  147. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  150. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  153. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  160. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  200. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  206. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  220. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  222. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  224. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  226. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  235. package/dist/web/standalone/.next/server/app/index.html +1 -1
  236. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  237. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  238. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  239. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  240. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  241. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  242. package/dist/web/standalone/.next/server/app/page.js +2 -2
  243. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  244. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  245. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  246. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  247. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  248. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  249. package/dist/web/standalone/.next/server/middleware.js +2 -2
  250. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  251. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  252. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  253. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  254. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  255. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
  256. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  257. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  258. package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
  259. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  260. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  261. package/dist/web/standalone/.next/static/chunks/{webpack-4332cbd5dd1be584.js → webpack-a1c1e452c6b32d04.js} +1 -1
  262. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
  263. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  264. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  265. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  266. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  267. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  268. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  269. package/dist/web/standalone/server.js +1 -1
  270. package/dist/web-mode.js +2 -1
  271. package/dist/welcome-screen.d.ts +1 -0
  272. package/dist/welcome-screen.js +32 -6
  273. package/package.json +2 -2
  274. package/packages/daemon/src/cli.ts +49 -0
  275. package/packages/daemon/src/daemon.test.ts +104 -1
  276. package/packages/daemon/src/daemon.ts +24 -1
  277. package/packages/daemon/src/discord-bot.ts +73 -3
  278. package/packages/daemon/src/event-bridge.ts +15 -9
  279. package/packages/daemon/src/event-formatter.ts +30 -2
  280. package/packages/daemon/src/index.ts +9 -0
  281. package/packages/daemon/src/launchd.test.ts +356 -0
  282. package/packages/daemon/src/launchd.ts +242 -0
  283. package/packages/daemon/src/message-batcher.test.ts +2 -2
  284. package/packages/daemon/src/message-batcher.ts +9 -3
  285. package/packages/daemon/src/orchestrator.test.ts +1 -0
  286. package/packages/daemon/src/orchestrator.ts +106 -2
  287. package/packages/native/dist/ast/index.js +9 -5
  288. package/packages/native/dist/ast/types.js +2 -1
  289. package/packages/native/dist/clipboard/index.js +12 -7
  290. package/packages/native/dist/clipboard/types.js +2 -1
  291. package/packages/native/dist/diff/index.js +12 -7
  292. package/packages/native/dist/diff/types.js +2 -1
  293. package/packages/native/dist/fd/index.js +6 -3
  294. package/packages/native/dist/fd/types.js +2 -1
  295. package/packages/native/dist/glob/index.js +9 -5
  296. package/packages/native/dist/glob/types.js +2 -1
  297. package/packages/native/dist/grep/index.js +9 -5
  298. package/packages/native/dist/grep/types.js +2 -1
  299. package/packages/native/dist/gsd-parser/index.js +18 -11
  300. package/packages/native/dist/gsd-parser/types.js +2 -1
  301. package/packages/native/dist/highlight/index.js +12 -7
  302. package/packages/native/dist/highlight/types.js +2 -1
  303. package/packages/native/dist/html/index.js +6 -3
  304. package/packages/native/dist/html/types.js +2 -1
  305. package/packages/native/dist/image/index.js +10 -5
  306. package/packages/native/dist/image/types.js +7 -4
  307. package/packages/native/dist/index.js +70 -17
  308. package/packages/native/dist/json-parse/index.js +13 -8
  309. package/packages/native/dist/native.js +47 -10
  310. package/packages/native/dist/ps/index.js +15 -9
  311. package/packages/native/dist/ps/types.js +2 -1
  312. package/packages/native/dist/stream-process/index.js +12 -7
  313. package/packages/native/dist/text/index.js +24 -14
  314. package/packages/native/dist/text/types.js +5 -2
  315. package/packages/native/dist/truncate/index.js +12 -7
  316. package/packages/native/dist/ttsr/index.js +12 -7
  317. package/packages/native/dist/ttsr/types.js +2 -1
  318. package/packages/native/dist/xxhash/index.js +9 -5
  319. package/packages/native/package.json +19 -19
  320. package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
  321. package/packages/native/src/native.ts +9 -8
  322. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  323. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  324. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  325. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  326. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  327. package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
  328. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  329. package/packages/pi-agent-core/src/proxy.ts +1 -1
  330. package/packages/pi-ai/dist/env-api-keys.js +1 -0
  331. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  332. package/packages/pi-ai/dist/index.d.ts +1 -0
  333. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  334. package/packages/pi-ai/dist/index.js +1 -0
  335. package/packages/pi-ai/dist/index.js.map +1 -1
  336. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  337. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
  338. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  339. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
  340. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
  341. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
  342. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
  343. package/packages/pi-ai/dist/types.d.ts +3 -3
  344. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  345. package/packages/pi-ai/dist/types.js.map +1 -1
  346. package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
  347. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  348. package/packages/pi-ai/dist/utils/json-parse.js +24 -1
  349. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  350. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
  351. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
  352. package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
  353. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
  354. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
  355. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
  356. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
  357. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
  358. package/packages/pi-ai/src/env-api-keys.ts +1 -0
  359. package/packages/pi-ai/src/index.ts +1 -0
  360. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
  361. package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
  362. package/packages/pi-ai/src/types.ts +3 -2
  363. package/packages/pi-ai/src/utils/json-parse.ts +28 -1
  364. package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
  365. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
  366. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  367. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  368. package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
  369. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  370. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
  371. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  372. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
  373. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
  375. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
  376. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
  377. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
  378. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/exec.js +3 -1
  380. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
  382. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
  383. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
  384. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
  385. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
  386. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
  387. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
  388. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
  389. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
  390. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
  391. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
  392. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
  393. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
  394. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
  395. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
  396. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
  397. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
  398. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  399. package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
  400. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  401. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  402. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  403. package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
  404. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  405. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
  406. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
  407. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
  408. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
  409. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
  410. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
  411. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
  412. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
  413. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  414. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  415. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  416. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  417. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  418. package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
  419. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  420. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
  422. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  424. package/packages/pi-coding-agent/dist/core/messages.js +31 -2
  425. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  426. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
  427. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
  428. package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
  429. package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
  430. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  431. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  432. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  433. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
  434. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  435. package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
  436. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  437. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
  438. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  439. package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
  440. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  441. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
  442. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
  443. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
  444. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
  445. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  446. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
  447. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  448. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  449. package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
  450. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  451. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
  452. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
  453. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
  454. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
  455. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  456. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  457. package/packages/pi-coding-agent/dist/index.js +1 -1
  458. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  459. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts +1 -1
  460. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
  461. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js +9 -8
  462. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
  463. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  464. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +0 -3
  465. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  466. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -0
  467. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  468. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -1
  469. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  470. package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js +1 -1
  471. package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  472. package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -1
  473. package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  474. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  475. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  476. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  477. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js +5 -2
  478. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
  479. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +1 -0
  480. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  481. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +4 -0
  482. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  483. package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js +1 -1
  484. package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
  485. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts +1 -1
  486. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  487. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js +4 -2
  488. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
  489. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +2 -2
  490. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  491. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  492. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +8 -1
  493. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  494. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  495. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +2 -0
  496. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
  497. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  498. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js +4 -0
  499. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js.map +1 -1
  500. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  501. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +26 -12
  502. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  503. package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js +4 -4
  504. package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  505. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +3 -0
  506. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  507. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +46 -14
  508. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  509. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  510. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -8
  511. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  512. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +4 -4
  513. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  514. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +2 -2
  515. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  516. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  517. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -3
  518. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  519. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  520. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -2
  521. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  522. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  523. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +19 -1
  524. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  525. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  526. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +16 -1
  527. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  528. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -0
  529. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  530. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +27 -4
  531. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  532. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  533. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +6 -0
  534. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  535. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
  536. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  537. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
  538. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  539. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
  540. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  541. package/packages/pi-coding-agent/package.json +1 -1
  542. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
  543. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
  544. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
  545. package/packages/pi-coding-agent/src/core/exec.ts +3 -1
  546. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
  547. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
  548. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
  549. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
  550. package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
  551. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  552. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
  553. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
  554. package/packages/pi-coding-agent/src/core/index.ts +6 -0
  555. package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
  556. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
  557. package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
  558. package/packages/pi-coding-agent/src/core/messages.ts +29 -2
  559. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  560. package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
  561. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
  562. package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
  563. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
  564. package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
  565. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
  566. package/packages/pi-coding-agent/src/index.ts +6 -0
  567. package/packages/pi-coding-agent/src/modes/interactive/components/armin.ts +9 -9
  568. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -2
  569. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +3 -1
  570. package/packages/pi-coding-agent/src/modes/interactive/components/bordered-loader.ts +1 -1
  571. package/packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts +1 -1
  572. package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +1 -1
  573. package/packages/pi-coding-agent/src/modes/interactive/components/config-selector.ts +7 -2
  574. package/packages/pi-coding-agent/src/modes/interactive/components/countdown-timer.ts +3 -0
  575. package/packages/pi-coding-agent/src/modes/interactive/components/custom-message.ts +1 -1
  576. package/packages/pi-coding-agent/src/modes/interactive/components/daxnuts.ts +4 -3
  577. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +2 -2
  578. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -1
  579. package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +1 -0
  580. package/packages/pi-coding-agent/src/modes/interactive/components/extension-selector.ts +4 -0
  581. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +27 -13
  582. package/packages/pi-coding-agent/src/modes/interactive/components/oauth-selector.ts +4 -4
  583. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +45 -14
  584. package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -7
  585. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +4 -4
  586. package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +2 -2
  587. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +8 -3
  588. package/packages/pi-coding-agent/src/modes/interactive/components/user-message-selector.ts +3 -2
  589. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +24 -1
  590. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +14 -1
  591. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +35 -3
  592. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -0
  593. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
  594. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
  595. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  596. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  597. package/packages/pi-tui/dist/terminal.js +9 -0
  598. package/packages/pi-tui/dist/terminal.js.map +1 -1
  599. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  600. package/packages/pi-tui/dist/tui.js +9 -0
  601. package/packages/pi-tui/dist/tui.js.map +1 -1
  602. package/packages/pi-tui/src/terminal.ts +14 -0
  603. package/packages/pi-tui/src/tui.ts +8 -0
  604. package/pkg/dist/modes/interactive/theme/themes.js +1 -1
  605. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  606. package/pkg/package.json +1 -1
  607. package/scripts/ensure-workspace-builds.cjs +45 -14
  608. package/src/resources/agents/researcher.md +1 -1
  609. package/src/resources/extensions/ask-user-questions.ts +21 -3
  610. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  611. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  612. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  613. package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
  614. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
  615. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
  616. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
  617. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  618. package/src/resources/extensions/get-secrets-from-user.ts +8 -5
  619. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  620. package/src/resources/extensions/google-search/index.ts +2 -1
  621. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  622. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  623. package/src/resources/extensions/gsd/auto/phases.ts +43 -34
  624. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  625. package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
  626. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -5
  627. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
  628. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  629. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  630. package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
  631. package/src/resources/extensions/gsd/auto-start.ts +35 -26
  632. package/src/resources/extensions/gsd/auto-worktree.ts +200 -11
  633. package/src/resources/extensions/gsd/auto.ts +5 -0
  634. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
  635. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +87 -9
  636. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
  637. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -35
  638. package/src/resources/extensions/gsd/bootstrap/system-context.ts +72 -12
  639. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
  640. package/src/resources/extensions/gsd/captures.ts +63 -3
  641. package/src/resources/extensions/gsd/codebase-generator.ts +351 -0
  642. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  643. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  644. package/src/resources/extensions/gsd/commands-codebase.ts +164 -0
  645. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +46 -4
  646. package/src/resources/extensions/gsd/complexity-classifier.ts +8 -6
  647. package/src/resources/extensions/gsd/db-writer.ts +140 -7
  648. package/src/resources/extensions/gsd/dispatch-guard.ts +12 -1
  649. package/src/resources/extensions/gsd/doctor-git-checks.ts +75 -1
  650. package/src/resources/extensions/gsd/doctor-proactive.ts +35 -1
  651. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  652. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
  653. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  654. package/src/resources/extensions/gsd/doctor.ts +3 -1
  655. package/src/resources/extensions/gsd/error-classifier.ts +13 -11
  656. package/src/resources/extensions/gsd/extension-manifest.json +16 -1
  657. package/src/resources/extensions/gsd/forensics.ts +144 -20
  658. package/src/resources/extensions/gsd/git-service.ts +119 -3
  659. package/src/resources/extensions/gsd/gitignore.ts +33 -0
  660. package/src/resources/extensions/gsd/gsd-db.ts +49 -8
  661. package/src/resources/extensions/gsd/guided-flow.ts +114 -45
  662. package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
  663. package/src/resources/extensions/gsd/health-widget.ts +17 -0
  664. package/src/resources/extensions/gsd/index.ts +1 -0
  665. package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
  666. package/src/resources/extensions/gsd/migrate-external.ts +9 -1
  667. package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
  668. package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
  669. package/src/resources/extensions/gsd/model-router.ts +35 -1
  670. package/src/resources/extensions/gsd/native-git-bridge.ts +41 -0
  671. package/src/resources/extensions/gsd/notifications.ts +16 -0
  672. package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
  673. package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
  674. package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -6
  675. package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
  676. package/src/resources/extensions/gsd/paths.ts +44 -0
  677. package/src/resources/extensions/gsd/preferences-models.ts +14 -1
  678. package/src/resources/extensions/gsd/preferences-types.ts +10 -1
  679. package/src/resources/extensions/gsd/preferences.ts +45 -29
  680. package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
  681. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  682. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  683. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  684. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  685. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
  686. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  687. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  688. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  689. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  690. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  691. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  692. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  693. package/src/resources/extensions/gsd/repo-identity.ts +186 -11
  694. package/src/resources/extensions/gsd/rethink.ts +6 -0
  695. package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
  696. package/src/resources/extensions/gsd/state.ts +84 -32
  697. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
  698. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
  699. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
  700. package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
  701. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
  702. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +488 -0
  703. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
  704. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
  705. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
  706. package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +4 -4
  707. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
  708. package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
  709. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
  710. package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
  711. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
  712. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
  713. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
  714. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +47 -0
  715. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  716. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
  717. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
  718. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
  719. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
  720. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
  721. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
  722. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
  723. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
  724. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
  725. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
  726. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
  727. package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
  728. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
  729. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
  730. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +134 -0
  731. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
  732. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
  733. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +72 -0
  734. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +68 -0
  735. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
  736. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
  737. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  738. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
  739. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
  740. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
  741. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
  742. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
  743. package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
  744. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
  745. package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
  746. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
  747. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
  748. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +9 -8
  749. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
  750. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
  751. package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -0
  752. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
  753. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +36 -0
  754. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
  755. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
  756. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
  757. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
  758. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
  759. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
  760. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
  761. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
  762. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
  763. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
  764. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
  765. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
  766. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
  767. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
  768. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
  769. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
  770. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
  771. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +44 -0
  772. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
  773. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
  774. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
  775. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
  776. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
  777. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +27 -2
  778. package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +44 -2
  779. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
  780. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
  781. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
  782. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
  783. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
  784. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
  785. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +175 -0
  786. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
  787. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
  788. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
  789. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
  790. package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
  791. package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
  792. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
  793. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -2
  794. package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
  795. package/src/resources/extensions/gsd/types.ts +4 -2
  796. package/src/resources/extensions/gsd/undo.ts +2 -2
  797. package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
  798. package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
  799. package/src/resources/extensions/gsd/watch/header-renderer.ts +275 -0
  800. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  801. package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
  802. package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
  803. package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
  804. package/src/resources/extensions/gsd/workspace-index.ts +30 -0
  805. package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
  806. package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
  807. package/src/resources/extensions/mcp-client/index.ts +13 -7
  808. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
  809. package/src/resources/extensions/ollama/index.ts +130 -0
  810. package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
  811. package/src/resources/extensions/ollama/ollama-client.ts +196 -0
  812. package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
  813. package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
  814. package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
  815. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
  816. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
  817. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
  818. package/src/resources/extensions/ollama/types.ts +130 -0
  819. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  820. package/src/resources/extensions/shared/interview-ui.ts +12 -1
  821. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
  822. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
  823. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  824. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  825. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  826. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  827. package/dist/web/standalone/.next/static/chunks/6502.2305d0afd2385711.js +0 -9
  828. package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
  829. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  830. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  831. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
  832. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
  833. /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → uDm3eO1oo9lDfY2TyoO9t}/_buildManifest.js +0 -0
  834. /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → uDm3eO1oo9lDfY2TyoO9t}/_ssgManifest.js +0 -0
@@ -680,6 +680,16 @@ export function nativeAddAll(basePath: string): void {
680
680
  gitFileExec(basePath, ["add", "-A"]);
681
681
  }
682
682
 
683
+ /**
684
+ * Stage only already-tracked files (git add -u).
685
+ * Does NOT add new untracked files — only updates modifications and deletions
686
+ * for files git already knows about. Safe for automated snapshots where
687
+ * pulling in unknown untracked files (secrets, binaries) would be dangerous.
688
+ */
689
+ export function nativeAddTracked(basePath: string): void {
690
+ gitFileExec(basePath, ["add", "-u"]);
691
+ }
692
+
683
693
  /**
684
694
  * Stage all files with pathspec exclusions (git add -A -- ':!pattern' ...).
685
695
  * Excluded paths are never hashed by git, preventing hangs on large
@@ -931,6 +941,37 @@ export function nativeResetHard(basePath: string): void {
931
941
  execSync("git reset --hard HEAD", { cwd: basePath, stdio: "pipe" });
932
942
  }
933
943
 
944
+ /**
945
+ * Soft reset to a target ref (git reset --soft <ref>).
946
+ * Moves HEAD to `target` while keeping all changes staged in the index.
947
+ * Used to squash snapshot commits back into a single real commit.
948
+ */
949
+ export function nativeResetSoft(basePath: string, target: string): void {
950
+ execFileSync("git", ["reset", "--soft", target], {
951
+ cwd: basePath,
952
+ stdio: ["ignore", "pipe", "pipe"],
953
+ encoding: "utf-8",
954
+ env: GIT_NO_PROMPT_ENV,
955
+ });
956
+ }
957
+
958
+ /**
959
+ * Get the subject line of a commit (git log -1 --format=%s <ref>).
960
+ * Returns empty string if the ref doesn't exist.
961
+ */
962
+ export function nativeCommitSubject(basePath: string, ref: string): string {
963
+ try {
964
+ return execFileSync("git", ["log", "-1", "--format=%s", ref], {
965
+ cwd: basePath,
966
+ stdio: ["ignore", "pipe", "pipe"],
967
+ encoding: "utf-8",
968
+ env: GIT_NO_PROMPT_ENV,
969
+ }).trim();
970
+ } catch {
971
+ return "";
972
+ }
973
+ }
974
+
934
975
  /**
935
976
  * Delete a branch.
936
977
  * Native: libgit2 branch delete.
@@ -23,7 +23,13 @@ export function sendDesktopNotification(
23
23
  message: string,
24
24
  level: NotifyLevel = "info",
25
25
  kind: NotificationKind = "complete",
26
+ projectName?: string,
26
27
  ): void {
28
+ // When a projectName is provided and the title is the default "GSD",
29
+ // replace it with a project-qualified title for multi-project clarity.
30
+ if (projectName && title === "GSD") {
31
+ title = formatNotificationTitle(projectName);
32
+ }
27
33
  const loaded = loadEffectiveGSDPreferences()?.preferences;
28
34
  if (!shouldSendDesktopNotification(kind, loaded?.notifications)) return;
29
35
 
@@ -64,6 +70,16 @@ export function shouldSendDesktopNotification(
64
70
  }
65
71
  }
66
72
 
73
+ /**
74
+ * Format a notification title that includes the project name for context.
75
+ * Returns "GSD — projectName" when a project name is available, otherwise "GSD".
76
+ */
77
+ export function formatNotificationTitle(projectName?: string): string {
78
+ const trimmed = projectName?.trim();
79
+ if (trimmed) return `GSD — ${trimmed}`;
80
+ return "GSD";
81
+ }
82
+
67
83
  export function buildDesktopNotificationCommand(
68
84
  platform: NodeJS.Platform,
69
85
  title: string,
@@ -112,7 +112,20 @@ export async function analyzeParallelEligibility(
112
112
  for (const mid of milestoneIds) {
113
113
  const entry = registryMap.get(mid);
114
114
  const title = entry?.title ?? mid;
115
- const status = entry?.status ?? "pending";
115
+
116
+ // Rule 0: milestones with no registry entry (ghost directories, unknown
117
+ // state) are ineligible — we cannot determine their status or deps (#2501)
118
+ if (!entry) {
119
+ ineligible.push({
120
+ milestoneId: mid,
121
+ title,
122
+ eligible: false,
123
+ reason: "Milestone has no planning data — cannot determine eligibility.",
124
+ });
125
+ continue;
126
+ }
127
+
128
+ const status = entry.status;
116
129
 
117
130
  // Rule 1: skip complete and parked milestones
118
131
  if (status === "complete" || status === "parked") {
@@ -126,7 +139,7 @@ export async function analyzeParallelEligibility(
126
139
  }
127
140
 
128
141
  // Rule 2: check dependency satisfaction
129
- const deps = entry?.dependsOn ?? [];
142
+ const deps = entry.dependsOn ?? [];
130
143
  const unsatisfied = deps.filter(dep => {
131
144
  const depEntry = registryMap.get(dep);
132
145
  return !depEntry || depEntry.status !== "complete";
@@ -5,6 +5,9 @@
5
5
  * with safety checks for parallel execution context.
6
6
  */
7
7
 
8
+ import { existsSync, readdirSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { spawnSync } from "node:child_process";
8
11
  import { loadFile } from "./files.js";
9
12
  import { resolveMilestoneFile } from "./paths.js";
10
13
  import { mergeMilestoneToMain } from "./auto-worktree.js";
@@ -28,22 +31,102 @@ export type MergeOrder = "sequential" | "by-completion";
28
31
 
29
32
  // ─── Merge Queue ───────────────────────────────────────────────────────────
30
33
 
34
+ /**
35
+ * Check whether a milestone is complete by querying its worktree SQLite DB.
36
+ * Uses a subprocess to avoid disrupting the global DB singleton.
37
+ * Returns true when milestones.status = 'complete' in the worktree's gsd.db.
38
+ */
39
+ export function isMilestoneCompleteInWorktreeDb(basePath: string, mid: string): boolean {
40
+ const dbPath = join(basePath, ".gsd", "worktrees", mid, ".gsd", "gsd.db");
41
+ if (!existsSync(dbPath)) return false;
42
+
43
+ try {
44
+ const result = spawnSync(
45
+ "sqlite3",
46
+ [dbPath, `SELECT status FROM milestones WHERE id='${mid}' LIMIT 1`],
47
+ { timeout: 3000, encoding: "utf-8" },
48
+ );
49
+ return (result.stdout || "").trim() === "complete";
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Discover milestone IDs with status='complete' in their worktree DB,
57
+ * scanning .gsd/worktrees/<MID>/.gsd/gsd.db for each worktree directory.
58
+ */
59
+ function discoverDbCompletedMilestones(basePath: string): Set<string> {
60
+ const completed = new Set<string>();
61
+ const worktreeDir = join(basePath, ".gsd", "worktrees");
62
+ try {
63
+ for (const entry of readdirSync(worktreeDir)) {
64
+ if (entry.startsWith("M") && isMilestoneCompleteInWorktreeDb(basePath, entry)) {
65
+ completed.add(entry);
66
+ }
67
+ }
68
+ } catch {
69
+ // worktrees dir may not exist
70
+ }
71
+ return completed;
72
+ }
73
+
31
74
  /**
32
75
  * Determine safe merge order for completed milestones.
33
76
  * Sequential: merge in milestone ID order (M001 before M002).
34
77
  * By-completion: merge in the order milestones finished.
78
+ *
79
+ * When basePath is provided, also checks worktree SQLite DBs as the
80
+ * source of truth — workers with stale orchestrator state (e.g. "error")
81
+ * are included if their worktree DB shows status='complete'.
82
+ * See: https://github.com/gsd-build/gsd-2/issues/2812
35
83
  */
36
84
  export function determineMergeOrder(
37
85
  workers: WorkerInfo[],
38
86
  order: MergeOrder = "sequential",
87
+ basePath?: string,
39
88
  ): string[] {
40
- const completed = workers.filter(w => w.state === "stopped");
89
+ // Start with workers the orchestrator already knows are stopped
90
+ const stoppedIds = new Set(
91
+ workers.filter(w => w.state === "stopped").map(w => w.milestoneId),
92
+ );
93
+
94
+ // When basePath is available, also check worktree DBs for milestones
95
+ // whose orchestrator state is stale but are actually complete (#2812)
96
+ const dbCompleted = basePath ? discoverDbCompletedMilestones(basePath) : new Set<string>();
97
+
98
+ // Union: milestone is mergeable if stopped OR DB-complete
99
+ const mergeableIds = new Set([...stoppedIds, ...dbCompleted]);
100
+
101
+ // Build the list from tracked workers + any DB-discovered milestones
102
+ // not tracked by the orchestrator at all
103
+ const workerMap = new Map(workers.map(w => [w.milestoneId, w]));
104
+ const allMergeable: WorkerInfo[] = [];
105
+ for (const mid of mergeableIds) {
106
+ const w = workerMap.get(mid);
107
+ if (w) {
108
+ allMergeable.push(w);
109
+ } else {
110
+ // Milestone discovered from worktree DB but not in workers list
111
+ allMergeable.push({
112
+ milestoneId: mid,
113
+ title: mid,
114
+ pid: 0,
115
+ process: null,
116
+ worktreePath: basePath ? join(basePath, ".gsd", "worktrees", mid) : "",
117
+ startedAt: 0,
118
+ state: "stopped",
119
+ cost: 0,
120
+ });
121
+ }
122
+ }
123
+
41
124
  if (order === "by-completion") {
42
- return completed
125
+ return allMergeable
43
126
  .sort((a, b) => a.startedAt - b.startedAt) // earliest first
44
127
  .map(w => w.milestoneId);
45
128
  }
46
- return completed
129
+ return allMergeable
47
130
  .sort((a, b) => a.milestoneId.localeCompare(b.milestoneId))
48
131
  .map(w => w.milestoneId);
49
132
  }
@@ -114,7 +197,7 @@ export async function mergeAllCompleted(
114
197
  workers: WorkerInfo[],
115
198
  order: MergeOrder = "sequential",
116
199
  ): Promise<MergeResult[]> {
117
- const mergeOrder = determineMergeOrder(workers, order);
200
+ const mergeOrder = determineMergeOrder(workers, order, basePath);
118
201
  const results: MergeResult[] = [];
119
202
 
120
203
  for (const mid of mergeOrder) {
@@ -519,8 +519,19 @@ function createMilestoneWorktree(basePath: string, milestoneId: string): string
519
519
 
520
520
  /**
521
521
  * Spawn a worker process for a milestone.
522
- * The worker runs `gsd --print "/gsd auto"` in the milestone's worktree
522
+ * The worker runs `gsd headless --json auto` in the milestone's worktree
523
523
  * with GSD_MILESTONE_LOCK set to isolate state derivation.
524
+ *
525
+ * IMPORTANT: We use `headless --json auto` instead of `--print "/gsd auto"`.
526
+ * --print mode calls session.prompt() which returns immediately after the
527
+ * extension command handler fires, because auto-mode's ctx.newSession()
528
+ * resets the session and unblocks the outer prompt() await. This causes
529
+ * process.exit(0) to fire before any LLM work happens. See #2792.
530
+ *
531
+ * The headless subcommand uses an RPC client that keeps the process alive
532
+ * until auto-mode emits a terminal notification or the idle timer fires.
533
+ * It outputs NDJSON events to stdout (with --json), which our
534
+ * processWorkerLine() parser already understands.
524
535
  */
525
536
  export function spawnWorker(
526
537
  basePath: string,
@@ -537,7 +548,7 @@ export function spawnWorker(
537
548
 
538
549
  let child: ChildProcess;
539
550
  try {
540
- child = spawn(process.execPath, [binPath, "--mode", "json", "--print", "/gsd auto"], {
551
+ child = spawn(process.execPath, [binPath, "headless", "--json", "auto"], {
541
552
  cwd: worker.worktreePath,
542
553
  env: {
543
554
  ...process.env,
@@ -577,9 +588,10 @@ export function spawnWorker(
577
588
  }
578
589
 
579
590
  // ── NDJSON stdout monitoring ────────────────────────────────────────
580
- // Workers run with --mode json, emitting one JSON event per line.
581
- // We parse message_end events to extract cost/token usage, keeping
582
- // the coordinator's cost tracking in sync with actual API spend.
591
+ // Workers run via `headless --json`, which forwards all RPC events
592
+ // as NDJSON to stdout. We parse message_end events to extract
593
+ // cost/token usage, keeping the coordinator's cost tracking in sync
594
+ // with actual API spend.
583
595
  if (child.stdout) {
584
596
  let stdoutBuffer = "";
585
597
  child.stdout.on("data", (data: Buffer) => {
@@ -808,7 +820,12 @@ export async function stopParallel(
808
820
  } catch { /* process may already be dead */ }
809
821
  }
810
822
 
811
- const exitedAfterTerm = await waitForWorkerExit(worker, 750);
823
+ // Wait for the headless process to cascade SIGTERM to its RPC child.
824
+ // The headless signal handler calls client.stop() which sends SIGTERM
825
+ // to the RPC child and waits up to 1000ms. The previous 750ms window
826
+ // was insufficient — the parent got SIGKILL before the child died,
827
+ // leaving orphaned RPC processes holding auto.lock. See #2798.
828
+ const exitedAfterTerm = await waitForWorkerExit(worker, 3000);
812
829
  if (!exitedAfterTerm && worker.pid > 0) {
813
830
  try {
814
831
  if (worker.process) {
@@ -196,18 +196,28 @@ function _parsePlanImpl(content: string): SlicePlan {
196
196
  const mhSection = extractSection(body, 'Must-Haves');
197
197
  const mustHaves = mhSection ? parseBullets(mhSection) : [];
198
198
 
199
+ // Parse tasks from ## Tasks section first, then scan the full body for any
200
+ // task checkboxes that were missed. Multi-task plans can interleave T01 detail
201
+ // headings (## Steps, ## Must-Haves) before T02's checkbox, which causes
202
+ // extractSection("Tasks") to stop at the first ## heading and miss T02+ (#3105).
199
203
  const tasksSection = extractSection(body, 'Tasks');
200
204
  const tasks: TaskPlanEntry[] = [];
201
205
 
202
- if (tasksSection) {
203
- const taskLines = tasksSection.split('\n');
206
+ // Parse task entries from a set of lines, appending to `tasks`.
207
+ const parseTaskLines = (lines: string[], knownIds: Set<string>): void => {
204
208
  let currentTask: TaskPlanEntry | null = null;
205
209
 
206
- for (const line of taskLines) {
210
+ for (const line of lines) {
207
211
  const cbMatch = line.match(/^-\s+\[([ xX])\]\s+\*\*([\w.]+):\s+(.+?)\*\*\s*(.*)/);
208
212
  // Heading-style: ### T01 -- Title, ### T01: Title, ### T01 — Title
209
213
  const hdMatch = !cbMatch ? line.match(/^#{2,4}\s+([\w.]+)\s*(?:--|—|:)\s*(.+)/) : null;
210
214
  if (cbMatch || hdMatch) {
215
+ const taskId = cbMatch ? cbMatch[2] : hdMatch![1];
216
+ // Skip tasks already found in the Tasks section
217
+ if (knownIds.has(taskId)) {
218
+ currentTask = null;
219
+ continue;
220
+ }
211
221
  if (currentTask) tasks.push(currentTask);
212
222
 
213
223
  if (cbMatch) {
@@ -259,8 +269,17 @@ function _parsePlanImpl(content: string): SlicePlan {
259
269
  }
260
270
  }
261
271
  if (currentTask) tasks.push(currentTask);
272
+ };
273
+
274
+ if (tasksSection) {
275
+ parseTaskLines(tasksSection.split('\n'), new Set());
262
276
  }
263
277
 
278
+ // Second pass: scan the full body for task checkboxes outside ## Tasks.
279
+ // This handles interleaved plans where T02+ appear after T01's detail headings.
280
+ const foundIds = new Set(tasks.map(t => t.id));
281
+ parseTaskLines(body.split('\n'), foundIds);
282
+
264
283
  const filesSection = extractSection(body, 'Files Likely Touched');
265
284
  const filesLikelyTouched = filesSection ? parseBullets(filesSection) : [];
266
285
 
@@ -264,6 +264,7 @@ export const GSD_ROOT_FILES = {
264
264
  REQUIREMENTS: "REQUIREMENTS.md",
265
265
  OVERRIDES: "OVERRIDES.md",
266
266
  KNOWLEDGE: "KNOWLEDGE.md",
267
+ CODEBASE: "CODEBASE.md",
267
268
  } as const;
268
269
 
269
270
  export type GSDRootFileKey = keyof typeof GSD_ROOT_FILES;
@@ -276,6 +277,7 @@ const LEGACY_GSD_ROOT_FILES: Record<GSDRootFileKey, string> = {
276
277
  REQUIREMENTS: "requirements.md",
277
278
  OVERRIDES: "overrides.md",
278
279
  KNOWLEDGE: "knowledge.md",
280
+ CODEBASE: "codebase.md",
279
281
  };
280
282
 
281
283
  // ─── GSD Root Discovery ───────────────────────────────────────────────────────
@@ -307,16 +309,58 @@ export function gsdRoot(basePath: string): string {
307
309
  return result;
308
310
  }
309
311
 
312
+ /**
313
+ * Detect if a path is inside a .gsd/worktrees/<name>/ structure.
314
+ *
315
+ * GSD auto-worktrees live at <project>/.gsd/worktrees/<milestoneId>/.
316
+ * When gsdRoot() is called with such a path, we must NOT walk up to the
317
+ * project root's .gsd — each worktree manages its own .gsd state (#2594).
318
+ *
319
+ * Matches both forward-slash and platform-native separators to handle
320
+ * Windows paths (path.sep = '\\') and normalized Unix paths.
321
+ */
322
+ function isInsideGsdWorktree(p: string): boolean {
323
+ // Match /.gsd/worktrees/<name> where <name> is the final segment or
324
+ // followed by a separator. The <name> segment must be non-empty.
325
+ const sepFwd = "/";
326
+ const sepNative = "\\";
327
+ const markers = [
328
+ `${sepFwd}.gsd${sepFwd}worktrees${sepFwd}`,
329
+ `${sepNative}.gsd${sepNative}worktrees${sepNative}`,
330
+ ];
331
+ for (const marker of markers) {
332
+ const idx = p.indexOf(marker);
333
+ if (idx === -1) continue;
334
+ // Verify there's a non-empty worktree name after the marker
335
+ const afterMarker = p.slice(idx + marker.length);
336
+ // The name is everything up to the next separator (or end of string)
337
+ const nameEnd = afterMarker.search(/[/\\]/);
338
+ const name = nameEnd === -1 ? afterMarker : afterMarker.slice(0, nameEnd);
339
+ if (name.length > 0) return true;
340
+ }
341
+ return false;
342
+ }
343
+
310
344
  function probeGsdRoot(rawBasePath: string): string {
311
345
  // 1. Fast path — check the input path directly
312
346
  const local = join(rawBasePath, ".gsd");
313
347
  if (existsSync(local)) return local;
314
348
 
349
+ // 1b. Worktree guard (#2594) — if basePath is inside a .gsd/worktrees/<name>/
350
+ // structure, return the worktree-local .gsd path immediately. Without this,
351
+ // the git-root probe (step 2) or walk-up (step 3) escapes to the project
352
+ // root's .gsd, causing ensurePreconditions() and deriveState() to read/write
353
+ // state in the wrong location.
354
+ if (isInsideGsdWorktree(rawBasePath)) return local;
355
+
315
356
  // Resolve symlinks so path comparisons work correctly across platforms
316
357
  // (e.g. macOS /var → /private/var). Use rawBasePath as fallback if not resolvable.
317
358
  let basePath: string;
318
359
  try { basePath = realpathSync.native(rawBasePath); } catch { basePath = rawBasePath; }
319
360
 
361
+ // Also check the resolved path for the worktree pattern (macOS /tmp → /private/tmp)
362
+ if (basePath !== rawBasePath && isInsideGsdWorktree(basePath)) return local;
363
+
320
364
  // 2. Git root anchor — used as both probe target and walk-up boundary
321
365
  // Only walk if we're inside a git project — prevents escaping into
322
366
  // unrelated filesystem territory when running outside any repo.
@@ -69,6 +69,7 @@ export function resolveModelWithFallbacksForUnit(unitType: string): ResolvedMode
69
69
  break;
70
70
  case "complete-slice":
71
71
  case "complete-milestone":
72
+ case "worktree-merge":
72
73
  case "run-uat":
73
74
  phaseConfig = m.completion;
74
75
  break;
@@ -137,6 +138,18 @@ export function getNextFallbackModel(
137
138
  }
138
139
  }
139
140
 
141
+ /**
142
+ * Detect whether an error message indicates a transient network error
143
+ * (worth retrying the same model) vs a permanent provider error
144
+ * (auth failure, quota exceeded, etc. -- should fall back immediately).
145
+ */
146
+ export function isTransientNetworkError(errorMsg: string): boolean {
147
+ if (!errorMsg) return false;
148
+ const hasNetworkSignal = /network|ECONNRESET|ETIMEDOUT|ECONNREFUSED|socket hang up|fetch failed|connection.*reset|dns/i.test(errorMsg);
149
+ const hasPermanentSignal = /auth|unauthorized|forbidden|invalid.*key|quota|billing/i.test(errorMsg);
150
+ return hasNetworkSignal && !hasPermanentSignal;
151
+ }
152
+
140
153
  /**
141
154
  * Validate a model ID string.
142
155
  * Returns true if the ID looks like a valid model identifier.
@@ -308,7 +321,7 @@ export function resolveContextSelection(): import("./types.js").ContextSelection
308
321
  }
309
322
 
310
323
  /**
311
- * Resolve the search provider preference from PREFERENCES.md.
324
+ * Resolve the search provider preference from preferences.md.
312
325
  * Returns undefined if not configured (caller falls back to existing behavior).
313
326
  */
314
327
  export function resolveSearchProviderFromPreferences(): GSDPreferences["search_provider"] | undefined {
@@ -93,6 +93,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
93
93
  "service_tier",
94
94
  "forensics_dedup",
95
95
  "show_token_cost",
96
+ "stale_commit_threshold_minutes",
96
97
  "experimental",
97
98
  ]);
98
99
 
@@ -100,7 +101,8 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
100
101
  export const KNOWN_UNIT_TYPES = [
101
102
  "research-milestone", "plan-milestone", "research-slice", "plan-slice",
102
103
  "execute-task", "reactive-execute", "gate-evaluate", "complete-slice", "replan-slice", "reassess-roadmap",
103
- "run-uat", "complete-milestone",
104
+ "run-uat", "complete-milestone", "validate-milestone", "rewrite-docs",
105
+ "discuss-milestone", "discuss-slice", "worktree-merge",
104
106
  ] as const;
105
107
  export type UnitType = (typeof KNOWN_UNIT_TYPES)[number];
106
108
 
@@ -252,6 +254,13 @@ export interface GSDPreferences {
252
254
  forensics_dedup?: boolean;
253
255
  /** Opt-in: show per-prompt and cumulative session token cost in the footer. Default: false. */
254
256
  show_token_cost?: boolean;
257
+ /**
258
+ * Minutes without a commit before flagging uncommitted changes as stale.
259
+ * When the threshold is exceeded and the working tree is dirty, doctor will
260
+ * auto-commit a safety snapshot tagged with `[gsd safety]`. Default: 30.
261
+ * Set to 0 to disable.
262
+ */
263
+ stale_commit_threshold_minutes?: number;
255
264
  /**
256
265
  * Opt-in experimental features. All features here are disabled by default.
257
266
  * See the preferences reference for details on each feature.
@@ -22,6 +22,7 @@ import { normalizeStringArray } from "../shared/format-utils.js";
22
22
  import { resolveProfileDefaults as _resolveProfileDefaults } from "./preferences-models.js";
23
23
 
24
24
  import {
25
+ KNOWN_PREFERENCE_KEYS,
25
26
  MODE_DEFAULTS,
26
27
  type WorkflowMode,
27
28
  type GSDPreferences,
@@ -68,6 +69,7 @@ export {
68
69
  resolveModelForUnit,
69
70
  resolveModelWithFallbacksForUnit,
70
71
  getNextFallbackModel,
72
+ isTransientNetworkError,
71
73
  validateModelId,
72
74
  updatePreferencesModels,
73
75
  resolveDynamicRoutingConfig,
@@ -86,7 +88,7 @@ function gsdHome(): string {
86
88
  }
87
89
 
88
90
  function globalPreferencesPath(): string {
89
- return join(gsdHome(), "PREFERENCES.md");
91
+ return join(gsdHome(), "preferences.md");
90
92
  }
91
93
 
92
94
  function legacyGlobalPreferencesPath(): string {
@@ -94,15 +96,15 @@ function legacyGlobalPreferencesPath(): string {
94
96
  }
95
97
 
96
98
  function projectPreferencesPath(): string {
97
- return join(gsdRoot(process.cwd()), "PREFERENCES.md");
99
+ return join(gsdRoot(process.cwd()), "preferences.md");
98
100
  }
99
- // Legacy: older versions used lowercase preferences.md.
100
- // Check lowercase as a fallback so those files aren't silently ignored.
101
- function globalPreferencesPathLegacy(): string {
102
- return join(gsdHome(), "preferences.md");
101
+ // Bootstrap in gitignore.ts historically created PREFERENCES.md (uppercase) by mistake.
102
+ // Check uppercase as a fallback so those files aren't silently ignored.
103
+ function globalPreferencesPathUppercase(): string {
104
+ return join(gsdHome(), "PREFERENCES.md");
103
105
  }
104
- function projectPreferencesPathLegacy(): string {
105
- return join(gsdRoot(process.cwd()), "preferences.md");
106
+ function projectPreferencesPathUppercase(): string {
107
+ return join(gsdRoot(process.cwd()), "PREFERENCES.md");
106
108
  }
107
109
 
108
110
  export function getGlobalGSDPreferencesPath(): string {
@@ -121,13 +123,13 @@ export function getProjectGSDPreferencesPath(): string {
121
123
 
122
124
  export function loadGlobalGSDPreferences(): LoadedGSDPreferences | null {
123
125
  return loadPreferencesFile(globalPreferencesPath(), "global")
124
- ?? loadPreferencesFile(globalPreferencesPathLegacy(), "global")
126
+ ?? loadPreferencesFile(globalPreferencesPathUppercase(), "global")
125
127
  ?? loadPreferencesFile(legacyGlobalPreferencesPath(), "global");
126
128
  }
127
129
 
128
130
  export function loadProjectGSDPreferences(): LoadedGSDPreferences | null {
129
131
  return loadPreferencesFile(projectPreferencesPath(), "project")
130
- ?? loadPreferencesFile(projectPreferencesPathLegacy(), "project");
132
+ ?? loadPreferencesFile(projectPreferencesPathUppercase(), "project");
131
133
  }
132
134
 
133
135
  export function loadEffectiveGSDPreferences(): LoadedGSDPreferences | null {
@@ -222,7 +224,7 @@ export function parsePreferencesMarkdown(content: string): GSDPreferences | null
222
224
 
223
225
  if (!_warnedUnrecognizedFormat) {
224
226
  _warnedUnrecognizedFormat = true;
225
- console.warn("[parsePreferencesMarkdown] PREFERENCES.md exists but uses an unrecognized format — skipping.");
227
+ console.warn("[parsePreferencesMarkdown] preferences.md exists but uses an unrecognized format — skipping.");
226
228
  }
227
229
  return null;
228
230
  }
@@ -250,7 +252,7 @@ function parseFrontmatterBlock(frontmatter: string): GSDPreferences {
250
252
  * - planner: sonnet
251
253
  */
252
254
  function parseHeadingListFormat(content: string): GSDPreferences {
253
- const result: Record<string, Record<string, string>> = {};
255
+ const result: Record<string, string[]> = {};
254
256
  let currentSection: string | null = null;
255
257
 
256
258
  for (const rawLine of content.split('\n')) {
@@ -258,27 +260,44 @@ function parseHeadingListFormat(content: string): GSDPreferences {
258
260
  const headingMatch = line.match(/^##\s+(.+)$/);
259
261
  if (headingMatch) {
260
262
  currentSection = headingMatch[1].trim().toLowerCase().replace(/\s+/g, '_');
263
+ if (!result[currentSection]) result[currentSection] = [];
261
264
  continue;
262
265
  }
263
- if (currentSection) {
264
- const itemMatch = line.match(/^-\s+([^:]+):\s*(.*)$/);
265
- if (itemMatch) {
266
- if (!result[currentSection]) result[currentSection] = {};
267
- const value = itemMatch[2].trim();
268
- // Coerce "true"/"false" strings and numbers
269
- result[currentSection][itemMatch[1].trim()] = value;
270
- }
266
+ if (currentSection && line.trim() && !line.trimStart().startsWith('#')) {
267
+ result[currentSection].push(line);
271
268
  }
272
269
  }
273
270
 
274
- // Convert string values to appropriate types via YAML parser for each section
275
271
  const typed: Record<string, unknown> = {};
276
- for (const [section, entries] of Object.entries(result)) {
277
- const yamlLines = Object.entries(entries).map(([k, v]) => `${k}: ${v}`).join('\n');
272
+ for (const [section, lines] of Object.entries(result)) {
273
+ if (lines.length === 0) continue;
274
+
275
+ const usesLegacyListItems = lines.every((line) => /^\s*-\s+[^:]+:\s*.*$/.test(line));
276
+ const yamlBlock = usesLegacyListItems
277
+ ? lines.map((line) => line.replace(/^\s*-\s+/, '')).join('\n')
278
+ : lines.join('\n');
279
+
278
280
  try {
279
- typed[section] = parseYaml(yamlLines);
281
+ const parsed = parseYaml(yamlBlock);
282
+ if (typeof parsed !== 'object' || parsed === null) continue;
283
+
284
+ let targetSection = section;
285
+ let value: unknown = parsed;
286
+
287
+ if (!Array.isArray(parsed)) {
288
+ const keys = Object.keys(parsed);
289
+ if (keys.length === 1) {
290
+ const [onlyKey] = keys;
291
+ if (onlyKey === section || (!KNOWN_PREFERENCE_KEYS.has(section) && KNOWN_PREFERENCE_KEYS.has(onlyKey))) {
292
+ targetSection = onlyKey;
293
+ value = (parsed as Record<string, unknown>)[onlyKey];
294
+ }
295
+ }
296
+ }
297
+
298
+ typed[targetSection] = value;
280
299
  } catch {
281
- typed[section] = entries;
300
+ /* malformed section skip */
282
301
  }
283
302
  }
284
303
 
@@ -352,9 +371,6 @@ function mergePreferences(base: GSDPreferences, override: GSDPreferences): GSDPr
352
371
  service_tier: override.service_tier ?? base.service_tier,
353
372
  forensics_dedup: override.forensics_dedup ?? base.forensics_dedup,
354
373
  show_token_cost: override.show_token_cost ?? base.show_token_cost,
355
- experimental: (base.experimental || override.experimental)
356
- ? { ...(base.experimental ?? {}), ...(override.experimental ?? {}) }
357
- : undefined,
358
374
  };
359
375
  }
360
376
 
@@ -501,7 +517,7 @@ export function resolvePreDispatchHooks(): PreDispatchHookConfig[] {
501
517
  * Resolve the effective git isolation mode from preferences.
502
518
  * Returns "none" (default), "worktree", or "branch".
503
519
  *
504
- * Default is "none" so GSD works out of the box without PREFERENCES.md.
520
+ * Default is "none" so GSD works out of the box without preferences.md.
505
521
  * Worktree isolation requires explicit opt-in because it depends on git
506
522
  * branch infrastructure that must be set up before use.
507
523
  */
@@ -134,7 +134,10 @@ export function loadPrompt(name: string, vars: Record<string, string> = {}): str
134
134
  }
135
135
 
136
136
  for (const [key, value] of Object.entries(effectiveVars)) {
137
- content = content.replaceAll(`{{${key}}}`, value);
137
+ // Use split/join instead of replaceAll to avoid JavaScript's special
138
+ // replacement patterns ($', $`, $&) being interpreted in the value.
139
+ // See: https://github.com/gsd-build/gsd-2/issues/2968
140
+ content = content.split(`{{${key}}}`).join(value);
138
141
  }
139
142
 
140
143
  return content.trim();