@maniclang/workbench 0.1.11

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 (644) hide show
  1. package/CONTRIBUTING.md +40 -0
  2. package/README.md +155 -0
  3. package/dist/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  4. package/dist/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  5. package/dist/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  6. package/dist/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  7. package/dist/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  8. package/dist/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  9. package/dist/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  10. package/dist/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  11. package/dist/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  12. package/dist/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  13. package/dist/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  14. package/dist/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  15. package/dist/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  16. package/dist/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  17. package/dist/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  18. package/dist/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  19. package/dist/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  20. package/dist/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  21. package/dist/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  22. package/dist/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  23. package/dist/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  24. package/dist/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  25. package/dist/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  26. package/dist/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  27. package/dist/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  28. package/dist/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  29. package/dist/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  30. package/dist/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  31. package/dist/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  32. package/dist/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  33. package/dist/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  34. package/dist/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  35. package/dist/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  36. package/dist/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  37. package/dist/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  38. package/dist/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  39. package/dist/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  40. package/dist/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  41. package/dist/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  42. package/dist/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  43. package/dist/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  44. package/dist/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  45. package/dist/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  46. package/dist/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  47. package/dist/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  48. package/dist/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  49. package/dist/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  50. package/dist/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  51. package/dist/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  52. package/dist/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  53. package/dist/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  54. package/dist/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  55. package/dist/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  56. package/dist/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  57. package/dist/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  58. package/dist/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  59. package/dist/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  60. package/dist/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  61. package/dist/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  62. package/dist/client/assets/abap-CRCWOmpq.js +1 -0
  63. package/dist/client/assets/apex-DnsZk_dE.js +1 -0
  64. package/dist/client/assets/azcli-1IWB1ccx.js +1 -0
  65. package/dist/client/assets/bat-DPkNLes8.js +1 -0
  66. package/dist/client/assets/bicep-Corcdgou.js +2 -0
  67. package/dist/client/assets/cameligo-CGrWLZr3.js +1 -0
  68. package/dist/client/assets/clojure-D9WOWImG.js +1 -0
  69. package/dist/client/assets/codicon-CgENjH2v.ttf +0 -0
  70. package/dist/client/assets/coffee-B7EJu28W.js +1 -0
  71. package/dist/client/assets/cpp-SEyurbux.js +1 -0
  72. package/dist/client/assets/csharp-BoL64M5l.js +1 -0
  73. package/dist/client/assets/csp-C46ZqvIl.js +1 -0
  74. package/dist/client/assets/css-DQU6DXDx.js +3 -0
  75. package/dist/client/assets/cssMode-CtRONlr8.js +4 -0
  76. package/dist/client/assets/cypher-D84EuPTj.js +1 -0
  77. package/dist/client/assets/dart-D8lhlL1r.js +1 -0
  78. package/dist/client/assets/dockerfile-DLk6rpji.js +1 -0
  79. package/dist/client/assets/ecl-BO6FnfXk.js +1 -0
  80. package/dist/client/assets/editor.worker-CZyr7Ur9.js +26 -0
  81. package/dist/client/assets/elixir-BRjLKONM.js +1 -0
  82. package/dist/client/assets/flow9-Cac8vKd7.js +1 -0
  83. package/dist/client/assets/freemarker2-BTSNJUl8.js +3 -0
  84. package/dist/client/assets/fsharp-fd1GTHhf.js +1 -0
  85. package/dist/client/assets/go-O9LJTZXk.js +1 -0
  86. package/dist/client/assets/graphql-LQdxqEYJ.js +1 -0
  87. package/dist/client/assets/handlebars-qkUBjVg6.js +1 -0
  88. package/dist/client/assets/hcl-DxDQ3s82.js +1 -0
  89. package/dist/client/assets/html-pguqE00h.js +1 -0
  90. package/dist/client/assets/htmlMode-BCCLuk2F.js +4 -0
  91. package/dist/client/assets/index-BFrMLHHu.css +1 -0
  92. package/dist/client/assets/index-CdBC-xgi.js +1250 -0
  93. package/dist/client/assets/ini-BvajGCUy.js +1 -0
  94. package/dist/client/assets/java-SYsfObOQ.js +1 -0
  95. package/dist/client/assets/javascript-ciDUXdez.js +1 -0
  96. package/dist/client/assets/jsonMode-BmkXC0tI.js +10 -0
  97. package/dist/client/assets/julia-DQXNmw_w.js +1 -0
  98. package/dist/client/assets/kotlin-qQ0MG-9I.js +1 -0
  99. package/dist/client/assets/less-GGFNNJHn.js +2 -0
  100. package/dist/client/assets/lexon-Canl7DCW.js +1 -0
  101. package/dist/client/assets/liquid-CwE4UIwf.js +1 -0
  102. package/dist/client/assets/lua-D28Ae8-K.js +1 -0
  103. package/dist/client/assets/m3-DPitgjJI.js +1 -0
  104. package/dist/client/assets/markdown-B811l8j2.js +1 -0
  105. package/dist/client/assets/mdx-K_9Emnjy.js +1 -0
  106. package/dist/client/assets/mips-CdjsipkG.js +1 -0
  107. package/dist/client/assets/msdax-CYqgjx_P.js +1 -0
  108. package/dist/client/assets/mysql-BHd6q0vd.js +1 -0
  109. package/dist/client/assets/objective-c-B1aVtJYH.js +1 -0
  110. package/dist/client/assets/pascal-BhNW15KB.js +1 -0
  111. package/dist/client/assets/pascaligo-5jv8CcQD.js +1 -0
  112. package/dist/client/assets/perl-DlYyT36c.js +1 -0
  113. package/dist/client/assets/pgsql-Dy0bjov7.js +1 -0
  114. package/dist/client/assets/php-120yhfDK.js +1 -0
  115. package/dist/client/assets/pla-CjnFlu4u.js +1 -0
  116. package/dist/client/assets/postiats-CQpG440k.js +1 -0
  117. package/dist/client/assets/powerquery-DdJtto1Z.js +1 -0
  118. package/dist/client/assets/powershell-Bu_VLpJB.js +1 -0
  119. package/dist/client/assets/protobuf-IBS6jZEB.js +2 -0
  120. package/dist/client/assets/pug-kFxLfcjb.js +1 -0
  121. package/dist/client/assets/python-BzIc0EVe.js +1 -0
  122. package/dist/client/assets/qsharp-q7JyzKFN.js +1 -0
  123. package/dist/client/assets/r-BIFz-_sK.js +1 -0
  124. package/dist/client/assets/razor-lXZl6dtu.js +1 -0
  125. package/dist/client/assets/redis-CHOsPHWR.js +1 -0
  126. package/dist/client/assets/redshift-CBifECDb.js +1 -0
  127. package/dist/client/assets/restructuredtext-CghPJEOS.js +1 -0
  128. package/dist/client/assets/ruby-CYWGW-b1.js +1 -0
  129. package/dist/client/assets/rust-DMDD0SHb.js +1 -0
  130. package/dist/client/assets/sb-BYAiYHFx.js +1 -0
  131. package/dist/client/assets/scala-Bqvq8jcR.js +1 -0
  132. package/dist/client/assets/scheme-Dhb-2j9p.js +1 -0
  133. package/dist/client/assets/scss-CTwUZ5N7.js +3 -0
  134. package/dist/client/assets/shell-CsDZo4DB.js +1 -0
  135. package/dist/client/assets/solidity-CME5AdoB.js +1 -0
  136. package/dist/client/assets/sophia-RYC1BQQz.js +1 -0
  137. package/dist/client/assets/sparql-KEyrF7De.js +1 -0
  138. package/dist/client/assets/sql-BdTr02Mf.js +1 -0
  139. package/dist/client/assets/st-C7iG7M4S.js +1 -0
  140. package/dist/client/assets/swift-D7IUmUK8.js +1 -0
  141. package/dist/client/assets/systemverilog-DgMryOEJ.js +1 -0
  142. package/dist/client/assets/tcl-PloMZuKG.js +1 -0
  143. package/dist/client/assets/tsMode-BAXmgo_t.js +11 -0
  144. package/dist/client/assets/twig-BfRIq3la.js +1 -0
  145. package/dist/client/assets/typescript-Cdf8nS1n.js +1 -0
  146. package/dist/client/assets/typespec-CzxlYoT_.js +1 -0
  147. package/dist/client/assets/vb-BwAE3J76.js +1 -0
  148. package/dist/client/assets/wgsl-B_1kOXbF.js +298 -0
  149. package/dist/client/assets/xml-DGyPgYnj.js +1 -0
  150. package/dist/client/assets/yaml-Dqv3HtbL.js +1 -0
  151. package/dist/client/index.html +14 -0
  152. package/dist/client/manic-logo.png +0 -0
  153. package/dist/client/wasm/manic_lang.d.ts +74 -0
  154. package/dist/client/wasm/manic_lang.js +302 -0
  155. package/dist/client/wasm/manic_lang_bg.wasm +0 -0
  156. package/dist/client/wasm/manic_lang_bg.wasm.d.ts +13 -0
  157. package/dist/server/agentProtocol.d.ts +131 -0
  158. package/dist/server/agentProtocol.js +21 -0
  159. package/dist/server/agentProtocol.js.map +1 -0
  160. package/dist/server/agentRuns.d.ts +46 -0
  161. package/dist/server/agentRuns.js +138 -0
  162. package/dist/server/agentRuns.js.map +1 -0
  163. package/dist/server/agentThreads.d.ts +20 -0
  164. package/dist/server/agentThreads.js +205 -0
  165. package/dist/server/agentThreads.js.map +1 -0
  166. package/dist/server/aiSecrets.d.ts +21 -0
  167. package/dist/server/aiSecrets.js +68 -0
  168. package/dist/server/aiSecrets.js.map +1 -0
  169. package/dist/server/app.d.ts +34 -0
  170. package/dist/server/app.js +804 -0
  171. package/dist/server/app.js.map +1 -0
  172. package/dist/server/assets.d.ts +34 -0
  173. package/dist/server/assets.js +659 -0
  174. package/dist/server/assets.js.map +1 -0
  175. package/dist/server/candidateFix.d.ts +28 -0
  176. package/dist/server/candidateFix.js +111 -0
  177. package/dist/server/candidateFix.js.map +1 -0
  178. package/dist/server/cli.d.ts +2 -0
  179. package/dist/server/cli.js +118 -0
  180. package/dist/server/cli.js.map +1 -0
  181. package/dist/server/diagnostics.d.ts +13 -0
  182. package/dist/server/diagnostics.js +73 -0
  183. package/dist/server/diagnostics.js.map +1 -0
  184. package/dist/server/engineCheck.d.ts +7 -0
  185. package/dist/server/engineCheck.js +60 -0
  186. package/dist/server/engineCheck.js.map +1 -0
  187. package/dist/server/engineInstall.d.ts +34 -0
  188. package/dist/server/engineInstall.js +228 -0
  189. package/dist/server/engineInstall.js.map +1 -0
  190. package/dist/server/enginePaths.d.ts +3 -0
  191. package/dist/server/enginePaths.js +76 -0
  192. package/dist/server/enginePaths.js.map +1 -0
  193. package/dist/server/folderPicker.d.ts +1 -0
  194. package/dist/server/folderPicker.js +54 -0
  195. package/dist/server/folderPicker.js.map +1 -0
  196. package/dist/server/manicAgent.d.ts +75 -0
  197. package/dist/server/manicAgent.js +476 -0
  198. package/dist/server/manicAgent.js.map +1 -0
  199. package/dist/server/manicEnv.d.ts +18 -0
  200. package/dist/server/manicEnv.js +64 -0
  201. package/dist/server/manicEnv.js.map +1 -0
  202. package/dist/server/promptStore.d.ts +11 -0
  203. package/dist/server/promptStore.js +85 -0
  204. package/dist/server/promptStore.js.map +1 -0
  205. package/dist/server/renderJobs.d.ts +54 -0
  206. package/dist/server/renderJobs.js +290 -0
  207. package/dist/server/renderJobs.js.map +1 -0
  208. package/dist/server/settings.d.ts +40 -0
  209. package/dist/server/settings.js +262 -0
  210. package/dist/server/settings.js.map +1 -0
  211. package/dist/server/smartDraw.d.ts +7 -0
  212. package/dist/server/smartDraw.js +88 -0
  213. package/dist/server/smartDraw.js.map +1 -0
  214. package/dist/server/workspace.d.ts +27 -0
  215. package/dist/server/workspace.js +172 -0
  216. package/dist/server/workspace.js.map +1 -0
  217. package/examples/.manic-output/40b6f3b9-7638-4c0e-bb4f-570d45d1b225/job.json +26 -0
  218. package/examples/.manic-output/993f3788-f75e-445c-ba45-c401907b3c02/job.json +26 -0
  219. package/examples/.manic-output/993f3788-f75e-445c-ba45-c401907b3c02/markers.json +13 -0
  220. package/examples/.manic-output/993f3788-f75e-445c-ba45-c401907b3c02/out.mp4 +0 -0
  221. package/examples/.manic-workbench-threads/thread_3ce7448a13f64f9e887d1bc8106a97a8.json +45 -0
  222. package/examples/.manic-workbench-threads/thread_d494cda29249477591056234719e4a3a.json +21 -0
  223. package/examples/.manic-workbench-threads/thread_e98ebdc225184ea5b8ddda8b44541f63.json +29 -0
  224. package/examples/README.md +35 -0
  225. package/examples/a-story-1.manic +222 -0
  226. package/examples/a-story.manic +100 -0
  227. package/examples/achromat-cinematic.manic +105 -0
  228. package/examples/achromat.manic +32 -0
  229. package/examples/aes-decrypt.manic +359 -0
  230. package/examples/aes-encrypt.manic +359 -0
  231. package/examples/aes-round.manic +70 -0
  232. package/examples/aes-story.manic +622 -0
  233. package/examples/ai-story.manic +118 -0
  234. package/examples/analysis.manic +53 -0
  235. package/examples/archimedes_pi.manic +89 -0
  236. package/examples/area_under_curve.manic +131 -0
  237. package/examples/art-rakkan.manic +69 -0
  238. package/examples/aspheric-lens.manic +32 -0
  239. package/examples/astronomical-watch.manic +96 -0
  240. package/examples/asymptote-randomwalk3-reference.manic +58 -0
  241. package/examples/asymptote-tiling-reference.manic +65 -0
  242. package/examples/aws-clustered-web-services.manic +186 -0
  243. package/examples/aws-event-processing-clusters-poc.manic +97 -0
  244. package/examples/aws-three-tier-web-application.manic +134 -0
  245. package/examples/band.manic +43 -0
  246. package/examples/banner.manic +37 -0
  247. package/examples/bayes.manic +27 -0
  248. package/examples/bellcurve.manic +41 -0
  249. package/examples/bfs_dfs.manic +35 -0
  250. package/examples/block-tackle.manic +26 -0
  251. package/examples/bloom-scope.manic +172 -0
  252. package/examples/boolean.manic +46 -0
  253. package/examples/boxplot-wave.manic +93 -0
  254. package/examples/boxplot.manic +43 -0
  255. package/examples/brace.manic +46 -0
  256. package/examples/brachistochrone-annotated.manic +51 -0
  257. package/examples/brachistochrone.manic +27 -0
  258. package/examples/bubble_sort.manic +41 -0
  259. package/examples/bullet-block-annotated.manic +48 -0
  260. package/examples/bullet-block.manic +11 -0
  261. package/examples/bullet-impact.manic +65 -0
  262. package/examples/bungee.manic +9 -0
  263. package/examples/c4-internet-banking-components.manic +33 -0
  264. package/examples/c4-internet-banking-containers.manic +29 -0
  265. package/examples/c4-internet-banking.manic +26 -0
  266. package/examples/c4-story.manic +171 -0
  267. package/examples/c4-test.manic +52 -0
  268. package/examples/c4-zoom.manic +69 -0
  269. package/examples/calculus-demo.manic +129 -0
  270. package/examples/calculus-one.manic +288 -0
  271. package/examples/captions.manic +31 -0
  272. package/examples/car-suspension-annotated.manic +57 -0
  273. package/examples/car-suspension.manic +8 -0
  274. package/examples/cart-pendulum.manic +11 -0
  275. package/examples/charts-bar-line.manic +26 -0
  276. package/examples/charts-column-race.manic +19 -0
  277. package/examples/charts-gdp-race.manic +43 -0
  278. package/examples/charts-german-elections.manic +28 -0
  279. package/examples/charts-line-race.manic +21 -0
  280. package/examples/circle-in-three.manic +156 -0
  281. package/examples/circle-thirds-no-triangle.manic +161 -0
  282. package/examples/clip-window.manic +34 -0
  283. package/examples/cloud-feathers.manic +50 -0
  284. package/examples/cloud-jellyfish-v2.manic +87 -0
  285. package/examples/cloud-jellyfish.manic +48 -0
  286. package/examples/cloud-kaleidoscope.manic +48 -0
  287. package/examples/cloud-koi.manic +51 -0
  288. package/examples/cloud-lissajous.manic +23 -0
  289. package/examples/cloud-medusae.manic +46 -0
  290. package/examples/cloud-phoenix.manic +49 -0
  291. package/examples/cloud-plumes.manic +47 -0
  292. package/examples/cloud-pottery.manic +104 -0
  293. package/examples/cloud-shells.manic +50 -0
  294. package/examples/cloud-starfield.manic +23 -0
  295. package/examples/cloud-wave-lattice.manic +23 -0
  296. package/examples/cloud-word.manic +31 -0
  297. package/examples/cloud3-ripple.manic +53 -0
  298. package/examples/cloud3-sphere.manic +26 -0
  299. package/examples/clt.manic +35 -0
  300. package/examples/collide-blocks-annotated.manic +45 -0
  301. package/examples/collide-blocks.manic +11 -0
  302. package/examples/compare-pendulum.manic +11 -0
  303. package/examples/complex-flowchart.manic +196 -0
  304. package/examples/compound-pulley.manic +25 -0
  305. package/examples/conics.manic +46 -0
  306. package/examples/coordinates.manic +52 -0
  307. package/examples/correlation.manic +35 -0
  308. package/examples/covariance.manic +30 -0
  309. package/examples/creator-affine-fern-growth.manic +72 -0
  310. package/examples/creator-bowl-to-saddle.manic +86 -0
  311. package/examples/creator-branch-counting-tree3.manic +77 -0
  312. package/examples/creator-chaos-game-fern.manic +72 -0
  313. package/examples/creator-circle-inversion-chain.manic +61 -0
  314. package/examples/creator-convex-hull-depth.manic +59 -0
  315. package/examples/creator-coordinate-worlds.manic +182 -0
  316. package/examples/creator-ellipse-reflection-property.manic +59 -0
  317. package/examples/creator-free-kicks.manic +261 -0
  318. package/examples/creator-geometry-language-showcase.manic +259 -0
  319. package/examples/creator-geometry-morph-promo.manic +151 -0
  320. package/examples/creator-heightmap-world.manic +130 -0
  321. package/examples/creator-hilbert3-spatial-index.manic +203 -0
  322. package/examples/creator-how-rocket-launch-works.manic +192 -0
  323. package/examples/creator-implicit-surface-parameterized.manic +51 -0
  324. package/examples/creator-incenter-dissection.manic +56 -0
  325. package/examples/creator-lattice-paths.manic +118 -0
  326. package/examples/creator-line-inversion.manic +49 -0
  327. package/examples/creator-lsystem-fractal-curve.manic +121 -0
  328. package/examples/creator-mandelbrot-escape-test.manic +58 -0
  329. package/examples/creator-monty-hall.manic +104 -0
  330. package/examples/creator-noise-story.manic +123 -0
  331. package/examples/creator-one-tile-pattern-story.manic +169 -0
  332. package/examples/creator-pathfinding.manic +82 -0
  333. package/examples/creator-point-to-plane-distance.manic +167 -0
  334. package/examples/creator-race-quiz.manic +76 -0
  335. package/examples/creator-randomwalk3-diffusion.manic +72 -0
  336. package/examples/creator-reflected-ellipse.manic +48 -0
  337. package/examples/creator-rule90-sierpinski.manic +64 -0
  338. package/examples/creator-three-shadows-of-a-curve.manic +48 -0
  339. package/examples/creator-trigonometry-one-angle.manic +307 -0
  340. package/examples/creator-v2-latex-algebra.manic +29 -0
  341. package/examples/creator-v2-latex-calculus.manic +37 -0
  342. package/examples/creator-v2-latex-physics.manic +29 -0
  343. package/examples/creator-v2-olympiad-geometry.manic +92 -0
  344. package/examples/creator-v2-options-socials.manic +21 -0
  345. package/examples/creator-v2-timers.manic +25 -0
  346. package/examples/creator-v2-timing-square.manic +25 -0
  347. package/examples/creator-v2-timing.manic +34 -0
  348. package/examples/creator-v2.manic +36 -0
  349. package/examples/creator-why-rockets-use-stages.manic +198 -0
  350. package/examples/creator-wrap-real-line.manic +51 -0
  351. package/examples/cubic-graphs.manic +432 -0
  352. package/examples/curve-features.manic +41 -0
  353. package/examples/definedmotion-fourier-gallery.manic +171 -0
  354. package/examples/derivative-of-ln-x.manic +194 -0
  355. package/examples/diagonalise.manic +56 -0
  356. package/examples/dijkstra.manic +29 -0
  357. package/examples/dimensions-unfold.manic +211 -0
  358. package/examples/disc-integration.manic +172 -0
  359. package/examples/double-incline.manic +9 -0
  360. package/examples/double-integral3.manic +43 -0
  361. package/examples/double-pendulum.manic +35 -0
  362. package/examples/double-spring.manic +9 -0
  363. package/examples/drop-mass.manic +25 -0
  364. package/examples/eigen3.manic +34 -0
  365. package/examples/equal_cuts.manic +44 -0
  366. package/examples/equation.manic +16 -0
  367. package/examples/equilateral.manic +57 -0
  368. package/examples/euler_line.manic +51 -0
  369. package/examples/exponential-shells.manic +188 -0
  370. package/examples/extrude3.manic +37 -0
  371. package/examples/factorial-flowchart.manic +69 -0
  372. package/examples/fibonacci-sphere.manic +57 -0
  373. package/examples/flow-lorenz.manic +47 -0
  374. package/examples/fourier-series-live-wave.manic +114 -0
  375. package/examples/fourier-square-wave-live.manic +114 -0
  376. package/examples/fractal_tree.manic +39 -0
  377. package/examples/frame3-grid-policies.manic +48 -0
  378. package/examples/ftc.manic +54 -0
  379. package/examples/function_graph.manic +54 -0
  380. package/examples/galton-board-process.manic +150 -0
  381. package/examples/gcp-clustered-web-services.manic +186 -0
  382. package/examples/gcp-message-collecting.manic +139 -0
  383. package/examples/geo-pythagoras-short.manic +119 -0
  384. package/examples/glsl-boxgrid.manic +105 -0
  385. package/examples/glsl-parameter.manic +30 -0
  386. package/examples/glsl-raymarch.manic +59 -0
  387. package/examples/glsl-shapes.manic +122 -0
  388. package/examples/gradient-descent-field.manic +116 -0
  389. package/examples/gradient-fastest-descent-shorts.manic +153 -0
  390. package/examples/gradient-fastest-descent.manic +125 -0
  391. package/examples/gradient-pendulum-shorts.manic +117 -0
  392. package/examples/gradient.manic +74 -0
  393. package/examples/graph.manic +45 -0
  394. package/examples/graph_moving.manic +67 -0
  395. package/examples/grid-astar.manic +15 -0
  396. package/examples/grid-life-soup.manic +31 -0
  397. package/examples/grid-life-zoo.manic +46 -0
  398. package/examples/grid-life.manic +19 -0
  399. package/examples/grid-wfc.manic +13 -0
  400. package/examples/growing-fractal-tree3.manic +58 -0
  401. package/examples/gun-shot.manic +82 -0
  402. package/examples/hashmap.manic +38 -0
  403. package/examples/heightmap3-world.manic +64 -0
  404. package/examples/heightmap3.manic +23 -0
  405. package/examples/hilbert-curve3-space-filling.manic +117 -0
  406. package/examples/hill_run.manic +71 -0
  407. package/examples/histogram.manic +43 -0
  408. package/examples/hotdog-taco.manic +147 -0
  409. package/examples/hue_wave.manic +35 -0
  410. package/examples/hypothesis.manic +32 -0
  411. package/examples/image.manic +29 -0
  412. package/examples/incircle_tangents.manic +64 -0
  413. package/examples/incline-bumper.manic +11 -0
  414. package/examples/incline-pulley.manic +11 -0
  415. package/examples/incline-showcase.manic +55 -0
  416. package/examples/inline-math.manic +16 -0
  417. package/examples/inscribed-angle-short.manic +56 -0
  418. package/examples/integral-sqrt-tanx.manic +255 -0
  419. package/examples/integrals.manic +274 -0
  420. package/examples/inverse-derivatives.manic +94 -0
  421. package/examples/k8s-cluster-components.manic +82 -0
  422. package/examples/k8s-stateful-architecture.manic +134 -0
  423. package/examples/k8s-three-tier.manic +146 -0
  424. package/examples/kapitza.manic +11 -0
  425. package/examples/latex-disintegration.manic +123 -0
  426. package/examples/lens-paper.manic +36 -0
  427. package/examples/lens-prescription.manic +33 -0
  428. package/examples/lens-system.manic +34 -0
  429. package/examples/lens.manic +31 -0
  430. package/examples/limit-infinity.manic +30 -0
  431. package/examples/limit.manic +33 -0
  432. package/examples/linear-algebra-3d.manic +50 -0
  433. package/examples/linear-algebra.manic +115 -0
  434. package/examples/linear-map.manic +39 -0
  435. package/examples/linear-map3.manic +33 -0
  436. package/examples/linear-system.manic +99 -0
  437. package/examples/linear_transform.manic +43 -0
  438. package/examples/linked_list.manic +38 -0
  439. package/examples/lln.manic +31 -0
  440. package/examples/loop-cinematic.manic +41 -0
  441. package/examples/loop-track.manic +11 -0
  442. package/examples/lorenz-attractor.manic +55 -0
  443. package/examples/lorenz-shells.manic +43 -0
  444. package/examples/lost-in-patterns.manic +149 -0
  445. package/examples/lsystem-asymptote-curves.manic +81 -0
  446. package/examples/manic-ml-activation-focus.manic +133 -0
  447. package/examples/manic-ml-cnn-edge-story.manic +102 -0
  448. package/examples/manic-ml-forward-pass.manic +93 -0
  449. package/examples/manic-ml-learning-step.manic +116 -0
  450. package/examples/manic-ml-logits-sampling.manic +112 -0
  451. package/examples/manic-ml-scalar-to-tensor.manic +143 -0
  452. package/examples/manic-ml-token-embedding.manic +110 -0
  453. package/examples/manic-ml-transformer-attention.manic +102 -0
  454. package/examples/manic-ml-transformer-block.manic +116 -0
  455. package/examples/manic-promo.manic +64 -0
  456. package/examples/map-attractor.manic +45 -0
  457. package/examples/mask-lens.manic +33 -0
  458. package/examples/matrix.manic +37 -0
  459. package/examples/matrix3.manic +101 -0
  460. package/examples/matrix_addition.manic +66 -0
  461. package/examples/matrix_addition_plane.manic +91 -0
  462. package/examples/maxwell-boltzmann-effusion-v2.manic +142 -0
  463. package/examples/maxwell-boltzmann-process.manic +86 -0
  464. package/examples/microservices-platform.manic +140 -0
  465. package/examples/molecule.manic +8 -0
  466. package/examples/morph-icons.manic +29 -0
  467. package/examples/morph.manic +29 -0
  468. package/examples/morph3.manic +49 -0
  469. package/examples/motion-flow-foundation.manic +148 -0
  470. package/examples/motion-graphics-v2-story.manic +189 -0
  471. package/examples/motion-graphics-v2.manic +81 -0
  472. package/examples/motion-graphics.manic +81 -0
  473. package/examples/multivariable3.manic +26 -0
  474. package/examples/mystory.manic +9 -0
  475. package/examples/newton.manic +39 -0
  476. package/examples/newtons-cradle.manic +10 -0
  477. package/examples/nine_point.manic +59 -0
  478. package/examples/noise-terrain.manic +16 -0
  479. package/examples/off-axis.manic +32 -0
  480. package/examples/onprem-advanced-web-service-v2.manic +196 -0
  481. package/examples/onprem-advanced-web-service.manic +175 -0
  482. package/examples/orthocenter.manic +63 -0
  483. package/examples/param3.manic +43 -0
  484. package/examples/parameter-journeys.manic +154 -0
  485. package/examples/parameterized-field-advection.manic +57 -0
  486. package/examples/parameterized-generated-families3.manic +83 -0
  487. package/examples/particles-flow.manic +61 -0
  488. package/examples/pascal-triangle.manic +92 -0
  489. package/examples/pendulum-annotated.manic +72 -0
  490. package/examples/pendulum-damped.manic +35 -0
  491. package/examples/pendulum.manic +38 -0
  492. package/examples/perfect-reel.manic +43 -0
  493. package/examples/pie.manic +41 -0
  494. package/examples/pieday.manic +113 -0
  495. package/examples/piston.manic +7 -0
  496. package/examples/popkorn-field.manic +38 -0
  497. package/examples/prism-cinematic.manic +36 -0
  498. package/examples/prism.manic +32 -0
  499. package/examples/probability.manic +57 -0
  500. package/examples/process-branching-dispatch.manic +71 -0
  501. package/examples/process-stream-observe.manic +54 -0
  502. package/examples/projection.manic +57 -0
  503. package/examples/prompt-test-10.manic +257 -0
  504. package/examples/prompt-test-11.manic +168 -0
  505. package/examples/prompt-test-12.manic +177 -0
  506. package/examples/prompt-test-13.manic +228 -0
  507. package/examples/prompt-test-14.manic +319 -0
  508. package/examples/prompt-test-15.manic +325 -0
  509. package/examples/prompt-test-16.manic +252 -0
  510. package/examples/prompt-test-2.manic +239 -0
  511. package/examples/prompt-test-3.manic +336 -0
  512. package/examples/prompt-test-4.manic +195 -0
  513. package/examples/prompt-test-5.manic +223 -0
  514. package/examples/prompt-test-6.manic +222 -0
  515. package/examples/prompt-test-7.manic +156 -0
  516. package/examples/prompt-test-8.manic +266 -0
  517. package/examples/prompt-test-9.manic +171 -0
  518. package/examples/prompt-test.manic +158 -0
  519. package/examples/pulley-annotated.manic +54 -0
  520. package/examples/pulley-paper.manic +52 -0
  521. package/examples/pulley-scale.manic +23 -0
  522. package/examples/pulley.manic +24 -0
  523. package/examples/quadratic-formula-continuity.manic +110 -0
  524. package/examples/quiz-euler.manic +52 -0
  525. package/examples/quiz-geometry-2.manic +107 -0
  526. package/examples/quiz-geometry.manic +108 -0
  527. package/examples/quiz-skins.manic +22 -0
  528. package/examples/raft-cm.manic +24 -0
  529. package/examples/ramp.manic +25 -0
  530. package/examples/ray-fan.manic +27 -0
  531. package/examples/raymarch-alpha.manic +39 -0
  532. package/examples/raymarch-boxgrid.manic +47 -0
  533. package/examples/raymarch-docker-latency.manic +74 -0
  534. package/examples/raymarch-metaballs.manic +37 -0
  535. package/examples/raymarch-sculpture.manic +39 -0
  536. package/examples/raymarch-shapes3.manic +31 -0
  537. package/examples/reactive-integral.manic +172 -0
  538. package/examples/reactive-math-journey.manic +185 -0
  539. package/examples/reactive-math-notation.manic +150 -0
  540. package/examples/reactive-multiformat.manic +130 -0
  541. package/examples/reactive-world.manic +111 -0
  542. package/examples/refraction-paper.manic +40 -0
  543. package/examples/refraction.manic +32 -0
  544. package/examples/resonance.manic +10 -0
  545. package/examples/rewrite-exponential-cubic.manic +141 -0
  546. package/examples/rewrite-integration.manic +199 -0
  547. package/examples/riemann_rainbow.manic +61 -0
  548. package/examples/riemann_readout.manic +61 -0
  549. package/examples/robot-arm.manic +25 -0
  550. package/examples/rref.manic +48 -0
  551. package/examples/second-law-thermodynamics.manic +385 -0
  552. package/examples/series-parallel-springs.manic +8 -0
  553. package/examples/serverless-processing.manic +145 -0
  554. package/examples/shader-cellular.manic +35 -0
  555. package/examples/shader-fractal.manic +45 -0
  556. package/examples/shader-fx.manic +34 -0
  557. package/examples/shader-glitch-grid.manic +55 -0
  558. package/examples/shader-parameter.manic +25 -0
  559. package/examples/shader-patterns.manic +37 -0
  560. package/examples/shader-plasma.manic +43 -0
  561. package/examples/shader-shapes-dsl.manic +46 -0
  562. package/examples/shader-shapes.manic +37 -0
  563. package/examples/shader-warp.manic +22 -0
  564. package/examples/shapes-howto.manic +411 -0
  565. package/examples/sine_wave.manic +42 -0
  566. package/examples/skew.manic +40 -0
  567. package/examples/smoke.rs +57 -0
  568. package/examples/solids3.manic +22 -0
  569. package/examples/some-story.manic +299 -0
  570. package/examples/spinning-cylinder-flow.manic +87 -0
  571. package/examples/spline.manic +21 -0
  572. package/examples/spot-diagram.manic +32 -0
  573. package/examples/spring-annotated.manic +60 -0
  574. package/examples/spring-chain.manic +11 -0
  575. package/examples/spring-damped.manic +33 -0
  576. package/examples/spring-incline.manic +10 -0
  577. package/examples/spring-paper.manic +46 -0
  578. package/examples/spring-pendulum.manic +14 -0
  579. package/examples/spring.manic +33 -0
  580. package/examples/sqrt-tanx.manic +217 -0
  581. package/examples/ssl-handshake-sdf.manic +116 -0
  582. package/examples/stack_queue.manic +53 -0
  583. package/examples/statistics.manic +60 -0
  584. package/examples/story-addressable-asset-cues.manic +71 -0
  585. package/examples/story-dependent-chain-history.manic +56 -0
  586. package/examples/story-living-dependency-cloud.manic +50 -0
  587. package/examples/story-time-varying-field3.manic +57 -0
  588. package/examples/story.manic +4 -0
  589. package/examples/string-art-breath.manic +70 -0
  590. package/examples/string-wave.manic +10 -0
  591. package/examples/summary.manic +48 -0
  592. package/examples/svg-howto.manic +172 -0
  593. package/examples/svg-import.manic +18 -0
  594. package/examples/systems-architecture-poc.manic +92 -0
  595. package/examples/systems-arrow-patterns.manic +151 -0
  596. package/examples/systems-foundation.manic +71 -0
  597. package/examples/systems-rabbitmq-consumers.manic +118 -0
  598. package/examples/table.manic +39 -0
  599. package/examples/table_braces.manic +54 -0
  600. package/examples/tangent-length-short.manic +57 -0
  601. package/examples/tangent.manic +29 -0
  602. package/examples/tangents.manic +54 -0
  603. package/examples/taylor.manic +44 -0
  604. package/examples/terminal_boot.manic +40 -0
  605. package/examples/test.manic +61 -0
  606. package/examples/text-guide.manic +304 -0
  607. package/examples/textbook-coordinate-worlds.manic +129 -0
  608. package/examples/textbook-doubly-list.manic +33 -0
  609. package/examples/textbook-function-to-solid.manic +126 -0
  610. package/examples/textbook-geometry-dimension-reduction.manic +129 -0
  611. package/examples/textbook-incline-fbd.manic +43 -0
  612. package/examples/textbook-length-area-volume.manic +137 -0
  613. package/examples/textbook-matrix-inverses.manic +172 -0
  614. package/examples/textbook-pulley.manic +35 -0
  615. package/examples/textbook-statistical-dimensions.manic +151 -0
  616. package/examples/textbook-tension.manic +39 -0
  617. package/examples/textbook-watermelon-sections.manic +216 -0
  618. package/examples/thales-semicircle-short.manic +53 -0
  619. package/examples/three-d-v2-lab.manic +83 -0
  620. package/examples/three-d-v2-story.manic +106 -0
  621. package/examples/three-d-v2.manic +69 -0
  622. package/examples/three_d.manic +39 -0
  623. package/examples/timing-v2-scene.manic +47 -0
  624. package/examples/trajectory.manic +28 -0
  625. package/examples/transform_copy.manic +35 -0
  626. package/examples/transforms.manic +54 -0
  627. package/examples/trapped-light-dimensions.manic +226 -0
  628. package/examples/tree-of-leaves.manic +215 -0
  629. package/examples/triangle.manic +68 -0
  630. package/examples/two_person_walk.manic +296 -0
  631. package/examples/two_pointer.manic +32 -0
  632. package/examples/type-to-sdf.manic +139 -0
  633. package/examples/typewriter.manic +28 -0
  634. package/examples/vector_field.manic +32 -0
  635. package/examples/vertical-spring.manic +10 -0
  636. package/examples/volume3.manic +21 -0
  637. package/examples/volumes-solid-of-revolution.manic +111 -0
  638. package/examples/walk.manic +154 -0
  639. package/examples/wheel-duo.manic +91 -0
  640. package/examples/wheel-radial.manic +78 -0
  641. package/examples/wheel-square.manic +83 -0
  642. package/examples/wireframe-spheres.manic +37 -0
  643. package/examples/zeroth-law-thermodynamics.manic +269 -0
  644. package/package.json +59 -0
