@agent-native/core 0.15.13 → 0.16.0

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 (411) hide show
  1. package/README.md +37 -0
  2. package/dist/agent/app-model-defaults.d.ts +37 -0
  3. package/dist/agent/app-model-defaults.d.ts.map +1 -0
  4. package/dist/agent/app-model-defaults.js +136 -0
  5. package/dist/agent/app-model-defaults.js.map +1 -0
  6. package/dist/agent/engine/registry.d.ts +12 -7
  7. package/dist/agent/engine/registry.d.ts.map +1 -1
  8. package/dist/agent/engine/registry.js +28 -8
  9. package/dist/agent/engine/registry.js.map +1 -1
  10. package/dist/agent/production-agent.d.ts +2 -0
  11. package/dist/agent/production-agent.d.ts.map +1 -1
  12. package/dist/agent/production-agent.js +3 -1
  13. package/dist/agent/production-agent.js.map +1 -1
  14. package/dist/browser-sessions/actions.d.ts +7 -0
  15. package/dist/browser-sessions/actions.d.ts.map +1 -0
  16. package/dist/browser-sessions/actions.js +223 -0
  17. package/dist/browser-sessions/actions.js.map +1 -0
  18. package/dist/browser-sessions/routes.d.ts +7 -0
  19. package/dist/browser-sessions/routes.d.ts.map +1 -0
  20. package/dist/browser-sessions/routes.js +159 -0
  21. package/dist/browser-sessions/routes.js.map +1 -0
  22. package/dist/browser-sessions/store.d.ts +33 -0
  23. package/dist/browser-sessions/store.d.ts.map +1 -0
  24. package/dist/browser-sessions/store.js +506 -0
  25. package/dist/browser-sessions/store.js.map +1 -0
  26. package/dist/browser-sessions/types.d.ts +68 -0
  27. package/dist/browser-sessions/types.d.ts.map +1 -0
  28. package/dist/browser-sessions/types.js +2 -0
  29. package/dist/browser-sessions/types.js.map +1 -0
  30. package/dist/cli/code-agent-commands.d.ts +36 -0
  31. package/dist/cli/code-agent-commands.d.ts.map +1 -0
  32. package/dist/cli/code-agent-commands.js +192 -0
  33. package/dist/cli/code-agent-commands.js.map +1 -0
  34. package/dist/cli/code-agent-connector.d.ts +17 -0
  35. package/dist/cli/code-agent-connector.d.ts.map +1 -0
  36. package/dist/cli/code-agent-connector.js +724 -0
  37. package/dist/cli/code-agent-connector.js.map +1 -0
  38. package/dist/cli/code-agent-executor.d.ts +31 -0
  39. package/dist/cli/code-agent-executor.d.ts.map +1 -0
  40. package/dist/cli/code-agent-executor.js +921 -0
  41. package/dist/cli/code-agent-executor.js.map +1 -0
  42. package/dist/cli/code-agent-runs.d.ts +102 -0
  43. package/dist/cli/code-agent-runs.d.ts.map +1 -0
  44. package/dist/cli/code-agent-runs.js +277 -0
  45. package/dist/cli/code-agent-runs.js.map +1 -0
  46. package/dist/cli/code.d.ts +66 -0
  47. package/dist/cli/code.d.ts.map +1 -0
  48. package/dist/cli/code.js +1306 -0
  49. package/dist/cli/code.js.map +1 -0
  50. package/dist/cli/create.d.ts +2 -1
  51. package/dist/cli/create.d.ts.map +1 -1
  52. package/dist/cli/create.js +11 -1
  53. package/dist/cli/create.js.map +1 -1
  54. package/dist/cli/index.js +26 -1
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/cli/migrate.d.ts +27 -0
  57. package/dist/cli/migrate.d.ts.map +1 -1
  58. package/dist/cli/migrate.js +1328 -20
  59. package/dist/cli/migrate.js.map +1 -1
  60. package/dist/cli/templates-meta.d.ts.map +1 -1
  61. package/dist/cli/templates-meta.js +26 -2
  62. package/dist/cli/templates-meta.js.map +1 -1
  63. package/dist/cli/workspacify.d.ts +2 -0
  64. package/dist/cli/workspacify.d.ts.map +1 -1
  65. package/dist/cli/workspacify.js +2 -1
  66. package/dist/cli/workspacify.js.map +1 -1
  67. package/dist/client/AgentNative.d.ts +32 -0
  68. package/dist/client/AgentNative.d.ts.map +1 -0
  69. package/dist/client/AgentNative.js +79 -0
  70. package/dist/client/AgentNative.js.map +1 -0
  71. package/dist/client/AgentNativeEmbedded.d.ts +47 -0
  72. package/dist/client/AgentNativeEmbedded.d.ts.map +1 -0
  73. package/dist/client/AgentNativeEmbedded.js +148 -0
  74. package/dist/client/AgentNativeEmbedded.js.map +1 -0
  75. package/dist/client/AgentNativeFrame.d.ts +25 -0
  76. package/dist/client/AgentNativeFrame.d.ts.map +1 -0
  77. package/dist/client/AgentNativeFrame.js +68 -0
  78. package/dist/client/AgentNativeFrame.js.map +1 -0
  79. package/dist/client/AgentPanel.d.ts +19 -2
  80. package/dist/client/AgentPanel.d.ts.map +1 -1
  81. package/dist/client/AgentPanel.js +15 -4
  82. package/dist/client/AgentPanel.js.map +1 -1
  83. package/dist/client/AssistantChat.d.ts +1 -1
  84. package/dist/client/AssistantChat.d.ts.map +1 -1
  85. package/dist/client/AssistantChat.js +79 -48
  86. package/dist/client/AssistantChat.js.map +1 -1
  87. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  88. package/dist/client/MultiTabAssistantChat.js +2 -1
  89. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  90. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  91. package/dist/client/NewWorkspaceAppFlow.js +3 -2
  92. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  93. package/dist/client/browser-session-bridge.d.ts +44 -0
  94. package/dist/client/browser-session-bridge.d.ts.map +1 -0
  95. package/dist/client/browser-session-bridge.js +339 -0
  96. package/dist/client/browser-session-bridge.js.map +1 -0
  97. package/dist/client/client-action.d.ts +7 -0
  98. package/dist/client/client-action.d.ts.map +1 -0
  99. package/dist/client/client-action.js +4 -0
  100. package/dist/client/client-action.js.map +1 -0
  101. package/dist/client/components/ui/tooltip.d.ts.map +1 -1
  102. package/dist/client/components/ui/tooltip.js +1 -1
  103. package/dist/client/components/ui/tooltip.js.map +1 -1
  104. package/dist/client/composer/AgentComposerFrame.d.ts +17 -0
  105. package/dist/client/composer/AgentComposerFrame.d.ts.map +1 -0
  106. package/dist/client/composer/AgentComposerFrame.js +14 -0
  107. package/dist/client/composer/AgentComposerFrame.js.map +1 -0
  108. package/dist/client/composer/MentionPopover.d.ts.map +1 -1
  109. package/dist/client/composer/MentionPopover.js +2 -2
  110. package/dist/client/composer/MentionPopover.js.map +1 -1
  111. package/dist/client/composer/PromptComposer.d.ts +35 -2
  112. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  113. package/dist/client/composer/PromptComposer.js +31 -17
  114. package/dist/client/composer/PromptComposer.js.map +1 -1
  115. package/dist/client/composer/TiptapComposer.d.ts +20 -2
  116. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  117. package/dist/client/composer/TiptapComposer.js +112 -22
  118. package/dist/client/composer/TiptapComposer.js.map +1 -1
  119. package/dist/client/composer/index.d.ts +3 -2
  120. package/dist/client/composer/index.d.ts.map +1 -1
  121. package/dist/client/composer/index.js +1 -0
  122. package/dist/client/composer/index.js.map +1 -1
  123. package/dist/client/composer/types.d.ts +1 -0
  124. package/dist/client/composer/types.d.ts.map +1 -1
  125. package/dist/client/composer/types.js.map +1 -1
  126. package/dist/client/extensions/AgentNativeExtensionFrame.d.ts +58 -0
  127. package/dist/client/extensions/AgentNativeExtensionFrame.d.ts.map +1 -0
  128. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts +2 -0
  129. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts.map +1 -0
  130. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js +110 -0
  131. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js.map +1 -0
  132. package/dist/client/extensions/AgentNativeExtensionFrame.js +354 -0
  133. package/dist/client/extensions/AgentNativeExtensionFrame.js.map +1 -0
  134. package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts +2 -0
  135. package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts.map +1 -0
  136. package/dist/client/extensions/AgentNativeExtensionFrame.spec.js +68 -0
  137. package/dist/client/extensions/AgentNativeExtensionFrame.spec.js.map +1 -0
  138. package/dist/client/extensions/agent-native-extension-runtime.d.ts +69 -0
  139. package/dist/client/extensions/agent-native-extension-runtime.d.ts.map +1 -0
  140. package/dist/client/extensions/agent-native-extension-runtime.js +348 -0
  141. package/dist/client/extensions/agent-native-extension-runtime.js.map +1 -0
  142. package/dist/client/extensions/index.d.ts +2 -0
  143. package/dist/client/extensions/index.d.ts.map +1 -1
  144. package/dist/client/extensions/index.js +2 -0
  145. package/dist/client/extensions/index.js.map +1 -1
  146. package/dist/client/extensions/portable-extension.d.ts +86 -0
  147. package/dist/client/extensions/portable-extension.d.ts.map +1 -0
  148. package/dist/client/extensions/portable-extension.js +480 -0
  149. package/dist/client/extensions/portable-extension.js.map +1 -0
  150. package/dist/client/host-bridge.d.ts +266 -0
  151. package/dist/client/host-bridge.d.ts.map +1 -0
  152. package/dist/client/host-bridge.js +745 -0
  153. package/dist/client/host-bridge.js.map +1 -0
  154. package/dist/client/host-tools.d.ts +40 -0
  155. package/dist/client/host-tools.d.ts.map +1 -0
  156. package/dist/client/host-tools.js +94 -0
  157. package/dist/client/host-tools.js.map +1 -0
  158. package/dist/client/index.d.ts +13 -2
  159. package/dist/client/index.d.ts.map +1 -1
  160. package/dist/client/index.js +11 -2
  161. package/dist/client/index.js.map +1 -1
  162. package/dist/client/resources/BuiltinCapabilityDetail.d.ts +10 -0
  163. package/dist/client/resources/BuiltinCapabilityDetail.d.ts.map +1 -0
  164. package/dist/client/resources/BuiltinCapabilityDetail.js +51 -0
  165. package/dist/client/resources/BuiltinCapabilityDetail.js.map +1 -0
  166. package/dist/client/resources/ResourceEditor.d.ts +3 -1
  167. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  168. package/dist/client/resources/ResourceEditor.js +40 -17
  169. package/dist/client/resources/ResourceEditor.js.map +1 -1
  170. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  171. package/dist/client/resources/ResourceTree.js +23 -2
  172. package/dist/client/resources/ResourceTree.js.map +1 -1
  173. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  174. package/dist/client/resources/ResourcesPanel.js +77 -17
  175. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  176. package/dist/client/resources/index.d.ts +1 -0
  177. package/dist/client/resources/index.d.ts.map +1 -1
  178. package/dist/client/resources/index.js +1 -0
  179. package/dist/client/resources/index.js.map +1 -1
  180. package/dist/client/resources/use-builtin-capabilities.d.ts +62 -0
  181. package/dist/client/resources/use-builtin-capabilities.d.ts.map +1 -0
  182. package/dist/client/resources/use-builtin-capabilities.js +54 -0
  183. package/dist/client/resources/use-builtin-capabilities.js.map +1 -0
  184. package/dist/client/resources/use-resources.d.ts +30 -2
  185. package/dist/client/resources/use-resources.d.ts.map +1 -1
  186. package/dist/client/resources/use-resources.js +42 -1
  187. package/dist/client/resources/use-resources.js.map +1 -1
  188. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  189. package/dist/client/settings/SettingsPanel.js +151 -2
  190. package/dist/client/settings/SettingsPanel.js.map +1 -1
  191. package/dist/client/use-chat-models.d.ts.map +1 -1
  192. package/dist/client/use-chat-models.js +20 -0
  193. package/dist/client/use-chat-models.js.map +1 -1
  194. package/dist/client/use-chat-threads.d.ts.map +1 -1
  195. package/dist/client/use-chat-threads.js +46 -2
  196. package/dist/client/use-chat-threads.js.map +1 -1
  197. package/dist/client/use-chat-threads.spec.js +77 -0
  198. package/dist/client/use-chat-threads.spec.js.map +1 -1
  199. package/dist/code-agents/index.d.ts +4 -0
  200. package/dist/code-agents/index.d.ts.map +1 -0
  201. package/dist/code-agents/index.js +4 -0
  202. package/dist/code-agents/index.js.map +1 -0
  203. package/dist/connections/catalog.d.ts +134 -0
  204. package/dist/connections/catalog.d.ts.map +1 -0
  205. package/dist/connections/catalog.js +180 -0
  206. package/dist/connections/catalog.js.map +1 -0
  207. package/dist/connections/index.d.ts +2 -0
  208. package/dist/connections/index.d.ts.map +1 -0
  209. package/dist/connections/index.js +2 -0
  210. package/dist/connections/index.js.map +1 -0
  211. package/dist/extensions/change-marker.d.ts +10 -0
  212. package/dist/extensions/change-marker.d.ts.map +1 -0
  213. package/dist/extensions/change-marker.js +42 -0
  214. package/dist/extensions/change-marker.js.map +1 -0
  215. package/dist/extensions/routes.d.ts.map +1 -1
  216. package/dist/extensions/routes.js +1 -7
  217. package/dist/extensions/routes.js.map +1 -1
  218. package/dist/extensions/schema.d.ts +1 -0
  219. package/dist/extensions/schema.d.ts.map +1 -1
  220. package/dist/extensions/schema.js +1 -0
  221. package/dist/extensions/schema.js.map +1 -1
  222. package/dist/extensions/slots/routes.js +1 -1
  223. package/dist/extensions/slots/routes.js.map +1 -1
  224. package/dist/extensions/store.d.ts +3 -0
  225. package/dist/extensions/store.d.ts.map +1 -1
  226. package/dist/extensions/store.js +112 -4
  227. package/dist/extensions/store.js.map +1 -1
  228. package/dist/index.d.ts +4 -1
  229. package/dist/index.d.ts.map +1 -1
  230. package/dist/index.js +6 -1
  231. package/dist/index.js.map +1 -1
  232. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  233. package/dist/integrations/adapters/telegram.js +1 -0
  234. package/dist/integrations/adapters/telegram.js.map +1 -1
  235. package/dist/integrations/index.d.ts +5 -1
  236. package/dist/integrations/index.d.ts.map +1 -1
  237. package/dist/integrations/index.js +4 -1
  238. package/dist/integrations/index.js.map +1 -1
  239. package/dist/integrations/plugin.d.ts +8 -0
  240. package/dist/integrations/plugin.d.ts.map +1 -1
  241. package/dist/integrations/plugin.js +760 -32
  242. package/dist/integrations/plugin.js.map +1 -1
  243. package/dist/integrations/remote-commands-store.d.ts +36 -0
  244. package/dist/integrations/remote-commands-store.d.ts.map +1 -0
  245. package/dist/integrations/remote-commands-store.js +273 -0
  246. package/dist/integrations/remote-commands-store.js.map +1 -0
  247. package/dist/integrations/remote-devices-store.d.ts +43 -0
  248. package/dist/integrations/remote-devices-store.d.ts.map +1 -0
  249. package/dist/integrations/remote-devices-store.js +315 -0
  250. package/dist/integrations/remote-devices-store.js.map +1 -0
  251. package/dist/integrations/remote-push-store.d.ts +37 -0
  252. package/dist/integrations/remote-push-store.d.ts.map +1 -0
  253. package/dist/integrations/remote-push-store.js +299 -0
  254. package/dist/integrations/remote-push-store.js.map +1 -0
  255. package/dist/integrations/remote-retry-job.d.ts +7 -0
  256. package/dist/integrations/remote-retry-job.d.ts.map +1 -0
  257. package/dist/integrations/remote-retry-job.js +45 -0
  258. package/dist/integrations/remote-retry-job.js.map +1 -0
  259. package/dist/integrations/remote-run-events-store.d.ts +18 -0
  260. package/dist/integrations/remote-run-events-store.d.ts.map +1 -0
  261. package/dist/integrations/remote-run-events-store.js +82 -0
  262. package/dist/integrations/remote-run-events-store.js.map +1 -0
  263. package/dist/integrations/remote-types.d.ts +101 -0
  264. package/dist/integrations/remote-types.d.ts.map +1 -0
  265. package/dist/integrations/remote-types.js +2 -0
  266. package/dist/integrations/remote-types.js.map +1 -0
  267. package/dist/integrations/webhook-handler.d.ts +2 -0
  268. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  269. package/dist/integrations/webhook-handler.js +4 -1
  270. package/dist/integrations/webhook-handler.js.map +1 -1
  271. package/dist/jobs/scheduler.d.ts +4 -2
  272. package/dist/jobs/scheduler.d.ts.map +1 -1
  273. package/dist/jobs/scheduler.js +9 -3
  274. package/dist/jobs/scheduler.js.map +1 -1
  275. package/dist/mcp-client/builtin-capabilities.d.ts +20 -0
  276. package/dist/mcp-client/builtin-capabilities.d.ts.map +1 -0
  277. package/dist/mcp-client/builtin-capabilities.js +75 -0
  278. package/dist/mcp-client/builtin-capabilities.js.map +1 -0
  279. package/dist/mcp-client/builtin-store.d.ts +10 -0
  280. package/dist/mcp-client/builtin-store.d.ts.map +1 -0
  281. package/dist/mcp-client/builtin-store.js +55 -0
  282. package/dist/mcp-client/builtin-store.js.map +1 -0
  283. package/dist/mcp-client/index.d.ts +3 -1
  284. package/dist/mcp-client/index.d.ts.map +1 -1
  285. package/dist/mcp-client/index.js +3 -1
  286. package/dist/mcp-client/index.js.map +1 -1
  287. package/dist/mcp-client/routes.d.ts +28 -0
  288. package/dist/mcp-client/routes.d.ts.map +1 -1
  289. package/dist/mcp-client/routes.js +195 -1
  290. package/dist/mcp-client/routes.js.map +1 -1
  291. package/dist/org/context.d.ts.map +1 -1
  292. package/dist/org/context.js +34 -0
  293. package/dist/org/context.js.map +1 -1
  294. package/dist/resources/handlers.d.ts +4 -0
  295. package/dist/resources/handlers.d.ts.map +1 -1
  296. package/dist/resources/handlers.js +46 -7
  297. package/dist/resources/handlers.js.map +1 -1
  298. package/dist/resources/script-helpers.d.ts +8 -1
  299. package/dist/resources/script-helpers.d.ts.map +1 -1
  300. package/dist/resources/script-helpers.js +18 -8
  301. package/dist/resources/script-helpers.js.map +1 -1
  302. package/dist/resources/store.d.ts +19 -0
  303. package/dist/resources/store.d.ts.map +1 -1
  304. package/dist/resources/store.js +86 -3
  305. package/dist/resources/store.js.map +1 -1
  306. package/dist/scripts/agent-engines/list-agent-engines.d.ts +1 -1
  307. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  308. package/dist/scripts/agent-engines/list-agent-engines.js +18 -7
  309. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  310. package/dist/scripts/agent-engines/manage-agent-engine.d.ts.map +1 -1
  311. package/dist/scripts/agent-engines/manage-agent-engine.js +100 -7
  312. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  313. package/dist/scripts/resources/delete.d.ts.map +1 -1
  314. package/dist/scripts/resources/delete.js +4 -1
  315. package/dist/scripts/resources/delete.js.map +1 -1
  316. package/dist/scripts/resources/effective.d.ts +11 -0
  317. package/dist/scripts/resources/effective.d.ts.map +1 -0
  318. package/dist/scripts/resources/effective.js +54 -0
  319. package/dist/scripts/resources/effective.js.map +1 -0
  320. package/dist/scripts/resources/index.d.ts.map +1 -1
  321. package/dist/scripts/resources/index.js +1 -0
  322. package/dist/scripts/resources/index.js.map +1 -1
  323. package/dist/scripts/resources/list.d.ts +1 -1
  324. package/dist/scripts/resources/list.d.ts.map +1 -1
  325. package/dist/scripts/resources/list.js +17 -5
  326. package/dist/scripts/resources/list.js.map +1 -1
  327. package/dist/scripts/resources/read.d.ts +1 -1
  328. package/dist/scripts/resources/read.d.ts.map +1 -1
  329. package/dist/scripts/resources/read.js +20 -5
  330. package/dist/scripts/resources/read.js.map +1 -1
  331. package/dist/scripts/resources/write.d.ts.map +1 -1
  332. package/dist/scripts/resources/write.js +4 -1
  333. package/dist/scripts/resources/write.js.map +1 -1
  334. package/dist/scripts/runner.d.ts +11 -1
  335. package/dist/scripts/runner.d.ts.map +1 -1
  336. package/dist/scripts/runner.js +75 -27
  337. package/dist/scripts/runner.js.map +1 -1
  338. package/dist/server/action-discovery.d.ts.map +1 -1
  339. package/dist/server/action-discovery.js +5 -0
  340. package/dist/server/action-discovery.js.map +1 -1
  341. package/dist/server/agent-chat-plugin.d.ts +24 -0
  342. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  343. package/dist/server/agent-chat-plugin.js +608 -54
  344. package/dist/server/agent-chat-plugin.js.map +1 -1
  345. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  346. package/dist/server/core-routes-plugin.js +2 -0
  347. package/dist/server/core-routes-plugin.js.map +1 -1
  348. package/dist/server/embedded.d.ts +72 -0
  349. package/dist/server/embedded.d.ts.map +1 -0
  350. package/dist/server/embedded.js +119 -0
  351. package/dist/server/embedded.js.map +1 -0
  352. package/dist/server/index.d.ts +8 -1
  353. package/dist/server/index.d.ts.map +1 -1
  354. package/dist/server/index.js +7 -1
  355. package/dist/server/index.js.map +1 -1
  356. package/dist/server/poll.d.ts.map +1 -1
  357. package/dist/server/poll.js +184 -13
  358. package/dist/server/poll.js.map +1 -1
  359. package/dist/server/resources-plugin.d.ts.map +1 -1
  360. package/dist/server/resources-plugin.js +11 -2
  361. package/dist/server/resources-plugin.js.map +1 -1
  362. package/dist/sharing/actions/extension-change.d.ts +4 -0
  363. package/dist/sharing/actions/extension-change.d.ts.map +1 -0
  364. package/dist/sharing/actions/extension-change.js +13 -0
  365. package/dist/sharing/actions/extension-change.js.map +1 -0
  366. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  367. package/dist/sharing/actions/set-resource-visibility.js +3 -0
  368. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  369. package/dist/sharing/actions/share-resource.d.ts.map +1 -1
  370. package/dist/sharing/actions/share-resource.js +4 -0
  371. package/dist/sharing/actions/share-resource.js.map +1 -1
  372. package/dist/sharing/actions/unshare-resource.d.ts.map +1 -1
  373. package/dist/sharing/actions/unshare-resource.js +3 -0
  374. package/dist/sharing/actions/unshare-resource.js.map +1 -1
  375. package/dist/templates/default/AGENTS.md +3 -3
  376. package/dist/templates/workspace-core/AGENTS.md +7 -0
  377. package/dist/templates/workspace-root/AGENTS.md +7 -0
  378. package/dist/templates/workspace-root/README.md +25 -0
  379. package/dist/triggers/dispatcher.d.ts +3 -1
  380. package/dist/triggers/dispatcher.d.ts.map +1 -1
  381. package/dist/triggers/dispatcher.js +9 -3
  382. package/dist/triggers/dispatcher.js.map +1 -1
  383. package/dist/workspace-connections/index.d.ts +2 -0
  384. package/dist/workspace-connections/index.d.ts.map +1 -0
  385. package/dist/workspace-connections/index.js +2 -0
  386. package/dist/workspace-connections/index.js.map +1 -0
  387. package/dist/workspace-connections/store.d.ts +229 -0
  388. package/dist/workspace-connections/store.d.ts.map +1 -0
  389. package/dist/workspace-connections/store.js +938 -0
  390. package/dist/workspace-connections/store.js.map +1 -0
  391. package/docs/content/agent-teams.md +6 -0
  392. package/docs/content/cloneable-saas.md +1 -0
  393. package/docs/content/code-agents-ui.md +261 -0
  394. package/docs/content/dispatch.md +40 -3
  395. package/docs/content/embedding-sdk.md +459 -0
  396. package/docs/content/faq.md +1 -0
  397. package/docs/content/getting-started.md +1 -0
  398. package/docs/content/mcp-clients.md +41 -3
  399. package/docs/content/migration-workbench.md +237 -54
  400. package/docs/content/multi-app-workspace.md +41 -0
  401. package/docs/content/multi-tenancy.md +1 -1
  402. package/docs/content/template-brain.md +418 -0
  403. package/docs/content/template-dispatch.md +30 -0
  404. package/docs/content/workspace-connections.md +509 -0
  405. package/docs/content/workspace-management.md +12 -12
  406. package/docs/content/workspace.md +180 -40
  407. package/package.json +7 -2
  408. package/src/templates/default/AGENTS.md +3 -3
  409. package/src/templates/workspace-core/AGENTS.md +7 -0
  410. package/src/templates/workspace-root/AGENTS.md +7 -0
  411. package/src/templates/workspace-root/README.md +25 -0
