gsd-pi 2.74.0-dev.28a6415 → 2.74.0-dev.658744a

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 (303) hide show
  1. package/dist/resources/extensions/gsd/auto/phases.js +51 -6
  2. package/dist/resources/extensions/gsd/auto-model-selection.js +3 -3
  3. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -3
  4. package/dist/resources/extensions/gsd/auto-recovery.js +24 -10
  5. package/dist/resources/extensions/gsd/auto-worktree.js +2 -0
  6. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -3
  7. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +10 -1
  8. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +61 -9
  9. package/dist/resources/extensions/gsd/cache.js +16 -5
  10. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  11. package/dist/resources/extensions/gsd/commands/handlers/core.js +5 -1
  12. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +50 -3
  13. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -0
  14. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
  15. package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
  16. package/dist/resources/extensions/gsd/guided-flow.js +8 -6
  17. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  18. package/dist/resources/extensions/gsd/preferences-validation.js +10 -0
  19. package/dist/resources/extensions/gsd/preferences.js +5 -0
  20. package/dist/resources/extensions/gsd/safety/evidence-collector.js +15 -30
  21. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  22. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  23. package/dist/web/standalone/.next/BUILD_ID +1 -1
  24. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  25. package/dist/web/standalone/.next/build-manifest.json +2 -2
  26. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  27. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  28. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  33. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  35. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  36. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  45. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
  46. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  48. package/dist/web/standalone/.next/server/app/index.html +1 -1
  49. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  56. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  57. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  58. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  59. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  60. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  61. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  62. package/package.json +1 -1
  63. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  64. package/packages/mcp-server/dist/workflow-tools.js +88 -6
  65. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  66. package/packages/mcp-server/src/workflow-tools.ts +95 -10
  67. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  68. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  69. package/packages/pi-ai/dist/index.d.ts +1 -9
  70. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  71. package/packages/pi-ai/dist/index.js +1 -9
  72. package/packages/pi-ai/dist/index.js.map +1 -1
  73. package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
  74. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
  75. package/packages/pi-ai/dist/models/capability-patches.js +36 -0
  76. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
  77. package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
  78. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
  79. package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
  80. package/packages/pi-ai/dist/models/custom.js.map +1 -0
  81. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
  82. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
  83. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
  84. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
  85. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
  86. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
  87. package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
  88. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
  89. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
  90. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
  91. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
  92. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
  93. package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
  94. package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
  95. package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
  96. package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
  97. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
  98. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
  99. package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
  100. package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
  101. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
  102. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
  103. package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
  104. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
  105. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
  106. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
  107. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
  108. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
  109. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
  110. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
  111. package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
  112. package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
  113. package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
  114. package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
  115. package/packages/pi-ai/dist/models/generated/google.js +464 -0
  116. package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
  117. package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
  118. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
  119. package/packages/pi-ai/dist/models/generated/groq.js +311 -0
  120. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
  121. package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
  122. package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
  123. package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
  124. package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
  125. package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
  126. package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
  127. package/packages/pi-ai/dist/models/generated/index.js +51 -0
  128. package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
  129. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
  130. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
  131. package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
  132. package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
  133. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
  134. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
  135. package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
  136. package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
  137. package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
  138. package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
  139. package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
  140. package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
  141. package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
  142. package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
  143. package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
  144. package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
  145. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
  146. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
  147. package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
  148. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
  149. package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
  150. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
  151. package/packages/pi-ai/dist/models/generated/openai.js +702 -0
  152. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
  153. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
  154. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
  155. package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
  156. package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
  157. package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
  158. package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
  159. package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
  160. package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
  161. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
  162. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
  163. package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
  164. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
  165. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
  166. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
  167. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
  168. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
  169. package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
  170. package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/models/generated/xai.js +413 -0
  172. package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
  173. package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
  174. package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
  175. package/packages/pi-ai/dist/models/generated/zai.js +239 -0
  176. package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
  177. package/packages/pi-ai/dist/models/index.d.ts +27 -0
  178. package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
  179. package/packages/pi-ai/dist/models/index.js +80 -0
  180. package/packages/pi-ai/dist/models/index.js.map +1 -0
  181. package/packages/pi-ai/dist/models.d.ts +1 -36
  182. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  183. package/packages/pi-ai/dist/models.generated.test.js +1 -2
  184. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  185. package/packages/pi-ai/dist/models.js +3 -112
  186. package/packages/pi-ai/dist/models.js.map +1 -1
  187. package/packages/pi-ai/dist/models.test.js +6 -5
  188. package/packages/pi-ai/dist/models.test.js.map +1 -1
  189. package/packages/pi-ai/scripts/generate-models.ts +74 -40
  190. package/packages/pi-ai/src/index.ts +1 -9
  191. package/packages/pi-ai/src/models/capability-patches.ts +40 -0
  192. package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
  193. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
  194. package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
  195. package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
  196. package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
  197. package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
  198. package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
  199. package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
  200. package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
  201. package/packages/pi-ai/src/models/generated/google.ts +466 -0
  202. package/packages/pi-ai/src/models/generated/groq.ts +313 -0
  203. package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
  204. package/packages/pi-ai/src/models/generated/index.ts +52 -0
  205. package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
  206. package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
  207. package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
  208. package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
  209. package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
  210. package/packages/pi-ai/src/models/generated/openai.ts +704 -0
  211. package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
  212. package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
  213. package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
  214. package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
  215. package/packages/pi-ai/src/models/generated/xai.ts +415 -0
  216. package/packages/pi-ai/src/models/generated/zai.ts +241 -0
  217. package/packages/pi-ai/src/models/index.ts +106 -0
  218. package/packages/pi-ai/src/models.generated.test.ts +1 -2
  219. package/packages/pi-ai/src/models.test.ts +6 -5
  220. package/packages/pi-ai/src/models.ts +3 -153
  221. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  222. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
  224. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +214 -0
  226. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  227. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +11 -0
  228. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  229. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -0
  230. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  231. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +18 -8
  232. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  233. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
  234. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
  235. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +47 -0
  236. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
  237. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  238. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +68 -8
  240. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
  243. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +115 -4
  246. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  248. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  249. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  250. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  251. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -0
  252. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  253. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +70 -6
  254. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  255. package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
  256. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +273 -0
  257. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +19 -0
  258. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +20 -9
  259. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +67 -0
  260. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +83 -7
  261. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
  262. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +176 -40
  263. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  264. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +92 -6
  265. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  266. package/src/resources/extensions/gsd/auto/phases.ts +70 -6
  267. package/src/resources/extensions/gsd/auto-model-selection.ts +3 -3
  268. package/src/resources/extensions/gsd/auto-post-unit.ts +7 -3
  269. package/src/resources/extensions/gsd/auto-recovery.ts +29 -9
  270. package/src/resources/extensions/gsd/auto-worktree.ts +1 -0
  271. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +5 -3
  272. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -1
  273. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +72 -8
  274. package/src/resources/extensions/gsd/cache.ts +16 -5
  275. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  276. package/src/resources/extensions/gsd/commands/handlers/core.ts +5 -1
  277. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +57 -3
  278. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -0
  279. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
  280. package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
  281. package/src/resources/extensions/gsd/guided-flow.ts +4 -2
  282. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  283. package/src/resources/extensions/gsd/preferences-validation.ts +10 -0
  284. package/src/resources/extensions/gsd/preferences.ts +6 -0
  285. package/src/resources/extensions/gsd/safety/evidence-collector.ts +15 -31
  286. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  287. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +177 -0
  288. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +272 -0
  289. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +117 -0
  290. package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
  291. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +3 -3
  292. package/src/resources/extensions/gsd/tests/preferences.test.ts +145 -0
  293. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +57 -2
  294. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
  295. package/src/resources/extensions/gsd/types.ts +13 -0
  296. package/src/resources/extensions/gsd/workflow-logger.ts +2 -1
  297. package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
  298. package/packages/pi-ai/dist/models.custom.js.map +0 -1
  299. package/packages/pi-ai/dist/models.generated.js +0 -14343
  300. package/packages/pi-ai/dist/models.generated.js.map +0 -1
  301. package/packages/pi-ai/src/models.generated.ts +0 -14345
  302. /package/dist/web/standalone/.next/static/{fMaWScj7m6EsI3DbaNv2_ → Es_JWCfFZjIvYZShmjyye}/_buildManifest.js +0 -0
  303. /package/dist/web/standalone/.next/static/{fMaWScj7m6EsI3DbaNv2_ → Es_JWCfFZjIvYZShmjyye}/_ssgManifest.js +0 -0
