@superblocksteam/vite-plugin-file-sync 2.0.114 → 2.0.115-next.1

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 (355) hide show
  1. package/dist/ai-service/agent/middleware.d.ts.map +1 -1
  2. package/dist/ai-service/agent/middleware.js +19 -0
  3. package/dist/ai-service/agent/middleware.js.map +1 -1
  4. package/dist/ai-service/agent/prompts/api-prompts.d.ts.map +1 -1
  5. package/dist/ai-service/agent/prompts/api-prompts.js +13 -17
  6. package/dist/ai-service/agent/prompts/api-prompts.js.map +1 -1
  7. package/dist/ai-service/agent/prompts/build-base-system-prompt.d.ts.map +1 -1
  8. package/dist/ai-service/agent/prompts/build-base-system-prompt.js +22 -3
  9. package/dist/ai-service/agent/prompts/build-base-system-prompt.js.map +1 -1
  10. package/dist/ai-service/agent/subagents/coding/prompt-builder.d.ts +16 -0
  11. package/dist/ai-service/agent/subagents/coding/prompt-builder.d.ts.map +1 -0
  12. package/dist/ai-service/agent/subagents/coding/prompt-builder.js +30 -0
  13. package/dist/ai-service/agent/subagents/coding/prompt-builder.js.map +1 -0
  14. package/dist/ai-service/agent/subagents/coding/run-coding-subagent.d.ts +29 -0
  15. package/dist/ai-service/agent/subagents/coding/run-coding-subagent.d.ts.map +1 -0
  16. package/dist/ai-service/agent/subagents/coding/run-coding-subagent.js +108 -0
  17. package/dist/ai-service/agent/subagents/coding/run-coding-subagent.js.map +1 -0
  18. package/dist/ai-service/agent/subagents/types.d.ts +9 -1
  19. package/dist/ai-service/agent/subagents/types.d.ts.map +1 -1
  20. package/dist/ai-service/agent/subagents/types.js +8 -0
  21. package/dist/ai-service/agent/subagents/types.js.map +1 -1
  22. package/dist/ai-service/agent/tool-message-utils.d.ts.map +1 -1
  23. package/dist/ai-service/agent/tool-message-utils.js +5 -0
  24. package/dist/ai-service/agent/tool-message-utils.js.map +1 -1
  25. package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.d.ts.map +1 -1
  26. package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.js +2 -1
  27. package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.js.map +1 -1
  28. package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.d.ts +6 -0
  29. package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.d.ts.map +1 -0
  30. package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.js +138 -0
  31. package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.js.map +1 -0
  32. package/dist/ai-service/agent/tools/build-finalize.d.ts.map +1 -1
  33. package/dist/ai-service/agent/tools/build-finalize.js +39 -15
  34. package/dist/ai-service/agent/tools/build-finalize.js.map +1 -1
  35. package/dist/ai-service/agent/tools/build-manage-checklist.d.ts +6 -3
  36. package/dist/ai-service/agent/tools/build-manage-checklist.d.ts.map +1 -1
  37. package/dist/ai-service/agent/tools/build-manage-checklist.js +116 -49
  38. package/dist/ai-service/agent/tools/build-manage-checklist.js.map +1 -1
  39. package/dist/ai-service/agent/tools/index.d.ts +2 -0
  40. package/dist/ai-service/agent/tools/index.d.ts.map +1 -1
  41. package/dist/ai-service/agent/tools/index.js +2 -0
  42. package/dist/ai-service/agent/tools/index.js.map +1 -1
  43. package/dist/ai-service/agent/tools/integrations/execute-request.d.ts +3 -0
  44. package/dist/ai-service/agent/tools/integrations/execute-request.d.ts.map +1 -1
  45. package/dist/ai-service/agent/tools/integrations/execute-request.js +330 -204
  46. package/dist/ai-service/agent/tools/integrations/execute-request.js.map +1 -1
  47. package/dist/ai-service/agent/tools.d.ts.map +1 -1
  48. package/dist/ai-service/agent/tools.js +40 -2
  49. package/dist/ai-service/agent/tools.js.map +1 -1
  50. package/dist/ai-service/agent/tools2/access-control.d.ts +1 -1
  51. package/dist/ai-service/agent/tools2/access-control.d.ts.map +1 -1
  52. package/dist/ai-service/agent/tools2/access-control.js +15 -4
  53. package/dist/ai-service/agent/tools2/access-control.js.map +1 -1
  54. package/dist/ai-service/agent/tools2/registry.d.ts +3 -0
  55. package/dist/ai-service/agent/tools2/registry.d.ts.map +1 -1
  56. package/dist/ai-service/agent/tools2/registry.js +50 -8
  57. package/dist/ai-service/agent/tools2/registry.js.map +1 -1
  58. package/dist/ai-service/agent/tools2/tools/ask-multi-choice.d.ts.map +1 -1
  59. package/dist/ai-service/agent/tools2/tools/ask-multi-choice.js +3 -2
  60. package/dist/ai-service/agent/tools2/tools/ask-multi-choice.js.map +1 -1
  61. package/dist/ai-service/agent/tools2/tools/ask-searchable-dropdown.d.ts.map +1 -1
  62. package/dist/ai-service/agent/tools2/tools/ask-searchable-dropdown.js +2 -1
  63. package/dist/ai-service/agent/tools2/tools/ask-searchable-dropdown.js.map +1 -1
  64. package/dist/ai-service/agent/tools2/tools/deploy-service.d.ts +16 -0
  65. package/dist/ai-service/agent/tools2/tools/deploy-service.d.ts.map +1 -0
  66. package/dist/ai-service/agent/tools2/tools/deploy-service.js +135 -0
  67. package/dist/ai-service/agent/tools2/tools/deploy-service.js.map +1 -0
  68. package/dist/ai-service/agent/tools2/tools/download-attachments.d.ts +33 -0
  69. package/dist/ai-service/agent/tools2/tools/download-attachments.d.ts.map +1 -0
  70. package/dist/ai-service/agent/tools2/tools/download-attachments.js +308 -0
  71. package/dist/ai-service/agent/tools2/tools/download-attachments.js.map +1 -0
  72. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
  73. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +8 -4
  74. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
  75. package/dist/ai-service/agent/tools2/tools/git.d.ts +57 -1
  76. package/dist/ai-service/agent/tools2/tools/git.d.ts.map +1 -1
  77. package/dist/ai-service/agent/tools2/tools/git.js +275 -8
  78. package/dist/ai-service/agent/tools2/tools/git.js.map +1 -1
  79. package/dist/ai-service/agent/tools2/tools/index.d.ts +2 -1
  80. package/dist/ai-service/agent/tools2/tools/index.d.ts.map +1 -1
  81. package/dist/ai-service/agent/tools2/tools/index.js +2 -1
  82. package/dist/ai-service/agent/tools2/tools/index.js.map +1 -1
  83. package/dist/ai-service/agent/tools2/tools/list-attachments.d.ts +4 -1
  84. package/dist/ai-service/agent/tools2/tools/list-attachments.d.ts.map +1 -1
  85. package/dist/ai-service/agent/tools2/tools/list-attachments.js +20 -4
  86. package/dist/ai-service/agent/tools2/tools/list-attachments.js.map +1 -1
  87. package/dist/ai-service/agent/tools2/tools/spawn-coding-subagents.d.ts +28 -0
  88. package/dist/ai-service/agent/tools2/tools/spawn-coding-subagents.d.ts.map +1 -0
  89. package/dist/ai-service/agent/tools2/tools/spawn-coding-subagents.js +152 -0
  90. package/dist/ai-service/agent/tools2/tools/spawn-coding-subagents.js.map +1 -0
  91. package/dist/ai-service/agent/tools2/types.d.ts +1 -18
  92. package/dist/ai-service/agent/tools2/types.d.ts.map +1 -1
  93. package/dist/ai-service/agent/tools2/types.js.map +1 -1
  94. package/dist/ai-service/agent/utils.d.ts.map +1 -1
  95. package/dist/ai-service/agent/utils.js +22 -5
  96. package/dist/ai-service/agent/utils.js.map +1 -1
  97. package/dist/ai-service/app-interface/file-system-interface.d.ts +0 -4
  98. package/dist/ai-service/app-interface/file-system-interface.d.ts.map +1 -1
  99. package/dist/ai-service/app-interface/file-system-interface.js +0 -21
  100. package/dist/ai-service/app-interface/file-system-interface.js.map +1 -1
  101. package/dist/ai-service/app-interface/filesystem/virtual-file-system.d.ts +11 -1
  102. package/dist/ai-service/app-interface/filesystem/virtual-file-system.d.ts.map +1 -1
  103. package/dist/ai-service/app-interface/filesystem/virtual-file-system.js +29 -7
  104. package/dist/ai-service/app-interface/filesystem/virtual-file-system.js.map +1 -1
  105. package/dist/ai-service/app-interface/shell.d.ts +6 -0
  106. package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
  107. package/dist/ai-service/app-interface/shell.js +8 -0
  108. package/dist/ai-service/app-interface/shell.js.map +1 -1
  109. package/dist/ai-service/app-skills/helpers.d.ts.map +1 -1
  110. package/dist/ai-service/app-skills/helpers.js +4 -2
  111. package/dist/ai-service/app-skills/helpers.js.map +1 -1
  112. package/dist/ai-service/attachments/store.d.ts +18 -2
  113. package/dist/ai-service/attachments/store.d.ts.map +1 -1
  114. package/dist/ai-service/attachments/store.js +102 -9
  115. package/dist/ai-service/attachments/store.js.map +1 -1
  116. package/dist/ai-service/attachments/uploaded-content-part.d.ts +5 -2
  117. package/dist/ai-service/attachments/uploaded-content-part.d.ts.map +1 -1
  118. package/dist/ai-service/attachments/uploaded-content-part.js +32 -0
  119. package/dist/ai-service/attachments/uploaded-content-part.js.map +1 -1
  120. package/dist/ai-service/chat/chat-session-store.d.ts +2 -2
  121. package/dist/ai-service/chat/chat-session-store.d.ts.map +1 -1
  122. package/dist/ai-service/chat/chat-session-store.js +45 -243
  123. package/dist/ai-service/chat/chat-session-store.js.map +1 -1
  124. package/dist/ai-service/chat/utils.d.ts +6 -0
  125. package/dist/ai-service/chat/utils.d.ts.map +1 -1
  126. package/dist/ai-service/chat/utils.js +47 -0
  127. package/dist/ai-service/chat/utils.js.map +1 -1
  128. package/dist/ai-service/features.d.ts +4 -0
  129. package/dist/ai-service/features.d.ts.map +1 -1
  130. package/dist/ai-service/features.js +4 -0
  131. package/dist/ai-service/features.js.map +1 -1
  132. package/dist/ai-service/index.d.ts +36 -11
  133. package/dist/ai-service/index.d.ts.map +1 -1
  134. package/dist/ai-service/index.js +228 -68
  135. package/dist/ai-service/index.js.map +1 -1
  136. package/dist/ai-service/judge/tools/playwright-action.d.ts +1 -1
  137. package/dist/ai-service/llm/client.d.ts.map +1 -1
  138. package/dist/ai-service/llm/client.js +4 -2
  139. package/dist/ai-service/llm/client.js.map +1 -1
  140. package/dist/ai-service/llm/stream/observers/retry-notification.d.ts.map +1 -1
  141. package/dist/ai-service/llm/stream/observers/retry-notification.js +4 -2
  142. package/dist/ai-service/llm/stream/observers/retry-notification.js.map +1 -1
  143. package/dist/ai-service/prompt-builder-service/classifiers/prompt-interpret-task.d.ts.map +1 -1
  144. package/dist/ai-service/prompt-builder-service/classifiers/prompt-interpret-task.js +1 -16
  145. package/dist/ai-service/prompt-builder-service/classifiers/prompt-interpret-task.js.map +1 -1
  146. package/dist/ai-service/prompt-builder-service/types.d.ts +2 -13
  147. package/dist/ai-service/prompt-builder-service/types.d.ts.map +1 -1
  148. package/dist/ai-service/prompt-builder-service/types.js.map +1 -1
  149. package/dist/ai-service/skills/system/_registry.generated.d.ts.map +1 -1
  150. package/dist/ai-service/skills/system/_registry.generated.js +6 -0
  151. package/dist/ai-service/skills/system/_registry.generated.js.map +1 -1
  152. package/dist/ai-service/skills/system/superblocks-migration/references/focused-debug.generated.d.ts +2 -0
  153. package/dist/ai-service/skills/system/superblocks-migration/references/focused-debug.generated.d.ts.map +1 -0
  154. package/dist/ai-service/skills/system/superblocks-migration/references/focused-debug.generated.js +58 -0
  155. package/dist/ai-service/skills/system/superblocks-migration/references/focused-debug.generated.js.map +1 -0
  156. package/dist/ai-service/skills/system/superblocks-migration/references/yaml-block-mapping.generated.d.ts +2 -0
  157. package/dist/ai-service/skills/system/superblocks-migration/references/yaml-block-mapping.generated.d.ts.map +1 -0
  158. package/dist/ai-service/skills/system/superblocks-migration/references/yaml-block-mapping.generated.js +107 -0
  159. package/dist/ai-service/skills/system/superblocks-migration/references/yaml-block-mapping.generated.js.map +1 -0
  160. package/dist/ai-service/skills/system/superblocks-migration/skill.generated.d.ts +2 -0
  161. package/dist/ai-service/skills/system/superblocks-migration/skill.generated.d.ts.map +1 -0
  162. package/dist/ai-service/skills/system/superblocks-migration/skill.generated.js +137 -0
  163. package/dist/ai-service/skills/system/superblocks-migration/skill.generated.js.map +1 -0
  164. package/dist/ai-service/state-machine/clark-fsm.d.ts +26 -13
  165. package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
  166. package/dist/ai-service/state-machine/clark-fsm.js +12 -7
  167. package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
  168. package/dist/ai-service/state-machine/handlers/agent-planning.d.ts.map +1 -1
  169. package/dist/ai-service/state-machine/handlers/agent-planning.js +51 -27
  170. package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -1
  171. package/dist/ai-service/state-machine/handlers/awaiting-user.d.ts.map +1 -1
  172. package/dist/ai-service/state-machine/handlers/awaiting-user.js +15 -6
  173. package/dist/ai-service/state-machine/handlers/awaiting-user.js.map +1 -1
  174. package/dist/ai-service/state-machine/handlers/idle.d.ts.map +1 -1
  175. package/dist/ai-service/state-machine/handlers/idle.js +4 -2
  176. package/dist/ai-service/state-machine/handlers/idle.js.map +1 -1
  177. package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -1
  178. package/dist/ai-service/state-machine/handlers/llm-generating.js +48 -15
  179. package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
  180. package/dist/ai-service/state-machine/handlers/post-processing.d.ts +1 -1
  181. package/dist/ai-service/state-machine/handlers/post-processing.d.ts.map +1 -1
  182. package/dist/ai-service/state-machine/handlers/post-processing.js +23 -151
  183. package/dist/ai-service/state-machine/handlers/post-processing.js.map +1 -1
  184. package/dist/ai-service/state-machine/handlers/runtime-reviewing.d.ts.map +1 -1
  185. package/dist/ai-service/state-machine/handlers/runtime-reviewing.js +16 -8
  186. package/dist/ai-service/state-machine/handlers/runtime-reviewing.js.map +1 -1
  187. package/dist/ai-service/state-machine/helpers/change-info.d.ts.map +1 -1
  188. package/dist/ai-service/state-machine/helpers/change-info.js +2 -15
  189. package/dist/ai-service/state-machine/helpers/change-info.js.map +1 -1
  190. package/dist/ai-service/state-machine/helpers/peer.d.ts +3 -3
  191. package/dist/ai-service/state-machine/helpers/peer.d.ts.map +1 -1
  192. package/dist/ai-service/state-machine/helpers/peer.js +9 -23
  193. package/dist/ai-service/state-machine/helpers/peer.js.map +1 -1
  194. package/dist/ai-service/state-machine/helpers/stable-peer.d.ts +52 -0
  195. package/dist/ai-service/state-machine/helpers/stable-peer.d.ts.map +1 -0
  196. package/dist/ai-service/state-machine/helpers/stable-peer.js +141 -0
  197. package/dist/ai-service/state-machine/helpers/stable-peer.js.map +1 -0
  198. package/dist/ai-service/state-machine/mocks.d.ts.map +1 -1
  199. package/dist/ai-service/state-machine/mocks.js +0 -17
  200. package/dist/ai-service/state-machine/mocks.js.map +1 -1
  201. package/dist/ai-service/types.d.ts +2 -21
  202. package/dist/ai-service/types.d.ts.map +1 -1
  203. package/dist/ai-service/types.js.map +1 -1
  204. package/dist/ai-service/util/archive-extractors.d.ts +52 -0
  205. package/dist/ai-service/util/archive-extractors.d.ts.map +1 -0
  206. package/dist/ai-service/util/archive-extractors.js +278 -0
  207. package/dist/ai-service/util/archive-extractors.js.map +1 -0
  208. package/dist/codegen.d.ts +1 -22
  209. package/dist/codegen.d.ts.map +1 -1
  210. package/dist/codegen.js +1 -117
  211. package/dist/codegen.js.map +1 -1
  212. package/dist/components-manager.d.ts +0 -6
  213. package/dist/components-manager.d.ts.map +1 -1
  214. package/dist/components-manager.js +0 -27
  215. package/dist/components-manager.js.map +1 -1
  216. package/dist/file-sync-vite-plugin.d.ts.map +1 -1
  217. package/dist/file-sync-vite-plugin.js +47 -94
  218. package/dist/file-sync-vite-plugin.js.map +1 -1
  219. package/dist/file-system-manager.d.ts +2 -15
  220. package/dist/file-system-manager.d.ts.map +1 -1
  221. package/dist/file-system-manager.js +16 -128
  222. package/dist/file-system-manager.js.map +1 -1
  223. package/dist/git-service/live-branch.d.ts.map +1 -1
  224. package/dist/git-service/live-branch.js +15 -1
  225. package/dist/git-service/live-branch.js.map +1 -1
  226. package/dist/lock-service/index.d.ts.map +1 -1
  227. package/dist/lock-service/index.js +8 -5
  228. package/dist/lock-service/index.js.map +1 -1
  229. package/dist/migration/get-fullstack-template-dir.d.ts +37 -0
  230. package/dist/migration/get-fullstack-template-dir.d.ts.map +1 -0
  231. package/dist/migration/get-fullstack-template-dir.js +99 -0
  232. package/dist/migration/get-fullstack-template-dir.js.map +1 -0
  233. package/dist/migration/migration-checklist.d.ts +60 -0
  234. package/dist/migration/migration-checklist.d.ts.map +1 -0
  235. package/dist/migration/migration-checklist.js +230 -0
  236. package/dist/migration/migration-checklist.js.map +1 -0
  237. package/dist/migration/migration-routes.d.ts +23 -0
  238. package/dist/migration/migration-routes.d.ts.map +1 -0
  239. package/dist/migration/migration-routes.js +533 -0
  240. package/dist/migration/migration-routes.js.map +1 -0
  241. package/dist/migration/restructure.d.ts +76 -0
  242. package/dist/migration/restructure.d.ts.map +1 -0
  243. package/dist/migration/restructure.js +446 -0
  244. package/dist/migration/restructure.js.map +1 -0
  245. package/dist/migration/translation-prompt.d.ts +22 -0
  246. package/dist/migration/translation-prompt.d.ts.map +1 -0
  247. package/dist/migration/translation-prompt.js +27 -0
  248. package/dist/migration/translation-prompt.js.map +1 -0
  249. package/dist/migration-templates/app-fullstack/client/App.tsx +17 -0
  250. package/dist/migration-templates/app-fullstack/client/components/common/sonner.tsx +20 -0
  251. package/dist/migration-templates/app-fullstack/client/components/hooks/use-active-page.ts +73 -0
  252. package/dist/migration-templates/app-fullstack/client/components/hooks/use-mobile.ts +21 -0
  253. package/dist/migration-templates/app-fullstack/client/components/ui/accordion.tsx +197 -0
  254. package/dist/migration-templates/app-fullstack/client/components/ui/area-chart.tsx +432 -0
  255. package/dist/migration-templates/app-fullstack/client/components/ui/aspect-ratio.tsx +45 -0
  256. package/dist/migration-templates/app-fullstack/client/components/ui/avatar.tsx +117 -0
  257. package/dist/migration-templates/app-fullstack/client/components/ui/badge.tsx +143 -0
  258. package/dist/migration-templates/app-fullstack/client/components/ui/bar-chart.tsx +390 -0
  259. package/dist/migration-templates/app-fullstack/client/components/ui/breadcrumb.tsx +259 -0
  260. package/dist/migration-templates/app-fullstack/client/components/ui/button.tsx +182 -0
  261. package/dist/migration-templates/app-fullstack/client/components/ui/calendar.tsx +300 -0
  262. package/dist/migration-templates/app-fullstack/client/components/ui/card.tsx +129 -0
  263. package/dist/migration-templates/app-fullstack/client/components/ui/chart.tsx +403 -0
  264. package/dist/migration-templates/app-fullstack/client/components/ui/chat.tsx +2303 -0
  265. package/dist/migration-templates/app-fullstack/client/components/ui/checkbox.tsx +97 -0
  266. package/dist/migration-templates/app-fullstack/client/components/ui/code-block-content.tsx +66 -0
  267. package/dist/migration-templates/app-fullstack/client/components/ui/date-range-picker.tsx +396 -0
  268. package/dist/migration-templates/app-fullstack/client/components/ui/dialog.tsx +223 -0
  269. package/dist/migration-templates/app-fullstack/client/components/ui/dropdown-menu.tsx +284 -0
  270. package/dist/migration-templates/app-fullstack/client/components/ui/file-dropzone.tsx +395 -0
  271. package/dist/migration-templates/app-fullstack/client/components/ui/file-input.tsx +166 -0
  272. package/dist/migration-templates/app-fullstack/client/components/ui/hover-card.tsx +162 -0
  273. package/dist/migration-templates/app-fullstack/client/components/ui/icon.tsx +133 -0
  274. package/dist/migration-templates/app-fullstack/client/components/ui/image.tsx +68 -0
  275. package/dist/migration-templates/app-fullstack/client/components/ui/input.tsx +219 -0
  276. package/dist/migration-templates/app-fullstack/client/components/ui/label.tsx +55 -0
  277. package/dist/migration-templates/app-fullstack/client/components/ui/line-chart.tsx +380 -0
  278. package/dist/migration-templates/app-fullstack/client/components/ui/link.tsx +139 -0
  279. package/dist/migration-templates/app-fullstack/client/components/ui/navigation-menu.tsx +345 -0
  280. package/dist/migration-templates/app-fullstack/client/components/ui/pagination.tsx +192 -0
  281. package/dist/migration-templates/app-fullstack/client/components/ui/pie-chart.tsx +295 -0
  282. package/dist/migration-templates/app-fullstack/client/components/ui/popover.tsx +162 -0
  283. package/dist/migration-templates/app-fullstack/client/components/ui/progress.tsx +69 -0
  284. package/dist/migration-templates/app-fullstack/client/components/ui/radar-chart.tsx +386 -0
  285. package/dist/migration-templates/app-fullstack/client/components/ui/radial-chart.tsx +402 -0
  286. package/dist/migration-templates/app-fullstack/client/components/ui/scroll-area.tsx +86 -0
  287. package/dist/migration-templates/app-fullstack/client/components/ui/select.tsx +229 -0
  288. package/dist/migration-templates/app-fullstack/client/components/ui/separator.tsx +62 -0
  289. package/dist/migration-templates/app-fullstack/client/components/ui/sheet.tsx +234 -0
  290. package/dist/migration-templates/app-fullstack/client/components/ui/sidebar.tsx +974 -0
  291. package/dist/migration-templates/app-fullstack/client/components/ui/skeleton.tsx +13 -0
  292. package/dist/migration-templates/app-fullstack/client/components/ui/slider.tsx +198 -0
  293. package/dist/migration-templates/app-fullstack/client/components/ui/switch.tsx +95 -0
  294. package/dist/migration-templates/app-fullstack/client/components/ui/table.tsx +145 -0
  295. package/dist/migration-templates/app-fullstack/client/components/ui/tabs.tsx +87 -0
  296. package/dist/migration-templates/app-fullstack/client/components/ui/textarea.tsx +148 -0
  297. package/dist/migration-templates/app-fullstack/client/components/ui/toggle-group.tsx +225 -0
  298. package/dist/migration-templates/app-fullstack/client/components/ui/toggle.tsx +150 -0
  299. package/dist/migration-templates/app-fullstack/client/components/ui/tooltip.tsx +175 -0
  300. package/dist/migration-templates/app-fullstack/client/hooks/useApi.ts +25 -0
  301. package/dist/migration-templates/app-fullstack/client/hooks/useApiData.ts +10 -0
  302. package/dist/migration-templates/app-fullstack/client/index.css +131 -0
  303. package/dist/migration-templates/app-fullstack/client/lib/executeApi.ts +9 -0
  304. package/dist/migration-templates/app-fullstack/client/lib/utils.ts +6 -0
  305. package/dist/migration-templates/app-fullstack/client/pages/Page1/index.tsx +3 -0
  306. package/dist/migration-templates/app-fullstack/client/root.tsx +17 -0
  307. package/dist/migration-templates/app-fullstack/client/router.tsx +48 -0
  308. package/dist/migration-templates/app-fullstack/client/types/node.d.ts +9 -0
  309. package/dist/migration-templates/app-fullstack/components.json +21 -0
  310. package/dist/migration-templates/app-fullstack/eslint.config.js +108 -0
  311. package/dist/migration-templates/app-fullstack/package.json +89 -0
  312. package/dist/migration-templates/app-fullstack/server/.gitkeep +0 -0
  313. package/dist/migration-templates/app-fullstack/server/apis/index.ts +22 -0
  314. package/dist/migration-templates/app-fullstack/server/index.ts +2 -0
  315. package/dist/migration-templates/app-fullstack/tsconfig.client.json +27 -0
  316. package/dist/migration-templates/app-fullstack/tsconfig.eslint.json +8 -0
  317. package/dist/migration-templates/app-fullstack/tsconfig.json +25 -0
  318. package/dist/migration-templates/app-fullstack/tsconfig.server.json +13 -0
  319. package/dist/migration-templates/app-fullstack/vite.config.ts +17 -0
  320. package/dist/parsing/imports.d.ts +0 -16
  321. package/dist/parsing/imports.d.ts.map +1 -1
  322. package/dist/parsing/imports.js +0 -68
  323. package/dist/parsing/imports.js.map +1 -1
  324. package/dist/parsing/jsx.d.ts +0 -2
  325. package/dist/parsing/jsx.d.ts.map +1 -1
  326. package/dist/parsing/jsx.js +0 -62
  327. package/dist/parsing/jsx.js.map +1 -1
  328. package/dist/socket-manager.d.ts.map +1 -1
  329. package/dist/socket-manager.js +109 -32
  330. package/dist/socket-manager.js.map +1 -1
  331. package/dist/source-tracker.d.ts +7 -85
  332. package/dist/source-tracker.d.ts.map +1 -1
  333. package/dist/source-tracker.js +19 -695
  334. package/dist/source-tracker.js.map +1 -1
  335. package/dist/sync-service/index.d.ts +79 -2
  336. package/dist/sync-service/index.d.ts.map +1 -1
  337. package/dist/sync-service/index.js +139 -10
  338. package/dist/sync-service/index.js.map +1 -1
  339. package/package.json +11 -9
  340. package/dist/ai-service/artifacts/bolt.d.ts +0 -8
  341. package/dist/ai-service/artifacts/bolt.d.ts.map +0 -1
  342. package/dist/ai-service/artifacts/bolt.js +0 -92
  343. package/dist/ai-service/artifacts/bolt.js.map +0 -1
  344. package/dist/ai-service/result-buffer/bolt.d.ts +0 -18
  345. package/dist/ai-service/result-buffer/bolt.d.ts.map +0 -1
  346. package/dist/ai-service/result-buffer/bolt.js +0 -100
  347. package/dist/ai-service/result-buffer/bolt.js.map +0 -1
  348. package/dist/ai-service/result-buffer/shared.d.ts +0 -17
  349. package/dist/ai-service/result-buffer/shared.d.ts.map +0 -1
  350. package/dist/ai-service/result-buffer/shared.js +0 -7
  351. package/dist/ai-service/result-buffer/shared.js.map +0 -1
  352. package/dist/inject-no-select.d.ts +0 -15
  353. package/dist/inject-no-select.d.ts.map +0 -1
  354. package/dist/inject-no-select.js +0 -175
  355. package/dist/inject-no-select.js.map +0 -1
