@field/cascade 0.11.0 → 0.13.0

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 (220) hide show
  1. package/AGENTS.md +8 -5
  2. package/ARCHITECTURE.md +5 -4
  3. package/CHANGELOG.md +245 -0
  4. package/README.md +1 -1
  5. package/dist/assets/AgentPanel-1JugFjE4.css +1 -0
  6. package/dist/assets/AgentPanel-BDL5MddA.js +5 -0
  7. package/dist/assets/{CodeEditor-4O7FQ__R.js → CodeEditor-C-xYG-Wn.js} +120 -120
  8. package/dist/assets/CodePanel-CtXd50m6.js +2 -0
  9. package/dist/assets/CookInfoPanel-B3NMhKJF.css +1 -0
  10. package/dist/assets/CookInfoPanel-DG4_TRsX.js +2 -0
  11. package/dist/assets/CustomNodeDialog-CHfZUs-r.js +1 -0
  12. package/dist/assets/DefinitionNode-CaRTXQ_b.js +1 -0
  13. package/dist/assets/DefinitionPanel-C3CxZY9r.js +1 -0
  14. package/dist/assets/DefinitionPanel-VNLnAiQD.css +1 -0
  15. package/dist/assets/OpenGraphDialog-BLdr6k_q.js +1 -0
  16. package/dist/assets/ProjectSettings-ZnvmIAir.js +2 -0
  17. package/dist/assets/{SettingsDialog-Bz8JxISH.js → SettingsDialog-CBX3Wa87.js} +1 -1
  18. package/dist/assets/TimelinePanel-CDeR0arY.css +1 -0
  19. package/dist/assets/TimelinePanel-CWgnFH1e.js +1 -0
  20. package/dist/assets/{VersionHistoryDialog-D5Z0nJ5-.js → VersionHistoryDialog-BOSoW1R-.js} +1 -1
  21. package/dist/assets/assert-BO2_erPD.js +1 -0
  22. package/dist/assets/assert-hvykGCnP.js +1 -0
  23. package/dist/assets/builder-BmBKcDix.js +1 -0
  24. package/dist/assets/camera-DFF7YA3F.js +1 -0
  25. package/dist/assets/checks-DAvyO9Gf.js +1 -0
  26. package/dist/assets/contactSheet-N1NcaWxw.js +2 -0
  27. package/dist/assets/{core-Yqi0Ni61.js → core-DB-MkGjj.js} +3 -4
  28. package/dist/assets/coreTypes-DtnDATZ7.js +1 -0
  29. package/dist/assets/{cssMode-CxUzc4vp.js → cssMode-DPVckSOc.js} +1 -1
  30. package/dist/assets/definitions-B227e7f_.js +1 -0
  31. package/dist/assets/definitions-D0WOUJd7.js +1 -0
  32. package/dist/assets/{editor.api-BNFb25CX.js → editor.api-Dkutg_Z1.js} +1 -1
  33. package/dist/assets/expressions-X-Z-GrgW.js +5 -0
  34. package/dist/assets/file-DAL6IfjV.js +1 -0
  35. package/dist/assets/filters-D3k1LRMa.js +1 -0
  36. package/dist/assets/{freemarker2-0ZDnWxeM.js → freemarker2-CLiLKk3B.js} +1 -1
  37. package/dist/assets/generators-BhDxRAFC.js +1 -0
  38. package/dist/assets/geo-BsMImJIJ.js +1 -0
  39. package/dist/assets/geo-C4YngDob.js +2 -0
  40. package/dist/assets/{handlebars-Cy18MoaD.js → handlebars-CcD3aMeL.js} +1 -1
  41. package/dist/assets/{html-B-2Dx7nq.js → html-DvZWGfqb.js} +1 -1
  42. package/dist/assets/{htmlMode-DUAc9B_d.js → htmlMode-DUD3VaoN.js} +1 -1
  43. package/dist/assets/image-0SfH-snh.js +1 -0
  44. package/dist/assets/image-Ck-RdGU4.js +2 -0
  45. package/dist/assets/index-BWnrmIB9.js +137 -0
  46. package/dist/assets/index-DIaxEONI.css +1 -0
  47. package/dist/assets/io-BGmt2g0D.js +1 -0
  48. package/dist/assets/{javascript-DeQsDqP5.js → javascript-Cap2ahgh.js} +1 -1
  49. package/dist/assets/{jsonMode-BiFwJVSk.js → jsonMode-B0uLjp9C.js} +1 -1
  50. package/dist/assets/{liquid-BLoHH68a.js → liquid-CnxwhfLn.js} +1 -1
  51. package/dist/assets/{lspLanguageFeatures-CNFgm1Kv.js → lspLanguageFeatures-Dn9hlKX6.js} +1 -1
  52. package/dist/assets/math-GeULS-sk.js +1 -0
  53. package/dist/assets/{mdx-CFXQVNfs.js → mdx-BV3jbrVa.js} +1 -1
  54. package/dist/assets/pop-KMF_qloi.js +1 -0
  55. package/dist/assets/preload-helper-Czpn1I53.js +1 -0
  56. package/dist/assets/{python-Cf7S7p2E.js → python-CGyFk4XK.js} +1 -1
  57. package/dist/assets/{razor-CMHBcG-g.js → razor-CQfzX3-N.js} +1 -1
  58. package/dist/assets/remap-5SjXQU-q.js +1 -0
  59. package/dist/assets/renderMarkdown-ork0Oir7.js +67 -0
  60. package/dist/assets/studioImages-CAyH-0Pl.js +1 -0
  61. package/dist/assets/text-ZpX7qNkx.js +2 -0
  62. package/dist/assets/time-P_OiBhcf.js +1 -0
  63. package/dist/assets/{tsMode-BEih0GDj.js → tsMode-BOeXzO9H.js} +1 -1
  64. package/dist/assets/{typescript-COEKYD_a.js → typescript-J1SnE_Tu.js} +1 -1
  65. package/dist/assets/{workers-BNhAhMNn.js → workers-CYwwTiVF.js} +1 -1
  66. package/dist/assets/{xml-CPiMpnPl.js → xml-DnPRNzK9.js} +1 -1
  67. package/dist/assets/{yaml-Bgp1ITLR.js → yaml-BmmYBNa9.js} +1 -1
  68. package/dist/cli/DefinitionNode-P7AA4TAU.js +15 -0
  69. package/dist/cli/{Graph-ZJJTRQTM.js → Graph-OB6EWSGL.js} +12 -12
  70. package/dist/cli/assert-GROGQNCQ.js +25 -0
  71. package/dist/cli/checks-3WB44XBL.js +189 -0
  72. package/dist/cli/{chunk-3JTJHF7V.js → chunk-2L34ERS2.js} +4 -4
  73. package/dist/cli/chunk-53LGFPWX.js +138 -0
  74. package/dist/cli/chunk-5ORUQ6ES.js +267 -0
  75. package/dist/cli/{chunk-YAT5Y25U.js → chunk-7QE2ZNSN.js} +3 -3
  76. package/dist/cli/{chunk-SGJAET2L.js → chunk-BPODRH52.js} +8 -4
  77. package/dist/cli/{chunk-XWDSKG7N.js → chunk-BZ63XQ3I.js} +2 -2
  78. package/dist/cli/{chunk-FCDXJ6EK.js → chunk-CTPLRSWF.js} +2 -13
  79. package/dist/cli/{chunk-WIH4TEIS.js → chunk-EZRWJ4G2.js} +1 -1
  80. package/dist/cli/{chunk-BIJO5OFS.js → chunk-FWMSGKEH.js} +1 -1
  81. package/dist/cli/{chunk-POMMNKZZ.js → chunk-G23A2BZZ.js} +38 -5
  82. package/dist/cli/{chunk-35D343DC.js → chunk-GRIN2DDP.js} +19 -1
  83. package/dist/cli/{chunk-WKURDVYP.js → chunk-JEW5MPGI.js} +28 -331
  84. package/dist/cli/chunk-JVOCK5W4.js +83 -0
  85. package/dist/cli/chunk-KBGUO27Q.js +15 -0
  86. package/dist/cli/{chunk-GFS6W3C5.js → chunk-L6B6FUQP.js} +54 -32
  87. package/dist/cli/chunk-LTXWBXOM.js +438 -0
  88. package/dist/cli/chunk-MI5JLQYA.js +220 -0
  89. package/dist/cli/{chunk-A4OAMOZH.js → chunk-NJFMDXHR.js} +13 -3
  90. package/dist/cli/{chunk-DUIUFVU2.js → chunk-OBZAP3GG.js} +49 -23
  91. package/dist/cli/chunk-QAGATJGE.js +336 -0
  92. package/dist/cli/{chunk-EUIAC3U3.js → chunk-QKL7CCRS.js} +966 -132
  93. package/dist/cli/{chunk-RLCAJBVR.js → chunk-TJW67QSI.js} +8 -7
  94. package/dist/cli/{chunk-RQZ4SX5R.js → chunk-W5PJ5RMP.js} +156 -84
  95. package/dist/cli/chunk-W7OUAT7J.js +122 -0
  96. package/dist/cli/chunk-WGKPJZDY.js +364 -0
  97. package/dist/cli/{chunk-D6BUOHUG.js → chunk-X4WKAOQP.js} +4 -4
  98. package/dist/cli/{chunk-VVGSLVSF.js → chunk-X566FWBV.js} +6 -1
  99. package/dist/cli/chunk-YH637PDL.js +317 -0
  100. package/dist/cli/chunk-ZSCUZE6I.js +112 -0
  101. package/dist/cli/{cliCommands-UQSFGEHF.js → cliCommands-XVFRD7CF.js} +23 -17
  102. package/dist/cli/{commands-Q23M26QM.js → commands-M2XLTPTZ.js} +129 -47
  103. package/dist/cli/contactSheet-2PQVRUFW.js +11 -0
  104. package/dist/cli/{definitions-HF2FTHYU.js → definitions-BPOPW52L.js} +7 -7
  105. package/dist/cli/{doctorCommand-B7BPQMN6.js → doctorCommand-RAEI7GVY.js} +36 -6
  106. package/dist/cli/{edit-JHCPTQFT.js → edit-S5KEQ5RA.js} +3 -3
  107. package/dist/cli/editorCommands-5BBG4S6V.js +41 -0
  108. package/dist/cli/{encode-HAUZTYPT.js → encode-ICPEPMH5.js} +2 -2
  109. package/dist/cli/file-3HTQHPYQ.js +41 -0
  110. package/dist/cli/filters-6ODFWYK4.js +379 -0
  111. package/dist/cli/generators-YU7GB4MD.js +210 -0
  112. package/dist/cli/{geo-4RNK3QVN.js → geo-6ZPGKZRU.js} +7 -7
  113. package/dist/cli/{graphCommands-6BMAKGQE.js → graphCommands-MULQ7VD2.js} +4 -4
  114. package/dist/cli/{graphFile-VPSQ6OF7.js → graphFile-CITF36ZM.js} +25 -19
  115. package/dist/cli/{headlessCanvas-5XLDZT7M.js → headlessCanvas-ENRHC7GS.js} +3 -2
  116. package/dist/cli/{helpCommand-3VRE3KVO.js → helpCommand-X2QDANM3.js} +9 -7
  117. package/dist/cli/image-TXELZZK5.js +55 -0
  118. package/dist/cli/index.js +14 -14
  119. package/dist/cli/{math-ZRMLKU2D.js → math-RSYRQ3C6.js} +5 -5
  120. package/dist/cli/{mcp-ZLEEMYGF.js → mcp-YRIGRLYQ.js} +4 -4
  121. package/dist/cli/{parity-KINARCP2.js → parity-3N3HTKWX.js} +42 -36
  122. package/dist/cli/{pop-USDFXB7H.js → pop-B7SIIYKN.js} +5 -5
  123. package/dist/cli/project-SJF5ZF3F.js +12 -0
  124. package/dist/cli/{projectDefinition-DMTZN2NE.js → projectDefinition-F3D7UIHJ.js} +8 -8
  125. package/dist/cli/{projectRuntime-Z5PJOH47.js → projectRuntime-NY4XMDFH.js} +19 -12
  126. package/dist/cli/registerStandardNodes-BXJCB6E4.js +744 -0
  127. package/dist/cli/{render-YURAPPUI.js → render-Y23W6MY6.js} +29 -22
  128. package/dist/cli/{runCommand-PI764LEG.js → runCommand-XOG7AVC5.js} +3 -3
  129. package/dist/cli/runner-DNJO5WO2.js +43 -0
  130. package/dist/cli/runtime/image.ts +27 -2
  131. package/dist/cli/runtime/io.ts +78 -0
  132. package/dist/cli/share-B7HTCOJX.js +166 -0
  133. package/dist/cli/stageCache-TY2BFZJR.js +15 -0
  134. package/dist/cli/{stageRunner-KUNIMQKJ.js → stageRunner-KY2EJP7X.js} +2 -2
  135. package/dist/cli/text-MB3EKR4H.js +126 -0
  136. package/dist/cli/{verbs-RCE3K4VQ.js → verbs-PI2JH5FI.js} +2 -2
  137. package/dist/cli/webBuild-2K4COCGY.js +44 -0
  138. package/dist/contracts/capabilities.d.ts +39 -1
  139. package/dist/contracts/color.d.ts +8 -0
  140. package/dist/contracts/color.js +23 -0
  141. package/dist/contracts/definition.d.ts +10 -0
  142. package/dist/contracts/schema.d.ts +1 -1
  143. package/dist/contracts/schema.js +1 -0
  144. package/dist/contracts/validate.js +11 -1
  145. package/dist/contracts/values.d.ts +24 -0
  146. package/dist/image.d.ts +15 -0
  147. package/dist/image.js +36 -2
  148. package/dist/index.html +8 -2
  149. package/dist/io.d.ts +29 -0
  150. package/dist/io.js +40 -0
  151. package/dist/player/app.js +11 -7
  152. package/dist/player/editor.js +3 -2
  153. package/dist/player/editorEngine.js +3 -2
  154. package/dist/player/embed.js +2 -0
  155. package/dist/player/types.d.ts +6 -0
  156. package/dist/runtime/builtins/assert/checks.d.ts +18 -0
  157. package/dist/runtime/builtins/assert/checks.js +207 -0
  158. package/dist/runtime/builtins/assert/definitions.d.ts +130 -0
  159. package/dist/runtime/builtins/assert/definitions.js +54 -0
  160. package/dist/runtime/builtins/assert/index.d.ts +152 -0
  161. package/dist/runtime/builtins/assert/index.js +36 -0
  162. package/dist/runtime/builtins/image/contactSheet.d.ts +3 -165
  163. package/dist/runtime/builtins/image/contactSheet.js +0 -49
  164. package/dist/runtime/builtins/image/definitions.d.ts +950 -0
  165. package/dist/runtime/builtins/image/definitions.js +343 -0
  166. package/dist/runtime/builtins/image/file.d.ts +8 -0
  167. package/dist/runtime/builtins/image/file.js +37 -0
  168. package/dist/runtime/builtins/image/filters.d.ts +8 -0
  169. package/dist/runtime/builtins/image/filters.js +394 -0
  170. package/dist/runtime/builtins/image/generators.d.ts +7 -0
  171. package/dist/runtime/builtins/image/generators.js +144 -0
  172. package/dist/runtime/builtins/image/index.d.ts +947 -4
  173. package/dist/runtime/builtins/image/index.js +41 -6
  174. package/dist/runtime/builtins/image/io.d.ts +100 -0
  175. package/dist/runtime/builtins/image/io.js +142 -0
  176. package/dist/runtime/builtins/image/planar.d.ts +55 -0
  177. package/dist/runtime/builtins/image/planar.js +274 -0
  178. package/dist/runtime/builtins/image/simplex.d.ts +22 -0
  179. package/dist/runtime/builtins/image/simplex.js +92 -0
  180. package/dist/runtime/builtins/image/text.d.ts +4 -0
  181. package/dist/runtime/builtins/image/text.js +141 -0
  182. package/dist/runtime/builtins/index.d.ts +3 -0
  183. package/dist/runtime/builtins/index.js +7 -0
  184. package/dist/runtime/definition/architecture.js +89 -0
  185. package/dist/runtime/gpu.d.ts +25 -0
  186. package/dist/runtime/gpu.js +40 -0
  187. package/dist/runtime/runtime.d.ts +2 -0
  188. package/dist/runtime/runtime.js +268 -44
  189. package/dist/runtime/types.d.ts +30 -0
  190. package/doc/CLI_REFERENCE.md +21 -3
  191. package/doc/EDITOR_EXPORT.md +26 -0
  192. package/doc/MCP.md +2 -1
  193. package/doc/NODE_REFERENCE.md +286 -14
  194. package/doc/PROJECT_AUTHORING.md +158 -4
  195. package/doc/WEB_PLAYER.md +9 -1
  196. package/package.json +4 -1
  197. package/dist/assets/CodePanel-BU-autmq.js +0 -2
  198. package/dist/assets/CustomNodeDialog-BRpDfOV5.js +0 -1
  199. package/dist/assets/OpenGraphDialog-BwbRlC0X.js +0 -1
  200. package/dist/assets/ProjectSettings-DLOXLxcA.js +0 -2
  201. package/dist/assets/definitions-GreEMXLV.js +0 -1
  202. package/dist/assets/geo-u0n_jOsD.js +0 -1
  203. package/dist/assets/image-cAa-Nu9O.js +0 -2062
  204. package/dist/assets/index-5ZtDAuy2.js +0 -220
  205. package/dist/assets/index-7vae6YFC.css +0 -1
  206. package/dist/assets/math-DioIQOPJ.js +0 -1
  207. package/dist/assets/pop-DC_TQG9t.js +0 -1
  208. package/dist/cli/chunk-36P5K3SD.js +0 -631
  209. package/dist/cli/chunk-4UDFYF5G.js +0 -132
  210. package/dist/cli/chunk-53NMBJAO.js +0 -35
  211. package/dist/cli/chunk-MIIEFUGG.js +0 -623
  212. package/dist/cli/chunk-QBBKRNGY.js +0 -90
  213. package/dist/cli/chunk-WPUDGEFY.js +0 -20
  214. package/dist/cli/editorCommands-UIF5YLUZ.js +0 -33
  215. package/dist/cli/project-K3QIPGBB.js +0 -12
  216. package/dist/cli/registerStandardNodes-S2VLMF6J.js +0 -3081
  217. package/dist/cli/runner-RA6UKEPD.js +0 -37
  218. package/dist/cli/webBuild-GT4PZT5D.js +0 -37
  219. package/dist/runtime/builtins/headless.d.ts +0 -19
  220. package/dist/runtime/builtins/headless.js +0 -25
