@mariozechner/pi-web-ui 0.5.44 → 0.5.45

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
@@ -6,6 +6,17 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { LitElement } from "lit";
8
8
  import { customElement, property } from "lit/decorators.js";
9
+ import { ConsoleRuntimeProvider } from "./sandbox/ConsoleRuntimeProvider.js";
10
+ import { RuntimeMessageBridge } from "./sandbox/RuntimeMessageBridge.js";
11
+ import { RUNTIME_MESSAGE_ROUTER } from "./sandbox/RuntimeMessageRouter.js";
12
+ /**
13
+ * Escape HTML special sequences in code to prevent premature tag closure
14
+ * @param code Code that will be injected into <script> tags
15
+ * @returns Escaped code safe for injection
16
+ */
17
+ function escapeScriptContent(code) {
18
+ return code.replace(/<\/script/gi, "<\\/script");
19
+ }
9
20
  let SandboxIframe = class SandboxIframe extends LitElement {
10
21
  createRenderRoot() {
11
22
  return this;
@@ -15,199 +26,314 @@ let SandboxIframe = class SandboxIframe extends LitElement {
15
26
  }
16
27
  disconnectedCallback() {
17
28
  super.disconnectedCallback();
29
+ // Note: We don't unregister the sandbox here for loadContent() mode
30
+ // because the caller (HtmlArtifact) owns the sandbox lifecycle.
31
+ // For execute() mode, the sandbox is unregistered in the cleanup function.
18
32
  this.iframe?.remove();
19
33
  }
20
34
  /**
21
35
  * Load HTML content into sandbox and keep it displayed (for HTML artifacts)
22
36
  * @param sandboxId Unique ID
23
37
  * @param htmlContent Full HTML content
24
- * @param attachments Attachments available
38
+ * @param providers Runtime providers to inject
39
+ * @param consumers Message consumers to register (optional)
25
40
  */
26
- loadContent(sandboxId, htmlContent, attachments) {
27
- const completeHtml = this.prepareHtmlDocument(sandboxId, htmlContent, attachments);
41
+ loadContent(sandboxId, htmlContent, providers = [], consumers = []) {
42
+ // Unregister previous sandbox if exists
43
+ try {
44
+ RUNTIME_MESSAGE_ROUTER.unregisterSandbox(sandboxId);
45
+ }
46
+ catch {
47
+ // Sandbox might not exist, that's ok
48
+ }
49
+ providers = [new ConsoleRuntimeProvider(), ...providers];
50
+ RUNTIME_MESSAGE_ROUTER.registerSandbox(sandboxId, providers, consumers);
51
+ // loadContent is always used for HTML artifacts (not standalone)
52
+ const completeHtml = this.prepareHtmlDocument(sandboxId, htmlContent, providers, {
53
+ isHtmlArtifact: true,
54
+ isStandalone: false,
55
+ });
56
+ // Validate HTML before loading
57
+ const validationError = this.validateHtml(completeHtml);
58
+ if (validationError) {
59
+ console.error("HTML validation failed:", validationError);
60
+ // Show error in iframe instead of crashing
61
+ this.iframe?.remove();
62
+ this.iframe = document.createElement("iframe");
63
+ this.iframe.style.cssText = "width: 100%; height: 100%; border: none;";
64
+ this.iframe.srcdoc = `
65
+ <html>
66
+ <body style="font-family: monospace; padding: 20px; background: #fff; color: #000;">
67
+ <h3 style="color: #c00;">HTML Validation Error</h3>
68
+ <pre style="background: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto; white-space: pre-wrap;">${validationError}</pre>
69
+ </body>
70
+ </html>
71
+ `;
72
+ this.appendChild(this.iframe);
73
+ return;
74
+ }
75
+ // Remove previous iframe if exists
76
+ this.iframe?.remove();
28
77
  if (this.sandboxUrlProvider) {
29
78
  // Browser extension mode: use sandbox.html with postMessage
30
- this.loadViaSandboxUrl(sandboxId, completeHtml, attachments);
79
+ this.loadViaSandboxUrl(sandboxId, completeHtml);
31
80
  }
32
81
  else {
33
82
  // Web mode: use srcdoc
34
- this.loadViaSrcdoc(completeHtml);
83
+ this.loadViaSrcdoc(sandboxId, completeHtml);
35
84
  }
36
85
  }
37
- loadViaSandboxUrl(sandboxId, completeHtml, attachments) {
38
- // Wait for sandbox-ready and send content
86
+ loadViaSandboxUrl(sandboxId, completeHtml) {
87
+ // Create iframe pointing to sandbox URL
88
+ this.iframe = document.createElement("iframe");
89
+ this.iframe.sandbox.add("allow-scripts");
90
+ this.iframe.sandbox.add("allow-modals");
91
+ this.iframe.style.width = "100%";
92
+ this.iframe.style.height = "100%";
93
+ this.iframe.style.border = "none";
94
+ this.iframe.src = this.sandboxUrlProvider();
95
+ // Update router with iframe reference BEFORE appending to DOM
96
+ RUNTIME_MESSAGE_ROUTER.setSandboxIframe(sandboxId, this.iframe);
97
+ // Listen for open-external-url messages from iframe
98
+ const externalUrlHandler = (e) => {
99
+ if (e.data.type === "open-external-url" && e.source === this.iframe?.contentWindow) {
100
+ // Use chrome.tabs API to open in new tab
101
+ const chromeAPI = globalThis.chrome;
102
+ if (chromeAPI?.tabs) {
103
+ chromeAPI.tabs.create({ url: e.data.url });
104
+ }
105
+ else {
106
+ // Fallback for non-extension context
107
+ window.open(e.data.url, "_blank");
108
+ }
109
+ }
110
+ };
111
+ window.addEventListener("message", externalUrlHandler);
112
+ // Listen for sandbox-ready and sandbox-error messages directly
39
113
  const readyHandler = (e) => {
40
114
  if (e.data.type === "sandbox-ready" && e.source === this.iframe?.contentWindow) {
41
115
  window.removeEventListener("message", readyHandler);
116
+ window.removeEventListener("message", errorHandler);
117
+ // Send content to sandbox
42
118
  this.iframe?.contentWindow?.postMessage({
43
119
  type: "sandbox-load",
44
120
  sandboxId,
45
121
  code: completeHtml,
46
- attachments,
122
+ }, "*");
123
+ }
124
+ };
125
+ const errorHandler = (e) => {
126
+ if (e.data.type === "sandbox-error" && e.source === this.iframe?.contentWindow) {
127
+ window.removeEventListener("message", readyHandler);
128
+ window.removeEventListener("message", errorHandler);
129
+ // The sandbox.js already sent us the error via postMessage.
130
+ // We need to convert it to an execution-error message that the execute() consumer will handle.
131
+ // Simulate receiving an execution-error from the sandbox
132
+ window.postMessage({
133
+ sandboxId: sandboxId,
134
+ type: "execution-error",
135
+ error: { message: e.data.error, stack: e.data.stack },
47
136
  }, "*");
48
137
  }
49
138
  };
50
139
  window.addEventListener("message", readyHandler);
51
- // Always recreate iframe to ensure fresh sandbox and sandbox-ready message
52
- this.iframe?.remove();
53
- this.iframe = document.createElement("iframe");
54
- this.iframe.sandbox.add("allow-scripts");
55
- this.iframe.sandbox.add("allow-modals");
56
- this.iframe.style.width = "100%";
57
- this.iframe.style.height = "100%";
58
- this.iframe.style.border = "none";
59
- this.iframe.src = this.sandboxUrlProvider();
140
+ window.addEventListener("message", errorHandler);
60
141
  this.appendChild(this.iframe);
61
142
  }
62
- loadViaSrcdoc(completeHtml) {
63
- // Always recreate iframe to ensure fresh sandbox
64
- this.iframe?.remove();
143
+ loadViaSrcdoc(sandboxId, completeHtml) {
144
+ // Create iframe with srcdoc
65
145
  this.iframe = document.createElement("iframe");
66
146
  this.iframe.sandbox.add("allow-scripts");
67
147
  this.iframe.sandbox.add("allow-modals");
68
148
  this.iframe.style.width = "100%";
69
149
  this.iframe.style.height = "100%";
70
150
  this.iframe.style.border = "none";
71
- // Set content directly via srcdoc (no CSP restrictions in web apps)
72
151
  this.iframe.srcdoc = completeHtml;
152
+ // Update router with iframe reference BEFORE appending to DOM
153
+ RUNTIME_MESSAGE_ROUTER.setSandboxIframe(sandboxId, this.iframe);
154
+ // Listen for open-external-url messages from iframe
155
+ const externalUrlHandler = (e) => {
156
+ if (e.data.type === "open-external-url" && e.source === this.iframe?.contentWindow) {
157
+ // Fallback for non-extension context
158
+ window.open(e.data.url, "_blank");
159
+ }
160
+ };
161
+ window.addEventListener("message", externalUrlHandler);
73
162
  this.appendChild(this.iframe);
74
163
  }
75
164
  /**
76
165
  * Execute code in sandbox
77
166
  * @param sandboxId Unique ID for this execution
78
167
  * @param code User code (plain JS for REPL, or full HTML for artifacts)
79
- * @param attachments Attachments available to the code
168
+ * @param providers Runtime providers to inject
169
+ * @param consumers Additional message consumers (optional, execute has its own internal consumer)
80
170
  * @param signal Abort signal
81
171
  * @returns Promise resolving to execution result
82
172
  */
83
- async execute(sandboxId, code, attachments, signal) {
173
+ async execute(sandboxId, code, providers = [], consumers = [], signal, isHtmlArtifact = false) {
84
174
  if (signal?.aborted) {
85
175
  throw new Error("Execution aborted");
86
176
  }
87
- // Prepare the complete HTML document with runtime + user code
88
- const completeHtml = this.prepareHtmlDocument(sandboxId, code, attachments);
89
- // Wait for execution to complete
177
+ const consoleProvider = new ConsoleRuntimeProvider();
178
+ providers = [consoleProvider, ...providers];
179
+ RUNTIME_MESSAGE_ROUTER.registerSandbox(sandboxId, providers, consumers);
180
+ const files = [];
181
+ let completed = false;
90
182
  return new Promise((resolve, reject) => {
91
- const logs = [];
92
- const files = [];
93
- let completed = false;
94
- const messageHandler = (e) => {
95
- // Ignore messages not for this sandbox
96
- if (e.data.sandboxId !== sandboxId)
97
- return;
98
- if (e.data.type === "console") {
99
- logs.push({
100
- type: e.data.method === "error" ? "error" : "log",
101
- text: e.data.text,
102
- });
103
- }
104
- else if (e.data.type === "file-returned") {
105
- files.push({
106
- fileName: e.data.fileName,
107
- content: e.data.content,
108
- mimeType: e.data.mimeType,
109
- });
110
- }
111
- else if (e.data.type === "execution-complete") {
112
- completed = true;
113
- cleanup();
114
- resolve({
115
- success: true,
116
- console: logs,
117
- files: files,
118
- });
119
- }
120
- else if (e.data.type === "execution-error") {
121
- completed = true;
122
- cleanup();
123
- resolve({
124
- success: false,
125
- console: logs,
126
- error: e.data.error,
127
- files,
128
- });
129
- }
183
+ // 4. Create execution consumer for lifecycle messages
184
+ const executionConsumer = {
185
+ async handleMessage(message) {
186
+ if (message.type === "file-returned") {
187
+ files.push({
188
+ fileName: message.fileName,
189
+ content: message.content,
190
+ mimeType: message.mimeType,
191
+ });
192
+ }
193
+ else if (message.type === "execution-complete") {
194
+ completed = true;
195
+ cleanup();
196
+ resolve({
197
+ success: true,
198
+ console: consoleProvider.getLogs(),
199
+ files,
200
+ returnValue: message.returnValue,
201
+ });
202
+ }
203
+ else if (message.type === "execution-error") {
204
+ completed = true;
205
+ cleanup();
206
+ resolve({ success: false, console: consoleProvider.getLogs(), error: message.error, files });
207
+ }
208
+ },
130
209
  };
210
+ RUNTIME_MESSAGE_ROUTER.addConsumer(sandboxId, executionConsumer);
211
+ const cleanup = () => {
212
+ RUNTIME_MESSAGE_ROUTER.unregisterSandbox(sandboxId);
213
+ signal?.removeEventListener("abort", abortHandler);
214
+ clearTimeout(timeoutId);
215
+ this.iframe?.remove();
216
+ this.iframe = undefined;
217
+ };
218
+ // Abort handler
131
219
  const abortHandler = () => {
132
220
  if (!completed) {
221
+ completed = true;
133
222
  cleanup();
134
223
  reject(new Error("Execution aborted"));
135
224
  }
136
225
  };
137
- let readyHandler;
138
- const cleanup = () => {
139
- window.removeEventListener("message", messageHandler);
140
- signal?.removeEventListener("abort", abortHandler);
141
- if (readyHandler) {
142
- window.removeEventListener("message", readyHandler);
143
- }
144
- clearTimeout(timeoutId);
145
- };
146
- // Set up listeners BEFORE creating iframe
147
- window.addEventListener("message", messageHandler);
148
- signal?.addEventListener("abort", abortHandler);
149
- // Timeout after 30 seconds
226
+ if (signal) {
227
+ signal.addEventListener("abort", abortHandler);
228
+ }
229
+ // Timeout handler (30 seconds)
150
230
  const timeoutId = setTimeout(() => {
151
231
  if (!completed) {
232
+ completed = true;
152
233
  cleanup();
153
234
  resolve({
154
235
  success: false,
155
- error: { message: "Execution timeout (30s)", stack: "" },
156
- console: logs,
236
+ console: consoleProvider.getLogs(),
237
+ error: { message: "Execution timeout (120s)", stack: "" },
157
238
  files,
158
239
  });
159
240
  }
160
- }, 30000);
241
+ }, 120000);
242
+ // 4. Prepare HTML and create iframe
243
+ const completeHtml = this.prepareHtmlDocument(sandboxId, code, providers, {
244
+ isHtmlArtifact,
245
+ isStandalone: false,
246
+ });
247
+ // 5. Validate HTML before sending to sandbox
248
+ const validationError = this.validateHtml(completeHtml);
249
+ if (validationError) {
250
+ reject(new Error(`HTML validation failed: ${validationError}`));
251
+ return;
252
+ }
161
253
  if (this.sandboxUrlProvider) {
162
- // Browser extension mode: wait for sandbox-ready and send content
163
- readyHandler = (e) => {
254
+ // Browser extension mode: wait for sandbox-ready
255
+ this.iframe = document.createElement("iframe");
256
+ this.iframe.sandbox.add("allow-scripts", "allow-modals");
257
+ this.iframe.style.cssText = "width: 100%; height: 100%; border: none;";
258
+ this.iframe.src = this.sandboxUrlProvider();
259
+ // Update router with iframe reference BEFORE appending to DOM
260
+ RUNTIME_MESSAGE_ROUTER.setSandboxIframe(sandboxId, this.iframe);
261
+ // Listen for sandbox-ready and sandbox-error messages
262
+ const readyHandler = (e) => {
164
263
  if (e.data.type === "sandbox-ready" && e.source === this.iframe?.contentWindow) {
165
264
  window.removeEventListener("message", readyHandler);
166
- // Send the complete HTML
265
+ window.removeEventListener("message", errorHandler);
266
+ // Send content to sandbox
167
267
  this.iframe?.contentWindow?.postMessage({
168
268
  type: "sandbox-load",
169
269
  sandboxId,
170
270
  code: completeHtml,
171
- attachments,
271
+ }, "*");
272
+ }
273
+ };
274
+ const errorHandler = (e) => {
275
+ if (e.data.type === "sandbox-error" && e.source === this.iframe?.contentWindow) {
276
+ window.removeEventListener("message", readyHandler);
277
+ window.removeEventListener("message", errorHandler);
278
+ // Convert sandbox-error to execution-error for the execution consumer
279
+ window.postMessage({
280
+ sandboxId: sandboxId,
281
+ type: "execution-error",
282
+ error: { message: e.data.error, stack: e.data.stack },
172
283
  }, "*");
173
284
  }
174
285
  };
175
286
  window.addEventListener("message", readyHandler);
176
- // Create iframe AFTER all listeners are set up
177
- this.iframe?.remove();
178
- this.iframe = document.createElement("iframe");
179
- this.iframe.sandbox.add("allow-scripts");
180
- this.iframe.sandbox.add("allow-modals");
181
- this.iframe.style.width = "100%";
182
- this.iframe.style.height = "100%";
183
- this.iframe.style.border = "none";
184
- this.iframe.src = this.sandboxUrlProvider();
287
+ window.addEventListener("message", errorHandler);
185
288
  this.appendChild(this.iframe);
186
289
  }
187
290
  else {
188
291
  // Web mode: use srcdoc
189
- this.iframe?.remove();
190
292
  this.iframe = document.createElement("iframe");
191
- this.iframe.sandbox.add("allow-scripts");
192
- this.iframe.sandbox.add("allow-modals");
193
- this.iframe.style.width = "100%";
194
- this.iframe.style.height = "100%";
195
- this.iframe.style.border = "none";
196
- // Set content via srcdoc BEFORE appending to DOM
293
+ this.iframe.sandbox.add("allow-scripts", "allow-modals");
294
+ this.iframe.style.cssText = "width: 100%; height: 100%; border: none; display: none;";
197
295
  this.iframe.srcdoc = completeHtml;
296
+ // Update router with iframe reference BEFORE appending to DOM
297
+ RUNTIME_MESSAGE_ROUTER.setSandboxIframe(sandboxId, this.iframe);
198
298
  this.appendChild(this.iframe);
199
299
  }
200
300
  });
201
301
  }
302
+ /**
303
+ * Validate HTML using DOMParser - returns error message if invalid, null if valid
304
+ * Note: JavaScript syntax validation is done in sandbox.js to avoid CSP restrictions
305
+ */
306
+ validateHtml(html) {
307
+ try {
308
+ const parser = new DOMParser();
309
+ const doc = parser.parseFromString(html, "text/html");
310
+ // Check for parser errors
311
+ const parserError = doc.querySelector("parsererror");
312
+ if (parserError) {
313
+ return parserError.textContent || "Unknown parse error";
314
+ }
315
+ return null;
316
+ }
317
+ catch (error) {
318
+ return error.message || "Unknown validation error";
319
+ }
320
+ }
202
321
  /**
203
322
  * Prepare complete HTML document with runtime + user code
323
+ * PUBLIC so HtmlArtifact can use it for download button
204
324
  */
205
- prepareHtmlDocument(sandboxId, userCode, attachments) {
325
+ prepareHtmlDocument(sandboxId, userCode, providers = [], options) {
326
+ // Default options
327
+ const opts = {
328
+ isHtmlArtifact: false,
329
+ isStandalone: false,
330
+ ...options,
331
+ };
206
332
  // Runtime script that will be injected
207
- const runtime = this.getRuntimeScript(sandboxId, attachments);
208
- // Check if user provided full HTML
209
- const hasHtmlTag = /<html[^>]*>/i.test(userCode);
210
- if (hasHtmlTag) {
333
+ const runtime = this.getRuntimeScript(sandboxId, providers, opts.isStandalone || false);
334
+ // Only check for HTML tags if explicitly marked as HTML artifact
335
+ // For javascript_repl, userCode is JavaScript that may contain HTML in string literals
336
+ if (opts.isHtmlArtifact) {
211
337
  // HTML Artifact - inject runtime into existing HTML
212
338
  const headMatch = userCode.match(/<head[^>]*>/i);
213
339
  if (headMatch) {
@@ -224,6 +350,8 @@ let SandboxIframe = class SandboxIframe extends LitElement {
224
350
  }
225
351
  else {
226
352
  // REPL - wrap code in HTML with runtime and call complete() when done
353
+ // Escape </script> in user code to prevent premature tag closure
354
+ const escapedUserCode = escapeScriptContent(userCode);
227
355
  return `<!DOCTYPE html>
228
356
  <html>
229
357
  <head>
@@ -233,11 +361,35 @@ let SandboxIframe = class SandboxIframe extends LitElement {
233
361
  <script type="module">
234
362
  (async () => {
235
363
  try {
236
- ${userCode}
237
- window.complete();
364
+ // Wrap user code in async function to capture return value
365
+ const userCodeFunc = async () => {
366
+ ${escapedUserCode}
367
+ };
368
+
369
+ const returnValue = await userCodeFunc();
370
+
371
+ // Call completion callbacks before complete()
372
+ if (window.__completionCallbacks && window.__completionCallbacks.length > 0) {
373
+ try {
374
+ await Promise.all(window.__completionCallbacks.map(cb => cb(true)));
375
+ } catch (e) {
376
+ console.error('Completion callback error:', e);
377
+ }
378
+ }
379
+
380
+ await window.complete(null, returnValue);
238
381
  } catch (error) {
239
- console.error(error?.stack || error?.message || String(error));
240
- window.complete({
382
+
383
+ // Call completion callbacks before complete() (error path)
384
+ if (window.__completionCallbacks && window.__completionCallbacks.length > 0) {
385
+ try {
386
+ await Promise.all(window.__completionCallbacks.map(cb => cb(false)));
387
+ } catch (e) {
388
+ console.error('Completion callback error:', e);
389
+ }
390
+ }
391
+
392
+ await window.complete({
241
393
  message: error?.message || String(error),
242
394
  stack: error?.stack || new Error().stack
243
395
  });
@@ -249,180 +401,96 @@ let SandboxIframe = class SandboxIframe extends LitElement {
249
401
  }
250
402
  }
251
403
  /**
252
- * Get the runtime script that captures console, provides helpers, etc.
404
+ * Generate runtime script from providers
405
+ * @param sandboxId Unique sandbox ID
406
+ * @param providers Runtime providers
407
+ * @param isStandalone If true, skip runtime bridge and navigation interceptor (for standalone downloads)
253
408
  */
254
- getRuntimeScript(sandboxId, attachments) {
255
- // Convert attachments to serializable format
256
- const attachmentsData = attachments.map((a) => ({
257
- id: a.id,
258
- fileName: a.fileName,
259
- mimeType: a.mimeType,
260
- size: a.size,
261
- content: a.content,
262
- extractedText: a.extractedText,
263
- }));
264
- // Runtime function that will run in the sandbox (NO parameters - values injected before function)
265
- const runtimeFunc = () => {
266
- // Helper functions
267
- window.listFiles = () => (attachments || []).map((a) => ({
268
- id: a.id,
269
- fileName: a.fileName,
270
- mimeType: a.mimeType,
271
- size: a.size,
272
- }));
273
- window.readTextFile = (attachmentId) => {
274
- const a = (attachments || []).find((x) => x.id === attachmentId);
275
- if (!a)
276
- throw new Error("Attachment not found: " + attachmentId);
277
- if (a.extractedText)
278
- return a.extractedText;
279
- try {
280
- return atob(a.content);
281
- }
282
- catch {
283
- throw new Error("Failed to decode text content for: " + attachmentId);
284
- }
285
- };
286
- window.readBinaryFile = (attachmentId) => {
287
- const a = (attachments || []).find((x) => x.id === attachmentId);
288
- if (!a)
289
- throw new Error("Attachment not found: " + attachmentId);
290
- const bin = atob(a.content);
291
- const bytes = new Uint8Array(bin.length);
292
- for (let i = 0; i < bin.length; i++)
293
- bytes[i] = bin.charCodeAt(i);
294
- return bytes;
295
- };
296
- window.returnFile = async (fileName, content, mimeType) => {
297
- let finalContent, finalMimeType;
298
- if (content instanceof Blob) {
299
- const arrayBuffer = await content.arrayBuffer();
300
- finalContent = new Uint8Array(arrayBuffer);
301
- finalMimeType = mimeType || content.type || "application/octet-stream";
302
- if (!mimeType && !content.type) {
303
- throw new Error("returnFile: MIME type is required for Blob content. Please provide a mimeType parameter (e.g., 'image/png').");
304
- }
305
- }
306
- else if (content instanceof Uint8Array) {
307
- finalContent = content;
308
- if (!mimeType) {
309
- throw new Error("returnFile: MIME type is required for Uint8Array content. Please provide a mimeType parameter (e.g., 'image/png').");
310
- }
311
- finalMimeType = mimeType;
312
- }
313
- else if (typeof content === "string") {
314
- finalContent = content;
315
- finalMimeType = mimeType || "text/plain";
316
- }
317
- else {
318
- finalContent = JSON.stringify(content, null, 2);
319
- finalMimeType = mimeType || "application/json";
320
- }
321
- window.parent.postMessage({
322
- type: "file-returned",
323
- sandboxId,
324
- fileName,
325
- content: finalContent,
326
- mimeType: finalMimeType,
327
- }, "*");
328
- };
329
- // Console capture
330
- const originalConsole = {
331
- log: console.log,
332
- error: console.error,
333
- warn: console.warn,
334
- info: console.info,
335
- };
336
- ["log", "error", "warn", "info"].forEach((method) => {
337
- console[method] = (...args) => {
338
- const text = args
339
- .map((arg) => {
340
- try {
341
- return typeof arg === "object" ? JSON.stringify(arg) : String(arg);
342
- }
343
- catch {
344
- return String(arg);
345
- }
346
- })
347
- .join(" ");
348
- window.parent.postMessage({
349
- type: "console",
350
- sandboxId,
351
- method,
352
- text,
353
- }, "*");
354
- originalConsole[method].apply(console, args);
355
- };
356
- });
357
- // Track errors for HTML artifacts
358
- let lastError = null;
359
- // Error handlers
360
- window.addEventListener("error", (e) => {
361
- const text = (e.error?.stack || e.message || String(e)) + " at line " + (e.lineno || "?") + ":" + (e.colno || "?");
362
- // Store the error
363
- lastError = {
364
- message: e.error?.message || e.message || String(e),
365
- stack: e.error?.stack || text,
366
- };
367
- window.parent.postMessage({
368
- type: "console",
369
- sandboxId,
370
- method: "error",
371
- text,
372
- }, "*");
373
- });
374
- window.addEventListener("unhandledrejection", (e) => {
375
- const text = "Unhandled promise rejection: " + (e.reason?.message || e.reason || "Unknown error");
376
- // Store the error
377
- lastError = {
378
- message: e.reason?.message || String(e.reason) || "Unhandled promise rejection",
379
- stack: e.reason?.stack || text,
380
- };
381
- window.parent.postMessage({
382
- type: "console",
383
- sandboxId,
384
- method: "error",
385
- text,
386
- }, "*");
409
+ getRuntimeScript(sandboxId, providers = [], isStandalone = false) {
410
+ // Collect all data from providers
411
+ const allData = {};
412
+ for (const provider of providers) {
413
+ Object.assign(allData, provider.getData());
414
+ }
415
+ // Generate bridge code (skip if standalone)
416
+ const bridgeCode = isStandalone
417
+ ? ""
418
+ : RuntimeMessageBridge.generateBridgeCode({
419
+ context: "sandbox-iframe",
420
+ sandboxId,
387
421
  });
388
- // Expose complete() method for user code to call
389
- let completionSent = false;
390
- window.complete = (error) => {
391
- if (completionSent)
392
- return;
393
- completionSent = true;
394
- // Use provided error or last caught error
395
- const finalError = error || lastError;
396
- if (finalError) {
397
- window.parent.postMessage({
398
- type: "execution-error",
399
- sandboxId,
400
- error: finalError,
401
- }, "*");
402
- }
403
- else {
404
- window.parent.postMessage({
405
- type: "execution-complete",
406
- sandboxId,
407
- }, "*");
408
- }
409
- };
410
- // Fallback timeout for HTML artifacts that don't call complete()
411
- if (document.readyState === "complete" || document.readyState === "interactive") {
412
- setTimeout(() => window.complete(), 2000);
413
- }
414
- else {
415
- window.addEventListener("load", () => {
416
- setTimeout(() => window.complete(), 2000);
417
- });
418
- }
419
- };
420
- // Prepend the const declarations, then the function
421
- return (`<script>\n` +
422
- `window.sandboxId = ${JSON.stringify(sandboxId)};\n` +
423
- `window.attachments = ${JSON.stringify(attachmentsData)};\n` +
424
- `(${runtimeFunc.toString()})();\n` +
425
- `</script>`);
422
+ // Collect all runtime functions - pass sandboxId as string literal
423
+ const runtimeFunctions = [];
424
+ for (const provider of providers) {
425
+ runtimeFunctions.push(`(${provider.getRuntime().toString()})(${JSON.stringify(sandboxId)});`);
426
+ }
427
+ // Build script with HTML escaping
428
+ // Escape </script> to prevent premature tag closure in HTML parser
429
+ const dataInjection = Object.entries(allData)
430
+ .map(([key, value]) => {
431
+ const jsonStr = JSON.stringify(value).replace(/<\/script/gi, "<\\/script");
432
+ return `window.${key} = ${jsonStr};`;
433
+ })
434
+ .join("\n");
435
+ // TODO the font-size is needed, as chrome seems to inject a stylesheet into iframes
436
+ // found in an extension context like sidepanel, settin body { font-size: 75% }. It's
437
+ // definitely not our code doing that.
438
+ // See https://stackoverflow.com/questions/71480433/chrome-is-injecting-some-stylesheet-in-popup-ui-which-reduces-the-font-size-to-7
439
+ // Navigation interceptor (only if NOT standalone)
440
+ const navigationInterceptor = isStandalone
441
+ ? ""
442
+ : `
443
+ // Navigation interceptor: prevent all navigation and open externally
444
+ (function() {
445
+ // Intercept link clicks
446
+ document.addEventListener('click', function(e) {
447
+ const link = e.target.closest('a');
448
+ if (link && link.href) {
449
+ // Check if it's an external link (not javascript: or #hash)
450
+ if (link.href.startsWith('http://') || link.href.startsWith('https://')) {
451
+ e.preventDefault();
452
+ e.stopPropagation();
453
+ window.parent.postMessage({ type: 'open-external-url', url: link.href }, '*');
454
+ }
455
+ }
456
+ }, true);
457
+
458
+ // Intercept form submissions
459
+ document.addEventListener('submit', function(e) {
460
+ const form = e.target;
461
+ if (form && form.action) {
462
+ e.preventDefault();
463
+ e.stopPropagation();
464
+ window.parent.postMessage({ type: 'open-external-url', url: form.action }, '*');
465
+ }
466
+ }, true);
467
+
468
+ // Prevent window.location changes (only if not already redefined)
469
+ try {
470
+ const originalLocation = window.location;
471
+ Object.defineProperty(window, 'location', {
472
+ get: function() { return originalLocation; },
473
+ set: function(url) {
474
+ window.parent.postMessage({ type: 'open-external-url', url: url.toString() }, '*');
475
+ }
476
+ });
477
+ } catch (e) {
478
+ // Already defined, skip
479
+ }
480
+ })();
481
+ `;
482
+ return `<style>
483
+ html, body {
484
+ font-size: initial;
485
+ }
486
+ </style>
487
+ <script>
488
+ window.sandboxId = ${JSON.stringify(sandboxId)};
489
+ ${dataInjection}
490
+ ${bridgeCode}
491
+ ${runtimeFunctions.join("\n")}
492
+ ${navigationInterceptor}
493
+ </script>`;
426
494
  }
427
495
  };
428
496
  __decorate([