@@ -1 +1 @@
1
- {"version":3,"file":"use-chat-models.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-models.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,gBAAgB,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,eAAe,CAAC;IAChC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,UAAU,OAAO;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AA2BD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,UAAgC,GACjC,GAAE,OAAY,GAAG,mBAAmB,CA8OpC"}
1
+ {"version":3,"file":"use-chat-models.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-models.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,gBAAgB,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,eAAe,CAAC;IAChC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,UAAU,OAAO;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AA2BD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,UAAgC,GACjC,GAAE,OAAY,GAAG,mBAAmB,CAsQpC"}
@@ -32,6 +32,7 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, } = {}) {
32
32
  const [availableModels, setAvailableModels] = useState([]);
33
33
  const [defaultModel, setDefaultModel] = useState(DEFAULT_MODEL);
34
34
  const initialPersisted = readPersisted(storageKey);
35
+ const hasExplicitSelectionRef = useRef(Boolean(initialPersisted.model));
35
36
  const [selectedModel, setSelectedModel] = useState(initialPersisted.model ?? DEFAULT_MODEL);
36
37
  const [selectedEngine, setSelectedEngine] = useState(initialPersisted.engine ?? "");
37
38
  const [selectedEffort, setSelectedEffort] = useState(initialPersisted.effort ?? "auto");
@@ -48,6 +49,7 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, } = {}) {
48
49
  };
49
50
  }, [selectedEffort, selectedEngine, selectedModel]);
50
51
  const onModelChange = useCallback((model, engine) => {
52
+ hasExplicitSelectionRef.current = true;
51
53
  const effortOptions = getReasoningEffortOptionsForModel(model);
52
54
  setSelectedModel(model);
53
55
  setSelectedEngine(engine);
@@ -60,6 +62,7 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, } = {}) {
60
62
  });