package/AGENTS.md CHANGED
@@ -39,7 +39,7 @@ Use `cascade new <name>` to create a project and `cascade node <Name>` to scaffo
39
39
 
40
40
  Never hand-edit a `.cascade` file. Change graphs with `cascade node add|rm`, `connect`, `disconnect`, `set` and `subnet create|move|dissolve` (or `cascade edit` for a batch); they check the edit like `cascade check`, keep the diff minimal and lay new nodes out. Every command takes `--json`, and `cascade mcp` serves the same operations as MCP tools. Read `doc/CLI_REFERENCE.md` and `doc/MCP.md`.
41
41
 
42
- For agents working headlessly: `cascade help node <type>` prints a node's ports and description from the installed package; `cascade run <graph> --out <dir> [--out-node <id>]` saves image outputs as `<node>[.<port>].<ext>` (and `run --json` lists them in `data.images`); `cascade.assert.*` nodes fail a run with a readable message; what nodes and stages print is in the run trace under `.cascade/runs/`; `--env NAME=value` replaces a shell prefix; `cascade doctor --fix` builds the Python environment a project declares in `cascade.json` `python`; every MCP tool takes `project` to work in another directory.
42
+ For agents working headlessly: `cascade help node <type>` prints a node's ports and description from the installed package; `cascade run <graph> --out <dir> [--out-node <id>]` saves image outputs as `<node>[.<port>].<ext>` (and `run --json` lists them in `data.images`); `cascade.assert.*` nodes fail a run with a readable message; what nodes and stages print is in the run trace under `.cascade/runs/`; `--env NAME=value` replaces a shell prefix; `cascade doctor --fix` builds the Python environment a project declares in `cascade.json` `python`; every MCP tool takes `project` to work in another directory. To have Marcus choose a variant on his phone: `cascade ladder <graph> <node> --name <name> --seeds a,b,c --cairn <Substrate vault>/<space>/_attachments/ladders/<id> --json`, post `data.cairnChoice` (a `cairn:choice` fence, at most 8 pictures) in the Cairn chat as is, and when "Picked: <label> (pick:<id>:<n>)" comes back run `cascade pick <id> <n> --project <project>` and reply with that locked image (`doc/CLI_REFERENCE.md`, "Picking a ladder variant in Cairn").
43
43
 
