@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,514 @@
1
+ /**
2
+ * What Save writes for a profile or tool the builder added in the studio: a
3
+ * new file beside the project's others, and the lines in the setup that import
4
+ * and register it. A scope checks a profile against the tools registered
5
+ * before it, and an agent tool against the profile it runs, so each line goes
6
+ * where that order holds.
7
+ *
8
+ * @module
9
+ */
10
+ import { dirname, relative, resolve } from 'node:path';
11
+ import ts from 'typescript';
12
+ import { AGENTS_PACKAGE, agentIdentifier, agentModule, providerModule, toolModule, } from "../source.js";
13
+ import { keySource } from "../tool-schema.js";
14
+ import { calleeName, importExtension, isInside, kernelImportOf, namedValue, setupExport, specifierTo, unwrapped, } from "./project-source.js";
15
+ import { indentAt, indentUnit } from "./save-plan.js";
16
+ /**
17
+ * The file an id or name is written to: the id itself, with each run of what not every file system
18
+ * takes made one `-`. None when nothing of it is left.
19
+ */
20
+ function fileNameOf(of) {
21
+ const name = of.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^[._-]+|-+$/g, '');
22
+ return name || undefined;
23
+ }
24
+ function registrations(source) {
25
+ const found = [];
26
+ const visit = (node) => {
27
+ if (ts.isExpressionStatement(node)) {
28
+ const held = ts.isAwaitExpression(node.expression)
29
+ ? node.expression.expression
30
+ : node.expression;
31
+ const call = unwrapped(held);
32
+ const name = ts.isCallExpression(call) ? calleeName(call) : undefined;
33
+ if (ts.isCallExpression(call) && (name === 'registerProfile' || name === 'registerTool')) {
34
+ found.push({ statement: node, call, name });
35
+ }
36
+ }
37
+ ts.forEachChild(node, visit);
38
+ };
39
+ visit(source);
40
+ return found;
41
+ }
42
+ /** The file whose statements register the project's profiles: the setup, or the first file it reads that does. */
43
+ function registeringFile(project) {
44
+ const files = [...project.files.values()];
45
+ return (files.find((source) => registrations(source).some(({ name }) => name === 'registerProfile')) ??
46
+ files.find((source) => registrations(source).length > 0) ??
47
+ project.files.get(project.entry));
48
+ }
49
+ /** The id of the profile a `registerProfile` statement registers, when its files write it out. */
50
+ function registeredId(project, source, call) {
51
+ const [argument] = call.arguments;
52
+ if (!argument)
53
+ return undefined;
54
+ const { origin } = namedValue(project, { node: argument, source });
55
+ const defined = unwrapped(origin.node);
56
+ const options = ts.isCallExpression(defined) && defined.arguments[0]
57
+ ? unwrapped(defined.arguments[0])
58
+ : defined;
59
+ for (const [id, targets] of project.profiles) {
60
+ if (targets.some((target) => target.options === options))
61
+ return id;
62
+ }
63
+ return undefined;
64
+ }
65
+ /** Where a file imports one of the kernel's `names` from, under any name, the first of the project's files that does. */
66
+ function importedFrom(project, names) {
67
+ for (const [file, source] of project.files) {
68
+ for (const name of names) {
69
+ const found = kernelImportOf(source, name);
70
+ if (found)
71
+ return { specifier: found.specifier, file };
72
+ }
73
+ }
74
+ return undefined;
75
+ }
76
+ /** A specifier written in `file`, as `to` must write it: a relative one is turned to start from there. */
77
+ function carried(specifier, file, to) {
78
+ if (!specifier.startsWith('.'))
79
+ return specifier;
80
+ const path = relative(dirname(to), resolve(dirname(file), specifier));
81
+ return path.startsWith('.') ? path : `./${path}`;
82
+ }
83
+ /** The folder most of `files` are in, or `fallback` when there are none. */
84
+ function commonFolder(files, fallback) {
85
+ const counts = new Map();
86
+ for (const file of files)
87
+ counts.set(dirname(file), (counts.get(dirname(file)) ?? 0) + 1);
88
+ let best = fallback;
89
+ let most = 0;
90
+ for (const [folder, count] of counts) {
91
+ if (count > most)
92
+ [best, most] = [folder, count];
93
+ }
94
+ return best;
95
+ }
96
+ /** `registerLogWatering` for the tool `log_watering`, `registerGemini` for the provider `gemini`: unique among `taken`. */
97
+ function registerName(id, taken) {
98
+ const words = id.split(/[^A-Za-z0-9]+/).filter(Boolean);
99
+ const base = `register${words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join('')}`;
100
+ let name = base;
101
+ for (let n = 2; taken.has(name); n++)
102
+ name = `${base}${n}`;
103
+ taken.add(name);
104
+ return name;
105
+ }
106
+ /** Every name a file already uses, so a new one does not shadow it. */
107
+ function namesIn(source) {
108
+ const names = new Set();
109
+ const visit = (node) => {
110
+ if (ts.isIdentifier(node))
111
+ names.add(node.text);
112
+ ts.forEachChild(node, visit);
113
+ };
114
+ visit(source);
115
+ return names;
116
+ }
117
+ /** The note above each export the studio writes into a setup that has none yet. */
118
+ const SETUP_NOTES = {
119
+ questions: '/** What each decision profile is asked, by profile id. The studio reads it. */',
120
+ images: '/** The pictures each decision profile sends, by profile id. The studio reads it. */',
121
+ };
122
+ /** The places in the setup a new line can go, each as the position and the text around the line. */
123
+ class Setup {
124
+ project;
125
+ source;
126
+ taken;
127
+ edits = [];
128
+ found;
129
+ file;
130
+ /** What this plan imports from the kernel, by its name there, as the name the setup reads. */
131
+ imported = new Map();
132
+ /** The lines that go after everything the setup registers, in order. */
133
+ tail = [];
134
+ /** What each new decision is asked and sends, as the entries the setup's exports gain. */
135
+ entries = { questions: [], images: [] };
136
+ constructor(project, source, taken) {
137
+ this.project = project;
138
+ this.source = source;
139
+ this.taken = taken;
140
+ this.found = registrations(source);
141
+ this.file = source.fileName;
142
+ }
143
+ /** Whether each registration is a statement of the file or of a function, where a line beside it runs once. */
144
+ get plain() {
145
+ return this.found.every(({ statement: { parent } }) => ts.isSourceFile(parent) || (ts.isBlock(parent) && ts.isFunctionLike(parent.parent)));
146
+ }
147
+ /** The object the setup's `name` export writes out, when it has the export and writes it so. */
148
+ held(name) {
149
+ const value = setupExport(this.source, name)?.initializer;
150
+ const held = value && unwrapped(value);
151
+ return held && ts.isObjectLiteralExpression(held) ? held : undefined;
152
+ }
153
+ /**
154
+ * Whether the setup can name what a new decision is asked, or the pictures it sends. The studio
155
+ * reads them from the module it opens, so that is the file that must hold them: as an object it
156
+ * writes out, or not yet.
157
+ */
158
+ names(name) {
159
+ if (this.file !== this.project.entry)
160
+ return false;
161
+ return this.held(name) !== undefined || !namesIn(this.source).has(name);
162
+ }
163
+ /** Names what a new decision profile is asked or sends: `expression`, under the profile's id. */
164
+ add(name, profile, expression) {
165
+ this.entries[name].push(`${keySource(profile)}: ${expression}`);
166
+ }
167
+ /** The new decisions' entries: more of the `name` export, or the export itself at the end. */
168
+ place(name) {
169
+ const added = this.entries[name];
170
+ const held = this.held(name);
171
+ if (!held) {
172
+ const { text } = this.source;
173
+ const unit = indentUnit(this.source);
174
+ const entries = added.map((entry) => `${unit}${entry},\n`).join('');
175
+ const gap = text && !text.endsWith('\n') ? '\n\n' : '\n';
176
+ return this.insert(text.length, `${gap}${SETUP_NOTES[name]}\nexport const ${name} = {\n${entries}};\n`);
177
+ }
178
+ const last = held.properties.at(-1);
179
+ if (!last)
180
+ return this.insert(held.getStart(this.source) + 1, ` ${added.join(', ')} `);
181
+ const indent = indentAt(this.source, last.getStart(this.source));
182
+ const between = held.getText(this.source).includes('\n') ? `,\n${indent}` : ', ';
183
+ this.insert(last.end, added.map((entry) => `${between}${entry}`).join(''));
184
+ }
185
+ insert(position, text) {
186
+ this.edits.push({ file: this.file, start: position, end: position, text });
187
+ }
188
+ /** The statement that registers `profile`, when the files show which one does. */
189
+ registers(profile) {
190
+ return this.found.find(({ name, call }) => name === 'registerProfile' && registeredId(this.project, this.source, call) === profile)?.statement;
191
+ }
192
+ after(statement, lines) {
193
+ const indent = indentAt(this.source, statement.getStart(this.source));
194
+ this.insert(statement.end, lines.map((line) => `\n${indent}${line}`).join(''));
195
+ }
196
+ before(statement, lines) {
197
+ const start = statement.getStart(this.source);
198
+ const indent = indentAt(this.source, start);
199
+ this.insert(start, lines.map((line) => `${line}\n${indent}`).join(''));
200
+ }
201
+ /**
202
+ * The name the setup calls the kernel's `name` by. When the file does not import it yet, it is
203
+ * added to the import that reads the kernel, or a new one, under another name if the file
204
+ * already uses `name` for something else.
205
+ */
206
+ needs(name, agents) {
207
+ const known = kernelImportOf(this.source, name)?.local ?? this.imported.get(name);
208
+ if (known)
209
+ return known;
210
+ const local = this.taken.has(name) ? agentIdentifier(`theorem ${name}`, this.taken) : name;
211
+ if (local === name)
212
+ this.taken.add(name);
213
+ this.imported.set(name, local);
214
+ const binding = local === name ? name : `${name} as ${local}`;
215
+ for (const statement of this.source.statements) {
216
+ if (!ts.isImportDeclaration(statement) || !ts.isStringLiteralLike(statement.moduleSpecifier))
217
+ continue;
218
+ const bindings = statement.importClause?.namedBindings;
219
+ if (statement.moduleSpecifier.text !== agents || statement.importClause?.isTypeOnly)
220
+ continue;
221
+ const last = bindings && ts.isNamedImports(bindings) ? bindings.elements.at(-1) : undefined;
222
+ if (last) {
223
+ this.insert(last.end, `, ${binding}`);
224
+ return local;
225
+ }
226
+ }
227
+ this.import(`import { ${binding} } from '${agents}';`);
228
+ return local;
229
+ }
230
+ /** After the file's last import, or at its top. */
231
+ import(line) {
232
+ const last = this.source.statements.findLast((statement) => ts.isImportDeclaration(statement));
233
+ if (last)
234
+ this.insert(last.end, `\n${line}`);
235
+ else
236
+ this.insert(0, `${line}\n`);
237
+ }
238
+ /** After everything the setup registers. */
239
+ last(line) {
240
+ this.tail.push(line);
241
+ }
242
+ /** Before the first profile the setup registers, so every profile can allow it. */
243
+ beforeProfiles(line) {
244
+ const first = this.found.find(({ name }) => name === 'registerProfile');
245
+ if (first)
246
+ this.before(first.statement, [line]);
247
+ else
248
+ this.last(line);
249
+ }
250
+ /** The last lines: after the last profile, else the last registration, else in the setup's function, else at the end. */
251
+ placeTail() {
252
+ const end = this.found.findLast(({ name }) => name === 'registerProfile') ?? this.found.at(-1);
253
+ if (end)
254
+ return this.after(end.statement, this.tail);
255
+ const body = this.source.statements.find((statement) => ts.isFunctionDeclaration(statement) &&
256
+ statement.body !== undefined &&
257
+ (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Default) !== 0)?.body;
258
+ const within = body?.statements.at(-1);
259
+ if (within)
260
+ return this.after(within, this.tail);
261
+ if (body) {
262
+ const unit = indentUnit(this.source);
263
+ return this.insert(body.getStart(this.source) + 1, `${this.tail.map((line) => `\n${unit}${line}`).join('')}\n`);
264
+ }
265
+ const { text } = this.source;
266
+ this.insert(text.length, `${text && !text.endsWith('\n') ? '\n' : ''}${this.tail.join('\n')}\n`);
267
+ }
268
+ /** Every line placed, as edits to the setup. */
269
+ finish() {
270
+ if (this.tail.length)
271
+ this.placeTail();
272
+ for (const name of ['questions', 'images'])
273
+ if (this.entries[name].length)
274
+ this.place(name);
275
+ return this.edits;
276
+ }
277
+ }
278
+ const held = (calls, agent) => calls.get(agent) ?? [];
279
+ /** One plan in the making: the files it creates, the setup lines, and what it could not place. */
280
+ class NewPlan {
281
+ ground;
282
+ added;
283
+ plan = { changes: [], edits: [] };
284
+ setup;
285
+ taken;
286
+ claimed = new Set();
287
+ placed = new Set();
288
+ extension;
289
+ zod;
290
+ folders;
291
+ isNew;
292
+ constructor(ground, added) {
293
+ this.ground = ground;
294
+ this.added = added;
295
+ const { project, source, agents } = ground;
296
+ const folder = (targets) => commonFolder([...targets.values()].flat().map((target) => target.file), dirname(project.entry));
297
+ this.taken = namesIn(source);
298
+ this.setup = new Setup(project, source, this.taken);
299
+ this.extension = importExtension(project, agents.specifier);
300
+ this.zod = importedFrom(project, ['z']) ?? { specifier: 'zod', file: project.entry };
301
+ this.folders = {
302
+ profile: folder(project.profiles),
303
+ tool: folder(project.tools),
304
+ provider: folder(project.providers),
305
+ };
306
+ this.isNew = new Set(added.profiles);
307
+ }
308
+ refuse(kind, of, status, file) {
309
+ this.plan.changes.push({ kind, of, setting: '', status, file });
310
+ }
311
+ nowhere(registration) {
312
+ this.refuse('tool', registration.name, 'setup', this.ground.project.entry);
313
+ }
314
+ /** Nothing can be placed: the setup does not show where it registers. */
315
+ unplaced() {
316
+ const { entry } = this.ground.project;
317
+ for (const id of this.added.profiles)
318
+ this.refuse('profile', id, 'setup', entry);
319
+ for (const tool of this.added.tools)
320
+ this.refuse('tool', tool.name, 'setup', entry);
321
+ for (const provider of this.added.providers)
322
+ this.refuse('provider', provider.id, 'setup', entry);
323
+ return this.plan;
324
+ }
325
+ /** The specifiers a new file at `file` imports the kernel and zod by. */
326
+ from(file) {
327
+ const { agents } = this.ground;
328
+ return {
329
+ agents: carried(agents.specifier, agents.file, file),
330
+ zod: carried(this.zod.specifier, this.zod.file, file),
331
+ };
332
+ }
333
+ /** The new file for `of`, written and imported. False when it cannot be, with the reason planned. */
334
+ create(kind, of, text, imports) {
335
+ const { project, source, exists } = this.ground;
336
+ const name = fileNameOf(of);
337
+ const file = resolve(this.folders[kind], `${name}.ts`);
338
+ const code = name && isInside(project.root, file) ? text(file) : undefined;
339
+ if (code === undefined) {
340
+ this.refuse(kind, of, 'setup', project.entry);
341
+ return false;
342
+ }
343
+ if (exists(file) || this.claimed.has(file)) {
344
+ this.refuse(kind, of, 'taken', file);
345
+ return false;
346
+ }
347
+ this.claimed.add(file);
348
+ this.plan.edits.push({ file, start: 0, end: 0, text: code });
349
+ this.setup.import(imports(specifierTo(source.fileName, file, this.extension)));
350
+ this.plan.changes.push({ kind, of, setting: '', status: 'written', file, line: 1 });
351
+ return true;
352
+ }
353
+ /** A provider's file, and the setup's call of the function in it that registers the provider before every profile. */
354
+ provider(provider) {
355
+ const register = registerName(provider.id, this.taken);
356
+ const made = this.create('provider', provider.id, (file) => providerModule(provider, register, this.from(file).agents), (specifier) => `import { ${register} } from '${specifier}';`);
357
+ if (made)
358
+ this.setup.beforeProfiles(`${register}();`);
359
+ }
360
+ /** A tool's file, and the setup's call of the function in it that registers the tool. */
361
+ tool(registration) {
362
+ const register = registerName(registration.name, this.taken);
363
+ const made = this.create('tool', registration.name, (file) => toolModule(registration, register, this.from(file)), (specifier) => `import { ${register} } from '${specifier}';`);
364
+ return made ? [`${register}();`] : [];
365
+ }
366
+ /** Where an agent tool goes when an agent the project has allows it: `first` is the earliest of those agents. */
367
+ call(registration, first, calls) {
368
+ const { profile } = registration;
369
+ if (this.isNew.has(profile)) {
370
+ // An agent the project has calls a new one: the new agent and this tool go right before it.
371
+ const earlier = calls.hoist.get(profile);
372
+ calls.hoist.set(profile, earlier && earlier.pos < first.pos ? earlier : first);
373
+ calls.trail.set(profile, [...held(calls.trail, profile), registration]);
374
+ return;
375
+ }
376
+ const ran = this.setup.registers(profile);
377
+ if (!ran || ran.end > first.getStart(this.ground.source))
378
+ return this.nowhere(registration);
379
+ this.setup.after(ran, this.tool(registration));
380
+ }
381
+ /**
382
+ * Places each new tool. One that calls no agent goes before every profile. An agent tool goes
383
+ * after the agent it runs and before every agent that allows it, or waits for a new agent's line.
384
+ */
385
+ tools() {
386
+ const calls = { lead: new Map(), trail: new Map(), hoist: new Map() };
387
+ for (const registration of this.added.tools) {
388
+ if (registration.type !== 'agent') {
389
+ for (const line of this.tool(registration))
390
+ this.setup.beforeProfiles(line);
391
+ continue;
392
+ }
393
+ const callers = this.added.agents.filter((agent) => agent.customTools.some(({ name }) => name === registration.name));
394
+ const fresh = callers.find((agent) => this.isNew.has(agent.agentId));
395
+ const known = callers
396
+ .filter((agent) => !this.isNew.has(agent.agentId))
397
+ .map((agent) => this.setup.registers(agent.agentId));
398
+ const found = known
399
+ .filter((statement) => statement !== undefined)
400
+ .toSorted((a, b) => a.pos - b.pos);
401
+ const [first] = found;
402
+ // Only new agents allow it, and they are registered last: it goes right before the first of them.
403
+ if (!known.length && fresh)
404
+ calls.lead.set(fresh.agentId, [...held(calls.lead, fresh.agentId), registration]);
405
+ else if (first && found.length === known.length)
406
+ this.call(registration, first, calls);
407
+ else
408
+ this.nowhere(registration);
409
+ }
410
+ return calls;
411
+ }
412
+ /** A new agent's file and the line that imports it. False when it cannot be written. */
413
+ profile(agent, name) {
414
+ // An item rule runs a check the builder's code holds: a file with the rule alone would not load.
415
+ const [list] = Object.keys(('outputs' in agent.profile && agent.profile.outputs?.validation?.items) || {});
416
+ if (list !== undefined) {
417
+ this.plan.changes.push({
418
+ kind: 'profile',
419
+ of: agent.agentId,
420
+ setting: `outputs.validation.items.${list}.check`,
421
+ status: 'owed',
422
+ });
423
+ return false;
424
+ }
425
+ // A decision is asked the questions the setup names and sends the pictures it names, so one the setup cannot name them for is not written.
426
+ if ((agent.questions && !this.setup.names('questions')) ||
427
+ (agent.images && !this.setup.names('images'))) {
428
+ this.refuse('profile', agent.agentId, 'setup', this.ground.project.entry);
429
+ return false;
430
+ }
431
+ const { agents } = this.ground;
432
+ return this.create('profile', agent.agentId, (file) => {
433
+ const code = agentModule(agent, this.from(file).agents);
434
+ // The compiled patterns come from a path of the package, which only its own name reaches.
435
+ return code.includes('compileDetect(') && agents.specifier !== AGENTS_PACKAGE
436
+ ? undefined
437
+ : code;
438
+ }, (specifier) => `import * as ${name} from '${specifier}';`);
439
+ }
440
+ /** A new agent's file and its lines in the setup, after any new agent it calls. */
441
+ agent(agent, calls) {
442
+ if (this.placed.has(agent.agentId))
443
+ return;
444
+ this.placed.add(agent.agentId);
445
+ const { agents, source } = this.ground;
446
+ const before = calls.hoist.get(agent.agentId);
447
+ const waits = held(calls.lead, agent.agentId);
448
+ for (const registration of waits) {
449
+ const ran = registration.type === 'agent' && this.isNew.has(registration.profile)
450
+ ? this.added.agents.find((other) => other.agentId === registration.profile)
451
+ : undefined;
452
+ if (ran)
453
+ this.agent(ran, calls);
454
+ }
455
+ const name = agentIdentifier(agent.agentId, this.taken);
456
+ const made = this.profile(agent, name);
457
+ const follows = held(calls.trail, agent.agentId);
458
+ // An agent that goes before one the project has cannot wait for a tool of its own: that tool has no place.
459
+ if (!made || (before && waits.length)) {
460
+ for (const registration of [...waits, ...follows])
461
+ this.nowhere(registration);
462
+ return;
463
+ }
464
+ const kernel = carried(agents.specifier, agents.file, source.fileName);
465
+ const lines = waits.flatMap((registration) => this.tool(registration));
466
+ if (agent.questions)
467
+ this.setup.add('questions', agent.agentId, `${name}.questions`);
468
+ if (agent.images)
469
+ this.setup.add('images', agent.agentId, `${name}.images`);
470
+ if (agent.structured) {
471
+ const structured = this.setup.needs('registerStructured', kernel);
472
+ lines.push(`${structured}(${name}.structured.id, ${name}.structured.spec);`);
473
+ }
474
+ const register = this.setup.needs('registerProfile', kernel);
475
+ lines.push(`${register}(${name}.profile);`, ...follows.flatMap((registration) => this.tool(registration)));
476
+ if (before)
477
+ this.setup.before(before, lines);
478
+ else
479
+ for (const line of lines)
480
+ this.setup.last(line);
481
+ }
482
+ build() {
483
+ if (!this.setup.plain)
484
+ return this.unplaced();
485
+ for (const provider of this.added.providers)
486
+ this.provider(provider);
487
+ const calls = this.tools();
488
+ for (const agent of this.added.agents) {
489
+ if (this.isNew.has(agent.agentId))
490
+ this.agent(agent, calls);
491
+ }
492
+ this.plan.edits.push(...this.setup.finish());
493
+ return this.plan;
494
+ }
495
+ }
496
+ /**
497
+ * Plans the files and setup lines for what the studio added. `exists` says whether a path is
498
+ * taken. A change it cannot write says why, and nothing is planned for it.
499
+ */
500
+ export function planNew(project, added, exists) {
501
+ if (!added.profiles.length && !added.tools.length && !added.providers.length)
502
+ return { changes: [], edits: [] };
503
+ const source = registeringFile(project);
504
+ const agents = importedFrom(project, ['defineProfile', 'registerProfile', 'registerTool']);
505
+ if (!source || !agents) {
506
+ const changes = [
507
+ ...added.profiles.map((of) => ({ kind: 'profile', of })),
508
+ ...added.tools.map(({ name }) => ({ kind: 'tool', of: name })),
509
+ ...added.providers.map(({ id }) => ({ kind: 'provider', of: id })),
510
+ ].map((change) => ({ ...change, setting: '', status: 'setup', file: project.entry }));
511
+ return { changes, edits: [] };
512
+ }
513
+ return new NewPlan({ project, source, agents, exists }, added).build();
514
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * What Save writes: each changed value of a profile or a tool, found in the
3
+ * builder's file and rewritten there. A value written in the call is changed in
4
+ * place. A value from a constant is changed where the constant is set, when
5
+ * every profile and tool that reads the constant makes the same change, and the
6
+ * plan says when other code reads the constant too. A value from a constant that
7
+ * someone leaves as it was, or from code, is not written; the plan says where it
8
+ * is set and who shares it. A tool's schema is changed in the Zod that writes it,
9
+ * one part at a time (`zod-edit.ts`).
10
+ *
11
+ * @module
12
+ */
13
+ import ts from 'typescript';
14
+ import { type ProjectSource, type SubjectKind } from './project-source.ts';
15
+ import type { DiffHunk, SaveChange } from './save-wire.ts';
16
+ /** A profile, tool, or provider that changed: its values before and after, as the studio holds them. */
17
+ export interface SaveSubject {
18
+ kind: SubjectKind;
19
+ of: string;
20
+ before: unknown;
21
+ after: unknown;
22
+ }
23
+ /** One replacement in a file's text. An insertion has `start === end`. */
24
+ export interface SourceEdit {
25
+ file: string;
26
+ start: number;
27
+ end: number;
28
+ text: string;
29
+ }
30
+ export interface SavePlan {
31
+ changes: SaveChange[];
32
+ edits: SourceEdit[];
33
+ }
34
+ export declare const NOT_PLAIN: unique symbol;
35
+ /** The value an expression writes out in full, or `NOT_PLAIN` when it names or computes anything. */
36
+ export declare function plain(expression: ts.Expression): unknown;
37
+ /** The whitespace a line starts with. */
38
+ export declare function indentAt(source: ts.SourceFile, position: number): string;
39
+ /** One level of a file's indentation: a tab, or its narrowest run of spaces. */
40
+ export declare function indentUnit(source: ts.SourceFile): string;
41
+ /** Finds each subject's call in the project and plans its changes. */
42
+ export declare function planSave(project: ProjectSource, subjects: readonly SaveSubject[]): SavePlan;
43
+ /** `text` with the edits made. Throws when two edits touch the same characters. */
44
+ export declare function applyEdits(text: string, edits: readonly SourceEdit[]): string;
45
+ /** The changed lines of one file, from the edits made to it. */
46
+ export declare function diffHunks(text: string, edits: readonly SourceEdit[]): DiffHunk[];