@@ -4,7 +4,9 @@ import path from "node:path";
4
4
  import { generateObject, hasToolCall, } from "ai";
5
5
  import { z } from "zod";
6
6
  import { AiMode, resolveAttachmentFileName, } from "@superblocksteam/library-shared/types";
7
- import { addTracingToMethods, FactAccessType, FactCreatedSource, FactEntityScope, TracedEventEmitter, } from "@superblocksteam/shared";
7
+ import { addTracingToMethods, classifyAttachmentDelivery, FactAccessType, FactCreatedSource, FactEntityScope, TracedEventEmitter, } from "@superblocksteam/shared";
8
+ import { readMigrationChecklist } from "../migration/migration-checklist.js";
9
+ import { buildTranslationPrompt } from "../migration/translation-prompt.js";
8
10
  import { getErrorMeta, getLogger, setDefaultLogger } from "../util/logger.js";
9
11
  import { getToolCallArguments, getToolErrorCode, getToolOutput, } from "./agent/tool-message-utils.js";
10
12
  import { hasPendingEscalations, flushPendingEscalations, } from "./agent/tools/apis/api-validation-orchestrator.js";
@@ -20,7 +22,6 @@ import { FileSystemInterface } from "./app-interface/file-system-interface.js";
20
22
  import { createDefaultVirtualFileSystem, createPathValidator, } from "./app-interface/filesystem/index.js";
