@mariozechner/pi-web-ui 0.5.44 → 0.5.46

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 (346) hide show
  1. package/README.md +178 -99
  2. package/dist/ChatPanel.d.ts +15 -10
  3. package/dist/ChatPanel.d.ts.map +1 -1
  4. package/dist/ChatPanel.js +68 -100
  5. package/dist/ChatPanel.js.map +1 -1
  6. package/dist/{state/agent-session.d.ts → agent/agent.d.ts} +23 -19
  7. package/dist/agent/agent.d.ts.map +1 -0
  8. package/dist/{state/agent-session.js → agent/agent.js} +50 -32
  9. package/dist/agent/agent.js.map +1 -0
  10. package/dist/{state → agent}/transports/AppTransport.d.ts +1 -3
  11. package/dist/agent/transports/AppTransport.d.ts.map +1 -0
  12. package/dist/{state → agent}/transports/AppTransport.js +5 -4
  13. package/dist/{state → agent}/transports/AppTransport.js.map +1 -1
  14. package/dist/{state → agent}/transports/ProviderTransport.d.ts +1 -3
  15. package/dist/agent/transports/ProviderTransport.d.ts.map +1 -0
  16. package/dist/{state → agent}/transports/ProviderTransport.js +6 -7
  17. package/dist/agent/transports/ProviderTransport.js.map +1 -0
  18. package/dist/{state → agent}/transports/index.d.ts.map +1 -1
  19. package/dist/agent/transports/index.js.map +1 -0
  20. package/dist/{state → agent}/transports/proxy-types.d.ts.map +1 -1
  21. package/dist/agent/transports/proxy-types.js.map +1 -0
  22. package/dist/agent/transports/types.d.ts +12 -0
  23. package/dist/agent/transports/types.d.ts.map +1 -0
  24. package/dist/{state → agent}/transports/types.js.map +1 -1
  25. package/dist/{state → agent}/types.d.ts.map +1 -1
  26. package/dist/{state → agent}/types.js.map +1 -1
  27. package/dist/app.css +1 -1
  28. package/dist/components/AgentInterface.d.ts +7 -4
  29. package/dist/components/AgentInterface.d.ts.map +1 -1
  30. package/dist/components/AgentInterface.js +29 -17
  31. package/dist/components/AgentInterface.js.map +1 -1
  32. package/dist/components/ConsoleBlock.d.ts +1 -0
  33. package/dist/components/ConsoleBlock.d.ts.map +1 -1
  34. package/dist/components/ConsoleBlock.js +7 -1
  35. package/dist/components/ConsoleBlock.js.map +1 -1
  36. package/dist/components/ExpandableSection.d.ts +15 -0
  37. package/dist/components/ExpandableSection.d.ts.map +1 -0
  38. package/dist/components/ExpandableSection.js +63 -0
  39. package/dist/components/ExpandableSection.js.map +1 -0
  40. package/dist/components/MessageEditor.d.ts +8 -1
  41. package/dist/components/MessageEditor.d.ts.map +1 -1
  42. package/dist/components/MessageEditor.js +149 -6
  43. package/dist/components/MessageEditor.js.map +1 -1
  44. package/dist/components/MessageList.d.ts +3 -2
  45. package/dist/components/MessageList.d.ts.map +1 -1
  46. package/dist/components/MessageList.js +14 -1
  47. package/dist/components/MessageList.js.map +1 -1
  48. package/dist/components/Messages.d.ts +15 -6
  49. package/dist/components/Messages.d.ts.map +1 -1
  50. package/dist/components/Messages.js +17 -83
  51. package/dist/components/Messages.js.map +1 -1
  52. package/dist/components/ProviderKeyInput.d.ts.map +1 -1
  53. package/dist/components/ProviderKeyInput.js +6 -5
  54. package/dist/components/ProviderKeyInput.js.map +1 -1
  55. package/dist/components/SandboxedIframe.d.ts +29 -7
  56. package/dist/components/SandboxedIframe.d.ts.map +1 -1
  57. package/dist/components/SandboxedIframe.js +350 -282
  58. package/dist/components/SandboxedIframe.js.map +1 -1
  59. package/dist/components/message-renderer-registry.d.ts +12 -0
  60. package/dist/components/message-renderer-registry.d.ts.map +1 -0
  61. package/dist/components/message-renderer-registry.js +12 -0
  62. package/dist/components/message-renderer-registry.js.map +1 -0
  63. package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts +35 -0
  64. package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts.map +1 -0
  65. package/dist/components/sandbox/ArtifactsRuntimeProvider.js +189 -0
  66. package/dist/components/sandbox/ArtifactsRuntimeProvider.js.map +1 -0
  67. package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts +17 -0
  68. package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts.map +1 -0
  69. package/dist/components/sandbox/AttachmentsRuntimeProvider.js +64 -0
  70. package/dist/components/sandbox/AttachmentsRuntimeProvider.js.map +1 -0
  71. package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts +42 -0
  72. package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts.map +1 -0
  73. package/dist/components/sandbox/ConsoleRuntimeProvider.js +161 -0
  74. package/dist/components/sandbox/ConsoleRuntimeProvider.js.map +1 -0
  75. package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts +30 -0
  76. package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts.map +1 -0
  77. package/dist/components/sandbox/FileDownloadRuntimeProvider.js +97 -0
  78. package/dist/components/sandbox/FileDownloadRuntimeProvider.js.map +1 -0
  79. package/dist/components/sandbox/RuntimeMessageBridge.d.ts +19 -0
  80. package/dist/components/sandbox/RuntimeMessageBridge.d.ts.map +1 -0
  81. package/dist/components/sandbox/RuntimeMessageBridge.js +74 -0
  82. package/dist/components/sandbox/RuntimeMessageBridge.js.map +1 -0
  83. package/dist/components/sandbox/RuntimeMessageRouter.d.ts +65 -0
  84. package/dist/components/sandbox/RuntimeMessageRouter.d.ts.map +1 -0
  85. package/dist/components/sandbox/RuntimeMessageRouter.js +168 -0
  86. package/dist/components/sandbox/RuntimeMessageRouter.js.map +1 -0
  87. package/dist/components/sandbox/SandboxRuntimeProvider.d.ts +33 -0
  88. package/dist/components/sandbox/SandboxRuntimeProvider.d.ts.map +1 -0
  89. package/dist/components/sandbox/SandboxRuntimeProvider.js +2 -0
  90. package/dist/components/sandbox/SandboxRuntimeProvider.js.map +1 -0
  91. package/dist/dialogs/ApiKeyPromptDialog.d.ts.map +1 -1
  92. package/dist/dialogs/ApiKeyPromptDialog.js +2 -5
  93. package/dist/dialogs/ApiKeyPromptDialog.js.map +1 -1
  94. package/dist/dialogs/ModelSelector.js.map +1 -1
  95. package/dist/dialogs/PersistentStorageDialog.d.ts +17 -0
  96. package/dist/dialogs/PersistentStorageDialog.d.ts.map +1 -0
  97. package/dist/dialogs/PersistentStorageDialog.js +144 -0
  98. package/dist/dialogs/PersistentStorageDialog.js.map +1 -0
  99. package/dist/dialogs/SessionListDialog.d.ts +19 -0
  100. package/dist/dialogs/SessionListDialog.d.ts.map +1 -0
  101. package/dist/dialogs/SessionListDialog.js +152 -0
  102. package/dist/dialogs/SessionListDialog.js.map +1 -0
  103. package/dist/dialogs/SettingsDialog.d.ts.map +1 -1
  104. package/dist/dialogs/SettingsDialog.js +1 -0
  105. package/dist/dialogs/SettingsDialog.js.map +1 -1
  106. package/dist/index.d.ts +34 -16
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +32 -14
  109. package/dist/index.js.map +1 -1
  110. package/dist/prompts/prompts.d.ts +11 -0
  111. package/dist/prompts/prompts.d.ts.map +1 -0
  112. package/dist/prompts/prompts.js +272 -0
  113. package/dist/prompts/prompts.js.map +1 -0
  114. package/dist/storage/app-storage.d.ts +17 -12
  115. package/dist/storage/app-storage.d.ts.map +1 -1
  116. package/dist/storage/app-storage.js +13 -20
  117. package/dist/storage/app-storage.js.map +1 -1
  118. package/dist/storage/backends/indexeddb-storage-backend.d.ts +27 -0
  119. package/dist/storage/backends/indexeddb-storage-backend.d.ts.map +1 -0
  120. package/dist/storage/backends/indexeddb-storage-backend.js +166 -0
  121. package/dist/storage/backends/indexeddb-storage-backend.js.map +1 -0
  122. package/dist/storage/store.d.ts +23 -0
  123. package/dist/storage/store.d.ts.map +1 -0
  124. package/dist/storage/store.js +26 -0
  125. package/dist/storage/store.js.map +1 -0
  126. package/dist/storage/stores/provider-keys-store.d.ts +14 -0
  127. package/dist/storage/stores/provider-keys-store.d.ts.map +1 -0
  128. package/dist/storage/stores/provider-keys-store.js +27 -0
  129. package/dist/storage/stores/provider-keys-store.js.map +1 -0
  130. package/dist/storage/stores/sessions-store.d.ts +31 -0
  131. package/dist/storage/stores/sessions-store.d.ts.map +1 -0
  132. package/dist/storage/stores/sessions-store.js +113 -0
  133. package/dist/storage/stores/sessions-store.js.map +1 -0
  134. package/dist/storage/stores/settings-store.d.ts +14 -0
  135. package/dist/storage/stores/settings-store.d.ts.map +1 -0
  136. package/dist/storage/stores/settings-store.js +28 -0
  137. package/dist/storage/stores/settings-store.js.map +1 -0
  138. package/dist/storage/types.d.ts +156 -22
  139. package/dist/storage/types.d.ts.map +1 -1
  140. package/dist/tools/artifacts/ArtifactElement.d.ts +0 -1
  141. package/dist/tools/artifacts/ArtifactElement.d.ts.map +1 -1
  142. package/dist/tools/artifacts/ArtifactElement.js +0 -1
  143. package/dist/tools/artifacts/ArtifactElement.js.map +1 -1
  144. package/dist/tools/artifacts/ArtifactPill.d.ts +4 -0
  145. package/dist/tools/artifacts/ArtifactPill.d.ts.map +1 -0
  146. package/dist/tools/artifacts/ArtifactPill.js +22 -0
  147. package/dist/tools/artifacts/ArtifactPill.js.map +1 -0
  148. package/dist/tools/artifacts/Console.d.ts +18 -0
  149. package/dist/tools/artifacts/Console.d.ts.map +1 -0
  150. package/dist/tools/artifacts/Console.js +95 -0
  151. package/dist/tools/artifacts/Console.js.map +1 -0
  152. package/dist/tools/artifacts/DocxArtifact.d.ts +22 -0
  153. package/dist/tools/artifacts/DocxArtifact.d.ts.map +1 -0
  154. package/dist/tools/artifacts/DocxArtifact.js +208 -0
  155. package/dist/tools/artifacts/DocxArtifact.js.map +1 -0
  156. package/dist/tools/artifacts/ExcelArtifact.d.ts +24 -0
  157. package/dist/tools/artifacts/ExcelArtifact.d.ts.map +1 -0
  158. package/dist/tools/artifacts/ExcelArtifact.js +216 -0
  159. package/dist/tools/artifacts/ExcelArtifact.js.map +1 -0
  160. package/dist/tools/artifacts/GenericArtifact.d.ts +19 -0
  161. package/dist/tools/artifacts/GenericArtifact.d.ts.map +1 -0
  162. package/dist/tools/artifacts/GenericArtifact.js +117 -0
  163. package/dist/tools/artifacts/GenericArtifact.js.map +1 -0
  164. package/dist/tools/artifacts/HtmlArtifact.d.ts +8 -11
  165. package/dist/tools/artifacts/HtmlArtifact.d.ts.map +1 -1
  166. package/dist/tools/artifacts/HtmlArtifact.js +56 -88
  167. package/dist/tools/artifacts/HtmlArtifact.js.map +1 -1
  168. package/dist/tools/artifacts/ImageArtifact.d.ts +20 -0
  169. package/dist/tools/artifacts/ImageArtifact.d.ts.map +1 -0
  170. package/dist/tools/artifacts/ImageArtifact.js +120 -0
  171. package/dist/tools/artifacts/ImageArtifact.js.map +1 -0
  172. package/dist/tools/artifacts/MarkdownArtifact.d.ts +0 -1
  173. package/dist/tools/artifacts/MarkdownArtifact.d.ts.map +1 -1
  174. package/dist/tools/artifacts/MarkdownArtifact.js +0 -4
  175. package/dist/tools/artifacts/MarkdownArtifact.js.map +1 -1
  176. package/dist/tools/artifacts/PdfArtifact.d.ts +25 -0
  177. package/dist/tools/artifacts/PdfArtifact.d.ts.map +1 -0
  178. package/dist/tools/artifacts/PdfArtifact.js +184 -0
  179. package/dist/tools/artifacts/PdfArtifact.js.map +1 -0
  180. package/dist/tools/artifacts/SvgArtifact.d.ts +0 -1
  181. package/dist/tools/artifacts/SvgArtifact.d.ts.map +1 -1
  182. package/dist/tools/artifacts/SvgArtifact.js +0 -4
  183. package/dist/tools/artifacts/SvgArtifact.js.map +1 -1
  184. package/dist/tools/artifacts/TextArtifact.d.ts +0 -1
  185. package/dist/tools/artifacts/TextArtifact.d.ts.map +1 -1
  186. package/dist/tools/artifacts/TextArtifact.js +0 -4
  187. package/dist/tools/artifacts/TextArtifact.js.map +1 -1
  188. package/dist/tools/artifacts/artifacts-tool-renderer.d.ts +11 -0
  189. package/dist/tools/artifacts/artifacts-tool-renderer.d.ts.map +1 -0
  190. package/dist/tools/artifacts/artifacts-tool-renderer.js +262 -0
  191. package/dist/tools/artifacts/artifacts-tool-renderer.js.map +1 -0
  192. package/dist/tools/artifacts/artifacts.d.ts +10 -13
  193. package/dist/tools/artifacts/artifacts.d.ts.map +1 -1
  194. package/dist/tools/artifacts/artifacts.js +166 -344
  195. package/dist/tools/artifacts/artifacts.js.map +1 -1
  196. package/dist/tools/artifacts/index.d.ts +1 -0
  197. package/dist/tools/artifacts/index.d.ts.map +1 -1
  198. package/dist/tools/artifacts/index.js +1 -0
  199. package/dist/tools/artifacts/index.js.map +1 -1
  200. package/dist/tools/extract-document.d.ts +24 -0
  201. package/dist/tools/extract-document.d.ts.map +1 -0
  202. package/dist/tools/extract-document.js +193 -0
  203. package/dist/tools/extract-document.js.map +1 -0
  204. package/dist/tools/index.d.ts +9 -7
  205. package/dist/tools/index.d.ts.map +1 -1
  206. package/dist/tools/index.js +17 -13
  207. package/dist/tools/index.js.map +1 -1
  208. package/dist/tools/javascript-repl.d.ts +16 -15
  209. package/dist/tools/javascript-repl.d.ts.map +1 -1
  210. package/dist/tools/javascript-repl.js +101 -133
  211. package/dist/tools/javascript-repl.js.map +1 -1
  212. package/dist/tools/renderer-registry.d.ts +12 -0
  213. package/dist/tools/renderer-registry.d.ts.map +1 -1
  214. package/dist/tools/renderer-registry.js +78 -0
  215. package/dist/tools/renderer-registry.js.map +1 -1
  216. package/dist/tools/renderers/BashRenderer.d.ts +2 -4
  217. package/dist/tools/renderers/BashRenderer.d.ts.map +1 -1
  218. package/dist/tools/renderers/BashRenderer.js +30 -26
  219. package/dist/tools/renderers/BashRenderer.js.map +1 -1
  220. package/dist/tools/renderers/CalculateRenderer.d.ts +2 -4
  221. package/dist/tools/renderers/CalculateRenderer.d.ts.map +1 -1
  222. package/dist/tools/renderers/CalculateRenderer.js +32 -28
  223. package/dist/tools/renderers/CalculateRenderer.js.map +1 -1
  224. package/dist/tools/renderers/DefaultRenderer.d.ts +2 -4
  225. package/dist/tools/renderers/DefaultRenderer.d.ts.map +1 -1
  226. package/dist/tools/renderers/DefaultRenderer.js +78 -18
  227. package/dist/tools/renderers/DefaultRenderer.js.map +1 -1
  228. package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts +2 -4
  229. package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts.map +1 -1
  230. package/dist/tools/renderers/GetCurrentTimeRenderer.js +57 -21
  231. package/dist/tools/renderers/GetCurrentTimeRenderer.js.map +1 -1
  232. package/dist/tools/types.d.ts +5 -2
  233. package/dist/tools/types.d.ts.map +1 -1
  234. package/dist/utils/i18n.d.ts +424 -1
  235. package/dist/utils/i18n.d.ts.map +1 -1
  236. package/dist/utils/i18n.js +131 -7
  237. package/dist/utils/i18n.js.map +1 -1
  238. package/example/package.json +2 -1
  239. package/example/src/custom-messages.ts +112 -0
  240. package/example/src/main.ts +391 -38
  241. package/package.json +48 -43
  242. package/scripts/count-prompt-tokens.ts +88 -0
  243. package/src/ChatPanel.ts +93 -101
  244. package/src/{state/agent-session.ts → agent/agent.ts} +80 -55
  245. package/src/{state → agent}/transports/AppTransport.ts +6 -6
  246. package/src/{state → agent}/transports/ProviderTransport.ts +13 -7
  247. package/src/{state → agent}/transports/types.ts +8 -2
  248. package/src/components/AgentInterface.ts +32 -16
  249. package/src/components/ConsoleBlock.ts +5 -1
  250. package/src/components/ExpandableSection.ts +46 -0
  251. package/src/components/MessageEditor.ts +159 -5
  252. package/src/components/MessageList.ts +18 -3
  253. package/src/components/Messages.ts +48 -89
  254. package/src/components/ProviderKeyInput.ts +6 -5
  255. package/src/components/SandboxedIframe.ts +412 -321
  256. package/src/components/message-renderer-registry.ts +28 -0
  257. package/src/components/sandbox/ArtifactsRuntimeProvider.ts +219 -0
  258. package/src/components/sandbox/AttachmentsRuntimeProvider.ts +66 -0
  259. package/src/components/sandbox/ConsoleRuntimeProvider.ts +187 -0
  260. package/src/components/sandbox/FileDownloadRuntimeProvider.ts +110 -0
  261. package/src/components/sandbox/RuntimeMessageBridge.ts +82 -0
  262. package/src/components/sandbox/RuntimeMessageRouter.ts +216 -0
  263. package/src/components/sandbox/SandboxRuntimeProvider.ts +35 -0
  264. package/src/dialogs/ApiKeyPromptDialog.ts +2 -5
  265. package/src/dialogs/ModelSelector.ts +2 -2
  266. package/src/dialogs/PersistentStorageDialog.ts +141 -0
  267. package/src/dialogs/SessionListDialog.ts +148 -0
  268. package/src/dialogs/SettingsDialog.ts +1 -0
  269. package/src/index.ts +61 -20
  270. package/src/prompts/prompts.ts +282 -0
  271. package/src/storage/app-storage.ts +27 -24
  272. package/src/storage/backends/indexeddb-storage-backend.ts +193 -0
  273. package/src/storage/store.ts +33 -0
  274. package/src/storage/stores/provider-keys-store.ts +33 -0
  275. package/src/storage/stores/sessions-store.ts +130 -0
  276. package/src/storage/stores/settings-store.ts +34 -0
  277. package/src/storage/types.ts +182 -22
  278. package/src/tools/artifacts/ArtifactElement.ts +0 -1
  279. package/src/tools/artifacts/ArtifactPill.ts +25 -0
  280. package/src/tools/artifacts/Console.ts +93 -0
  281. package/src/tools/artifacts/DocxArtifact.ts +213 -0
  282. package/src/tools/artifacts/ExcelArtifact.ts +231 -0
  283. package/src/tools/artifacts/GenericArtifact.ts +117 -0
  284. package/src/tools/artifacts/HtmlArtifact.ts +64 -94
  285. package/src/tools/artifacts/ImageArtifact.ts +116 -0
  286. package/src/tools/artifacts/MarkdownArtifact.ts +0 -1
  287. package/src/tools/artifacts/PdfArtifact.ts +201 -0
  288. package/src/tools/artifacts/SvgArtifact.ts +0 -1
  289. package/src/tools/artifacts/TextArtifact.ts +0 -1
  290. package/src/tools/artifacts/artifacts-tool-renderer.ts +298 -0
  291. package/src/tools/artifacts/artifacts.ts +190 -366
  292. package/src/tools/artifacts/index.ts +1 -0
  293. package/src/tools/extract-document.ts +250 -0
  294. package/src/tools/index.ts +25 -14
  295. package/src/tools/javascript-repl.ts +138 -160
  296. package/src/tools/renderer-registry.ts +98 -0
  297. package/src/tools/renderers/BashRenderer.ts +33 -30
  298. package/src/tools/renderers/CalculateRenderer.ts +36 -31
  299. package/src/tools/renderers/DefaultRenderer.ts +84 -21
  300. package/src/tools/renderers/GetCurrentTimeRenderer.ts +68 -23
  301. package/src/tools/types.ts +10 -2
  302. package/src/utils/i18n.ts +203 -8
  303. package/dist/state/agent-session.d.ts.map +0 -1
  304. package/dist/state/agent-session.js.map +0 -1
  305. package/dist/state/transports/AppTransport.d.ts.map +0 -1
  306. package/dist/state/transports/ProviderTransport.d.ts.map +0 -1
  307. package/dist/state/transports/ProviderTransport.js.map +0 -1
  308. package/dist/state/transports/index.js.map +0 -1
  309. package/dist/state/transports/proxy-types.js.map +0 -1
  310. package/dist/state/transports/types.d.ts +0 -11
  311. package/dist/state/transports/types.d.ts.map +0 -1
  312. package/dist/storage/backends/chrome-storage-backend.d.ts +0 -18
  313. package/dist/storage/backends/chrome-storage-backend.d.ts.map +0 -1
  314. package/dist/storage/backends/chrome-storage-backend.js +0 -67
  315. package/dist/storage/backends/chrome-storage-backend.js.map +0 -1
  316. package/dist/storage/backends/indexeddb-backend.d.ts +0 -20
  317. package/dist/storage/backends/indexeddb-backend.d.ts.map +0 -1
  318. package/dist/storage/backends/indexeddb-backend.js +0 -89
  319. package/dist/storage/backends/indexeddb-backend.js.map +0 -1
  320. package/dist/storage/backends/local-storage-backend.d.ts +0 -18
  321. package/dist/storage/backends/local-storage-backend.d.ts.map +0 -1
  322. package/dist/storage/backends/local-storage-backend.js +0 -69
  323. package/dist/storage/backends/local-storage-backend.js.map +0 -1
  324. package/dist/storage/repositories/provider-keys-repository.d.ts +0 -34
  325. package/dist/storage/repositories/provider-keys-repository.d.ts.map +0 -1
  326. package/dist/storage/repositories/provider-keys-repository.js +0 -50
  327. package/dist/storage/repositories/provider-keys-repository.js.map +0 -1
  328. package/dist/storage/repositories/settings-repository.d.ts +0 -34
  329. package/dist/storage/repositories/settings-repository.d.ts.map +0 -1
  330. package/dist/storage/repositories/settings-repository.js +0 -46
  331. package/dist/storage/repositories/settings-repository.js.map +0 -1
  332. package/src/storage/backends/chrome-storage-backend.ts +0 -82
  333. package/src/storage/backends/indexeddb-backend.ts +0 -107
  334. package/src/storage/backends/local-storage-backend.ts +0 -74
  335. package/src/storage/repositories/provider-keys-repository.ts +0 -55
  336. package/src/storage/repositories/settings-repository.ts +0 -51
  337. /package/dist/{state → agent}/transports/index.d.ts +0 -0
  338. /package/dist/{state → agent}/transports/index.js +0 -0
  339. /package/dist/{state → agent}/transports/proxy-types.d.ts +0 -0
  340. /package/dist/{state → agent}/transports/proxy-types.js +0 -0
  341. /package/dist/{state → agent}/transports/types.js +0 -0
  342. /package/dist/{state → agent}/types.d.ts +0 -0
  343. /package/dist/{state → agent}/types.js +0 -0
  344. /package/src/{state → agent}/transports/index.ts +0 -0
  345. /package/src/{state → agent}/transports/proxy-types.ts +0 -0
  346. /package/src/{state → agent}/types.ts +0 -0