44
44
  `cascade build <graph.cascade> --out <new-directory>` exports a static browser
45
45
  player. Use repeatable `--asset <project-relative-file>` for inputs whose paths
@@ -138,7 +138,7 @@ Definition rules:
138
138
  - Vector props support `min`, `max`, and `step`, shared across components. Props may declare a default `expression`; an explicitly saved value overrides that default, including when it equals the numeric default.
139
139
  - WebGPU nodes declare `gpu` and use its shared device and per-node `cache`. Portable GPU nodes can run through optional Dawn in the CLI; browser-only declarations remain refused. Import constants and explicit `readTexture` (RGBA8 only) from `cascade/gpu`. Graph texture exchange remains future work. See `doc/HEADLESS_GPU.md` for bounded agent renders, diagnostics and hardware tests.
140
140
  - Treat graph wires as the primary data boundary. A node may observe only its connected inputs, its props, and declared host capabilities; it must not inspect sibling nodes or the graph to discover data.
141
- - Deterministic node modules may not retain module-level mutable values, access ambient state such as `globalThis`, browser storage, or `process`, run top-level effects, or import sibling node implementations. `cascade check` reports these as `architecture/*` diagnostics.
141
+ - Deterministic node modules may not retain module-level mutable values, access ambient state such as `globalThis`, browser storage, or `process`, run top-level effects, or import sibling node implementations. `cascade check` reports these as `architecture/*` diagnostics. Pure module-level helpers are allowed: function declarations, and `const` values that cannot change (literals and arithmetic, `Math.PI`, arrow functions, arrays and objects under `as const` or `Object.freeze`). `let`, `new Map()`, a bare `[]`/`{}`, a regex or any other call is module state.
142
142
  - A cache may memoize computation from wired inputs, but it must never supply unwired data. Make cache use an explicitly labelled prop and keep cache keys derived from the complete wired input and relevant props.
143
143
  - Keep model/provider integrations in the project. Cascade core has no Google,
144
144
  Anthropic, OpenAI, or generic `ai` capability. Use normal typed outputs such
@@ -225,13 +225,16 @@ type system knows what a `vec2` is; nothing tells it that `offset_x` and
225
225
 
226
226
  ## Change workflow
227
227
 
228
- Use Node.js 22.13 or newer. Cascade compiles with TypeScript 6; do not move to
229
- the TypeScript 7 preview until it is stable and the repository gates pass.
228
+ Use Node.js 22.13 or newer. Cascade compiles with TypeScript 6 (the
229
+ `typescript` dependency: the CLI and server use its JS API, and svelte-check
230
+ runs on it). The plain-tsc gates in `scripts/verify.mjs` run on TypeScript 7
231
+ (the `typescript7` devDependency), which reports the same errors about seven
232
+ times faster; keep code clean under both.
230
233
 
231
234
  1. Add or update a focused regression test.
232
235
  2. Make the smallest change at the owning layer.
233
236
  3. Prefer deletion or an existing utility over another wrapper.
234
- 4. While iterating, run the focused test or `npm run verify:fast` (types for src, tests and server, the node reference, the architecture ratchets, and `vitest related` for the files you changed). Before you commit, run `npm run verify`: it builds the packages, then runs the typechecks, `check:packages`, svelte-check, the whole vitest suite, the package tests and the Studio bundle budget, stopping at the first failure. It never touches `dist/`. Run `npm run build` and `npm run build:cli` only when you need the built CLI or Studio; both replace `dist/` only on success, so a failed build leaves the previous CLI working.
237
+ 4. While iterating, run the focused test or `npm run verify:fast` (types for src, tests and server, the node reference, the architecture ratchets, and `vitest related` for the files you changed). Before you commit, run `npm run verify`: it builds the packages, then runs the typechecks, `check:packages`, svelte-check, the whole vitest suite, the package tests and the Studio bundle budget, stopping at the first failure. It never touches `dist/`. Run `npm run build` and `npm run build:cli` only when you need the built CLI or Studio; both replace `dist/` only on success, so a failed build leaves the previous CLI working. `build:cli` skips the package build when every `packages/*/dist` is newer than its sources (`-- --force` rebuilds them). For a runtime or CLI change, `npx vitest run --project node` runs the suite without the Studio component tests. `git push` runs a pre-push gate (`.githooks/pre-push`, installed by `npm install`): when the pushed commits touch code it runs `verify --push` (the fast gate, svelte-check alongside, and the tests related to the pushed files, leaving out `tests/performance/`), 10–14 s. It checks the working tree, so someone else's uncommitted edit can fail it; `git push --no-verify` skips it once, and it does not replace `npm run verify` before you commit.
235
238
  5. For package/public API changes, also test the packed tarball from an empty temporary project.
236
239
  6. When a built-in definition or a node library registry changes, regenerate the node reference with `npm run build:node-reference` and commit the result. `verify` fails on a stale one (`npm run check:node-reference`).
237
240
  7. The ratchets in `tests/architecture-*.test.ts`, `scripts/bundle-budget.mjs` and the test type-error list in `scripts/verify.mjs` only go down. When one fails, fix the code: split the file, move the shared code down a layer, break the cycle, lazy-load the new Studio code. Never add to a list or raise a number; when your change lowers one, lower the number in the same commit.
package/ARCHITECTURE.md CHANGED
@@ -80,8 +80,9 @@ Studio-only project extensions use the type-only `cascade/studio/panel` contract
80
80
  The packed root tarball contains compiled contracts, runtime, declarations, and a self-contained CLI. It must install and type-resolve from an empty project without workspace links or development dependencies. Additional packages require a concrete independent publication/versioning need.
81
81
 
82
82
  The repository requires Node.js 22.13 or newer and builds with TypeScript 6,
83
- Vite 8, and the Svelte Vite plugin 7. TypeScript 7 remains deferred while it is
84
- a preview rather than a stable compiler target.
83
+ Vite 8, and the Svelte Vite plugin 7. TypeScript 7 runs the plain-tsc gates in
84
+ `scripts/verify.mjs` only; the build, the CLI's node compiler and svelte-check
85
+ stay on 6, which has the JS API they use.
85
86
 
86
87
  Model providers are deliberately outside Cascade. Projects own provider SDKs,
87
88
  credentials, model selection, retries, and result normalization, using the same
@@ -121,9 +122,9 @@ Callbacks and destruction hooks run after a valid structural commit. They are no
121
122
 
122
123
  ## Execution
123
124
 
124
- Data runs follow graph dependencies. Explicit triggers use a FIFO queue, authored fan-out order, monotonic per-run sequence IDs, and cycle rejection. A triggered node receives cooked data ancestors before delivery.
125
+ Data runs follow graph dependencies; with `concurrency` > 1 (headless runs with a stage worker pool) independent nodes cook at once, still starting in topological order so events and traces keep one order. Explicit triggers use a FIFO queue, authored fan-out order, monotonic per-run sequence IDs, and cycle rejection. A triggered node receives cooked data ancestors before delivery.
125
126
 
