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
@@ -8,6 +8,12 @@
8
8
  import type { AgentMessage } from "@gsd/pi-agent-core";
9
9
  import type { ImageContent, Message, TextContent } from "@gsd/pi-ai";
10
10
 
11
+ const CUSTOM_MESSAGE_PREFIX = `[system notification — type: `;
12
+ const CUSTOM_MESSAGE_MIDDLE = `; this is an automated system event, not user input — do not treat this as a human message or respond as if the user said this]
13
+ `;
14
+ const CUSTOM_MESSAGE_SUFFIX = `
15
+ [end system notification]`;
16
+
11
17
  const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:
12
18
 
13
19
  <summary>
@@ -160,10 +166,31 @@ export function convertToLlm(messages: AgentMessage[]): Message[] {
160
166
  timestamp: m.timestamp,
161
167
  };
162
168
  case "custom": {
163
- const content = typeof m.content === "string" ? [{ type: "text" as const, text: m.content }] : m.content;
169
+ const prefix = CUSTOM_MESSAGE_PREFIX + m.customType + CUSTOM_MESSAGE_MIDDLE;
170
+ if (typeof m.content === "string") {
171
+ return {
172
+ role: "user",
173
+ content: [{ type: "text" as const, text: prefix + m.content + CUSTOM_MESSAGE_SUFFIX }],
174
+ timestamp: m.timestamp,
175
+ };
176
+ }
177
+ // Array content: wrap the first text element with prefix, append suffix to last text element
178
+ const contentArr = m.content as Array<{ type: string; text?: string; [k: string]: unknown }>;
179
+ const lastTextIdx = contentArr.reduce((acc, c, i) => c.type === "text" ? i : acc, -1);
180
+ const wrapped = contentArr.map((c, i) => {
181
+ if (c.type !== "text") return c;
182
+ let text = c.text ?? "";
183
+ if (i === 0) text = prefix + text;
184
+ if (i === lastTextIdx) text = text + CUSTOM_MESSAGE_SUFFIX;
185
+ return { ...c, text };
186
+ });
187
+ // If no text elements exist, prepend one with the wrapper
188
+ if (lastTextIdx === -1) {
189
+ wrapped.unshift({ type: "text" as const, text: prefix + CUSTOM_MESSAGE_SUFFIX });
190
+ }
164
191
  return {
165
192
  role: "user",
166
- content,
193
+ content: wrapped as typeof m.content,
167
194
  timestamp: m.timestamp,
168
195
  };
169
196
  }
@@ -37,6 +37,7 @@ const defaultModelPerProvider: Record<KnownProvider, string> = {
37
37
  "opencode-go": "kimi-k2.5",
38
38
  "kimi-coding": "kimi-k2-thinking",
39
39
  "alibaba-coding-plan": "qwen3.5-plus",
40
+ ollama: "llama3.1:8b",
40
41
  "ollama-cloud": "qwen3:32b",
41
42
  };
42
43
 