21
23
  import { AppShell } from "./app-interface/shell.js";
22
24
  import { AppSkillsManager } from "./app-skills/manager.js";
23
- import { BoltArtifactProcessor } from "./artifacts/bolt.js";
24
25
  import { isUploadedAttachment, toUploadedAttachmentContentPart, } from "./attachments/uploaded-content-part.js";
25
26
  import { ChatSessionStore } from "./chat/chat-session-store.js";
26
27
  import { normalizeTextAttachmentForModel } from "./chat/utils.js";
@@ -54,6 +55,7 @@ import { doRuntimeReviewing } from "./state-machine/handlers/runtime-reviewing.j
54
55
  import { classificationHelper } from "./state-machine/helpers/classification.js";
55
56
  import { getContextId } from "./state-machine/helpers/context-id.js";
56
57
  import { sendUserMessageChannel, clearPendingToolPermissionRequest, } from "./state-machine/helpers/peer.js";
58
+ import { StablePeer } from "./state-machine/helpers/stable-peer.js";
57
59
  import { transitionFrom } from "./state-machine/helpers/transition.js";
58
60
  import { TemplateRenderer } from "./template-renderer.js";
59
61
  import { createJsonStreamParser } from "./util/json-stream-parser.js";
@@ -125,7 +127,6 @@ const mergePlanContexts = (existing, incoming) => {
125
127
  };