126
- Execution failures resolve to a failed `RunResult`; API misuse and invalid preflight reject. Cancellation propagates through capability calls. Inspection and output values are immutable snapshots; browser-only live resources remain host-owned handles.
127
+ Execution failures resolve to a failed `RunResult`; API misuse and invalid preflight reject. Cancellation propagates through capability calls. Inspection and output values are immutable; browser-only live resources remain host-owned handles. A value a node hands to `set()` is adopted, not copied: under the default `values: "freeze"` it is checked and deep-frozen where it stands, and every later read (`getOutputs`, `inspect`, `node:output`, the next node's input) is that same value. Headless runs (`cascade run`) use `values: "trust"`, which checks the top-level type and freezes shallowly without walking the contents. Caller-supplied values (`setInput`, presets, definitions) are still copied.
127
128
 
128
129
  ### Geometry, simulation and feedback
129
130
 
package/CHANGELOG.md CHANGED
@@ -4,6 +4,251 @@ Notable changes to Cascade. Newest first.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.13.0 — 2026-11-09
8
+
9
+ ### Added
10
+
11
+ - **Browser player without chrome.** `mount(…, { chrome: false })`, or
12
+ `player.html?chrome=0` in a plain iframe, shows the output alone on a
13
+ transparent page: no dark frame, Play button or frame field. See
14
+ `doc/WEB_PLAYER.md`.
15
+ - **Read-only roots outside the project.** `"reads": ["../other/data"]` in
16
+ `cascade.json` lets file reads (`files`, `cascade/io`, Studio media) resolve
17
+ into another folder by `..` or a symlink; writes there are still refused,
18
+ and any other path out of the project still is. See "Reading another
19
+ project's data" in `doc/PROJECT_AUTHORING.md`.
20
+ - **Named exports and a keyed cache for nodes.** `"writes": ["renders"]` in
21
+ `cascade.json` lets the `files` capability write stably named files into a
22
+ declared project folder beside `.cascade-cache/`. `files.cache.get(key)` /
23
+ `files.cache.put(key, data)` (contract `KeyedCache`) keep entries under
24
+ `.cascade-cache/keyed/<key>`, found again by key on the next run, where
25
+ `cascade/io` names carry a content hash. `files.write` is now atomic, and
26
+ normalises before its folder test, so `.cascade-cache/../x` is refused.
27
+ - **Node files may hold immutable module-level constants.** Helper functions
28
+ were already allowed; `architecture/module-state` now also passes `const`s
29
+ that cannot change (`const TAU = Math.PI * 2`, `[...] as const`,
30
+ `Object.freeze({...})`, arrow-function helpers). `let`, `new Map()`, a bare
31
+ array or object, a regex and other calls are still refused.
32
+
33
+ ### Fixed
34
+
35
+ - **The browser player re-cooks only what changed.** `setProp`, `setInput`
36
+ and each frame now cook the changed node and what lies downstream of it;
37
+ an unchanged upstream node keeps its outputs (`reuse: "strict"`), so a
38
+ paint prop no longer re-runs a slow data node above it.
39
+ - **`cascade render --workers` accepts a piece animated on twos.** Two frames
40
+ whose node saved the same drawing land on one content-named cache file
41
+ (`.cascade-cache/<node>.<hash>.png`); that is the same bytes, not a
42
+ clobber, so the fixed-path probe no longer refuses it.
43
+
44
+ ### Changed
45
+
46
+ - **`FileCapability` has a required `cache: KeyedCache` member.** A custom
47
+ host that implements the `files` capability itself must now provide
48
+ `cache.get(key)` and `cache.put(key, data)`; it no longer type-checks
49
+ without them. Studio and the headless host already do.
50
+
51
+ ### Known gaps
52
+
53
+ - **Ramp's stop editor and Image's file picker are not in Studio yet.** The
54
+ definition-v1 port of the image nodes left them out. Graphs that already
55
+ set them render unchanged.
56
+
57
+ ## 0.12.0 — 2026-11-09
58
+
59
+ ### Added
60
+
61
+ - **GPU nodes get the whole GPU, and can say what they need.** Studio and
62
+ the headless host now ask for every limit the adapter allows instead of
63
+ WebGPU's defaults: on an M3 Max, 4 GiB per storage binding instead of
64
+ 128 MiB, 1,024 workgroup invocations instead of 256, 32 KiB workgroup
65
+ storage instead of 16, 10 storage buffers per stage instead of 8. A node
66
+ may declare `gpuLimits` (`{ maxStorageBufferBindingSize: 512 * 2 ** 20 }`);
67
+ on a GPU below it the node fails before cooking, naming the limit and what
68
+ the GPU gives. An adapter that refuses its own ceiling still gets a device
69
+ with the defaults.
70
+ - **Scrub number in the Inspector.** Every number field and each vector
71
+ component drags anywhere on the field (at `scrub.ts`'s rates, Shift ×10,
72
+ Cmd ÷10), with a tick ruler that slides under the pointer and stops at a
73
+ declared min/max while that edge lights; hover shows the ruler and ‹ ›
74
+ steppers; a click without a drag opens typing, and plain arithmetic
75
+ (`320/2`, `10+5`) commits the number it works out to, not an expression. A
76
+ sideways touch drag scrubs and a vertical one still scrolls. Middle-drag,
77
+ label-drag and Alt-drag are unchanged. Vector fields are now text, so they
78
+ take the same sums and arrow-key steps.
79
+ - **Scrub number on every node's vector parameters.** The vector components
80
+ most nodes render through (CoreValue: `vec2`/`vec3`/`vec2i`… params and
81
+ ports) are the same scrub field: drag anywhere, click to type `10+5`, ‹ ›
82
+ and arrow-key steps, the ruler stopping at a declared range with the edge
83
+ lit. A bounded component keeps its range hairline. Read-only values stay
84
+ plain. Middle-, Alt- and label-drag and the Σ expression path are unchanged.
85
+ - **`cascade check` warns on nodes that have grown into a pipeline.**
86
+ `shape/long-execute` when `execute` passes 150 lines; `shape/mixed-jobs`
87
+ when one module loads, generates, colours, draws and exports (four of the
88
+ five, or loading and exporting together), judged from the calls it makes.
89
+ Advice only: the check still passes, `--strict` included, and `validate`
90
+ and `run` stay quiet. Points at "Design the graph" in
91
+ `doc/PROJECT_AUTHORING.md`.
92
+ - **Ladder variants as a Cairn choice card.** `cascade ladder … --cairn
93
+ <vault dir>` (MCP `ladder` `cairn`) copies each variant to
94
+ `<dir>/<id>-<nn>.png` in the Substrate vault and prints a `cairn:choice`
95
+ fence (`--json`: `data.cairnChoice`): one option per variant, labelled with
96
+ what it changed (`seed 42`, `hue=0.3`), its image relative to the vault
97
+ (nearest `.obsidian` or `.git`, or `--vault`), and the value
98
+ `pick:<id>:<n>`. Marcus taps a picture on his phone; the agent gets
99
+ "Picked: … (pick:<id>:<n>)", runs `cascade pick <id> <n>` and replies with
100
+ the locked image. At most 8 variants, refused before cooking. The loop is in
101
+ AGENTS.md, `doc/CLI_REFERENCE.md` and the `cascade new` template.
102
+ - **`cascade share`: output reaches people as a link.** `cascade share
103
+ <graph | site-directory> [--name <slug>]` exports the editor (or takes a
104
+ static directory with an `index.html`) into a scratch directory, with the
105
+ export allowlist and leak scan, deploys it to the Vercel project
106
+ `cascade-<slug>` and prints the production URL (`data.url` with `--json`).
107
+ Each share is recorded in the project's `shares.json`. Public unless
108
+ `--protected`. Also the MCP tool `share`. The deploy step is a `Deployer`
109
+ (`deployVercel` in `editorExport.ts`), which tests stub; `cascade export
110
+ --deploy vercel` uses the same one and now checks the production alias
111
+ Vercel reports rather than assuming `<project>.vercel.app`.
112
+
113
+ ### Changed
114
+
115
+ - **`git push` runs a pre-push gate.** `npm install` points the checkout's
116
+ hooks at `.githooks/`; a push whose commits touch code runs
117
+ `verify --push`: types, node reference, architecture, svelte-check in
118
+ parallel, and the tests related to the pushed files, without the
119
+ load-sensitive `tests/performance/` timings. 10.8 s for a Studio change,
120
+ 10–14 s for a `Graph.ts` change on a loaded machine. A push of docs alone
121
+ skips it; `--no-verify` skips it once.
122
+ - **The test suite runs in about 13 s, down from 18 s.** Studio imported
123
+ Lucide through its `@lucide/svelte` barrel, which loads every icon: 4.8 s
124
+ of module loading in each component test file and on every dev-server
125
+ cold start. Icons are now imported one by one
126
+ (`@lucide/svelte/icons/<name>`), and an architecture test fails if the
127
+ barrel comes back. The Studio bundle stays inside its budget.
128
+ - **Independent nodes cook at once in a headless run.** A project with a
129
+ warm stage worker gets a small pool of them (2–4, sized from cores and
130
+ memory; `exec.stages.workers` or `CASCADE_STAGE_WORKERS` sets it, a
131
+ `cascade render` worker keeps one), and the run cooks that many nodes at
132
+ once, a node only after everything it reads. Nodes still start in
133
+ topological order, so the run trace's order is the same every run, and a
134
+ stage call or log line goes to the node that made it. cloud-plots
135
+ `morph.cascade`, cold (Python cache missed), frames 101–107: 873 → 271 ms a
136
+ frame with 4 workers, the four renders overlapping; the first frame, which
137
+ starts the workers, 6.3 → 5.1 s. Runtime option `concurrency` (default 1);
138
+ feedback, trigger-wired and GPU nodes still cook alone.
139
+ - **The runtime stops copying values.** A value a node hands to `set()` is
140
+ checked and deep-frozen where it stands (`values: "freeze"`, the default)
141
+ instead of being cloned, and every later read (the `node:output` event,
142
+ `getOutputs`, a run's result, `inspect()`, the next node's input) is that
143
+ same value rather than another copy. `cascade run` uses `values: "trust"`:
144
+ the top-level type is checked and the value frozen shallowly, its contents
145
+ are not walked. `run --frames` works out which ports to save once per run
146
+ instead of calling `inspect()` every frame. A 1M-point plain array through
147
+ three nodes: 1,335 → 8 ms a frame under `trust` (105 ms under `freeze`),
148
+ `inspect()` 427 → 0 ms. A node that mutates a plain array or object after
149
+ handing it to `set()` now throws; it used to change nothing.
150
+ - **The image library is definition-v1 and runs everywhere.** Color,
151
+ Checkers, Noise, Ramp, Text, File (`cascade.image.Image`), Blur, Normal Map,
152
+ Resize, Transform and Composite were Studio classes over `ImageNodeBase`;
153
+ they are portable built-ins in `packages/runtime` with the same module ids,
154
+ ports and props, so saved graphs load unchanged and now also run under
155
+ `cascade run`/`render`, MCP, exported editors and the web player. Images pass
156
+ between them through the in-memory image contract; in Studio they stay in
157
+ the page (`.cascade-studio/…` paths the Viewer draws from memory) rather than
158
+ becoming files. 53 golden fixtures captured on the class nodes render pixel
159
+ for pixel the same on the runtime and in Studio. A colour saved as
160
+ `{ r, g, b, a }` reads as the four-component colour on load
161
+ (`Color.upgrade`). Noise no longer fetches simplex-noise from esm.sh (4.0.3
162
+ is vendored). Text takes a project font file in `font` and falls back to
163
+ sans-serif when it is missing. The Ramp's stops edit as JSON in the
164
+ Parameters section rather than with the ramp widget, and File's path is a
165
+ text field. A dynamic node that read an `ImageBuffer` from these ports now
166
+ gets an `ImageRef`.
167
+ - **Contact Sheet and the assertions are in Studio.** `cascade.image.ContactSheet`
168
+ is in the Image library's Composite category and `cascade.assert.*` has its
169
+ own Assert library. The assertions are portable now (Not Blank takes kept
170
+ pixels or decodes with `DecompressionStream`), so they live in the runtime's
171
+ built-in list and `src/cli/assertNodes.ts` and the headless-only list are
172
+ gone. Their bodies load lazily: Studio's first-paint JS went down, 969,706 →
173
+ 964,958 B, with the class library and `ImageBuffer` gone; the budget is
174
+ lowered to match.
175
+ - **Studio paints the viewed node first.** After the Viewer's node cooks,
176
+ nothing outside its upstream starts until the Viewer has shown the new
177
+ picture (image loaded, then a frame; at most 300 ms), and while a slider
178
+ is held or a number field scrubs, only the viewed node's upstream cooks:
179
+ the rest waits for release. field-logo hue slider, input to painted:
180
+ 440 → 141 ms median; a held drag no longer runs watercolor (~300 ms long
181
+ task) at all until release. Studio only (`src/editor/stores/viewedFirstCook.ts`);
182
+ the CLI and the scheduler are unchanged.
183
+ - **Smaller Studio first paint.** The Agent, Definition, Node Info and
184
+ Timeline panels load when their panel is created, and marked + DOMPurify
185
+ load with the Agent panel or the first text annotation (which shows plain
186
+ text for that moment). First-paint JS 1,135,042 → 968,597 B (gzip 325 →
187
+ 273 KB), CSS 239,446 → 223,490 B. `scripts/bundle-budget.mjs` now counts
188
+ the chunks the entry modulepreloads too, and its budgets are lowered to the
189
+ new size plus 25 KB of JS and 10 KB of CSS headroom.
190
+ - **Faster dev loop.** `npm run build:cli` skips the package build when
191
+ every `packages/*/dist` is newer than its sources (3.5 → 2.0 s; `--force`
192
+ rebuilds). Vitest runs two projects, `node` and `studio` (the Svelte
193
+ plugin only where components are tested): `vitest run --project node` is
194
+ 1,767 tests in ~10 s against ~18 s for the whole suite, which `verify`
195
+ still runs in full; `verify --fast` uses the node project when nothing
196
+ Studio-side changed. The plain-tsc gates in `verify` run on TypeScript 7
197
+ (`typescript7` devDependency), same errors per file, src + tests 3.0 →
198
+ 0.4 s; the build, the CLI's node compiler and svelte-check stay on
199
+ TypeScript 6.
200
+ - **Intermediate images encode six times faster headlessly.** `saveImage`
201
+ (`cascade/io`) and `writeImage` (`cascade/image`) hand a canvas to the
202
+ headless host as pixels, and it writes a lossless PNG at zlib level 1
203
+ through sharp instead of Skia's default encoder: 157 → 26 ms per 1024²
204
+ image. field-logo renders at 887 ms a frame instead of 1,791, with
205
+ pixel-identical outputs. The CLI now bundles `cascade/io` from its own
206
+ install, as it already did `cascade/image`, so a sketch pinned to an older
207
+ package gets it too. New optional `IoBridge.keep` and
208
+ `AssetCapability.keepImage`; Studio and the browser player are unchanged.
209
+ - **Images pass between nodes in memory under `cascade run`/`render`.** The
210
+ headless host holds an intermediate's pixels (`ImagePixels` in contracts:
211
+ RGBA8, sRGB, unpremultiplied), names its file by their hash and writes the
212
+ level-1 PNG behind the run; `readImage`/`loadBitmap` get those pixels back
213
+ with no read and no decode (`AssetCapability.imagePixels`,
214
+ `IoBridge.pixels`). Every file reader still finds a whole file: Python stage
215
+ calls, `assets.read`, server nodes, the end of a run, freeze/lock/ladder all
216
+ wait for the write behind. Saved outputs are encoded from the pixels at
217
+ full compression (zlib 6, adaptive filtering), not copied from the
218
+ intermediate. field-logo 887 → 834 ms a frame (1,791 before round 2),
219
+ outputs pixel-identical; what remains is the nodes' own pixel loops. The
220
+ contract is in `doc/PROJECT_AUTHORING.md`, "How an image travels between
221
+ nodes".
222
+ - **`cascade render` workers start Python during the probe frames.** Each
223
+ worker process starts the project's warm Python worker as it boots
224
+ (`installProjectStages(…, { prewarm: true })`, `PythonWorker.warm()`), so
225
+ the interpreter start and imports overlap the first two serial frames
226
+ instead of following them. A project whose worker takes 3 s to import
227
+ renders 24 frames on 4 workers in 4.0 s instead of 7.0. A worker whose
228
+ interpreter cannot start now fails the call that needs it instead of
229
+ crashing the process. `run --frames` over 30 frames prints one line naming
230
+ `cascade render` for the same range.
231
+ - **Run traces time the frame and the save.** Each run in
232
+ `.cascade/runs/*.json` has `ms` (the cook), `frameMs` (to outputs on disk)
233
+ and `saveMs` (the difference), so a slow save shows without a profiler
234
+ (field-logo now: 747 ms cook, 82 ms save a frame).
235
+
236
+ ### Fixed
237
+
238
+ - **`run --frames … --mp4` with an absolute `--out`.** ffmpeg was handed the
239
+ project root joined to the absolute sequence path and found no files; the
240
+ sequence is now resolved, not joined.
241
+ - **`cascade doctor` fails a project whose stages cannot import numpy.** With
242
+ no `python` environment declared, a stage source importing numpy and an
243
+ interpreter without it is a `stage imports` failure naming the file and the
244
+ fix. cloud-wall and cloud-volumes passed doctor and could not render.
245
+
246
+ ### Known gaps
247
+
248
+ - **Ramp's stop editor and Image's file picker are not in Studio yet.** The
249
+ definition-v1 port of the image nodes left them out. Graphs that already
250
+ set them render unchanged.
251
+
7
252
  ## 0.11.0 — 2026-11-07
