@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,64 @@
1
+ import { type SharedReach, type SharedSites, type StudioDraft, type StudioWorkspace, type ToolReach, type ToolSpecDraft } from '../../mod.ts';
2
+ import { type RestoredStudio } from './studio-session.ts';
3
+ export type DraftAuthor = 'th30' | 'visitor';
4
+ /** Which sections one change touched, and who made it. */
5
+ export interface DraftChange {
6
+ revision: number;
7
+ by: DraftAuthor;
8
+ sections: string[];
9
+ }
10
+ /** A tool as kept: its URLs and headers with their credentials masked. `started` is its start. */
11
+ export declare function keptTool(tool: ToolSpecDraft, started?: ToolSpecDraft): ToolSpecDraft;
12
+ /**
13
+ * The workspace as kept: each tool's URLs and headers with their credentials masked, in the library
14
+ * and in the starts a reset puts back.
15
+ */
16
+ export declare function keptWorkspace(workspace: StudioWorkspace): StudioWorkspace;
17
+ export type StudioStore = ReturnType<typeof createStudioStore>;
18
+ /**
19
+ * The workspace as an external store. `getWorkspace()` is current the moment `update` returns,
20
+ * before React renders, so a th30 tool reads what it just did. th30 and the editor work on one
21
+ * agent at a time, the focused one: `getDraft` and `updateDraft` read and write its draft, with
22
+ * the whole tool library as its tools.
23
+ */
24
+ export declare function createStudioStore(initial: RestoredStudio, sites?: SharedSites, toolSites?: SharedSites): {
25
+ getWorkspace: () => StudioWorkspace;
26
+ getRevision: () => number;
27
+ getFocus: () => string;
28
+ getDraft: () => StudioDraft;
29
+ update: (next: StudioWorkspace | ((current: StudioWorkspace) => StudioWorkspace), by?: DraftAuthor) => StudioWorkspace;
30
+ /** Takes in what the project's files changed, without the question an edit to a shared value gets. */
31
+ takeFiles: (made: StudioWorkspace) => StudioWorkspace;
32
+ /** Changes the focused agent's draft; a no-op keeps the revision. Returns the draft now held. */
33
+ updateDraft: (next: StudioDraft | ((current: StudioDraft) => StudioDraft), by?: DraftAuthor) => StudioDraft;
34
+ /** Opens a node, as `selectNode` does: an agent's node is the one the preview talks to. */
35
+ select: (id: string) => void;
36
+ /** Picks the agent the preview talks to; not an edit either. */
37
+ chatWith: (key: string) => void;
38
+ /** Changes after `since`, oldest first; only the last 50 are kept. */
39
+ changesSince: (since: number) => DraftChange[];
40
+ subscribe: (listener: () => void) => () => void;
41
+ /**
42
+ * Says which reading of the project's files the starts stand on now: after a Save, an undo,
43
+ * or opening the files again.
44
+ */
45
+ /** The reading of the project's files the starts stand on. */
46
+ standsOn: () => string | undefined;
47
+ /** Says where the files write each shared value now: after they are read again. */
48
+ setSites: (next: SharedSites | undefined, tools?: SharedSites) => void;
49
+ /** What a held change to a shared value reaches. Undefined when none is held. */
50
+ getPending: () => SharedReach | ToolReach | undefined;
51
+ /**
52
+ * Makes the held change, on every agent that shares the value. The same value is not asked
53
+ * about again while the same node stays open, and `quiet` stops the asking for this tab.
54
+ */
55
+ confirmShared: (quiet?: boolean) => void;
56
+ /** Whether a change to a shared value is made without asking. */
57
+ isQuiet: () => boolean;
58
+ setQuiet: (quiet: boolean) => void;
59
+ /** Drops the held change: no agent has it. */
60
+ cancelShared: () => void;
61
+ standOn: (files: string) => void;
62
+ /** Writes now if a write is pending; the route calls it on pagehide and unmount. */
63
+ flush(): void;
64
+ };
@@ -0,0 +1,391 @@
1
+ /**
2
+ * The studio's workspace, kept in this tab's sessionStorage so it outlives a reload or a trip
3
+ * to the docs and back. Every change bumps a revision, so th30 can tell its own edits from the
4
+ * visitor's. Keys never come here: the vault stays in memory, and a tool's URLs and headers are kept
5
+ * with their credentials masked.
6
+ */
7
+ import { maskHeaders, maskUrl } from '@theoremjs/agents/surface';
8
+ import { agentNodeId, createBlankDraft, libraryDraft, STUDIO_WORKSPACE_VERSION, sharedSnapshot, toolReach, toolSnapshot, withLibraryDraft, withSharedCarry, withToolCarry, } from "../../mod.js";
9
+ import { getPref, setPref } from "./studio-prefs.js";
10
+ import { isRecord, session, WORKSPACE_KEY, } from "./studio-session.js";
11
+ const WRITE_MS = 300;
12
+ /** Beside the workspace's key: the builder said not to be asked about shared values again. */
13
+ const QUIET_SUFFIX = '.shared-quiet';
14
+ const NO_SNAPSHOT = new Map();
15
+ const CHANGES_SIZE = 50;
16
+ /** Headers that are a JSON object, else undefined: what can be masked with certainty. */
17
+ function headersObject(raw) {
18
+ try {
19
+ const parsed = JSON.parse(raw);
20
+ return isRecord(parsed) ? parsed : undefined;
21
+ }
22
+ catch {
23
+ return undefined;
24
+ }
25
+ }
26
+ /**
27
+ * Headers as kept: unchanged (formatting and all) when nothing in them is a credential, masked when
28
+ * something is. Text that isn't a JSON object yet isn't kept: the headers as they started are, so
29
+ * nothing in it reaches storage unmasked.
30
+ */
31
+ function keptHeaders(raw, started) {
32
+ const headers = headersObject(raw);
33
+ if (!headers)
34
+ return started && started !== raw ? keptHeaders(started, undefined) : '';
35
+ const masked = maskHeaders(headers);
36
+ return isRecord(masked) && Object.keys(headers).some((name) => masked[name] !== headers[name])
37
+ ? JSON.stringify(masked)
38
+ : raw;
39
+ }
40
+ /** A tool as kept: its URLs and headers with their credentials masked. `started` is its start. */
41
+ export function keptTool(tool, started) {
42
+ return {
43
+ ...tool,
44
+ ...(tool.endpoint ? { endpoint: maskUrl(tool.endpoint) } : {}),
45
+ ...(tool.serverUrl ? { serverUrl: maskUrl(tool.serverUrl) } : {}),
46
+ ...(tool.headersJson
47
+ ? { headersJson: keptHeaders(tool.headersJson, started?.headersJson) }
48
+ : {}),
49
+ };
50
+ }
51
+ /**
52
+ * The workspace as kept: each tool's URLs and headers with their credentials masked, in the library
53
+ * and in the starts a reset puts back.
54
+ */
55
+ export function keptWorkspace(workspace) {
56
+ return {
57
+ ...workspace,
58
+ toolSpecs: workspace.toolSpecs.map((tool) => keptTool(tool, workspace.starts.tools[tool.key])),
59
+ starts: {
60
+ ...workspace.starts,
61
+ tools: Object.fromEntries(Object.entries(workspace.starts.tools).map(([key, tool]) => [key, keptTool(tool)])),
62
+ },
63
+ };
64
+ }
65
+ /** True when two values are the same, or records holding the same values. */
66
+ function sameSection(a, b) {
67
+ if (a === b)
68
+ return true;
69
+ if (!isRecord(a) || !isRecord(b))
70
+ return false;
71
+ const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
72
+ return [...keys].every((key) => a[key] === b[key]);
73
+ }
74
+ /**
75
+ * The top-level draft sections that differ. Drafts are immutable, so a section that changed is a new
76
+ * object; the agent's lens rebuilds its tools section on every read, so that one is compared a level in.
77
+ */
78
+ function changedSections(before, after) {
79
+ const was = { ...before };
80
+ const now = { ...after };
81
+ const keys = new Set([...Object.keys(was), ...Object.keys(now)]);
82
+ return [...keys].filter((key) => !sameSection(was[key], now[key]));
83
+ }
84
+ /** The agent whose draft an open node is under; a library tool keeps the one open before it. */
85
+ function agentOf(workspace, id) {
86
+ return workspace.agents.find((agent) => {
87
+ const root = agentNodeId(agent.key);
88
+ return id === root || id.startsWith(`${root}/`);
89
+ })?.key;
90
+ }
91
+ /** Writes the workspace, masked, to sessionStorage. */
92
+ function writeWorkspace(state) {
93
+ state.timer = undefined;
94
+ const record = {
95
+ v: STUDIO_WORKSPACE_VERSION,
96
+ workspace: keptWorkspace(state.workspace),
97
+ revision: state.revision,
98
+ ...(state.files === undefined ? {} : { files: state.files }),
99
+ };
100
+ try {
101
+ session()?.setItem(state.slot, JSON.stringify(record));
102
+ }
103
+ catch {
104
+ // Quota or a blocked store: the page keeps working on what is in memory.
105
+ }
106
+ }
107
+ /** Queues a write, unless one is already queued. */
108
+ function scheduleWrite(state) {
109
+ state.timer ??= setTimeout(() => {
110
+ writeWorkspace(state);
111
+ }, WRITE_MS);
112
+ }
113
+ function notifyListeners(state) {
114
+ for (const listener of state.listeners)
115
+ listener();
116
+ }
117
+ /** The focused agent: the last one opened, or the first once that one is gone. */
118
+ function focusOf(state) {
119
+ return state.workspace.agents.some((agent) => agent.key === state.focus)
120
+ ? state.focus
121
+ : (state.workspace.agents[0]?.key ?? '');
122
+ }
123
+ /** The focused agent's draft; the same object until the workspace or the focus changes. */
124
+ function draftOf(state) {
125
+ const { workspace } = state;
126
+ let { view } = state;
127
+ const key = focusOf(state);
128
+ if (view?.agents !== workspace.agents ||
129
+ view.toolSpecs !== workspace.toolSpecs ||
130
+ view.providers !== workspace.providers ||
131
+ view.focus !== key) {
132
+ view = {
133
+ agents: workspace.agents,
134
+ toolSpecs: workspace.toolSpecs,
135
+ providers: workspace.providers,
136
+ focus: key,
137
+ draft: libraryDraft(workspace, key) ?? createBlankDraft(),
138
+ };
139
+ state.view = view;
140
+ }
141
+ return view.draft;
142
+ }
143
+ /** `made`, with a change to a value the files write once made on every agent or tool that shares it. */
144
+ function sharedCarry(state, made) {
145
+ let carry = { workspace: made, snapshot: NO_SNAPSHOT };
146
+ if (state.sites) {
147
+ state.good ??= sharedSnapshot(state.workspace);
148
+ carry = withSharedCarry(state.good, made, state.sites);
149
+ }
150
+ if (!state.toolSites)
151
+ return carry;
152
+ state.goodTools ??= toolSnapshot(state.workspace);
153
+ const tools = withToolCarry(state.goodTools, carry.workspace, state.toolSites);
154
+ // One question covers both: agreeing to it agrees to each place.
155
+ const reach = carry.reach && tools.reach
156
+ ? { ...carry.reach, sites: [...carry.reach.sites, ...tools.reach.sites] }
157
+ : (carry.reach ?? tools.reach);
158
+ return {
159
+ workspace: tools.workspace,
160
+ snapshot: carry.snapshot,
161
+ tools: tools.snapshot,
162
+ ...(reach ? { reach } : {}),
163
+ };
164
+ }
165
+ /**
166
+ * Whether the builder said not to be asked about shared values: in Settings, for this browser, or
167
+ * with the question's own "don't ask again", for this tab.
168
+ */
169
+ function isQuiet(state) {
170
+ if (getPref('askShared') === 'never')
171
+ return true;
172
+ try {
173
+ return session()?.getItem(`${state.slot}${QUIET_SUFFIX}`) === '1';
174
+ }
175
+ catch {
176
+ return false;
177
+ }
178
+ }
179
+ /** Sets whether shared values are asked about, as Settings does: asking again also ends this tab's "don't ask again". */
180
+ function setQuiet(state, quiet) {
181
+ setPref('askShared', quiet ? 'never' : 'always');
182
+ if (!quiet) {
183
+ try {
184
+ session()?.removeItem(`${state.slot}${QUIET_SUFFIX}`);
185
+ }
186
+ catch {
187
+ // Storage is off: nothing was kept to end.
188
+ }
189
+ }
190
+ notifyListeners(state);
191
+ }
192
+ /** What agreeing to `reach` covers: the places the files write, or the tools. */
193
+ const reachKeys = (reach) => 'tools' in reach ? reach.tools : reach.sites;
194
+ /**
195
+ * Moves to `next`, as the visitor's or th30's change, with the move in the open node. A change
196
+ * to a shared value is held until the person says to make it: `confirmShared`. So is th30's
197
+ * change to a tool other agents allow: the person did not open that tool to change it.
198
+ */
199
+ function updateWorkspace(state, next, by) {
200
+ const made = typeof next === 'function' ? next(state.workspace) : next;
201
+ if (made === state.workspace)
202
+ return state.workspace;
203
+ const carry = sharedCarry(state, made);
204
+ const reach = carry.reach ?? (by === 'th30' ? toolReach(state.workspace, made, focusOf(state)) : undefined);
205
+ const asks = reach && !isQuiet(state) && reachKeys(reach).some((key) => !state.agreed.has(key));
206
+ if (reach && asks) {
207
+ state.pending = { carry, reach, by };
208
+ notifyListeners(state);
209
+ return state.workspace;
210
+ }
211
+ return commitWorkspace(state, carry, by);
212
+ }
213
+ function commitWorkspace(state, carry, by) {
214
+ state.pending = undefined;
215
+ if (state.sites)
216
+ state.good = carry.snapshot;
217
+ if (state.toolSites)
218
+ state.goodTools = carry.tools;
219
+ const before = draftOf(state);
220
+ const agentsBefore = state.workspace.agents.map((agent) => agent.key).join();
221
+ state.workspace = carry.workspace;
222
+ state.focus = agentOf(state.workspace, state.workspace.selected) ?? state.focus;
223
+ const sections = changedSections(before, draftOf(state));
224
+ if (state.workspace.agents.map((agent) => agent.key).join() !== agentsBefore) {
225
+ sections.push('agents');
226
+ }
227
+ state.revision += 1;
228
+ state.changes = [...state.changes, { revision: state.revision, by, sections }].slice(-CHANGES_SIZE);
229
+ scheduleWrite(state);
230
+ notifyListeners(state);
231
+ return state.workspace;
232
+ }
233
+ /**
234
+ * Takes in what the project's files changed. Each value is in the code already, at every place
235
+ * that reads it: nothing is asked, nothing is carried, and what the files say now is what the next
236
+ * edit is measured against.
237
+ */
238
+ function takeFiles(state, made) {
239
+ if (made === state.workspace)
240
+ return state.workspace;
241
+ const held = commitWorkspace(state, { workspace: made, snapshot: NO_SNAPSHOT }, 'visitor');
242
+ state.good = undefined;
243
+ state.goodTools = undefined;
244
+ return held;
245
+ }
246
+ /** Changes the workspace without an edit: no revision, no change record. */
247
+ function moveWorkspace(state, workspace) {
248
+ state.workspace = workspace;
249
+ scheduleWrite(state);
250
+ notifyListeners(state);
251
+ }
252
+ /** Changes the focused agent's draft; a no-op keeps the revision. Returns the draft now held. */
253
+ function updateFocusedDraft(state, next, by) {
254
+ const current = draftOf(state);
255
+ const value = typeof next === 'function' ? next(current) : next;
256
+ if (value !== current) {
257
+ updateWorkspace(state, withLibraryDraft(state.workspace, focusOf(state), value), by);
258
+ }
259
+ return draftOf(state);
260
+ }
261
+ /**
262
+ * Opens a node: not an edit, so the revision stays. An agent's node focuses that agent, and the
263
+ * preview talks to it, including one an edit just added and selected.
264
+ */
265
+ function selectNode(state, id) {
266
+ const agent = agentOf(state.workspace, id);
267
+ const chatWith = agent ?? state.workspace.chatWith;
268
+ if (id === state.workspace.selected && chatWith === state.workspace.chatWith)
269
+ return;
270
+ const workspace = { ...state.workspace, selected: id, chatWith };
271
+ state.focus = agent ?? state.focus;
272
+ state.agreed.clear();
273
+ moveWorkspace(state, workspace);
274
+ }
275
+ /**
276
+ * The workspace as an external store. `getWorkspace()` is current the moment `update` returns,
277
+ * before React renders, so a th30 tool reads what it just did. th30 and the editor work on one
278
+ * agent at a time, the focused one: `getDraft` and `updateDraft` read and write its draft, with
279
+ * the whole tool library as its tools.
280
+ */
281
+ export function createStudioStore(initial, sites, toolSites) {
282
+ const state = {
283
+ workspace: initial.workspace,
284
+ sites,
285
+ good: undefined,
286
+ toolSites,
287
+ goodTools: undefined,
288
+ pending: undefined,
289
+ agreed: new Set(),
290
+ revision: initial.revision,
291
+ focus: agentOf(initial.workspace, initial.workspace.selected) ?? initial.workspace.chatWith,
292
+ changes: [],
293
+ listeners: new Set(),
294
+ timer: undefined,
295
+ slot: initial.project?.key ?? WORKSPACE_KEY,
296
+ files: initial.project?.files,
297
+ view: undefined,
298
+ };
299
+ const getFocus = () => focusOf(state);
300
+ const getDraft = () => draftOf(state);
301
+ const update = (next, by = 'visitor') => updateWorkspace(state, next, by);
302
+ return {
303
+ getWorkspace: () => state.workspace,
304
+ getRevision: () => state.revision,
305
+ getFocus,
306
+ getDraft,
307
+ update,
308
+ /** Takes in what the project's files changed, without the question an edit to a shared value gets. */
309
+ takeFiles: (made) => takeFiles(state, made),
310
+ /** Changes the focused agent's draft; a no-op keeps the revision. Returns the draft now held. */
311
+ updateDraft: (next, by = 'visitor') => updateFocusedDraft(state, next, by),
312
+ /** Opens a node, as `selectNode` does: an agent's node is the one the preview talks to. */
313
+ select: (id) => {
314
+ selectNode(state, id);
315
+ },
316
+ /** Picks the agent the preview talks to; not an edit either. */
317
+ chatWith: (key) => {
318
+ if (key === state.workspace.chatWith)
319
+ return;
320
+ moveWorkspace(state, { ...state.workspace, chatWith: key });
321
+ },
322
+ /** Changes after `since`, oldest first; only the last 50 are kept. */
323
+ changesSince: (since) => state.changes.filter((change) => change.revision > since),
324
+ subscribe: (listener) => {
325
+ state.listeners.add(listener);
326
+ return () => {
327
+ state.listeners.delete(listener);
328
+ };
329
+ },
330
+ /**
331
+ * Says which reading of the project's files the starts stand on now: after a Save, an undo,
332
+ * or opening the files again.
333
+ */
334
+ /** The reading of the project's files the starts stand on. */
335
+ standsOn: () => state.files,
336
+ /** Says where the files write each shared value now: after they are read again. */
337
+ setSites: (next, tools) => {
338
+ state.sites = next;
339
+ state.good = undefined;
340
+ state.toolSites = tools;
341
+ state.goodTools = undefined;
342
+ },
343
+ /** What a held change to a shared value reaches. Undefined when none is held. */
344
+ getPending: () => state.pending?.reach,
345
+ /**
346
+ * Makes the held change, on every agent that shares the value. The same value is not asked
347
+ * about again while the same node stays open, and `quiet` stops the asking for this tab.
348
+ */
349
+ confirmShared: (quiet = false) => {
350
+ const { pending } = state;
351
+ if (!pending)
352
+ return;
353
+ for (const key of reachKeys(pending.reach))
354
+ state.agreed.add(key);
355
+ if (quiet) {
356
+ try {
357
+ session()?.setItem(`${state.slot}${QUIET_SUFFIX}`, '1');
358
+ }
359
+ catch {
360
+ // Storage is full or off: the builder is asked again.
361
+ }
362
+ }
363
+ commitWorkspace(state, pending.carry, pending.by);
364
+ },
365
+ /** Whether a change to a shared value is made without asking. */
366
+ isQuiet: () => isQuiet(state),
367
+ setQuiet: (quiet) => {
368
+ setQuiet(state, quiet);
369
+ },
370
+ /** Drops the held change: no agent has it. */
371
+ cancelShared: () => {
372
+ if (!state.pending)
373
+ return;
374
+ state.pending = undefined;
375
+ notifyListeners(state);
376
+ },
377
+ standOn: (files) => {
378
+ if (files === state.files)
379
+ return;
380
+ state.files = files;
381
+ scheduleWrite(state);
382
+ },
383
+ /** Writes now if a write is pending; the route calls it on pagehide and unmount. */
384
+ flush() {
385
+ if (state.timer === undefined)
386
+ return;
387
+ clearTimeout(state.timer);
388
+ writeWorkspace(state);
389
+ },
390
+ };
391
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Watching the project's files from the page: the local server says when the builder's editor
3
+ * writes one. Whether the builder wants that is a preference, in `studio-prefs.ts`.
4
+ */
5
+ /**
6
+ * Listens for the files the server says changed. `onOpen` runs when the server is watching: one
7
+ * started with `--no-watch` never opens. Answers how to stop listening.
8
+ */
9
+ export declare function subscribeToFiles(endpoint: string, on: {
10
+ open: () => void;
11
+ files: (files: string[]) => void;
12
+ }): () => void;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Watching the project's files from the page: the local server says when the builder's editor
3
+ * writes one. Whether the builder wants that is a preference, in `studio-prefs.ts`.
4
+ */
5
+ /**
6
+ * Listens for the files the server says changed. `onOpen` runs when the server is watching: one
7
+ * started with `--no-watch` never opens. Answers how to stop listening.
8
+ */
9
+ export function subscribeToFiles(endpoint, on) {
10
+ if (typeof EventSource === 'undefined')
11
+ return () => undefined;
12
+ const source = new EventSource(`${endpoint}/watch`);
13
+ source.onopen = on.open;
14
+ source.onmessage = (event) => {
15
+ try {
16
+ const told = JSON.parse(event.data);
17
+ const files = typeof told === 'object' && told !== null && 'files' in told ? told.files : undefined;
18
+ on.files(Array.isArray(files) ? files.filter((file) => typeof file === 'string') : []);
19
+ }
20
+ catch {
21
+ on.files([]);
22
+ }
23
+ };
24
+ return () => {
25
+ source.close();
26
+ };
27
+ }
@@ -0,0 +1,6 @@
1
+ import type { KeyboardEvent } from 'react';
2
+ /**
3
+ * Tab in an empty field takes its placeholder up as the text, to edit rather than retype. Only for a
4
+ * placeholder that is a value (an example, or the default it stands for); anywhere else Tab moves on.
5
+ */
6
+ export declare function tabFills(value: string, placeholder: string | undefined, onChange: (next: string) => void): (event: KeyboardEvent) => void;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Tab in an empty field takes its placeholder up as the text, to edit rather than retype. Only for a
3
+ * placeholder that is a value (an example, or the default it stands for); anywhere else Tab moves on.
4
+ */
5
+ export function tabFills(value, placeholder, onChange) {
6
+ return (event) => {
7
+ if (event.key !== 'Tab' || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
8
+ return;
9
+ if (value !== '' || !placeholder)
10
+ return;
11
+ event.preventDefault();
12
+ onChange(placeholder);
13
+ };
14
+ }
@@ -0,0 +1,3 @@
1
+ export declare function toolCredential(key: string): string;
2
+ export declare function setToolCredential(key: string, value: string): void;
3
+ export declare function subscribeToolCredentials(listener: () => void): () => void;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The credentials typed into tool tests, by tool key. In this tab's memory only: never saved, never
3
+ * sent anywhere but the one test request. th30 sees them only as cards.
4
+ */
5
+ const credentials = new Map();
6
+ const listeners = new Set();
7
+ export function toolCredential(key) {
8
+ return credentials.get(key) ?? '';
9
+ }
10
+ export function setToolCredential(key, value) {
11
+ if (value)
12
+ credentials.set(key, value);
13
+ else
14
+ credentials.delete(key);
15
+ for (const listener of listeners)
16
+ listener();
17
+ }
18
+ export function subscribeToolCredentials(listener) {
19
+ listeners.add(listener);
20
+ return () => {
21
+ listeners.delete(listener);
22
+ };
23
+ }
@@ -0,0 +1,19 @@
1
+ import type { GuardrailsDraft } from '../../draft.ts';
2
+ import { type ToolSpecDraft } from '../../mod.ts';
3
+ /** What the test-connection route answers: an HTTP response, or an MCP server's tool list. */
4
+ export interface ProbeResult {
5
+ ok: boolean;
6
+ status?: number;
7
+ statusText?: string;
8
+ error?: string;
9
+ preview?: string;
10
+ elapsedMs?: number;
11
+ tools?: string[];
12
+ targetToolFound?: boolean;
13
+ }
14
+ /**
15
+ * Sends the probe with the draft's network guardrail, which the server keeps to only when it is
16
+ * the builder's own; any other keeps to public hosts. A request that can't be made, or a server
17
+ * that can't be reached, comes back as a failed result.
18
+ */
19
+ export declare function runToolProbe(tool: ToolSpecDraft, sampleInput: string, credential: string, guardrails: GuardrailsDraft): Promise<ProbeResult>;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * One real call to a draft tool, from the server, which reaches public hosts only: the editor's
3
+ * Test and th30's `test` action both go through here.
4
+ */
5
+ import { HTTP_METHODS } from '@theoremjs/agents';
6
+ import { draftNetwork } from "../../compile.js";
7
+ import { credentialHeaderProblem, credentialUrlProblem, unheldProblem, } from "../../mod.js";
8
+ import { screenEndpoint } from "./project-address.js";
9
+ /** A JSON object typed into the test, or why it isn't one. Blank is `undefined`. */
10
+ function parseObject(raw, label) {
11
+ if (!raw.trim())
12
+ return {};
13
+ try {
14
+ const parsed = JSON.parse(raw);
15
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
16
+ return { value: parsed };
17
+ }
18
+ }
19
+ catch {
20
+ // Falls through to the error below.
21
+ }
22
+ return { error: `${label} must be a JSON object.` };
23
+ }
24
+ /** The test-connection request for `tool`. */
25
+ function probeRequest(tool, sampleInput, credential) {
26
+ const headers = parseObject(tool.headersJson ?? '', 'Headers');
27
+ if (headers.error)
28
+ return { error: headers.error };
29
+ const credentialHeader = credentialHeaderProblem(headers.value);
30
+ if (credentialHeader)
31
+ return { error: credentialHeader };
32
+ const credentialInUrl = credentialUrlProblem(tool.toolType === 'mcp' ? tool.serverUrl : tool.endpoint);
33
+ if (credentialInUrl)
34
+ return { error: credentialInUrl };
35
+ // A mask stands for a value only the project holds: this request would carry the mask itself.
36
+ const unheld = unheldProblem(tool.toolName, {
37
+ endpoint: tool.endpoint,
38
+ serverUrl: tool.serverUrl,
39
+ headers: headers.value,
40
+ });
41
+ if (unheld)
42
+ return { error: unheld };
43
+ const authType = tool.authType ?? 'none';
44
+ const shared = {
45
+ headers: headers.value,
46
+ ...(authType === 'none'
47
+ ? {}
48
+ : {
49
+ auth: {
50
+ type: authType,
51
+ ...(authType === 'api_key' && tool.authQueryParam?.trim()
52
+ ? { queryParam: tool.authQueryParam.trim() }
53
+ : { headerName: tool.authHeaderName, headerPrefix: tool.authHeaderPrefix }),
54
+ },
55
+ testCredential: credential || undefined,
56
+ }),
57
+ };
58
+ if (tool.toolType === 'mcp') {
59
+ return {
60
+ body: {
61
+ type: 'mcp',
62
+ serverUrl: tool.serverUrl ?? '',
63
+ mcpToolName: tool.mcpToolName,
64
+ ...shared,
65
+ },
66
+ };
67
+ }
68
+ const input = parseObject(sampleInput, 'Sample input');
69
+ if (input.error)
70
+ return { error: input.error };
71
+ return {
72
+ body: {
73
+ type: 'http',
74
+ endpoint: tool.endpoint ?? '',
75
+ method: tool.method ?? HTTP_METHODS[0],
76
+ pathParams: tool.pathParams,
77
+ queryParams: tool.queryParams,
78
+ bodyParam: tool.bodyParam,
79
+ sampleInput: input.value,
80
+ ...shared,
81
+ },
82
+ };
83
+ }
84
+ /**
85
+ * Sends the probe with the draft's network guardrail, which the server keeps to only when it is
86
+ * the builder's own; any other keeps to public hosts. A request that can't be made, or a server
87
+ * that can't be reached, comes back as a failed result.
88
+ */
89
+ export async function runToolProbe(tool, sampleInput, credential, guardrails) {
90
+ const request = probeRequest(tool, sampleInput, credential);
91
+ if (!request.body)
92
+ return { ok: false, error: request.error };
93
+ try {
94
+ const response = await fetch(`${screenEndpoint()}/test-connection`, {
95
+ method: 'POST',
96
+ headers: { 'Content-Type': 'application/json' },
97
+ body: JSON.stringify({ ...request.body, network: draftNetwork(guardrails) }),
98
+ });
99
+ return await response.json();
100
+ }
101
+ catch {
102
+ return { ok: false, error: "Couldn't reach the studio server." };
103
+ }
104
+ }