gsd-pi 2.57.0-dev.f22a903 → 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 (770) 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/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 +199 -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 +42 -34
  35. package/dist/resources/extensions/gsd/bootstrap/system-context.js +66 -12
  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/codebase-generator.js +279 -0
  39. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  40. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  41. package/dist/resources/extensions/gsd/commands-codebase.js +115 -0
  42. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +41 -4
  43. package/dist/resources/extensions/gsd/complexity-classifier.js +8 -6
  44. package/dist/resources/extensions/gsd/db-writer.js +116 -8
  45. package/dist/resources/extensions/gsd/doctor-git-checks.js +76 -1
  46. package/dist/resources/extensions/gsd/doctor-proactive.js +34 -1
  47. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  48. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
  49. package/dist/resources/extensions/gsd/doctor.js +3 -1
  50. package/dist/resources/extensions/gsd/error-classifier.js +12 -10
  51. package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
  52. package/dist/resources/extensions/gsd/forensics.js +123 -20
  53. package/dist/resources/extensions/gsd/git-service.js +105 -2
  54. package/dist/resources/extensions/gsd/gitignore.js +33 -0
  55. package/dist/resources/extensions/gsd/gsd-db.js +36 -9
  56. package/dist/resources/extensions/gsd/guided-flow.js +106 -44
  57. package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
  58. package/dist/resources/extensions/gsd/health-widget.js +17 -0
  59. package/dist/resources/extensions/gsd/index.js +1 -1
  60. package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
  61. package/dist/resources/extensions/gsd/migrate-external.js +8 -1
  62. package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
  63. package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
  64. package/dist/resources/extensions/gsd/model-router.js +35 -1
  65. package/dist/resources/extensions/gsd/native-git-bridge.js +39 -0
  66. package/dist/resources/extensions/gsd/notifications.js +16 -1
  67. package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
  68. package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
  69. package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
  70. package/dist/resources/extensions/gsd/paths.js +45 -0
  71. package/dist/resources/extensions/gsd/preferences-models.js +14 -1
  72. package/dist/resources/extensions/gsd/preferences-types.js +3 -1
  73. package/dist/resources/extensions/gsd/preferences.js +13 -16
  74. package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
  75. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  77. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
  80. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  81. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  83. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  84. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  86. package/dist/resources/extensions/gsd/repo-identity.js +205 -11
  87. package/dist/resources/extensions/gsd/rethink.js +5 -0
  88. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
  89. package/dist/resources/extensions/gsd/state.js +85 -27
  90. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  91. package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
  92. package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
  93. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
  94. package/dist/resources/extensions/gsd/tools/validate-milestone.js +14 -3
  95. package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
  96. package/dist/resources/extensions/gsd/undo.js +2 -2
  97. package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
  98. package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
  99. package/dist/resources/extensions/gsd/watch/header-renderer.js +241 -0
  100. package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
  101. package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
  102. package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
  103. package/dist/resources/extensions/gsd/workspace-index.js +24 -0
  104. package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
  105. package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
  106. package/dist/resources/extensions/mcp-client/index.js +11 -7
  107. package/dist/resources/extensions/ollama/index.js +112 -0
  108. package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
  109. package/dist/resources/extensions/ollama/ollama-client.js +168 -0
  110. package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
  111. package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
  112. package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
  113. package/dist/resources/extensions/ollama/types.js +2 -0
  114. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  115. package/dist/resources/extensions/shared/interview-ui.js +11 -1
  116. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
  117. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  118. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  119. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  120. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  121. package/dist/startup-model-validation.d.ts +39 -0
  122. package/dist/startup-model-validation.js +50 -0
  123. package/dist/web/standalone/.next/BUILD_ID +1 -1
  124. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  125. package/dist/web/standalone/.next/build-manifest.json +3 -3
  126. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  127. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  130. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  146. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/index.html +1 -1
  201. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  202. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  204. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  206. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  207. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  209. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  210. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  213. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  214. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  215. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
  216. package/dist/web/standalone/.next/static/chunks/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
  217. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
  218. package/dist/web-mode.js +2 -1
  219. package/dist/welcome-screen.d.ts +1 -0
  220. package/dist/welcome-screen.js +32 -6
  221. package/package.json +2 -2
  222. package/packages/daemon/src/cli.ts +49 -0
  223. package/packages/daemon/src/daemon.test.ts +104 -1
  224. package/packages/daemon/src/daemon.ts +24 -1
  225. package/packages/daemon/src/discord-bot.ts +73 -3
  226. package/packages/daemon/src/event-bridge.ts +15 -9
  227. package/packages/daemon/src/event-formatter.ts +30 -2
  228. package/packages/daemon/src/index.ts +9 -0
  229. package/packages/daemon/src/launchd.test.ts +356 -0
  230. package/packages/daemon/src/launchd.ts +242 -0
  231. package/packages/daemon/src/message-batcher.test.ts +2 -2
  232. package/packages/daemon/src/message-batcher.ts +9 -3
  233. package/packages/daemon/src/orchestrator.test.ts +1 -0
  234. package/packages/daemon/src/orchestrator.ts +106 -2
  235. package/packages/native/dist/ast/index.js +9 -5
  236. package/packages/native/dist/ast/types.js +2 -1
  237. package/packages/native/dist/clipboard/index.js +12 -7
  238. package/packages/native/dist/clipboard/types.js +2 -1
  239. package/packages/native/dist/diff/index.js +12 -7
  240. package/packages/native/dist/diff/types.js +2 -1
  241. package/packages/native/dist/fd/index.js +6 -3
  242. package/packages/native/dist/fd/types.js +2 -1
  243. package/packages/native/dist/glob/index.js +9 -5
  244. package/packages/native/dist/glob/types.js +2 -1
  245. package/packages/native/dist/grep/index.js +9 -5
  246. package/packages/native/dist/grep/types.js +2 -1
  247. package/packages/native/dist/gsd-parser/index.js +18 -11
  248. package/packages/native/dist/gsd-parser/types.js +2 -1
  249. package/packages/native/dist/highlight/index.js +12 -7
  250. package/packages/native/dist/highlight/types.js +2 -1
  251. package/packages/native/dist/html/index.js +6 -3
  252. package/packages/native/dist/html/types.js +2 -1
  253. package/packages/native/dist/image/index.js +10 -5
  254. package/packages/native/dist/image/types.js +7 -4
  255. package/packages/native/dist/index.js +70 -17
  256. package/packages/native/dist/json-parse/index.js +13 -8
  257. package/packages/native/dist/native.js +47 -10
  258. package/packages/native/dist/ps/index.js +15 -9
  259. package/packages/native/dist/ps/types.js +2 -1
  260. package/packages/native/dist/stream-process/index.js +12 -7
  261. package/packages/native/dist/text/index.js +24 -14
  262. package/packages/native/dist/text/types.js +5 -2
  263. package/packages/native/dist/truncate/index.js +12 -7
  264. package/packages/native/dist/ttsr/index.js +12 -7
  265. package/packages/native/dist/ttsr/types.js +2 -1
  266. package/packages/native/dist/xxhash/index.js +9 -5
  267. package/packages/native/package.json +19 -19
  268. package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
  269. package/packages/native/src/native.ts +9 -8
  270. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  271. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  272. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  273. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  274. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  275. package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
  276. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  277. package/packages/pi-agent-core/src/proxy.ts +1 -1
  278. package/packages/pi-ai/dist/env-api-keys.js +1 -0
  279. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  280. package/packages/pi-ai/dist/index.d.ts +1 -0
  281. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  282. package/packages/pi-ai/dist/index.js +1 -0
  283. package/packages/pi-ai/dist/index.js.map +1 -1
  284. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  285. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
  286. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  287. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
  288. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
  289. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
  290. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
  291. package/packages/pi-ai/dist/types.d.ts +3 -3
  292. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  293. package/packages/pi-ai/dist/types.js.map +1 -1
  294. package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
  295. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  296. package/packages/pi-ai/dist/utils/json-parse.js +24 -1
  297. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  298. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
  299. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
  300. package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
  301. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
  302. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
  303. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
  304. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
  305. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
  306. package/packages/pi-ai/src/env-api-keys.ts +1 -0
  307. package/packages/pi-ai/src/index.ts +1 -0
  308. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
  309. package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
  310. package/packages/pi-ai/src/types.ts +3 -2
  311. package/packages/pi-ai/src/utils/json-parse.ts +28 -1
  312. package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
  313. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
  314. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  315. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  316. package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
  317. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
  319. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  320. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
  321. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
  323. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
  324. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
  325. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
  326. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/exec.js +3 -1
  328. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
  330. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
  331. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
  332. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
  333. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
  334. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
  335. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
  336. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
  337. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
  338. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
  339. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
  340. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
  341. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
  342. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
  343. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
  344. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
  345. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
  346. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  347. package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
  348. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  350. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
  352. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
  354. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
  355. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
  356. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
  357. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
  358. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
  359. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
  360. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
  361. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  362. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  364. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  366. package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
  367. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  368. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
  370. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  372. package/packages/pi-coding-agent/dist/core/messages.js +31 -2
  373. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
  375. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
  376. package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
  377. package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
  378. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  380. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
  382. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
  384. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
  386. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
  388. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  389. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
  390. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
  391. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
  392. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
  393. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  394. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
  395. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  396. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  397. package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
  398. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  399. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
  400. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
  401. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
  402. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
  403. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  404. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  405. package/packages/pi-coding-agent/dist/index.js +1 -1
  406. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  407. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts +1 -1
  408. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
  409. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js +9 -8
  410. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
  411. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  412. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +0 -3
  413. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  414. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -0
  415. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  416. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -1
  417. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  418. package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js +1 -1
  419. package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  420. package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -1
  421. package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  422. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  423. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  424. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  425. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js +5 -2
  426. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +1 -0
  428. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  429. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +4 -0
  430. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  431. package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js +1 -1
  432. package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
  433. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts +1 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  435. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js +4 -2
  436. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
  437. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +2 -2
  438. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  439. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  440. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +8 -1
  441. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  442. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  443. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +2 -0
  444. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
  445. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  446. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js +4 -0
  447. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js.map +1 -1
  448. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  449. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +26 -12
  450. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  451. package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js +4 -4
  452. package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  453. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +3 -0
  454. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  455. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +46 -14
  456. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  457. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  458. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -8
  459. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  460. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +4 -4
  461. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  462. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +2 -2
  463. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  464. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  465. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -3
  466. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  467. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  468. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -2
  469. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  470. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  471. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +19 -1
  472. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  473. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  474. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +16 -1
  475. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  476. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -0
  477. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  478. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +27 -4
  479. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  480. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  481. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +6 -0
  482. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  483. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
  484. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  485. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
  486. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  487. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
  488. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  489. package/packages/pi-coding-agent/package.json +1 -1
  490. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
  491. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
  492. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
  493. package/packages/pi-coding-agent/src/core/exec.ts +3 -1
  494. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
  495. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
  496. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
  497. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
  498. package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
  499. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  500. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
  501. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
  502. package/packages/pi-coding-agent/src/core/index.ts +6 -0
  503. package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
  504. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
  505. package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
  506. package/packages/pi-coding-agent/src/core/messages.ts +29 -2
  507. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  508. package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
  509. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
  510. package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
  511. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
  512. package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
  513. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
  514. package/packages/pi-coding-agent/src/index.ts +6 -0
  515. package/packages/pi-coding-agent/src/modes/interactive/components/armin.ts +9 -9
  516. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -2
  517. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +3 -1
  518. package/packages/pi-coding-agent/src/modes/interactive/components/bordered-loader.ts +1 -1
  519. package/packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts +1 -1
  520. package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +1 -1
  521. package/packages/pi-coding-agent/src/modes/interactive/components/config-selector.ts +7 -2
  522. package/packages/pi-coding-agent/src/modes/interactive/components/countdown-timer.ts +3 -0
  523. package/packages/pi-coding-agent/src/modes/interactive/components/custom-message.ts +1 -1
  524. package/packages/pi-coding-agent/src/modes/interactive/components/daxnuts.ts +4 -3
  525. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +2 -2
  526. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -1
  527. package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +1 -0
  528. package/packages/pi-coding-agent/src/modes/interactive/components/extension-selector.ts +4 -0
  529. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +27 -13
  530. package/packages/pi-coding-agent/src/modes/interactive/components/oauth-selector.ts +4 -4
  531. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +45 -14
  532. package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -7
  533. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +4 -4
  534. package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +2 -2
  535. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +8 -3
  536. package/packages/pi-coding-agent/src/modes/interactive/components/user-message-selector.ts +3 -2
  537. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +24 -1
  538. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +14 -1
  539. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +35 -3
  540. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -0
  541. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
  542. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
  543. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  544. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  545. package/packages/pi-tui/dist/terminal.js +9 -0
  546. package/packages/pi-tui/dist/terminal.js.map +1 -1
  547. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  548. package/packages/pi-tui/dist/tui.js +9 -0
  549. package/packages/pi-tui/dist/tui.js.map +1 -1
  550. package/packages/pi-tui/src/terminal.ts +14 -0
  551. package/packages/pi-tui/src/tui.ts +8 -0
  552. package/pkg/dist/modes/interactive/theme/themes.js +1 -1
  553. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  554. package/pkg/package.json +1 -1
  555. package/scripts/ensure-workspace-builds.cjs +45 -14
  556. package/src/resources/agents/researcher.md +1 -1
  557. package/src/resources/extensions/ask-user-questions.ts +21 -3
  558. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  559. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  560. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  561. package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
  562. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
  563. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
  564. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
  565. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  566. package/src/resources/extensions/get-secrets-from-user.ts +8 -5
  567. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  568. package/src/resources/extensions/google-search/index.ts +2 -1
  569. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  570. package/src/resources/extensions/gsd/auto/phases.ts +43 -34
  571. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  572. package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
  573. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
  574. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
  575. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  576. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  577. package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
  578. package/src/resources/extensions/gsd/auto-start.ts +35 -26
  579. package/src/resources/extensions/gsd/auto-worktree.ts +193 -9
  580. package/src/resources/extensions/gsd/auto.ts +5 -0
  581. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
  582. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
  583. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
  584. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -35
  585. package/src/resources/extensions/gsd/bootstrap/system-context.ts +72 -12
  586. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
  587. package/src/resources/extensions/gsd/captures.ts +63 -3
  588. package/src/resources/extensions/gsd/codebase-generator.ts +351 -0
  589. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  590. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  591. package/src/resources/extensions/gsd/commands-codebase.ts +164 -0
  592. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +46 -4
  593. package/src/resources/extensions/gsd/complexity-classifier.ts +8 -6
  594. package/src/resources/extensions/gsd/db-writer.ts +140 -7
  595. package/src/resources/extensions/gsd/doctor-git-checks.ts +75 -1
  596. package/src/resources/extensions/gsd/doctor-proactive.ts +35 -1
  597. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  598. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
  599. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  600. package/src/resources/extensions/gsd/doctor.ts +3 -1
  601. package/src/resources/extensions/gsd/error-classifier.ts +13 -11
  602. package/src/resources/extensions/gsd/extension-manifest.json +16 -1
  603. package/src/resources/extensions/gsd/forensics.ts +144 -20
  604. package/src/resources/extensions/gsd/git-service.ts +119 -3
  605. package/src/resources/extensions/gsd/gitignore.ts +33 -0
  606. package/src/resources/extensions/gsd/gsd-db.ts +43 -7
  607. package/src/resources/extensions/gsd/guided-flow.ts +114 -45
  608. package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
  609. package/src/resources/extensions/gsd/health-widget.ts +17 -0
  610. package/src/resources/extensions/gsd/index.ts +1 -0
  611. package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
  612. package/src/resources/extensions/gsd/migrate-external.ts +9 -1
  613. package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
  614. package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
  615. package/src/resources/extensions/gsd/model-router.ts +35 -1
  616. package/src/resources/extensions/gsd/native-git-bridge.ts +41 -0
  617. package/src/resources/extensions/gsd/notifications.ts +16 -0
  618. package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
  619. package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
  620. package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
  621. package/src/resources/extensions/gsd/paths.ts +44 -0
  622. package/src/resources/extensions/gsd/preferences-models.ts +14 -1
  623. package/src/resources/extensions/gsd/preferences-types.ts +10 -1
  624. package/src/resources/extensions/gsd/preferences.ts +13 -15
  625. package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
  626. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  627. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  628. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  629. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  630. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
  631. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  632. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  633. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  634. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  635. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  636. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  637. package/src/resources/extensions/gsd/repo-identity.ts +186 -11
  638. package/src/resources/extensions/gsd/rethink.ts +6 -0
  639. package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
  640. package/src/resources/extensions/gsd/state.ts +84 -32
  641. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
  642. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
  643. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
  644. package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
  645. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
  646. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +488 -0
  647. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
  648. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
  649. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
  650. package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +4 -4
  651. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
  652. package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
  653. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
  654. package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
  655. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
  656. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
  657. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
  658. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  659. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
  660. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
  661. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
  662. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
  663. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
  664. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
  665. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
  666. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
  667. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
  668. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
  669. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
  670. package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
  671. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
  672. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
  673. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +134 -0
  674. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
  675. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
  676. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +72 -0
  677. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +68 -0
  678. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
  679. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
  680. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  681. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
  682. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
  683. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
  684. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
  685. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
  686. package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
  687. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
  688. package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
  689. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
  690. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
  691. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
  692. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
  693. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
  694. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -0
  695. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
  696. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
  697. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
  698. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
  699. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
  700. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
  701. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
  702. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
  703. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
  704. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
  705. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
  706. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
  707. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
  708. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
  709. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
  710. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
  711. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
  712. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +44 -0
  713. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
  714. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
  715. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
  716. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
  717. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
  718. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +4 -1
  719. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
  720. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
  721. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
  722. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
  723. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
  724. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
  725. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
  726. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
  727. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
  728. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
  729. package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
  730. package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
  731. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
  732. package/src/resources/extensions/gsd/tools/validate-milestone.ts +20 -2
  733. package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
  734. package/src/resources/extensions/gsd/types.ts +4 -2
  735. package/src/resources/extensions/gsd/undo.ts +2 -2
  736. package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
  737. package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
  738. package/src/resources/extensions/gsd/watch/header-renderer.ts +275 -0
  739. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  740. package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
  741. package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
  742. package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
  743. package/src/resources/extensions/gsd/workspace-index.ts +30 -0
  744. package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
  745. package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
  746. package/src/resources/extensions/mcp-client/index.ts +13 -7
  747. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
  748. package/src/resources/extensions/ollama/index.ts +130 -0
  749. package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
  750. package/src/resources/extensions/ollama/ollama-client.ts +196 -0
  751. package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
  752. package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
  753. package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
  754. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
  755. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
  756. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
  757. package/src/resources/extensions/ollama/types.ts +130 -0
  758. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  759. package/src/resources/extensions/shared/interview-ui.ts +12 -1
  760. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
  761. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
  762. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  763. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  764. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  765. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  766. package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +0 -9
  767. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
  768. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
  769. /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → uDm3eO1oo9lDfY2TyoO9t}/_buildManifest.js +0 -0
  770. /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → uDm3eO1oo9lDfY2TyoO9t}/_ssgManifest.js +0 -0