8
253
 
9
254
  ### Added
package/README.md CHANGED
@@ -36,7 +36,7 @@ cascade . # reopen it later
36
36
  cascade run index.cascade --frames 1 --json # render headlessly
37
37
  ```
38
38
 
39
- The npm package is at 0.11.0 and includes every command below. 0.11 adds `cascade/image`, `ladder`/`pick`, `run --out`, assertion nodes, `help node` and `doctor`; see the [changelog](CHANGELOG.md).
39
+ The npm package is at 0.13.0 and includes every command below. 0.13 adds the chrome-free player, read-only roots and named writes in `cascade.json`, a keyed node cache and module-level constants in node files; see the [changelog](CHANGELOG.md).
40
40
 
41
41
  ## New in 0.9: shareable editors
42
42
 
@@ -0,0 +1 @@
1
+ .console.svelte-1cqop5k{background:var(--surface-panel);width:100%;height:100%;color:var(--text-primary);flex-direction:column;min-height:0;font-family:SF Mono,Monaco,Cascadia Code,Consolas,monospace;font-size:12px;display:flex}.console.drop-active.svelte-1cqop5k{outline:1px solid var(--accent);outline-offset:-1px}.bar.svelte-1cqop5k{border-bottom:1px solid var(--border-divider);background:var(--surface-panel-alt);align-items:center;gap:6px;padding:4px 6px;display:flex}.bar.svelte-1cqop5k select:where(.svelte-1cqop5k),.bar.svelte-1cqop5k button:where(.svelte-1cqop5k),.send.svelte-1cqop5k{background:var(--surface-control);color:var(--text-primary);border:1px solid var(--border);font:inherit;cursor:pointer;border-radius:4px;padding:2px 6px}.send.svelte-1cqop5k{flex:none;width:30px;height:30px;padding:0;font-size:15px;line-height:1}.bar.svelte-1cqop5k button.icon:where(.svelte-1cqop5k){width:22px;height:22px;padding:0;font-size:12px;line-height:1}.bar.svelte-1cqop5k button.stop:where(.svelte-1cqop5k){color:var(--accent)}.zoom.svelte-1cqop5k{color:var(--text-secondary);font:inherit;cursor:pointer;background:0 0;border:none;padding:0 4px}.zoom.svelte-1cqop5k:hover{color:var(--text-primary)}.bar.svelte-1cqop5k button:where(.svelte-1cqop5k):hover,.send.svelte-1cqop5k:hover:not(:disabled){background:var(--surface-control-hover)}.send.svelte-1cqop5k:disabled{color:var(--text-disabled);cursor:default}.sketch.svelte-1cqop5k{color:var(--text-tertiary);text-overflow:ellipsis;white-space:nowrap;max-width:40%;overflow:hidden}.spacer.svelte-1cqop5k{flex:1}.notice.svelte-1cqop5k{background:var(--banner-warn-bg);color:var(--banner-warn-text);border-bottom:1px solid var(--banner-warn-border);padding:6px 8px;line-height:1.5}.notice.svelte-1cqop5k code:where(.svelte-1cqop5k){color:var(--text-code);white-space:pre-wrap;margin-top:4px;display:block}.transcript.svelte-1cqop5k{min-height:0;font-size:calc(12px * var(--agent-zoom,1));flex-direction:column;flex:1;gap:4px;padding:6px 8px;line-height:1.45;display:flex;overflow:auto}.hint.svelte-1cqop5k{color:var(--text-faint);line-height:1.6}.entry.svelte-1cqop5k{white-space:pre-wrap;word-break:break-word;line-height:1.5}.entry.you.svelte-1cqop5k{color:var(--accent)}.entry.agent.svelte-1cqop5k{color:var(--text-primary)}.entry.result.svelte-1cqop5k{color:var(--text-bright)}.entry.tool.svelte-1cqop5k{color:var(--text-tertiary)}.entry.system.svelte-1cqop5k{color:var(--text-faint)}.entry.detail.svelte-1cqop5k{color:var(--text-faint);font-size:.9em}.entry.error.svelte-1cqop5k{color:var(--status-error)}.detail-toggle.svelte-1cqop5k{border:1px solid var(--border-faint);color:var(--text-faint);font:inherit;cursor:pointer;background:0 0;border-radius:3px;align-self:flex-start;margin-top:.25rem;padding:.1rem .4rem;font-size:.85em}.detail-toggle.svelte-1cqop5k:hover{color:var(--text-secondary);border-color:var(--border-divider)}.composer.svelte-1cqop5k{border-top:1px solid var(--border-divider);background:var(--surface-panel-alt);flex-direction:column;gap:8px;padding:10px;display:flex}.composer-context.svelte-1cqop5k,.composer-row.svelte-1cqop5k{align-items:center;gap:8px;display:flex}.composer-context.svelte-1cqop5k button:where(.svelte-1cqop5k){border:1px solid var(--border);background:var(--surface-control);color:var(--text-secondary);font:inherit;cursor:pointer;border-radius:4px;padding:3px 7px}.composer-context.svelte-1cqop5k button.active:where(.svelte-1cqop5k){border-color:var(--accent);color:var(--text-primary);background:var(--accent-tint)}.composer-context.svelte-1cqop5k button:where(.svelte-1cqop5k):disabled{color:var(--text-disabled);cursor:default}.composer-context.svelte-1cqop5k span:where(.svelte-1cqop5k){min-width:0;color:var(--text-tertiary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.composer-row.svelte-1cqop5k{align-items:flex-end}.composer.svelte-1cqop5k textarea:where(.svelte-1cqop5k){resize:none;background:var(--surface-input);max-height:50%;color:var(--text-primary);border:1px solid var(--border);font-family:inherit;font-size:calc(12px * var(--agent-zoom,1));border-radius:4px;flex:1;padding:8px 10px;line-height:1.45;overflow-y:auto}.composer.svelte-1cqop5k textarea:where(.svelte-1cqop5k):focus{outline:1px solid var(--accent);outline-offset:-1px}.entry.markdown.svelte-1cqop5k{white-space:normal}.entry.markdown.svelte-1cqop5k>:first-child{margin-top:0}.entry.markdown.svelte-1cqop5k>:last-child{margin-bottom:0}.entry.markdown.svelte-1cqop5k p{margin:0 0 .6em}.entry.markdown.svelte-1cqop5k h1,.entry.markdown.svelte-1cqop5k h2,.entry.markdown.svelte-1cqop5k h3,.entry.markdown.svelte-1cqop5k h4,.entry.markdown.svelte-1cqop5k h5,.entry.markdown.svelte-1cqop5k h6{color:var(--text-bright);margin:.9em 0 .35em;font-weight:600;line-height:1.3}.entry.markdown.svelte-1cqop5k h1{font-size:1.3em}.entry.markdown.svelte-1cqop5k h2{font-size:1.18em}.entry.markdown.svelte-1cqop5k h3{font-size:1.08em}.entry.markdown.svelte-1cqop5k h4,.entry.markdown.svelte-1cqop5k h5,.entry.markdown.svelte-1cqop5k h6{font-size:1em}.entry.markdown.svelte-1cqop5k ul,.entry.markdown.svelte-1cqop5k ol{margin:0 0 .6em;padding-left:1.4em}.entry.markdown.svelte-1cqop5k li{margin:.15em 0}.entry.markdown.svelte-1cqop5k li>p{margin:0}.entry.markdown.svelte-1cqop5k strong{color:var(--text-bright);font-weight:600}.entry.markdown.svelte-1cqop5k blockquote{border-left:2px solid var(--border-divider);color:var(--text-tertiary);margin:0 0 .6em;padding-left:.8em}.entry.markdown.svelte-1cqop5k hr{border:0;border-top:1px solid var(--border-faint);margin:.8em 0}.entry.markdown.svelte-1cqop5k a{color:var(--accent)}.entry.markdown.svelte-1cqop5k code{background:var(--surface-raised);color:var(--text-code);border-radius:3px;padding:.1em .3em;font-size:.92em}.entry.markdown.svelte-1cqop5k pre{background:var(--surface-raised);border:1px solid var(--border-faint);white-space:pre;border-radius:4px;margin:0 0 .6em;padding:.5em .6em;overflow-x:auto}.entry.markdown.svelte-1cqop5k pre code{white-space:pre;background:0 0;border-radius:0;padding:0}.entry.markdown.svelte-1cqop5k table{border-collapse:collapse;max-width:100%;margin:0 0 .6em;display:block;overflow-x:auto}.entry.markdown.svelte-1cqop5k th,.entry.markdown.svelte-1cqop5k td{border:1px solid var(--border-faint);text-align:left;vertical-align:top;white-space:nowrap;word-break:normal;padding:.25em .5em}.entry.markdown.svelte-1cqop5k th{background:var(--surface-raised);color:var(--text-bright);font-weight:600}.entry.markdown.svelte-1cqop5k img{max-width:100%}
@@ -0,0 +1,5 @@
1
+ import{$ as e,D as t,Dt as n,F as r,G as i,I as a,L as o,O as s,Ot as ee,Q as c,T as te,U as l,V as u,W as ne,X as d,Z as re,_t as ie,at as ae,ct as f,dt as p,et as m,ft as oe,gt as se,it as h,jt as g,l as ce,lt as _,n as le,nt as v,ot as y,p as ue,pt as b,q as de,r as fe,rt as pe,st as me,v as he,vt as ge,w as _e,x as ve,yt as ye,z as x}from"./legacy-CTEeXeqF.js";import{_ as be,dt as xe,g as Se,h as Ce,m as we,o as S,p as Te,v as Ee,y as De}from"./index-BWnrmIB9.js";import{renderMarkdown as Oe}from"./renderMarkdown-ork0Oir7.js";var C=class extends Error{constructor(e,t=null,n=null){super(e),this.hint=t,this.code=n,this.name=`AgentUnavailableError`}},w=null,T=null;function ke(){return w?Promise.resolve(w):(T??=Ae().finally(()=>{T=null}),T)}async function Ae(){let e=await fetch(`/api/agent/capability`);if(e.status===404)throw new C(`The agent console is disabled on this server. It is available only on a loopback server or one started with an explicit trusted host.`);if(!e.ok)throw new C(`Could not start an agent session (${e.status})`);let{capability:t}=await e.json();if(typeof t!=`string`||!t)throw new C(`Server issued no agent capability`);return w=t,t}async function E(e,t){let n=e=>({...t.headers??{},"X-Cascade-Agent-Capability":e}),r=await fetch(e,{...t,headers:n(await ke())});return r.status===403&&(w=null,r=await fetch(e,{...t,headers:n(await ke())})),r}async function je(e){let t=await E(`/api/agent/status${e?`?sketch=${encodeURIComponent(e)}`:``}`,{method:`GET`});if(!t.ok)throw new C(`Could not read agent status (${t.status})`);let n=await t.json();return{root:String(n?.root??``),agents:Array.isArray(n?.agents)?n.agents:[],sessions:Array.isArray(n?.sessions)?n.sessions:[]}}var D=2e3,O=3e4;function Me(e){let t=!1,n=null,r=null,i=D,a=e.sketch?`?sketch=${encodeURIComponent(e.sketch)}`:``,o=typeof document<`u`,s=()=>!o||document.visibilityState!==`hidden`,ee=()=>{t||r||!s()||(r=setTimeout(()=>{r=null,c()},i),i=Math.min(i*2,O))};async function c(){if(t||n||!s())return;let r=new AbortController;n=r;try{let n=await E(`/api/agent/watch${a}`,{method:`GET`,signal:r.signal});if(n.status===404){t=!0;return}if(!n.ok)throw Error(`agent watch ${n.status}`);i=D,await k(n,t=>{t?.type===`status`&&Array.isArray(t.sessions)&&e.onSessions(t.sessions)})}catch(e){if(e instanceof C){t=!0;return}if(e?.name===`AbortError`)return}finally{n===r&&(n=null)}ee()}let te=()=>{s()?(i=D,c()):(n?.abort(),n=null,r&&clearTimeout(r),r=null)};return o&&document.addEventListener(`visibilitychange`,te),c(),()=>{t=!0,n?.abort(),n=null,r&&clearTimeout(r),o&&document.removeEventListener(`visibilitychange`,te)}}async function k(e,t){if(!e.body)return;let n=e.body.getReader(),r=new TextDecoder,i=``,a=e=>{if(e.trim())try{t(JSON.parse(e))}catch{}};for(;;){let{value:e,done:t}=await n.read();if(t)break;i+=r.decode(e,{stream:!0});let o=i.split(`
2
+ `);i=o.pop()??``;for(let e of o)a(e)}a(i)}async function Ne(e,t){let n=await E(`/api/agent/cancel`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({agent:e,sketch:t})});return n.ok?(await n.json().catch(()=>null))?.cancelled===!0:!1}async function Pe(e,t){await E(`/api/agent/reset`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({agent:e,sketch:t})})}async function Fe(e){let t=await E(`/api/agent/attach`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({agent:e.agent,sketch:e.sketch,since:e.since??0}),signal:e.signal});if(!t.ok){let e=await t.json().catch(()=>null);throw new C(String(e?.error??`Could not reconnect to the agent (${t.status})`))}await A(t,e.onEvent)}async function Ie(e){let t=await E(`/api/agent/prompt`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({agent:e.agent,sketch:e.sketch,prompt:e.prompt}),signal:e.signal});if(!t.ok){let e=await t.json().catch(()=>null);throw new C(String(e?.error??`Agent request failed (${t.status})`),e?.hint??null,e?.code??null)}await A(t,e.onEvent)}async function A(e,t){if(!e.body)throw new C(`Agent produced no stream`);let n=e.body.getReader(),r=new TextDecoder,i=``;for(;;){let{value:e,done:a}=await n.read();if(a)break;i+=r.decode(e,{stream:!0});let o=i.split(`
3
+ `);i=o.pop()??``;for(let e of o)Le(e,t)}Le(i,t)}function Le(e,t){if(e.trim())try{t(JSON.parse(e))}catch{t({type:`stderr`,text:e})}}function Re(e){let t=e.trim();if(!t)return null;if(!t.startsWith(`{`))return{kind:`raw`,text:t};let n;try{n=JSON.parse(t)}catch{return{kind:`raw`,text:t}}if(n?.type===`system`)return null;if(n?.type===`assistant`&&Array.isArray(n?.message?.content)){let e=[];for(let t of n.message.content)t?.type===`text`&&typeof t.text==`string`&&t.text.trim()?e.push(t.text.trim()):t?.type===`tool_use`&&e.push(`· ${t.name??`tool`}${ze(t.input)}`);let t=e.join(`
4
+ `);return t?{kind:e.every(e=>e.startsWith(`· `))?`tool`:`text`,text:t}:null}if(n?.type===`user`)return null;if(n?.type===`result`){let e=typeof n.result==`string`&&n.result.trim()?n.result.trim():null;return e?{kind:`result`,text:e}:null}if(n?.type===`item.completed`||n?.type===`item.started`){let e=n?.item;if(e?.type===`agent_message`&&typeof e.text==`string`&&e.text.trim())return n.type===`item.completed`?{kind:`text`,text:e.text.trim()}:null;if(e?.type===`command_execution`){if(n.type===`item.started`&&typeof e.command==`string`&&e.command.trim())return{kind:`tool`,text:`· Command ${e.command.trim()}`};if(n.type===`item.completed`){let t=typeof e.aggregated_output==`string`?e.aggregated_output.trim():``,n=typeof e.status==`string`?e.status:`completed`,r=`· Command ${(typeof e.command==`string`?e.command.trim():``)||n}`;return{kind:t?`result`:`tool`,text:t?`${r}\n${t}`:r}}}if(e?.type===`file_change`){let t=(Array.isArray(e.changes)?e.changes:[]).map(e=>e?.path).filter(e=>typeof e==`string`&&!!e);return{kind:`tool`,text:`· File change${t.length?` ${t.join(`, `)}`:``}`}}}return n?.type===`thread.started`||n?.type===`turn.started`||n?.type===`turn.completed`?null:typeof n?.type==`string`?{kind:`detail`,text:t}:{kind:`raw`,text:t}}function ze(e){if(!e||typeof e!=`object`)return``;let t=e,n=t.file_path??t.path??t.pattern??t.command;return typeof n==`string`&&n?` ${n}`:``}var Be=i(`<option> </option>`),Ve=i(`<span class="sketch svelte-1cqop5k" title="Open the sketch through the cascade CLI">no project file</span>`),He=i(`<button type="button" class="zoom svelte-1cqop5k" title="Text size — click to reset (⌘0)"> </button>`),Ue=i(`<button type="button" class="icon svelte-1cqop5k" title="Copy the whole transcript, including hidden stream events" aria-label="Copy transcript"> </button>`),We=i(`<button type="button" class="icon stop svelte-1cqop5k" title="Stop the agent" aria-label="Stop the agent">■</button>`),Ge=i(`<button type="button" title="Forget the conversation for this sketch" class="svelte-1cqop5k">Reset</button>`),Ke=i(`<div class="notice svelte-1cqop5k"> </div>`),qe=i(`<code class="svelte-1cqop5k"> </code>`),Je=i(`<div class="notice svelte-1cqop5k"><div> </div> <!></div>`),Ye=i(`<div class="hint svelte-1cqop5k"><!></div>`),Xe=i(`<div></div>`),Ze=i(`<div> </div>`),Qe=i(`<button class="detail-toggle svelte-1cqop5k"> </button>`),$e=i(`<span class="svelte-1cqop5k"> </span>`),et=i(`<div data-panel-scope="agent" role="group" aria-label="Agent console"><div class="bar svelte-1cqop5k"><select aria-label="Agent" class="svelte-1cqop5k"></select> <!> <span class="spacer svelte-1cqop5k"></span> <!> <!> <!></div> <!> <div class="transcript svelte-1cqop5k"><!> <!> <!></div> <div class="composer svelte-1cqop5k"><div class="composer-context svelte-1cqop5k"><button type="button">Use selected node</button> <!></div> <div class="composer-row svelte-1cqop5k"><textarea rows="2" spellcheck="false" placeholder="Prompt the sketch" class="svelte-1cqop5k"></textarea> <button type="button" class="send svelte-1cqop5k" title="Send (⌘↵)" aria-label="Send prompt">↑</button></div></div></div>`);function tt(i,w){ee(w,!1);let T=()=>ye(xe,`$sharedContextStore`,ke),[ke,Ae]=ge(),E=p(),D=p(),O=p(),k=p(),A=p(),Le=p(),ze=new Set([`agent`,`result`]),tt=[`claude`,`codex`],j=p(`claude`),M=p(``),N=p([]),P=p(!1),F=p(!1),I=p([]),nt=p(``),L=p(null),rt=p(!1),R=null,z=null,it=null,at=null,B=p(!1),V=p(null),H=p(null),U=p(!1),W=p(null),G=p(!1);fe(()=>Ee.subscribe(t=>{t.length!==0&&(b(M,be(c(M),Se())),e().then(()=>{_t(),c(H)?.focus()}))}));let ot=`cascade.agentPanel.zoom`,K=[.75,.85,1,1.15,1.3,1.5,1.75,2],q=p(st());function st(){try{let e=Number(localStorage.getItem(ot));return K.includes(e)?e:1}catch{return 1}}function ct(e){b(q,e);try{localStorage.setItem(ot,String(e))}catch{}}function lt(e){let t=K.indexOf(c(q)),n=t===-1?K.indexOf(1):t,r=Math.min(K.length-1,Math.max(0,n+e));r!==n&&ct(K[r])}function ut(e){if(e.altKey)return;let t=e.metaKey||e.ctrlKey;if(!c(W)||!we(`agent`))return;let n=e.target instanceof HTMLTextAreaElement||e.target instanceof HTMLInputElement;!t&&n||(e.key===`0`?(e.preventDefault(),ct(1)):e.key===`+`||e.key===`=`?(e.preventDefault(),lt(1)):(e.key===`-`||e.key===`_`)&&(e.preventDefault(),lt(-1)))}let J=p(S()?.file()??null),dt=[];fe(()=>{ht(c(J));let e=Me({onSessions:e=>{dt=e,gt()}}),t=setInterval(()=>{let e=S()?.file()??null;e===c(J)?!c(F)&&at!==c(j)?ht(e):gt():(b(J,e),ht(e))},1e3);return()=>{clearInterval(t),e()}}),ft();async function ft(){try{let e=await je(c(J)??void 0);if(b(I,e.agents),b(nt,e.root),!c(I).find(e=>e.alias===c(j)&&e.configured&&e.resolved)){let e=c(I).find(e=>e.configured&&e.resolved);e&&b(j,e.alias)}}catch(e){b(L,e instanceof Error?e.message:String(e))}finally{b(rt,!0)}}function pt(e){if(e.type===`attached`)b(B,e.running),e.running||mt(),e.dropped>0&&Y(`system`,`${e.dropped} earlier ${e.dropped===1?`line`:`lines`} were dropped from the server's buffer.`),e.running?Y(`system`,`Reconnected to the ${e.agent} session running for ${e.sketch}.`):e.replayed>0&&Y(`system`,`Showing the last ${e.agent} run for ${e.sketch}. Nothing is running now.`);else if(e.type===`started`)b(B,!0),Y(`system`,`${e.agent} ${e.resumed?`resumed`:`started`} for ${e.sketch}`);else if(e.type===`stdout`){let t=Re(e.text);t&&Y(t.kind===`raw`?`system`:t.kind===`text`?`agent`:t.kind,t.text)}else e.type===`stderr`?Y(`error`,e.text.trimEnd()):e.type===`exit`?(b(B,!1),mt(),e.cancelled?Y(`system`,`Stopped.`):e.timedOut?Y(`error`,`The agent was still running after 15 minutes and was stopped.`):e.code!==0&&Y(`error`,`${c(j)} exited with code ${e.code}.`)):e.type===`error`&&(b(B,!1),mt(),Y(`error`,e.message))}function mt(){dt=dt.map(e=>e.sketch===c(J)&&e.agent===c(j)?{...e,running:!1}:e)}async function ht(e){if(z?.abort(),z=null,it=e,at=c(j),b(B,!1),c(F)||(b(N,[]),!e))return;let t=new AbortController;z=t;try{await Fe({agent:c(j),sketch:e,onEvent:t=>{it===e&&pt(t)},signal:t.signal})}catch(e){e?.name!==`AbortError`&&Y(`error`,e instanceof Error?e.message:String(e))}finally{z===t&&(z=null),b(B,!1)}}async function gt(){c(F)||c(B)||z||!c(J)||c(L)||dt.find(e=>e.sketch===c(J)&&e.agent===c(j)&&e.running)&&await ht(c(J))}function Y(e,t){t.trim()&&(b(N,[...c(N),{kind:e,text:t}]),vt())}function _t(){if(!c(H))return;oe(H,c(H).style.height=`auto`);let e=Math.max(120,Math.round((c(V)?.clientHeight??400)/2));oe(H,c(H).style.height=`${Math.min(c(H).scrollHeight,e)}px`)}async function vt(){await e(),c(V)&&oe(V,c(V).scrollTop=c(V).scrollHeight)}async function yt(){let e=S();if(!e)return Y(`error`,`Studio has not registered the open document, so it cannot be saved before the prompt runs. Nothing was sent.`),null;let t=e.file();if(!t)return Y(`error`,"This graph is not a project file, so the agent has nothing to edit. Open the sketch through the `cascade` CLI, or save it into the project first."),null;if(e.isDirty()){if(!await e.save())return Y(`error`,`Could not save ${t}, so the prompt was not sent — the agent would have rewritten the file underneath your unsaved changes.`),null;Y(`system`,`Saved ${t} before handing the prompt over.`)}return t}async function bt(){let t=c(M).trim();if(!t||c(F))return;let n=await yt();if(!n)return;let r=c(G)?De(T()):null,i=Ce(n,t,r);z?.abort(),z=null,Y(`you`,t),b(M,``),e().then(_t),b(F,!0),R=new AbortController;try{await Ie({agent:c(j),sketch:n,prompt:i,signal:R.signal,onEvent:pt})}catch(e){e instanceof C?(Y(`error`,e.message),e.hint&&Y(`system`,e.hint)):e?.name===`AbortError`?Y(`system`,`Stopped.`):Y(`error`,e instanceof Error?e.message:String(e))}finally{b(F,!1),R=null,b(B,!1)}}async function xt(){let e=c(J)??S()?.file()??null;e&&await Ne(c(j),e),R?.abort(),z?.abort()}async function St(){let e=S()?.file();z?.abort(),z=null,e&&await Pe(c(j),e),b(N,[]),b(B,!1),Y(`system`,`New ${c(j)} session for ${e??`this sketch`}.`)}function Ct(e){e.key===`Enter`&&(e.metaKey||e.ctrlKey||!e.shiftKey)&&(e.preventDefault(),bt())}function wt(e){let t=e.dataTransfer?.getData(`text/plain`);b(U,!1),t&&(e.preventDefault(),e.stopPropagation(),At(t.trim()))}function Tt(e){let t=Array.from(e.dataTransfer?.types??[]);!t.includes(`text/plain`)||t.includes(`Files`)||(e.preventDefault(),e.stopPropagation(),e.dataTransfer&&(e.dataTransfer.dropEffect=`copy`),b(U,!0))}function Et(e){if(!c(W)){b(U,!1);return}let t=c(W).getBoundingClientRect();e.clientX>=t.left&&e.clientX<=t.right&&e.clientY>=t.top&&e.clientY<=t.bottom||b(U,!1)}let Dt=p(!1),Ot;async function kt(){let e=c(N).map(e=>e.text).join(`
5
+ `);if(await Te(e)){b(Dt,!0),clearTimeout(Ot),Ot=setTimeout(()=>b(Dt,!1),1200);return}Y(`error`,`Could not reach the clipboard. Select the transcript and copy it by hand.`)}function At(t){if(!t)return;let n=c(H)?.selectionStart??c(M).length,r=c(M).slice(0,n),i=c(M).slice(n),a=r&&!/\s$/.test(r)?` `:``;b(M,`${r}${a}${t}${i}`),e().then(()=>{c(H)?.focus();let e=(r+a+t).length;c(H)?.setSelectionRange(e,e)})}le(()=>{R?.abort(),z?.abort(),clearTimeout(Ot)}),v(()=>T(),()=>{b(E,T()?.selectedNode??null)}),v(()=>c(E),()=>{c(E)||b(G,!1)}),v(()=>(c(I),c(j)),()=>{b(D,c(I).find(e=>e.alias===c(j))??null)}),v(()=>(c(F),c(B)),()=>{b(O,c(F)||c(B))}),v(()=>(c(rt),c(D)),()=>{b(k,!c(rt)||!!(c(D)?.configured&&c(D)?.resolved))}),v(()=>c(N),()=>{b(A,c(N).filter(e=>e.kind===`detail`).length)}),v(()=>(c(P),c(N)),()=>{b(Le,c(P)?c(N):c(N).filter(e=>e.kind!==`detail`))}),pe(),ce();var X=et();d(`keydown`,ae,ut),d(`dragend`,ae,()=>b(U,!1));let jt;var Mt=y(X),Z=y(Mt);a(Z,5,()=>tt,o,(e,t)=>{var n=Be(),r=f(n,!0),i={};h(()=>{u(r,c(t)),i!==(i=c(t))&&(n.value=(n.__value=i)??``)}),l(e,n)}),g(Z),te(Z);var Nt=_(Z,2),Pt=e=>{var t=Ve();l(e,t)};x(Nt,e=>{c(J)||e(Pt)});var Ft=_(Nt,4),It=e=>{var t=He(),n=f(t);h(e=>u(n,`${e??``}%`),[()=>(c(q),m(()=>Math.round(c(q)*100)))]),d(`click`,t,()=>ct(1)),l(e,t)};x(Ft,e=>{c(q)!==1&&e(It)});var Lt=_(Ft,2),Rt=e=>{var t=Ue(),n=f(t,!0);h(()=>u(n,c(Dt)?`✓`:`⧉`)),d(`click`,t,kt),l(e,t)};x(Lt,e=>{c(N),m(()=>c(N).length>0)&&e(Rt)});var zt=_(Lt,2),Bt=e=>{var t=We();d(`click`,t,xt),l(e,t)},Vt=e=>{var t=Ge();d(`click`,t,St),l(e,t)};x(zt,e=>{c(O)?e(Bt):e(Vt,-1)}),g(Mt);var Ht=_(Mt,2),Ut=e=>{var t=Ke(),n=f(t,!0);h(()=>u(n,c(L))),l(e,t)},Wt=e=>{var t=Je(),n=y(t),r=f(n,!0),i=_(n,2),a=e=>{var t=qe(),n=f(t);h(()=>u(n,`"commands": { "${c(j)??``}": "<path>" }`)),l(e,t)};x(i,e=>{c(nt),c(D),m(()=>c(nt)&&!c(D)?.configured)&&e(a)}),g(t),h(()=>u(r,(c(D),c(j),m(()=>c(D)?.hint??`Command "${c(j)}" is not allowed.`)))),l(e,t)};x(Ht,e=>{c(L)?e(Ut):c(rt)&&!c(k)&&e(Wt,1)});var Gt=_(Ht,2),Kt=y(Gt),qt=e=>{var t=Ye(),n=y(t),r=e=>{var t=de(`No project file is open, so there is nothing for an agent to edit.`);l(e,t)},i=e=>{var t=de(`Say what the sketch should become. Drag in a node or a parameter for its exact path.`);l(e,t)};x(n,e=>{c(J)?e(i,-1):e(r)}),g(t),l(e,t)};x(Kt,e=>{c(N),m(()=>c(N).length===0)&&e(qt)});var Jt=_(Kt,2);a(Jt,1,()=>c(Le),o,(e,t)=>{var n=ne(),i=me(n),a=e=>{var n=Xe();r(n,()=>(re(Oe),c(t),m(()=>Oe(c(t).text))),!0),g(n),h(()=>s(n,1,`entry ${c(t),m(()=>c(t).kind)??``} markdown`,`svelte-1cqop5k`)),l(e,n)},o=se(()=>(c(t),m(()=>ze.has(c(t).kind)))),ee=e=>{var n=Ze(),r=f(n,!0);h(()=>{s(n,1,`entry ${c(t),m(()=>c(t).kind)??``}`,`svelte-1cqop5k`),u(r,(c(t),m(()=>c(t).text)))}),l(e,n)};x(i,e=>{c(o)?e(a):e(ee,-1)}),l(e,n)});var Yt=_(Jt,2),Xt=e=>{var t=Qe(),n=f(t);h(()=>u(n,`${c(P)?`Hide`:`Show`} ${c(A)??``} stream ${c(A)===1?`event`:`events`}`)),d(`click`,t,()=>b(P,!c(P))),l(e,t)};x(Yt,e=>{c(A)>0&&e(Xt)}),g(Gt),ue(Gt,e=>b(V,e),()=>c(V));var Zt=_(Gt,2),Qt=y(Zt),Q=y(Qt);let $t;var en=_(Q,2),tn=e=>{var t=$e(),n=f(t,!0);h(()=>u(n,(c(E),m(()=>c(E).id)))),l(e,t)};x(en,e=>{c(G)&&c(E)&&e(tn)}),g(Qt);var nn=_(Qt,2),$=y(nn);ie($),ue($,e=>b(H,e),()=>c(H));var rn=_($,2);g(nn),g(Zt),g(X),ue(X,e=>b(W,e),()=>c(W)),h(e=>{jt=s(X,1,`console svelte-1cqop5k`,null,jt,{"drop-active":c(U)}),t(X,`--agent-zoom: ${c(q)??``}`),Z.disabled=c(O),ve(Q,`aria-pressed`,c(G)),Q.disabled=!c(E)||c(O),$t=s(Q,1,`svelte-1cqop5k`,null,$t,{active:c(G)}),$.disabled=c(O),rn.disabled=e},[()=>(c(O),c(M),c(k),m(()=>c(O)||!c(M).trim()||!c(k)))]),_e(Z,()=>c(j),e=>b(j,e)),d(`click`,Q,()=>b(G,!c(G))),he($,()=>c(M),e=>b(M,e)),d(`keydown`,$,Ct),d(`input`,$,_t),d(`click`,rn,bt),d(`dragover`,X,Tt),d(`dragleave`,X,Et),d(`drop`,X,wt),l(i,X),n(),Ae()}export{tt as default};