@theoremjs/studio 0.0.0-stage → 0.3.2

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 (473) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +295 -2
  3. package/agreement.d.ts +14 -0
  4. package/agreement.js +80 -0
  5. package/asks.d.ts +47 -0
  6. package/asks.js +54 -0
  7. package/browser-connection.d.ts +49 -0
  8. package/browser-connection.js +215 -0
  9. package/browser-engine.d.ts +11 -0
  10. package/browser-engine.js +11 -0
  11. package/browser-execution.d.ts +6 -0
  12. package/browser-execution.js +18 -0
  13. package/browser-live.d.ts +4 -0
  14. package/browser-live.js +132 -0
  15. package/browser-transport.d.ts +33 -0
  16. package/browser-transport.js +229 -0
  17. package/browser.d.ts +4 -0
  18. package/browser.js +4 -0
  19. package/canonical.d.ts +10 -0
  20. package/canonical.js +25 -0
  21. package/compile-workspace.d.ts +28 -0
  22. package/compile-workspace.js +295 -0
  23. package/compile.d.ts +65 -0
  24. package/compile.js +1605 -0
  25. package/concierge-demo.d.ts +17 -0
  26. package/concierge-demo.js +1230 -0
  27. package/conversation-key.d.ts +5 -0
  28. package/conversation-key.js +10 -0
  29. package/decision-example-images.d.ts +30 -0
  30. package/decision-example-images.js +30 -0
  31. package/deno.json +3 -0
  32. package/draft.d.ts +407 -0
  33. package/draft.js +505 -0
  34. package/editors.d.ts +29 -0
  35. package/editors.js +51 -0
  36. package/example-embedding-files.d.ts +11 -0
  37. package/example-embedding-files.js +20 -0
  38. package/example.d.ts +36 -0
  39. package/example.js +357 -0
  40. package/guardrail-probe.d.ts +100 -0
  41. package/guardrail-probe.js +722 -0
  42. package/held-credentials.d.ts +28 -0
  43. package/held-credentials.js +87 -0
  44. package/installed.mjs +40 -0
  45. package/lent-keys.d.ts +122 -0
  46. package/lent-keys.js +47 -0
  47. package/line-diff.d.ts +15 -0
  48. package/line-diff.js +41 -0
  49. package/live-connection.d.ts +22 -0
  50. package/live-connection.js +27 -0
  51. package/live-session-bridge.d.ts +15 -0
  52. package/live-session-bridge.js +202 -0
  53. package/map-line.d.ts +19 -0
  54. package/map-line.js +42 -0
  55. package/map.d.ts +154 -0
  56. package/map.js +525 -0
  57. package/media-accept.d.ts +19 -0
  58. package/media-accept.js +65 -0
  59. package/mod.d.ts +39 -0
  60. package/mod.js +33 -0
  61. package/origins.d.ts +52 -0
  62. package/origins.js +165 -0
  63. package/package.json +85 -4
  64. package/page/assets/Banner-BISz3nXA.js +2 -0
  65. package/page/assets/BottomSheet-BwfBDtje.js +1 -0
  66. package/page/assets/Card-Lp-0P5eL.js +1 -0
  67. package/page/assets/CardWall-CBRLdDZW.js +1 -0
  68. package/page/assets/Center-nHS1JSux.js +1 -0
  69. package/page/assets/CheckboxInput-Cj5pk-KI.js +2 -0
  70. package/page/assets/CodeBlock-C7XJ4ioE.js +51 -0
  71. package/page/assets/CollapsibleGroup-N7_SOjbm.js +2 -0
  72. package/page/assets/ContextMenu-CBu9H-9H.js +2 -0
  73. package/page/assets/DateInput-BGrQ5tPC.js +1 -0
  74. package/page/assets/Dialog-DELWQo-v.js +1 -0
  75. package/page/assets/EmptyState-C8W4JKBZ.js +1 -0
  76. package/page/assets/HoverCard-D1Y1ltWQ.js +1 -0
  77. package/page/assets/Icon-JrysT8aU.js +3 -0
  78. package/page/assets/IconAlertTriangle-BqAEqqdU.js +1 -0
  79. package/page/assets/IconButton-DlOGzJIX.js +1 -0
  80. package/page/assets/IconEye-BB5aY-wQ.js +1 -0
  81. package/page/assets/IconFileText-6zOFKKrF.js +1 -0
  82. package/page/assets/IconSearch-BTx66a40.js +1 -0
  83. package/page/assets/IconShield-DDOh7Gr5.js +1 -0
  84. package/page/assets/ItemSwipeLayer-Ckn4X6h9.js +1 -0
  85. package/page/assets/PaneState-BvA2tLQg.js +1 -0
  86. package/page/assets/PaneState-eUzUkNE8.css +1 -0
  87. package/page/assets/ScrollableArea-Ckugdj1N.js +1 -0
  88. package/page/assets/Section-DJ97F7QE.js +1 -0
  89. package/page/assets/SegmentedControlItem-h-aaXzyS.js +1 -0
  90. package/page/assets/SidePanel-BL32abk8.js +1 -0
  91. package/page/assets/StackItem-CQviqAfM.js +1 -0
  92. package/page/assets/Text-bum6zWWx.js +2 -0
  93. package/page/assets/TimestampHoverCard-DQIG0RZF.js +1 -0
  94. package/page/assets/ToolResultCharts-CgshSv9Q.js +1 -0
  95. package/page/assets/Tooltip-BH9xiRMl.js +1 -0
  96. package/page/assets/TraceInspector-_yZiz05W.js +1 -0
  97. package/page/assets/TraceOverview-BPO-HIYK.js +57 -0
  98. package/page/assets/VStack-CkVMcNiK.js +1 -0
  99. package/page/assets/_virtual_studio-type-sources-ByxqQaOG.js +12936 -0
  100. package/page/assets/arrive-DvbqpeRS.js +1 -0
  101. package/page/assets/browser-engine-CYq9DQAM.js +9 -0
  102. package/page/assets/browser-transport-D-2jDYe7.js +47 -0
  103. package/page/assets/codicon-DF1abBS2.ttf +0 -0
  104. package/page/assets/compile-egress-BSxOdX4K.js +23 -0
  105. package/page/assets/container.stylex-BmOi-8DQ.js +1 -0
  106. package/page/assets/createReactComponent-CZwsv6DD.js +1 -0
  107. package/page/assets/decision-example-images-CZGr7YIT.js +1 -0
  108. package/page/assets/devWarning-DxuplmRl.js +1 -0
  109. package/page/assets/editor-DjpsE8to.css +1 -0
  110. package/page/assets/editor.api-Cd3ViPQa.js +908 -0
  111. package/page/assets/editor.worker-6GY8RhDc.js +1 -0
  112. package/page/assets/editor.worker-BmdWdrHZ.js +33 -0
  113. package/page/assets/editors-BJX_S59A.js +1 -0
  114. package/page/assets/egress-automata-B5ZGE1mT.js +1 -0
  115. package/page/assets/embedding-space-view-CfQBPDxD.js +140 -0
  116. package/page/assets/encode-files-Bc3HJyAh.js +1 -0
  117. package/page/assets/export-agent-C3yyzXH8.js +43 -0
  118. package/page/assets/figtree-latin-400-normal-BD4aNku5.woff +0 -0
  119. package/page/assets/figtree-latin-400-normal-g7Dtegnw.woff2 +0 -0
  120. package/page/assets/figtree-latin-500-normal-BWnGEVsr.woff2 +0 -0
  121. package/page/assets/figtree-latin-500-normal-B_yy1phn.woff +0 -0
  122. package/page/assets/figtree-latin-600-normal-BM_oTo4n.woff +0 -0
  123. package/page/assets/figtree-latin-600-normal-Cv_xCTDl.woff2 +0 -0
  124. package/page/assets/figtree-latin-700-normal-BCCt2T1q.woff +0 -0
  125. package/page/assets/figtree-latin-700-normal-th6qEP7c.woff2 +0 -0
  126. package/page/assets/focusOutline.stylex-BT0kfa4t.js +1 -0
  127. package/page/assets/focusableSelector-DXZeMU85.js +1 -0
  128. package/page/assets/groupStyles-C7Ter7zC.js +1 -0
  129. package/page/assets/guardrail-tester-Gut5xK4a.js +9 -0
  130. package/page/assets/host-patterns-C9RMP16Q.js +1 -0
  131. package/page/assets/index-CvvmFKgS.js +105 -0
  132. package/page/assets/index-DOaHlqBo.css +1 -0
  133. package/page/assets/isRtlElement-BG33-k_H.js +1 -0
  134. package/page/assets/labels-provider-4TIWDvsE.js +3 -0
  135. package/page/assets/lent-keys-C32ems-I.js +1 -0
  136. package/page/assets/live-ingress-lDUGPwth.js +1 -0
  137. package/page/assets/live-messages-CnkL4GWi.js +1 -0
  138. package/page/assets/mergeProps-ptS-gIMz.js +1 -0
  139. package/page/assets/padding.stylex-B76907Zf.js +1 -0
  140. package/page/assets/preload-helper-DpV6A1kQ.js +1 -0
  141. package/page/assets/reader-BOCCYaRp.js +7 -0
  142. package/page/assets/register-CDgivxvX.js +2 -0
  143. package/page/assets/rolldown-runtime-hePW80VL.js +1 -0
  144. package/page/assets/schemas-BQ9Jydzb.js +56 -0
  145. package/page/assets/shaped-data-BcarWqd5.js +16 -0
  146. package/page/assets/sharedResizeObserver-4U9Xq5Oq.js +1 -0
  147. package/page/assets/stub-DhdcU_Ew.js +471 -0
  148. package/page/assets/studio-code-pane-C_SAbcOa.js +8 -0
  149. package/page/assets/studio-console-DZwlEsvr.js +3 -0
  150. package/page/assets/studio-decision-B0FnCAXA.js +1 -0
  151. package/page/assets/studio-embedding-CmA51HVo.js +2 -0
  152. package/page/assets/studio-host-console-By7hqu2l.js +2 -0
  153. package/page/assets/studio-live-BrcVQcyV.js +1 -0
  154. package/page/assets/studio-map-B_xSia-z.js +1 -0
  155. package/page/assets/studio-map-Bb06Tw1F.css +1 -0
  156. package/page/assets/studio-monaco-CbKf90i6.css +1 -0
  157. package/page/assets/studio-monaco-xfyfezQS.js +34 -0
  158. package/page/assets/studio-ts.worker-B-EXG4Sv.js +67741 -0
  159. package/page/assets/studio-ts.worker-BXtW3z-O.js +1 -0
  160. package/page/assets/studio-type-checker-BOvxudki.js +23 -0
  161. package/page/assets/themeProps-3IqahpCr.js +1 -0
  162. package/page/assets/tokens.stylex-DkHf0P9C.js +1 -0
  163. package/page/assets/tool-schema-idaOe2nI.js +18 -0
  164. package/page/assets/trace-patterns-DnYJa0nI.js +1 -0
  165. package/page/assets/trace-record-C3zNksA_.js +1 -0
  166. package/page/assets/trace-schema-9CdEyG6Q.js +1 -0
  167. package/page/assets/tree-DqyAMsbI.js +3 -0
  168. package/page/assets/turn-client-Du3Um3Mg.js +2 -0
  169. package/page/assets/types-BhfXQCLx.js +1 -0
  170. package/page/assets/typescript-20GgZ8PJ.js +1 -0
  171. package/page/assets/use-one-call-Hcs8YBp1.js +1 -0
  172. package/page/assets/useAdaptivePresentation-BzmPCddb.js +1 -0
  173. package/page/assets/useClipboard-BgGRxRMJ.js +1 -0
  174. package/page/assets/useContainerReveal-BFy8N_QU.js +1 -0
  175. package/page/assets/useDevWarning-Z9SoixOP.js +1 -0
  176. package/page/assets/useLayerDismissal-B_G7IWpC.js +1 -0
  177. package/page/assets/useMediaQuery-BCT0NUeZ.js +1 -0
  178. package/page/assets/useScrollLock-Dyf6PHJt.js +1 -0
  179. package/page/assets/useScrollableArea-0NzdiBCq.js +1 -0
  180. package/page/assets/useTooltip-CJM_xhLB.js +1 -0
  181. package/page/assets/workspace-DZALqEDX.js +1 -0
  182. package/page/assets/zip-DTcEfps6.js +1 -0
  183. package/page/index.html +90 -0
  184. package/page.mjs +49 -0
  185. package/people.d.ts +87 -0
  186. package/people.js +110 -0
  187. package/policy.d.ts +43 -0
  188. package/policy.js +102 -0
  189. package/ports.d.mts +32 -0
  190. package/ports.mjs +85 -0
  191. package/probe-battery.d.ts +13 -0
  192. package/probe-battery.js +404 -0
  193. package/providers.d.ts +149 -0
  194. package/providers.js +306 -0
  195. package/read-source.d.ts +48 -0
  196. package/read-source.js +1301 -0
  197. package/read-steps.d.ts +23 -0
  198. package/read-steps.js +2 -0
  199. package/reader.d.ts +11 -0
  200. package/reader.js +11 -0
  201. package/registrations.d.ts +83 -0
  202. package/registrations.js +1 -0
  203. package/requirements.d.ts +22 -0
  204. package/requirements.js +38 -0
  205. package/run-payload-core.d.ts +28 -0
  206. package/run-payload-core.js +123 -0
  207. package/run-payload.d.ts +32 -0
  208. package/run-payload.js +26 -0
  209. package/runtime-scope.d.ts +84 -0
  210. package/runtime-scope.js +308 -0
  211. package/runtime.d.ts +84 -0
  212. package/runtime.js +387 -0
  213. package/section-notes.d.ts +33 -0
  214. package/section-notes.js +38 -0
  215. package/serve-page.mjs +96 -0
  216. package/server/draft-decide.d.ts +72 -0
  217. package/server/draft-decide.js +111 -0
  218. package/server/draft-embedding.d.ts +3 -0
  219. package/server/draft-embedding.js +35 -0
  220. package/server/draft-handler.d.ts +82 -0
  221. package/server/draft-handler.js +213 -0
  222. package/server/draft-probe.d.ts +14 -0
  223. package/server/draft-probe.js +61 -0
  224. package/server/draft-replies.d.ts +22 -0
  225. package/server/draft-replies.js +46 -0
  226. package/server/edited-session.d.ts +28 -0
  227. package/server/edited-session.js +83 -0
  228. package/server/edits.d.ts +38 -0
  229. package/server/edits.js +195 -0
  230. package/server/handler.d.ts +133 -0
  231. package/server/handler.js +598 -0
  232. package/server/lent-draft.d.ts +19 -0
  233. package/server/lent-draft.js +23 -0
  234. package/server/live.d.ts +15 -0
  235. package/server/live.js +96 -0
  236. package/server/open-editor.d.ts +63 -0
  237. package/server/open-editor.js +115 -0
  238. package/server/origins.d.ts +18 -0
  239. package/server/origins.js +330 -0
  240. package/server/project-source.d.ts +208 -0
  241. package/server/project-source.js +1042 -0
  242. package/server/project.d.ts +22 -0
  243. package/server/project.js +56 -0
  244. package/server/run-traces.d.ts +20 -0
  245. package/server/run-traces.js +96 -0
  246. package/server/save-new.d.ts +29 -0
  247. package/server/save-new.js +514 -0
  248. package/server/save-plan.d.ts +46 -0
  249. package/server/save-plan.js +1134 -0
  250. package/server/save-remove.d.ts +21 -0
  251. package/server/save-remove.js +528 -0
  252. package/server/save-session.d.ts +96 -0
  253. package/server/save-session.js +418 -0
  254. package/server/save-wire.d.ts +235 -0
  255. package/server/save-wire.js +8 -0
  256. package/server/save.d.ts +52 -0
  257. package/server/save.js +209 -0
  258. package/server/serve.d.ts +23 -0
  259. package/server/serve.js +413 -0
  260. package/server/test-connection.d.ts +17 -0
  261. package/server/test-connection.js +362 -0
  262. package/server/test-key.d.ts +2 -0
  263. package/server/test-key.js +83 -0
  264. package/server/watch.d.ts +28 -0
  265. package/server/watch.js +93 -0
  266. package/server/zod-edit.d.ts +74 -0
  267. package/server/zod-edit.js +558 -0
  268. package/server.d.ts +8 -0
  269. package/server.js +8 -0
  270. package/setups.mjs +170 -0
  271. package/shared-carry.d.ts +114 -0
  272. package/shared-carry.js +523 -0
  273. package/shared-settings.d.ts +34 -0
  274. package/shared-settings.js +70 -0
  275. package/source.d.ts +75 -0
  276. package/source.js +414 -0
  277. package/start.mjs +169 -0
  278. package/stream-lines.d.ts +9 -0
  279. package/stream-lines.js +27 -0
  280. package/stub.d.ts +6 -0
  281. package/stub.js +33 -0
  282. package/surface.d.ts +53 -0
  283. package/surface.js +631 -0
  284. package/system-markup.d.ts +20 -0
  285. package/system-markup.js +51 -0
  286. package/tool-schema.d.ts +23 -0
  287. package/tool-schema.js +69 -0
  288. package/tools.d.ts +16 -0
  289. package/tools.js +91 -0
  290. package/traces.d.ts +24 -0
  291. package/traces.js +29 -0
  292. package/transport.d.ts +57 -0
  293. package/transport.js +187 -0
  294. package/tree.d.ts +32 -0
  295. package/tree.js +83 -0
  296. package/types.d.ts +62 -0
  297. package/types.js +6 -0
  298. package/ui/acting-as-button.d.ts +2 -0
  299. package/ui/acting-as-button.js +16 -0
  300. package/ui/add-provider.d.ts +13 -0
  301. package/ui/add-provider.js +20 -0
  302. package/ui/boot-mark.css +53 -0
  303. package/ui/boot-mark.d.ts +19 -0
  304. package/ui/boot-mark.js +128 -0
  305. package/ui/boot-paint.d.ts +8 -0
  306. package/ui/boot-paint.js +8 -0
  307. package/ui/brand-icons.d.ts +57 -0
  308. package/ui/brand-icons.js +148 -0
  309. package/ui/built/theme.css +830 -0
  310. package/ui/built/theme.css.d.ts +9 -0
  311. package/ui/built/theorem-studio.d.ts +13 -0
  312. package/ui/built/theorem-studio.js +705 -0
  313. package/ui/built/theorem-studio.variants.d.ts +28 -0
  314. package/ui/code/monaco-contributions.d.ts +45 -0
  315. package/ui/code/studio-code.d.ts +7 -0
  316. package/ui/code/studio-code.js +253 -0
  317. package/ui/code/studio-monaco.d.ts +44 -0
  318. package/ui/code/studio-monaco.js +48 -0
  319. package/ui/code/studio-ts.worker.d.ts +1 -0
  320. package/ui/code/studio-ts.worker.js +16 -0
  321. package/ui/code/studio-type-checker.d.ts +12 -0
  322. package/ui/code/studio-type-checker.js +308 -0
  323. package/ui/code/studio-type-sources.d.ts +26 -0
  324. package/ui/confirm-write.d.ts +12 -0
  325. package/ui/confirm-write.js +45 -0
  326. package/ui/diff-block.d.ts +21 -0
  327. package/ui/diff-block.js +17 -0
  328. package/ui/figtree.css +59 -0
  329. package/ui/file-place.d.ts +4 -0
  330. package/ui/file-place.js +26 -0
  331. package/ui/guardrail-tester.d.ts +18 -0
  332. package/ui/guardrail-tester.js +248 -0
  333. package/ui/inspector-context.d.ts +119 -0
  334. package/ui/inspector-context.js +84 -0
  335. package/ui/inspector.d.ts +247 -0
  336. package/ui/inspector.js +284 -0
  337. package/ui/lib/acting-as.d.ts +25 -0
  338. package/ui/lib/acting-as.js +90 -0
  339. package/ui/lib/boot-sequence.d.ts +32 -0
  340. package/ui/lib/boot-sequence.js +57 -0
  341. package/ui/lib/export-agent.d.ts +11 -0
  342. package/ui/lib/export-agent.js +335 -0
  343. package/ui/lib/facet-icons.d.ts +20 -0
  344. package/ui/lib/facet-icons.js +21 -0
  345. package/ui/lib/panel-motion.d.ts +8 -0
  346. package/ui/lib/panel-motion.js +74 -0
  347. package/ui/lib/project-address.d.ts +14 -0
  348. package/ui/lib/project-address.js +24 -0
  349. package/ui/lib/project-starting.d.ts +13 -0
  350. package/ui/lib/project-starting.js +30 -0
  351. package/ui/lib/project-traces.d.ts +17 -0
  352. package/ui/lib/project-traces.js +54 -0
  353. package/ui/lib/read-map.d.ts +30 -0
  354. package/ui/lib/read-map.js +173 -0
  355. package/ui/lib/read-progress.d.ts +14 -0
  356. package/ui/lib/read-progress.js +12 -0
  357. package/ui/lib/refusal-lines.d.ts +3 -0
  358. package/ui/lib/refusal-lines.js +8 -0
  359. package/ui/lib/studio-activity.d.ts +5 -0
  360. package/ui/lib/studio-activity.js +17 -0
  361. package/ui/lib/studio-console.d.ts +27 -0
  362. package/ui/lib/studio-console.js +9 -0
  363. package/ui/lib/studio-conversation.d.ts +20 -0
  364. package/ui/lib/studio-conversation.js +130 -0
  365. package/ui/lib/studio-examples.d.ts +31 -0
  366. package/ui/lib/studio-examples.js +25 -0
  367. package/ui/lib/studio-labels.d.ts +6 -0
  368. package/ui/lib/studio-labels.js +13 -0
  369. package/ui/lib/studio-map-kept.d.ts +17 -0
  370. package/ui/lib/studio-map-kept.js +48 -0
  371. package/ui/lib/studio-open.d.ts +22 -0
  372. package/ui/lib/studio-open.js +54 -0
  373. package/ui/lib/studio-page.d.ts +33 -0
  374. package/ui/lib/studio-page.js +121 -0
  375. package/ui/lib/studio-prefs.d.ts +26 -0
  376. package/ui/lib/studio-prefs.js +87 -0
  377. package/ui/lib/studio-project.d.ts +106 -0
  378. package/ui/lib/studio-project.js +177 -0
  379. package/ui/lib/studio-restore.d.ts +49 -0
  380. package/ui/lib/studio-restore.js +251 -0
  381. package/ui/lib/studio-run-open.d.ts +15 -0
  382. package/ui/lib/studio-run-open.js +16 -0
  383. package/ui/lib/studio-session.d.ts +34 -0
  384. package/ui/lib/studio-session.js +17 -0
  385. package/ui/lib/studio-settings.d.ts +15 -0
  386. package/ui/lib/studio-settings.js +48 -0
  387. package/ui/lib/studio-store.d.ts +64 -0
  388. package/ui/lib/studio-store.js +391 -0
  389. package/ui/lib/studio-watch.d.ts +12 -0
  390. package/ui/lib/studio-watch.js +27 -0
  391. package/ui/lib/tab-fills.d.ts +6 -0
  392. package/ui/lib/tab-fills.js +14 -0
  393. package/ui/lib/tool-credentials.d.ts +3 -0
  394. package/ui/lib/tool-credentials.js +23 -0
  395. package/ui/lib/tool-probe.d.ts +19 -0
  396. package/ui/lib/tool-probe.js +104 -0
  397. package/ui/lib/type-icons.d.ts +35 -0
  398. package/ui/lib/type-icons.js +38 -0
  399. package/ui/lib/when-idle.d.ts +5 -0
  400. package/ui/lib/when-idle.js +14 -0
  401. package/ui/lib/zip.d.ts +5 -0
  402. package/ui/lib/zip.js +8 -0
  403. package/ui/map-token.css +11 -0
  404. package/ui/map-token.d.ts +17 -0
  405. package/ui/map-token.js +29 -0
  406. package/ui/mcp-icon.d.ts +6 -0
  407. package/ui/mcp-icon.js +8 -0
  408. package/ui/motion.css +113 -0
  409. package/ui/pan.d.ts +32 -0
  410. package/ui/pan.js +90 -0
  411. package/ui/profile-editor.d.ts +33 -0
  412. package/ui/profile-editor.js +2638 -0
  413. package/ui/provider-editor.d.ts +15 -0
  414. package/ui/provider-editor.js +92 -0
  415. package/ui/read-map.css +48 -0
  416. package/ui/read-map.d.ts +7 -0
  417. package/ui/read-map.js +163 -0
  418. package/ui/refusal-detail.d.ts +4 -0
  419. package/ui/refusal-detail.js +21 -0
  420. package/ui/shared-change.d.ts +9 -0
  421. package/ui/shared-change.js +28 -0
  422. package/ui/shell-motion.css +121 -0
  423. package/ui/shell-motion.d.ts +73 -0
  424. package/ui/shell-motion.js +194 -0
  425. package/ui/studio-code-pane.d.ts +19 -0
  426. package/ui/studio-code-pane.js +44 -0
  427. package/ui/studio-compare.d.ts +80 -0
  428. package/ui/studio-compare.js +326 -0
  429. package/ui/studio-conflicts.d.ts +17 -0
  430. package/ui/studio-conflicts.js +87 -0
  431. package/ui/studio-connection.d.ts +64 -0
  432. package/ui/studio-connection.js +286 -0
  433. package/ui/studio-decision.d.ts +6 -0
  434. package/ui/studio-decision.js +49 -0
  435. package/ui/studio-embedding.d.ts +6 -0
  436. package/ui/studio-embedding.js +30 -0
  437. package/ui/studio-host-console.d.ts +6 -0
  438. package/ui/studio-host-console.js +17 -0
  439. package/ui/studio-host.d.ts +73 -0
  440. package/ui/studio-host.js +12 -0
  441. package/ui/studio-live.d.ts +17 -0
  442. package/ui/studio-live.js +26 -0
  443. package/ui/studio-map.css +273 -0
  444. package/ui/studio-map.d.ts +17 -0
  445. package/ui/studio-map.js +397 -0
  446. package/ui/studio-nav.d.ts +24 -0
  447. package/ui/studio-nav.js +17 -0
  448. package/ui/studio-no-project.d.ts +5 -0
  449. package/ui/studio-no-project.js +9 -0
  450. package/ui/studio-run.css +76 -0
  451. package/ui/studio-run.d.ts +14 -0
  452. package/ui/studio-run.js +119 -0
  453. package/ui/studio-runner.d.ts +45 -0
  454. package/ui/studio-runner.js +187 -0
  455. package/ui/studio-save.d.ts +49 -0
  456. package/ui/studio-save.js +307 -0
  457. package/ui/studio-screen.d.ts +61 -0
  458. package/ui/studio-screen.js +2078 -0
  459. package/ui/studio-settings.d.ts +31 -0
  460. package/ui/studio-settings.js +288 -0
  461. package/ui/studio-shell.css +27 -0
  462. package/ui/studio-shell.d.ts +43 -0
  463. package/ui/studio-shell.js +87 -0
  464. package/ui/studio-theme.d.ts +7 -0
  465. package/ui/studio-theme.js +94 -0
  466. package/ui/studio.css +427 -0
  467. package/ui/theorem-mark.css +84 -0
  468. package/ui/theorem-mark.d.ts +22 -0
  469. package/ui/theorem-mark.js +21 -0
  470. package/vite.d.mts +30 -0
  471. package/vite.mjs +277 -0
  472. package/workspace.d.ts +230 -0
  473. package/workspace.js +1054 -0