@@ -0,0 +1,289 @@
1
+ /**
2
+ * uat-stuck-loop-orphaned-worktree.test.ts — Regression tests for #2821.
3
+ *
4
+ * Reproduces two cascading bugs:
5
+ *
6
+ * Bug 1 — UAT stuck-loop: syncProjectRootToWorktree uses force:false for
7
+ * milestone files. When the project root has an ASSESSMENT with a verdict
8
+ * but the worktree has a stale/empty ASSESSMENT (or none at all after DB
9
+ * rebuild), the verdict is NOT synced into the worktree. checkNeedsRunUat
10
+ * finds no verdict → re-dispatches run-uat indefinitely.
11
+ *
12
+ * Bug 2 — Orphaned worktree: removeWorktree silently swallows failures when
13
+ * git worktree remove fails (untracked files, CWD inside worktree, etc.).
14
+ * The worktree directory and branch persist on disk after teardown.
15
+ * teardownAutoWorktree has a fallback rmSync but it also fails when the
16
+ * git internal .git/worktrees/<name> directory holds a lock.
17
+ */
18
+
19
+ import { describe, test, beforeEach, afterEach } from "node:test";
20
+ import assert from "node:assert/strict";
21
+ import {
22
+ mkdtempSync,
23
+ mkdirSync,
24
+ writeFileSync,
25
+ rmSync,
26
+ existsSync,
27
+ readFileSync,
28
+ } from "node:fs";
29
+ import { join } from "node:path";
30
+ import { tmpdir } from "node:os";
31
+ import { execFileSync } from "node:child_process";
32
+
33
+ import { syncProjectRootToWorktree } from "../auto-worktree.ts";
34
+ import {
35
+ createWorktree,
36
+ removeWorktree,
37
+ worktreePath,
38
+ } from "../worktree-manager.ts";
39
+
40
+ function git(args: string[], cwd: string): string {
41
+ return execFileSync("git", args, {
42
+ cwd,
43
+ stdio: ["ignore", "pipe", "pipe"],
44
+ encoding: "utf-8",
45
+ }).trim();
46
+ }
47
+
48
+ function makeBaseRepo(): string {
49
+ const base = mkdtempSync(join(tmpdir(), "gsd-2821-"));
50
+ git(["init", "-b", "main"], base);
51
+ git(["config", "user.name", "Test"], base);
52
+ git(["config", "user.email", "test@test.com"], base);
53
+ writeFileSync(join(base, "README.md"), "# test\n");
54
+ mkdirSync(join(base, ".gsd", "milestones", "M011"), { recursive: true });
55
+ git(["add", "."], base);
56
+ git(["commit", "-m", "init"], base);
57
+ return base;
58
+ }
59
+
60
+ // ─── Bug 1: ASSESSMENT force-sync ─────────────────────────────────────────
61
+
62
+ describe("#2821 Bug 1 — ASSESSMENT file force-synced on resume", () => {
63
+ let mainBase: string;
64
+ let wtBase: string;
65
+
66
+ beforeEach(() => {
67
+ mainBase = mkdtempSync(join(tmpdir(), "gsd-2821-main-"));
68
+ wtBase = mkdtempSync(join(tmpdir(), "gsd-2821-wt-"));
69
+ mkdirSync(join(mainBase, ".gsd", "milestones", "M011", "slices", "S01"), {
70
+ recursive: true,
71
+ });
72
+ mkdirSync(join(wtBase, ".gsd", "milestones", "M011", "slices", "S01"), {
73
+ recursive: true,
74
+ });
75
+ });
76
+
77
+ afterEach(() => {
78
+ rmSync(mainBase, { recursive: true, force: true });
79
+ rmSync(wtBase, { recursive: true, force: true });
80
+ });
81
+
82
+ test("force-syncs ASSESSMENT with verdict from project root into worktree when worktree copy has no verdict", () => {
83
+ // Project root has ASSESSMENT with a PASS verdict (written by run-uat, synced by post-unit)
84
+ const prAssessment = join(
85
+ mainBase,
86
+ ".gsd",
87
+ "milestones",
88
+ "M011",
89
+ "slices",
90
+ "S01",
91
+ "S01-ASSESSMENT.md",
92
+ );
93
+ writeFileSync(
94
+ prAssessment,
95
+ "---\nverdict: pass\n---\n# S01 Assessment\nAll tests pass.\n",
96
+ );
97
+
98
+ // Worktree has a stale ASSESSMENT with FAIL verdict (from the initial run-uat execution)
99
+ const wtAssessment = join(
100
+ wtBase,
101
+ ".gsd",
102
+ "milestones",
103
+ "M011",
104
+ "slices",
105
+ "S01",
106
+ "S01-ASSESSMENT.md",
107
+ );
108
+ writeFileSync(
109
+ wtAssessment,
110
+ "---\nverdict: fail\n---\n# S01 Assessment\nSome tests fail.\n",
111
+ );
112
+
113
+ syncProjectRootToWorktree(mainBase, wtBase, "M011");
114
+
115
+ // The worktree ASSESSMENT must now have the project root's PASS verdict
116
+ const content = readFileSync(wtAssessment, "utf-8");
117
+ assert.ok(
118
+ content.includes("verdict: pass"),
119
+ `Expected worktree ASSESSMENT to have verdict:pass after sync, got: ${content.slice(0, 100)}`,
120
+ );
121
+ });
122
+
123
+ test("force-syncs ASSESSMENT from project root when worktree has no ASSESSMENT at all", () => {
124
+ // Project root has ASSESSMENT with verdict
125
+ const prAssessment = join(
126
+ mainBase,
127
+ ".gsd",
128
+ "milestones",
129
+ "M011",
130
+ "slices",
131
+ "S01",
132
+ "S01-ASSESSMENT.md",
133
+ );
134
+ writeFileSync(
135
+ prAssessment,
136
+ "---\nverdict: pass\n---\n# S01 Assessment\n",
137
+ );
138
+
139
+ // Worktree has NO ASSESSMENT (deleted during DB rebuild)
140
+ // — file simply doesn't exist
141
+
142
+ syncProjectRootToWorktree(mainBase, wtBase, "M011");
143
+
144
+ const wtAssessment = join(
145
+ wtBase,
146
+ ".gsd",
147
+ "milestones",
148
+ "M011",
149
+ "slices",
150
+ "S01",
151
+ "S01-ASSESSMENT.md",
152
+ );
153
+ assert.ok(
154
+ existsSync(wtAssessment),
155
+ "ASSESSMENT should be copied to worktree when missing",
156
+ );
157
+ const content = readFileSync(wtAssessment, "utf-8");
158
+ assert.ok(
159
+ content.includes("verdict: pass"),
160
+ `Synced ASSESSMENT should contain verdict:pass, got: ${content.slice(0, 100)}`,
161
+ );
162
+ });
163
+
164
+ test("does NOT overwrite worktree ASSESSMENT when project root has no verdict", () => {
165
+ // Project root has ASSESSMENT without verdict (incomplete)
166
+ const prAssessment = join(
167
+ mainBase,
168
+ ".gsd",
169
+ "milestones",
170
+ "M011",
171
+ "slices",
172
+ "S01",
173
+ "S01-ASSESSMENT.md",
174
+ );
175
+ writeFileSync(prAssessment, "# S01 Assessment\nIn progress...\n");
176
+
177
+ // Worktree has ASSESSMENT with verdict:fail
178
+ const wtAssessment = join(
179
+ wtBase,
180
+ ".gsd",
181
+ "milestones",
182
+ "M011",
183
+ "slices",
184
+ "S01",
185
+ "S01-ASSESSMENT.md",
186
+ );
187
+ writeFileSync(
188
+ wtAssessment,
189
+ "---\nverdict: fail\n---\n# S01 Assessment\nSome tests fail.\n",
190
+ );
191
+
192
+ syncProjectRootToWorktree(mainBase, wtBase, "M011");
193
+
194
+ // Worktree copy should NOT be overwritten by the verdictless project root copy
195
+ const content = readFileSync(wtAssessment, "utf-8");
196
+ assert.ok(
197
+ content.includes("verdict: fail"),
198
+ `Worktree ASSESSMENT should keep verdict:fail when project root has no verdict, got: ${content.slice(0, 100)}`,
199
+ );
200
+ });
201
+ });
202
+
203
+ // ─── Bug 2: Orphaned worktree cleanup ─────────────────────────────────────
204
+
205
+ describe("#2821 Bug 2 — removeWorktree cleans up despite untracked files", () => {
206
+ let base: string;
207
+
208
+ beforeEach(() => {
209
+ base = makeBaseRepo();
210
+ });
211
+
212
+ afterEach(() => {
213
+ rmSync(base, { recursive: true, force: true });
214
+ });
215
+
216
+ test("removes worktree directory even when it contains untracked files", () => {
217
+ const info = createWorktree(base, "M011", {
218
+ branch: "milestone/M011",
219
+ });
220
+
221
+ // Simulate run-uat writing untracked files (S01-UAT-RESULT.md, ASSESSMENT)
222
+ mkdirSync(
223
+ join(info.path, ".gsd", "milestones", "M011", "slices", "S01"),
224
+ { recursive: true },
225
+ );
226
+ writeFileSync(
227
+ join(
228
+ info.path,
229
+ ".gsd",
230
+ "milestones",
231
+ "M011",
232
+ "slices",
233
+ "S01",
234
+ "S01-UAT-RESULT.md",
235
+ ),
236
+ "# UAT Result\nverdict: fail\n",
237
+ );
238
+ writeFileSync(
239
+ join(
240
+ info.path,
241
+ ".gsd",
242
+ "milestones",
243
+ "M011",
244
+ "slices",
245
+ "S01",
246
+ "S01-ASSESSMENT.md",
247
+ ),
248
+ "---\nverdict: fail\n---\n# Assessment\n",
249
+ );
250
+
251
+ removeWorktree(base, "M011", {
252
+ branch: "milestone/M011",
253
+ deleteBranch: true,
254
+ force: true,
255
+ });
256
+
257
+ const wtDir = worktreePath(base, "M011");
258
+ assert.ok(
259
+ !existsSync(wtDir),
260
+ `Worktree directory should be removed after teardown, but still exists at ${wtDir}`,
261
+ );
262
+ });
263
+
264
+ test("removes git internal worktree metadata after filesystem removal", () => {
265
+ createWorktree(base, "M011", {
266
+ branch: "milestone/M011",
267
+ });
268
+
269
+ removeWorktree(base, "M011", {
270
+ branch: "milestone/M011",
271
+ deleteBranch: true,
272
+ force: true,
273
+ });
274
+
275
+ // The git internal worktree directory should be cleaned up
276
+ const gitInternalWorktreeDir = join(base, ".git", "worktrees", "M011");
277
+ assert.ok(
278
+ !existsSync(gitInternalWorktreeDir),
279
+ `Git internal worktree dir should be removed: ${gitInternalWorktreeDir}`,
280
+ );
281
+
282
+ // The branch should be deleted
283
+ const branches = git(["branch"], base);
284
+ assert.ok(
285
+ !branches.includes("milestone/M011"),
286
+ "milestone/M011 branch should be deleted after removeWorktree",
287
+ );
288
+ });
289
+ });
@@ -3,7 +3,7 @@
3
3
 