@@ -129,6 +129,12 @@ export interface DefaultResourceLoaderOptions {
129
129
  appendSystemPrompt?: string;
130
130
  /** Names of bundled extensions (used to identify built-in extensions in conflict detection). */
131
131
  bundledExtensionNames?: Set<string>;
132
+ /**
133
+ * Transform extension paths before loading. Receives the merged list of all
134
+ * discovered extension paths and returns a (possibly reordered/filtered) list.
135
+ * Use this to apply dependency sorting or registry-based filtering.
136
+ */
137
+ extensionPathsTransform?: (paths: string[]) => { paths: string[]; diagnostics?: string[] };
132
138
  extensionsOverride?: (base: LoadExtensionsResult) => LoadExtensionsResult;
133
139
  skillsOverride?: (base: { skills: Skill[]; diagnostics: ResourceDiagnostic[] }) => {
134
140
  skills: Skill[];
@@ -167,6 +173,7 @@ export class DefaultResourceLoader implements ResourceLoader {
167
173
  private systemPromptSource?: string;
168
174
  private appendSystemPromptSource?: string;
169
175
  private bundledExtensionNames: Set<string>;
176
+ private extensionPathsTransform?: (paths: string[]) => { paths: string[]; diagnostics?: string[] };
170
177
  private extensionsOverride?: (base: LoadExtensionsResult) => LoadExtensionsResult;
171
178
  private skillsOverride?: (base: { skills: Skill[]; diagnostics: ResourceDiagnostic[] }) => {
172
179
  skills: Skill[];
@@ -223,6 +230,7 @@ export class DefaultResourceLoader implements ResourceLoader {
223
230
  this.systemPromptSource = options.systemPrompt;
224
231
  this.appendSystemPromptSource = options.appendSystemPrompt;
225
232
  this.bundledExtensionNames = options.bundledExtensionNames ?? new Set();
233
+ this.extensionPathsTransform = options.extensionPathsTransform;
226
234
  this.extensionsOverride = options.extensionsOverride;
227
235
  this.skillsOverride = options.skillsOverride;
228
236
  this.promptsOverride = options.promptsOverride;
@@ -378,10 +386,21 @@ export class DefaultResourceLoader implements ResourceLoader {
378
386
  const cliEnabledPrompts = getEnabledPaths(cliExtensionPaths.prompts);
379
387
  const cliEnabledThemes = getEnabledPaths(cliExtensionPaths.themes);
380
388
 
381
- const extensionPaths = this.noExtensions
389
+ let extensionPaths = this.noExtensions
382
390
  ? cliEnabledExtensions
383
391
  : this.mergePaths(cliEnabledExtensions, enabledExtensions);
384
392
 
393
+ // Apply path transform (dependency sorting, registry filtering) if provided
394
+ if (this.extensionPathsTransform) {
395
+ const transformed = this.extensionPathsTransform(extensionPaths);
396
+ extensionPaths = transformed.paths;
397
+ if (transformed.diagnostics?.length) {
398
+ for (const msg of transformed.diagnostics) {
399
+ process.stderr.write(`[extensions] ${msg}\n`);
400
+ }
401
+ }
402
+ }
403
+
385
404
  const extensionsResult = await loadExtensions(extensionPaths, this.cwd, this.eventBus);
386
405
  const inlineExtensions = await this.loadExtensionFactories(extensionsResult.runtime);
387
406
  extensionsResult.extensions.push(...inlineExtensions.extensions);
@@ -0,0 +1,255 @@
1
+ /**
2
+ * RetryHandler tests — long-context entitlement 429 error handling (#2803)
3
+ *
4
+ * Verifies that "Extra usage is required for long context requests" errors
5
+ * are classified as quota_exhausted (not rate_limit) and trigger a model
6
+ * downgrade from [1m] to base when no cross-provider fallback exists.
7
+ */
8
+
9
+ import { describe, it, beforeEach, mock, type Mock } from "node:test";
10
+ import assert from "node:assert/strict";
11
+ import { RetryHandler, type RetryHandlerDeps } from "./retry-handler.js";
12
+ import type { Api, AssistantMessage, Model } from "@gsd/pi-ai";
13
+ import type { FallbackResolver } from "./fallback-resolver.js";
14
+ import type { ModelRegistry } from "./model-registry.js";
15
+ import type { SettingsManager } from "./settings-manager.js";
16
+
17
+ // ─── Helpers ────────────────────────────────────────────────────────────────
18
+
19
+ function createMockModel(provider: string, id: string): Model<Api> {
20
+ return {
21
+ id,
22
+ name: id,
23
+ api: "anthropic" as Api,
24
+ provider,
25
+ baseUrl: "https://api.anthropic.com",
26
+ reasoning: false,
27
+ input: ["text"],
28
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
29
+ contextWindow: 1_000_000,
30
+ maxTokens: 16384,
31
+ } as Model<Api>;
32
+ }
33
+
34
+ function errorMessage(msg: string): AssistantMessage {
35
+ return {
36
+ role: "assistant",
37
+ content: [],
38
+ api: "anthropic-messages",
39
+ provider: "anthropic",
40
+ model: "claude-opus-4-6[1m]",
41
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
42
+ stopReason: "error",
43
+ errorMessage: msg,
44
+ timestamp: Date.now(),
45
+ } as AssistantMessage;
46
+ }
47
+
48
+ interface MockDeps {
49
+ deps: RetryHandlerDeps;
50
+ emittedEvents: Array<Record<string, any>>;
51
+ continueFn: Mock<() => Promise<void>>;
52
+ onModelChangeFn: Mock<(model: Model<any>) => void>;
53
+ markUsageLimitReached: Mock<(...args: any[]) => boolean>;
54
+ findFallback: Mock<(...args: any[]) => Promise<any>>;
55
+ findModel: Mock<(provider: string, modelId: string) => Model<Api> | undefined>;
56
+ }
57
+
58
+ function createMockDeps(overrides?: {
59
+ model?: Model<Api>;
60
+ retryEnabled?: boolean;
61
+ markUsageLimitReachedResult?: boolean;
62
+ fallbackResult?: any;
63
+ findModelResult?: (provider: string, modelId: string) => Model<Api> | undefined;
64
+ }): MockDeps {
65
+ const model = overrides?.model ?? createMockModel("anthropic", "claude-opus-4-6[1m]");
66
+ const emittedEvents: Array<Record<string, any>> = [];
67
+ const continueFn = mock.fn(async () => {});
68
+ const onModelChangeFn = mock.fn((_model: Model<any>) => {});
69
+ const markUsageLimitReached = mock.fn(
70
+ () => overrides?.markUsageLimitReachedResult ?? false,
71
+ );
72
+ const findFallback = mock.fn(async () => overrides?.fallbackResult ?? null);
73
+ const findModel = mock.fn(
74
+ overrides?.findModelResult ?? ((_provider: string, _modelId: string) => undefined),
75
+ );
76
+
77
+ const messages: Array<{ role: string } & Record<string, any>> = [];
78
+
79
+ const deps: RetryHandlerDeps = {
80
+ agent: {
81
+ continue: continueFn,
82
+ state: { messages },
83
+ setModel: mock.fn(),
84
+ replaceMessages: mock.fn((newMessages: any[]) => {
85
+ messages.length = 0;
86
+ messages.push(...newMessages);
87
+ }),
88
+ } as any,
89
+ settingsManager: {
90
+ getRetryEnabled: () => overrides?.retryEnabled ?? true,
91
+ getRetrySettings: () => ({
92
+ enabled: overrides?.retryEnabled ?? true,
93
+ maxRetries: 5,
94
+ baseDelayMs: 1000,
95
+ maxDelayMs: 30000,
96
+ }),
97
+ } as unknown as SettingsManager,
98
+ modelRegistry: {
99
+ authStorage: {
100
+ markUsageLimitReached,
101
+ },
102
+ find: findModel,
103
+ } as unknown as ModelRegistry,
104
+ fallbackResolver: {
105
+ findFallback,
106
+ } as unknown as FallbackResolver,
107
+ getModel: () => model,
108
+ getSessionId: () => "test-session",
109
+ emit: (event: any) => emittedEvents.push(event),
110
+ onModelChange: onModelChangeFn,
111
+ };
112
+
113
+ return { deps, emittedEvents, continueFn, onModelChangeFn, markUsageLimitReached, findFallback, findModel };
114
+ }
115
+
116
+ // ─── _classifyErrorType (tested via handleRetryableError behavior) ──────────
117
+
118
+ describe("RetryHandler — long-context entitlement 429 (#2803)", () => {
119
+
120
+ describe("error classification", () => {
121
+ it("classifies 'Extra usage is required for long context requests' as quota_exhausted, not rate_limit", async () => {
122
+ // When the error is classified as quota_exhausted AND no alternate credentials
123
+ // AND no fallback, the handler should emit fallback_chain_exhausted and stop.
124
+ // If misclassified as rate_limit, it would enter the backoff loop instead.
125
+ const { deps, emittedEvents, findModel } = createMockDeps({
126
+ model: createMockModel("anthropic", "claude-opus-4-6[1m]"),
127
+ markUsageLimitReachedResult: false, // no alternate credentials
128
+ fallbackResult: null, // no cross-provider fallback
129
+ findModelResult: () => undefined, // no base model either
130
+ });
131
+
132
+ const handler = new RetryHandler(deps);
133
+ const msg = errorMessage(
134
+ '429 {"type":"error","error":{"type":"rate_limit_error","message":"Extra usage is required for long context requests."}}'
135
+ );
136
+
137
+ const result = await handler.handleRetryableError(msg);
138
+
139
+ // Should NOT retry (would be true if misclassified as rate_limit entering backoff)
140
+ assert.equal(result, false);
141
+
142
+ // Should emit fallback_chain_exhausted (quota_exhausted path), NOT auto_retry_start (backoff path)
143
+ const chainExhausted = emittedEvents.find((e) => e.type === "fallback_chain_exhausted");
144
+ assert.ok(chainExhausted, "Expected fallback_chain_exhausted event for entitlement error");
145
+
146
+ const retryStart = emittedEvents.find((e) => e.type === "auto_retry_start");
147
+ assert.equal(retryStart, undefined, "Should NOT emit auto_retry_start for entitlement error");
148
+ });
149
+
150
+ it("still classifies regular 429 rate limits as rate_limit", async () => {
151
+ // A normal "rate limit" 429 should still be classified as rate_limit
152
+ const { deps, emittedEvents } = createMockDeps({
153
+ model: createMockModel("anthropic", "claude-opus-4-6"),
154
+ markUsageLimitReachedResult: false,
155
+ fallbackResult: null,
156
+ });
157
+
158
+ const handler = new RetryHandler(deps);
159
+ const msg = errorMessage("429 Too Many Requests");
160
+
161
+ const result = await handler.handleRetryableError(msg);
162
+
163
+ // Should enter the backoff loop (rate_limit path, not quota_exhausted)
164
+ assert.equal(result, true);
165
+
166
+ const retryStart = emittedEvents.find((e) => e.type === "auto_retry_start");
167
+ assert.ok(retryStart, "Regular 429 should enter backoff retry");
168
+ });
169
+ });
170
+
171
+ describe("long-context model downgrade", () => {
172
+ it("downgrades from [1m] to base model when entitlement error and no fallback", async () => {
173
+ const baseModel = createMockModel("anthropic", "claude-opus-4-6");
174
+ const { deps, emittedEvents, onModelChangeFn, continueFn } = createMockDeps({
175
+ model: createMockModel("anthropic", "claude-opus-4-6[1m]"),
176
+ markUsageLimitReachedResult: false,
177
+ fallbackResult: null,
178
+ findModelResult: (provider: string, modelId: string) => {
179
+ if (provider === "anthropic" && modelId === "claude-opus-4-6") return baseModel;
180
+ return undefined;
181
+ },
182
+ });
183
+
184
+ const handler = new RetryHandler(deps);
185
+ const msg = errorMessage("Extra usage is required for long context requests.");
186
+
187
+ const result = await handler.handleRetryableError(msg);
188
+
189
+ assert.equal(result, true, "Should retry after downgrade");
190
+
191
+ // Should have called setModel with the base model
192
+ const setModelCalls = (deps.agent.setModel as any).mock.calls;
193
+ assert.equal(setModelCalls.length, 1);
194
+ assert.equal(setModelCalls[0].arguments[0].id, "claude-opus-4-6");
195
+
196
+ // Should have notified about model change
197
+ assert.equal(onModelChangeFn.mock.calls.length, 1);
198
+
199
+ // Should emit a fallback_provider_switch event indicating downgrade
200
+ const switchEvent = emittedEvents.find((e) => e.type === "fallback_provider_switch");
201
+ assert.ok(switchEvent, "Expected fallback_provider_switch event for downgrade");
202
+ assert.ok(switchEvent!.reason.includes("long context downgrade"), `reason should mention downgrade: ${switchEvent!.reason}`);
203
+ });
204
+
205
+ it("emits fallback_chain_exhausted when base model is also unavailable", async () => {
206
+ const { deps, emittedEvents } = createMockDeps({
207
+ model: createMockModel("anthropic", "claude-opus-4-6[1m]"),
208
+ markUsageLimitReachedResult: false,
209
+ fallbackResult: null,
210
+ findModelResult: () => undefined, // base model not found
211
+ });
212
+
213
+ const handler = new RetryHandler(deps);
214
+ const msg = errorMessage("Extra usage is required for long context requests.");
215
+
216
+ const result = await handler.handleRetryableError(msg);
217
+
218
+ assert.equal(result, false);
219
+ const chainExhausted = emittedEvents.find((e) => e.type === "fallback_chain_exhausted");
220
+ assert.ok(chainExhausted, "Expected fallback_chain_exhausted when base model unavailable");
221
+ });
222
+
223
+ it("does not attempt downgrade for non-[1m] models", async () => {
224
+ // When a regular model (no [1m] suffix) gets a quota_exhausted error
225
+ // with no fallback, it should just stop — no downgrade attempt.
226
+ const { deps, emittedEvents } = createMockDeps({
227
+ model: createMockModel("anthropic", "claude-opus-4-6"),
228
+ markUsageLimitReachedResult: false,
229
+ fallbackResult: null,
230
+ });
231
+
232
+ const handler = new RetryHandler(deps);
233
+ const msg = errorMessage("Extra usage is required for long context requests.");
234
+
235
+ const result = await handler.handleRetryableError(msg);
236
+
237
+ assert.equal(result, false);
238
+ const chainExhausted = emittedEvents.find((e) => e.type === "fallback_chain_exhausted");
239
+ assert.ok(chainExhausted);
240
+
241
+ // No downgrade switch should occur
242
+ const switchEvent = emittedEvents.find((e) => e.type === "fallback_provider_switch");
243
+ assert.equal(switchEvent, undefined, "Should not switch for non-[1m] models");
244
+ });
245
+ });
246
+
247
+ describe("isRetryableError", () => {
248
+ it("considers long-context entitlement error as retryable", () => {
249
+ const { deps } = createMockDeps();
250
+ const handler = new RetryHandler(deps);
251
+ const msg = errorMessage("Extra usage is required for long context requests.");
252
+ assert.equal(handler.isRetryableError(msg), true);
253
+ });
254
+ });
255
+ });
@@ -107,7 +107,7 @@ export class RetryHandler {
107
107
  if (isContextOverflow(message, contextWindow)) return false;
108
108
 
109
109
  const err = message.errorMessage;
110
- return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\s+)?unavailable|credentials.*expired|temporarily backed off/i.test(
110
+ return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\s+)?unavailable|credentials.*expired|temporarily backed off|extra usage is required/i.test(
111
111
  err,
112
112
  );
113
113
  }
@@ -202,6 +202,10 @@ export class RetryHandler {
202
202
 
203
203
  // No fallback available either
204
204
  if (errorType === "quota_exhausted") {
205
+ // Try long-context model downgrade ([1m] → base) before giving up
206
+ const downgraded = this._tryLongContextDowngrade(message);
207
+ if (downgraded) return true;
208
+
205
209
  this._deps.emit({
206
210
  type: "fallback_chain_exhausted",
207
211
  reason: `All providers exhausted for ${this._deps.getModel()!.provider}/${this._deps.getModel()!.id}`,
@@ -343,12 +347,59 @@ export class RetryHandler {
343
347
  */
344
348
  private _classifyErrorType(errorMessage: string): UsageLimitErrorType {
345
349
  const err = errorMessage.toLowerCase();
350
+ // Long-context entitlement errors are billing gates, not transient rate limits.
351
+ // Must be checked before the generic 429/rate_limit regex.
352
+ if (/extra usage is required|long context required/i.test(err)) return "quota_exhausted";
346
353
  if (/quota|billing|exceeded.*limit|usage.*limit/i.test(err)) return "quota_exhausted";
347
354
  if (/rate.?limit|too many requests|429/i.test(err)) return "rate_limit";
348
355
  if (/500|502|503|504|server.?error|internal.?error|service.?unavailable/i.test(err)) return "server_error";
349
356
  return "unknown";
350
357
  }
351
358
 
359
+ /**
360
+ * Attempt to downgrade a long-context model (e.g. claude-opus-4-6[1m]) to its
361
+ * base model (claude-opus-4-6) when the account lacks the long-context billing
362
+ * entitlement. Returns true if the downgrade was initiated.
363
+ */
364
+ private _tryLongContextDowngrade(message: AssistantMessage): boolean {
365
+ const currentModel = this._deps.getModel();
366
+ if (!currentModel) return false;
367
+
368
+ // Only attempt downgrade for [1m] (or similar long-context) model IDs
369
+ const match = currentModel.id.match(/^(.+)\[\d+m\]$/);
370
+ if (!match) return false;
371
+
372
+ const baseModelId = match[1];
373
+ const baseModel = this._deps.modelRegistry.find(currentModel.provider, baseModelId);
374
+ if (!baseModel) return false;
375
+
376
+ const previousId = currentModel.id;
377
+ this._deps.agent.setModel(baseModel);
378
+ this._deps.onModelChange(baseModel);
379
+ this._removeLastAssistantError();
380
+
381
+ this._deps.emit({
382
+ type: "fallback_provider_switch",
383
+ from: `${currentModel.provider}/${previousId}`,
384
+ to: `${baseModel.provider}/${baseModel.id}`,
385
+ reason: `long context downgrade: ${previousId} → ${baseModel.id}`,
386
+ });
387
+
388
+ this._deps.emit({
389
+ type: "auto_retry_start",
390
+ attempt: this._retryAttempt + 1,
391
+ maxAttempts: this._deps.settingsManager.getRetrySettings().maxRetries,
392
+ delayMs: 0,
393
+ errorMessage: `${message.errorMessage} (long context downgrade)`,
394
+ });
395
+
396
+ setTimeout(() => {
397
+ this._deps.agent.continue().catch(() => {});
398
+ }, 0);
399
+
400
+ return true;
401
+ }
402
+
352
403
  /** Remove the last assistant error message from agent state */
353
404
  private _removeLastAssistantError(): void {
354
405
  const messages = this._deps.agent.state.messages;
@@ -123,12 +123,15 @@ export function createHashlineReadTool(cwd: string, options?: HashlineReadToolOp
123
123
  const allLines = textContent.split("\n");
124
124
  const totalFileLines = allLines.length;
125
125
 
126
- const startLine = offset ? Math.max(0, offset - 1) : 0;
127
- const startLineDisplay = startLine + 1;
126
+ let startLine = offset ? Math.max(0, offset - 1) : 0;
128
127
 
128
+ // Clamp offset to file bounds instead of throwing (#3007)
129
+ let offsetClamped = false;
129
130
  if (startLine >= allLines.length) {
130
- throw new Error(`Offset ${offset} is beyond end of file (${allLines.length} lines total)`);
131
+ startLine = Math.max(0, allLines.length - 1);
132
+ offsetClamped = true;
131
133
  }
134
+ const startLineDisplay = startLine + 1;
132
135
 
133
136
  let selectedContent: string;
134
137
  let userLimitedLines: number | undefined;
@@ -172,6 +175,11 @@ export function createHashlineReadTool(cwd: string, options?: HashlineReadToolOp
172
175
  outputText = formatHashLines(truncation.content, startLineDisplay);
173
176
  }
174
177
 
178
+ // Prepend clamp notice so the agent knows offset was adjusted
179
+ if (offsetClamped) {
180
+ outputText = `[Offset ${offset} beyond end of file (${totalFileLines} lines). Clamped to line ${startLineDisplay}.]\n\n${outputText}`;
181
+ }
182
+
175
183
  content = [{ type: "text", text: outputText }];
176
184
  }
177
185
 
@@ -133,13 +133,18 @@ export function createReadTool(cwd: string, options?: ReadToolOptions): AgentToo
133
133
  const totalFileLines = allLines.length;
134
134
 
135
135
  // Apply offset if specified (1-indexed to 0-indexed)
136
- const startLine = offset ? Math.max(0, offset - 1) : 0;
137
- const startLineDisplay = startLine + 1; // For display (1-indexed)
136
+ let startLine = offset ? Math.max(0, offset - 1) : 0;
138
137
 
139
- // Check if offset is out of bounds
138
+ // Clamp offset to file bounds instead of throwing (#3007).
139
+ // When an agent requests offset:30 on a 13-line file, return
140
+ // the last line with a notice rather than an error that
141
+ // propagates as invalid JSON downstream.
142
+ let offsetClamped = false;
140
143
  if (startLine >= allLines.length) {
141
- throw new Error(`Offset ${offset} is beyond end of file (${allLines.length} lines total)`);
144
+ startLine = Math.max(0, allLines.length - 1);
145
+ offsetClamped = true;
142
146
  }
147
+ const startLineDisplay = startLine + 1; // For display (1-indexed)
143
148
 
144
149
  // If limit is specified by user, use it; otherwise we'll let truncateHead decide
145
150
  let selectedContent: string;
@@ -187,6 +192,11 @@ export function createReadTool(cwd: string, options?: ReadToolOptions): AgentToo
187
192
  outputText = truncation.content;
188
193
  }
189
194
 
195
+ // Prepend clamp notice so the agent knows offset was adjusted
196
+ if (offsetClamped) {
197
+ outputText = `[Offset ${offset} beyond end of file (${totalFileLines} lines). Clamped to line ${startLineDisplay}.]\n\n${outputText}`;
198
+ }
199
+
190
200
  content = [{ type: "text", text: outputText }];
191
201
  }
192
202
 
@@ -0,0 +1,92 @@
1
+ /**
2
+ * spawn-shell-windows.test.ts — Regression test for Windows spawn ENOENT/EINVAL.
3
+ *
4
+ * On Windows, npm/npx/tsc and other tools are installed as .cmd batch scripts.
5
+ * Node's `spawn()` without `shell: true` cannot execute .cmd files, resulting
6
+ * in ENOENT or EINVAL errors. Every spawn site that may invoke a user-installed
7
+ * binary (not `node` or a shell like `sh`/`bash`/`cmd`) must include
8
+ * `shell: process.platform === "win32"` so the call is resolved through cmd.exe
9
+ * on Windows while remaining a direct exec on POSIX.
10
+ *
11
+ * This test structurally scans all spawn sites and verifies the guard is present.
12
+ *
13
+ * Fixes: gsd-build/gsd-2#2854
14
+ */
15
+
16
+ import test from "node:test";
17
+ import assert from "node:assert/strict";
18
+ import { readFileSync } from "node:fs";
19
+ import { join, dirname, relative } from "node:path";
20
+ import { fileURLToPath } from "node:url";
21
+
22
+ const __dirname = dirname(fileURLToPath(import.meta.url));
23
+ const coreDir = join(__dirname, "..");
24
+
25
+ /**
26
+ * Files that call `spawn()` with a user-facing binary (not `node`, `sh`, `bash`,
27
+ * or `cmd`) and therefore need the Windows shell guard.
28
+ *
29
+ * If a file spawns only hardcoded system binaries (like `node` in rpc-client.ts),
30
+ * it does not need the guard and should NOT appear here.
31
+ */
32
+ const SPAWN_FILES_NEEDING_SHELL_GUARD = [
33
+ // Extension's GSD client — spawns the `gsd` binary which is a .cmd on Windows
34
+ join(coreDir, "..", "..", "..", "vscode-extension", "src", "gsd-client.ts"),
35
+ // exec.ts — used by extensions to run arbitrary commands
36
+ join(coreDir, "exec.ts"),
37
+ // LSP index — spawns project-type commands (tsc, cargo, etc.)
38
+ join(coreDir, "lsp", "index.ts"),
39
+ // LSP client — spawns LSP server binaries (npx, etc.)
40
+ join(coreDir, "lsp", "client.ts"),
41
+ // LSP mux — spawns lspmux binary
42
+ join(coreDir, "lsp", "lspmux.ts"),
43
+ // Package manager — spawns npm/yarn/pnpm
44
+ join(coreDir, "package-manager.ts"),
45
+ ];
46
+
47
+ test("all spawn sites that invoke user-facing binaries include shell: process.platform === 'win32'", () => {
48
+ const failures: string[] = [];
49
+
50
+ for (const file of SPAWN_FILES_NEEDING_SHELL_GUARD) {
51
+ let content: string;
52
+ try {
53
+ content = readFileSync(file, "utf-8");
54
+ } catch {
55
+ // File may not exist in this checkout — skip
56
+ continue;
57
+ }
58
+
59
+ const lines = content.split("\n");
60
+
61
+ // Find all spawn(..., { ... }) call sites and check each one
62
+ // for the presence of `shell: process.platform === "win32"` within
63
+ // 5 lines after the spawn call.
64
+ for (let i = 0; i < lines.length; i++) {
65
+ const line = lines[i]!;
66
+ // Skip comments
67
+ if (line.trim().startsWith("//") || line.trim().startsWith("*")) continue;
68
+
69
+ // Detect a spawn() call
70
+ if (/\bspawn\(/.test(line)) {
71
+ // Look ahead up to 8 lines for the shell guard
72
+ const lookahead = lines.slice(i, i + 8).join("\n");
73
+ const hasShellGuard =
74
+ /shell:\s*process\.platform\s*===\s*["']win32["']/.test(lookahead);
75
+
76
+ if (!hasShellGuard) {
77
+ const relPath = relative(join(coreDir, "..", ".."), file);
78
+ failures.push(`${relPath}:${i + 1}`);
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ assert.deepEqual(
85
+ failures,
86
+ [],
87
+ `The following spawn sites are missing 'shell: process.platform === "win32"':\n` +
88
+ failures.map(f => ` - ${f}`).join("\n") +
89
+ `\nOn Windows, .cmd wrapper scripts (npm, npx, tsc, gsd) require shell ` +
90
+ `resolution. Without this guard, spawn fails with ENOENT or EINVAL.`,
91
+ );
92
+ });
@@ -68,6 +68,7 @@ export type {
68
68
  Extension,
69
69
  ExtensionActions,
70
70
  ExtensionAPI,
71
+ ExtensionManifest,
71
72
  ExtensionCommandContext,
72
73
  ExtensionCommandContextActions,
73
74
  ExtensionContext,
@@ -119,6 +120,8 @@ export type {
119
120
  ToolCallEvent,
120
121
  ToolDefinition,
121
122
  ToolInfo,
123
+ SortResult,
124
+ SortWarning,
122
125
  ToolRenderResultOptions,
123
126
  ToolResultEvent,
124
127
  TurnEndEvent,
@@ -137,6 +140,9 @@ export {
137
140
  importExtensionModule,
138
141
  isToolCallEventType,
139
142
  isToolResultEventType,
143
+ readManifest,
144
+ readManifestFromEntryPath,
145
+ sortExtensionPaths,
140
146
  wrapRegisteredTool,
141
147
  wrapRegisteredTools,
142
148
  wrapToolsWithExtensions,
@@ -2,7 +2,7 @@
2
2
  * Armin says hi! A fun easter egg with animated XBM art.
3
3
  */
4
4
 
5
- import type { Component, TUI } from "@gsd/pi-tui";
5
+ import { type Component, type TUI, visibleWidth } from "@gsd/pi-tui";
6
6
  import { theme } from "../theme/theme.js";
7
7
 
8
8
  // XBM image: 31x36 pixels, LSB first, 1=background, 0=foreground
@@ -88,20 +88,20 @@ export class ArminComponent implements Component {
88
88
  return this.cachedLines;
89
89
  }
90
90
 
91
- const padding = 1;
92
- const availableWidth = width - padding;
91
+ const center = (s: string) => {
92
+ const visible = visibleWidth(s);
93
+ const left = Math.max(0, Math.floor((width - visible) / 2));
94
+ return " ".repeat(left) + s;
95
+ };
93
96
 
94
97
  this.cachedLines = this.currentGrid.map((row) => {
95
- // Clip row to available width before applying color
96
- const clipped = row.slice(0, availableWidth).join("");
97
- const padRight = Math.max(0, width - padding - clipped.length);
98
- return ` ${theme.fg("accent", clipped)}${" ".repeat(padRight)}`;
98
+ const clipped = row.slice(0, width).join("");
99
+ return center(theme.fg("accent", clipped));
99
100
  });
100
101
 
101
102
  // Add "ARMIN SAYS HI" at the end
102
103
  const message = "ARMIN SAYS HI";
103
- const msgPadRight = Math.max(0, width - padding - message.length);
104
- this.cachedLines.push(` ${theme.fg("accent", message)}${" ".repeat(msgPadRight)}`);
104
+ this.cachedLines.push(center(theme.fg("accent", message)));
105
105
 
106
106
  this.cachedWidth = width;
107
107
  this.cachedVersion = this.gridVersion;
@@ -105,8 +105,6 @@ export class AssistantMessageComponent extends Container {
105
105
  : "Operation aborted";
106
106
  if (hasVisibleContent) {
107
107
  this.contentContainer.addChild(new Spacer(1));
108
- } else {
109
- this.contentContainer.addChild(new Spacer(1));
110
108
  }
111
109
  this.contentContainer.addChild(new Text(theme.fg("error", abortMessage), 1, 0));
112
110
  } else if (message.stopReason === "error") {