61
63
  }, [storageKey]);
62
64
  const onEffortChange = useCallback((effort) => {
65
+ hasExplicitSelectionRef.current = true;
63
66
  setSelectedEffort(effort);
64
67
  writePersisted(storageKey, {
65
68
  model: selectedModel,
@@ -177,6 +180,23 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, } = {}) {
177
180
  setAvailableModels(groups);
178
181
  setDefaultModel(nextDefaultModel);
179
182
  const selection = selectionRef.current;
183
+ if (!hasExplicitSelectionRef.current) {
184
+ const defaultGroup = groups.find((group) => group.models.includes(nextDefaultModel)) ??
185
+ groups[0];
186
+ const nextModel = defaultGroup?.models.find((model) => model === nextDefaultModel) ??
187
+ defaultGroup?.models[0] ??
188
+ nextDefaultModel;
189
+ const nextEngine = defaultGroup?.engine ?? "";
190
+ const effortOptions = getReasoningEffortOptionsForModel(nextModel);
191
+ const nextEffort = selection.selectedEffort === "auto" ||
192
+ effortOptions.includes(selection.selectedEffort)
193
+ ? selection.selectedEffort
194
+ : "auto";
195
+ setSelectedModel(nextModel);
196
+ setSelectedEngine(nextEngine);
197
+ setSelectedEffort(nextEffort);
198
+ return;
199
+ }
180
200
  const selectedGroup = groups.find((group) => group.models.includes(selection.selectedModel) &&
181
201
  (!selection.selectedEngine ||
182
202
  group.engine === selection.selectedEngine));
@@ -1 +1 @@
1
- {"version":3,"file":"use-chat-models.js","sourceRoot":"","sources":["../../src/client/use-chat-models.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { agentNativePath } from \"./api-path.js\";\nimport { DEFAULT_MODEL } from \"../agent/default-model.js\";\nimport {\n getReasoningEffortOptionsForModel,\n type ReasoningEffort,\n} from \"../shared/reasoning-effort.js\";\n\nexport interface EngineModelGroup {\n engine: string;\n label: string;\n models: string[];\n configured: boolean;\n}\n\nexport interface UseChatModelsResult {\n availableModels: EngineModelGroup[];\n defaultModel: string;\n selectedModel: string;\n selectedEngine: string;\n selectedEffort: ReasoningEffort;\n onModelChange: (model: string, engine: string) => void;\n onEffortChange: (effort: ReasoningEffort) => void;\n refreshEngines: () => void;\n}\n\ninterface Options {\n /**\n * localStorage key used to persist the user's model + effort selection across\n * page loads. Pass `null` to disable persistence.\n */\n storageKey?: string | null;\n}\n\nconst DEFAULT_STORAGE_KEY = \"agent-native:chat-models:selection\";\n\ninterface PersistedSelection {\n model?: string;\n engine?: string;\n effort?: ReasoningEffort;\n}\n\nfunction readPersisted(key: string | null): PersistedSelection {\n if (!key || typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as PersistedSelection) : {};\n } catch {\n return {};\n }\n}\n\nfunction writePersisted(key: string | null, value: PersistedSelection) {\n if (!key || typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {}\n}\n\n/**\n * Fetches available engines/models from the agent server and exposes the same\n * model picker state that `MultiTabAssistantChat` wires up — for surfaces like\n * the Dispatch homepage hero composer that need an identical model picker\n * without mounting the full tabbed chat.\n */\nexport function useChatModels({\n storageKey = DEFAULT_STORAGE_KEY,\n}: Options = {}): UseChatModelsResult {\n const [availableModels, setAvailableModels] = useState<EngineModelGroup[]>(\n [],\n );\n const [defaultModel, setDefaultModel] = useState<string>(DEFAULT_MODEL);\n\n const initialPersisted = readPersisted(storageKey);\n const [selectedModel, setSelectedModel] = useState<string>(\n initialPersisted.model ?? DEFAULT_MODEL,\n );\n const [selectedEngine, setSelectedEngine] = useState<string>(\n initialPersisted.engine ?? \"\",\n );\n const [selectedEffort, setSelectedEffort] = useState<ReasoningEffort>(\n initialPersisted.effort ?? \"auto\",\n );\n const selectionRef = useRef({\n selectedModel,\n selectedEngine,\n selectedEffort,\n });\n\n useEffect(() => {\n selectionRef.current = {\n selectedModel,\n selectedEngine,\n selectedEffort,\n };\n }, [selectedEffort, selectedEngine, selectedModel]);\n\n const onModelChange = useCallback(\n (model: string, engine: string) => {\n const effortOptions = getReasoningEffortOptionsForModel(model);\n setSelectedModel(model);\n setSelectedEngine(engine);\n setSelectedEffort((prevEffort) => {\n const next =\n prevEffort === \"auto\" || effortOptions.includes(prevEffort)\n ? prevEffort\n : \"auto\";\n writePersisted(storageKey, { model, engine, effort: next });\n return next;\n });\n },\n [storageKey],\n );\n\n const onEffortChange = useCallback(\n (effort: ReasoningEffort) => {\n setSelectedEffort(effort);\n writePersisted(storageKey, {\n model: selectedModel,\n engine: selectedEngine,\n effort,\n });\n },\n [selectedEngine, selectedModel, storageKey],\n );\n\n const refreshEngines = useCallback(() => {\n Promise.all([\n fetch(agentNativePath(\"/_agent-native/actions/manage-agent-engine\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ action: \"list\" }),\n }).then((r) => (r.ok ? r.json() : null)),\n fetch(agentNativePath(\"/_agent-native/env-status\"))\n .then((r) => (r.ok ? r.json() : []))\n .catch(() => []),\n fetch(agentNativePath(\"/_agent-native/builder/status\"))\n .then((r) => (r.ok ? r.json() : null))\n .catch(() => null),\n ])\n .then(([enginesData, envKeys, builderStatus]) => {\n if (!enginesData?.engines) return;\n const configuredKeys = new Set(\n (envKeys as Array<{ key: string; configured: boolean }>)\n .filter((k) => k.configured)\n .map((k) => k.key),\n );\n const builderConnected = builderStatus?.configured === true;\n const currentEngineName: string | undefined =\n enginesData.current?.engine;\n const currentModel: string | undefined = enginesData.current?.model;\n\n let groups: EngineModelGroup[];\n\n if (builderConnected) {\n const builderEngine = enginesData.engines.find(\n (e: any) => e.name === \"builder\",\n );\n const builderModels: string[] = builderEngine?.supportedModels ?? [];\n const claude = builderModels.filter((m: string) =>\n m.startsWith(\"claude-\"),\n );\n const openai = builderModels.filter((m: string) =>\n m.startsWith(\"gpt-\"),\n );\n const gemini = builderModels.filter((m: string) =>\n m.startsWith(\"gemini-\"),\n );\n const other = builderModels.filter(\n (m: string) =>\n !m.startsWith(\"claude-\") &&\n !m.startsWith(\"gpt-\") &&\n !m.startsWith(\"gemini-\"),\n );\n\n groups = [\n ...(claude.length\n ? [\n {\n engine: \"builder\",\n label: \"Claude\",\n models: claude,\n configured: true,\n },\n ]\n : []),\n ...(openai.length\n ? [\n {\n engine: \"builder\",\n label: \"OpenAI\",\n models: openai,\n configured: true,\n },\n ]\n : []),\n ...(gemini.length\n ? [\n {\n engine: \"builder\",\n label: \"Gemini\",\n models: gemini,\n configured: true,\n },\n ]\n : []),\n ...(other.length\n ? [\n {\n engine: \"builder\",\n label: \"More\",\n models: other,\n configured: true,\n },\n ]\n : []),\n ];\n\n if (currentModel && !builderModels.includes(currentModel)) {\n const firstGroup = groups[0];\n if (firstGroup) firstGroup.models.unshift(currentModel);\n }\n } else {\n const allowedEngines = new Set([\n \"anthropic\",\n \"ai-sdk:openai\",\n \"ai-sdk:google\",\n ]);\n groups = enginesData.engines\n .filter((e: any) => allowedEngines.has(e.name))\n .map((e: any) => {\n const models = [...e.supportedModels];\n if (\n e.name === currentEngineName &&\n currentModel &&\n !models.includes(currentModel)\n ) {\n models.unshift(currentModel);\n }\n return {\n engine: e.name,\n label: e.label,\n models,\n configured:\n e.requiredEnvVars.length === 0 ||\n e.requiredEnvVars.some((v: string) =>\n configuredKeys.has(v),\n ) ||\n e.name === currentEngineName,\n };\n });\n }\n const nextDefaultModel = currentModel ?? DEFAULT_MODEL;\n setAvailableModels(groups);\n setDefaultModel(nextDefaultModel);\n\n const selection = selectionRef.current;\n const selectedGroup = groups.find(\n (group) =>\n group.models.includes(selection.selectedModel) &&\n (!selection.selectedEngine ||\n group.engine === selection.selectedEngine),\n );\n if (!selectedGroup) {\n const defaultGroup =\n groups.find((group) => group.models.includes(nextDefaultModel)) ??\n groups[0];\n const nextModel =\n defaultGroup?.models.find((model) => model === nextDefaultModel) ??\n defaultGroup?.models[0] ??\n nextDefaultModel;\n const nextEngine = defaultGroup?.engine ?? \"\";\n const effortOptions = getReasoningEffortOptionsForModel(nextModel);\n const nextEffort =\n selection.selectedEffort === \"auto\" ||\n effortOptions.includes(selection.selectedEffort)\n ? selection.selectedEffort\n : \"auto\";\n setSelectedModel(nextModel);\n setSelectedEngine(nextEngine);\n setSelectedEffort(nextEffort);\n writePersisted(storageKey, {\n model: nextModel,\n engine: nextEngine,\n effort: nextEffort,\n });\n }\n })\n .catch(() => {});\n }, [storageKey]);\n\n useEffect(() => {\n refreshEngines();\n }, [refreshEngines]);\n\n return {\n availableModels,\n defaultModel,\n selectedModel,\n selectedEngine,\n selectedEffort,\n onModelChange,\n onEffortChange,\n refreshEngines,\n };\n}\n"]}
1
+ {"version":3,"file":"use-chat-models.js","sourceRoot":"","sources":["../../src/client/use-chat-models.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { agentNativePath } from \"./api-path.js\";\nimport { DEFAULT_MODEL } from \"../agent/default-model.js\";\nimport {\n getReasoningEffortOptionsForModel,\n type ReasoningEffort,\n} from \"../shared/reasoning-effort.js\";\n\nexport interface EngineModelGroup {\n engine: string;\n label: string;\n models: string[];\n configured: boolean;\n}\n\nexport interface UseChatModelsResult {\n availableModels: EngineModelGroup[];\n defaultModel: string;\n selectedModel: string;\n selectedEngine: string;\n selectedEffort: ReasoningEffort;\n onModelChange: (model: string, engine: string) => void;\n onEffortChange: (effort: ReasoningEffort) => void;\n refreshEngines: () => void;\n}\n\ninterface Options {\n /**\n * localStorage key used to persist the user's model + effort selection across\n * page loads. Pass `null` to disable persistence.\n */\n storageKey?: string | null;\n}\n\nconst DEFAULT_STORAGE_KEY = \"agent-native:chat-models:selection\";\n\ninterface PersistedSelection {\n model?: string;\n engine?: string;\n effort?: ReasoningEffort;\n}\n\nfunction readPersisted(key: string | null): PersistedSelection {\n if (!key || typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as PersistedSelection) : {};\n } catch {\n return {};\n }\n}\n\nfunction writePersisted(key: string | null, value: PersistedSelection) {\n if (!key || typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {}\n}\n\n/**\n * Fetches available engines/models from the agent server and exposes the same\n * model picker state that `MultiTabAssistantChat` wires up — for surfaces like\n * the Dispatch homepage hero composer that need an identical model picker\n * without mounting the full tabbed chat.\n */\nexport function useChatModels({\n storageKey = DEFAULT_STORAGE_KEY,\n}: Options = {}): UseChatModelsResult {\n const [availableModels, setAvailableModels] = useState<EngineModelGroup[]>(\n [],\n );\n const [defaultModel, setDefaultModel] = useState<string>(DEFAULT_MODEL);\n\n const initialPersisted = readPersisted(storageKey);\n const hasExplicitSelectionRef = useRef(Boolean(initialPersisted.model));\n const [selectedModel, setSelectedModel] = useState<string>(\n initialPersisted.model ?? DEFAULT_MODEL,\n );\n const [selectedEngine, setSelectedEngine] = useState<string>(\n initialPersisted.engine ?? \"\",\n );\n const [selectedEffort, setSelectedEffort] = useState<ReasoningEffort>(\n initialPersisted.effort ?? \"auto\",\n );\n const selectionRef = useRef({\n selectedModel,\n selectedEngine,\n selectedEffort,\n });\n\n useEffect(() => {\n selectionRef.current = {\n selectedModel,\n selectedEngine,\n selectedEffort,\n };\n }, [selectedEffort, selectedEngine, selectedModel]);\n\n const onModelChange = useCallback(\n (model: string, engine: string) => {\n hasExplicitSelectionRef.current = true;\n const effortOptions = getReasoningEffortOptionsForModel(model);\n setSelectedModel(model);\n setSelectedEngine(engine);\n setSelectedEffort((prevEffort) => {\n const next =\n prevEffort === \"auto\" || effortOptions.includes(prevEffort)\n ? prevEffort\n : \"auto\";\n writePersisted(storageKey, { model, engine, effort: next });\n return next;\n });\n },\n [storageKey],\n );\n\n const onEffortChange = useCallback(\n (effort: ReasoningEffort) => {\n hasExplicitSelectionRef.current = true;\n setSelectedEffort(effort);\n writePersisted(storageKey, {\n model: selectedModel,\n engine: selectedEngine,\n effort,\n });\n },\n [selectedEngine, selectedModel, storageKey],\n );\n\n const refreshEngines = useCallback(() => {\n Promise.all([\n fetch(agentNativePath(\"/_agent-native/actions/manage-agent-engine\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ action: \"list\" }),\n }).then((r) => (r.ok ? r.json() : null)),\n fetch(agentNativePath(\"/_agent-native/env-status\"))\n .then((r) => (r.ok ? r.json() : []))\n .catch(() => []),\n fetch(agentNativePath(\"/_agent-native/builder/status\"))\n .then((r) => (r.ok ? r.json() : null))\n .catch(() => null),\n ])\n .then(([enginesData, envKeys, builderStatus]) => {\n if (!enginesData?.engines) return;\n const configuredKeys = new Set(\n (envKeys as Array<{ key: string; configured: boolean }>)\n .filter((k) => k.configured)\n .map((k) => k.key),\n );\n const builderConnected = builderStatus?.configured === true;\n const currentEngineName: string | undefined =\n enginesData.current?.engine;\n const currentModel: string | undefined = enginesData.current?.model;\n\n let groups: EngineModelGroup[];\n\n if (builderConnected) {\n const builderEngine = enginesData.engines.find(\n (e: any) => e.name === \"builder\",\n );\n const builderModels: string[] = builderEngine?.supportedModels ?? [];\n const claude = builderModels.filter((m: string) =>\n m.startsWith(\"claude-\"),\n );\n const openai = builderModels.filter((m: string) =>\n m.startsWith(\"gpt-\"),\n );\n const gemini = builderModels.filter((m: string) =>\n m.startsWith(\"gemini-\"),\n );\n const other = builderModels.filter(\n (m: string) =>\n !m.startsWith(\"claude-\") &&\n !m.startsWith(\"gpt-\") &&\n !m.startsWith(\"gemini-\"),\n );\n\n groups = [\n ...(claude.length\n ? [\n {\n engine: \"builder\",\n label: \"Claude\",\n models: claude,\n configured: true,\n },\n ]\n : []),\n ...(openai.length\n ? [\n {\n engine: \"builder\",\n label: \"OpenAI\",\n models: openai,\n configured: true,\n },\n ]\n : []),\n ...(gemini.length\n ? [\n {\n engine: \"builder\",\n label: \"Gemini\",\n models: gemini,\n configured: true,\n },\n ]\n : []),\n ...(other.length\n ? [\n {\n engine: \"builder\",\n label: \"More\",\n models: other,\n configured: true,\n },\n ]\n : []),\n ];\n\n if (currentModel && !builderModels.includes(currentModel)) {\n const firstGroup = groups[0];\n if (firstGroup) firstGroup.models.unshift(currentModel);\n }\n } else {\n const allowedEngines = new Set([\n \"anthropic\",\n \"ai-sdk:openai\",\n \"ai-sdk:google\",\n ]);\n groups = enginesData.engines\n .filter((e: any) => allowedEngines.has(e.name))\n .map((e: any) => {\n const models = [...e.supportedModels];\n if (\n e.name === currentEngineName &&\n currentModel &&\n !models.includes(currentModel)\n ) {\n models.unshift(currentModel);\n }\n return {\n engine: e.name,\n label: e.label,\n models,\n configured:\n e.requiredEnvVars.length === 0 ||\n e.requiredEnvVars.some((v: string) =>\n configuredKeys.has(v),\n ) ||\n e.name === currentEngineName,\n };\n });\n }\n const nextDefaultModel = currentModel ?? DEFAULT_MODEL;\n setAvailableModels(groups);\n setDefaultModel(nextDefaultModel);\n\n const selection = selectionRef.current;\n if (!hasExplicitSelectionRef.current) {\n const defaultGroup =\n groups.find((group) => group.models.includes(nextDefaultModel)) ??\n groups[0];\n const nextModel =\n defaultGroup?.models.find((model) => model === nextDefaultModel) ??\n defaultGroup?.models[0] ??\n nextDefaultModel;\n const nextEngine = defaultGroup?.engine ?? \"\";\n const effortOptions = getReasoningEffortOptionsForModel(nextModel);\n const nextEffort =\n selection.selectedEffort === \"auto\" ||\n effortOptions.includes(selection.selectedEffort)\n ? selection.selectedEffort\n : \"auto\";\n setSelectedModel(nextModel);\n setSelectedEngine(nextEngine);\n setSelectedEffort(nextEffort);\n return;\n }\n\n const selectedGroup = groups.find(\n (group) =>\n group.models.includes(selection.selectedModel) &&\n (!selection.selectedEngine ||\n group.engine === selection.selectedEngine),\n );\n if (!selectedGroup) {\n const defaultGroup =\n groups.find((group) => group.models.includes(nextDefaultModel)) ??\n groups[0];\n const nextModel =\n defaultGroup?.models.find((model) => model === nextDefaultModel) ??\n defaultGroup?.models[0] ??\n nextDefaultModel;\n const nextEngine = defaultGroup?.engine ?? \"\";\n const effortOptions = getReasoningEffortOptionsForModel(nextModel);\n const nextEffort =\n selection.selectedEffort === \"auto\" ||\n effortOptions.includes(selection.selectedEffort)\n ? selection.selectedEffort\n : \"auto\";\n setSelectedModel(nextModel);\n setSelectedEngine(nextEngine);\n setSelectedEffort(nextEffort);\n writePersisted(storageKey, {\n model: nextModel,\n engine: nextEngine,\n effort: nextEffort,\n });\n }\n })\n .catch(() => {});\n }, [storageKey]);\n\n useEffect(() => {\n refreshEngines();\n }, [refreshEngines]);\n\n return {\n availableModels,\n defaultModel,\n selectedModel,\n selectedEngine,\n selectedEffort,\n onModelChange,\n onEffortChange,\n refreshEngines,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"use-chat-threads.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-threads.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AASD,wBAAgB,cAAc,CAC5B,MAAM,SAA+C,EACrD,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI;;;;iCAyMb,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;uBAuCV,MAAM;uBAK/B,MAAM;6BAzBA,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;2BA6I3B,MAAM,mBACC,kBAAkB,GAAG,IAAI,KACzC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;yBApFnB,MAAM,QACJ;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;8BAmDc,MAAM,WAAW,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;2BA2EnD,MAAM,KAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;;sBA/K9C,MAAM;EAiNd"}
1
+ {"version":3,"file":"use-chat-threads.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-threads.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAaD,wBAAgB,cAAc,CAC5B,MAAM,SAA+C,EACrD,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI;;;;iCAyMb,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;uBAuCV,MAAM;uBAK/B,MAAM;6BAzBA,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;2BA6I3B,MAAM,mBACC,kBAAkB,GAAG,IAAI,KACzC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;yBApFnB,MAAM,QACJ;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;8BAmDc,MAAM,WAAW,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;2BA2HnD,MAAM,KAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;;sBA/N9C,MAAM;EAiQd"}
@@ -326,6 +326,43 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
326
326
  }, [apiUrl]);
327
327
  const forkThread = useCallback(async (sourceId, sourceSnapshot) => {
328
328
  const id = crypto.randomUUID();
329
+ const fallbackForkFromSnapshot = async (source) => {
330
+ const title = source.title ? `${source.title} (fork)` : "";
331
+ const createdAt = Date.now();
332
+ const createRes = await fetch(`${apiUrl}/threads`, {
333
+ method: "POST",
334
+ headers: { "Content-Type": "application/json" },
335
+ body: JSON.stringify({
336
+ id,
337
+ title,
338
+ ...(source.scope ? { scope: source.scope } : {}),
339
+ }),
340
+ });
341
+ if (!createRes.ok)
342
+ return null;
343
+ const saveRes = await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {
344
+ method: "PUT",
345
+ headers: { "Content-Type": "application/json" },
346
+ body: JSON.stringify({
347
+ threadData: source.threadData,
348
+ title,
349
+ preview: source.preview,
350
+ messageCount: source.messageCount,
351
+ scope: source.scope,
352
+ }),
353
+ });
354
+ if (!saveRes.ok)
355
+ return null;
356
+ return {
357
+ id,
358
+ title,
359
+ preview: source.preview,
360
+ messageCount: source.messageCount,
361
+ createdAt,
362
+ updatedAt: Date.now(),
363
+ scope: source.scope,
364
+ };
365
+ };
329
366
  try {
330
367
  const localScope = threadsRef.current.find((t) => t.id === sourceId)?.scope ?? null;
331
368
  const source = sourceSnapshot && sourceSnapshot.messageCount > 0
@@ -336,13 +373,20 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
336
373
  headers: { "Content-Type": "application/json" },
337
374
  body: JSON.stringify({ id, ...(source ? { source } : {}) }),
338
375
  });
376
+ let thread = null;
339
377
  if (!res.ok) {
340
378
  // Surface failures so a click on the Fork button isn't a silent
341
379
  // no-op when the source thread can't be found or auth has lapsed.
342
380
  console.error(`[chat] fork failed for ${sourceId}: ${res.status} ${res.statusText}`);
343
- return null;
381
+ if (source && (res.status === 404 || res.status === 405)) {
382
+ thread = await fallbackForkFromSnapshot(source);
383
+ }
384
+ if (!thread)
385
+ return null;
386
+ }
387
+ else {
388
+ thread = await res.json();
344
389
  }
345
- const thread = await res.json();
346
390
  setThreads((prev) => [
347
391
  {
348
392
  id: thread.id,
@@ -1 +1 @@
1
- {"version":3,"file":"use-chat-threads.js","sourceRoot":"","sources":["../../src/client/use-chat-threads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAqChD,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAErD,SAAS,eAAe,CAAC,KAA8B;IACrD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,UAAU,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAM,GAAG,eAAe,CAAC,2BAA2B,CAAC,EACrD,UAAmB,EACnB,KAA8B;IAE9B,wEAAwE;IACxE,wEAAwE;IACxE,oEAAoE;IACpE,8BAA8B;IAC9B,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE;QACnC,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,UAAU;YACf,CAAC,CAAC,GAAG,iBAAiB,IAAI,UAAU,GAAG,SAAS,EAAE;YAClD,CAAC,CAAC,GAAG,iBAAiB,GAAG,SAAS,EAAE,CAAC;IACzC,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAsB,EAAE,CAAC,CAAC;IAEhE,yEAAyE;IACzE,oEAAoE;IACpE,oEAAoE;IACpE,oEAAoE;IACpE,MAAM,eAAe,GAAG,MAAM,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAEvD,2EAA2E;IAC3E,wEAAwE;IACxE,wEAAwE;IACxE,2EAA2E;IAC3E,qEAAqE;IACrE,qEAAqE;IACrE,wEAAwE;IACxE,uDAAuD;IACvD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAgB,GAAG,EAAE;QACvE,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QAC/C,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,MAAM,iBAAiB,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;IACjD,iBAAiB,CAAC,OAAO,GAAG,cAAc,CAAC;IAE3C,oEAAoE;IACpE,sEAAsE;IACtE,iEAAiE;IACjE,oEAAoE;IACpE,mEAAmE;IACnE,8CAA8C;IAC9C,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;IAChD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,eAAe,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;YAChD,eAAe,CAAC,OAAO,GAAG,eAAe,CAAC;YAC1C,IAAI,CAAC;gBACH,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;YAC3D,CAAC;YAAC,MAAM,CAAC;gBACP,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,IAAI,cAAc,EAAE,CAAC;gBACnB,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;YACxD,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,CAAC;IAEtC,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,UAAU,CAAC,CAAC;YAC7C,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO;YACpB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE;gBAClB,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAwB,CAAC;gBAC3D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACnD,kEAAkE;gBAClE,mEAAmE;gBACnE,gEAAgE;gBAChE,4DAA4D;gBAC5D,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACjE,CAAC;gBACF,oEAAoE;gBACpE,gEAAgE;gBAChE,iEAAiE;gBACjE,8DAA8D;gBAC9D,4DAA4D;gBAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;oBACnC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC;oBACnD,IAAI,CAAC,KAAK;wBAAE,OAAO,MAAM,CAAC;oBAC1B,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;oBAC3B,IAAI,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;wBACvC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;oBACnC,CAAC;oBACD,IAAI,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;wBAC7C,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;wBACvC,IAAI,KAAK,CAAC,OAAO;4BAAE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;wBAChD,IAAI,KAAK,CAAC,KAAK;4BAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;oBAC5C,CAAC;oBACD,6DAA6D;oBAC7D,8DAA8D;oBAC9D,6DAA6D;oBAC7D,4DAA4D;oBAC5D,6DAA6D;oBAC7D,qDAAqD;oBACrD,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;wBACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;oBAC3B,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC,CAAC,CAAC;gBACH,OAAO,CAAC,GAAG,cAAc,EAAE,GAAG,MAAM,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,OAA8B,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,uEAAuE;IACvE,oEAAoE;IACpE,sEAAsE;IACtE,sDAAsD;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAqC,KAAK,CAAC,CAAC;IACnE,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IAEzB,kEAAkE;IAClE,EAAE;IACF,0EAA0E;IAC1E,+DAA+D;IAC/D,kEAAkE;IAClE,oEAAoE;IACpE,6DAA6D;IAC7D,qEAAqE;IACrE,2DAA2D;IAC3D,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,EAAU,EAAE,WAAmC,EAAE,EAAE;QAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,UAAU,GAAsB;YACpC,EAAE;YACF,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,EAAE;YACX,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;YACd,KAAK,EAAE,WAAW;SACnB,CAAC;QACF,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAClB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAC7D,CAAC;IACJ,CAAC,EACD,EAAE,CACH,CAAC;IAEF,qEAAqE;IACrE,uBAAuB;IACvB,EAAE;IACF,mEAAmE;IACnE,wEAAwE;IACxE,uEAAuE;IACvE,wDAAwD;IACxD,sEAAsE;IACtE,uEAAuE;IACvE,uEAAuE;IACvE,qEAAqE;IACrE,iCAAiC;IACjC,oEAAoE;IACpE,oDAAoD;IACpD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,UAAU,CAAC,OAAO;YAAE,OAAO;QAC/B,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAE1B,CAAC,KAAK,IAAI,EAAE;YACV,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,aAAa,GAAG,MAAM,YAAY,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC;YAE1C,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,IACE,OAAO;oBACP,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;oBACrC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAC5C,CAAC;oBACD,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACzC,CAAC;qBAAM,IAAI,CAAC,OAAO,EAAE,CAAC;oBACpB,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBACpB,+DAA+D;gBAC/D,6DAA6D;gBAC7D,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;oBACvD,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;oBAC/B,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAChC,mBAAmB,CAAC,EAAE,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;oBAClD,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;YACD,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,EAAE,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAExC,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,WAAoB,EAA0B,EAAE;QAC/C,iEAAiE;QACjE,iEAAiE;QACjE,iEAAiE;QACjE,8BAA8B;QAC9B,MAAM,EAAE,GAAG,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9C,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,mBAAmB,CAAC,EAAE,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QAClD,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACtB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,EACD,CAAC,mBAAmB,CAAC,CACtB,CAAC;IAEF,uEAAuE;IACvE,mEAAmE;IACnE,oEAAoE;IACpE,mBAAmB;IACnB,MAAM,YAAY,GAAG,WAAW,CAC9B,KAAK,EAAE,QAAgB,EAAiB,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,GAAG,MAAM,YAAY,kBAAkB,CAAC,QAAQ,CAAC,EAAE,EAAE;gBAC/D,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;aACtC,CAAC,CAAC;YACH,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAClB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACjE,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,EAAU,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAC/C,EAAE,CACH,CAAC;IAEF,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,EAAU,EAAE,EAAE;QAC9C,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,YAAY,GAAG,WAAW,CAC9B,KAAK,EAAE,EAAU,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,GAAG,MAAM,YAAY,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE;gBACzD,MAAM,EAAE,QAAQ;aACjB,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE;YAClB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7C,IAAI,EAAE,KAAK,cAAc,EAAE,CAAC;gBAC1B,8DAA8D;gBAC9D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpB,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACN,sBAAsB;oBACtB,YAAY,EAAE,CAAC;gBACjB,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EACD,CAAC,MAAM,EAAE,cAAc,EAAE,YAAY,CAAC,CACvC,CAAC;IAEF,2DAA2D;IAC3D,gEAAgE;IAChE,4DAA4D;IAC5D,kEAAkE;IAClE,uDAAuD;IACvD,0DAA0D;IAC1D,MAAM,UAAU,GAAG,MAAM,CAAsB,OAAO,CAAC,CAAC;IACxD,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,MAAM,cAAc,GAAG,WAAW,CAChC,KAAK,EACH,EAAU,EACV,IAKC,EACD,EAAE;QACF,IAAI,CAAC;YACH,MAAM,UAAU,GACd,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;YAC7D,MAAM,KAAK,CAAC,GAAG,MAAM,YAAY,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE;gBACzD,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;aACrD,CAAC,CAAC;YACH,gEAAgE;YAChE,iEAAiE;YACjE,qEAAqE;YACrE,oCAAoC;YACpC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE;gBAClB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC7C,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,CAAC,CAAC,EAAE,KAAK,EAAE;wBACT,CAAC,CAAC;4BACE,GAAG,CAAC;4BACJ,KAAK,EAAE,IAAI,CAAC,KAAK;4BACjB,OAAO,EAAE,IAAI,CAAC,OAAO;4BACrB,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,IAAI;gCAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;6BAChC,CAAC;4BACF,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;yBACtB;wBACH,CAAC,CAAC,CAAC,CACN,CAAC;gBACJ,CAAC;gBACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvB,OAAO;oBACL;wBACE,EAAE;wBACF,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC;wBACpC,SAAS,EAAE,GAAG;wBACd,SAAS,EAAE,GAAG;wBACd,KAAK,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI;qBAChC;oBACD,GAAG,IAAI;iBACR,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,aAAa,GAAG,WAAW,CAC/B,KAAK,EAAE,QAAgB,EAAE,OAAe,EAA0B,EAAE;QAClE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,iBAAiB,EAAE;gBAClD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;aAClC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACzB,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YACxB,kCAAkC;YAClC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAClB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3D,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAC5B,KAAK,EACH,QAAgB,EAChB,cAA0C,EAClB,EAAE;QAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,UAAU,GACd,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;YACnE,MAAM,MAAM,GACV,cAAc,IAAI,cAAc,CAAC,YAAY,GAAG,CAAC;gBAC/C,CAAC,CAAC,EAAE,GAAG,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE;gBAC1C,CAAC,CAAC,SAAS,CAAC;YAChB,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,MAAM,YAAY,kBAAkB,CAAC,QAAQ,CAAC,OAAO,EACxD;gBACE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;aAC5D,CACF,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,gEAAgE;gBAChE,kEAAkE;gBAClE,OAAO,CAAC,KAAK,CACX,0BAA0B,QAAQ,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CACtE,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAChC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBACnB;oBACE,EAAE,EAAE,MAAM,CAAC,EAAE;oBACb,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,YAAY,EAAE,MAAM,CAAC,YAAY;oBACjC,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI;iBAC5B;gBACD,GAAG,IAAI;aACR,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,EAAE,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,aAAa,GAAG,WAAW,CAC/B,KAAK,EAAE,KAAa,EAAgC,EAAE;QACpD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,MAAM,cAAc,kBAAkB,CAAC,KAAK,CAAC,EAAE,CACnD,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,YAAY,EAAE,CAAC;IACjB,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,OAAO;QACL,OAAO;QACP,cAAc;QACd,SAAS;QACT,YAAY;QACZ,YAAY;QACZ,YAAY,EAAE,YAAY;QAC1B,YAAY;QACZ,UAAU;QACV,cAAc;QACd,aAAa;QACb,aAAa;QACb,cAAc;QACd,WAAW;KACZ,CAAC;AACJ,CAAC","sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { agentNativePath } from \"./api-path.js\";\n\nexport interface ChatThreadScope {\n type: string;\n id: string;\n label?: string;\n}\n\nexport interface ChatThreadSummary {\n id: string;\n title: string;\n preview: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n scope: ChatThreadScope | null;\n}\n\nexport interface ChatThreadData {\n id: string;\n ownerEmail: string;\n title: string;\n preview: string;\n threadData: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n scope: ChatThreadScope | null;\n}\n\nexport interface ChatThreadSnapshot {\n threadData: string;\n title: string;\n preview: string;\n messageCount: number;\n}\n\nconst ACTIVE_THREAD_KEY = \"agent-chat-active-thread\";\n\nfunction scopeKeySegment(scope?: ChatThreadScope | null): string {\n if (!scope) return \"\";\n return `:scope:${scope.type}:${scope.id}`;\n}\n\nexport function useChatThreads(\n apiUrl = agentNativePath(\"/_agent-native/agent-chat\"),\n storageKey?: string,\n scope?: ChatThreadScope | null,\n) {\n // Each (storageKey, scope) pair gets its own active-thread localStorage\n // key, so navigating between decks/designs/dashboards lands on whatever\n // thread the user had open last *for that resource* — not whichever\n // thread was active globally.\n const activeThreadKey = useMemo(() => {\n const scopePart = scopeKeySegment(scope);\n return storageKey\n ? `${ACTIVE_THREAD_KEY}:${storageKey}${scopePart}`\n : `${ACTIVE_THREAD_KEY}${scopePart}`;\n }, [storageKey, scope?.type, scope?.id]);\n const [threads, setThreads] = useState<ChatThreadSummary[]>([]);\n\n // IDs we generated client-side this session — consumers use this to know\n // whether to skip the per-thread restore skeleton, and we use it to\n // protect the optimistic-only thread from being yanked out of local\n // state when the server's threads list (which never sees it) loads.\n const newlyCreatedRef = useRef<Set<string>>(new Set());\n\n // Restore the saved active thread synchronously on mount so the chat shell\n // can paint immediately. We do NOT synthesize a fresh UUID here when no\n // saved id exists — that flow was creating empty `chat_threads` rows on\n // every page load via the optimistic POST, even if the user never chatted.\n // (Steve's account had 127 threads; 112 had message_count=0 and zero\n // agent_runs — pure ghosts.) When localStorage is empty, the initial\n // useEffect picks the most-recent server thread, or synthesizes a brand\n // new id only when there are no server threads at all.\n const [activeThreadId, setActiveThreadId] = useState<string | null>(() => {\n if (typeof window === \"undefined\") return null;\n try {\n return localStorage.getItem(activeThreadKey);\n } catch {\n return null;\n }\n });\n const [isLoading, setIsLoading] = useState(true);\n const fetchedRef = useRef(false);\n const activeThreadIdRef = useRef(activeThreadId);\n activeThreadIdRef.current = activeThreadId;\n\n // Persist active thread ID — and rehydrate on scope flips. When the\n // user navigates from deck A to deck B, `activeThreadKey` changes; we\n // need to re-read whatever thread was last active for B *before*\n // persisting back, otherwise we'd write A's id under B's key on the\n // very next render. The ref-and-branch pattern below keeps the two\n // concerns in one effect without racing them.\n const persistedKeyRef = useRef(activeThreadKey);\n useEffect(() => {\n if (persistedKeyRef.current !== activeThreadKey) {\n persistedKeyRef.current = activeThreadKey;\n try {\n setActiveThreadId(localStorage.getItem(activeThreadKey));\n } catch {\n setActiveThreadId(null);\n }\n return;\n }\n try {\n if (activeThreadId) {\n localStorage.setItem(activeThreadKey, activeThreadId);\n } else {\n localStorage.removeItem(activeThreadKey);\n }\n } catch {}\n }, [activeThreadId, activeThreadKey]);\n\n const fetchThreads = useCallback(async () => {\n try {\n const res = await fetch(`${apiUrl}/threads`);\n if (!res.ok) return;\n const data = await res.json();\n setThreads((prev) => {\n const loaded = (data.threads ?? []) as ChatThreadSummary[];\n const loadedIds = new Set(loaded.map((t) => t.id));\n // Preserve any optimistic threads we've created this session that\n // haven't shown up in the server list yet — the server only learns\n // about a thread when the user actually sends a message and the\n // agent run's `persistSubmittedUserMessage` writes the row.\n const optimisticOnly = prev.filter(\n (t) => newlyCreatedRef.current.has(t.id) && !loadedIds.has(t.id),\n );\n // Reconcile each server thread against our local copy. If the local\n // copy has a newer updatedAt or higher messageCount, keep those\n // fields — the server probably hasn't observed the user's latest\n // send yet, and naively replacing makes the recent-chats list\n // visibly jump back to older timestamps right after a send.\n const merged = loaded.map((server) => {\n const local = prev.find((t) => t.id === server.id);\n if (!local) return server;\n const next = { ...server };\n if (local.updatedAt > server.updatedAt) {\n next.updatedAt = local.updatedAt;\n }\n if (local.messageCount > server.messageCount) {\n next.messageCount = local.messageCount;\n if (local.preview) next.preview = local.preview;\n if (local.title) next.title = local.title;\n }\n // Preserve optimistic scope: when the server creates the row\n // on first message it does so without scope, and the next PUT\n // (saveThreadData) writes the local scope back. In the brief\n // window between those, the server list returns scope: null\n // while the user is clearly working inside a deck — keep the\n // local value so the tab bar doesn't blink unscoped.\n if (local.scope && !server.scope) {\n next.scope = local.scope;\n }\n return next;\n });\n return [...optimisticOnly, ...merged];\n });\n return data.threads as ChatThreadSummary[];\n } catch {\n return undefined;\n }\n }, [apiUrl]);\n\n // Latest scope as a ref so `createThread` (a useCallback that we don't\n // want to depend on scope identity) reads the current value at call\n // time. The scope a new chat inherits is the one in effect when the +\n // button is clicked, not when the hook first mounted.\n const scopeRef = useRef<ChatThreadScope | null | undefined>(scope);\n scopeRef.current = scope;\n\n // Add a client-generated thread to the local list optimistically.\n //\n // Critically, this does NOT `POST /threads` to the server — that path was\n // creating an empty row in `chat_threads` (message_count=0, no\n // agent_runs) on every page mount and every \"+\" click. The server\n // already creates the row idempotently the moment the user actually\n // sends their first message (`persistSubmittedUserMessage` →\n // `createThread`), so the client doesn't need to pre-create it. This\n // makes the threads table reflect real conversations only.\n const addOptimisticThread = useCallback(\n (id: string, threadScope: ChatThreadScope | null) => {\n const now = Date.now();\n const optimistic: ChatThreadSummary = {\n id,\n title: \"\",\n preview: \"\",\n messageCount: 0,\n createdAt: now,\n updatedAt: now,\n scope: threadScope,\n };\n setThreads((prev) =>\n prev.some((t) => t.id === id) ? prev : [optimistic, ...prev],\n );\n },\n [],\n );\n\n // Initial load: load threads from server, then reconcile against the\n // saved active thread.\n //\n // - savedId in loadedThreads → keep it (user's last conversation).\n // - savedId in newlyCreatedRef (we just created it this session) → keep\n // it; the server hasn't seen it yet because there's no POST anymore,\n // the row gets written when the user sends a message.\n // - savedId is set but neither on the server nor newly created here →\n // it's a stale id from a previous session whose row no longer exists\n // (was a ghost cleaned up, or the user emptied their account, etc.).\n // Drop them on the most-recent real thread instead of leaving them\n // staring at a 404'd composer.\n // - No savedId, no server threads → synthesize a fresh local id (no\n // POST; server creates the row on first message).\n useEffect(() => {\n if (fetchedRef.current) return;\n fetchedRef.current = true;\n\n (async () => {\n setIsLoading(true);\n const loadedThreads = await fetchThreads();\n const savedId = activeThreadIdRef.current;\n\n if (loadedThreads && loadedThreads.length > 0) {\n if (\n savedId &&\n !newlyCreatedRef.current.has(savedId) &&\n !loadedThreads.find((t) => t.id === savedId)\n ) {\n setActiveThreadId(loadedThreads[0].id);\n } else if (!savedId) {\n setActiveThreadId(loadedThreads[0].id);\n }\n } else if (!savedId) {\n // Brand new user — synthesize a local id so the composer has a\n // target. No POST: the server creates the row on first send.\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n const id = crypto.randomUUID();\n newlyCreatedRef.current.add(id);\n addOptimisticThread(id, scopeRef.current ?? null);\n setActiveThreadId(id);\n }\n }\n setIsLoading(false);\n })();\n }, [fetchThreads, addOptimisticThread]);\n\n const createThread = useCallback(\n (preferredId?: string): Promise<string | null> => {\n // Generate ID client-side for instant UI response. No POST — the\n // server creates the row when the user actually sends a message,\n // which prevents accumulation of empty thread rows when the user\n // clicks \"+\" but never chats.\n const id = preferredId || crypto.randomUUID();\n newlyCreatedRef.current.add(id);\n addOptimisticThread(id, scopeRef.current ?? null);\n setActiveThreadId(id);\n return Promise.resolve(id);\n },\n [addOptimisticThread],\n );\n\n // Drop a thread's scope so it becomes a general (cross-resource) chat.\n // This is the \"Detach from <deck>\" escape hatch in the UI. The PUT\n // also bumps the thread's updatedAt so it surfaces in the All Chats\n // list right away.\n const detachThread = useCallback(\n async (threadId: string): Promise<void> => {\n try {\n await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ scope: null }),\n });\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, scope: null } : t)),\n );\n } catch {}\n },\n [apiUrl],\n );\n\n const isNewThread = useCallback(\n (id: string) => newlyCreatedRef.current.has(id),\n [],\n );\n\n const switchThread = useCallback((id: string) => {\n setActiveThreadId(id);\n }, []);\n\n const removeThread = useCallback(\n async (id: string) => {\n try {\n await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n });\n } catch {}\n setThreads((prev) => {\n const next = prev.filter((t) => t.id !== id);\n if (id === activeThreadId) {\n // Switch to the next available thread, or create new if empty\n if (next.length > 0) {\n setActiveThreadId(next[0].id);\n } else {\n // Create a new thread\n createThread();\n }\n }\n return next;\n });\n },\n [apiUrl, activeThreadId, createThread],\n );\n\n // Ref to look up the latest scope of a known thread inside\n // saveThreadData without making the callback re-create on every\n // setThreads. The thread's scope is owned by createThread /\n // detachThread / fetchThreads — saveThreadData just mirrors it on\n // every save so the server eventually catches up after\n // persistSubmittedUserMessage creates the row sans scope.\n const threadsRef = useRef<ChatThreadSummary[]>(threads);\n threadsRef.current = threads;\n\n const saveThreadData = useCallback(\n async (\n id: string,\n data: {\n threadData: string;\n title: string;\n preview: string;\n messageCount?: number;\n },\n ) => {\n try {\n const localScope =\n threadsRef.current.find((t) => t.id === id)?.scope ?? null;\n await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ ...data, scope: localScope }),\n });\n // Update local thread list metadata. If the thread isn't in our\n // local list yet (an optimistic-only thread that the server just\n // created via persistSubmittedUserMessage), add it so HistoryPopover\n // can show it once it has messages.\n setThreads((prev) => {\n const exists = prev.some((t) => t.id === id);\n if (exists) {\n return prev.map((t) =>\n t.id === id\n ? {\n ...t,\n title: data.title,\n preview: data.preview,\n ...(data.messageCount != null && {\n messageCount: data.messageCount,\n }),\n updatedAt: Date.now(),\n }\n : t,\n );\n }\n const now = Date.now();\n return [\n {\n id,\n title: data.title,\n preview: data.preview,\n messageCount: data.messageCount ?? 0,\n createdAt: now,\n updatedAt: now,\n scope: scopeRef.current ?? null,\n },\n ...prev,\n ];\n });\n } catch {}\n },\n [apiUrl],\n );\n\n const generateTitle = useCallback(\n async (threadId: string, message: string): Promise<string | null> => {\n try {\n const res = await fetch(`${apiUrl}/generate-title`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ message }),\n });\n if (!res.ok) return null;\n const data = await res.json();\n const title = data.title;\n if (!title) return null;\n // Update the title in local state\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, title } : t)),\n );\n return title;\n } catch {\n return null;\n }\n },\n [apiUrl],\n );\n\n const forkThread = useCallback(\n async (\n sourceId: string,\n sourceSnapshot?: ChatThreadSnapshot | null,\n ): Promise<string | null> => {\n const id = crypto.randomUUID();\n try {\n const localScope =\n threadsRef.current.find((t) => t.id === sourceId)?.scope ?? null;\n const source =\n sourceSnapshot && sourceSnapshot.messageCount > 0\n ? { ...sourceSnapshot, scope: localScope }\n : undefined;\n const res = await fetch(\n `${apiUrl}/threads/${encodeURIComponent(sourceId)}/fork`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id, ...(source ? { source } : {}) }),\n },\n );\n if (!res.ok) {\n // Surface failures so a click on the Fork button isn't a silent\n // no-op when the source thread can't be found or auth has lapsed.\n console.error(\n `[chat] fork failed for ${sourceId}: ${res.status} ${res.statusText}`,\n );\n return null;\n }\n const thread = await res.json();\n setThreads((prev) => [\n {\n id: thread.id,\n title: thread.title,\n preview: thread.preview,\n messageCount: thread.messageCount,\n createdAt: thread.createdAt,\n updatedAt: thread.updatedAt,\n scope: thread.scope ?? null,\n },\n ...prev,\n ]);\n return thread.id;\n } catch (err) {\n console.error(`[chat] fork threw for ${sourceId}:`, err);\n return null;\n }\n },\n [apiUrl],\n );\n\n const searchThreads = useCallback(\n async (query: string): Promise<ChatThreadSummary[]> => {\n try {\n const res = await fetch(\n `${apiUrl}/threads?q=${encodeURIComponent(query)}`,\n );\n if (!res.ok) return [];\n const data = await res.json();\n return data.threads ?? [];\n } catch {\n return [];\n }\n },\n [apiUrl],\n );\n\n const refreshThreads = useCallback(() => {\n fetchThreads();\n }, [fetchThreads]);\n\n return {\n threads,\n activeThreadId,\n isLoading,\n createThread,\n switchThread,\n deleteThread: removeThread,\n detachThread,\n forkThread,\n saveThreadData,\n generateTitle,\n searchThreads,\n refreshThreads,\n isNewThread,\n };\n}\n"]}
1
+ {"version":3,"file":"use-chat-threads.js","sourceRoot":"","sources":["../../src/client/use-chat-threads.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { agentNativePath } from \"./api-path.js\";\n\nexport interface ChatThreadScope {\n type: string;\n id: string;\n label?: string;\n}\n\nexport interface ChatThreadSummary {\n id: string;\n title: string;\n preview: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n scope: ChatThreadScope | null;\n}\n\nexport interface ChatThreadData {\n id: string;\n ownerEmail: string;\n title: string;\n preview: string;\n threadData: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n scope: ChatThreadScope | null;\n}\n\nexport interface ChatThreadSnapshot {\n threadData: string;\n title: string;\n preview: string;\n messageCount: number;\n}\n\ninterface ForkSnapshotWithScope extends ChatThreadSnapshot {\n scope: ChatThreadScope | null;\n}\n\nconst ACTIVE_THREAD_KEY = \"agent-chat-active-thread\";\n\nfunction scopeKeySegment(scope?: ChatThreadScope | null): string {\n if (!scope) return \"\";\n return `:scope:${scope.type}:${scope.id}`;\n}\n\nexport function useChatThreads(\n apiUrl = agentNativePath(\"/_agent-native/agent-chat\"),\n storageKey?: string,\n scope?: ChatThreadScope | null,\n) {\n // Each (storageKey, scope) pair gets its own active-thread localStorage\n // key, so navigating between decks/designs/dashboards lands on whatever\n // thread the user had open last *for that resource* — not whichever\n // thread was active globally.\n const activeThreadKey = useMemo(() => {\n const scopePart = scopeKeySegment(scope);\n return storageKey\n ? `${ACTIVE_THREAD_KEY}:${storageKey}${scopePart}`\n : `${ACTIVE_THREAD_KEY}${scopePart}`;\n }, [storageKey, scope?.type, scope?.id]);\n const [threads, setThreads] = useState<ChatThreadSummary[]>([]);\n\n // IDs we generated client-side this session — consumers use this to know\n // whether to skip the per-thread restore skeleton, and we use it to\n // protect the optimistic-only thread from being yanked out of local\n // state when the server's threads list (which never sees it) loads.\n const newlyCreatedRef = useRef<Set<string>>(new Set());\n\n // Restore the saved active thread synchronously on mount so the chat shell\n // can paint immediately. We do NOT synthesize a fresh UUID here when no\n // saved id exists — that flow was creating empty `chat_threads` rows on\n // every page load via the optimistic POST, even if the user never chatted.\n // (Steve's account had 127 threads; 112 had message_count=0 and zero\n // agent_runs — pure ghosts.) When localStorage is empty, the initial\n // useEffect picks the most-recent server thread, or synthesizes a brand\n // new id only when there are no server threads at all.\n const [activeThreadId, setActiveThreadId] = useState<string | null>(() => {\n if (typeof window === \"undefined\") return null;\n try {\n return localStorage.getItem(activeThreadKey);\n } catch {\n return null;\n }\n });\n const [isLoading, setIsLoading] = useState(true);\n const fetchedRef = useRef(false);\n const activeThreadIdRef = useRef(activeThreadId);\n activeThreadIdRef.current = activeThreadId;\n\n // Persist active thread ID — and rehydrate on scope flips. When the\n // user navigates from deck A to deck B, `activeThreadKey` changes; we\n // need to re-read whatever thread was last active for B *before*\n // persisting back, otherwise we'd write A's id under B's key on the\n // very next render. The ref-and-branch pattern below keeps the two\n // concerns in one effect without racing them.\n const persistedKeyRef = useRef(activeThreadKey);\n useEffect(() => {\n if (persistedKeyRef.current !== activeThreadKey) {\n persistedKeyRef.current = activeThreadKey;\n try {\n setActiveThreadId(localStorage.getItem(activeThreadKey));\n } catch {\n setActiveThreadId(null);\n }\n return;\n }\n try {\n if (activeThreadId) {\n localStorage.setItem(activeThreadKey, activeThreadId);\n } else {\n localStorage.removeItem(activeThreadKey);\n }\n } catch {}\n }, [activeThreadId, activeThreadKey]);\n\n const fetchThreads = useCallback(async () => {\n try {\n const res = await fetch(`${apiUrl}/threads`);\n if (!res.ok) return;\n const data = await res.json();\n setThreads((prev) => {\n const loaded = (data.threads ?? []) as ChatThreadSummary[];\n const loadedIds = new Set(loaded.map((t) => t.id));\n // Preserve any optimistic threads we've created this session that\n // haven't shown up in the server list yet — the server only learns\n // about a thread when the user actually sends a message and the\n // agent run's `persistSubmittedUserMessage` writes the row.\n const optimisticOnly = prev.filter(\n (t) => newlyCreatedRef.current.has(t.id) && !loadedIds.has(t.id),\n );\n // Reconcile each server thread against our local copy. If the local\n // copy has a newer updatedAt or higher messageCount, keep those\n // fields — the server probably hasn't observed the user's latest\n // send yet, and naively replacing makes the recent-chats list\n // visibly jump back to older timestamps right after a send.\n const merged = loaded.map((server) => {\n const local = prev.find((t) => t.id === server.id);\n if (!local) return server;\n const next = { ...server };\n if (local.updatedAt > server.updatedAt) {\n next.updatedAt = local.updatedAt;\n }\n if (local.messageCount > server.messageCount) {\n next.messageCount = local.messageCount;\n if (local.preview) next.preview = local.preview;\n if (local.title) next.title = local.title;\n }\n // Preserve optimistic scope: when the server creates the row\n // on first message it does so without scope, and the next PUT\n // (saveThreadData) writes the local scope back. In the brief\n // window between those, the server list returns scope: null\n // while the user is clearly working inside a deck — keep the\n // local value so the tab bar doesn't blink unscoped.\n if (local.scope && !server.scope) {\n next.scope = local.scope;\n }\n return next;\n });\n return [...optimisticOnly, ...merged];\n });\n return data.threads as ChatThreadSummary[];\n } catch {\n return undefined;\n }\n }, [apiUrl]);\n\n // Latest scope as a ref so `createThread` (a useCallback that we don't\n // want to depend on scope identity) reads the current value at call\n // time. The scope a new chat inherits is the one in effect when the +\n // button is clicked, not when the hook first mounted.\n const scopeRef = useRef<ChatThreadScope | null | undefined>(scope);\n scopeRef.current = scope;\n\n // Add a client-generated thread to the local list optimistically.\n //\n // Critically, this does NOT `POST /threads` to the server — that path was\n // creating an empty row in `chat_threads` (message_count=0, no\n // agent_runs) on every page mount and every \"+\" click. The server\n // already creates the row idempotently the moment the user actually\n // sends their first message (`persistSubmittedUserMessage` →\n // `createThread`), so the client doesn't need to pre-create it. This\n // makes the threads table reflect real conversations only.\n const addOptimisticThread = useCallback(\n (id: string, threadScope: ChatThreadScope | null) => {\n const now = Date.now();\n const optimistic: ChatThreadSummary = {\n id,\n title: \"\",\n preview: \"\",\n messageCount: 0,\n createdAt: now,\n updatedAt: now,\n scope: threadScope,\n };\n setThreads((prev) =>\n prev.some((t) => t.id === id) ? prev : [optimistic, ...prev],\n );\n },\n [],\n );\n\n // Initial load: load threads from server, then reconcile against the\n // saved active thread.\n //\n // - savedId in loadedThreads → keep it (user's last conversation).\n // - savedId in newlyCreatedRef (we just created it this session) → keep\n // it; the server hasn't seen it yet because there's no POST anymore,\n // the row gets written when the user sends a message.\n // - savedId is set but neither on the server nor newly created here →\n // it's a stale id from a previous session whose row no longer exists\n // (was a ghost cleaned up, or the user emptied their account, etc.).\n // Drop them on the most-recent real thread instead of leaving them\n // staring at a 404'd composer.\n // - No savedId, no server threads → synthesize a fresh local id (no\n // POST; server creates the row on first message).\n useEffect(() => {\n if (fetchedRef.current) return;\n fetchedRef.current = true;\n\n (async () => {\n setIsLoading(true);\n const loadedThreads = await fetchThreads();\n const savedId = activeThreadIdRef.current;\n\n if (loadedThreads && loadedThreads.length > 0) {\n if (\n savedId &&\n !newlyCreatedRef.current.has(savedId) &&\n !loadedThreads.find((t) => t.id === savedId)\n ) {\n setActiveThreadId(loadedThreads[0].id);\n } else if (!savedId) {\n setActiveThreadId(loadedThreads[0].id);\n }\n } else if (!savedId) {\n // Brand new user — synthesize a local id so the composer has a\n // target. No POST: the server creates the row on first send.\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n const id = crypto.randomUUID();\n newlyCreatedRef.current.add(id);\n addOptimisticThread(id, scopeRef.current ?? null);\n setActiveThreadId(id);\n }\n }\n setIsLoading(false);\n })();\n }, [fetchThreads, addOptimisticThread]);\n\n const createThread = useCallback(\n (preferredId?: string): Promise<string | null> => {\n // Generate ID client-side for instant UI response. No POST — the\n // server creates the row when the user actually sends a message,\n // which prevents accumulation of empty thread rows when the user\n // clicks \"+\" but never chats.\n const id = preferredId || crypto.randomUUID();\n newlyCreatedRef.current.add(id);\n addOptimisticThread(id, scopeRef.current ?? null);\n setActiveThreadId(id);\n return Promise.resolve(id);\n },\n [addOptimisticThread],\n );\n\n // Drop a thread's scope so it becomes a general (cross-resource) chat.\n // This is the \"Detach from <deck>\" escape hatch in the UI. The PUT\n // also bumps the thread's updatedAt so it surfaces in the All Chats\n // list right away.\n const detachThread = useCallback(\n async (threadId: string): Promise<void> => {\n try {\n await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ scope: null }),\n });\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, scope: null } : t)),\n );\n } catch {}\n },\n [apiUrl],\n );\n\n const isNewThread = useCallback(\n (id: string) => newlyCreatedRef.current.has(id),\n [],\n );\n\n const switchThread = useCallback((id: string) => {\n setActiveThreadId(id);\n }, []);\n\n const removeThread = useCallback(\n async (id: string) => {\n try {\n await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n });\n } catch {}\n setThreads((prev) => {\n const next = prev.filter((t) => t.id !== id);\n if (id === activeThreadId) {\n // Switch to the next available thread, or create new if empty\n if (next.length > 0) {\n setActiveThreadId(next[0].id);\n } else {\n // Create a new thread\n createThread();\n }\n }\n return next;\n });\n },\n [apiUrl, activeThreadId, createThread],\n );\n\n // Ref to look up the latest scope of a known thread inside\n // saveThreadData without making the callback re-create on every\n // setThreads. The thread's scope is owned by createThread /\n // detachThread / fetchThreads — saveThreadData just mirrors it on\n // every save so the server eventually catches up after\n // persistSubmittedUserMessage creates the row sans scope.\n const threadsRef = useRef<ChatThreadSummary[]>(threads);\n threadsRef.current = threads;\n\n const saveThreadData = useCallback(\n async (\n id: string,\n data: {\n threadData: string;\n title: string;\n preview: string;\n messageCount?: number;\n },\n ) => {\n try {\n const localScope =\n threadsRef.current.find((t) => t.id === id)?.scope ?? null;\n await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ ...data, scope: localScope }),\n });\n // Update local thread list metadata. If the thread isn't in our\n // local list yet (an optimistic-only thread that the server just\n // created via persistSubmittedUserMessage), add it so HistoryPopover\n // can show it once it has messages.\n setThreads((prev) => {\n const exists = prev.some((t) => t.id === id);\n if (exists) {\n return prev.map((t) =>\n t.id === id\n ? {\n ...t,\n title: data.title,\n preview: data.preview,\n ...(data.messageCount != null && {\n messageCount: data.messageCount,\n }),\n updatedAt: Date.now(),\n }\n : t,\n );\n }\n const now = Date.now();\n return [\n {\n id,\n title: data.title,\n preview: data.preview,\n messageCount: data.messageCount ?? 0,\n createdAt: now,\n updatedAt: now,\n scope: scopeRef.current ?? null,\n },\n ...prev,\n ];\n });\n } catch {}\n },\n [apiUrl],\n );\n\n const generateTitle = useCallback(\n async (threadId: string, message: string): Promise<string | null> => {\n try {\n const res = await fetch(`${apiUrl}/generate-title`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ message }),\n });\n if (!res.ok) return null;\n const data = await res.json();\n const title = data.title;\n if (!title) return null;\n // Update the title in local state\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, title } : t)),\n );\n return title;\n } catch {\n return null;\n }\n },\n [apiUrl],\n );\n\n const forkThread = useCallback(\n async (\n sourceId: string,\n sourceSnapshot?: ChatThreadSnapshot | null,\n ): Promise<string | null> => {\n const id = crypto.randomUUID();\n const fallbackForkFromSnapshot = async (\n source: ForkSnapshotWithScope,\n ): Promise<ChatThreadSummary | null> => {\n const title = source.title ? `${source.title} (fork)` : \"\";\n const createdAt = Date.now();\n const createRes = await fetch(`${apiUrl}/threads`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n id,\n title,\n ...(source.scope ? { scope: source.scope } : {}),\n }),\n });\n if (!createRes.ok) return null;\n\n const saveRes = await fetch(\n `${apiUrl}/threads/${encodeURIComponent(id)}`,\n {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n threadData: source.threadData,\n title,\n preview: source.preview,\n messageCount: source.messageCount,\n scope: source.scope,\n }),\n },\n );\n if (!saveRes.ok) return null;\n\n return {\n id,\n title,\n preview: source.preview,\n messageCount: source.messageCount,\n createdAt,\n updatedAt: Date.now(),\n scope: source.scope,\n };\n };\n\n try {\n const localScope =\n threadsRef.current.find((t) => t.id === sourceId)?.scope ?? null;\n const source =\n sourceSnapshot && sourceSnapshot.messageCount > 0\n ? { ...sourceSnapshot, scope: localScope }\n : undefined;\n const res = await fetch(\n `${apiUrl}/threads/${encodeURIComponent(sourceId)}/fork`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id, ...(source ? { source } : {}) }),\n },\n );\n let thread: ChatThreadSummary | null = null;\n if (!res.ok) {\n // Surface failures so a click on the Fork button isn't a silent\n // no-op when the source thread can't be found or auth has lapsed.\n console.error(\n `[chat] fork failed for ${sourceId}: ${res.status} ${res.statusText}`,\n );\n if (source && (res.status === 404 || res.status === 405)) {\n thread = await fallbackForkFromSnapshot(source);\n }\n if (!thread) return null;\n } else {\n thread = await res.json();\n }\n setThreads((prev) => [\n {\n id: thread.id,\n title: thread.title,\n preview: thread.preview,\n messageCount: thread.messageCount,\n createdAt: thread.createdAt,\n updatedAt: thread.updatedAt,\n scope: thread.scope ?? null,\n },\n ...prev,\n ]);\n return thread.id;\n } catch (err) {\n console.error(`[chat] fork threw for ${sourceId}:`, err);\n return null;\n }\n },\n [apiUrl],\n );\n\n const searchThreads = useCallback(\n async (query: string): Promise<ChatThreadSummary[]> => {\n try {\n const res = await fetch(\n `${apiUrl}/threads?q=${encodeURIComponent(query)}`,\n );\n if (!res.ok) return [];\n const data = await res.json();\n return data.threads ?? [];\n } catch {\n return [];\n }\n },\n [apiUrl],\n );\n\n const refreshThreads = useCallback(() => {\n fetchThreads();\n }, [fetchThreads]);\n\n return {\n threads,\n activeThreadId,\n isLoading,\n createThread,\n switchThread,\n deleteThread: removeThread,\n detachThread,\n forkThread,\n saveThreadData,\n generateTitle,\n searchThreads,\n refreshThreads,\n isNewThread,\n };\n}\n"]}
@@ -81,5 +81,82 @@ describe("useChatThreads", () => {
81
81
  source: { ...snapshot, scope: sourceThread.scope },
82
82
  });
83
83
  });
84
+ it("creates a fork from the client snapshot when the fork endpoint cannot find the source", async () => {
85
+ const sourceThread = {
86
+ id: "source-thread",
87
+ title: "Pipeline",
88
+ preview: "make this slide better",
89
+ messageCount: 2,
90
+ createdAt: 1,
91
+ updatedAt: 2,
92
+ scope: { type: "deck", id: "deck-1", label: "Pipeline deck" },
93
+ };
94
+ const fetchMock = vi.fn(async (url, init) => {
95
+ if (url === "/chat/threads" && !init) {
96
+ return jsonResponse({ threads: [sourceThread] });
97
+ }
98
+ if (url === "/chat/threads/source-thread/fork") {
99
+ return new Response(JSON.stringify({ error: "Thread not found" }), {
100
+ status: 404,
101
+ headers: { "Content-Type": "application/json" },
102
+ });
103
+ }
104
+ if (url === "/chat/threads" && init?.method === "POST") {
105
+ return jsonResponse({
106
+ id: "forked-thread",
107
+ title: "Pipeline (fork)",
108
+ preview: "",
109
+ messageCount: 0,
110
+ createdAt: 3,
111
+ updatedAt: 3,
112
+ scope: sourceThread.scope,
113
+ });
114
+ }
115
+ if (url === "/chat/threads/forked-thread" && init?.method === "PUT") {
116
+ return jsonResponse({ ok: true });
117
+ }
118
+ throw new Error(`Unexpected fetch: ${url}`);
119
+ });
120
+ vi.stubGlobal("fetch", fetchMock);
121
+ let hook = null;
122
+ function Harness() {
123
+ hook = useChatThreads("/chat", "fork-test");
124
+ return null;
125
+ }
126
+ await act(async () => {
127
+ root.render(_jsx(Harness, {}));
128
+ });
129
+ await act(async () => {
130
+ await Promise.resolve();
131
+ await Promise.resolve();
132
+ });
133
+ const snapshot = {
134
+ threadData: JSON.stringify({ messages: [{ message: { id: "m1" } }] }),
135
+ title: "Pipeline",
136
+ preview: "make this slide better",
137
+ messageCount: 1,
138
+ };
139
+ let forkedId = null;
140
+ await act(async () => {
141
+ forkedId = await hook.forkThread("source-thread", snapshot);
142
+ });
143
+ expect(forkedId).toBe("forked-thread");
144
+ const createCall = fetchMock.mock.calls.find(([url, init]) => url === "/chat/threads" && init?.method === "POST");
145
+ expect(createCall).toBeDefined();
146
+ expect(JSON.parse(createCall[1].body)).toEqual({
147
+ id: "forked-thread",
148
+ title: "Pipeline (fork)",
149
+ scope: sourceThread.scope,
150
+ });
151
+ const saveCall = fetchMock.mock.calls.find(([url, init]) => url === "/chat/threads/forked-thread" && init?.method === "PUT");
152
+ expect(saveCall).toBeDefined();
153
+ expect(JSON.parse(saveCall[1].body)).toEqual({
154
+ threadData: snapshot.threadData,
155
+ title: "Pipeline (fork)",
156
+ preview: snapshot.preview,
157
+ messageCount: snapshot.messageCount,
158
+ scope: sourceThread.scope,
159
+ });
160
+ });
84
161
  });
85
162
  //# sourceMappingURL=use-chat-threads.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-chat-threads.spec.js","sourceRoot":"","sources":["../../src/client/use-chat-threads.spec.tsx"],"names":[],"mappings":"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","sourcesContent":["// @vitest-environment happy-dom\n\nimport React, { act } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport {\n useChatThreads,\n type ChatThreadSnapshot,\n type ChatThreadSummary,\n} from \"./use-chat-threads.js\";\n\nfunction jsonResponse(data: unknown) {\n return new Response(JSON.stringify(data), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\ndescribe(\"useChatThreads\", () => {\n let container: HTMLDivElement;\n let root: Root;\n\n beforeEach(() => {\n vi.stubGlobal(\"IS_REACT_ACT_ENVIRONMENT\", true);\n vi.stubGlobal(\"crypto\", { randomUUID: () => \"forked-thread\" });\n window.localStorage.clear();\n container = document.createElement(\"div\");\n document.body.appendChild(container);\n root = createRoot(container);\n });\n\n afterEach(() => {\n act(() => {\n root.unmount();\n });\n container.remove();\n vi.unstubAllGlobals();\n });\n\n it(\"sends the current client snapshot when forking a thread\", async () => {\n const sourceThread: ChatThreadSummary = {\n id: \"source-thread\",\n title: \"Pipeline\",\n preview: \"make this slide better\",\n messageCount: 2,\n createdAt: 1,\n updatedAt: 2,\n scope: { type: \"dashboard\", id: \"dash-1\", label: \"Pipeline\" },\n };\n const fetchMock = vi.fn(async (url: string, init?: RequestInit) => {\n if (url === \"/chat/threads\" && !init) {\n return jsonResponse({ threads: [sourceThread] });\n }\n if (url === \"/chat/threads/source-thread/fork\") {\n return jsonResponse({\n ...sourceThread,\n id: \"forked-thread\",\n title: \"Pipeline (fork)\",\n });\n }\n throw new Error(`Unexpected fetch: ${url}`);\n });\n vi.stubGlobal(\"fetch\", fetchMock);\n\n let hook: ReturnType<typeof useChatThreads> | null = null;\n function Harness() {\n hook = useChatThreads(\"/chat\", \"fork-test\");\n return null;\n }\n\n await act(async () => {\n root.render(<Harness />);\n });\n await act(async () => {\n await Promise.resolve();\n await Promise.resolve();\n });\n\n const snapshot: ChatThreadSnapshot = {\n threadData: JSON.stringify({ messages: [{ message: { id: \"m1\" } }] }),\n title: \"Pipeline\",\n preview: \"make this slide better\",\n messageCount: 1,\n };\n\n let forkedId: string | null = null;\n await act(async () => {\n forkedId = await hook!.forkThread(\"source-thread\", snapshot);\n });\n\n expect(forkedId).toBe(\"forked-thread\");\n const forkCall = fetchMock.mock.calls.find(\n ([url]) => url === \"/chat/threads/source-thread/fork\",\n );\n expect(forkCall).toBeDefined();\n expect(JSON.parse(forkCall![1]!.body as string)).toEqual({\n id: \"forked-thread\",\n source: { ...snapshot, scope: sourceThread.scope },\n });\n });\n});\n"]}
1
+ {"version":3,"file":"use-chat-threads.spec.js","sourceRoot":"","sources":["../../src/client/use-chat-threads.spec.tsx"],"names":[],"mappings":"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","sourcesContent":["// @vitest-environment happy-dom\n\nimport React, { act } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport {\n useChatThreads,\n type ChatThreadSnapshot,\n type ChatThreadSummary,\n} from \"./use-chat-threads.js\";\n\nfunction jsonResponse(data: unknown) {\n return new Response(JSON.stringify(data), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\ndescribe(\"useChatThreads\", () => {\n let container: HTMLDivElement;\n let root: Root;\n\n beforeEach(() => {\n vi.stubGlobal(\"IS_REACT_ACT_ENVIRONMENT\", true);\n vi.stubGlobal(\"crypto\", { randomUUID: () => \"forked-thread\" });\n window.localStorage.clear();\n container = document.createElement(\"div\");\n document.body.appendChild(container);\n root = createRoot(container);\n });\n\n afterEach(() => {\n act(() => {\n root.unmount();\n });\n container.remove();\n vi.unstubAllGlobals();\n });\n\n it(\"sends the current client snapshot when forking a thread\", async () => {\n const sourceThread: ChatThreadSummary = {\n id: \"source-thread\",\n title: \"Pipeline\",\n preview: \"make this slide better\",\n messageCount: 2,\n createdAt: 1,\n updatedAt: 2,\n scope: { type: \"dashboard\", id: \"dash-1\", label: \"Pipeline\" },\n };\n const fetchMock = vi.fn(async (url: string, init?: RequestInit) => {\n if (url === \"/chat/threads\" && !init) {\n return jsonResponse({ threads: [sourceThread] });\n }\n if (url === \"/chat/threads/source-thread/fork\") {\n return jsonResponse({\n ...sourceThread,\n id: \"forked-thread\",\n title: \"Pipeline (fork)\",\n });\n }\n throw new Error(`Unexpected fetch: ${url}`);\n });\n vi.stubGlobal(\"fetch\", fetchMock);\n\n let hook: ReturnType<typeof useChatThreads> | null = null;\n function Harness() {\n hook = useChatThreads(\"/chat\", \"fork-test\");\n return null;\n }\n\n await act(async () => {\n root.render(<Harness />);\n });\n await act(async () => {\n await Promise.resolve();\n await Promise.resolve();\n });\n\n const snapshot: ChatThreadSnapshot = {\n threadData: JSON.stringify({ messages: [{ message: { id: \"m1\" } }] }),\n title: \"Pipeline\",\n preview: \"make this slide better\",\n messageCount: 1,\n };\n\n let forkedId: string | null = null;\n await act(async () => {\n forkedId = await hook!.forkThread(\"source-thread\", snapshot);\n });\n\n expect(forkedId).toBe(\"forked-thread\");\n const forkCall = fetchMock.mock.calls.find(\n ([url]) => url === \"/chat/threads/source-thread/fork\",\n );\n expect(forkCall).toBeDefined();\n expect(JSON.parse(forkCall![1]!.body as string)).toEqual({\n id: \"forked-thread\",\n source: { ...snapshot, scope: sourceThread.scope },\n });\n });\n\n it(\"creates a fork from the client snapshot when the fork endpoint cannot find the source\", async () => {\n const sourceThread: ChatThreadSummary = {\n id: \"source-thread\",\n title: \"Pipeline\",\n preview: \"make this slide better\",\n messageCount: 2,\n createdAt: 1,\n updatedAt: 2,\n scope: { type: \"deck\", id: \"deck-1\", label: \"Pipeline deck\" },\n };\n const fetchMock = vi.fn(async (url: string, init?: RequestInit) => {\n if (url === \"/chat/threads\" && !init) {\n return jsonResponse({ threads: [sourceThread] });\n }\n if (url === \"/chat/threads/source-thread/fork\") {\n return new Response(JSON.stringify({ error: \"Thread not found\" }), {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n if (url === \"/chat/threads\" && init?.method === \"POST\") {\n return jsonResponse({\n id: \"forked-thread\",\n title: \"Pipeline (fork)\",\n preview: \"\",\n messageCount: 0,\n createdAt: 3,\n updatedAt: 3,\n scope: sourceThread.scope,\n });\n }\n if (url === \"/chat/threads/forked-thread\" && init?.method === \"PUT\") {\n return jsonResponse({ ok: true });\n }\n throw new Error(`Unexpected fetch: ${url}`);\n });\n vi.stubGlobal(\"fetch\", fetchMock);\n\n let hook: ReturnType<typeof useChatThreads> | null = null;\n function Harness() {\n hook = useChatThreads(\"/chat\", \"fork-test\");\n return null;\n }\n\n await act(async () => {\n root.render(<Harness />);\n });\n await act(async () => {\n await Promise.resolve();\n await Promise.resolve();\n });\n\n const snapshot: ChatThreadSnapshot = {\n threadData: JSON.stringify({ messages: [{ message: { id: \"m1\" } }] }),\n title: \"Pipeline\",\n preview: \"make this slide better\",\n messageCount: 1,\n };\n\n let forkedId: string | null = null;\n await act(async () => {\n forkedId = await hook!.forkThread(\"source-thread\", snapshot);\n });\n\n expect(forkedId).toBe(\"forked-thread\");\n const createCall = fetchMock.mock.calls.find(\n ([url, init]) => url === \"/chat/threads\" && init?.method === \"POST\",\n );\n expect(createCall).toBeDefined();\n expect(JSON.parse(createCall![1]!.body as string)).toEqual({\n id: \"forked-thread\",\n title: \"Pipeline (fork)\",\n scope: sourceThread.scope,\n });\n const saveCall = fetchMock.mock.calls.find(\n ([url, init]) =>\n url === \"/chat/threads/forked-thread\" && init?.method === \"PUT\",\n );\n expect(saveCall).toBeDefined();\n expect(JSON.parse(saveCall![1]!.body as string)).toEqual({\n threadData: snapshot.threadData,\n title: \"Pipeline (fork)\",\n preview: snapshot.preview,\n messageCount: snapshot.messageCount,\n scope: sourceThread.scope,\n });\n });\n});\n"]}
@@ -0,0 +1,4 @@
1
+ export { CODE_AGENT_PERMISSION_MODES, appendCodeAgentTranscriptEvent, codeAgentRunArtifactsDir, codeAgentRunTranscriptPath, codeAgentRunsDir, codeAgentStoreRoot, codeAgentTranscriptsDir, createCodeAgentRunRecord, getCodeAgentRunRecord, getLastCodeAgentRunRecord, isActiveCodeAgentRun, listCodeAgentRunRecords, listCodeAgentTranscriptEvents, normalizeCodeAgentPermissionMode, queueCodeAgentFollowUp, updateCodeAgentRunRecord, type AppendCodeAgentTranscriptEventInput, type CodeAgentPermissionMode, type CodeAgentRunDetail, type CodeAgentRunProgress, type CodeAgentRunRecord, type CodeAgentRunStatus, type CodeAgentTranscriptEvent, type CodeAgentTranscriptEventKind, type CreateCodeAgentRunInput, type CodeAgentFollowUpMode, type QueueCodeAgentFollowUpInput, } from "../cli/code-agent-runs.js";
2
+ export { findProjectSlashCommand, isReservedProjectSlashCommandName, listProjectSkills, listProjectSlashCommands, listVisibleProjectSlashCommands, readProjectCodePack, renderProjectSlashCommandPrompt, type CodeAgentCodePack, type CodeAgentProjectCommand, type CodeAgentProjectSkill, type ReadProjectCodePackOptions, } from "../cli/code-agent-commands.js";
3
+ export { executeCodeAgentRun, executeExistingCodeAgentRun, executePendingCodeAgentApproval, type ExecuteCodeAgentRunOptions, } from "../cli/code-agent-executor.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/code-agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,8BAA8B,EAC9B,wBAAwB,EACxB,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,6BAA6B,EAC7B,gCAAgC,EAChC,sBAAsB,EACtB,wBAAwB,EACxB,KAAK,mCAAmC,EACxC,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,GACjC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,uBAAuB,EACvB,iCAAiC,EACjC,iBAAiB,EACjB,wBAAwB,EACxB,+BAA+B,EAC/B,mBAAmB,EACnB,+BAA+B,EAC/B,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,GAChC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,+BAA+B,EAC/B,KAAK,0BAA0B,GAChC,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { CODE_AGENT_PERMISSION_MODES, appendCodeAgentTranscriptEvent, codeAgentRunArtifactsDir, codeAgentRunTranscriptPath, codeAgentRunsDir, codeAgentStoreRoot, codeAgentTranscriptsDir, createCodeAgentRunRecord, getCodeAgentRunRecord, getLastCodeAgentRunRecord, isActiveCodeAgentRun, listCodeAgentRunRecords, listCodeAgentTranscriptEvents, normalizeCodeAgentPermissionMode, queueCodeAgentFollowUp, updateCodeAgentRunRecord, } from "../cli/code-agent-runs.js";
2
+ export { findProjectSlashCommand, isReservedProjectSlashCommandName, listProjectSkills, listProjectSlashCommands, listVisibleProjectSlashCommands, readProjectCodePack, renderProjectSlashCommandPrompt, } from "../cli/code-agent-commands.js";
3
+ export { executeCodeAgentRun, executeExistingCodeAgentRun, executePendingCodeAgentApproval, } from "../cli/code-agent-executor.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/code-agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,8BAA8B,EAC9B,wBAAwB,EACxB,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,6BAA6B,EAC7B,gCAAgC,EAChC,sBAAsB,EACtB,wBAAwB,GAYzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,uBAAuB,EACvB,iCAAiC,EACjC,iBAAiB,EACjB,wBAAwB,EACxB,+BAA+B,EAC/B,mBAAmB,EACnB,+BAA+B,GAKhC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,+BAA+B,GAEhC,MAAM,+BAA+B,CAAC","sourcesContent":["export {\n CODE_AGENT_PERMISSION_MODES,\n appendCodeAgentTranscriptEvent,\n codeAgentRunArtifactsDir,\n codeAgentRunTranscriptPath,\n codeAgentRunsDir,\n codeAgentStoreRoot,\n codeAgentTranscriptsDir,\n createCodeAgentRunRecord,\n getCodeAgentRunRecord,\n getLastCodeAgentRunRecord,\n isActiveCodeAgentRun,\n listCodeAgentRunRecords,\n listCodeAgentTranscriptEvents,\n normalizeCodeAgentPermissionMode,\n queueCodeAgentFollowUp,\n updateCodeAgentRunRecord,\n type AppendCodeAgentTranscriptEventInput,\n type CodeAgentPermissionMode,\n type CodeAgentRunDetail,\n type CodeAgentRunProgress,\n type CodeAgentRunRecord,\n type CodeAgentRunStatus,\n type CodeAgentTranscriptEvent,\n type CodeAgentTranscriptEventKind,\n type CreateCodeAgentRunInput,\n type CodeAgentFollowUpMode,\n type QueueCodeAgentFollowUpInput,\n} from \"../cli/code-agent-runs.js\";\nexport {\n findProjectSlashCommand,\n isReservedProjectSlashCommandName,\n listProjectSkills,\n listProjectSlashCommands,\n listVisibleProjectSlashCommands,\n readProjectCodePack,\n renderProjectSlashCommandPrompt,\n type CodeAgentCodePack,\n type CodeAgentProjectCommand,\n type CodeAgentProjectSkill,\n type ReadProjectCodePackOptions,\n} from \"../cli/code-agent-commands.js\";\nexport {\n executeCodeAgentRun,\n executeExistingCodeAgentRun,\n executePendingCodeAgentApproval,\n type ExecuteCodeAgentRunOptions,\n} from \"../cli/code-agent-executor.js\";\n"]}