@@ -0,0 +1,28 @@
1
+ import type { TemplateResult } from "lit";
2
+ import type { AppMessage } from "./Messages.js";
3
+
4
+ // Extract role type from AppMessage union
5
+ export type MessageRole = AppMessage["role"];
6
+
7
+ // Generic message renderer typed to specific message type
8
+ export interface MessageRenderer<TMessage extends AppMessage = AppMessage> {
9
+ render(message: TMessage): TemplateResult;
10
+ }
11
+
12
+ // Registry of custom message renderers by role
13
+ const messageRenderers = new Map<MessageRole, MessageRenderer<any>>();
14
+
15
+ export function registerMessageRenderer<TRole extends MessageRole>(
16
+ role: TRole,
17
+ renderer: MessageRenderer<Extract<AppMessage, { role: TRole }>>,
18
+ ): void {
19
+ messageRenderers.set(role, renderer);
20
+ }
21
+
22
+ export function getMessageRenderer(role: MessageRole): MessageRenderer | undefined {
23
+ return messageRenderers.get(role);
24
+ }
25
+
26
+ export function renderMessage(message: AppMessage): TemplateResult | undefined {
27
+ return messageRenderers.get(message.role)?.render(message);
28
+ }
@@ -0,0 +1,219 @@
1
+ import {
2
+ ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO,
3
+ ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RW,
4
+ } from "../../prompts/prompts.js";
5
+ import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
6
+
7
+ // Define minimal interface for ArtifactsPanel to avoid circular dependencies
8
+ interface ArtifactsPanelLike {
9
+ artifacts: Map<string, { content: string }>;
10
+ tool: {
11
+ execute(toolCallId: string, args: { command: string; filename: string; content?: string }): Promise<any>;
12
+ };
13
+ }
14
+
15
+ interface AgentLike {
16
+ appendMessage(message: any): void;
17
+ }
18
+
19
+ /**
20
+ * Artifacts Runtime Provider
21
+ *
22
+ * Provides programmatic access to session artifacts from sandboxed code.
23
+ * Allows code to create, read, update, and delete artifacts dynamically.
24
+ * Supports both online (extension) and offline (downloaded HTML) modes.
25
+ */
26
+ export class ArtifactsRuntimeProvider implements SandboxRuntimeProvider {
27
+ constructor(
28
+ private artifactsPanel: ArtifactsPanelLike,
29
+ private agent?: AgentLike,
30
+ private readWrite: boolean = true,
31
+ ) {}
32
+
33
+ getData(): Record<string, any> {
34
+ // Inject artifact snapshot for offline mode
35
+ const snapshot: Record<string, string> = {};
36
+ this.artifactsPanel.artifacts.forEach((artifact, filename) => {
37
+ snapshot[filename] = artifact.content;
38
+ });
39
+ return { artifacts: snapshot };
40
+ }
41
+
42
+ getRuntime(): (sandboxId: string) => void {
43
+ // This function will be stringified, so no external references!
44
+ return (_sandboxId: string) => {
45
+ // Auto-parse/stringify for .json files
46
+ const isJsonFile = (filename: string) => filename.endsWith(".json");
47
+
48
+ (window as any).listArtifacts = async (): Promise<string[]> => {
49
+ // Online: ask extension
50
+ if ((window as any).sendRuntimeMessage) {
51
+ const response = await (window as any).sendRuntimeMessage({
52
+ type: "artifact-operation",
53
+ action: "list",
54
+ });
55
+ if (!response.success) throw new Error(response.error);
56
+ return response.result;
57
+ }
58
+ // Offline: return snapshot keys
59
+ else {
60
+ return Object.keys((window as any).artifacts || {});
61
+ }
62
+ };
63
+
64
+ (window as any).getArtifact = async (filename: string): Promise<any> => {
65
+ let content: string;
66
+
67
+ // Online: ask extension
68
+ if ((window as any).sendRuntimeMessage) {
69
+ const response = await (window as any).sendRuntimeMessage({
70
+ type: "artifact-operation",
71
+ action: "get",
72
+ filename,
73
+ });
74
+ if (!response.success) throw new Error(response.error);
75
+ content = response.result;
76
+ }
77
+ // Offline: read snapshot
78
+ else {
79
+ if (!(window as any).artifacts?.[filename]) {
80
+ throw new Error(`Artifact not found (offline mode): ${filename}`);
81
+ }
82
+ content = (window as any).artifacts[filename];
83
+ }
84
+
85
+ // Auto-parse .json files
86
+ if (isJsonFile(filename)) {
87
+ try {
88
+ return JSON.parse(content);
89
+ } catch (e) {
90
+ throw new Error(`Failed to parse JSON from ${filename}: ${e}`);
91
+ }
92
+ }
93
+ return content;
94
+ };
95
+
96
+ (window as any).createOrUpdateArtifact = async (
97
+ filename: string,
98
+ content: any,
99
+ mimeType?: string,
100
+ ): Promise<void> => {
101
+ if (!(window as any).sendRuntimeMessage) {
102
+ throw new Error("Cannot create/update artifacts in offline mode (read-only)");
103
+ }
104
+
105
+ let finalContent = content;
106
+ // Auto-stringify .json files
107
+ if (isJsonFile(filename) && typeof content !== "string") {
108
+ finalContent = JSON.stringify(content, null, 2);
109
+ } else if (typeof content !== "string") {
110
+ finalContent = JSON.stringify(content, null, 2);
111
+ }
112
+
113
+ const response = await (window as any).sendRuntimeMessage({
114
+ type: "artifact-operation",
115
+ action: "createOrUpdate",
116
+ filename,
117
+ content: finalContent,
118
+ mimeType,
119
+ });
120
+ if (!response.success) throw new Error(response.error);
121
+ };
122
+
123
+ (window as any).deleteArtifact = async (filename: string): Promise<void> => {
124
+ if (!(window as any).sendRuntimeMessage) {
125
+ throw new Error("Cannot delete artifacts in offline mode (read-only)");
126
+ }
127
+
128
+ const response = await (window as any).sendRuntimeMessage({
129
+ type: "artifact-operation",
130
+ action: "delete",
131
+ filename,
132
+ });
133
+ if (!response.success) throw new Error(response.error);
134
+ };
135
+ };
136
+ }
137
+
138
+ async handleMessage(message: any, respond: (response: any) => void): Promise<void> {
139
+ if (message.type !== "artifact-operation") {
140
+ return;
141
+ }
142
+
143
+ const { action, filename, content, mimeType } = message;
144
+
145
+ try {
146
+ switch (action) {
147
+ case "list": {
148
+ const filenames = Array.from(this.artifactsPanel.artifacts.keys());
149
+ respond({ success: true, result: filenames });
150
+ break;
151
+ }
152
+
153
+ case "get": {
154
+ const artifact = this.artifactsPanel.artifacts.get(filename);
155
+ if (!artifact) {
156
+ respond({ success: false, error: `Artifact not found: ${filename}` });
157
+ } else {
158
+ respond({ success: true, result: artifact.content });
159
+ }
160
+ break;
161
+ }
162
+
163
+ case "createOrUpdate": {
164
+ try {
165
+ const exists = this.artifactsPanel.artifacts.has(filename);
166
+ const command = exists ? "rewrite" : "create";
167
+ const action = exists ? "update" : "create";
168
+
169
+ await this.artifactsPanel.tool.execute("", {
170
+ command,
171
+ filename,
172
+ content,
173
+ });
174
+ this.agent?.appendMessage({
175
+ role: "artifact",
176
+ action,
177
+ filename,
178
+ content,
179
+ ...(action === "create" && { title: filename }),
180
+ timestamp: new Date().toISOString(),
181
+ });
182
+ respond({ success: true });
183
+ } catch (err: any) {
184
+ respond({ success: false, error: err.message });
185
+ }
186
+ break;
187
+ }
188
+
189
+ case "delete": {
190
+ try {
191
+ await this.artifactsPanel.tool.execute("", {
192
+ command: "delete",
193
+ filename,
194
+ });
195
+ this.agent?.appendMessage({
196
+ role: "artifact",
197
+ action: "delete",
198
+ filename,
199
+ timestamp: new Date().toISOString(),
200
+ });
201
+ respond({ success: true });
202
+ } catch (err: any) {
203
+ respond({ success: false, error: err.message });
204
+ }
205
+ break;
206
+ }
207
+
208
+ default:
209
+ respond({ success: false, error: `Unknown artifact action: ${action}` });
210
+ }
211
+ } catch (error: any) {
212
+ respond({ success: false, error: error.message });
213
+ }
214
+ }
215
+
216
+ getDescription(): string {
217
+ return this.readWrite ? ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RW : ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO;
218
+ }
219
+ }
@@ -0,0 +1,66 @@
1
+ import { ATTACHMENTS_RUNTIME_DESCRIPTION } from "../../prompts/prompts.js";
2
+ import type { Attachment } from "../../utils/attachment-utils.js";
3
+ import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
4
+
5
+ /**
6
+ * Attachments Runtime Provider
7
+ *
8
+ * OPTIONAL provider that provides file access APIs to sandboxed code.
9
+ * Only needed when attachments are present.
10
+ * Attachments are read-only snapshot data - no messaging needed.
11
+ */
12
+ export class AttachmentsRuntimeProvider implements SandboxRuntimeProvider {
13
+ constructor(private attachments: Attachment[]) {}
14
+
15
+ getData(): Record<string, any> {
16
+ const attachmentsData = this.attachments.map((a) => ({
17
+ id: a.id,
18
+ fileName: a.fileName,
19
+ mimeType: a.mimeType,
20
+ size: a.size,
21
+ content: a.content,
22
+ extractedText: a.extractedText,
23
+ }));
24
+
25
+ return { attachments: attachmentsData };
26
+ }
27
+
28
+ getRuntime(): (sandboxId: string) => void {
29
+ // This function will be stringified, so no external references!
30
+ // These functions read directly from window.attachments
31
+ // Works both online AND offline (no messaging needed!)
32
+ return (_sandboxId: string) => {
33
+ (window as any).listAttachments = () =>
34
+ ((window as any).attachments || []).map((a: any) => ({
35
+ id: a.id,
36
+ fileName: a.fileName,
37
+ mimeType: a.mimeType,
38
+ size: a.size,
39
+ }));
40
+
41
+ (window as any).readTextAttachment = (attachmentId: string) => {
42
+ const a = ((window as any).attachments || []).find((x: any) => x.id === attachmentId);
43
+ if (!a) throw new Error("Attachment not found: " + attachmentId);
44
+ if (a.extractedText) return a.extractedText;
45
+ try {
46
+ return atob(a.content);
47
+ } catch {
48
+ throw new Error("Failed to decode text content for: " + attachmentId);
49
+ }
50
+ };
51
+
52
+ (window as any).readBinaryAttachment = (attachmentId: string) => {
53
+ const a = ((window as any).attachments || []).find((x: any) => x.id === attachmentId);
54
+ if (!a) throw new Error("Attachment not found: " + attachmentId);
55
+ const bin = atob(a.content);
56
+ const bytes = new Uint8Array(bin.length);
57
+ for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
58
+ return bytes;
59
+ };
60
+ };
61
+ }
62
+
63
+ getDescription(): string {
64
+ return ATTACHMENTS_RUNTIME_DESCRIPTION;
65
+ }
66
+ }
@@ -0,0 +1,187 @@
1
+ import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
2
+
3
+ export interface ConsoleLog {
4
+ type: "log" | "warn" | "error" | "info";
5
+ text: string;
6
+ args?: unknown[];
7
+ }
8
+
9
+ /**
10
+ * Console Runtime Provider
11
+ *
12
+ * REQUIRED provider that should always be included first.
13
+ * Provides console capture, error handling, and execution lifecycle management.
14
+ * Collects console output for retrieval by caller.
15
+ */
16
+ export class ConsoleRuntimeProvider implements SandboxRuntimeProvider {
17
+ private logs: ConsoleLog[] = [];
18
+ private completionError: { message: string; stack: string } | null = null;
19
+ private completed = false;
20
+
21
+ getData(): Record<string, any> {
22
+ // No data needed
23
+ return {};
24
+ }
25
+
26
+ getDescription(): string {
27
+ return "";
28
+ }
29
+
30
+ getRuntime(): (sandboxId: string) => void {
31
+ return (_sandboxId: string) => {
32
+ // Store truly original console methods on first wrap only
33
+ // This prevents accumulation of wrapper functions across multiple executions
34
+ if (!(window as any).__originalConsole) {
35
+ (window as any).__originalConsole = {
36
+ log: console.log.bind(console),
37
+ error: console.error.bind(console),
38
+ warn: console.warn.bind(console),
39
+ info: console.info.bind(console),
40
+ };
41
+ }
42
+
43
+ // Always use the truly original console, not the current (possibly wrapped) one
44
+ const originalConsole = (window as any).__originalConsole;
45
+
46
+ // Track pending send promises to wait for them in onCompleted
47
+ const pendingSends: Promise<any>[] = [];
48
+
49
+ ["log", "error", "warn", "info"].forEach((method) => {
50
+ (console as any)[method] = (...args: any[]) => {
51
+ const text = args
52
+ .map((arg) => {
53
+ try {
54
+ return typeof arg === "object" ? JSON.stringify(arg) : String(arg);
55
+ } catch {
56
+ return String(arg);
57
+ }
58
+ })
59
+ .join(" ");
60
+
61
+ // Always log locally too (using truly original console)
62
+ (originalConsole as any)[method].apply(console, args);
63
+
64
+ // Send immediately and track the promise (only in extension context)
65
+ if ((window as any).sendRuntimeMessage) {
66
+ const sendPromise = (window as any)
67
+ .sendRuntimeMessage({
68
+ type: "console",
69
+ method,
70
+ text,
71
+ args,
72
+ })
73
+ .catch(() => {});
74
+ pendingSends.push(sendPromise);
75
+ }
76
+ };
77
+ });
78
+
79
+ // Register completion callback to wait for all pending sends
80
+ if ((window as any).onCompleted) {
81
+ (window as any).onCompleted(async (_success: boolean) => {
82
+ // Wait for all pending console sends to complete
83
+ if (pendingSends.length > 0) {
84
+ await Promise.all(pendingSends);
85
+ }
86
+ });
87
+ }
88
+
89
+ // Track errors for HTML artifacts
90
+ let lastError: { message: string; stack: string } | null = null;
91
+
92
+ // Error handlers - track errors but don't log them
93
+ // (they'll be shown via execution-error message)
94
+ window.addEventListener("error", (e) => {
95
+ const text =
96
+ (e.error?.stack || e.message || String(e)) + " at line " + (e.lineno || "?") + ":" + (e.colno || "?");
97
+
98
+ lastError = {
99
+ message: e.error?.message || e.message || String(e),
100
+ stack: e.error?.stack || text,
101
+ };
102
+ });
103
+
104
+ window.addEventListener("unhandledrejection", (e) => {
105
+ const text = "Unhandled promise rejection: " + (e.reason?.message || e.reason || "Unknown error");
106
+
107
+ lastError = {
108
+ message: e.reason?.message || String(e.reason) || "Unhandled promise rejection",
109
+ stack: e.reason?.stack || text,
110
+ };
111
+ });
112
+
113
+ // Expose complete() method for user code to call
114
+ let completionSent = false;
115
+ (window as any).complete = async (error?: { message: string; stack: string }, returnValue?: any) => {
116
+ if (completionSent) return;
117
+ completionSent = true;
118
+
119
+ const finalError = error || lastError;
120
+
121
+ if ((window as any).sendRuntimeMessage) {
122
+ if (finalError) {
123
+ await (window as any).sendRuntimeMessage({
124
+ type: "execution-error",
125
+ error: finalError,
126
+ });
127
+ } else {
128
+ await (window as any).sendRuntimeMessage({
129
+ type: "execution-complete",
130
+ returnValue,
131
+ });
132
+ }
133
+ }
134
+ };
135
+ };
136
+ }
137
+
138
+ async handleMessage(message: any, respond: (response: any) => void): Promise<void> {
139
+ if (message.type === "console") {
140
+ // Collect console output
141
+ this.logs.push({
142
+ type:
143
+ message.method === "error"
144
+ ? "error"
145
+ : message.method === "warn"
146
+ ? "warn"
147
+ : message.method === "info"
148
+ ? "info"
149
+ : "log",
150
+ text: message.text,
151
+ args: message.args,
152
+ });
153
+ // Acknowledge receipt
154
+ respond({ success: true });
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Get collected console logs
160
+ */
161
+ getLogs(): ConsoleLog[] {
162
+ return this.logs;
163
+ }
164
+
165
+ /**
166
+ * Get completion status
167
+ */
168
+ isCompleted(): boolean {
169
+ return this.completed;
170
+ }
171
+
172
+ /**
173
+ * Get completion error if any
174
+ */
175
+ getCompletionError(): { message: string; stack: string } | null {
176
+ return this.completionError;
177
+ }
178
+
179
+ /**
180
+ * Reset state for reuse
181
+ */
182
+ reset(): void {
183
+ this.logs = [];
184
+ this.completionError = null;
185
+ this.completed = false;
186
+ }
187
+ }
@@ -0,0 +1,110 @@
1
+ import type { SandboxRuntimeProvider } from "./SandboxRuntimeProvider.js";
2
+
3
+ export interface DownloadableFile {
4
+ fileName: string;
5
+ content: string | Uint8Array;
6
+ mimeType: string;
7
+ }
8
+
9
+ /**
10
+ * File Download Runtime Provider
11
+ *
12
+ * Provides returnDownloadableFile() for creating user downloads.
13
+ * Files returned this way are NOT accessible to the LLM later (one-time download).
14
+ * Works both online (sends to extension) and offline (triggers browser download directly).
15
+ * Collects files for retrieval by caller.
16
+ */
17
+ export class FileDownloadRuntimeProvider implements SandboxRuntimeProvider {
18
+ private files: DownloadableFile[] = [];
19
+
20
+ getData(): Record<string, any> {
21
+ // No data needed
22
+ return {};
23
+ }
24
+
25
+ getRuntime(): (sandboxId: string) => void {
26
+ return (_sandboxId: string) => {
27
+ (window as any).returnDownloadableFile = async (fileName: string, content: any, mimeType?: string) => {
28
+ let finalContent: any, finalMimeType: string;
29
+
30
+ if (content instanceof Blob) {
31
+ const arrayBuffer = await content.arrayBuffer();
32
+ finalContent = new Uint8Array(arrayBuffer);
33
+ finalMimeType = mimeType || content.type || "application/octet-stream";
34
+ if (!mimeType && !content.type) {
35
+ throw new Error(
36
+ "returnDownloadableFile: MIME type is required for Blob content. Please provide a mimeType parameter (e.g., 'image/png').",
37
+ );
38
+ }
39
+ } else if (content instanceof Uint8Array) {
40
+ finalContent = content;
41
+ if (!mimeType) {
42
+ throw new Error(
43
+ "returnDownloadableFile: MIME type is required for Uint8Array content. Please provide a mimeType parameter (e.g., 'image/png').",
44
+ );
45
+ }
46
+ finalMimeType = mimeType;
47
+ } else if (typeof content === "string") {
48
+ finalContent = content;
49
+ finalMimeType = mimeType || "text/plain";
50
+ } else {
51
+ finalContent = JSON.stringify(content, null, 2);
52
+ finalMimeType = mimeType || "application/json";
53
+ }
54
+
55
+ // Send to extension if in extension context (online mode)
56
+ if ((window as any).sendRuntimeMessage) {
57
+ const response = await (window as any).sendRuntimeMessage({
58
+ type: "file-returned",
59
+ fileName,
60
+ content: finalContent,
61
+ mimeType: finalMimeType,
62
+ });
63
+ if (response.error) throw new Error(response.error);
64
+ } else {
65
+ // Offline mode: trigger browser download directly
66
+ const blob = new Blob([finalContent instanceof Uint8Array ? finalContent : finalContent], {
67
+ type: finalMimeType,
68
+ });
69
+ const url = URL.createObjectURL(blob);
70
+ const a = document.createElement("a");
71
+ a.href = url;
72
+ a.download = fileName;
73
+ a.click();
74
+ URL.revokeObjectURL(url);
75
+ }
76
+ };
77
+ };
78
+ }
79
+
80
+ async handleMessage(message: any, respond: (response: any) => void): Promise<void> {
81
+ if (message.type === "file-returned") {
82
+ // Collect file for caller
83
+ this.files.push({
84
+ fileName: message.fileName,
85
+ content: message.content,
86
+ mimeType: message.mimeType,
87
+ });
88
+
89
+ respond({ success: true });
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Get collected files
95
+ */
96
+ getFiles(): DownloadableFile[] {
97
+ return this.files;
98
+ }
99
+
100
+ /**
101
+ * Reset state for reuse
102
+ */
103
+ reset(): void {
104
+ this.files = [];
105
+ }
106
+
107
+ getDescription(): string {
108
+ return "returnDownloadableFile(filename, content, mimeType?) - Create downloadable file for user (one-time download, not accessible later)";
109
+ }
110
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Generates sendRuntimeMessage() function for injection into execution contexts.
3
+ * Provides unified messaging API that works in both sandbox iframe and user script contexts.
4
+ */
5
+
6
+ export type MessageType = "request-response" | "fire-and-forget";
7
+
8
+ export interface RuntimeMessageBridgeOptions {
9
+ context: "sandbox-iframe" | "user-script";
10
+ sandboxId: string;
11
+ }
12
+
13
+ // biome-ignore lint/complexity/noStaticOnlyClass: fine
14
+ export class RuntimeMessageBridge {
15
+ /**
16
+ * Generate sendRuntimeMessage() function as injectable string.
17
+ * Returns the function source code to be injected into target context.
18
+ */
19
+ static generateBridgeCode(options: RuntimeMessageBridgeOptions): string {
20
+ if (options.context === "sandbox-iframe") {
21
+ return RuntimeMessageBridge.generateSandboxBridge(options.sandboxId);
22
+ } else {
23
+ return RuntimeMessageBridge.generateUserScriptBridge(options.sandboxId);
24
+ }
25
+ }
26
+
27
+ private static generateSandboxBridge(sandboxId: string): string {
28
+ // Returns stringified function that uses window.parent.postMessage
29
+ return `
30
+ window.__completionCallbacks = [];
31
+ window.sendRuntimeMessage = async (message) => {
32
+ const messageId = 'msg_' + Date.now() + '_' + Math.random().toString(36).substring(2, 9);
33
+
34
+ return new Promise((resolve, reject) => {
35
+ const handler = (e) => {
36
+ if (e.data.type === 'runtime-response' && e.data.messageId === messageId) {
37
+ window.removeEventListener('message', handler);
38
+ if (e.data.success) {
39
+ resolve(e.data);
40
+ } else {
41
+ reject(new Error(e.data.error || 'Operation failed'));
42
+ }
43
+ }
44
+ };
45
+
46
+ window.addEventListener('message', handler);
47
+
48
+ window.parent.postMessage({
49
+ ...message,
50
+ sandboxId: ${JSON.stringify(sandboxId)},
51
+ messageId: messageId
52
+ }, '*');
53
+
54
+ // Timeout after 30s
55
+ setTimeout(() => {
56
+ window.removeEventListener('message', handler);
57
+ reject(new Error('Runtime message timeout'));
58
+ }, 30000);
59
+ });
60
+ };
61
+ window.onCompleted = (callback) => {
62
+ window.__completionCallbacks.push(callback);
63
+ };
64
+ `.trim();
65
+ }
66
+
67
+ private static generateUserScriptBridge(sandboxId: string): string {
68
+ // Returns stringified function that uses chrome.runtime.sendMessage
69
+ return `
70
+ window.__completionCallbacks = [];
71
+ window.sendRuntimeMessage = async (message) => {
72
+ return await chrome.runtime.sendMessage({
73
+ ...message,
74
+ sandboxId: ${JSON.stringify(sandboxId)}
75
+ });
76
+ };
77
+ window.onCompleted = (callback) => {
78
+ window.__completionCallbacks.push(callback);
79
+ };
80
+ `.trim();
81
+ }
82
+ }