4
4
  import test from 'node:test';
5
5
  import assert from 'node:assert/strict';
6
- import { mkdtempSync, rmSync, existsSync, readFileSync } from 'node:fs';
6
+ import { mkdtempSync, rmSync } from 'node:fs';
7
7
  import { join } from 'node:path';
8
8
  import { tmpdir } from 'node:os';
9
9
 
@@ -14,6 +14,8 @@ import {
14
14
  checkOwnership,
15
15
  taskUnitKey,
16
16
  sliceUnitKey,
17
+ initOwnershipTable,
18
+ closeOwnershipDb,
17
19
  } from '../unit-ownership.ts';
18
20
 
19
21
  function makeTmpBase(): string {
@@ -34,28 +36,51 @@ test('sliceUnitKey: builds correct key', () => {
34
36
  assert.equal(sliceUnitKey('M001', 'S01'), 'M001/S01');
35
37
  });
36
38
 
37
- // ─── Claim / get / release ───────────────────────────────────────────────
39
+ // ─── Claim / get / release (SQLite-backed) ──────────────────────────────
38
40
 
39
- test('claimUnit: creates claim file and records agent', () => {
41
+ test('claimUnit: creates DB and records agent', () => {
40
42
  const base = makeTmpBase();
41
43
  try {
42
- claimUnit(base, 'M001/S01/T01', 'executor-01');
44
+ initOwnershipTable(base);
45
+ const claimed = claimUnit(base, 'M001/S01/T01', 'executor-01');
43
46
 
44
- assert.ok(existsSync(join(base, '.gsd', 'unit-claims.json')), 'claim file should exist');
47
+ assert.equal(claimed, true, 'first claim should succeed');
45
48
  assert.equal(getOwner(base, 'M001/S01/T01'), 'executor-01');
46
49
  } finally {
50
+ closeOwnershipDb(base);
47
51
  cleanup(base);
48
52
  }
49
53
  });
50
54
 
51
- test('claimUnit: overwrites existing claim (last writer wins)', () => {
55
+ test('claimUnit: rejects second claim on same unit (first-writer-wins)', () => {
52
56
  const base = makeTmpBase();
53
57
  try {
54
- claimUnit(base, 'M001/S01/T01', 'executor-01');
55
- claimUnit(base, 'M001/S01/T01', 'executor-02');
58
+ initOwnershipTable(base);
59
+ const first = claimUnit(base, 'M001/S01/T01', 'executor-01');
60
+ const second = claimUnit(base, 'M001/S01/T01', 'executor-02');
56
61
 
57
- assert.equal(getOwner(base, 'M001/S01/T01'), 'executor-02');
62
+ assert.equal(first, true, 'first claim should succeed');
63
+ assert.equal(second, false, 'second claim should fail (first-writer-wins)');
64
+ assert.equal(getOwner(base, 'M001/S01/T01'), 'executor-01',
65
+ 'original owner must be preserved');
58
66
  } finally {
67
+ closeOwnershipDb(base);
68
+ cleanup(base);
69
+ }
70
+ });
71
+
72
+ test('claimUnit: same agent re-claiming same unit succeeds', () => {
73
+ const base = makeTmpBase();
74
+ try {
75
+ initOwnershipTable(base);
76
+ const first = claimUnit(base, 'M001/S01/T01', 'agent-a');
77
+ const second = claimUnit(base, 'M001/S01/T01', 'agent-a');
78
+
79
+ assert.equal(first, true);
80
+ assert.equal(second, true, 're-claim by same agent should succeed');
81
+ assert.equal(getOwner(base, 'M001/S01/T01'), 'agent-a');
82
+ } finally {
83
+ closeOwnershipDb(base);
59
84
  cleanup(base);
60
85
  }
61
86
  });
@@ -63,21 +88,25 @@ test('claimUnit: overwrites existing claim (last writer wins)', () => {
63
88
  test('claimUnit: multiple units can be claimed independently', () => {
64
89
  const base = makeTmpBase();
65
90
  try {
91
+ initOwnershipTable(base);
66
92
  claimUnit(base, 'M001/S01/T01', 'agent-a');
67
93
  claimUnit(base, 'M001/S01/T02', 'agent-b');
68
94
 
69
95
  assert.equal(getOwner(base, 'M001/S01/T01'), 'agent-a');
70
96
  assert.equal(getOwner(base, 'M001/S01/T02'), 'agent-b');
71
97
  } finally {
98
+ closeOwnershipDb(base);
72
99
  cleanup(base);
73
100
  }
74
101
  });
75
102
 
76
- test('getOwner: returns null when no claim file exists', () => {
103
+ test('getOwner: returns null when no DB initialized', () => {
77
104
  const base = makeTmpBase();
78
105
  try {
106
+ initOwnershipTable(base);
79
107
  assert.equal(getOwner(base, 'M001/S01/T01'), null);
80
108
  } finally {
109
+ closeOwnershipDb(base);
81
110
  cleanup(base);
82
111
  }
83
112
  });
@@ -85,9 +114,11 @@ test('getOwner: returns null when no claim file exists', () => {
85
114
  test('getOwner: returns null for unclaimed unit', () => {
86
115
  const base = makeTmpBase();
87
116
  try {
117
+ initOwnershipTable(base);
88
118
  claimUnit(base, 'M001/S01/T01', 'agent-a');
89
119
  assert.equal(getOwner(base, 'M001/S01/T99'), null);
90
120
  } finally {
121
+ closeOwnershipDb(base);
91
122
  cleanup(base);
92
123
  }
93
124
  });
@@ -95,11 +126,13 @@ test('getOwner: returns null for unclaimed unit', () => {
95
126
  test('releaseUnit: removes claim', () => {
96
127
  const base = makeTmpBase();
97
128
  try {
129
+ initOwnershipTable(base);
98
130
  claimUnit(base, 'M001/S01/T01', 'agent-a');
99
131
  releaseUnit(base, 'M001/S01/T01');
100
132
 
101
133
  assert.equal(getOwner(base, 'M001/S01/T01'), null);
102
134
  } finally {
135
+ closeOwnershipDb(base);
103
136
  cleanup(base);
104
137
  }
105
138
  });
@@ -107,32 +140,43 @@ test('releaseUnit: removes claim', () => {
107
140
  test('releaseUnit: no-op for non-existent claim', () => {
108
141
  const base = makeTmpBase();
109
142
  try {
143
+ initOwnershipTable(base);
110
144
  // Should not throw
111
145
  releaseUnit(base, 'M001/S01/T01');
112
146
  } finally {
147
+ closeOwnershipDb(base);
113
148
  cleanup(base);
114
149
  }
115
150
  });
116
151
 
117
- // ─── checkOwnership ──────────────────────────────────────────────────────
118
-
119
- test('checkOwnership: returns null when no actorName provided (opt-in)', () => {
152
+ test('releaseUnit: allows reclaim after release', () => {
120
153
  const base = makeTmpBase();
121
154
  try {
155
+ initOwnershipTable(base);
122
156
  claimUnit(base, 'M001/S01/T01', 'agent-a');
157
+ releaseUnit(base, 'M001/S01/T01');
123
158
 
124
- // No actorName ownership not enforced
125
- assert.equal(checkOwnership(base, 'M001/S01/T01', undefined), null);
159
+ const reclaimed = claimUnit(base, 'M001/S01/T01', 'agent-b');
160
+ assert.equal(reclaimed, true, 'reclaim after release should succeed');
161
+ assert.equal(getOwner(base, 'M001/S01/T01'), 'agent-b');
126
162
  } finally {
163
+ closeOwnershipDb(base);
127
164
  cleanup(base);
128
165
  }
129
166
  });
130
167
 
131
- test('checkOwnership: returns null when no claim file exists', () => {
168
+ // ─── checkOwnership ──────────────────────────────────────────────────────
169
+
170
+ test('checkOwnership: returns null when no actorName provided (opt-in)', () => {
132
171
  const base = makeTmpBase();
133
172
  try {
134
- assert.equal(checkOwnership(base, 'M001/S01/T01', 'agent-a'), null);
173
+ initOwnershipTable(base);
174
+ claimUnit(base, 'M001/S01/T01', 'agent-a');
175
+
176
+ // No actorName → ownership not enforced
177
+ assert.equal(checkOwnership(base, 'M001/S01/T01', undefined), null);
135
178
  } finally {
179
+ closeOwnershipDb(base);
136
180
  cleanup(base);
137
181
  }
138
182
  });
@@ -140,11 +184,13 @@ test('checkOwnership: returns null when no claim file exists', () => {
140
184
  test('checkOwnership: returns null when unit is unclaimed', () => {
141
185
  const base = makeTmpBase();
142
186
  try {
187
+ initOwnershipTable(base);
143
188
  claimUnit(base, 'M001/S01/T01', 'agent-a');
144
189
 
145
190
  // Different unit, unclaimed
146
191
  assert.equal(checkOwnership(base, 'M001/S01/T99', 'agent-b'), null);
147
192
  } finally {
193
+ closeOwnershipDb(base);
148
194
  cleanup(base);
149
195
  }
150
196
  });
@@ -152,10 +198,12 @@ test('checkOwnership: returns null when unit is unclaimed', () => {
152
198
  test('checkOwnership: returns null when actor matches owner', () => {
153
199
  const base = makeTmpBase();
154
200
  try {
201
+ initOwnershipTable(base);
155
202
  claimUnit(base, 'M001/S01/T01', 'agent-a');
156
203
 
157
204
  assert.equal(checkOwnership(base, 'M001/S01/T01', 'agent-a'), null);
158
205
  } finally {
206
+ closeOwnershipDb(base);
159
207
  cleanup(base);
160
208
  }
161
209
  });
@@ -163,6 +211,7 @@ test('checkOwnership: returns null when actor matches owner', () => {
163
211
  test('checkOwnership: returns error string when actor does not match owner', () => {
164
212
  const base = makeTmpBase();
165
213
  try {
214
+ initOwnershipTable(base);
166
215
  claimUnit(base, 'M001/S01/T01', 'agent-a');
167
216
 
168
217
  const err = checkOwnership(base, 'M001/S01/T01', 'agent-b');
@@ -170,6 +219,40 @@ test('checkOwnership: returns error string when actor does not match owner', ()
170
219
  assert.match(err!, /owned by agent-a/);
171
220
  assert.match(err!, /not agent-b/);
172
221
  } finally {
222
+ closeOwnershipDb(base);
223
+ cleanup(base);
224
+ }
225
+ });
226
+
227
+ // ─── Race condition: first-writer-wins atomicity ─────────────────────────
228
+
229
+ test('claimUnit: concurrent claims — only first writer wins (no lost update)', () => {
230
+ const base = makeTmpBase();
231
+ try {
232
+ initOwnershipTable(base);
233
+
234
+ // Simulate the race described in #2728:
235
+ // Two agents both try to claim the same unit.
236
+ // With SQLite INSERT OR IGNORE, only the first succeeds.
237
+ const results: boolean[] = [];
238
+ const agents = ['agent-alpha', 'agent-beta', 'agent-gamma'];
239
+ for (const agent of agents) {
240
+ results.push(claimUnit(base, 'M001/S01/T01', agent));
241
+ }
242
+
243
+ // Exactly one agent should have won
244
+ const wins = results.filter(r => r === true);
245
+ assert.equal(wins.length, 1, 'exactly one agent should win the claim');
246
+
247
+ // The winner is the first agent (deterministic in single-threaded)
248
+ assert.equal(results[0], true);
249
+ assert.equal(results[1], false);
250
+ assert.equal(results[2], false);
251
+
252
+ // The owner must be the first agent
253
+ assert.equal(getOwner(base, 'M001/S01/T01'), 'agent-alpha');
254
+ } finally {
255
+ closeOwnershipDb(base);
173
256
  cleanup(base);
174
257
  }
175
258
  });
@@ -0,0 +1,154 @@
1
+ import { describe, test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import * as fs from 'node:fs';
4
+ import * as path from 'node:path';
5
+ import * as os from 'node:os';
6
+ import { createRequire } from 'node:module';
7
+ import {
8
+ openDatabase,
9
+ closeDatabase,
10
+ isDbAvailable,
11
+ _getAdapter,
12
+ } from '../gsd-db.ts';
13
+
14
+ const _require = createRequire(import.meta.url);
15
+
16
+ // ═══════════════════════════════════════════════════════════════════════════
17
+ // Helpers
18
+ // ═══════════════════════════════════════════════════════════════════════════
19
+
20
+ function tempDbPath(): string {
21
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-vacuum-test-'));
22
+ return path.join(dir, 'test.db');
23
+ }
24
+
25
+ function cleanup(dbPath: string): void {
26
+ closeDatabase();
27
+ try {
28
+ const dir = path.dirname(dbPath);
29
+ for (const f of fs.readdirSync(dir)) {
30
+ fs.unlinkSync(path.join(dir, f));
31
+ }
32
+ fs.rmdirSync(dir);
33
+ } catch { /* best effort */ }
34
+ }
35
+
36
+ /**
37
+ * Create a SQLite DB with a corrupt freelist that causes DDL to fail
38
+ * with "database disk image is malformed" but is recoverable via VACUUM.
39
+ *
40
+ * Strategy:
41
+ * 1. Create a DB with schema_version at v0 (so initSchema needs to run DDL)
42
+ * 2. Add padding rows to create many pages, then delete + drop to free them
43
+ * 3. Corrupt the freelist trunk pointer to point at a B-tree page
44
+ *
45
+ * This simulates the real-world scenario described in #2519: an interrupted
46
+ * WAL checkpoint leaves the freelist in an inconsistent state.
47
+ */
48
+ function createCorruptFreelistDb(dbPath: string): void {
49
+ // Use node:sqlite directly to build the minimal corrupt DB
50
+ const sqlite = _require('node:sqlite');
51
+ const db = new sqlite.DatabaseSync(dbPath);
52
+ db.exec('PRAGMA journal_mode=WAL');
53
+ db.exec('CREATE TABLE schema_version (version INTEGER NOT NULL, applied_at TEXT NOT NULL)');
54
+ db.exec("INSERT INTO schema_version VALUES (0, '2024-01-01')");
55
+ // Pad with data to create many pages, then free them
56
+ db.exec('CREATE TABLE _padding (id INTEGER PRIMARY KEY, data TEXT)');
57
+ for (let i = 0; i < 30; i++) {
58
+ db.exec(`INSERT INTO _padding (data) VALUES ('${'x'.repeat(4000)}')`);
59
+ }
60
+ db.exec('DELETE FROM _padding');
61
+ db.exec('DROP TABLE _padding');
62
+ db.exec('PRAGMA wal_checkpoint(TRUNCATE)');
63
+ db.close();
64
+
65
+ // Remove WAL/SHM files to ensure clean file-only state
66
+ try { fs.unlinkSync(dbPath + '-wal'); } catch { /* may not exist */ }
67
+ try { fs.unlinkSync(dbPath + '-shm'); } catch { /* may not exist */ }
68
+
69
+ // Corrupt: point freelist trunk (offset 32-35) to page 2 (a B-tree page),
70
+ // and claim 10 free pages (offset 36-39)
71
+ const fd = fs.openSync(dbPath, 'r+');
72
+ try {
73
+ const buf = Buffer.alloc(8);
74
+ buf.writeUInt32BE(2, 0); // trunk page = page 2 (actually a B-tree page)
75
+ buf.writeUInt32BE(10, 4); // freelist count = 10
76
+ fs.writeSync(fd, buf, 0, 8, 32);
77
+ } finally {
78
+ fs.closeSync(fd);
79
+ }
80
+ }
81
+
82
+ // ═══════════════════════════════════════════════════════════════════════════
83
+ // Tests
84
+ // ═══════════════════════════════════════════════════════════════════════════
85
+
86
+ describe('openDatabase VACUUM recovery on corrupt freelist', () => {
87
+
88
+ test('recovers a file-backed DB with corrupt freelist via VACUUM', () => {
89
+ const dbPath = tempDbPath();
90
+
91
+ // Create a DB with corrupt freelist (schema at v0 so initSchema runs DDL)
92
+ createCorruptFreelistDb(dbPath);
93
+
94
+ // Without the fix, this throws "database disk image is malformed".
95
+ // With the fix, openDatabase detects "malformed", runs VACUUM, retries.
96
+ const ok = openDatabase(dbPath);
97
+ assert.ok(ok, 'openDatabase should succeed after VACUUM recovery');
98
+ assert.ok(isDbAvailable(), 'DB should be available after recovery');
99
+
100
+ // Verify full schema was applied
101
+ const adapter = _getAdapter()!;
102
+ const row = adapter.prepare(
103
+ 'SELECT MAX(version) as version FROM schema_version',
104
+ ).get();
105
+ assert.ok(
106
+ typeof row?.['version'] === 'number' && (row['version'] as number) > 0,
107
+ 'schema_version should have a positive version after recovery',
108
+ );
109
+
110
+ cleanup(dbPath);
111
+ });
112
+
113
+ test('does not attempt VACUUM for non-malformed errors', () => {
114
+ // openDatabase with :memory: never hits the fileBacked VACUUM path,
115
+ // so non-malformed errors propagate directly. We verify by checking
116
+ // that a non-file error from an in-memory DB propagates unchanged.
117
+ // (In-memory DBs always succeed for initSchema, so this is a design
118
+ // check — the VACUUM path is only for fileBacked = true.)
119
+ const ok = openDatabase(':memory:');
120
+ assert.ok(ok, 'in-memory DB should open fine');
121
+ closeDatabase();
122
+ });
123
+
124
+ test('throws if VACUUM itself fails on unrecoverable corruption', () => {
125
+ const dbPath = tempDbPath();
126
+
127
+ // Create a file with valid SQLite header but thoroughly corrupt content
128
+ const page = Buffer.alloc(4096);
129
+ // SQLite magic: "SQLite format 3\0"
130
+ page.write('SQLite format 3\0', 0, 'utf8');
131
+ // Page size: 4096 (big-endian at offset 16)
132
+ page.writeUInt16BE(4096, 16);
133
+ page[18] = 1; // write version
134
+ page[19] = 1; // read version
135
+ page[20] = 0; // reserved space
136
+ page[21] = 64; // max embedded payload fraction
137
+ page[22] = 32; // min embedded payload fraction
138
+ page[23] = 32; // leaf payload fraction
139
+ page.writeUInt32BE(1, 28); // page_count = 1
140
+ page.writeUInt32BE(999, 32); // corrupt freelist trunk
141
+ page.writeUInt32BE(5, 36); // freelist count = 5
142
+
143
+ fs.writeFileSync(dbPath, page);
144
+
145
+ // Should throw — VACUUM cannot save a thoroughly corrupt file
146
+ assert.throws(
147
+ () => openDatabase(dbPath),
148
+ /./,
149
+ 'should throw for unrecoverable corruption',
150
+ );
151
+
152
+ cleanup(dbPath);
153
+ });
154
+ });