@@ -0,0 +1,804 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { createReadStream } from "node:fs";
3
+ import { stat } from "node:fs/promises";
4
+ import { extname, relative, resolve } from "node:path";
5
+ import { Readable } from "node:stream";
6
+ import { Hono } from "hono";
7
+ import { normalizeAiBaseUrl } from "./settings.js";
8
+ import { RenderJobManager } from "./renderJobs.js";
9
+ import { runEngineCheck } from "./engineCheck.js";
10
+ import { createAiSecretStore } from "./aiSecrets.js";
11
+ import { AgentRunManager } from "./agentRuns.js";
12
+ import { createCandidateFixer } from "./candidateFix.js";
13
+ import { getEngineInstallPlan, installManicEngine } from "./engineInstall.js";
14
+ import { AnthropicProvider, OpenAiCompatibleProvider, OpenAiProvider } from "./manicAgent.js";
15
+ import { appendTurn, buildConversation, createThread, getThread, listThreads, recordApply, removeThread, ThreadNotFoundError, } from "./agentThreads.js";
16
+ import { createPromptStore } from "./promptStore.js";
17
+ import { exportProjectSmartDraw, importProjectAsset, importProjectSmartDraw, renameProjectSmartDraw, resolveAsset, searchAssets, trashProjectSmartDraw, } from "./assets.js";
18
+ import { requireSmartDrawInspection, requireSmartDrawSuggestion, runSmartDrawEngine, } from "./smartDraw.js";
19
+ import { createManicFile, duplicateManicFile, listManicFiles, readManicFile, renameManicFile, resolveExistingManicFile, resolveWorkspace, saveManicFile, trashManicFile, WorkspaceConflictError, } from "./workspace.js";
20
+ export function createApp(context) {
21
+ const app = new Hono();
22
+ let workspace = context.workspace;
23
+ const renders = new RenderJobManager(context.engineOverride);
24
+ const agentRuns = new AgentRunManager();
25
+ const aiSecrets = context.aiSecrets ?? createAiSecretStore();
26
+ const promptStore = context.promptStore ?? createPromptStore();
27
+ const candidateFixer = context.candidateAutofix ?? createCandidateFixer(context.clientRoot);
28
+ const engineCheck = context.engineCheck ?? runEngineCheck;
29
+ const smartDrawRunner = context.smartDrawRunner ?? runSmartDrawEngine;
30
+ app.use("*", async (c, next) => {
31
+ await next();
32
+ c.header("X-Content-Type-Options", "nosniff");
33
+ c.header("Referrer-Policy", "no-referrer");
34
+ c.header("X-Frame-Options", "DENY");
35
+ c.header("Content-Security-Policy", "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' blob:; connect-src 'self'; worker-src 'self' blob:; base-uri 'none'; frame-ancestors 'none'; form-action 'self'");
36
+ });
37
+ app.get("/health", (c) => c.json({ status: "ok", service: "manic-workbench" }));
38
+ app.use("/api/*", async (c, next) => {
39
+ const requestOrigin = c.req.header("Origin");
40
+ const listenerOrigin = new URL(c.req.url).origin;
41
+ if (requestOrigin && requestOrigin !== listenerOrigin) {
42
+ return c.json({ error: "The request origin is not allowed." }, 403);
43
+ }
44
+ if (c.req.header("X-Manic-Session") !== context.token) {
45
+ return c.json({ error: "This Workbench session is not authorized." }, 401);
46
+ }
47
+ await next();
48
+ });
49
+ app.get("/api/bootstrap", async (c) => {
50
+ const settings = await context.settingsStore.load();
51
+ const diagnostics = await context.diagnostics(settings);
52
+ return c.json({
53
+ workbench: { version: context.version },
54
+ workspace,
55
+ settings,
56
+ settingsPath: context.settingsStore.path,
57
+ diagnostics,
58
+ ai: aiSecrets.status(),
59
+ });
60
+ });
61
+ app.post("/api/workspace/pick", async (c) => {
62
+ if (!context.pickWorkspace)
63
+ return c.json({ error: "The native folder picker is unavailable." }, 501);
64
+ try {
65
+ const selected = await context.pickWorkspace(workspace);
66
+ if (!selected)
67
+ return c.json({ workspace, cancelled: true });
68
+ workspace = await resolveWorkspace(selected);
69
+ return c.json({ workspace, cancelled: false });
70
+ }
71
+ catch (error) {
72
+ return c.json({ error: error instanceof Error ? error.message : "Project folder could not be opened." }, 400);
73
+ }
74
+ });
75
+ app.put("/api/settings", async (c) => {
76
+ try {
77
+ const body = await c.req.json();
78
+ const settings = await context.settingsStore.save(body);
79
+ const diagnostics = await context.diagnostics(settings);
80
+ return c.json({ settings, diagnostics });
81
+ }
82
+ catch (error) {
83
+ return c.json({ error: error instanceof Error ? error.message : "Invalid settings." }, 400);
84
+ }
85
+ });
86
+ app.get("/api/engine/install", async (c) => {
87
+ try {
88
+ const settings = await context.settingsStore.load();
89
+ return c.json({ plan: await getEngineInstallPlan(settings.updateChannel) });
90
+ }
91
+ catch (error) {
92
+ return c.json({ error: error instanceof Error ? error.message : "Install options are unavailable." }, 400);
93
+ }
94
+ });
95
+ app.post("/api/engine/install", async (c) => {
96
+ try {
97
+ const settings = await context.settingsStore.load();
98
+ const body = await c.req.json();
99
+ const method = body.method === "brew" || body.method === "script" ? body.method : "script";
100
+ const result = await installManicEngine({
101
+ method,
102
+ channel: settings.updateChannel,
103
+ currentEnginePath: settings.enginePath,
104
+ });
105
+ let nextSettings = settings;
106
+ if (result.suggestedEnginePath && !settings.enginePath.trim()) {
107
+ nextSettings = await context.settingsStore.save({ ...settings, enginePath: result.suggestedEnginePath });
108
+ }
109
+ const diagnostics = await context.diagnostics(nextSettings);
110
+ return c.json({
111
+ result: { ...result, ok: result.ok || diagnostics.engine.available },
112
+ settings: nextSettings,
113
+ diagnostics,
114
+ });
115
+ }
116
+ catch (error) {
117
+ return c.json({ error: error instanceof Error ? error.message : "Manic could not be installed." }, 400);
118
+ }
119
+ });
120
+ app.get("/api/ai/status", (c) => c.json({ secrets: aiSecrets.status() }));
121
+ app.put("/api/ai/key", async (c) => {
122
+ try {
123
+ const body = await c.req.json();
124
+ // Backward-compatible: { apiKey } still sets OPENAI_API_KEY.
125
+ const key = typeof body.key === "string" && body.key.trim()
126
+ ? body.key
127
+ : typeof body.apiKey === "string"
128
+ ? "OPENAI_API_KEY"
129
+ : "";
130
+ if (!key)
131
+ throw new Error("key must be a string.");
132
+ const value = typeof body.value === "string"
133
+ ? body.value
134
+ : typeof body.apiKey === "string"
135
+ ? body.apiKey
136
+ : "";
137
+ if (typeof value !== "string")
138
+ throw new Error("value must be a string.");
139
+ if (value.trim())
140
+ aiSecrets.set(key, value);
141
+ else
142
+ aiSecrets.clear(key);
143
+ return c.json({ secrets: aiSecrets.status() });
144
+ }
145
+ catch (error) {
146
+ return c.json({ error: error instanceof Error ? error.message : "API key could not be configured." }, 400);
147
+ }
148
+ });
149
+ app.post("/api/ai/run", async (c) => {
150
+ try {
151
+ const settings = await context.settingsStore.load();
152
+ const body = await c.req.json();
153
+ const effective = applyRunOverride(settings, body);
154
+ if (effective.ai.provider === "none")
155
+ throw new Error("Enable an AI provider in Workbench settings first.");
156
+ const provider = resolveProvider(effective, aiSecrets, context);
157
+ const prompt = await promptStore.get();
158
+ // A thread turn resolves its target and steering context from the
159
+ // thread record; the client supplies only the message and images.
160
+ let input = body;
161
+ let conversation = "";
162
+ const threadId = typeof body.threadId === "string" ? body.threadId : "";
163
+ if (threadId) {
164
+ const thread = await getThread(workspace, threadId);
165
+ const targetPath = thread.target.kind === "file" ? thread.target.path : thread.target.draftName;
166
+ const existing = await readManicFile(workspace, targetPath).catch(() => null);
167
+ conversation = buildConversation(thread, existing?.version ?? null);
168
+ input = existing
169
+ ? { ...body, path: existing.path, newPath: "", intent: body.intent === "diagnose" ? "diagnose" : "refine" }
170
+ : { ...body, path: "", newPath: targetPath, intent: "create" };
171
+ }
172
+ const run = agentRuns.start({
173
+ workspace,
174
+ settings,
175
+ engineOverride: context.engineOverride,
176
+ prompt,
177
+ provider,
178
+ input,
179
+ conversation,
180
+ check: context.engineCheck,
181
+ autofix: (content, signal) => candidateFixer({
182
+ workspace,
183
+ content,
184
+ settings: effective,
185
+ engineOverride: context.engineOverride,
186
+ signal,
187
+ }),
188
+ onFinished: threadId
189
+ ? async (result) => {
190
+ await appendTurn(workspace, threadId, {
191
+ runId: result.id,
192
+ userMessage: typeof body.message === "string" ? body.message : "",
193
+ proposalSummary: result.message,
194
+ status: result.status,
195
+ appliedRevision: null,
196
+ at: Date.now(),
197
+ });
198
+ }
199
+ : undefined,
200
+ });
201
+ return c.json({ run }, 202);
202
+ }
203
+ catch (error) {
204
+ const status = error instanceof ThreadNotFoundError ? 404 : 400;
205
+ return c.json({ error: error instanceof Error ? error.message : "The Manic AI run failed." }, status);
206
+ }
207
+ });
208
+ app.get("/api/ai/threads", async (c) => {
209
+ try {
210
+ return c.json({ threads: await listThreads(workspace) });
211
+ }
212
+ catch (error) {
213
+ return c.json({ error: error instanceof Error ? error.message : "Authorship threads are unavailable." }, 400);
214
+ }
215
+ });
216
+ app.post("/api/ai/threads", async (c) => {
217
+ try {
218
+ const body = await c.req.json();
219
+ let target;
220
+ if (typeof body.path === "string" && body.path) {
221
+ target = { kind: "file", path: (await resolveExistingManicFile(workspace, body.path)).path };
222
+ }
223
+ else if (typeof body.draftName === "string" && body.draftName) {
224
+ target = { kind: "draft", draftName: body.draftName };
225
+ }
226
+ else {
227
+ throw new Error("A thread needs an existing Manic file path or a new draft name.");
228
+ }
229
+ return c.json({ thread: await createThread(workspace, target) }, 201);
230
+ }
231
+ catch (error) {
232
+ return c.json({ error: error instanceof Error ? error.message : "The thread could not be created." }, 400);
233
+ }
234
+ });
235
+ app.get("/api/ai/threads/:id", async (c) => {
236
+ try {
237
+ return c.json({ thread: await getThread(workspace, c.req.param("id")) });
238
+ }
239
+ catch (error) {
240
+ const status = error instanceof ThreadNotFoundError ? 404 : 400;
241
+ return c.json({ error: error instanceof Error ? error.message : "The thread could not be read." }, status);
242
+ }
243
+ });
244
+ app.delete("/api/ai/threads/:id", async (c) => {
245
+ try {
246
+ await removeThread(workspace, c.req.param("id"));
247
+ return c.json({ removed: true });
248
+ }
249
+ catch (error) {
250
+ const status = error instanceof ThreadNotFoundError ? 404 : 400;
251
+ return c.json({ error: error instanceof Error ? error.message : "The thread could not be removed." }, status);
252
+ }
253
+ });
254
+ app.post("/api/ai/threads/:id/apply", async (c) => {
255
+ try {
256
+ const threadId = c.req.param("id");
257
+ const body = await c.req.json();
258
+ if (typeof body.runId !== "string" || !body.runId)
259
+ throw new Error("runId is required.");
260
+ await getThread(workspace, threadId);
261
+ const run = agentRuns.get(body.runId);
262
+ if (!run || run.status !== "ready" || !run.proposal)
263
+ throw new Error("Only a Manic-validated proposal can be applied.");
264
+ const proposal = run.proposal;
265
+ let file;
266
+ if (proposal.operation === "create") {
267
+ file = await createManicFile(workspace, proposal.path, proposal.content);
268
+ }
269
+ else {
270
+ if (!proposal.basedOnRevision)
271
+ throw new Error("The proposal has no source revision.");
272
+ file = await saveManicFile(workspace, proposal.path, proposal.content, proposal.basedOnRevision);
273
+ }
274
+ const thread = await recordApply(workspace, threadId, run.id, file.path, file.version);
275
+ return c.json({ file, thread });
276
+ }
277
+ catch (error) {
278
+ const status = error instanceof ThreadNotFoundError
279
+ ? 404
280
+ : error instanceof WorkspaceConflictError ? 409 : 400;
281
+ return c.json({ error: error instanceof Error ? error.message : "The proposal could not be applied." }, status);
282
+ }
283
+ });
284
+ app.get("/api/ai/run/:id", (c) => {
285
+ const run = agentRuns.get(c.req.param("id"));
286
+ if (!run)
287
+ return c.json({ error: "That AI run was not found." }, 404);
288
+ return c.json({ run });
289
+ });
290
+ app.delete("/api/ai/run/:id", (c) => {
291
+ try {
292
+ return c.json({ run: agentRuns.cancel(c.req.param("id")) });
293
+ }
294
+ catch (error) {
295
+ return c.json({ error: error instanceof Error ? error.message : "The AI run could not be cancelled." }, 404);
296
+ }
297
+ });
298
+ app.get("/api/files", async (c) => {
299
+ try {
300
+ return c.json({ files: await listManicFiles(workspace) });
301
+ }
302
+ catch (error) {
303
+ return c.json({ error: error instanceof Error ? error.message : "Files could not be listed." }, 400);
304
+ }
305
+ });
306
+ app.get("/api/assets", async (c) => {
307
+ try {
308
+ const scope = c.req.query("scope") === "project" ? "project" : "library";
309
+ const kind = parseAssetKind(c.req.query("kind"));
310
+ const settings = await context.settingsStore.load();
311
+ return c.json(await searchAssets(workspace, settings, {
312
+ scope,
313
+ kind,
314
+ query: c.req.query("query") ?? "",
315
+ cursor: c.req.query("cursor") ?? null,
316
+ limit: Number(c.req.query("limit") ?? 48),
317
+ }, context.engineOverride));
318
+ }
319
+ catch (error) {
320
+ return c.json({ error: error instanceof Error ? error.message : "Assets could not be listed." }, 400);
321
+ }
322
+ });
323
+ app.get("/api/assets/resolve", async (c) => {
324
+ try {
325
+ const settings = await context.settingsStore.load();
326
+ const resolved = await resolveAsset(workspace, settings, c.req.query("uri") ?? "", context.engineOverride);
327
+ return c.json({ asset: resolved.asset });
328
+ }
329
+ catch (error) {
330
+ return c.json({ error: error instanceof Error ? error.message : "The asset could not be resolved." }, 404);
331
+ }
332
+ });
333
+ app.get("/api/assets/content", async (c) => {
334
+ try {
335
+ const settings = await context.settingsStore.load();
336
+ const resolved = await resolveAsset(workspace, settings, c.req.query("uri") ?? "", context.engineOverride);
337
+ const size = (await stat(resolved.path)).size;
338
+ const stream = createReadStream(resolved.path);
339
+ return new Response(Readable.toWeb(stream), {
340
+ headers: {
341
+ "Content-Type": resolved.asset.mediaType,
342
+ "Content-Length": String(size),
343
+ "Content-Disposition": "inline",
344
+ "Cache-Control": "private, no-store",
345
+ "X-Content-Type-Options": "nosniff",
346
+ },
347
+ });
348
+ }
349
+ catch (error) {
350
+ return c.json({ error: error instanceof Error ? error.message : "The asset content is unavailable." }, 404);
351
+ }
352
+ });
353
+ app.post("/api/assets/import", async (c) => {
354
+ try {
355
+ const form = await c.req.formData();
356
+ const file = form.get("file");
357
+ if (!(file instanceof File))
358
+ throw new Error("Choose a PNG, JPEG, or SVG file to upload.");
359
+ return c.json({ asset: await importProjectAsset(workspace, file) }, 201);
360
+ }
361
+ catch (error) {
362
+ return c.json({ error: error instanceof Error ? error.message : "The asset could not be imported." }, 400);
363
+ }
364
+ });
365
+ app.post("/api/assets/smartdraw/import", async (c) => {
366
+ try {
367
+ const form = await c.req.formData();
368
+ const source = form.get("source"), guideValue = form.get("guide");
369
+ if (!(source instanceof File))
370
+ throw new Error("Choose SVG artwork, or PNG artwork with an SVG reveal guide.");
371
+ const guide = guideValue instanceof File && guideValue.size > 0 ? guideValue : null;
372
+ const metadata = smartDrawImportMetadata(form);
373
+ const settings = await context.settingsStore.load();
374
+ let inspection = null;
375
+ let prepared = false;
376
+ const asset = await importProjectSmartDraw(workspace, source, guide, async (sourcePath, guidePath) => {
377
+ prepared = true;
378
+ const arguments_ = ["smartdraw", "init", sourcePath];
379
+ if (guidePath)
380
+ arguments_.push("--guide", guidePath);
381
+ await smartDrawRunner(workspace, arguments_, settings, context.engineOverride);
382
+ inspection = requireSmartDrawInspection(await smartDrawRunner(workspace, ["smartdraw", "inspect", sourcePath, "--json"], settings, context.engineOverride));
383
+ }, metadata);
384
+ if (!inspection) {
385
+ const resolved = await resolveProjectSmartDraw(workspace, settings, asset.uri, context.engineOverride);
386
+ inspection = requireSmartDrawInspection(await smartDrawRunner(workspace, ["smartdraw", "inspect", resolved.path, "--json"], settings, context.engineOverride));
387
+ }
388
+ return c.json({ asset, inspection, duplicate: !prepared }, prepared ? 201 : 200);
389
+ }
390
+ catch (error) {
391
+ return c.json({ error: error instanceof Error ? error.message : "The Smart Draw package could not be imported." }, 400);
392
+ }
393
+ });
394
+ app.get("/api/assets/smartdraw/inspect", async (c) => {
395
+ try {
396
+ const settings = await context.settingsStore.load();
397
+ const resolved = await resolveProjectSmartDraw(workspace, settings, c.req.query("uri") ?? "", context.engineOverride);
398
+ return c.json(requireSmartDrawInspection(await smartDrawRunner(workspace, ["smartdraw", "inspect", resolved.path, "--json"], settings, context.engineOverride)));
399
+ }
400
+ catch (error) {
401
+ return c.json({ error: error instanceof Error ? error.message : "The Smart Draw package could not be inspected." }, 400);
402
+ }
403
+ });
404
+ app.post("/api/assets/smartdraw/suggest", async (c) => {
405
+ try {
406
+ const body = await c.req.json();
407
+ if (typeof body.uri !== "string" || typeof body.write !== "boolean")
408
+ throw new Error("uri and write are required.");
409
+ const settings = await context.settingsStore.load();
410
+ const resolved = await resolveProjectSmartDraw(workspace, settings, body.uri, context.engineOverride);
411
+ const arguments_ = ["smartdraw", "suggest", resolved.path, "--json"];
412
+ if (body.write)
413
+ arguments_.push("--write", "--force");
414
+ const suggestion = requireSmartDrawSuggestion(await smartDrawRunner(workspace, arguments_, settings, context.engineOverride));
415
+ if (!body.write)
416
+ return c.json({ suggestion });
417
+ const inspection = requireSmartDrawInspection(await smartDrawRunner(workspace, ["smartdraw", "inspect", resolved.path, "--json"], settings, context.engineOverride));
418
+ return c.json({ suggestion, inspection });
419
+ }
420
+ catch (error) {
421
+ return c.json({ error: error instanceof Error ? error.message : "Smart Draw ordering could not be suggested." }, 400);
422
+ }
423
+ });
424
+ app.post("/api/assets/smartdraw/reverse", async (c) => {
425
+ try {
426
+ const body = await c.req.json();
427
+ if (typeof body.uri !== "string" || !Number.isSafeInteger(body.pathIndex) || Number(body.pathIndex) < 0 || typeof body.reversed !== "boolean") {
428
+ throw new Error("uri, a non-negative pathIndex, and reversed are required.");
429
+ }
430
+ const settings = await context.settingsStore.load();
431
+ const resolved = await resolveProjectSmartDraw(workspace, settings, body.uri, context.engineOverride);
432
+ return c.json(requireSmartDrawInspection(await smartDrawRunner(workspace, [
433
+ "smartdraw", "reverse", resolved.path, String(body.pathIndex), "--set", body.reversed ? "reverse" : "source", "--json",
434
+ ], settings, context.engineOverride)));
435
+ }
436
+ catch (error) {
437
+ return c.json({ error: error instanceof Error ? error.message : "Smart Draw path direction could not be changed." }, 400);
438
+ }
439
+ });
440
+ app.post("/api/assets/smartdraw/save", async (c) => {
441
+ try {
442
+ const body = await c.req.json();
443
+ if (typeof body.uri !== "string" || !isPathIndexList(body.order, false) || !isPathIndexList(body.reverse, true)) {
444
+ throw new Error("uri, a complete order, and a reverse path list are required.");
445
+ }
446
+ const settings = await context.settingsStore.load();
447
+ const resolved = await resolveProjectSmartDraw(workspace, settings, body.uri, context.engineOverride);
448
+ const arguments_ = ["smartdraw", "apply", resolved.path, "--order", body.order.join(",")];
449
+ if (body.reverse.length)
450
+ arguments_.push("--reverse", body.reverse.join(","));
451
+ arguments_.push("--json");
452
+ return c.json(requireSmartDrawInspection(await smartDrawRunner(workspace, arguments_, settings, context.engineOverride)));
453
+ }
454
+ catch (error) {
455
+ return c.json({ error: error instanceof Error ? error.message : "Smart Draw choreography could not be saved." }, 400);
456
+ }
457
+ });
458
+ app.post("/api/assets/smartdraw/rename", async (c) => {
459
+ try {
460
+ const body = await c.req.json();
461
+ if (typeof body.uri !== "string" || typeof body.title !== "string")
462
+ throw new Error("uri and title are required.");
463
+ return c.json({ asset: await renameProjectSmartDraw(workspace, body.uri, body.title) });
464
+ }
465
+ catch (error) {
466
+ return c.json({ error: error instanceof Error ? error.message : "The Smart Draw package could not be renamed." }, 400);
467
+ }
468
+ });
469
+ app.delete("/api/assets/smartdraw", async (c) => {
470
+ try {
471
+ const body = await c.req.json();
472
+ if (typeof body.uri !== "string")
473
+ throw new Error("uri is required.");
474
+ return c.json({ asset: await trashProjectSmartDraw(workspace, body.uri), recoverable: true });
475
+ }
476
+ catch (error) {
477
+ return c.json({ error: error instanceof Error ? error.message : "The Smart Draw package could not be moved to trash." }, 400);
478
+ }
479
+ });
480
+ app.get("/api/assets/smartdraw/export", async (c) => {
481
+ try {
482
+ const exported = await exportProjectSmartDraw(workspace, c.req.query("uri") ?? "");
483
+ return new Response(new Uint8Array(exported.bytes), {
484
+ headers: {
485
+ "Content-Type": exported.mediaType,
486
+ "Content-Length": String(exported.bytes.length),
487
+ "Content-Disposition": `attachment; filename="${exported.filename}"`,
488
+ "Cache-Control": "private, no-store",
489
+ "X-Content-Type-Options": "nosniff",
490
+ },
491
+ });
492
+ }
493
+ catch (error) {
494
+ return c.json({ error: error instanceof Error ? error.message : "The Smart Draw package could not be exported." }, 400);
495
+ }
496
+ });
497
+ app.get("/api/file", async (c) => {
498
+ try {
499
+ return c.json({ file: await readManicFile(workspace, c.req.query("path") ?? "") });
500
+ }
501
+ catch (error) {
502
+ return c.json({ error: error instanceof Error ? error.message : "File could not be read." }, 400);
503
+ }
504
+ });
505
+ app.put("/api/file", async (c) => {
506
+ try {
507
+ const body = await c.req.json();
508
+ if (typeof body.path !== "string" || typeof body.content !== "string" || typeof body.expectedVersion !== "string") {
509
+ throw new Error("path, content, and expectedVersion are required.");
510
+ }
511
+ return c.json({ file: await saveManicFile(workspace, body.path, body.content, body.expectedVersion) });
512
+ }
513
+ catch (error) {
514
+ const status = error instanceof WorkspaceConflictError ? 409 : 400;
515
+ return c.json({ error: error instanceof Error ? error.message : "File could not be saved." }, status);
516
+ }
517
+ });
518
+ app.post("/api/file", async (c) => {
519
+ try {
520
+ const body = await c.req.json();
521
+ if (typeof body.path !== "string" || typeof body.content !== "string")
522
+ throw new Error("path and content are required.");
523
+ return c.json({ file: await createManicFile(workspace, body.path, body.content) }, 201);
524
+ }
525
+ catch (error) {
526
+ const status = error instanceof WorkspaceConflictError ? 409 : 400;
527
+ return c.json({ error: error instanceof Error ? error.message : "File could not be created." }, status);
528
+ }
529
+ });
530
+ app.post("/api/file/rename", async (c) => {
531
+ try {
532
+ const body = await c.req.json();
533
+ if (typeof body.path !== "string" || typeof body.newPath !== "string" || typeof body.expectedVersion !== "string") {
534
+ throw new Error("path, newPath, and expectedVersion are required.");
535
+ }
536
+ return c.json({ file: await renameManicFile(workspace, body.path, body.newPath, body.expectedVersion) });
537
+ }
538
+ catch (error) {
539
+ const status = error instanceof WorkspaceConflictError ? 409 : 400;
540
+ return c.json({ error: error instanceof Error ? error.message : "File could not be renamed." }, status);
541
+ }
542
+ });
543
+ app.post("/api/file/duplicate", async (c) => {
544
+ try {
545
+ const body = await c.req.json();
546
+ if (typeof body.path !== "string" || typeof body.newPath !== "string" || typeof body.expectedVersion !== "string") {
547
+ throw new Error("path, newPath, and expectedVersion are required.");
548
+ }
549
+ if (body.content !== undefined && typeof body.content !== "string")
550
+ throw new Error("content must be text.");
551
+ return c.json({ file: await duplicateManicFile(workspace, body.path, body.newPath, body.expectedVersion, body.content) }, 201);
552
+ }
553
+ catch (error) {
554
+ const status = error instanceof WorkspaceConflictError ? 409 : 400;
555
+ return c.json({ error: error instanceof Error ? error.message : "File could not be duplicated." }, status);
556
+ }
557
+ });
558
+ app.delete("/api/file", async (c) => {
559
+ try {
560
+ const body = await c.req.json();
561
+ if (typeof body.path !== "string" || typeof body.expectedVersion !== "string")
562
+ throw new Error("path and expectedVersion are required.");
563
+ return c.json(await trashManicFile(workspace, body.path, body.expectedVersion));
564
+ }
565
+ catch (error) {
566
+ const status = error instanceof WorkspaceConflictError ? 409 : 400;
567
+ return c.json({ error: error instanceof Error ? error.message : "File could not be moved to trash." }, status);
568
+ }
569
+ });
570
+ app.post("/api/preview", async (c) => {
571
+ try {
572
+ const body = await c.req.json();
573
+ if (typeof body.path !== "string")
574
+ throw new Error("path is required.");
575
+ const file = await resolveExistingManicFile(workspace, body.path);
576
+ const settings = await context.settingsStore.load();
577
+ const check = await engineCheck(workspace, file.absolute, settings, context.engineOverride);
578
+ if (!check.ok)
579
+ return c.json({ started: false, path: file.path, check });
580
+ if (context.launchPreview)
581
+ await context.launchPreview(workspace, file.absolute, settings);
582
+ else
583
+ await renders.launchPreview(workspace, file.absolute, settings);
584
+ return c.json({ started: true, path: file.path, check });
585
+ }
586
+ catch (error) {
587
+ return c.json({ error: error instanceof Error ? error.message : "Preview could not be started." }, 400);
588
+ }
589
+ });
590
+ app.post("/api/check", async (c) => {
591
+ try {
592
+ const body = await c.req.json();
593
+ if (typeof body.path !== "string")
594
+ throw new Error("path is required.");
595
+ const file = await resolveExistingManicFile(workspace, body.path);
596
+ const settings = await context.settingsStore.load();
597
+ return c.json(await engineCheck(workspace, file.absolute, settings, context.engineOverride));
598
+ }
599
+ catch (error) {
600
+ return c.json({ error: error instanceof Error ? error.message : "Manic check could not be run." }, 400);
601
+ }
602
+ });
603
+ app.post("/api/render", async (c) => {
604
+ try {
605
+ const body = await c.req.json();
606
+ if (typeof body.path !== "string")
607
+ throw new Error("path is required.");
608
+ const file = await resolveExistingManicFile(workspace, body.path);
609
+ const settings = await context.settingsStore.load();
610
+ return c.json({ job: await renders.start(workspace, file.absolute, file.path, settings, body.options) }, 202);
611
+ }
612
+ catch (error) {
613
+ return c.json({ error: error instanceof Error ? error.message : "Render could not be started." }, 400);
614
+ }
615
+ });
616
+ app.get("/api/renders", async (c) => {
617
+ try {
618
+ return c.json({ jobs: await renders.history(workspace) });
619
+ }
620
+ catch (error) {
621
+ return c.json({ error: error instanceof Error ? error.message : "Render history is unavailable." }, 400);
622
+ }
623
+ });
624
+ app.get("/api/render/:id", async (c) => {
625
+ try {
626
+ return c.json({ job: await renders.get(workspace, c.req.param("id")) });
627
+ }
628
+ catch (error) {
629
+ return c.json({ error: error instanceof Error ? error.message : "Render was not found." }, 404);
630
+ }
631
+ });
632
+ app.delete("/api/render/:id", async (c) => {
633
+ try {
634
+ return c.json({ job: await renders.cancel(workspace, c.req.param("id")) });
635
+ }
636
+ catch (error) {
637
+ return c.json({ error: error instanceof Error ? error.message : "Render was not found." }, 404);
638
+ }
639
+ });
640
+ app.get("/api/render/:id/output", async (c) => {
641
+ try {
642
+ const output = await renders.output(workspace, c.req.param("id"));
643
+ const mime = output.format === "mp4" ? "video/mp4" : output.format === "gif" ? "image/gif" : "image/png";
644
+ const size = (await stat(output.path)).size;
645
+ const range = parseByteRange(c.req.header("Range"), size);
646
+ const stream = createReadStream(output.path, range ? { start: range.start, end: range.end } : undefined);
647
+ const headers = {
648
+ "Content-Type": mime, "Content-Disposition": `inline; filename=\"${output.name}\"`,
649
+ "Cache-Control": "no-store", "Accept-Ranges": "bytes",
650
+ "Content-Length": String(range ? range.end - range.start + 1 : size),
651
+ };
652
+ if (range)
653
+ headers["Content-Range"] = `bytes ${range.start}-${range.end}/${size}`;
654
+ return new Response(Readable.toWeb(stream), { status: range ? 206 : 200, headers });
655
+ }
656
+ catch (error) {
657
+ return c.json({ error: error instanceof Error ? error.message : "Render output is unavailable." }, 404);
658
+ }
659
+ });
660
+ app.get("*", async (c) => {
661
+ const requested = c.req.path === "/" ? "index.html" : c.req.path.slice(1);
662
+ const absolute = resolve(context.clientRoot, requested);
663
+ const local = relative(context.clientRoot, absolute);
664
+ if (local.startsWith("..") || local.includes("\0"))
665
+ return c.notFound();
666
+ try {
667
+ const body = await readFile(absolute);
668
+ return new Response(body, {
669
+ headers: { "Content-Type": contentType(absolute) },
670
+ });
671
+ }
672
+ catch {
673
+ if (extname(requested))
674
+ return c.notFound();
675
+ try {
676
+ const body = await readFile(resolve(context.clientRoot, "index.html"));
677
+ return new Response(body, { headers: { "Content-Type": "text/html; charset=utf-8" } });
678
+ }
679
+ catch {
680
+ return c.notFound();
681
+ }
682
+ }
683
+ });
684
+ app.onError((error, c) => {
685
+ console.error("Workbench request failed:", error);
686
+ return c.json({ error: "Workbench could not complete the request." }, 500);
687
+ });
688
+ return app;
689
+ }
690
+ async function resolveProjectSmartDraw(workspace, settings, uri, engineOverride = "") {
691
+ const resolved = await resolveAsset(workspace, settings, uri, engineOverride);
692
+ if (resolved.asset.scope !== "project" || resolved.asset.kind !== "smartdraw") {
693
+ throw new Error("Choose a project Smart Draw package.");
694
+ }
695
+ return resolved;
696
+ }
697
+ function smartDrawImportMetadata(form) {
698
+ const title = formText(form, "title"), author = formText(form, "author"), sourceUrl = formText(form, "sourceUrl");
699
+ const licenseId = formText(form, "licenseId"), licenseName = formText(form, "licenseName");
700
+ const licenseUrl = formText(form, "licenseUrl"), attribution = formText(form, "attribution");
701
+ const hasLicense = Boolean(licenseId || licenseName || licenseUrl || attribution || form.get("attributionRequired") === "true");
702
+ return {
703
+ ...(title ? { title } : {}),
704
+ ...(author ? { author } : {}),
705
+ ...(sourceUrl ? { sourceUrl } : {}),
706
+ ...(hasLicense ? { license: {
707
+ id: licenseId,
708
+ name: licenseName,
709
+ attributionRequired: form.get("attributionRequired") === "true",
710
+ ...(attribution ? { attribution } : {}),
711
+ ...(licenseUrl ? { url: licenseUrl } : {}),
712
+ } } : {}),
713
+ };
714
+ }
715
+ function formText(form, key) {
716
+ const value = form.get(key);
717
+ return typeof value === "string" ? value.trim() : "";
718
+ }
719
+ export function parseAssetKind(value) {
720
+ return value === "image" || value === "svg" || value === "smartdraw" || value === "model" ? value : "all";
721
+ }
722
+ function isPathIndexList(value, allowEmpty) {
723
+ return Array.isArray(value) && value.length <= 40_000 && (allowEmpty || value.length > 0)
724
+ && value.every((index) => Number.isSafeInteger(index) && index >= 0);
725
+ }
726
+ function applyRunOverride(settings, body) {
727
+ const provider = body.provider;
728
+ const model = body.model;
729
+ const reasoning = body.reasoning;
730
+ const baseUrl = body.baseUrl;
731
+ if (provider === undefined && model === undefined && reasoning === undefined && baseUrl === undefined)
732
+ return settings;
733
+ if (provider !== undefined && provider !== "openai" && provider !== "anthropic") {
734
+ throw new Error("The run provider must be openai or anthropic.");
735
+ }
736
+ if (model !== undefined && (typeof model !== "string" || !model || model.length > 128 || !/^[A-Za-z0-9._:/-]+$/u.test(model))) {
737
+ throw new Error("Model ids may only use letters, numbers, and . _ : / -");
738
+ }
739
+ if (reasoning !== undefined && !["none", "low", "medium", "high", "xhigh"].includes(reasoning)) {
740
+ throw new Error("Reasoning must be none, low, medium, high, or xhigh.");
741
+ }
742
+ return {
743
+ ...settings,
744
+ ai: {
745
+ ...settings.ai,
746
+ provider: provider ?? settings.ai.provider,
747
+ model: model ?? settings.ai.model,
748
+ reasoning: reasoning ?? settings.ai.reasoning,
749
+ // Explicit "" switches back to the official API; undefined keeps settings.
750
+ baseUrl: baseUrl === undefined ? settings.ai.baseUrl : normalizeAiBaseUrl(baseUrl),
751
+ },
752
+ };
753
+ }
754
+ function resolveProvider(settings, aiSecrets, context) {
755
+ if (settings.ai.provider === "openai") {
756
+ const apiKey = aiSecrets.openAiKey();
757
+ // A custom base URL targets an OpenAI-compatible server (Ollama, LM Studio,
758
+ // vLLM, …) over Chat Completions; local endpoints don't require a key.
759
+ if (settings.ai.baseUrl) {
760
+ return context.openAiCompatibleProvider?.(settings.ai.baseUrl, apiKey, settings.ai.model)
761
+ ?? new OpenAiCompatibleProvider(settings.ai.baseUrl, apiKey, settings.ai.model);
762
+ }
763
+ if (!apiKey) {
764
+ throw new Error("Configure OPENAI_API_KEY in Workbench settings, or set a Base URL for a local"
765
+ + " OpenAI-compatible server (e.g. http://127.0.0.1:11434/v1 for Ollama) — no key needed there.");
766
+ }
767
+ return context.openAiProvider?.(apiKey, settings.ai.model, settings.ai.reasoning)
768
+ ?? new OpenAiProvider(apiKey, settings.ai.model, settings.ai.reasoning);
769
+ }
770
+ if (settings.ai.provider === "anthropic") {
771
+ const apiKey = aiSecrets.anthropicKey();
772
+ if (!apiKey)
773
+ throw new Error("Configure ANTHROPIC_API_KEY in Workbench settings or the process environment.");
774
+ return context.anthropicProvider?.(apiKey, settings.ai.model, settings.ai.reasoning)
775
+ ?? new AnthropicProvider(apiKey, settings.ai.model, settings.ai.reasoning);
776
+ }
777
+ throw new Error("Enable an AI provider in Workbench settings first.");
778
+ }
779
+ function parseByteRange(value, size) {
780
+ if (!value)
781
+ return null;
782
+ const match = /^bytes=(\d+)-(\d*)$/u.exec(value.trim());
783
+ if (!match)
784
+ return null;
785
+ const start = Number(match[1]);
786
+ const requestedEnd = match[2] ? Number(match[2]) : size - 1;
787
+ if (!Number.isSafeInteger(start) || !Number.isSafeInteger(requestedEnd) || start < 0 || start >= size || requestedEnd < start)
788
+ return null;
789
+ return { start, end: Math.min(requestedEnd, size - 1) };
790
+ }
791
+ function contentType(path) {
792
+ switch (extname(path)) {
793
+ case ".html": return "text/html; charset=utf-8";
794
+ case ".js": return "text/javascript; charset=utf-8";
795
+ case ".css": return "text/css; charset=utf-8";
796
+ case ".svg": return "image/svg+xml";
797
+ case ".png": return "image/png";
798
+ case ".obj": return "model/obj";
799
+ case ".woff2": return "font/woff2";
800
+ case ".wasm": return "application/wasm";
801
+ default: return "application/octet-stream";
802
+ }
803
+ }
804
+ //# sourceMappingURL=app.js.map