126
128
  export class AiService extends TracedEventEmitter {
127
129
  config;
128
- artifactProcessor;
129
130
  templateRenderer;
130
131
  appShell;
131
132
  fileSystemInterface;
@@ -139,6 +140,7 @@ export class AiService extends TracedEventEmitter {
139
140
  chatSessionStore;
140
141
  contextManagerV2;
141
142
  llmClient;
143
+ stablePeer = new StablePeer();
142
144
  toolRegistry = new ToolRegistry();
143
145
  entityPermissionStore = new SessionEntityPermissionStore();
144
146
  _onGenerationCompleteCallback;
@@ -245,10 +247,12 @@ export class AiService extends TracedEventEmitter {
245
247
  return this.config.features.aiFileUploadEnabled === true;
246
248
  }
247
249
  /**
248
- * Checks if there is a connected peer (user is connected via socket)
250
+ * Checks if there is a live editor socket behind the StablePeer proxy.
251
+ * `clark.context.peer` is always present (it's the proxy); inner liveness
252
+ * is tracked on the proxy itself via `peerId`.
249
253
  */
250
254
  hasConnectedPeer() {
251
- return !!this.clark?.context?.peer;
255
+ return this.stablePeer?.peerId != null;
252
256
  }
253
257
  constructor(config) {
254
258
  super(config.tracer);
@@ -259,8 +263,6 @@ export class AiService extends TracedEventEmitter {
259
263
  this._logger = getLogger();
260
264
  // Prevent traced functions from creating traces when called outside of a Clark context
261
265
  llmobs.setDefaultRootPolicy("drop-if-no-parent");
262
- // todo: move to state handlers
263
- this.artifactProcessor = new BoltArtifactProcessor();
264
266
  this.llmProviderSettings = {
265
267
  anthropic: {
266
268
  baseURL: config.superblocksBaseUrl,
@@ -298,13 +300,13 @@ export class AiService extends TracedEventEmitter {
298
300
  enableDeletingLockfiles: config.features.enableDeletingLockfiles ?? false,
299
301
  messageSender: async (message) => {
300
302
  // Send checklist messages through the peer connection
301
- if (this.clark.context.peer &&
302
- (message.type === "checklist_item_added" ||
303
- message.type === "checklist_item_updated")) {
303
+ if (message.type === "checklist_item_added" ||
304
+ message.type === "checklist_item_updated") {
304
305
  const sendUserMessage = sendUserMessageChannel(this.clark, this.chatSessionStore);
305
306
  await sendUserMessage({
306
- type: "text",
307
- text: "",
307
+ role: "assistant",
308
+ type: "tool",
309
+ content: "",
308
310
  group: "checklist",
309
311
  status: "ready",
310
312
  checklistData: message,
@@ -375,6 +377,7 @@ export class AiService extends TracedEventEmitter {
375
377
  this.clark = new Clark({
376
378
  initialContext: {
377
379
  abortController: new AbortController(),
380
+ peer: this.stablePeer,
378
381
  },
379
382
  createTransitionHandler: this.createClarkTransitionHandler(),
380
383
  createTagProvider: this.createClarkTagProviderFactory(),
@@ -405,6 +408,7 @@ export class AiService extends TracedEventEmitter {
405
408
  });
406
409
  const handlerMethods = [
407
410
  "handleAiGenerate",
411
+ "handleAiTriggerMigrationTurn",
408
412
  "handleAiRespondToToolPermission",
409
413
  "handleUserAcceptedDraft",
410
414
  "handleUserRejectedDraft",
@@ -428,6 +432,7 @@ export class AiService extends TracedEventEmitter {
428
432
  */
429
433
  async initialize() {
430
434
  await this.integrationStore.initialize();
435
+ await this.hydrateMigrationChecklistFromDisk();
431
436
  // Start recording with initial commit ID from chat history (if enabled)
432
437
  if (this.config.features.sessionRecordingEnabled === true) {
433
438
  const initialCommitId = await this.chatSessionStore.getLatestCommitId();
@@ -438,6 +443,44 @@ export class AiService extends TracedEventEmitter {
438
443
  });
439
444
  this.getLogger().info("[ai-service] Initialized");
440
445
  }
446
+ async hydrateMigrationChecklistFromDisk() {
447
+ const migrationChecklist = await readMigrationChecklist(this.appRootDirPath);
448
+ if (!migrationChecklist) {
449
+ return;
450
+ }
451
+ const hasPendingSeedApi = migrationChecklist.items.some((item) => item.origin === "seed_api" &&
452
+ (item.status === "pending" || item.status === "in_progress"));
453
+ if (hasPendingSeedApi) {
454
+ this.appShell.setApiHandlerEnabled(false);
455
+ this.getLogger().info("[ai-service] Migration in progress on disk — disabled API VFS projection so Clark reads raw YAML");
456
+ }
457
+ await this.chatSessionStore.recordAssistant({
458
+ role: "assistant",
459
+ type: "tool",
460
+ content: "",
461
+ group: "checklist",
462
+ checklistData: {
463
+ type: "checklist_cleared",
464
+ payload: {},
465
+ },
466
+ });
467
+ const totalItems = migrationChecklist.items.length;
468
+ for (const item of migrationChecklist.items) {
469
+ await this.chatSessionStore.recordAssistant({
470
+ role: "assistant",
471
+ type: "tool",
472
+ content: "",
473
+ group: "checklist",
474
+ checklistData: {
475
+ type: "checklist_item_added",
476
+ payload: {
477
+ item,
478
+ totalItems,
479
+ },
480
+ },
481
+ });
482
+ }
483
+ }
441
484
  /**
442
485
  * Remove the integration metadata cache for this session.
443
486
  * Cleans up the session cache directory.
@@ -468,7 +511,6 @@ export class AiService extends TracedEventEmitter {
468
511
  ...this.config,
469
512
  logger: this.getLogger(),
470
513
  templateRenderer: this.templateRenderer,
471
- artifactProcessor: this.artifactProcessor,
472
514
  appShell: this.appShell,
473
515
  signals: this,
474
516
  fileSystemInterface: this.fileSystemInterface,
@@ -597,8 +639,113 @@ export class AiService extends TracedEventEmitter {
597
639
  this.getLogger().warn("[ai-service] Quota check failed, allowing request", getErrorMeta(error));
598
640
  }
599
641
  }
600
- async handleAiGenerate(request, peer, peerId) {
601
- this.getLogger().info(`[ai-service] handleAiGenerate: peerId=${peerId}`);
642
+ /**
643
+ * Fires the internal, UI-invisible migration turn if the app is post-flip
644
+ * and still has `seed_api` checklist items pending. Safe to call multiple
645
+ * times — the `migrationTurnTriggered` guard ensures one-shot semantics
646
+ * per ai-service lifetime. The disk checklist is the recovery source of
647
+ * truth across process restarts.
648
+ *
649
+ * Expected caller: the UI issues a dedicated RPC (see
650
+ * v1.ai.triggerMigrationTurn) once it observes the post-flip state via
651
+ * /sb-migration-status. jwt + llmConfig come from the UI's normal auth
652
+ * flow.
653
+ */
654
+ async handleAiTriggerMigrationTurn(request) {
655
+ // User-initiated "Fix with Clark" retries bypass the one-shot
656
+ // guard. The HTTP route that flips the items has already landed,
657
+ // so if we refused here the user would be stuck.
658
+ if (request.retryMode === "focused-debug") {
659
+ this.migrationTurnTriggered = false;
660
+ }
661
+ if (this.migrationTurnTriggered) {
662
+ return { dispatched: false, reason: "already-triggered" };
663
+ }
664
+ if (this.clark.state === ClarkStateNames.Dead) {
665
+ return { dispatched: false, reason: "dead" };
666
+ }
667
+ if (this.clark.state !== ClarkStateNames.Idle &&
668
+ this.clark.state !== ClarkStateNames.AwaitingUser) {
669
+ return { dispatched: false, reason: `busy:${this.clark.state}` };
670
+ }
671
+ const checklist = await readMigrationChecklist(this.appRootDirPath);
672
+ if (!checklist) {
673
+ this.getLogger().warn("[ai-service] Migration checklist not found or unreadable; skipping translation turn");
674
+ return { dispatched: false, reason: "checklist-unavailable" };
675
+ }
676
+ const pendingSeedApiItems = checklist.items.filter((item) => item.origin === "seed_api" && item.status === "pending");
677
+ const pendingSeedApiCount = pendingSeedApiItems.length;
678
+ if (pendingSeedApiCount === 0) {
679
+ return { dispatched: false, reason: "no-pending-items" };
680
+ }
681
+ this.migrationTurnTriggered = true;
682
+ this.appShell.setApiHandlerEnabled(false);
683
+ this.getLogger().info(`[ai-service] Dispatching internal v2→v3 migration turn for ${pendingSeedApiCount} API(s) (API VFS projection disabled, retryMode=${request.retryMode ?? "none"})`);
684
+ const prompt = buildTranslationPrompt({
685
+ focusedDebug: request.retryMode === "focused-debug",
686
+ });
687
+ const migrationLlmConfig = this.getMigrationSafeLlmConfig(request.llmConfig);
688
+ const generateRequest = {
689
+ prompt,
690
+ jwt: request.jwt,
691
+ llmConfig: migrationLlmConfig,
692
+ mode: AiMode.BUILD,
693
+ };
694
+ this.clark.updateContext((context) => ({
695
+ ...context,
696
+ promptId: randomUUID(),
697
+ llmConfig: migrationLlmConfig,
698
+ }));
699
+ const transitionTo = transitionFrom(this.clark);
700
+ // Promise is intentionally not awaited — the translation turn runs in the
701
+ // background. We reset the guard + re-enable the API handler when the
702
+ // turn *settles* (success or failure) so any remaining pending items
703
+ // (from auto-retry budget flips or genuine agent exits) can trigger
704
+ // another sweep without a dev-server restart.
705
+ transitionTo({
706
+ type: USER_SENT_PROMPT,
707
+ request: generateRequest,
708
+ internal: true,
709
+ })
710
+ .catch((error) => {
711
+ this.getLogger().error("[ai-service] Migration translation turn failed", getErrorMeta(error));
712
+ })
713
+ .finally(() => {
714
+ this.migrationTurnTriggered = false;
715
+ this.appShell.setApiHandlerEnabled(true);
716
+ });
717
+ return { dispatched: true };
718
+ }
719
+ getMigrationSafeLlmConfig(llmConfig) {
720
+ const requiredMigrationTools = new Set([
721
+ "build_manageChecklist",
722
+ "build_manage_checklist",
723
+ // Focused-debug retries instruct the agent to ask the user via
724
+ // askMultiChoice when the blocker is informational (e.g. the
725
+ // original SQL was stubbed before backup). If the caller
726
+ // disabled that tool, we'd loop on the ZERO-judgment rule.
727
+ "askMultiChoice",
728
+ ]);
729
+ const disabledTools = Array.isArray(llmConfig.disabledTools)
730
+ ? llmConfig.disabledTools
731
+ : [];
732
+ if (disabledTools.length === 0) {
733
+ return llmConfig;
734
+ }
735
+ const filteredDisabledTools = disabledTools.filter((tool) => !requiredMigrationTools.has(tool));
736
+ if (filteredDisabledTools.length !== disabledTools.length) {
737
+ this.getLogger().warn("[ai-service] Migration turn overrides disabledTools to keep checklist tool available", {
738
+ removedTools: disabledTools.filter((tool) => requiredMigrationTools.has(tool)),
739
+ });
740
+ }
741
+ return {
742
+ ...llmConfig,
743
+ disabledTools: filteredDisabledTools,
744
+ };
745
+ }
746
+ migrationTurnTriggered = false;
747
+ async handleAiGenerate(request) {
748
+ this.getLogger().info(`[ai-service] handleAiGenerate: peerId=${this.stablePeer.peerId ?? "unknown"}`);
602
749
  if (this.clark.state === ClarkStateNames.Dead) {
603
750
  throw new Error("Service is unavailable");
604
751
  }
@@ -648,11 +795,9 @@ export class AiService extends TracedEventEmitter {
648
795
  void transitionTo({
649
796
  type: USER_SENT_PROMPT,
650
797
  request,
651
- peer,
652
- peerId,
653
798
  });
654
799
  }
655
- async handleAiExplainCode(request, peer) {
800
+ async handleAiExplainCode(request) {
656
801
  if (this.clark.state === ClarkStateNames.Dead) {
657
802
  throw new Error("Service is unavailable");
658
803
  }
@@ -660,6 +805,7 @@ export class AiService extends TracedEventEmitter {
660
805
  this.getLogger().warn("[ai-service] Service is busy. State:", this.clark.state);
661
806
  throw new Error("Service is busy");
662
807
  }
808
+ const peer = this.clark.context.peer;
663
809
  this.clarkProfiler.startSession();
664
810
  getLogger().info(`[ai-service] Explaining code (${request.codeType}): ${request.itemId}.${request.propertyName}`);
665
811
  try {
@@ -795,10 +941,11 @@ export class AiService extends TracedEventEmitter {
795
941
  });
796
942
  }
797
943
  }
798
- async handleAiSummarizeApiUsage(request, peer) {
944
+ async handleAiSummarizeApiUsage(request) {
799
945
  if (this.clark.state === ClarkStateNames.Dead) {
800
946
  throw new Error("Service is unavailable");
801
947
  }
948
+ const peer = this.clark.context.peer;
802
949
  getLogger().info(`[ai-service] Summarizing API usage for: ${request.apiName}`);
803
950
  try {
804
951
  // Read the API source file and extract integration info
@@ -929,10 +1076,11 @@ export class AiService extends TracedEventEmitter {
929
1076
  });
930
1077
  }
931
1078
  }
932
- async handleAiSummarizeError(request, peer) {
1079
+ async handleAiSummarizeError(request) {
933
1080
  if (this.clark.state === ClarkStateNames.Dead) {
934
1081
  throw new Error("Service is unavailable");
935
1082
  }
1083
+ const peer = this.clark.context.peer;
936
1084
  try {
937
1085
  let apiSourceCode;
938
1086
  if (request.apiName) {
@@ -1052,6 +1200,28 @@ export class AiService extends TracedEventEmitter {
1052
1200
  fileName: attachment.fileName,
1053
1201
  type: attachment.type,
1054
1202
  });
1203
+ const attachmentMimeType = attachment.type === "uploaded"
1204
+ ? attachment.mediaType
1205
+ : attachment.type === "pdf"
1206
+ ? (attachment.data.match(/^data:([^;]+);base64,/)?.[1] ??
1207
+ "application/pdf")
1208
+ : attachment.type === "archive"
1209
+ ? (attachment.data.match(/^data:([^;]+);base64,/)?.[1] ??
1210
+ "application/octet-stream")
1211
+ : attachment.type === "image"
1212
+ ? (attachment.image.match(/^data:([^;]+);base64,/)?.[1] ??
1213
+ "image/png")
1214
+ : attachment.mimeType;
1215
+ const delivery = classifyAttachmentDelivery({
1216
+ fileName: attachment.fileName,
1217
+ mimeType: attachmentMimeType,
1218
+ });
1219
+ if (delivery === "reference_only") {
1220
+ return {
1221
+ label: "Reference attachment",
1222
+ insight: "This file is processed as a downloadable reference and is not labeled inline.",
1223
+ };
1224
+ }
1055
1225
  const llmConfig = request.llmConfig
1056
1226
  ? {
1057
1227
  ...request.llmConfig,
@@ -1128,11 +1298,14 @@ export class AiService extends TracedEventEmitter {
1128
1298
  image: attachment.image,
1129
1299
  };
1130
1300
  }
1131
- else if (attachment.type === "pdf") {
1301
+ else if (attachment.type === "pdf" || attachment.type === "archive") {
1132
1302
  // Parse data URL to extract base64 data
1133
1303
  const match = attachment.data.match(/^data:([^;]+);base64,(.+)$/);
1134
1304
  const data = match?.[2] ?? attachment.data;
1135
- const mediaType = match?.[1] ?? "application/pdf";
1305
+ const defaultMediaType = attachment.type === "pdf"
1306
+ ? "application/pdf"
1307
+ : "application/octet-stream";
1308
+ const mediaType = match?.[1] ?? defaultMediaType;
1136
1309
  return {
1137
1310
  type: "file",
1138
1311
  data,
@@ -1140,7 +1313,7 @@ export class AiService extends TracedEventEmitter {
1140
1313
  filename: resolveAttachmentFileName({
1141
1314
  fileName: attachment.fileName,
1142
1315
  mediaType,
1143
- type: "pdf",
1316
+ type: attachment.type,
1144
1317
  }),
1145
1318
  };
1146
1319
  }
@@ -1185,35 +1358,21 @@ export class AiService extends TracedEventEmitter {
1185
1358
  this.getLogger().warn(`[ai-service] Failed to submit feedback to Datadog: ${error}`, JSON.stringify(getErrorMeta(error), null, 2));
1186
1359
  }
1187
1360
  }
1188
- async handleUserAcceptedDraft(peer, silently) {
1361
+ async handleUserAcceptedDraft(silently) {
1189
1362
  this.getLogger().info(`[ai-service] handleUserAcceptedDraft`);
1190
1363
  this.submitAcceptanceEvaluation(true);
1191
1364
  if (this.clark.state !== ClarkStateNames.AwaitingUser) {
1192
1365
  throw new Error("Service is not awaiting user input");
1193
1366
  }
1194
- if (!this.clark.context.peer) {
1195
- // peer can be null if service was started with a draft
1196
- this.getLogger().info(`[ai-service] Setting peer from RPC caller`);
1197
- this.clark.updateContext({
1198
- peer,
1199
- });
1200
- }
1201
1367
  const transitionTo = transitionFrom(this.clark);
1202
1368
  void transitionTo({ type: USER_ACCEPTED_DRAFT, silently });
1203
1369
  }
1204
- async handleUserRejectedDraft(peer, silently) {
1370
+ async handleUserRejectedDraft(silently) {
1205
1371
  this.getLogger().info(`[ai-service] handleUserRejectedDraft`);
1206
1372
  this.submitAcceptanceEvaluation(false);
1207
1373
  if (this.clark.state !== ClarkStateNames.AwaitingUser) {
1208
1374
  throw new Error("Service is not awaiting user input");
1209
1375
  }
1210
- if (!this.clark.context.peer) {
1211
- // peer can be null if service was started with a draft
1212
- this.getLogger().info(`[ai-service] Setting peer from RPC caller`);
1213
- this.clark.updateContext({
1214
- peer,
1215
- });
1216
- }
1217
1376
  const transitionTo = transitionFrom(this.clark);
1218
1377
  void transitionTo({
1219
1378
  type: USER_REJECTED_DRAFT,
@@ -1237,7 +1396,7 @@ export class AiService extends TracedEventEmitter {
1237
1396
  contextManagerV2: this.contextManagerV2,
1238
1397
  applicationId: this.config.applicationId,
1239
1398
  };
1240
- await this.clark.recordSystemMessage(params, "Environment event", "User closed the integration setup form. The integration setup might not have been completed successfully.", { role: "user" });
1399
+ await this.clark.recordSystemMessage(params, "Environment event", "User closed the integration setup form. The integration setup might not have been completed successfully.");
1241
1400
  }
1242
1401
  async handleUserCanceled() {
1243
1402
  if (!this.isBusy()) {
@@ -1255,23 +1414,23 @@ export class AiService extends TracedEventEmitter {
1255
1414
  * Submit a prompt with interrupt behavior.
1256
1415
  * If not busy, starts immediately. Otherwise interrupts and continues.
1257
1416
  */
1258
- async handleAiGenerateWithQueue(request, peer, peerId, mode) {
1259
- this.getLogger().info(`[ai-service] handleAiGenerateWithQueue: peerId=${peerId}, mode=${mode}`);
1417
+ async handleAiGenerateWithQueue(request, mode) {
1418
+ this.getLogger().info(`[ai-service] handleAiGenerateWithQueue: peerId=${this.stablePeer.peerId ?? "unknown"}, mode=${mode}`);
1260
1419
  if (this.clark.state === ClarkStateNames.Dead) {
1261
1420
  throw new Error("Service is unavailable");
1262
1421
  }
1263
1422
  if (!this.isBusy()) {
1264
- await this.handleAiGenerate(request, peer, peerId);
1423
+ await this.handleAiGenerate(request);
1265
1424
  return { status: "started" };
1266
1425
  }
1267
- await this.interruptAndContinue(request, peer, peerId);
1426
+ await this.interruptAndContinue(request);
1268
1427
  return { status: "interrupted" };
1269
1428
  }
1270
1429
  /**
1271
1430
  * Interrupt current generation and continue with new prompt.
1272
1431
  * The partial response is preserved in chat history for context.
1273
1432
  */
1274
- async interruptAndContinue(request, peer, peerId) {
1433
+ async interruptAndContinue(request) {
1275
1434
  await this.ensureAiQuotaAvailable(request.jwt);
1276
1435
  const partialResponse = this.clark.context.partialResponse?.text ?? "";
1277
1436
  const preservedContext = {
@@ -1284,8 +1443,6 @@ export class AiService extends TracedEventEmitter {
1284
1443
  this.clark.context.abortController?.abort();
1285
1444
  await this.waitForAbortComplete();
1286
1445
  this.clark.updateContext({
1287
- peer,
1288
- peerId,
1289
1446
  jwt: preservedContext.jwt,
1290
1447
  llmConfig: preservedContext.llmConfig,
1291
1448
  availableIntegrations: preservedContext.availableIntegrations,
@@ -1296,7 +1453,8 @@ export class AiService extends TracedEventEmitter {
1296
1453
  });
1297
1454
  if (partialResponse.trim().length > 10) {
1298
1455
  await this.chatSessionStore.recordAssistant({
1299
- text: partialResponse,
1456
+ role: "assistant",
1457
+ content: partialResponse,
1300
1458
  type: "text",
1301
1459
  });
1302
1460
  }
@@ -1305,7 +1463,7 @@ export class AiService extends TracedEventEmitter {
1305
1463
  ...request,
1306
1464
  prompt: enhancedPrompt,
1307
1465
  };
1308
- await this.handleAiGenerate(enhancedRequest, peer, peerId);
1466
+ await this.handleAiGenerate(enhancedRequest);
1309
1467
  }
1310
1468
  /**
1311
1469
  * Wait for the FSM to transition out of busy state after abort.
@@ -1390,7 +1548,7 @@ export class AiService extends TracedEventEmitter {
1390
1548
  *
1391
1549
  * If denied, injects a tool error into the context and restarts the LLM.
1392
1550
  */
1393
- async handleAiRespondToToolPermission(request, peer, peerId) {
1551
+ async handleAiRespondToToolPermission(request) {
1394
1552
  const logger = this.getLogger();
1395
1553
  logger.info(`[ai-service] handleAiRespondToToolPermission: messageId=${request.messageId}, approved=${request.approved}`);
1396
1554
  const pendingRequest = this.clark.context.pendingToolPermissionRequest;
@@ -1465,6 +1623,8 @@ export class AiService extends TracedEventEmitter {
1465
1623
  // Use getToolOutput for consistent formatting with processStreamChunk
1466
1624
  const output = getToolOutput(toolName, result.data);
1467
1625
  void sendUserMessage({
1626
+ role: "assistant",
1627
+ content: "",
1468
1628
  type: "tool-result",
1469
1629
  toolCallId,
1470
1630
  toolName,
@@ -1491,6 +1651,8 @@ export class AiService extends TracedEventEmitter {
1491
1651
  // Use getToolErrorCode for consistent formatting with processStreamChunk
1492
1652
  const errorCode = getToolErrorCode(result.error);
1493
1653
  void sendUserMessage({
1654
+ role: "assistant",
1655
+ content: "",
1494
1656
  type: "tool-error",
1495
1657
  toolCallId,
1496
1658
  toolName,
@@ -1520,6 +1682,8 @@ export class AiService extends TracedEventEmitter {
1520
1682
  // Use getToolErrorCode for consistent formatting with processStreamChunk
1521
1683
  const errorCode = getToolErrorCode(error);
1522
1684
  void sendUserMessage({
1685
+ role: "assistant",
1686
+ content: "",
1523
1687
  type: "tool-error",
1524
1688
  toolCallId,
1525
1689
  toolName,
@@ -1628,8 +1792,6 @@ export class AiService extends TracedEventEmitter {
1628
1792
  void transitionTo({
1629
1793
  type: USER_SENT_PROMPT,
1630
1794
  request: continueRequest,
1631
- peer,
1632
- peerId,
1633
1795
  });
1634
1796
  }
1635
1797
  /**
@@ -1655,24 +1817,23 @@ export class AiService extends TracedEventEmitter {
1655
1817
  return `Continue with the task using alternative approaches. The tool ${toolName} was denied permission.`;
1656
1818
  }
1657
1819
  handleUserConnected(peer, peerId) {
1658
- const existingPeerId = this.clark.context.peerId;
1820
+ const existingPeerId = this.stablePeer.peerId;
1659
1821
  this.getLogger().info(`[ai-service] handleUserConnected: peerId=${peerId}`);
1660
- if (this.clark.context.peer) {
1822
+ if (existingPeerId) {
1661
1823
  if (existingPeerId === peerId) {
1662
1824
  this.getLogger().info(`[ai-service] Existing peer ${peerId} reconnected; refreshing reference`);
1663
1825
  }
1664
1826
  else {
1665
- this.getLogger().warn(`[ai-service] Replacing stale peer ${existingPeerId ?? "unknown"} with ${peerId}`);
1827
+ this.getLogger().warn(`[ai-service] Replacing stale peer ${existingPeerId} with ${peerId}`);
1666
1828
  }
1667
1829
  }
1668
1830
  else {
1669
1831
  this.getLogger().info(`[ai-service] peer connecting: ${peerId}`);
1670
1832
  }
1671
- this.clark.updateContext((context) => ({
1672
- ...context,
1673
- peer,
1674
- peerId,
1675
- }));
1833
+ // `clark.context.peer` is a permanent StablePeer proxy; we swap its
1834
+ // inner (and peerId) here. Any queued calls accumulated while
1835
+ // disconnected flush in order as part of setInner.
1836
+ this.stablePeer.setInner({ peer, peerId });
1676
1837
  this.getLogger().info(`[ai-service] Peer set: ${peerId}`);
1677
1838
  // 1. Sync generation state if generation is in progress
1678
1839
  if (this.clark.context.lastGenerationState) {
@@ -1709,7 +1870,7 @@ export class AiService extends TracedEventEmitter {
1709
1870
  }
1710
1871
  }
1711
1872
  handleUserDisconnected(peerId) {
1712
- const currentPeerId = this.clark.context.peerId;
1873
+ const currentPeerId = this.stablePeer.peerId;
1713
1874
  this.getLogger().info(`[ai-service] handleUserDisconnected: peerId=${peerId}`);
1714
1875
  if (!currentPeerId) {
1715
1876
  return;
@@ -1727,11 +1888,10 @@ export class AiService extends TracedEventEmitter {
1727
1888
  }
1728
1889
  clearPeerConnection() {
1729
1890
  this.getLogger().info(`[ai-service] Clearing peer connection`);
1730
- this.clark.updateContext((context) => ({
1731
- ...context,
1732
- peer: undefined,
1733
- peerId: undefined,
1734
- }));
1891
+ // The StablePeer reference on `clark.context.peer` stays — we only mark
1892
+ // the underlying socket as gone. Calls made during the disconnect window
1893
+ // are queued and flushed when the next peer connects.
1894
+ this.stablePeer.setInner({ peer: undefined });
1735
1895
  }
1736
1896
  handleBuildSystemError(error) {
1737
1897
  // Explicitly copy error properties since they're not enumerable
@@ -1892,8 +2052,8 @@ export class AiService extends TracedEventEmitter {
1892
2052
  // Invalidate context errors cache since build system errors changed
1893
2053
  debugCache.invalidateContextErrors();
1894
2054
  }
1895
- async handlePromptInterpretation(request, peer) {
1896
- void peer.call.aiPushPromptInterpretation({
2055
+ async handlePromptInterpretation(request) {
2056
+ void this.clark.context.peer.call.aiPushPromptInterpretation({
1897
2057
  prompt: request.prompt,
1898
2058
  classification: "full_app_gen",
1899
2059
  entities: [], // this is not used yet. It should send any additional inferred entities.