@@ -95,6 +95,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
95
95
  }
96
96
 
97
97
  host.footer.invalidate();
98
+ const timestampFormat = host.settingsManager.getTimestampFormat();
98
99
 
99
100
  // Reset content index tracker and pinned state when a new assistant message starts
100
101
  if (event.type === "message_start" && event.message.role === "assistant") {
@@ -238,7 +239,10 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
238
239
  // content (#4144 regression). Prior sub-turn children stay in
239
240
  // chatContainer as frozen history; new segments append after them.
240
241
  if (contentBlocks.length < lastContentLength) {
241
- orphanedSegments = [...renderedSegments];
242
+ // Accumulate across successive shrinks — overwriting would drop
243
+ // segments displaced by an earlier shrink, leaving them stranded
244
+ // in chatContainer once the prune pass finally runs.
245
+ orphanedSegments = [...orphanedSegments, ...renderedSegments];
242
246
  renderedSegments = [];
243
247
  lastPinnedText = "";
244
248
  lastProcessedContentIndex = 0;
@@ -341,29 +345,35 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
341
345
  type DesiredSegment =
342
346
  | { kind: "text-run"; startIndex: number; endIndex: number; contentType: "text" | "thinking" }
343
347
  | { kind: "tool"; contentIndex: number; toolId: string };
344
- const desired: DesiredSegment[] = [];
345
- let runStart = -1;
346
- let runEnd = -1;
347
- let runType: "text" | "thinking" | undefined;
348
- const closeRun = () => {
349
- if (runStart !== -1 && runType) {
350
- desired.push({ kind: "text-run", startIndex: runStart, endIndex: runEnd, contentType: runType });
351
- runStart = -1;
352
- runEnd = -1;
353
- runType = undefined;
348
+ const desired: DesiredSegment[] = [];
349
+ let runStart = -1;
350
+ let runEnd = -1;
351
+ let runType: "text" | "thinking" | undefined;
352
+ const closeRun = () => {
353
+ if (runStart !== -1 && runType) {
354
+ desired.push({ kind: "text-run", startIndex: runStart, endIndex: runEnd, contentType: runType });
355
+ runStart = -1;
356
+ runEnd = -1;
357
+ runType = undefined;
354
358
  }
355
359
  };
356
- for (let i = 0; i < blocks.length; i++) {
357
- const b = blocks[i];
358
- const blockType = b.type === "text" || b.type === "thinking" ? b.type : undefined;
359
- const isTextLike = blockType === "text" || blockType === "thinking";
360
- const isTool = b.type === "toolCall" || b.type === "serverToolUse";
361
- // For Claude Code MCP turns, prune only pre-tool prose, never thinking.
362
- const shouldSkipProse = shouldDropPreToolProse && firstToolIdx >= 0 && i < firstToolIdx && blockType === "text";
363
- if (shouldSkipProse) {
364
- closeRun();
365
- continue;
366
- }
360
+ for (let i = 0; i < blocks.length; i++) {
361
+ const b = blocks[i];
362
+ const blockType = b.type === "text" || b.type === "thinking" ? b.type : undefined;
363
+ const isTextLike = blockType === "text" || blockType === "thinking";
364
+ const isTool = b.type === "toolCall" || b.type === "serverToolUse";
365
+ // For Claude Code MCP turns, prune only pre-tool prose, never thinking.
366
+ const textValue = blockType === "text" && typeof b?.text === "string" ? b.text : "";
367
+ const isLikelyQuestion = blockType === "text" && typeof textValue === "string" && /\?\s*$/.test(textValue.trim());
368
+ const shouldSkipProse = shouldDropPreToolProse
369
+ && firstToolIdx >= 0
370
+ && i < firstToolIdx
371
+ && blockType === "text"
372
+ && !isLikelyQuestion;
373
+ if (shouldSkipProse) {
374
+ closeRun();
375
+ continue;
376
+ }
367
377
  if (isTextLike) {
368
378
  if (runStart === -1) {
369
379
  runStart = i;
@@ -459,7 +469,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
459
469
  undefined,
460
470
  host.hideThinkingBlock,
461
471
  host.getMarkdownThemeWithSettings(),
462
- host.settingsManager.getTimestampFormat(),
472
+ timestampFormat,
463
473
  { startIndex: seg.startIndex, endIndex: seg.endIndex },
464
474
  );
465
475
  host.chatContainer.addChild(comp);
@@ -553,11 +563,11 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
553
563
  }
554
564
  break;
555
565
 
556
- case "message_end":
557
- if (event.message.role === "user") break;
558
- if (event.message.role === "assistant") {
559
- host.streamingMessage = event.message;
560
- let errorMessage: string | undefined;
566
+ case "message_end":
567
+ if (event.message.role === "user") break;
568
+ if (event.message.role === "assistant") {
569
+ host.streamingMessage = event.message;
570
+ let errorMessage: string | undefined;
561
571
  if (host.streamingMessage.stopReason === "aborted") {
562
572
  const retryAttempt = host.session.retryAttempt;
563
573
  errorMessage = retryAttempt > 0
@@ -566,18 +576,144 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
566
576
  host.streamingMessage.errorMessage = errorMessage;
567
577
  }
568
578
 
569
- const shouldRenderAssistant = hasVisibleAssistantContent(host.streamingMessage)
570
- || (
571
- (host.streamingMessage.stopReason === "aborted" || host.streamingMessage.stopReason === "error")
572
- && !hasAssistantToolBlocks(host.streamingMessage)
573
- );
574
- if (!host.streamingComponent && shouldRenderAssistant) {
575
- host.streamingComponent = new AssistantMessageComponent(
576
- undefined,
577
- host.hideThinkingBlock,
578
- host.getMarkdownThemeWithSettings(),
579
- host.settingsManager.getTimestampFormat(),
580
- );
579
+ const shouldRenderAssistant = hasVisibleAssistantContent(host.streamingMessage)
580
+ || (
581
+ (host.streamingMessage.stopReason === "aborted" || host.streamingMessage.stopReason === "error")
582
+ && !hasAssistantToolBlocks(host.streamingMessage)
583
+ );
584
+
585
+ // The final message_end payload can contain additional text/thinking
586
+ // blocks that never arrived via message_update (e.g. SDK result
587
+ // aggregation). Rebuild this in-flight turn from final content so
588
+ // ranges/components don't keep stale partial indices.
589
+ if (renderedSegments.length > 0) {
590
+ const finalBlocks = host.streamingMessage.content;
591
+ type DesiredSegment =
592
+ | { kind: "text-run"; startIndex: number; endIndex: number; contentType: "text" | "thinking" }
593
+ | { kind: "tool"; contentIndex: number; toolId: string };
594
+ const desired: DesiredSegment[] = [];
595
+ let runStart = -1;
596
+ let runEnd = -1;
597
+ let runType: "text" | "thinking" | undefined;
598
+ const closeRun = () => {
599
+ if (runStart !== -1 && runType) {
600
+ desired.push({ kind: "text-run", startIndex: runStart, endIndex: runEnd, contentType: runType });
601
+ runStart = -1;
602
+ runEnd = -1;
603
+ runType = undefined;
604
+ }
605
+ };
606
+
607
+ for (let i = 0; i < finalBlocks.length; i++) {
608
+ const block = finalBlocks[i] as any;
609
+ const blockType = block?.type === "text" || block?.type === "thinking" ? block.type : undefined;
610
+ const isTextLike = blockType === "text" || blockType === "thinking";
611
+ const isTool = block?.type === "toolCall" || block?.type === "serverToolUse";
612
+
613
+ if (isTextLike) {
614
+ if (runStart === -1) {
615
+ runStart = i;
616
+ runEnd = i;
617
+ runType = blockType;
618
+ } else if (runType !== blockType) {
619
+ closeRun();
620
+ runStart = i;
621
+ runEnd = i;
622
+ runType = blockType;
623
+ } else {
624
+ runEnd = i;
625
+ }
626
+ } else {
627
+ closeRun();
628
+ if (isTool) {
629
+ desired.push({ kind: "tool", contentIndex: i, toolId: block.id });
630
+ }
631
+ }
632
+ }
633
+ closeRun();
634
+
635
+ const toolComponentsById = new Map<string, ToolExecutionComponent>();
636
+ for (const [toolId, component] of host.pendingTools.entries()) {
637
+ toolComponentsById.set(toolId, component);
638
+ }
639
+
640
+ for (const seg of renderedSegments) {
641
+ host.chatContainer.removeChild(seg.component);
642
+ if (seg.kind === "tool") {
643
+ const priorBlocks = host.streamingMessage.content;
644
+ const priorBlock = priorBlocks[seg.contentIndex] as any;
645
+ if (priorBlock?.id && !toolComponentsById.has(priorBlock.id)) {
646
+ toolComponentsById.set(priorBlock.id, seg.component);
647
+ }
648
+ }
649
+ }
650
+ renderedSegments = [];
651
+ host.streamingComponent = undefined;
652
+
653
+ for (const seg of desired) {
654
+ if (seg.kind === "tool") {
655
+ const finalBlock = finalBlocks[seg.contentIndex] as any;
656
+ let component = toolComponentsById.get(seg.toolId);
657
+ if (!component && finalBlock?.id) {
658
+ component = host.pendingTools.get(finalBlock.id);
659
+ }
660
+ if (!component && finalBlock?.type === "toolCall") {
661
+ component = new ToolExecutionComponent(
662
+ finalBlock.name,
663
+ finalBlock.arguments,
664
+ { showImages: host.settingsManager.getShowImages() },
665
+ host.getRegisteredToolDefinition(finalBlock.name),
666
+ host.ui,
667
+ );
668
+ component.setExpanded(host.toolOutputExpanded);
669
+ host.pendingTools.set(finalBlock.id, component);
670
+ toolComponentsById.set(finalBlock.id, component);
671
+ } else if (!component && finalBlock?.type === "serverToolUse") {
672
+ component = new ToolExecutionComponent(
673
+ finalBlock.name,
674
+ finalBlock.input ?? {},
675
+ { showImages: host.settingsManager.getShowImages() },
676
+ undefined,
677
+ host.ui,
678
+ );
679
+ component.setExpanded(host.toolOutputExpanded);
680
+ host.pendingTools.set(finalBlock.id, component);
681
+ toolComponentsById.set(finalBlock.id, component);
682
+ }
683
+ if (component) {
684
+ host.chatContainer.addChild(component);
685
+ renderedSegments.push({ kind: "tool", contentIndex: seg.contentIndex, component });
686
+ }
687
+ continue;
688
+ }
689
+
690
+ const comp = new AssistantMessageComponent(
691
+ undefined,
692
+ host.hideThinkingBlock,
693
+ host.getMarkdownThemeWithSettings(),
694
+ timestampFormat,
695
+ { startIndex: seg.startIndex, endIndex: seg.endIndex },
696
+ );
697
+ comp.updateContent(host.streamingMessage);
698
+ host.chatContainer.addChild(comp);
699
+ renderedSegments.push({
700
+ kind: "text-run",
701
+ startIndex: seg.startIndex,
702
+ endIndex: seg.endIndex,
703
+ contentType: seg.contentType,
704
+ component: comp,
705
+ });
706
+ host.streamingComponent = comp;
707
+ }
708
+ }
709
+
710
+ if (!host.streamingComponent && shouldRenderAssistant) {
711
+ host.streamingComponent = new AssistantMessageComponent(
712
+ undefined,
713
+ host.hideThinkingBlock,
714
+ host.getMarkdownThemeWithSettings(),
715
+ timestampFormat,
716
+ );
581
717
  host.chatContainer.addChild(host.streamingComponent);
582
718
  }
583
719
  if (host.streamingComponent) {
@@ -0,0 +1,44 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+
4
+ import { buildAssistantReplaySegments } from "./interactive-mode.js";
5
+
6
+ test("buildAssistantReplaySegments preserves tool-first ordering", () => {
7
+ const segments = buildAssistantReplaySegments([
8
+ { type: "toolCall", id: "t1", name: "read", arguments: {} },
9
+ { type: "text", text: "Done." },
10
+ ]);
11
+
12
+ assert.deepEqual(segments, [
13
+ { kind: "tool", contentIndex: 0 },
14
+ { kind: "assistant", startIndex: 1, endIndex: 1 },
15
+ ]);
16
+ });
17
+
18
+ test("buildAssistantReplaySegments preserves interleaved assistant-tool-assistant runs", () => {
19
+ const segments = buildAssistantReplaySegments([
20
+ { type: "text", text: "Let me check." },
21
+ { type: "serverToolUse", id: "s1", name: "mcp__fs__glob", input: {} },
22
+ { type: "thinking", thinking: "Tool result looks good." },
23
+ { type: "text", text: "Here is the answer." },
24
+ ]);
25
+
26
+ assert.deepEqual(segments, [
27
+ { kind: "assistant", startIndex: 0, endIndex: 0 },
28
+ { kind: "tool", contentIndex: 1 },
29
+ { kind: "assistant", startIndex: 2, endIndex: 3 },
30
+ ]);
31
+ });
32
+
33
+ test("buildAssistantReplaySegments ignores non-rendered non-tool blocks", () => {
34
+ const segments = buildAssistantReplaySegments([
35
+ { type: "text", text: "before" },
36
+ { type: "webSearchResult", toolUseId: "s1", content: {} },
37
+ { type: "text", text: "after" },
38
+ ]);
39
+
40
+ assert.deepEqual(segments, [
41
+ { kind: "assistant", startIndex: 0, endIndex: 0 },
42
+ { kind: "assistant", startIndex: 2, endIndex: 2 },
43
+ ]);
44
+ });
@@ -127,6 +127,45 @@ function isExpandable(obj: unknown): obj is Expandable {
127
127
  return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
128
128
  }
129
129
 
130
+ export type AssistantReplaySegment =
131
+ | { kind: "assistant"; startIndex: number; endIndex: number }
132
+ | { kind: "tool"; contentIndex: number };
133
+
134
+ /**
135
+ * Build replay segments for historical assistant messages so rebuild paths
136
+ * preserve the original content[] ordering between assistant prose and tools.
137
+ */
138
+ export function buildAssistantReplaySegments(contentBlocks: Array<any>): AssistantReplaySegment[] {
139
+ const segments: AssistantReplaySegment[] = [];
140
+ let runStart = -1;
141
+
142
+ for (let i = 0; i < contentBlocks.length; i++) {
143
+ const block = contentBlocks[i];
144
+ const isAssistantText = block?.type === "text" || block?.type === "thinking";
145
+ const isTool = block?.type === "toolCall" || block?.type === "serverToolUse";
146
+
147
+ if (isAssistantText) {
148
+ if (runStart === -1) runStart = i;
149
+ continue;
150
+ }
151
+
152
+ if (runStart !== -1) {
153
+ segments.push({ kind: "assistant", startIndex: runStart, endIndex: i - 1 });
154
+ runStart = -1;
155
+ }
156
+
157
+ if (isTool) {
158
+ segments.push({ kind: "tool", contentIndex: i });
159
+ }
160
+ }
161
+
162
+ if (runStart !== -1) {
163
+ segments.push({ kind: "assistant", startIndex: runStart, endIndex: contentBlocks.length - 1 });
164
+ }
165
+
166
+ return segments;
167
+ }
168
+
130
169
  type CompactionQueuedMessage = {
131
170
  text: string;
132
171
  mode: "steer" | "followUp";
@@ -1788,6 +1827,8 @@ export class InteractiveMode {
1788
1827
  this.showError(message);
1789
1828
  } else if (type === "warning") {
1790
1829
  this.showWarning(message);
1830
+ } else if (type === "success") {
1831
+ this.showSuccess(message);
1791
1832
  } else {
1792
1833
  this.showStatus(message, { append: true });
1793
1834
  }
@@ -2078,6 +2119,7 @@ export class InteractiveMode {
2078
2119
  }
2079
2120
 
2080
2121
  private addMessageToChat(message: AgentMessage, options?: { populateHistory?: boolean }): void {
2122
+ const timestampFormat = this.settingsManager.getTimestampFormat();
2081
2123
  switch (message.role) {
2082
2124
  case "bashExecution": {
2083
2125
  const component = new BashExecutionComponent(message.command, this.ui, message.excludeFromContext);
@@ -2135,12 +2177,12 @@ export class InteractiveMode {
2135
2177
  skillBlock.userMessage,
2136
2178
  this.getMarkdownThemeWithSettings(),
2137
2179
  message.timestamp,
2138
- this.settingsManager.getTimestampFormat(),
2180
+ timestampFormat,
2139
2181
  );
2140
2182
  this.chatContainer.addChild(userComponent);
2141
2183
  }
2142
2184
  } else {
2143
- const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), message.timestamp, this.settingsManager.getTimestampFormat());
2185
+ const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), message.timestamp, timestampFormat);
2144
2186
  this.chatContainer.addChild(userComponent);
2145
2187
  }
2146
2188
  if (options?.populateHistory) {
@@ -2154,7 +2196,7 @@ export class InteractiveMode {
2154
2196
  message,
2155
2197
  this.hideThinkingBlock,
2156
2198
  this.getMarkdownThemeWithSettings(),
2157
- this.settingsManager.getTimestampFormat(),
2199
+ timestampFormat,
2158
2200
  );
2159
2201
  this.chatContainer.addChild(assistantComponent);
2160
2202
  break;
@@ -2192,6 +2234,7 @@ export class InteractiveMode {
2192
2234
  options: { updateFooter?: boolean; populateHistory?: boolean } = {},
2193
2235
  ): void {
2194
2236
  this.pendingTools.clear();
2237
+ const timestampFormat = this.settingsManager.getTimestampFormat();
2195
2238
 
2196
2239
  if (options.updateFooter) {
2197
2240
  this.footer.invalidate();
@@ -2201,9 +2244,30 @@ export class InteractiveMode {
2201
2244
  for (const message of sessionContext.messages) {
2202
2245
  // Assistant messages need special handling for tool calls
2203
2246
  if (message.role === "assistant") {
2204
- this.addMessageToChat(message);
2205
- // Render tool call components
2206
- for (const content of message.content) {
2247
+ const hasToolBlocks = message.content.some((c) => c.type === "toolCall" || c.type === "serverToolUse");
2248
+ if (!hasToolBlocks) {
2249
+ this.addMessageToChat(message);
2250
+ continue;
2251
+ }
2252
+
2253
+ const assistantSegments: AssistantMessageComponent[] = [];
2254
+ const replaySegments = buildAssistantReplaySegments(message.content);
2255
+
2256
+ for (const segment of replaySegments) {
2257
+ if (segment.kind === "assistant") {
2258
+ const assistantComponent = new AssistantMessageComponent(
2259
+ message,
2260
+ this.hideThinkingBlock,
2261
+ this.getMarkdownThemeWithSettings(),
2262
+ timestampFormat,
2263
+ { startIndex: segment.startIndex, endIndex: segment.endIndex },
2264
+ );
2265
+ this.chatContainer.addChild(assistantComponent);
2266
+ assistantSegments.push(assistantComponent);
2267
+ continue;
2268
+ }
2269
+
2270
+ const content = message.content[segment.contentIndex];
2207
2271
  if (content.type === "toolCall") {
2208
2272
  const component = new ToolExecutionComponent(
2209
2273
  content.name,
@@ -2259,6 +2323,11 @@ export class InteractiveMode {
2259
2323
  }
2260
2324
  }
2261
2325
  }
2326
+
2327
+ // Match streaming-mode behavior: show metadata once on the final
2328
+ // assistant prose segment for this message.
2329
+ const lastAssistantSegment = assistantSegments[assistantSegments.length - 1];
2330
+ lastAssistantSegment?.setShowMetadata(true);
2262
2331
  } else if (message.role === "toolResult") {
2263
2332
  // Match tool results to pending tool components
2264
2333
  const component = this.pendingTools.get(message.toolCallId);
@@ -2272,6 +2341,12 @@ export class InteractiveMode {
2272
2341
  }
2273
2342
  }
2274
2343
 
2344
+ // Any pendingTools entries left over after replay are historical tool
2345
+ // calls whose results were squashed out of session context (commonly by
2346
+ // compaction). Mark them finished so the frame stops showing "Running".
2347
+ for (const component of this.pendingTools.values()) {
2348
+ component.markHistoricalNoResult();
2349
+ }
2275
2350
  this.pendingTools.clear();
2276
2351
  this.trimChatHistory();
2277
2352
  this.ui.requestRender();
@@ -2670,6 +2745,17 @@ export class InteractiveMode {
2670
2745
  this.ui.requestRender();
2671
2746
  }
2672
2747
 
2748
+ showSuccess(successMessage: string): void {
2749
+ this.chatContainer.addChild(new Spacer(1));
2750
+ this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("success", text)));
2751
+ this.chatContainer.addChild(
2752
+ new Text(theme.fg("success", successMessage), 1, 0),
2753
+ );
2754
+ this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("success", text)));
2755
+ this.chatContainer.addChild(new Spacer(1));
2756
+ this.ui.requestRender();
2757
+ }
2758
+
2673
2759
  showTip(message: string): void {
2674
2760
  this.chatContainer.addChild(new Spacer(1));
2675
2761
  this.chatContainer.addChild(new Text(theme.fg("dim", `💡 ${message}`), 1, 0));