gsd-pi 2.57.0-dev.f22a903 → 2.58.0-dev.778d6ac

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 (643) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +49 -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/phases.js +25 -21
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  22. package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -2
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
  26. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  27. package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
  28. package/dist/resources/extensions/gsd/auto-start.js +35 -22
  29. package/dist/resources/extensions/gsd/auto-worktree.js +196 -12
  30. package/dist/resources/extensions/gsd/auto.js +4 -0
  31. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
  32. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
  33. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
  35. package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
  36. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
  37. package/dist/resources/extensions/gsd/captures.js +56 -4
  38. package/dist/resources/extensions/gsd/db-writer.js +116 -8
  39. package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
  40. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  41. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
  42. package/dist/resources/extensions/gsd/doctor.js +3 -1
  43. package/dist/resources/extensions/gsd/error-classifier.js +13 -10
  44. package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
  45. package/dist/resources/extensions/gsd/forensics.js +123 -20
  46. package/dist/resources/extensions/gsd/git-service.js +23 -1
  47. package/dist/resources/extensions/gsd/gitignore.js +33 -0
  48. package/dist/resources/extensions/gsd/gsd-db.js +36 -9
  49. package/dist/resources/extensions/gsd/guided-flow.js +106 -44
  50. package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
  51. package/dist/resources/extensions/gsd/health-widget.js +17 -0
  52. package/dist/resources/extensions/gsd/index.js +1 -1
  53. package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
  54. package/dist/resources/extensions/gsd/migrate-external.js +8 -1
  55. package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
  56. package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
  57. package/dist/resources/extensions/gsd/model-router.js +35 -1
  58. package/dist/resources/extensions/gsd/native-git-bridge.js +17 -0
  59. package/dist/resources/extensions/gsd/notifications.js +16 -1
  60. package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
  61. package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
  62. package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
  63. package/dist/resources/extensions/gsd/paths.js +43 -0
  64. package/dist/resources/extensions/gsd/preferences-models.js +14 -1
  65. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  66. package/dist/resources/extensions/gsd/preferences.js +13 -16
  67. package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
  68. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  69. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  70. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  71. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
  73. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  74. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  75. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  77. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  79. package/dist/resources/extensions/gsd/repo-identity.js +205 -11
  80. package/dist/resources/extensions/gsd/rethink.js +5 -0
  81. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
  82. package/dist/resources/extensions/gsd/state.js +85 -27
  83. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  84. package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
  85. package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
  86. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
  87. package/dist/resources/extensions/gsd/tools/validate-milestone.js +14 -3
  88. package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
  89. package/dist/resources/extensions/gsd/undo.js +2 -2
  90. package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
  91. package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
  92. package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
  93. package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
  94. package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
  95. package/dist/resources/extensions/gsd/workspace-index.js +24 -0
  96. package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
  97. package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
  98. package/dist/resources/extensions/mcp-client/index.js +11 -7
  99. package/dist/resources/extensions/ollama/index.js +112 -0
  100. package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
  101. package/dist/resources/extensions/ollama/ollama-client.js +168 -0
  102. package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
  103. package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
  104. package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
  105. package/dist/resources/extensions/ollama/types.js +2 -0
  106. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  107. package/dist/resources/extensions/shared/interview-ui.js +11 -1
  108. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
  109. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  110. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  111. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  112. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  113. package/dist/startup-model-validation.d.ts +39 -0
  114. package/dist/startup-model-validation.js +50 -0
  115. package/dist/web/standalone/.next/BUILD_ID +1 -1
  116. package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
  117. package/dist/web/standalone/.next/build-manifest.json +3 -3
  118. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  119. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  122. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  138. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/index.html +1 -1
  193. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  194. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  195. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  196. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  197. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  198. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  199. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
  201. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  202. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  205. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  206. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  207. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
  208. package/dist/web/standalone/.next/static/chunks/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
  209. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
  210. package/dist/web-mode.js +2 -1
  211. package/package.json +2 -2
  212. package/packages/daemon/src/cli.ts +49 -0
  213. package/packages/daemon/src/daemon.test.ts +104 -1
  214. package/packages/daemon/src/daemon.ts +24 -1
  215. package/packages/daemon/src/discord-bot.ts +73 -3
  216. package/packages/daemon/src/event-bridge.ts +15 -9
  217. package/packages/daemon/src/event-formatter.ts +30 -2
  218. package/packages/daemon/src/index.ts +9 -0
  219. package/packages/daemon/src/launchd.test.ts +356 -0
  220. package/packages/daemon/src/launchd.ts +242 -0
  221. package/packages/daemon/src/message-batcher.test.ts +2 -2
  222. package/packages/daemon/src/message-batcher.ts +9 -3
  223. package/packages/daemon/src/orchestrator.test.ts +1 -0
  224. package/packages/daemon/src/orchestrator.ts +106 -2
  225. package/packages/native/dist/ast/index.js +9 -5
  226. package/packages/native/dist/ast/types.js +2 -1
  227. package/packages/native/dist/clipboard/index.js +12 -7
  228. package/packages/native/dist/clipboard/types.js +2 -1
  229. package/packages/native/dist/diff/index.js +12 -7
  230. package/packages/native/dist/diff/types.js +2 -1
  231. package/packages/native/dist/fd/index.js +6 -3
  232. package/packages/native/dist/fd/types.js +2 -1
  233. package/packages/native/dist/glob/index.js +9 -5
  234. package/packages/native/dist/glob/types.js +2 -1
  235. package/packages/native/dist/grep/index.js +9 -5
  236. package/packages/native/dist/grep/types.js +2 -1
  237. package/packages/native/dist/gsd-parser/index.js +18 -11
  238. package/packages/native/dist/gsd-parser/types.js +2 -1
  239. package/packages/native/dist/highlight/index.js +12 -7
  240. package/packages/native/dist/highlight/types.js +2 -1
  241. package/packages/native/dist/html/index.js +6 -3
  242. package/packages/native/dist/html/types.js +2 -1
  243. package/packages/native/dist/image/index.js +10 -5
  244. package/packages/native/dist/image/types.js +7 -4
  245. package/packages/native/dist/index.js +70 -17
  246. package/packages/native/dist/json-parse/index.js +13 -8
  247. package/packages/native/dist/native.js +47 -10
  248. package/packages/native/dist/ps/index.js +15 -9
  249. package/packages/native/dist/ps/types.js +2 -1
  250. package/packages/native/dist/stream-process/index.js +12 -7
  251. package/packages/native/dist/text/index.js +24 -14
  252. package/packages/native/dist/text/types.js +5 -2
  253. package/packages/native/dist/truncate/index.js +12 -7
  254. package/packages/native/dist/ttsr/index.js +12 -7
  255. package/packages/native/dist/ttsr/types.js +2 -1
  256. package/packages/native/dist/xxhash/index.js +9 -5
  257. package/packages/native/package.json +19 -19
  258. package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
  259. package/packages/native/src/native.ts +9 -8
  260. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  261. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  262. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  263. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  264. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  265. package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
  266. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  267. package/packages/pi-agent-core/src/proxy.ts +1 -1
  268. package/packages/pi-ai/dist/env-api-keys.js +1 -0
  269. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  270. package/packages/pi-ai/dist/index.d.ts +1 -0
  271. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  272. package/packages/pi-ai/dist/index.js +1 -0
  273. package/packages/pi-ai/dist/index.js.map +1 -1
  274. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  275. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
  276. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  277. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
  278. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
  279. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
  280. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
  281. package/packages/pi-ai/dist/types.d.ts +3 -3
  282. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  283. package/packages/pi-ai/dist/types.js.map +1 -1
  284. package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
  285. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  286. package/packages/pi-ai/dist/utils/json-parse.js +24 -1
  287. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  288. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
  289. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
  290. package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
  291. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
  292. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
  293. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
  294. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
  295. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
  296. package/packages/pi-ai/src/env-api-keys.ts +1 -0
  297. package/packages/pi-ai/src/index.ts +1 -0
  298. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
  299. package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
  300. package/packages/pi-ai/src/types.ts +3 -2
  301. package/packages/pi-ai/src/utils/json-parse.ts +28 -1
  302. package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
  303. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
  304. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  305. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
  307. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
  309. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
  311. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
  313. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
  314. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
  315. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
  316. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  317. package/packages/pi-coding-agent/dist/core/exec.js +3 -1
  318. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  319. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
  320. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
  321. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
  322. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
  323. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
  324. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
  325. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
  326. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
  327. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
  328. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
  329. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
  330. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
  331. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
  332. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
  333. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
  334. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
  335. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
  336. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  337. package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
  338. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  339. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  340. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  341. package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
  342. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  343. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
  344. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
  345. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
  346. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
  347. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
  348. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
  349. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
  350. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
  351. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  352. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  353. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  354. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  355. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  356. package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
  357. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  358. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  359. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
  360. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  361. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/core/messages.js +31 -2
  363. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
  365. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
  366. package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
  367. package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
  368. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  370. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
  372. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
  374. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
  376. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  377. package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
  378. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
  380. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
  381. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
  382. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
  383. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
  385. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  386. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
  388. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  389. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
  390. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
  391. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
  392. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
  393. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  394. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  395. package/packages/pi-coding-agent/dist/index.js +1 -1
  396. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  397. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  398. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
  399. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  400. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
  401. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  402. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
  403. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  404. package/packages/pi-coding-agent/package.json +1 -1
  405. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
  406. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
  407. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
  408. package/packages/pi-coding-agent/src/core/exec.ts +3 -1
  409. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
  410. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
  411. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
  412. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
  413. package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
  414. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  415. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
  416. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
  417. package/packages/pi-coding-agent/src/core/index.ts +6 -0
  418. package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
  419. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
  420. package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
  421. package/packages/pi-coding-agent/src/core/messages.ts +29 -2
  422. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  423. package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
  424. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
  425. package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
  426. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
  427. package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
  428. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
  429. package/packages/pi-coding-agent/src/index.ts +6 -0
  430. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
  431. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
  432. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  433. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  434. package/packages/pi-tui/dist/terminal.js +9 -0
  435. package/packages/pi-tui/dist/terminal.js.map +1 -1
  436. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  437. package/packages/pi-tui/dist/tui.js +9 -0
  438. package/packages/pi-tui/dist/tui.js.map +1 -1
  439. package/packages/pi-tui/src/terminal.ts +14 -0
  440. package/packages/pi-tui/src/tui.ts +8 -0
  441. package/pkg/package.json +1 -1
  442. package/scripts/ensure-workspace-builds.cjs +45 -14
  443. package/src/resources/agents/researcher.md +1 -1
  444. package/src/resources/extensions/ask-user-questions.ts +21 -3
  445. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  446. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  447. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  448. package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
  449. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
  450. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
  451. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
  452. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  453. package/src/resources/extensions/get-secrets-from-user.ts +8 -5
  454. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  455. package/src/resources/extensions/google-search/index.ts +2 -1
  456. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  457. package/src/resources/extensions/gsd/auto/phases.ts +43 -34
  458. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  459. package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
  460. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
  461. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
  462. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  463. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  464. package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
  465. package/src/resources/extensions/gsd/auto-start.ts +35 -26
  466. package/src/resources/extensions/gsd/auto-worktree.ts +190 -9
  467. package/src/resources/extensions/gsd/auto.ts +5 -0
  468. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
  469. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
  470. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
  471. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
  472. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
  473. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
  474. package/src/resources/extensions/gsd/captures.ts +63 -3
  475. package/src/resources/extensions/gsd/db-writer.ts +140 -7
  476. package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
  477. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  478. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
  479. package/src/resources/extensions/gsd/doctor.ts +3 -1
  480. package/src/resources/extensions/gsd/error-classifier.ts +14 -11
  481. package/src/resources/extensions/gsd/extension-manifest.json +16 -1
  482. package/src/resources/extensions/gsd/forensics.ts +144 -20
  483. package/src/resources/extensions/gsd/git-service.ts +26 -3
  484. package/src/resources/extensions/gsd/gitignore.ts +33 -0
  485. package/src/resources/extensions/gsd/gsd-db.ts +43 -7
  486. package/src/resources/extensions/gsd/guided-flow.ts +114 -45
  487. package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
  488. package/src/resources/extensions/gsd/health-widget.ts +17 -0
  489. package/src/resources/extensions/gsd/index.ts +1 -0
  490. package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
  491. package/src/resources/extensions/gsd/migrate-external.ts +9 -1
  492. package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
  493. package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
  494. package/src/resources/extensions/gsd/model-router.ts +35 -1
  495. package/src/resources/extensions/gsd/native-git-bridge.ts +17 -0
  496. package/src/resources/extensions/gsd/notifications.ts +16 -0
  497. package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
  498. package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
  499. package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
  500. package/src/resources/extensions/gsd/paths.ts +42 -0
  501. package/src/resources/extensions/gsd/preferences-models.ts +14 -1
  502. package/src/resources/extensions/gsd/preferences-types.ts +2 -1
  503. package/src/resources/extensions/gsd/preferences.ts +13 -15
  504. package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
  505. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  506. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  507. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  508. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  509. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
  510. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  511. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  512. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  513. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  514. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  515. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  516. package/src/resources/extensions/gsd/repo-identity.ts +186 -11
  517. package/src/resources/extensions/gsd/rethink.ts +6 -0
  518. package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
  519. package/src/resources/extensions/gsd/state.ts +84 -32
  520. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
  521. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
  522. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
  523. package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
  524. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
  525. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
  526. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
  527. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
  528. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
  529. package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
  530. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
  531. package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
  532. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
  533. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
  534. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
  535. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  536. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
  537. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
  538. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
  539. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
  540. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
  541. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
  542. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
  543. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
  544. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
  545. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
  546. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
  547. package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
  548. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
  549. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
  550. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
  551. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
  552. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
  553. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
  554. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
  555. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  556. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
  557. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
  558. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
  559. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
  560. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
  561. package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
  562. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
  563. package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
  564. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
  565. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
  566. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
  567. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
  568. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
  569. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -0
  570. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
  571. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
  572. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
  573. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
  574. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
  575. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
  576. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
  577. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
  578. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
  579. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
  580. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
  581. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
  582. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
  583. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
  584. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
  585. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
  586. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
  587. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
  588. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
  589. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
  590. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
  591. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
  592. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +4 -1
  593. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
  594. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
  595. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
  596. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
  597. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
  598. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
  599. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
  600. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
  601. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
  602. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
  603. package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
  604. package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
  605. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
  606. package/src/resources/extensions/gsd/tools/validate-milestone.ts +20 -2
  607. package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
  608. package/src/resources/extensions/gsd/types.ts +4 -2
  609. package/src/resources/extensions/gsd/undo.ts +2 -2
  610. package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
  611. package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
  612. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  613. package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
  614. package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
  615. package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
  616. package/src/resources/extensions/gsd/workspace-index.ts +30 -0
  617. package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
  618. package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
  619. package/src/resources/extensions/mcp-client/index.ts +13 -7
  620. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
  621. package/src/resources/extensions/ollama/index.ts +130 -0
  622. package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
  623. package/src/resources/extensions/ollama/ollama-client.ts +196 -0
  624. package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
  625. package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
  626. package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
  627. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
  628. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
  629. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
  630. package/src/resources/extensions/ollama/types.ts +130 -0
  631. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  632. package/src/resources/extensions/shared/interview-ui.ts +12 -1
  633. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
  634. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
  635. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  636. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  637. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  638. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  639. package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +0 -9
  640. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
  641. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
  642. /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
  643. /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