@@ -0,0 +1,17 @@
1
+ import { type FileConflict } from '../mod.ts';
2
+ /** Opens the choice a Save waits on, while the files and the builder's edits conflict. */
3
+ export declare const ChooseConflictsContext: import("react").Context<(() => void) | undefined>;
4
+ /**
5
+ * The settings the studio and the source code both changed, each as a diff from the source code's
6
+ * value to the studio edit, and a choice of which stands. Resolving puts the chosen values in the
7
+ * studio; the source code is written at Save. Closing leaves the studio edits standing and the
8
+ * choice still to make.
9
+ */
10
+ export declare function FileConflicts({ conflicts, files, onApply, onClose, }: {
11
+ conflicts: readonly FileConflict[];
12
+ /** The files that changed, as the builder reads them: a name, or how many. */
13
+ files: string;
14
+ /** Called with the conflicts to take from the source code, by their place in `conflicts`. */
15
+ onApply: (theirs: number[]) => void;
16
+ onClose: () => void;
17
+ }): import("react").JSX.Element;
@@ -0,0 +1,87 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Button } from '@astryxdesign/core/Button';
3
+ import { Dialog, DialogHeader } from '@astryxdesign/core/Dialog';
4
+ import { HStack } from '@astryxdesign/core/HStack';
5
+ import { Layout, LayoutContent, LayoutFooter } from '@astryxdesign/core/Layout';
6
+ import { ScrollableArea } from '@astryxdesign/core/ScrollableArea';
7
+ import { StackItem } from '@astryxdesign/core/Stack';
8
+ import { Text } from '@astryxdesign/core/Text';
9
+ import { ToggleButton, ToggleButtonGroup } from '@astryxdesign/core/ToggleButton';
10
+ import { VStack } from '@astryxdesign/core/VStack';
11
+ import { createContext, useState } from 'react';
12
+ import { lineDiff } from "../mod.js";
13
+ import { DiffBlock } from "./diff-block.js";
14
+ const DIALOG_WIDTH = 720;
15
+ const DIFF_MAX_HEIGHT = '20rem';
16
+ /** Opens the choice a Save waits on, while the files and the builder's edits conflict. */
17
+ export const ChooseConflictsContext = createContext(undefined);
18
+ const SIDE_NAME = { studio: 'Studio edit', source: 'Source code' };
19
+ /** A conflict's setting as the Save review names one: whose it is, then the path to it. */
20
+ function settingName(conflict) {
21
+ const path = conflict.path
22
+ .map((part) => (typeof part === 'number' ? `#${String(part + 1)}` : part))
23
+ .join('.')
24
+ .replaceAll('.#', ' #');
25
+ return path ? `${conflict.name} · ${path}` : conflict.name;
26
+ }
27
+ /** One side's value as text. A whole agent or tool is said, not printed. */
28
+ function valueText(conflict, side) {
29
+ const [value, other] = side === 'studio' ? [conflict.mine, conflict.theirs] : [conflict.theirs, conflict.mine];
30
+ // A whole agent or tool, or one row of a list, is there or taken out.
31
+ const isWhole = conflict.path.length === 0;
32
+ if (isWhole || typeof conflict.path.at(-1) === 'number') {
33
+ if (value === undefined)
34
+ return '(removed)';
35
+ if (isWhole && other === undefined)
36
+ return side === 'studio' ? '(kept, with studio edits)' : '(kept, and changed)';
37
+ }
38
+ if (value === undefined || value === null || value === '')
39
+ return '(not set)';
40
+ if (typeof value === 'string')
41
+ return value;
42
+ // A row's key is the studio's own name for it, and says nothing to the builder.
43
+ return JSON.stringify(value, (field, inner) => (field === 'key' ? undefined : inner), 2);
44
+ }
45
+ /** One conflict's setting, the same however the list around it changes. */
46
+ function conflictId(conflict) {
47
+ return `${conflict.kind}:${conflict.key}:${conflict.path.join('.')}`;
48
+ }
49
+ /**
50
+ * The settings the studio and the source code both changed, each as a diff from the source code's
51
+ * value to the studio edit, and a choice of which stands. Resolving puts the chosen values in the
52
+ * studio; the source code is written at Save. Closing leaves the studio edits standing and the
53
+ * choice still to make.
54
+ */
55
+ export function FileConflicts({ conflicts, files, onApply, onClose, }) {
56
+ // Picks go by setting, not by place: the files can change while this is open, and the list with them.
57
+ const [picks, setPicks] = useState({});
58
+ const all = (side) => {
59
+ setPicks(Object.fromEntries(conflicts.map((conflict) => [conflictId(conflict), side])));
60
+ };
61
+ const one = conflicts.length === 1;
62
+ // With no one file to name, the side's own name says it.
63
+ const sourceName = files === 'source code' ? SIDE_NAME.source : `${SIDE_NAME.source} (${files})`;
64
+ const count = one ? '1 setting' : `${String(conflicts.length)} settings`;
65
+ return (_jsx(Dialog, { isOpen: true, width: DIALOG_WIDTH, maxHeight: "80vh", onOpenChange: (isOpen) => {
66
+ if (!isOpen)
67
+ onClose();
68
+ }, children: _jsx(Layout, { header: _jsx(DialogHeader, { title: "Studio edits conflict with source code", subtitle: `${count} changed both in the studio and in ${files}. Choose which value each keeps.` }), content: _jsx(LayoutContent, { isScrollable: false, padding: 0, children: _jsx(ScrollableArea, { label: "Conflicts", height: "100%", paddingInline: 4, children: _jsx(VStack, { gap: 5, children: conflicts.map((conflict) => {
69
+ const id = conflictId(conflict);
70
+ const pick = picks[id] ?? 'studio';
71
+ const name = settingName(conflict);
72
+ return (_jsxs(VStack, { gap: 2, children: [_jsxs(HStack, { gap: 3, vAlign: "center", justify: "between", children: [_jsx(StackItem, { size: "fill", children: _jsx(Text, { weight: "semibold", children: name }) }), _jsxs(ToggleButtonGroup, { label: `Which value ${name} keeps`, size: "sm", value: pick, onChange: (next) => {
73
+ // Pressing the kept one again leaves it kept: one always stands.
74
+ if (next === 'studio' || next === 'source')
75
+ setPicks((held) => ({ ...held, [id]: next }));
76
+ }, children: [_jsx(ToggleButton, { value: "source", label: "Keep source code" }), _jsx(ToggleButton, { value: "studio", label: "Keep studio edit" })] })] }), _jsx(DiffBlock, { lines: lineDiff(valueText(conflict, 'source'), valueText(conflict, 'studio')), sides: {
77
+ removed: sourceName,
78
+ added: SIDE_NAME.studio,
79
+ }, kept: pick === 'studio' ? '+' : '-', isWrapped: true, maxHeight: DIFF_MAX_HEIGHT })] }, id));
80
+ }) }) }) }), footer: _jsx(LayoutFooter, { children: _jsxs(HStack, { gap: 2, justify: "between", children: [_jsx(HStack, { gap: 2, children: !one && (_jsxs(_Fragment, { children: [_jsx(Button, { label: "Keep all source code", variant: "ghost", onClick: () => {
81
+ all('source');
82
+ } }), _jsx(Button, { label: "Keep all studio edits", variant: "ghost", onClick: () => {
83
+ all('studio');
84
+ } })] })) }), _jsx(Button, { label: one ? 'Resolve conflict' : `Resolve ${String(conflicts.length)} conflicts`, variant: "primary", onClick: () => {
85
+ onApply(conflicts.flatMap((conflict, index) => picks[conflictId(conflict)] === 'source' ? [index] : []));
86
+ } })] }) }) }) }));
87
+ }
@@ -0,0 +1,64 @@
1
+ import { type Dispatch, type SetStateAction } from 'react';
2
+ import { type ListedProfileType, type ListedProvider, type ProviderModel } from '../browser-connection.ts';
3
+ import type { StudioBrowserRuntime } from '../browser-transport.ts';
4
+ import { type ModelRoute, type StudioRunsOn } from '../mod.ts';
5
+ import type { StudioSupplies } from './studio-host.ts';
6
+ type KeyEntry = {
7
+ id: string;
8
+ slot: string;
9
+ };
10
+ type LocalModels = {
11
+ status: 'idle' | 'loading' | 'ready' | 'error';
12
+ ids: string[];
13
+ error?: string;
14
+ };
15
+ /** Models select execution; the vault and connection settings remain in this tab's memory. */
16
+ export declare function useStudioConnection(models: readonly (ModelRoute & {
17
+ builtInTools?: string[];
18
+ local: boolean;
19
+ })[], initialBaseUrl?: string, namedSlots?: readonly string[], { lentKeys: keys, toolHandlers }?: StudioSupplies): {
20
+ entries: KeyEntry[];
21
+ setEntries: Dispatch<SetStateAction<KeyEntry[]>>;
22
+ localModels: LocalModels;
23
+ mode: "local" | "demo" | "byok";
24
+ on: StudioRunsOn;
25
+ runtime: StudioBrowserRuntime | null;
26
+ vault: Readonly<Record<string, string | undefined>>;
27
+ setVault: Dispatch<SetStateAction<Readonly<Record<string, string | undefined>>>>;
28
+ slots: string[];
29
+ local: {
30
+ baseUrl: string;
31
+ };
32
+ setLocal: Dispatch<SetStateAction<{
33
+ baseUrl: string;
34
+ }>>;
35
+ remoteTools: boolean;
36
+ setRemoteTools: Dispatch<SetStateAction<boolean>>;
37
+ };
38
+ export type StudioConnectionState = ReturnType<typeof useStudioConnection>;
39
+ export type ProviderModels = {
40
+ status: 'idle' | 'loading';
41
+ models: ProviderModel[];
42
+ } | {
43
+ status: 'ready';
44
+ models: ProviderModel[];
45
+ } | {
46
+ status: 'error';
47
+ models: ProviderModel[];
48
+ error: string;
49
+ };
50
+ /**
51
+ * The models a provider offers for this profile type, listed with the key in the slot the model
52
+ * reads. OpenRouter lists without a key; Gemini waits for one.
53
+ */
54
+ export declare function useProviderModels(provider: ListedProvider | undefined, type: ListedProfileType, secret: string | undefined): ProviderModels;
55
+ /** What a slot holds, for a slot picker: the service its key is for, or that it is empty. */
56
+ export declare function slotDescription(secret: string | undefined): string;
57
+ /** Key mappings use the editor's own section and compact controls. */
58
+ export declare function StudioKeys({ connection, onRenameSlot, onAddSlot, onRemoveSlot, }: {
59
+ connection: StudioConnectionState;
60
+ onRenameSlot?: (from: string, to: string) => void;
61
+ onAddSlot?: (slot: string) => void;
62
+ onRemoveSlot?: (slot: string) => void;
63
+ }): import("react").JSX.Element;
64
+ export {};
@@ -0,0 +1,286 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { HStack } from '@astryxdesign/core/HStack';
3
+ import { Icon } from '@astryxdesign/core/Icon';
4
+ import { IconButton } from '@astryxdesign/core/IconButton';
5
+ import { StackItem } from '@astryxdesign/core/Stack';
6
+ import { TextInput } from '@astryxdesign/core/TextInput';
7
+ import { VStack } from '@astryxdesign/core/VStack';
8
+ import { IconEye, IconEyeOff, IconKey, IconPlayerEject, IconPlus, IconTrash, } from '@tabler/icons-react';
9
+ import { isKeySlotName } from '@theoremjs/agents';
10
+ import { useEffect, useMemo, useState } from 'react';
11
+ import { keyKind, listLocalStudioModels, listProviderModels, localStudioConfig, STUDIO_KEY_SLOT_CAP, studioVault, } from "../browser-connection.js";
12
+ import { ON_OWN_KEYS, sectionNote, } from "../mod.js";
13
+ import { IconGemini, IconOpenRouter } from "./brand-icons.js";
14
+ import { InspectorSection } from "./inspector.js";
15
+ const withoutSlot = (vault, slot) => Object.fromEntries(Object.entries(vault).filter(([name]) => name !== slot));
16
+ /** The models a local server offers at `local`, listed again shortly after the endpoint settles. */
17
+ function useLocalModels(hasLocal, local) {
18
+ const [localModels, setLocalModels] = useState({ status: 'idle', ids: [] });
19
+ useEffect(() => {
20
+ if (!hasLocal || !local.baseUrl.trim()) {
21
+ setLocalModels({ status: 'idle', ids: [] });
22
+ return;
23
+ }
24
+ const controller = new AbortController();
25
+ setLocalModels({ status: 'loading', ids: [] });
26
+ const timer = globalThis.setTimeout(() => {
27
+ void listLocalStudioModels(local, AbortSignal.any([controller.signal, AbortSignal.timeout(8000)]))
28
+ .then((ids) => {
29
+ if (!controller.signal.aborted)
30
+ setLocalModels({ status: 'ready', ids });
31
+ })
32
+ .catch(() => {
33
+ if (!controller.signal.aborted)
34
+ setLocalModels({
35
+ status: 'error',
36
+ ids: [],
37
+ error: 'Couldn’t load models. Check the endpoint and local server.',
38
+ });
39
+ });
40
+ }, 350);
41
+ return () => {
42
+ globalThis.clearTimeout(timer);
43
+ controller.abort();
44
+ };
45
+ }, [hasLocal, local]);
46
+ return localModels;
47
+ }
48
+ /**
49
+ * Local when every model is local. The page's lent keys when it lends some, nothing is local or
50
+ * keyed, and every model runs on them. Otherwise the builder's own keys.
51
+ */
52
+ function runsOn(models, hasLocal, hasKeys, keys) {
53
+ if (hasLocal && models.every((model) => model.local))
54
+ return { mode: 'local' };
55
+ if (!keys || hasLocal || hasKeys)
56
+ return ON_OWN_KEYS;
57
+ const lent = models.every((model) => keys.runs(model.profileType, model.definition) &&
58
+ keys.violation({ ...model, builtInTools: model.builtInTools ?? [] }) === null);
59
+ return lent ? { mode: 'demo', keys } : ON_OWN_KEYS;
60
+ }
61
+ /** The local server's config; an invalid edit refuses execution rather than falling back to the hosted demo. */
62
+ function localRuntimeConfig(local) {
63
+ try {
64
+ return localStudioConfig(local);
65
+ }
66
+ catch (error) {
67
+ return {
68
+ baseUrl: local.baseUrl,
69
+ fetch: () => Promise.reject(error instanceof Error ? error : new Error(String(error))),
70
+ };
71
+ }
72
+ }
73
+ /**
74
+ * The key rows: one per slot the draft names or key the vault holds. Typing a slot name in the
75
+ * editor must not leave a row behind for every prefix. Unnamed rows stay until removed.
76
+ */
77
+ function useKeyEntries(slots) {
78
+ const [entries, setEntries] = useState([]);
79
+ useEffect(() => {
80
+ setEntries((current) => [
81
+ ...current.filter((entry) => !entry.slot || slots.includes(entry.slot)),
82
+ ...slots
83
+ .filter((slot) => !current.some((entry) => entry.slot === slot))
84
+ .map((slot) => ({ id: crypto.randomUUID(), slot })),
85
+ ]);
86
+ }, [slots]);
87
+ return [entries, setEntries];
88
+ }
89
+ /** The runtime the runner executes on, or null for the demo; each new one aborts the last. */
90
+ function useConnectionRuntime(mode, hasLocal, vault, local, remoteTools, slots, toolHandlers) {
91
+ const connection = useMemo(() => {
92
+ if (mode === 'demo')
93
+ return null;
94
+ const controller = new AbortController();
95
+ const localConfig = hasLocal ? localRuntimeConfig(local) : undefined;
96
+ const slotted = studioVault(slots, vault);
97
+ return {
98
+ controller,
99
+ runtime: {
100
+ mode,
101
+ signal: controller.signal,
102
+ remoteTools: hasLocal ? remoteTools : true,
103
+ providers: { vault: slotted, ...(localConfig ? { local: localConfig } : {}) },
104
+ decision: { vault: slotted },
105
+ toolHandlers,
106
+ },
107
+ };
108
+ }, [mode, hasLocal, vault, local, remoteTools, slots, toolHandlers]);
109
+ useEffect(() => () => {
110
+ connection?.controller.abort();
111
+ }, [connection]);
112
+ return connection?.runtime ?? null;
113
+ }
114
+ /** Models select execution; the vault and connection settings remain in this tab's memory. */
115
+ export function useStudioConnection(models, initialBaseUrl = 'http://127.0.0.1:11434', namedSlots = [], { lentKeys: keys, toolHandlers } = {}) {
116
+ const [vault, setVault] = useState({});
117
+ const [local, setLocal] = useState({
118
+ baseUrl: initialBaseUrl,
119
+ });
120
+ const [remoteTools, setRemoteTools] = useState(false);
121
+ const slotNames = [...new Set([...namedSlots, ...Object.keys(vault)])].join('\n');
122
+ const slots = useMemo(() => (slotNames ? slotNames.split('\n') : []), [slotNames]);
123
+ const [entries, setEntries] = useKeyEntries(slots);
124
+ const hasLocal = models.some((model) => model.local);
125
+ const localModels = useLocalModels(hasLocal, local);
126
+ const hasKeys = Object.values(vault).some((key) => Boolean(key?.trim()));
127
+ const mode = runsOn(models, hasLocal, hasKeys, keys).mode;
128
+ // One value per mode, so a render that keeps the mode keeps it too.
129
+ const on = useMemo(() => mode === 'demo' && keys ? { mode, keys } : mode === 'local' ? { mode } : ON_OWN_KEYS, [mode, keys]);
130
+ const runtime = useConnectionRuntime(mode, hasLocal, vault, local, remoteTools, slots, toolHandlers);
131
+ // One object while nothing in it changes, so panes that only read the connection can sit out a render.
132
+ return useMemo(() => ({
133
+ entries,
134
+ setEntries,
135
+ localModels,
136
+ mode,
137
+ on,
138
+ runtime,
139
+ vault,
140
+ setVault,
141
+ slots,
142
+ local,
143
+ setLocal,
144
+ remoteTools,
145
+ setRemoteTools,
146
+ }), [entries, setEntries, localModels, mode, on, runtime, vault, slots, local, remoteTools]);
147
+ }
148
+ /** Lists already fetched this tab, by provider, profile type, and key; a list barely changes. */
149
+ const listed = new Map();
150
+ /**
151
+ * The models a provider offers for this profile type, listed with the key in the slot the model
152
+ * reads. OpenRouter lists without a key; Gemini waits for one.
153
+ */
154
+ export function useProviderModels(provider, type, secret) {
155
+ const key = secret?.trim() ?? '';
156
+ const id = provider ? [provider, type, key].join('\n') : '';
157
+ const [state, setState] = useState({
158
+ id: '',
159
+ status: 'idle',
160
+ models: [],
161
+ });
162
+ useEffect(() => {
163
+ const cached = listed.get(id);
164
+ if (!provider || cached) {
165
+ setState({ id, status: cached ? 'ready' : 'idle', models: cached ?? [] });
166
+ return;
167
+ }
168
+ if (provider === 'gemini' && !key && type !== 'embedding') {
169
+ setState({ id, status: 'idle', models: [] });
170
+ return;
171
+ }
172
+ const controller = new AbortController();
173
+ setState({ id, status: 'loading', models: [] });
174
+ const timer = globalThis.setTimeout(() => {
175
+ void listProviderModels(provider, type, key || undefined, AbortSignal.any([controller.signal, AbortSignal.timeout(10_000)]))
176
+ .then((models) => {
177
+ listed.set(id, models);
178
+ if (!controller.signal.aborted)
179
+ setState({ id, status: 'ready', models });
180
+ })
181
+ .catch((error) => {
182
+ if (!controller.signal.aborted)
183
+ setState({
184
+ id,
185
+ status: 'error',
186
+ models: [],
187
+ error: error instanceof Error ? error.message : 'Couldn’t list models.',
188
+ });
189
+ });
190
+ }, 350);
191
+ return () => {
192
+ globalThis.clearTimeout(timer);
193
+ controller.abort();
194
+ };
195
+ }, [id, provider, type, key]);
196
+ // Until the effect catches up with a new key, the old list isn't this key's.
197
+ return state.id === id ? state : { status: provider ? 'loading' : 'idle', models: [] };
198
+ }
199
+ /** What a slot holds, for a slot picker: the service its key is for, or that it is empty. */
200
+ export function slotDescription(secret) {
201
+ if (!secret?.trim())
202
+ return 'No key yet';
203
+ const kind = keyKind(secret);
204
+ return kind ? KEY_KINDS[kind].label : 'Key';
205
+ }
206
+ /** The icon follows the pasted key; a key whose service its prefix doesn't show gets a plain key. */
207
+ const KEY_KINDS = {
208
+ gemini: { icon: IconGemini, label: 'Gemini key' },
209
+ openrouter: { icon: IconOpenRouter, label: 'OpenRouter key' },
210
+ };
211
+ /** Key mappings use the editor's own section and compact controls. */
212
+ export function StudioKeys({ connection, onRenameSlot, onAddSlot, onRemoveSlot, }) {
213
+ return (_jsx(InspectorSection, { note: sectionNote('connection'), children: _jsxs(VStack, { gap: 2, children: [connection.entries.map((entry) => (_jsx(KeyRow, { entry: entry, connection: connection, onRenameSlot: onRenameSlot, onAddSlot: onAddSlot, onRemoveSlot: onRemoveSlot }, entry.id))), _jsx(HStack, { children: _jsx(IconButton, { label: "Add key", variant: "ghost", size: "sm", icon: _jsx(Icon, { icon: IconPlus, size: "sm" }), isDisabled: connection.entries.length >= STUDIO_KEY_SLOT_CAP, onClick: () => {
214
+ connection.setEntries((current) => [
215
+ ...current,
216
+ { id: crypto.randomUUID(), slot: '' },
217
+ ]);
218
+ } }) })] }) }));
219
+ }
220
+ function KeyRow({ entry, connection, onRenameSlot, onAddSlot, onRemoveSlot }) {
221
+ const secret = Object.hasOwn(connection.vault, entry.slot)
222
+ ? (connection.vault[entry.slot] ?? '')
223
+ : '';
224
+ const { name, setName, error, rename } = useSlotName(entry, connection, secret, onRenameSlot, onAddSlot);
225
+ const [visible, setVisible] = useState(false);
226
+ return (_jsxs(HStack, { gap: 2, vAlign: "center", children: [_jsx(StackItem, { size: "static", children: _jsx(KeyKindIcon, { secret: secret }) }), _jsx(StackItem, { size: "fill", children: _jsx(TextInput, { label: "Key name", hasAutoFocus: !entry.slot, isLabelHidden: true, size: "sm", value: name, placeholder: "Key name", onChange: setName, onBlur: rename, status: error ? { type: 'error', message: error } : undefined }) }), _jsx(StackItem, { size: "fill", children: _jsx(KeySecretInput, { entry: entry, connection: connection, secret: secret, visible: visible }) }), _jsx(StackItem, { size: "static", children: _jsx(KeyRowActions, { entry: entry, connection: connection, visible: visible, setVisible: setVisible, onRemoveSlot: onRemoveSlot }) })] }));
227
+ }
228
+ /** The pasted key's service, or a plain key. */
229
+ function KeyKindIcon({ secret }) {
230
+ const kind = keyKind(secret);
231
+ return (_jsx(Icon, { icon: kind ? KEY_KINDS[kind].icon : IconKey, size: "sm", color: "secondary", label: kind ? KEY_KINDS[kind].label : 'Key' }));
232
+ }
233
+ /** The key itself, written to the vault under the row's slot; disabled until the slot has a name. */
234
+ function KeySecretInput({ entry, connection, secret, visible, }) {
235
+ return (_jsx(TextInput, { label: "API key", isLabelHidden: true, size: "sm", type: visible ? 'text' : 'password', value: secret, placeholder: "API key", autoComplete: "off", isDisabled: !entry.slot, onChange: (value) => {
236
+ connection.setVault((current) => ({
237
+ ...current,
238
+ [entry.slot]: value.trim() || undefined,
239
+ }));
240
+ } }));
241
+ }
242
+ /** A row's slot name as typed, committed on blur once it is valid and free. */
243
+ function useSlotName(entry, connection, secret, onRenameSlot, onAddSlot) {
244
+ const [name, setName] = useState(entry.slot);
245
+ useEffect(() => {
246
+ setName(entry.slot);
247
+ }, [entry.slot]);
248
+ const [error, setError] = useState();
249
+ const rename = () => {
250
+ if (name === entry.slot)
251
+ return;
252
+ if (!isKeySlotName(name)) {
253
+ setError('Use a valid slot name, up to 32 characters.');
254
+ return;
255
+ }
256
+ if (connection.entries.some((other) => other.id !== entry.id && other.slot === name)) {
257
+ setError('This key name already exists.');
258
+ return;
259
+ }
260
+ connection.setVault((current) => ({
261
+ ...withoutSlot(current, entry.slot),
262
+ [name]: secret || undefined,
263
+ }));
264
+ connection.setEntries((current) => current.map((other) => (other.id === entry.id ? { ...other, slot: name } : other)));
265
+ if (entry.slot)
266
+ onRenameSlot?.(entry.slot, name);
267
+ else
268
+ onAddSlot?.(name);
269
+ setError(undefined);
270
+ };
271
+ return { name, setName, error, rename };
272
+ }
273
+ /** Show or hide the key, and remove the row (or, where the profile names its slot, clear the key). */
274
+ function KeyRowActions({ entry, connection, visible, setVisible, onRemoveSlot, }) {
275
+ // Where the profile can't drop a slot it names (the run tab), its row stays and only the key goes.
276
+ const removable = onRemoveSlot !== undefined || !entry.slot;
277
+ return (_jsxs(HStack, { gap: 1, children: [_jsx(IconButton, { label: visible ? 'Hide key' : 'Show key', variant: "ghost", size: "sm", icon: _jsx(Icon, { icon: visible ? IconEyeOff : IconEye, size: "sm" }), onClick: () => {
278
+ setVisible((current) => !current);
279
+ } }), _jsx(IconButton, { label: removable ? 'Remove key' : 'Clear key', variant: "ghost", size: "sm", icon: _jsx(Icon, { icon: removable ? IconTrash : IconPlayerEject, size: "sm" }), onClick: () => {
280
+ connection.setVault((current) => withoutSlot(current, entry.slot));
281
+ if (!removable)
282
+ return;
283
+ connection.setEntries((current) => current.filter((other) => other.id !== entry.id));
284
+ onRemoveSlot?.(entry.slot);
285
+ } })] }));
286
+ }
@@ -0,0 +1,6 @@
1
+ import { type TheoremDecisionProps } from '@theoremjs/react/ui';
2
+ import { type ConsoleViewProps, type StudioConsoleProps } from './lib/studio-console.ts';
3
+ /** The same decision runner in the builder preview and the standalone run tab. */
4
+ export declare function StudioDecision(props: StudioConsoleProps): import("react").JSX.Element;
5
+ /** A decision on `transport`, seeded for its profile, its questions linked to the editor. */
6
+ export declare function DecisionView({ payload, transport, trace, flush, columns, className, }: ConsoleViewProps & Pick<TheoremDecisionProps, 'transport'>): import("react").JSX.Element;
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TheoremDecision } from '@theoremjs/react/ui';
3
+ import { use, useContext, useMemo } from 'react';
4
+ import { createBrowserStudioDecisionTransport } from "../browser.js";
5
+ import { createStudioDecisionTransport, DECISION_EXAMPLE_AGENT_ID, DECISION_EXAMPLE_STATE, decisionExampleAssets, EXAMPLE_DECISION_STATE, EXAMPLE_SPAN_DECISION_STATE, } from "../mod.js";
6
+ import { QuestionLink } from "./inspector-context.js";
7
+ import { useStudioTransport, } from "./lib/studio-console.js";
8
+ let exampleAssets;
9
+ /**
10
+ * What a decision's form starts with: an example its model can be asked about, and the pictures the
11
+ * example names. The example's pictures load the first time; until then the form suspends.
12
+ */
13
+ function useDecisionSeed(payload) {
14
+ if (payload.agentId === DECISION_EXAMPLE_AGENT_ID) {
15
+ exampleAssets ??= decisionExampleAssets();
16
+ return { defaultState: DECISION_EXAMPLE_STATE, defaultImages: { ...use(exampleAssets) } };
17
+ }
18
+ const { profile } = payload;
19
+ const model = profile.type === 'decision' ? Object.values(profile.models)[0] : undefined;
20
+ return {
21
+ defaultState: model?.apiId.startsWith('respan/')
22
+ ? EXAMPLE_SPAN_DECISION_STATE
23
+ : EXAMPLE_DECISION_STATE,
24
+ };
25
+ }
26
+ /** An instruction as one line of text: its own words, with a structured one's parts in order. */
27
+ function entryText(entry) {
28
+ if (typeof entry === 'string')
29
+ return entry;
30
+ if (Array.isArray(entry))
31
+ return entry.map(entryText).join(' ');
32
+ return Object.entries(entry)
33
+ .map(([key, value]) => `${key}: ${entryText(value)}`)
34
+ .join(' ');
35
+ }
36
+ /** The same decision runner in the builder preview and the standalone run tab. */
37
+ export function StudioDecision(props) {
38
+ const transport = useStudioTransport(props, createStudioDecisionTransport, createBrowserStudioDecisionTransport);
39
+ return _jsx(DecisionView, { ...props, transport: transport });
40
+ }
41
+ /** A decision on `transport`, seeded for its profile, its questions linked to the editor. */
42
+ export function DecisionView({ payload, transport, trace, flush, columns, className, }) {
43
+ const { open } = useContext(QuestionLink);
44
+ const seed = useDecisionSeed(payload);
45
+ const { questions } = payload;
46
+ const questionText = useMemo(() => questions &&
47
+ Object.fromEntries(Object.entries(questions).map(([id, question]) => [id, entryText(question.instructions)])), [questions]);
48
+ return (_jsx(TheoremDecision, { transport: transport, ...seed, trace: trace, flush: flush, columns: columns, className: className, onQuestion: open, questionText: questionText }));
49
+ }
@@ -0,0 +1,6 @@
1
+ import { type TheoremEmbeddingProps } from '@theoremjs/react/ui';
2
+ import { type ConsoleViewProps, type StudioConsoleProps } from './lib/studio-console.ts';
3
+ /** The same embedding runner in the builder preview and the standalone run tab. */
4
+ export declare function StudioEmbedding(props: StudioConsoleProps): import("react").JSX.Element;
5
+ /** An embedding on `transport`, seeded with the example its profile takes. */
6
+ export declare function EmbeddingView({ payload, transport, trace, flush, columns, className, }: ConsoleViewProps & Pick<TheoremEmbeddingProps, 'transport'>): import("react").JSX.Element;
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TheoremEmbedding } from '@theoremjs/react/ui';
3
+ import { createBrowserStudioEmbeddingTransport } from "../browser.js";
4
+ import { createStudioEmbeddingTransport, EXAMPLE_EMBEDDING_FILES, EXAMPLE_EMBEDDING_QUERY, EXAMPLE_EMBEDDING_TEXT, } from "../mod.js";
5
+ import { useStudioTransport, } from "./lib/studio-console.js";
6
+ /** Whether a profile that accepts `accept` takes `mimeType`, by name or by its `type/*` family. */
7
+ function accepts(accept, mimeType) {
8
+ return accept.some((rule) => rule === mimeType || (rule.endsWith('/*') && mimeType.startsWith(rule.slice(0, -1))));
9
+ }
10
+ /** The documents and query an embedding starts with: the example, less what the profile does not take. */
11
+ function embeddingSeed(profile) {
12
+ if (profile.type !== 'embedding')
13
+ return { defaultText: EXAMPLE_EMBEDDING_TEXT, defaultQuery: EXAMPLE_EMBEDDING_QUERY };
14
+ const { text, attachments } = profile.inputs;
15
+ const defaultDocuments = EXAMPLE_EMBEDDING_FILES.filter(({ input }) => typeof input === 'string' ? text !== false : accepts(attachments?.accept ?? [], 'image/png'));
16
+ return {
17
+ defaultText: text === false ? '' : EXAMPLE_EMBEDDING_TEXT,
18
+ defaultQuery: text === false ? '' : EXAMPLE_EMBEDDING_QUERY,
19
+ defaultDocuments,
20
+ };
21
+ }
22
+ /** The same embedding runner in the builder preview and the standalone run tab. */
23
+ export function StudioEmbedding(props) {
24
+ const transport = useStudioTransport(props, createStudioEmbeddingTransport, createBrowserStudioEmbeddingTransport);
25
+ return _jsx(EmbeddingView, { ...props, transport: transport });
26
+ }
27
+ /** An embedding on `transport`, seeded with the example its profile takes. */
28
+ export function EmbeddingView({ payload, transport, trace, flush, columns, className, }) {
29
+ return (_jsx(TheoremEmbedding, { transport: transport, ...embeddingSeed(payload.profile), trace: trace, flush: flush, columns: columns, className: className }));
30
+ }
@@ -0,0 +1,6 @@
1
+ import { type TheoremHostProps } from '@theoremjs/react/ui';
2
+ import { type ConsoleViewProps, type StudioConsoleProps } from './lib/studio-console.ts';
3
+ /** The same tool console in the builder preview and the standalone run tab. */
4
+ export declare function StudioHostConsole(props: StudioConsoleProps): import("react").JSX.Element;
5
+ /** A host's tool console on `transport`, its page tools answered with their stubs. */
6
+ export declare function HostView({ payload, transport, trace, flush, columns, className, }: ConsoleViewProps & Pick<TheoremHostProps, 'transport'>): import("react").JSX.Element;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TheoremHost } from '@theoremjs/react/ui';
3
+ import { useMemo } from 'react';
4
+ import { createBrowserStudioHostTransport } from "../browser.js";
5
+ import { createStudioHostTransport, studioPageTools } from "../mod.js";
6
+ import { useStudioTransport, } from "./lib/studio-console.js";
7
+ import { STUDIO_LABELS } from "./lib/studio-labels.js";
8
+ /** The same tool console in the builder preview and the standalone run tab. */
9
+ export function StudioHostConsole(props) {
10
+ const transport = useStudioTransport(props, createStudioHostTransport, createBrowserStudioHostTransport);
11
+ return _jsx(HostView, { ...props, transport: transport });
12
+ }
13
+ /** A host's tool console on `transport`, its page tools answered with their stubs. */
14
+ export function HostView({ payload, transport, trace, flush, columns, className, }) {
15
+ const pageTools = useMemo(() => studioPageTools(payload), [payload]);
16
+ return (_jsx(TheoremHost, { detectCodeLanguage: true, labels: STUDIO_LABELS, transport: transport, pageTools: pageTools, trace: trace, flush: flush, columns: columns, className: className }));
17
+ }
@@ -0,0 +1,73 @@
1
+ import type { LentKeys, StudioSourceError, StudioSourceSpan, StudioToolHandlers, StudioWorkspace } from '../mod.ts';
2
+ import type { studioSurface } from '../surface.ts';
3
+ import type { ProjectSession } from './lib/studio-project.ts';
4
+ import type { RestoredStudio } from './lib/studio-session.ts';
5
+ /** What the studio opens on: the workspace, and what arriving set aside. */
6
+ export interface StudioOpened {
7
+ start: RestoredStudio;
8
+ /** A question the chat opens with. */
9
+ question: string | undefined;
10
+ /** A kept workspace this arrival replaced, offered back behind Undo. */
11
+ displaced: StudioWorkspace | undefined;
12
+ /** True when a kept workspace could not be read back. */
13
+ discarded: boolean;
14
+ /** The local project the studio is open on, when it is. */
15
+ project?: ProjectSession;
16
+ }
17
+ /** What reading the code view's text back found: its errors, and where each node sits in it. */
18
+ export interface CodeApply {
19
+ errors: StudioSourceError[];
20
+ spans: StudioSourceSpan[];
21
+ }
22
+ /** An issue the code view marks on the node it belongs to. */
23
+ export interface CodeIssue {
24
+ nodeId: string;
25
+ field?: string;
26
+ message: string;
27
+ }
28
+ /**
29
+ * The code view. `text` is the latest print; while the visitor is typing the view keeps their
30
+ * text. `hold` means there is no new print, so the text they have stays. `isReadOnly` shows the
31
+ * text and takes no edit.
32
+ */
33
+ export interface StudioCodeProps {
34
+ text: string;
35
+ hold: boolean;
36
+ isReadOnly?: boolean;
37
+ issues: readonly CodeIssue[];
38
+ onApply: (text: string) => CodeApply;
39
+ }
40
+ /** What the screen shows of the draft, for a host that follows along. */
41
+ export interface StudioReport {
42
+ agent: string;
43
+ type: string;
44
+ issues: number;
45
+ section: string | undefined;
46
+ }
47
+ export interface StudioHost {
48
+ /** The `@theoremjs/agents` version the studio runs, shown under its title. */
49
+ kernelVersion: string;
50
+ /** Mounts the screen's surface while the screen is open; returns the unmount. */
51
+ mountSurface?: (surface: ReturnType<typeof studioSurface>) => () => void;
52
+ /** Called as what is on screen changes, and with null when the screen closes. */
53
+ onReport?: (report: StudioReport | null) => void;
54
+ /**
55
+ * True when the host's page has a door to Settings (`SettingsRailButton`). The screen then
56
+ * shows Settings when asked, and Keys are there and not in the editor's header.
57
+ */
58
+ hasSettings?: boolean;
59
+ /**
60
+ * Keys the page lends to whoever opens the studio, and what runs on them. Without them the
61
+ * studio runs only on the builder's own keys or machine.
62
+ */
63
+ lentKeys?: LentKeys;
64
+ /**
65
+ * Handlers for the page's own function tools, by name, as its examples use them. A tool with
66
+ * none answers with its sample reply or a stub.
67
+ */
68
+ toolHandlers?: StudioToolHandlers;
69
+ }
70
+ /** What a page gives every studio it opens, the run tab's too. */
71
+ export type StudioSupplies = Pick<StudioHost, 'lentKeys' | 'toolHandlers'>;
72
+ export declare const StudioHostContext: import("react").Context<StudioHost | null>;
73
+ export declare function useStudioHost(): StudioHost;