@@ -54,6 +54,7 @@ For each capture, classify it as one of:
54
54
  - Add `**Resolution:** <brief description of what will happen>`
55
55
  - Add `**Rationale:** <why this classification>`
56
56
  - Add `**Resolved:** <current ISO timestamp>`
57
+ - Add `**Milestone:** <current milestone ID>` (e.g., `**Milestone:** M003`)
57
58
 
58
59
  4. **Summarize** what was triaged: how many captures, what classifications were assigned, and what actions are pending (e.g., "2 quick-tasks ready for execution, 1 deferred to S03").
59
60
 
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { createHash } from "node:crypto";
9
9
  import { execFileSync } from "node:child_process";
10
- import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
10
+ import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
11
11
  import { homedir } from "node:os";
12
12
  import { basename, dirname, join, resolve } from "node:path";
13
13
  const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
@@ -255,9 +255,14 @@ export function validateProjectId(id) {
255
255
  * If `GSD_PROJECT_ID` is set, returns it directly (validation is expected
256
256
  * to have already happened at startup via `validateProjectId`).
257
257
  *
258
- * Otherwise returns SHA-256 of `${remoteUrl}\n${resolvedRoot}`, truncated
259
- * to 12 hex chars. Deterministic: same repo always produces the same hash
260
- * regardless of which worktree the caller is inside.
258
+ * For repos with a remote URL, returns SHA-256 of the remote URL only —
259
+ * this makes the identity stable across directory moves/renames (#2750).
260
+ *
261
+ * For local-only repos (no remote), includes the git root in the hash.
262
+ * Local repos use a `.gsd-id` marker file for recovery after moves.
263
+ *
264
+ * Deterministic: same repo always produces the same hash regardless of
265
+ * which worktree the caller is inside.
261
266
  */
262
267
  export function repoIdentity(basePath) {
263
268
  const projectId = process.env.GSD_PROJECT_ID;
@@ -265,8 +270,14 @@ export function repoIdentity(basePath) {
265
270
  return projectId;
266
271
  }
267
272
  const remoteUrl = getRemoteUrl(basePath);
273
+ if (remoteUrl) {
274
+ // Remote URL alone uniquely identifies the repo — path is redundant.
275
+ // This makes moves transparent for repos with remotes (#2750).
276
+ return createHash("sha256").update(remoteUrl).digest("hex").slice(0, 12);
277
+ }
278
+ // Local-only repo: include git root since there's no remote to anchor identity.
268
279
  const root = resolveGitRoot(basePath);
269
- const input = `${remoteUrl}\n${root}`;
280
+ const input = `\n${root}`;
270
281
  return createHash("sha256").update(input).digest("hex").slice(0, 12);
271
282
  }
272
283
  // ─── External State Directory ───────────────────────────────────────────────
@@ -325,20 +336,149 @@ export function cleanNumberedGsdVariants(projectPath) {
325
336
  }
326
337
  return removed;
327
338
  }
339
+ // ─── .gsd-id Marker ─────────────────────────────────────────────────────────
340
+ /**
341
+ * Write a `.gsd-id` marker file in the project root.
342
+ *
343
+ * This file records the identity hash used for the external state directory.
344
+ * For local-only repos (no remote), this marker survives directory moves and
345
+ * enables automatic recovery of orphaned state (#2750).
346
+ *
347
+ * The marker is gitignored by ensureGitignore(). Non-fatal: failure to write
348
+ * the marker must never block project setup.
349
+ */
350
+ function writeGsdIdMarker(projectPath, identity) {
351
+ try {
352
+ const markerPath = join(projectPath, ".gsd-id");
353
+ // Only write if content differs to avoid unnecessary disk writes.
354
+ if (existsSync(markerPath)) {
355
+ try {
356
+ if (readFileSync(markerPath, "utf-8").trim() === identity)
357
+ return;
358
+ }
359
+ catch { /* fall through and overwrite */ }
360
+ }
361
+ writeFileSync(markerPath, identity + "\n", "utf-8");
362
+ }
363
+ catch {
364
+ // Non-fatal — marker write failure should not block project setup
365
+ }
366
+ }
367
+ /**
368
+ * Read the `.gsd-id` marker from the project root.
369
+ * Returns the identity hash, or null if the marker doesn't exist or is unreadable.
370
+ */
371
+ function readGsdIdMarker(projectPath) {
372
+ try {
373
+ const markerPath = join(projectPath, ".gsd-id");
374
+ if (!existsSync(markerPath))
375
+ return null;
376
+ const content = readFileSync(markerPath, "utf-8").trim();
377
+ return /^[a-zA-Z0-9_-]+$/.test(content) ? content : null;
378
+ }
379
+ catch {
380
+ return null;
381
+ }
382
+ }
383
+ /**
384
+ * Check whether an external state directory has meaningful content.
385
+ * Returns true if the directory contains any files or subdirectories
386
+ * beyond just repo-meta.json.
387
+ */
388
+ function hasProjectState(externalPath) {
389
+ try {
390
+ if (!existsSync(externalPath))
391
+ return false;
392
+ const entries = readdirSync(externalPath);
393
+ return entries.some(e => e !== "repo-meta.json");
394
+ }
395
+ catch {
396
+ return false;
397
+ }
398
+ }
399
+ /**
400
+ * Resolve the external state directory, with recovery for relocated projects.
401
+ *
402
+ * For local-only repos where the computed identity produces an empty state dir,
403
+ * checks the `.gsd-id` marker for the original identity hash and recovers
404
+ * the old state directory if it still exists and contains data (#2750).
405
+ *
406
+ * Returns the resolved external path (may differ from the computed identity).
407
+ */
408
+ function resolveExternalPathWithRecovery(projectPath) {
409
+ const computedPath = externalGsdRoot(projectPath);
410
+ const computedId = repoIdentity(projectPath);
411
+ // Check if computed path already has state — fast path, no recovery needed.
412
+ if (hasProjectState(computedPath)) {
413
+ return computedPath;
414
+ }
415
+ // Check for .gsd-id marker from a previous location.
416
+ const markerId = readGsdIdMarker(projectPath);
417
+ if (markerId && markerId !== computedId) {
418
+ // The marker points to a different identity — the repo was likely moved.
419
+ const base = process.env.GSD_STATE_DIR || gsdHome;
420
+ const markerPath = join(base, "projects", markerId);
421
+ if (hasProjectState(markerPath)) {
422
+ // Recover: use the old state directory and update the marker to the new identity.
423
+ // Move the state from the old hash dir to the new one so future lookups work
424
+ // without the marker.
425
+ try {
426
+ mkdirSync(computedPath, { recursive: true });
427
+ const entries = readdirSync(markerPath);
428
+ for (const entry of entries) {
429
+ try {
430
+ const src = join(markerPath, entry);
431
+ const dst = join(computedPath, entry);
432
+ // Use rename for same-filesystem (fast) or fall back to copy.
433
+ try {
434
+ renameSync(src, dst);
435
+ }
436
+ catch {
437
+ cpSync(src, dst, { recursive: true, force: true });
438
+ }
439
+ }
440
+ catch { /* continue with remaining entries */ }
441
+ }
442
+ // Clean up old directory after successful migration.
443
+ try {
444
+ rmSync(markerPath, { recursive: true, force: true });
445
+ }
446
+ catch { /* non-fatal */ }
447
+ }
448
+ catch {
449
+ // If migration fails, just point at the old directory.
450
+ return markerPath;
451
+ }
452
+ }
453
+ }
454
+ return computedPath;
455
+ }
328
456
  // ─── Symlink Management ─────────────────────────────────────────────────────
329
457
  /**
330
458
  * Ensure the `<project>/.gsd` symlink points to the external state directory.
331
459
  *
332
460
  * 1. Clean up any macOS numbered collision variants (`.gsd 2`, `.gsd 3`, etc.)
333
- * 2. mkdir -p the external dir
334
- * 3. If `<project>/.gsd` doesn't exist → create symlink
335
- * 4. If `<project>/.gsd` is already the correct symlink → no-op
336
- * 5. If `<project>/.gsd` is a real directoryreturn as-is (migration handles later)
461
+ * 2. Resolve external dir (with relocation recovery via `.gsd-id` marker)
462
+ * 3. mkdir -p the external dir
463
+ * 4. If `<project>/.gsd` doesn't exist create symlink
464
+ * 5. If `<project>/.gsd` is already the correct symlink no-op
465
+ * 6. If `<project>/.gsd` is a real directory → return as-is (migration handles later)
466
+ * 7. Write `.gsd-id` marker for future relocation recovery
337
467
  *
338
468
  * Returns the resolved external path.
339
469
  */
340
470
  export function ensureGsdSymlink(projectPath) {
341
- const externalPath = externalGsdRoot(projectPath);
471
+ const result = ensureGsdSymlinkCore(projectPath);
472
+ // Write .gsd-id marker so future relocations can recover this state (#2750).
473
+ // Only write for the project root (not subdirectories or worktrees that
474
+ // delegate to a parent .gsd).
475
+ if (!isInsideWorktree(projectPath)) {
476
+ writeGsdIdMarker(projectPath, repoIdentity(projectPath));
477
+ }
478
+ return result;
479
+ }
480
+ function ensureGsdSymlinkCore(projectPath) {
481
+ const externalPath = resolveExternalPathWithRecovery(projectPath);
342
482
  const localGsd = join(projectPath, ".gsd");
343
483
  const inWorktree = isInsideWorktree(projectPath);
344
484
  // Guard: Never create a symlink at ~/.gsd — that's the user-level GSD home,
@@ -387,11 +527,34 @@ export function ensureGsdSymlink(projectPath) {
387
527
  writeRepoMeta(externalPath, getRemoteUrl(projectPath), resolveGitRoot(projectPath));
388
528
  const replaceWithSymlink = () => {
389
529
  rmSync(localGsd, { recursive: true, force: true });
530
+ // Defensive: remove any residual entry (e.g. dangling symlink) before creating.
531
+ try {
532
+ unlinkSync(localGsd);
533
+ }
534
+ catch { /* already gone */ }
390
535
  symlinkSync(externalPath, localGsd, "junction");
391
536
  return externalPath;
392
537
  };
538
+ // Check for dangling symlinks (e.g. after relocation recovery removed the old
539
+ // state dir). existsSync follows symlinks, so it returns false for dangling ones.
540
+ // lstatSync does NOT follow, so we can detect the dangling symlink and replace it.
393
541
  if (!existsSync(localGsd)) {
394
- // Nothing exists yet — create symlink
542
+ try {
543
+ const stat = lstatSync(localGsd);
544
+ if (stat.isSymbolicLink()) {
545
+ // Dangling symlink — replace with correct one (#2750).
546
+ return replaceWithSymlink();
547
+ }
548
+ }
549
+ catch {
550
+ // lstat also failed — nothing exists at this path
551
+ }
552
+ // Nothing exists yet — create symlink.
553
+ // Defensive: remove any residual entry to avoid EEXIST race (#2750).
554
+ try {
555
+ unlinkSync(localGsd);
556
+ }
557
+ catch { /* nothing to remove */ }
395
558
  symlinkSync(externalPath, localGsd, "junction");
396
559
  return externalPath;
397
560
  }
@@ -408,6 +571,37 @@ export function ensureGsdSymlink(projectPath) {
408
571
  if (inWorktree) {
409
572
  return replaceWithSymlink();
410
573
  }
574
+ // After identity hash change (e.g. upgrade from path-based to remote-only
575
+ // hash, or relocation recovery), migrate data from old target to new path
576
+ // and update the symlink (#2750).
577
+ if (!hasProjectState(externalPath) && hasProjectState(target)) {
578
+ try {
579
+ mkdirSync(externalPath, { recursive: true });
580
+ const oldEntries = readdirSync(target);
581
+ for (const entry of oldEntries) {
582
+ try {
583
+ const src = join(target, entry);
584
+ const dst = join(externalPath, entry);
585
+ try {
586
+ renameSync(src, dst);
587
+ }
588
+ catch {
589
+ cpSync(src, dst, { recursive: true, force: true });
590
+ }
591
+ }
592
+ catch { /* continue */ }
593
+ }
594
+ try {
595
+ rmSync(target, { recursive: true, force: true });
596
+ }
597
+ catch { /* non-fatal */ }
598
+ return replaceWithSymlink();
599
+ }
600
+ catch {
601
+ // Migration failed — preserve old symlink
602
+ return target;
603
+ }
604
+ }
411
605
  // Outside worktrees, preserve custom overrides or legacy symlinks.
412
606
  return target;
413
607
  }
@@ -16,6 +16,7 @@ import { getParkedReason } from "./milestone-actions.js";
16
16
  import { getMilestoneSlices, isDbAvailable } from "./gsd-db.js";
17
17
  import { buildExistingMilestonesContext } from "./guided-flow-queue.js";
18
18
  import { loadPrompt } from "./prompt-loader.js";
19
+ import { isGsdGitignored } from "./gitignore.js";
19
20
  // ─── Entry Point ──────────────────────────────────────────────────────────────
20
21
  export async function handleRethink(_args, ctx, pi) {
21
22
  if (isAutoActive()) {
@@ -38,9 +39,13 @@ export async function handleRethink(_args, ctx, pi) {
38
39
  const queueOrder = loadQueueOrder(basePath);
39
40
  const rethinkData = buildRethinkData(basePath, milestoneIds, state, queueOrder);
40
41
  const existingMilestonesContext = await buildExistingMilestonesContext(basePath, milestoneIds, state);
42
+ const commitInstruction = isGsdGitignored(basePath)
43
+ ? "Do not commit planning artifacts — .gsd/ is gitignored in this project."
44
+ : 'After changes, run `git add .gsd/ && git commit -m "docs(gsd): rethink milestone plan"` to persist (rethink runs interactively outside auto-mode, so no system auto-commit)';
41
45
  const content = loadPrompt("rethink", {
42
46
  rethinkData,
43
47
  existingMilestonesContext,
48
+ commitInstruction,
44
49
  });
45
50
  pi.sendMessage({ customType: "gsd-rethink", content, display: false }, { triggerTurn: true });
46
51
  }
@@ -211,12 +211,13 @@ export function parseRoadmapSlices(content) {
211
211
  function parseProseSliceHeaders(content) {
212
212
  const slices = [];
213
213
  // Match H1-H4 headers containing S<digits> with optional "Slice" prefix, bold markers,
214
- // and optional checkmark completion marker before the slice ID.
214
+ // numeric prefixes (e.g., "1.", "(1)"), bracketed IDs (e.g., "[S01]"),
215
+ // optional checkmark completion marker, and optional leading indentation.
215
216
  // Separator after the ID is flexible: colon, dash, em/en dash, dot, or just whitespace.
216
- const headerPattern = /^#{1,4}\s+\*{0,2}(?:\u2713\s+)?(?:Slice\s+)?(S\d+)\*{0,2}[:\s.\u2014\u2013-]*\s*(.+)/gm;
217
+ const headerPattern = /^\s*#{1,4}\s+\*{0,2}(?:\u2713\s+)?(?:\d+[.)]\s+)?(?:\(\d+\)\s+)?(?:Slice\s+)?\[?(S\d+)\]?\*{0,2}[:\s.\u2014\u2013-]*\s*(.+)/gm;
217
218
  let match;
218
219
  // Check for checkmark before the slice ID (e.g., "## checkmark S01: Title")
219
- const prefixCheckPattern = /^#{1,4}\s+\*{0,2}\u2713\s+/;
220
+ const prefixCheckPattern = /^\s*#{1,4}\s+\*{0,2}\u2713\s+/;
220
221
  while ((match = headerPattern.exec(content)) !== null) {
221
222
  const id = match[1];
222
223
  let title = match[2].trim().replace(/\*{1,2}$/g, "").trim(); // strip trailing bold markers
@@ -238,7 +239,7 @@ function parseProseSliceHeaders(content) {
238
239
  }
239
240
  // Try to extract depends from prose: "Depends on: S01" or "**Depends on:** S01, S02"
240
241
  const afterHeader = content.slice(match.index + match[0].length);
241
- const nextHeader = afterHeader.search(/^#{1,4}\s/m);
242
+ const nextHeader = afterHeader.search(/^\s*#{1,4}\s/m);
242
243
  const section = nextHeader !== -1 ? afterHeader.slice(0, nextHeader) : afterHeader.slice(0, 500);
243
244
  const depsMatch = section.match(/\*{0,2}Depends\s+on:?\*{0,2}\s*(.+)/i);
244
245
  let depends = [];
@@ -6,20 +6,41 @@ import { parseSummary, loadFile, parseRequirementCounts, parseContextDependsOn,
6
6
  import { resolveMilestoneFile, resolveSlicePath, resolveSliceFile, resolveTaskFile, resolveTasksDir, resolveGsdRootFile, gsdRoot, } from './paths.js';
7
7
  import { findMilestoneIds } from './milestone-ids.js';
8
8
  import { loadQueueOrder, sortByQueueOrder } from './queue-order.js';
9
- import { isClosedStatus } from './status-guards.js';
10
9
  import { nativeBatchParseGsdFiles } from './native-parser-bridge.js';
11
10
  import { join, resolve } from 'path';
12
- import { existsSync, readdirSync } from 'node:fs';
11
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
13
12
  import { debugCount, debugTime } from './debug-logger.js';
14
13
  import { extractVerdict } from './verdict-parser.js';
15
- import { isDbAvailable, getAllMilestones, getMilestoneSlices, getSliceTasks, getReplanHistory, getSlice, insertMilestone, updateTaskStatus, getPendingSliceGateCount, } from './gsd-db.js';
14
+ import { logWarning, logError } from './workflow-logger.js';
15
+ import { isDbAvailable, getAllMilestones, getMilestone, getMilestoneSlices, getSliceTasks, getReplanHistory, getSlice, insertMilestone, insertSlice, updateTaskStatus, getPendingSliceGateCount, } from './gsd-db.js';
16
16
  /**
17
17
  * A "ghost" milestone directory contains only META.json (and no substantive
18
18
  * files like CONTEXT, CONTEXT-DRAFT, ROADMAP, or SUMMARY). These appear when
19
19
  * a milestone is created but never initialised. Treating them as active causes
20
20
  * auto-mode to stall or falsely declare completion.
21
+ *
22
+ * However, a milestone is NOT a ghost if:
23
+ * - It has a DB row with a meaningful status (queued, active, etc.) — the DB
24
+ * knows about it even if content files haven't been created yet.
25
+ * - It has a worktree directory — a worktree proves the milestone was
26
+ * legitimately created and is expected to be populated.
27
+ *
28
+ * Fixes #2921: queued milestones with worktrees were incorrectly classified
29
+ * as ghosts, causing auto-mode to skip them entirely.
21
30
  */
22
31
  export function isGhostMilestone(basePath, mid) {
32
+ // If the milestone has a DB row, it's a known milestone — not a ghost.
33
+ if (isDbAvailable()) {
34
+ const dbRow = getMilestone(mid);
35
+ if (dbRow)
36
+ return false;
37
+ }
38
+ // If a worktree exists for this milestone, it was legitimately created.
39
+ const root = gsdRoot(basePath);
40
+ const wtPath = join(root, 'worktrees', mid);
41
+ if (existsSync(wtPath))
42
+ return false;
43
+ // Fall back to content-file check: no substantive files means ghost.
23
44
  const context = resolveMilestoneFile(basePath, mid, "CONTEXT");
24
45
  const draft = resolveMilestoneFile(basePath, mid, "CONTEXT-DRAFT");
25
46
  const roadmap = resolveMilestoneFile(basePath, mid, "ROADMAP");
@@ -140,10 +161,10 @@ export async function deriveState(basePath) {
140
161
  // Dual-path: try DB-backed derivation first when hierarchy tables are populated
141
162
  if (isDbAvailable()) {
142
163
  let dbMilestones = getAllMilestones();
143
- // Disk→DB reconciliation (#2631): when the milestones table is empty
144
- // (e.g. failed initial migration per #2529), the reconciliation code
145
- // inside deriveStateFromDb is unreachable. Populate from disk here so
146
- // the DB path activates correctly.
164
+ // Disk→DB reconciliation when DB is empty but disk has milestones (#2631).
165
+ // deriveStateFromDb() does its own reconciliation, but deriveState() skips
166
+ // it entirely when the DB is empty. Sync here so the DB path is used when
167
+ // disk milestones exist but haven't been migrated yet.
147
168
  if (dbMilestones.length === 0) {
148
169
  const diskIds = findMilestoneIds(basePath);
149
170
  let synced = false;
@@ -163,7 +184,7 @@ export async function deriveState(basePath) {
163
184
  _telemetry.dbDeriveCount++;
164
185
  }
165
186
  else {
166
- // DB open but empty hierarchy tables pre-migration project, use filesystem
187
+ // DB open but no milestones on disk either use filesystem path
167
188
  result = await _deriveStateImpl(basePath);
168
189
  _telemetry.markdownDeriveCount++;
169
190
  }
@@ -198,6 +219,12 @@ function extractContextTitle(content, fallback) {
198
219
  return stripMilestonePrefix(h1.slice(2).trim()) || fallback;
199
220
  }
200
221
  // ─── DB-backed State Derivation ────────────────────────────────────────────
222
+ /**
223
+ * Helper: check if a DB status counts as "done" (handles K002 ambiguity).
224
+ */
225
+ function isStatusDone(status) {
226
+ return status === 'complete' || status === 'done';
227
+ }
201
228
  /**
202
229
  * Derive GSD state from the milestones/slices/tasks DB tables.
203
230
  * Flag files (PARKED, VALIDATION, CONTINUE, REPLAN, REPLAN-TRIGGER, CONTEXT-DRAFT)
@@ -226,6 +253,39 @@ export async function deriveStateFromDb(basePath) {
226
253
  }
227
254
  if (synced)
228
255
  allMilestones = getAllMilestones();
256
+ // Disk→DB slice reconciliation (#2533): slices defined in ROADMAP.md but
257
+ // missing from the DB cause permanent "No slice eligible" blocks because
258
+ // the dependency resolver only sees DB rows. Parse each milestone's roadmap
259
+ // and insert any missing slices, checking SUMMARY files to set correct status.
260
+ // insertSlice uses INSERT OR IGNORE, so existing rows are never overwritten.
261
+ for (const mid of diskIds) {
262
+ if (isGhostMilestone(basePath, mid))
263
+ continue;
264
+ const roadmapPath = resolveMilestoneFile(basePath, mid, "ROADMAP");
265
+ if (!roadmapPath)
266
+ continue;
267
+ const dbSlices = getMilestoneSlices(mid);
268
+ const dbSliceIds = new Set(dbSlices.map(s => s.id));
269
+ let roadmapContent;
270
+ try {
271
+ roadmapContent = readFileSync(roadmapPath, "utf-8");
272
+ }
273
+ catch {
274
+ continue;
275
+ }
276
+ const parsed = parseRoadmap(roadmapContent);
277
+ for (const s of parsed.slices) {
278
+ if (dbSliceIds.has(s.id))
279
+ continue;
280
+ const summaryPath = resolveSliceFile(basePath, mid, s.id, "SUMMARY");
281
+ const sliceStatus = (s.done || summaryPath) ? "complete" : "pending";
282
+ insertSlice({
283
+ id: s.id, milestoneId: mid, title: s.title,
284
+ status: sliceStatus, risk: s.risk,
285
+ depends: s.depends, demo: s.demo,
286
+ });
287
+ }
288
+ }
229
289
  // Reconcile: discover milestones that exist on disk but are missing from
230
290
  // the DB. This happens when milestones were created before the DB migration
231
291
  // or were manually added to the filesystem. Without this, disk-only
@@ -281,7 +341,7 @@ export async function deriveStateFromDb(basePath) {
281
341
  parkedMilestoneIds.add(m.id);
282
342
  continue;
283
343
  }
284
- if (isClosedStatus(m.status)) {
344
+ if (isStatusDone(m.status)) {
285
345
  completeMilestoneIds.add(m.id);
286
346
  continue;
287
347
  }
@@ -293,7 +353,7 @@ export async function deriveStateFromDb(basePath) {
293
353
  }
294
354
  // Check roadmap: all slices done means milestone is complete
295
355
  const slices = getMilestoneSlices(m.id);
296
- if (slices.length > 0 && slices.every(s => isClosedStatus(s.status))) {
356
+ if (slices.length > 0 && slices.every(s => isStatusDone(s.status))) {
297
357
  // All slices done but no summary — still counts as complete for dep resolution
298
358
  // if a summary file exists
299
359
  // Note: without summary file, the milestone is in validating/completing state, not complete
@@ -312,7 +372,7 @@ export async function deriveStateFromDb(basePath) {
312
372
  }
313
373
  // Ghost milestone check: no slices in DB AND no substantive files on disk
314
374
  const slices = getMilestoneSlices(m.id);
315
- if (slices.length === 0 && !isClosedStatus(m.status)) {
375
+ if (slices.length === 0 && !isStatusDone(m.status)) {
316
376
  // Check disk for ghost detection
317
377
  if (isGhostMilestone(basePath, m.id))
318
378
  continue;
@@ -333,7 +393,7 @@ export async function deriveStateFromDb(basePath) {
333
393
  continue;
334
394
  }
335
395
  // Not complete — determine if it should be active
336
- const allSlicesDone = slices.length > 0 && slices.every(s => isClosedStatus(s.status));
396
+ const allSlicesDone = slices.length > 0 && slices.every(s => isStatusDone(s.status));
337
397
  // Get title — prefer DB, fall back to context file extraction
338
398
  let title = stripMilestonePrefix(m.title) || m.id;
339
399
  if (title === m.id) {
@@ -432,7 +492,8 @@ export async function deriveStateFromDb(basePath) {
432
492
  ? `All milestones complete. ${activeReqs} active requirement${activeReqs === 1 ? '' : 's'} in REQUIREMENTS.md ${activeReqs === 1 ? 'has' : 'have'} not been mapped to a milestone.`
433
493
  : 'All milestones complete.';
434
494
  return {
435
- activeMilestone: lastEntry ? { id: lastEntry.id, title: lastEntry.title } : null,
495
+ activeMilestone: null,
496
+ lastCompletedMilestone: lastEntry ? { id: lastEntry.id, title: lastEntry.title } : null,
436
497
  activeSlice: null, activeTask: null,
437
498
  phase: 'complete',
438
499
  recentDecisions: [], blockers: [],
@@ -470,10 +531,7 @@ export async function deriveStateFromDb(basePath) {
470
531
  };
471
532
  }
472
533
  // ── All slices done → validating/completing ─────────────────────────
473
- // Guard: [].every() === true (vacuous truth). Without the length check,
474
- // an empty slice array causes a premature phase transition to
475
- // validating-milestone. See: https://github.com/gsd-build/gsd-2/issues/2667
476
- const allSlicesDone = activeMilestoneSlices.length > 0 && activeMilestoneSlices.every(s => isClosedStatus(s.status));
534
+ const allSlicesDone = activeMilestoneSlices.every(s => isStatusDone(s.status));
477
535
  if (allSlicesDone) {
478
536
  const validationFile = resolveMilestoneFile(basePath, activeMilestone.id, "VALIDATION");
479
537
  const validationContent = validationFile ? await loadFile(validationFile) : null;
@@ -503,14 +561,14 @@ export async function deriveStateFromDb(basePath) {
503
561
  }
504
562
  // ── Find active slice (first incomplete with deps satisfied) ─────────
505
563
  const sliceProgress = {
506
- done: activeMilestoneSlices.filter(s => isClosedStatus(s.status)).length,
564
+ done: activeMilestoneSlices.filter(s => isStatusDone(s.status)).length,
507
565
  total: activeMilestoneSlices.length,
508
566
  };
509
- const doneSliceIds = new Set(activeMilestoneSlices.filter(s => isClosedStatus(s.status)).map(s => s.id));
567
+ const doneSliceIds = new Set(activeMilestoneSlices.filter(s => isStatusDone(s.status)).map(s => s.id));
510
568
  let activeSlice = null;
511
569
  let activeSliceRow = null;
512
570
  for (const s of activeMilestoneSlices) {
513
- if (isClosedStatus(s.status))
571
+ if (isStatusDone(s.status))
514
572
  continue;
515
573
  if (s.depends.every(dep => doneSliceIds.has(dep))) {
516
574
  activeSlice = { id: s.id, title: s.title };
@@ -550,18 +608,18 @@ export async function deriveStateFromDb(basePath) {
550
608
  // causing the dispatcher to re-dispatch the same completed task forever.
551
609
  let reconciled = false;
552
610
  for (const t of tasks) {
553
- if (isClosedStatus(t.status))
611
+ if (isStatusDone(t.status))
554
612
  continue;
555
613
  const summaryPath = resolveTaskFile(basePath, activeMilestone.id, activeSlice.id, t.id, "SUMMARY");
556
614
  if (summaryPath && existsSync(summaryPath)) {
557
615
  try {
558
616
  updateTaskStatus(activeMilestone.id, activeSlice.id, t.id, "complete");
559
- process.stderr.write(`gsd-reconcile: task ${activeMilestone.id}/${activeSlice.id}/${t.id} had SUMMARY on disk but DB status was "${t.status}" — updated to "complete" (#2514)\n`);
617
+ logWarning("reconcile", `task ${activeMilestone.id}/${activeSlice.id}/${t.id} status reconciled from "${t.status}" to "complete" (#2514)`, { mid: activeMilestone.id, sid: activeSlice.id, tid: t.id });
560
618
  reconciled = true;
561
619
  }
562
620
  catch (e) {
563
621
  // DB write failed — continue with stale status rather than crash
564
- process.stderr.write(`gsd-reconcile: failed to update task ${t.id}: ${e.message}\n`);
622
+ logError("reconcile", `failed to update task ${t.id}`, { tid: t.id, error: e.message });
565
623
  }
566
624
  }
567
625
  }
@@ -570,10 +628,10 @@ export async function deriveStateFromDb(basePath) {
570
628
  tasks = getSliceTasks(activeMilestone.id, activeSlice.id);
571
629
  }
572
630
  const taskProgress = {
573
- done: tasks.filter(t => isClosedStatus(t.status)).length,
631
+ done: tasks.filter(t => isStatusDone(t.status)).length,
574
632
  total: tasks.length,
575
633
  };
576
- const activeTaskRow = tasks.find(t => !isClosedStatus(t.status));
634
+ const activeTaskRow = tasks.find(t => !isStatusDone(t.status));
577
635
  if (!activeTaskRow && tasks.length > 0) {
578
636
  // All tasks done but slice not marked complete → summarizing
579
637
  return {
@@ -628,7 +686,7 @@ export async function deriveStateFromDb(basePath) {
628
686
  };
629
687
  }
630
688
  // ── Blocker detection: check completed tasks for blocker_discovered ──
631
- const completedTasks = tasks.filter(t => isClosedStatus(t.status));
689
+ const completedTasks = tasks.filter(t => isStatusDone(t.status));
632
690
  let blockerTaskId = null;
633
691
  for (const ct of completedTasks) {
634
692
  if (ct.blocker_discovered) {
@@ -1187,7 +1245,7 @@ export async function _deriveStateImpl(basePath) {
1187
1245
  const summaryPath = resolveTaskFile(basePath, activeMilestone.id, activeSlice.id, t.id, "SUMMARY");
1188
1246
  if (summaryPath && existsSync(summaryPath)) {
1189
1247
  t.done = true;
1190
- process.stderr.write(`gsd-reconcile: task ${activeMilestone.id}/${activeSlice.id}/${t.id} has SUMMARY on disk but plan shows incomplete marking done (#2514)\n`);
1248
+ logWarning("reconcile", `task ${activeMilestone.id}/${activeSlice.id}/${t.id} reconciled via SUMMARY on disk (#2514)`, { mid: activeMilestone.id, sid: activeSlice.id, tid: t.id });
1191
1249
  }
1192
1250
  }
1193
1251
  const taskProgress = {
@@ -87,7 +87,26 @@ export function load(url, context, nextLoad) {
87
87
  emitDecoratorMetadata: true,
88
88
  },
89
89
  });
90
- return { format: 'module', source: outputText, shortCircuit: true };
90
+ // Inject CJS-compatible globals (__dirname, __filename, require) so that
91
+ // workspace packages compiled as ESM can still use them. This avoids the
92
+ // need for import.meta.url behind indirect invocation patterns that fail in
93
+ // CJS and in dynamically-created scopes.
94
+ // Only inject globals that the source file doesn't already declare itself.
95
+ const preambleLines = [
96
+ 'import { fileURLToPath as __preamble_fUTP } from "node:url";',
97
+ 'import { dirname as __preamble_dn } from "node:path";',
98
+ 'import { createRequire as __preamble_cR } from "node:module";',
99
+ ];
100
+ if (!outputText.includes('const __filename') && !outputText.includes('let __filename')) {
101
+ preambleLines.push('const __filename = __preamble_fUTP(import.meta.url);');
102
+ }
103
+ if (!outputText.includes('const __dirname') && !outputText.includes('let __dirname')) {
104
+ preambleLines.push('const __dirname = __preamble_dn(__preamble_fUTP(import.meta.url));');
105
+ }
106
+ if (!outputText.includes('const require') && !outputText.includes('let require')) {
107
+ preambleLines.push('const require = __preamble_cR(import.meta.url);');
108
+ }
109
+ return { format: 'module', source: preambleLines.join('\n') + '\n' + outputText, shortCircuit: true };
91
110
  }
92
111
  return nextLoad(url, context);
93
112
  }