@field/cascade 0.3.1 → 0.5.1
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.
- package/AGENTS.md +32 -9
- package/ARCHITECTURE.md +75 -13
- package/CHANGELOG.md +98 -1
- package/CONTRIBUTING.md +104 -0
- package/DESIGN.md +24 -15
- package/README.md +121 -14
- package/dist/assets/{CodeEditor-D22fVi-4.js → CodeEditor-dOrU3aQg.js} +7 -7
- package/dist/assets/{CodePanel-DPNEYfcR.js → CodePanel-Bqy85qen.js} +2 -2
- package/dist/assets/{CustomNodeDialog-DeHCAvgb.js → CustomNodeDialog-DkZlOgjs.js} +1 -1
- package/dist/assets/{ProjectSettings-DWpVtWEx.js → ProjectSettings-D192mr6g.js} +2 -2
- package/dist/assets/{SettingsDialog-za00IS3L.js → SettingsDialog-BTeeIE3T.js} +1 -1
- package/dist/assets/{VersionHistoryDialog-DTMGhI0_.js → VersionHistoryDialog-TZQKkn3Y.js} +1 -1
- package/dist/assets/{core-JsyKMO1k.js → core-DwbcGL0o.js} +2 -2
- package/dist/assets/{cssMode-emdRheFK.js → cssMode-Dcjn356x.js} +1 -1
- package/dist/assets/definitions-C_SY6Bhg.js +1 -0
- package/dist/assets/{editor.api-xHX-fMSo.js → editor.api-D7Q83606.js} +1 -1
- package/dist/assets/{freemarker2-C3M8_Gs3.js → freemarker2-DCCiHlV6.js} +1 -1
- package/dist/assets/geo-CT-wtvaE.js +1 -0
- package/dist/assets/{handlebars-CBMurtFk.js → handlebars-BCxC8xu1.js} +1 -1
- package/dist/assets/{html-xbLQwknw.js → html-COwepzSd.js} +1 -1
- package/dist/assets/{htmlMode-2wKdDTon.js → htmlMode-Dpg7H0rx.js} +1 -1
- package/dist/assets/{image-i1j6nWKe.js → image-CMfMMxlC.js} +3 -3
- package/dist/assets/index-De1cIZ9N.js +212 -0
- package/dist/assets/index-ilgbOu6G.css +1 -0
- package/dist/assets/{javascript-DJaOo_2I.js → javascript-CSwWxfLr.js} +1 -1
- package/dist/assets/{jsonMode-Bheas8_0.js → jsonMode-BXRriTpj.js} +1 -1
- package/dist/assets/{liquid-BCj_BGbM.js → liquid-Cmkfyogc.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-BfIsx_xz.js → lspLanguageFeatures-xH9JbZGO.js} +1 -1
- package/dist/assets/{mdx-DwiQDiVO.js → mdx-BzrNjNvK.js} +1 -1
- package/dist/assets/nodeTypeUtils-BDJsc2Ks.js +1 -0
- package/dist/assets/pop-BdKEHslJ.js +1 -0
- package/dist/assets/{python-BjrB5nqj.js → python-D4E9jbx7.js} +1 -1
- package/dist/assets/{razor-CfoBmGDs.js → razor-B3x9cIEM.js} +1 -1
- package/dist/assets/{tsMode-BcEoMSxp.js → tsMode-dhQYPNMZ.js} +1 -1
- package/dist/assets/{typescript-DIg7TEmQ.js → typescript-CITkDxAE.js} +1 -1
- package/dist/assets/{workers-vXYuwtPw.js → workers-BQvF9bbO.js} +1 -1
- package/dist/assets/{xml-DexLQIQy.js → xml-DvHlU3A8.js} +1 -1
- package/dist/assets/{yaml-DUnD_1dE.js → yaml-uznsLgs8.js} +1 -1
- package/dist/cli/index.js +16465 -12096
- package/dist/cli/runtime/gpu.ts +71 -0
- package/dist/cli/runtime/io.ts +31 -25
- package/dist/contracts/camera.d.ts +70 -0
- package/dist/contracts/camera.js +27 -0
- package/dist/contracts/capabilities.d.ts +6 -6
- package/dist/contracts/definition.d.ts +62 -4
- package/dist/contracts/index.d.ts +4 -0
- package/dist/contracts/index.js +4 -0
- package/dist/contracts/particles.d.ts +54 -0
- package/dist/contracts/particles.js +167 -0
- package/dist/contracts/scene.d.ts +129 -0
- package/dist/contracts/scene.js +73 -0
- package/dist/contracts/schema.js +26 -3
- package/dist/contracts/series.d.ts +75 -0
- package/dist/contracts/series.js +2 -0
- package/dist/contracts/validate.js +23 -5
- package/dist/contracts/values.d.ts +4 -2
- package/dist/contracts/values.js +10 -0
- package/dist/gpu.d.ts +17 -0
- package/dist/gpu.js +61 -1
- package/dist/index.html +3 -3
- package/dist/io.d.ts +4 -16
- package/dist/io.js +26 -8
- package/dist/player/app.js +810 -0
- package/dist/player/embed.d.ts +4 -0
- package/dist/player/embed.js +77 -0
- package/dist/player/types.d.ts +35 -0
- package/dist/runtime/builtins/core/camera.d.ts +252 -0
- package/dist/runtime/builtins/core/camera.js +149 -0
- package/dist/runtime/builtins/core/index.d.ts +4 -2
- package/dist/runtime/builtins/core/index.js +8 -2
- package/dist/runtime/builtins/core/structural.d.ts +168 -0
- package/dist/runtime/builtins/core/structural.js +175 -0
- package/dist/runtime/builtins/core/time.d.ts +165 -0
- package/dist/runtime/builtins/core/time.js +110 -0
- package/dist/runtime/builtins/geo/definitions.d.ts +247 -0
- package/dist/runtime/builtins/geo/definitions.js +70 -0
- package/dist/runtime/builtins/geo/index.d.ts +2 -1
- package/dist/runtime/builtins/geo/index.js +3 -1
- package/dist/runtime/builtins/geo/render.d.ts +87 -0
- package/dist/runtime/builtins/geo/render.js +87 -0
- package/dist/runtime/builtins/geo/svgExport.d.ts +11 -0
- package/dist/runtime/builtins/geo/svgExport.js +10 -0
- package/dist/runtime/builtins/index.d.ts +5 -2
- package/dist/runtime/builtins/index.js +13 -3
- package/dist/runtime/builtins/pop/definitions.d.ts +2120 -0
- package/dist/runtime/builtins/pop/definitions.js +815 -0
- package/dist/runtime/builtins/pop/index.d.ts +2 -0
- package/dist/runtime/builtins/pop/index.js +2 -0
- package/dist/runtime/builtins/scene/definitions.d.ts +356 -0
- package/dist/runtime/builtins/scene/definitions.js +224 -0
- package/dist/runtime/builtins/scene/index.d.ts +2 -0
- package/dist/runtime/builtins/scene/index.js +2 -0
- package/dist/runtime/camera/index.d.ts +60 -0
- package/dist/runtime/camera/index.js +234 -0
- package/dist/runtime/definition/architecture.js +36 -1
- package/dist/runtime/geometry/render.d.ts +109 -0
- package/dist/runtime/geometry/render.js +145 -0
- package/dist/runtime/geometry/svg.d.ts +29 -0
- package/dist/runtime/geometry/svg.js +11 -5
- package/dist/runtime/gpu.d.ts +33 -0
- package/dist/runtime/gpu.js +218 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.js +4 -0
- package/dist/runtime/pop/cache.d.ts +27 -0
- package/dist/runtime/pop/cache.js +123 -0
- package/dist/runtime/pop/forces.d.ts +202 -0
- package/dist/runtime/pop/forces.js +519 -0
- package/dist/runtime/pop/index.d.ts +5 -0
- package/dist/runtime/pop/index.js +5 -0
- package/dist/runtime/pop/state.d.ts +136 -0
- package/dist/runtime/pop/state.js +283 -0
- package/dist/runtime/pop/trail.d.ts +62 -0
- package/dist/runtime/pop/trail.js +142 -0
- package/dist/runtime/runtime.js +284 -9
- package/dist/runtime/scene/index.d.ts +50 -0
- package/dist/runtime/scene/index.js +94 -0
- package/dist/runtime/series/index.d.ts +41 -0
- package/dist/runtime/series/index.js +167 -0
- package/dist/runtime/types.d.ts +1 -1
- package/dist/studio/panel.d.ts +68 -1
- package/doc/HEADLESS_GPU.md +160 -0
- package/doc/NODE_REFERENCE.md +408 -1
- package/doc/PROJECT_AUTHORING.md +118 -20
- package/doc/WEB_PLAYER.md +131 -0
- package/package.json +25 -3
- package/dist/assets/geo-BAR6lQp5.js +0 -1
- package/dist/assets/index-BDV5xGBZ.css +0 -1
- package/dist/assets/index-CMcH8AgP.js +0 -212
- package/dist/assets/nodeTypeUtils-BBA1JqHx.js +0 -1
package/AGENTS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Cascade agent guide
|
|
2
2
|
|
|
3
|
-
Cascade is a reusable generative-design graph runtime with an optional Studio UI. Keep authored algorithms independent from the editor so
|
|
3
|
+
Cascade is a reusable generative-design graph runtime with an optional Studio UI. Keep authored algorithms independent from the editor so a graph can run in Studio, on a server, or in a UI-free browser host when its declared execution locus and capabilities are supported.
|
|
4
4
|
|
|
5
5
|
## Start here
|
|
6
6
|
|
|
@@ -37,6 +37,15 @@ my-project/
|
|
|
37
37
|
|
|
38
38
|
Use `cascade new <name>` to create a project and `cascade node <Name>` to scaffold a custom node in one. Run `cascade .` from a project root to open Studio, `cascade validate <graph.cascade>` for validation, `cascade check <graph.cascade>` for static definition/type checks, `cascade inspect <graph.cascade>` for a JSON summary, `cascade run <graph.cascade>` for headless execution, and `cascade run <graph.cascade> --frames 1-100` for an offline image sequence. `cascade projects` shows or sets the default projects directory.
|
|
39
39
|
|
|
40
|
+
`cascade build <graph.cascade> --out <new-directory>` exports a static browser
|
|
41
|
+
player. Use repeatable `--asset <project-relative-file>` for inputs whose paths
|
|
42
|
+
are computed in code. Read `doc/WEB_PLAYER.md` before exporting: server stages
|
|
43
|
+
and dynamic modules are not supported, assets must be explicit, and an existing
|
|
44
|
+
output directory is never overwritten. Serve the result over HTTP, not file://.
|
|
45
|
+
The player is an application host under `src/player`, not another graph engine.
|
|
46
|
+
Each embed owns an iframe realm, assets, IO bridge and GPU lifecycle. No Studio
|
|
47
|
+
imports or `/api/*` dependency may enter the static deployment.
|
|
48
|
+
|
|
40
49
|
## Launch Studio
|
|
41
50
|
|
|
42
51
|
For a browser on the same machine, use the secure loopback default:
|
|
@@ -73,7 +82,7 @@ Project panels are trusted Studio extensions, not graph/runtime modules. Put the
|
|
|
73
82
|
|
|
74
83
|
## Create a deterministic node
|
|
75
84
|
|
|
76
|
-
Two node styles exist and both are
|
|
85
|
+
Two node styles exist and both are supported. A **definition-v1** module exports a literal `definition` and a typed `execute(context)`; it is statically inspectable and is what `cascade check` requires. A **dynamic** module exports `execute(node, graph)` and declares its ports and parameters imperatively inside it. Studio cooks both through `src/nodes/definition/projectDefinition.ts`. The CLI supports stills and frame sequences for fully deterministic graphs and for supported dynamic graphs, but rejects graphs mixing the two execution styles. Prefer definition-v1 for new nodes; inspect a project's current modules before assuming its style. Do not call dynamic modules "legacy" in user-facing guidance.
|
|
77
86
|
|
|
78
87
|
A definition-v1 module looks like this:
|
|
79
88
|
|
|
@@ -107,6 +116,9 @@ Definition rules:
|
|
|
107
116
|
and have the host registration select the executor. Never expose execution
|
|
108
117
|
location as an artist parameter; parity-test the shared contract.
|
|
109
118
|
- Declare every capability used. File, Python, and shell access are server-only; WebGL is browser-only.
|
|
119
|
+
- `context.nodeId` identifies the instance for namespaces such as `cachePath(context.nodeId, '.png')`; it does not grant access to siblings or hierarchy. A final output may instead have an artist-authored filename.
|
|
120
|
+
- 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.
|
|
121
|
+
- 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.
|
|
110
122
|
- 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.
|
|
111
123
|
- 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.
|
|
112
124
|
- 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.
|
|
@@ -124,6 +136,7 @@ Use the runtime-native core vocabulary before creating a project wrapper:
|
|
|
124
136
|
- `cascade.core.Null` passes any value through unchanged so downstream wiring can remain stable while upstream branches are reorganized.
|
|
125
137
|
- `cascade.core.Random` maps explicit integer `seed` and `sample` inputs to a stable float in `[0, 1)`.
|
|
126
138
|
- `cascade.core.Remap` maps scalar ranges and optionally clamps via its `clamp` prop.
|
|
139
|
+
- `cascade.core.Camera` emits the one `camera` type, following Houdini's `/obj/cam`: `translate` and `rotate` (degrees, XYZ) with an optional `lookat`, and a lens given as `focal` and `aperture` in millimetres rather than as a field of view. A camera looks down its own **-Z** with **+Y** up. `resolution` is on the camera because Houdini derives the vertical aperture from the frame shape, and it is one `vec2i` rather than Houdini's `resx`/`resy` because the vec rule below is the more specific one. Every derivation — the basis, the view and projection matrices, the horizontal and vertical angles — lives in `packages/runtime/src/camera`; never derive them a second time in a renderer.
|
|
127
140
|
|
|
128
141
|
The geometry set is reserved the same way, under `cascade.geo.*`:
|
|
129
142
|
`Rectangle`, `Circle`, `Transform`, `Merge`, `CopyToPoints`, and `SvgExport`.
|
|
@@ -131,6 +144,15 @@ They all speak the one `geometry` type, so any output fits any input, and they
|
|
|
131
144
|
follow Houdini's parameter names where Houdini has an equivalent node. Geometry
|
|
132
145
|
is +Y up; the flip into SVG's frame lives in `SvgExport` alone.
|
|
133
146
|
|
|
147
|
+
`cascade.pop.*` uses geometry-native particle state; forces accumulate and the
|
|
148
|
+
solver integrates once. `cascade.core.Feedback` owns previous state and bounded
|
|
149
|
+
history, including nested loops. Trails are geometry, not a second canvas
|
|
150
|
+
history. A checkpoint is only an accelerator: cold and warm runs must match
|
|
151
|
+
complete geometry and trails. `cascade.scene.*` assembles geometry, camera and
|
|
152
|
+
lights; the current renderer draws wireframes/points and does not shade lights.
|
|
153
|
+
Read the generated reference for the complete library rather than extending
|
|
154
|
+
the partial vocabulary examples in this guide.
|
|
155
|
+
|
|
134
156
|
These modules are reserved and need no file under `nodes/`. Do not override a
|
|
135
157
|
`cascade.core.*` module or use ambient random/time state in a portable node.
|
|
136
158
|
Time and randomness reach a parameter as an expression or a keyframe channel,
|
|
@@ -146,13 +168,13 @@ type system knows what a `vec2` is; nothing tells it that `offset_x` and
|
|
|
146
168
|
|
|
147
169
|
## Animation, expressions, and parameters
|
|
148
170
|
|
|
149
|
-
- **`
|
|
171
|
+
- **`resolvePropBinding` in `packages/runtime/src/params/resolve.ts` owns binding precedence:** channel, expression, value. Studio's `Node.evalParm` and the neutral runtime both call it with their own expression scope and frame. Never read `prop.value` to obtain an animated parameter or implement a second precedence rule.
|
|
150
172
|
- **A parameter is one store.** `param()` declares the parameter; the value, the expression and the channel live in the prop of the same name. `NodeParameter.value` reads *resolved*; `rawParameterValue()` reads what the author typed, and is what serialization and cache keys must use. `param()` is re-declared on every cook of a dynamic node, so it must stay idempotent — it may never reset a value, an expression, or a channel.
|
|
151
173
|
- **Mechanisms belong to the runtime, composition to the host.** `packages/runtime/src/expressions` owns preprocessing, scope and the maths library; `packages/runtime/src/animation` owns the channel model, sampling, interpolation, serialization and frame-range walking. Both depend only on contracts. Do not implement interpolation, a frame clock, or a second `$T` anywhere else.
|
|
152
174
|
- **The serialized shape is owned by contracts** (`packages/contracts/src/animation.ts`): a channel is `{ keys: [{ frame, value, interpolation? }] }` inside the node's `props`, with `interpolation` omitted when it is the `smooth` default. There is no timeline section in the document, and adding one would need reconciling on every rename, delete and embed.
|
|
153
175
|
- Bare trigonometry is **radians**, deliberately unlike Houdini; `sind`/`cosd`/`tand`/`radians()`/`degrees()` exist for formulae carried over. Only `ch()`, `chs()` and `chv()` are scanned for dependencies, so a new way to reach another parameter also needs a dependency pattern or it will not recook.
|
|
154
|
-
- The deterministic runtime
|
|
155
|
-
- Studio's timeline
|
|
176
|
+
- The deterministic runtime resolves parameter animation through `setFrame`, `setFps`, and `run({ frame, fps })`. `cascade run --frames` supports fully definition-v1 graphs when the Node host can supply their capabilities. A browser-only node still cannot run in that host.
|
|
177
|
+
- Studio's timeline supplies the playhead and fps to the engine; its range and loop setting are panel state. Parameter channels are saved in the document, but playback settings are not.
|
|
156
178
|
|
|
157
179
|
## Agent sessions
|
|
158
180
|
|
|
@@ -178,7 +200,7 @@ type system knows what a `vec2` is; nothing tells it that `offset_x` and
|
|
|
178
200
|
- Contracts have no runtime dependencies.
|
|
179
201
|
- Runtime depends only on contracts and contains no DOM, Svelte, Express, Node filesystem, or child-process imports.
|
|
180
202
|
- Hosts inject capabilities explicitly.
|
|
181
|
-
- Studio
|
|
203
|
+
- Studio uses `StudioGraphController` over its compatibility `Graph`/`Node` engine and reuses runtime mechanisms. Custom frontends consume the neutral runtime directly; full Studio migration remains incomplete.
|
|
182
204
|
- User modules are trusted project code, not a sandbox. Static definitions improve tooling and portability, not isolation.
|
|
183
205
|
- Keep legacy support inside the existing Studio/CLI compatibility engine; do not spread compatibility branches into the deterministic runtime.
|
|
184
206
|
|
|
@@ -198,9 +220,10 @@ Do not add dependencies without a concrete need. Do not create extra packages un
|
|
|
198
220
|
|
|
199
221
|
## Versioning
|
|
200
222
|
|
|
201
|
-
Cascade `0.2.0` is the 2026 architecture rework
|
|
202
|
-
|
|
203
|
-
|
|
223
|
+
Cascade `0.2.0` is the 2026 architecture rework; `0.3.0` added animation and the
|
|
224
|
+
agent console. Read `package.json` for the checkout version and `CHANGELOG.md`
|
|
225
|
+
for release history and unreleased changes; a local build can contain changes
|
|
226
|
+
not yet in the published package. Update the changelog before a release commit. Increment the
|
|
204
227
|
root package and CLI patch version for every committed feature or release
|
|
205
228
|
change, keeping `package.json`, the lockfile, and CLI output aligned. A minor
|
|
206
229
|
bump is for a feature large enough to need its own `CHANGELOG.md` section.
|
package/ARCHITECTURE.md
CHANGED
|
@@ -20,18 +20,19 @@ Contracts contain no DOM, Svelte, Express, filesystem, process, or implementatio
|
|
|
20
20
|
|
|
21
21
|
The runtime is environment-neutral. It works in Node and browsers without importing either platform’s APIs, and it never imports Studio. Registration is sealed after the first graph load. Each graph permits one active run and has explicit lifecycle states.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
Reserved built-ins are registered once in `packages/runtime/src/builtins`:
|
|
24
|
+
core hierarchy/routing/time/camera, geometry operations, particle simulation,
|
|
25
|
+
and scene assembly. They need no project module file. The generated
|
|
26
|
+
[node reference](doc/NODE_REFERENCE.md) owns the complete port/parameter list.
|
|
27
|
+
Named, typed root Input/Output nodes form the public graph interface; child
|
|
28
|
+
Input/Output nodes form a subnet interface. Randomness takes an authored seed.
|
|
28
29
|
|
|
29
30
|
## Hosts
|
|
30
31
|
|
|
31
32
|
Hosts adapt the neutral runtime to an environment:
|
|
32
33
|
|
|
33
|
-
- Node: files, assets, media, Python, and
|
|
34
|
-
- Browser: assets, media, and
|
|
34
|
+
- Node: files, assets, media, Python, shell, and optional Dawn WebGPU in the CLI.
|
|
35
|
+
- Browser: assets, media, and the `gpu` capability when WebGPU is available.
|
|
35
36
|
- Mixed application: an explicit bridge for serializable server stages.
|
|
36
37
|
|
|
37
38
|
Capabilities are injected. A node’s literal `runsOn` and `capabilities` fields are checked before its `execute` module is loaded.
|
|
@@ -44,11 +45,19 @@ resize, composite, and encode when both Canvas/WebGL and native implementations
|
|
|
44
45
|
exist. Both executors must obey the same definition and should share golden
|
|
45
46
|
parity tests for geometry, metadata, and edge cases.
|
|
46
47
|
|
|
48
|
+
`packages/runtime/src/gpu.ts` owns shared device/cache lifecycle with an injected
|
|
49
|
+
acquisition function. Studio acquires browser WebGPU; `src/cli/headlessGpu.ts`
|
|
50
|
+
loads optional Dawn lazily. The runtime awaits readiness and supplies a per-node
|
|
51
|
+
view; the application owns disposal. `cascade/gpu` supplies explicit RGBA8
|
|
52
|
+
readback without encoding or colour conversion. Graph ports still exchange
|
|
53
|
+
images; GPU-resident intermediate connections remain future work. See
|
|
54
|
+
[headless GPU rendering](doc/HEADLESS_GPU.md).
|
|
55
|
+
|
|
47
56
|
`server/` is the project-scoped Node application host. It owns project paths, compilation, HTTP transport, media serving, Python workers, shell policy, and credentials. It is separately manifested and is not a third contracts/runtime workspace.
|
|
48
57
|
|
|
49
58
|
## Applications and controllers
|
|
50
59
|
|
|
51
|
-
Studio’s Svelte components under `src/editor` own rendering, selection, panels, and interaction state. Its compatibility graph now has one graph-owned cook scheduler, while `StudioGraphController` centralizes an increasing set of structural mutations and publishes view snapshots. Compatibility adapters still present runtime-owned built-ins in Studio; collapse/extract and the remaining
|
|
60
|
+
Studio’s Svelte components under `src/editor` own rendering, selection, panels, and interaction state. Its compatibility graph now has one graph-owned cook scheduler, while `StudioGraphController` centralizes an increasing set of structural mutations and publishes view snapshots. Compatibility adapters still present runtime-owned built-ins in Studio; collapse/extract and the remaining dynamic compatibility nodes must migrate before Studio can consume `packages/runtime` directly.
|
|
52
61
|
|
|
53
62
|
Studio uses Dockview through the public `dockview` API. Code panels lazy-load
|
|
54
63
|
Monaco and its native editor/TypeScript workers rather than adding Monaco to the
|
|
@@ -59,9 +68,12 @@ Custom server applications and browser frontends use `cascade/runtime` directly
|
|
|
59
68
|
|
|
60
69
|
## Distribution
|
|
61
70
|
|
|
62
|
-
The repository has exactly two internal npm workspaces: `@cascade/contracts` and `@cascade/runtime`. The root
|
|
71
|
+
The repository has exactly two internal npm workspaces: `@cascade/contracts` and `@cascade/runtime`. The root `@field/cascade` package, normally installed under the alias `cascade` in projects, is the only published package and executable owner.
|
|
63
72
|
|
|
64
|
-
Public subpaths
|
|
73
|
+
Public subpaths include contracts/schema, runtime and its Node/browser,
|
|
74
|
+
expression, animation, camera, render, scene and definition-extraction entries,
|
|
75
|
+
plus `cascade/io`, `cascade/gpu`, `cascade/net`, `cascade/stage`,
|
|
76
|
+
`cascade/shell`, and `cascade/player`. `package.json` is the exact export map.
|
|
65
77
|
|
|
66
78
|
Studio-only project extensions use the type-only `cascade/studio/panel` contract. They are compiled and loaded only by Studio; the neutral runtime and headless hosts never discover or import them.
|
|
67
79
|
|
|
@@ -113,15 +125,57 @@ Data runs follow graph dependencies. Explicit triggers use a FIFO queue, authore
|
|
|
113
125
|
|
|
114
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.
|
|
115
127
|
|
|
128
|
+
### Geometry, simulation and feedback
|
|
129
|
+
|
|
130
|
+
Geometry is a shared typed value with point/vertex/primitive attributes,
|
|
131
|
+
topology and groups, not an editor object. POP uses that same value for
|
|
132
|
+
particle state. Forces accumulate acceleration; the solver integrates once
|
|
133
|
+
per timestep. Trails are geometry and can feed the ordinary render/export nodes.
|
|
134
|
+
|
|
135
|
+
`cascade.core.Feedback` is an explicit stateful container within the data DAG.
|
|
136
|
+
Its children run per step; nested Feedback owns its own descendants. Previous
|
|
137
|
+
state and bounded history are wired values, not sibling lookups. Result and
|
|
138
|
+
history use normal output staging and cancellation, with transient loop state
|
|
139
|
+
released even when a child throws.
|
|
140
|
+
|
|
141
|
+
POP checkpoints accelerate deterministic re-simulation; clearing them must not
|
|
142
|
+
change particles **or trails**. The sparse derived cache is module-local, has a
|
|
143
|
+
64-checkpoint bound across keys, and copies snapshots at its boundary. It does
|
|
144
|
+
not define simulation state. CLI `--frames` already reuses a loaded runtime,
|
|
145
|
+
so it can benefit from checkpoints within the sequence. Separate CLI launches
|
|
146
|
+
do not share that cache.
|
|
147
|
+
|
|
148
|
+
A `scene` contains geometry, an optional camera and lights. A missing camera
|
|
149
|
+
means the viewer supplies its view; an explicit render requires an authored
|
|
150
|
+
camera. The current shared CPU renderer draws wireframes and points, not lit
|
|
151
|
+
surfaces. Camera derivations belong to `packages/runtime/src/camera`; Studio's
|
|
152
|
+
3D view and offline rendering use that convention rather than separate matrices.
|
|
153
|
+
|
|
154
|
+
### Browser player
|
|
155
|
+
|
|
156
|
+
The player is a browser application host under `src/player`, not another graph
|
|
157
|
+
engine or package. Static export compiles definition-v1 project modules into
|
|
158
|
+
browser ESM and supplies assets locally. Studio, Python, shell and project
|
|
159
|
+
server routes are not deployment dependencies. Unsupported server operations
|
|
160
|
+
fail explicitly during export. See [browser player](doc/WEB_PLAYER.md) for the
|
|
161
|
+
build/embed contract and current limitations.
|
|
162
|
+
|
|
163
|
+
Each embed has its own iframe realm, runtime, IO bridge, assets and GPU host.
|
|
164
|
+
This isolates existing ambient `cascade/io` imports without swapping global
|
|
165
|
+
transports between asynchronous runs. Shared browser GPU acquisition lives in
|
|
166
|
+
`src/browser/gpu.ts`, also used by Studio. A future migration to explicit
|
|
167
|
+
capability-only IO could permit direct DOM mounts; that is not implemented by
|
|
168
|
+
the iframe player.
|
|
169
|
+
|
|
116
170
|
## Animation
|
|
117
171
|
|
|
118
|
-
A parameter carries up to three bindings: a raw value, an expression, and a keyframe channel.
|
|
172
|
+
A parameter carries up to three bindings: a raw value, an expression, and a keyframe channel. `packages/runtime/src/params/resolve.ts` owns their shared resolution rule: channel, expression, value. A channel that samples takes precedence and leaves the expression stored but inert, so emptying the channel restores it. Studio invokes the resolver from `Node.evalParm`; the deterministic runtime invokes it through `PropAnimator`. Nothing else in Studio may read a prop's `value` directly to obtain an animated parameter; a second rule is how an expression badge and a viewer disagree about the same frame.
|
|
119
173
|
|
|
120
|
-
The mechanisms are runtime-owned and the composition is
|
|
174
|
+
The mechanisms are runtime-owned and the composition is host-specific. `packages/runtime/src/expressions` owns preprocessing (`$F`, `$FF`, `$T`, `$FPS` rewritten to plain identifiers), the evaluation scope, and the maths library; `packages/runtime/src/animation` owns the channel model, sampling, interpolation, serialization, and frame-range walking; `packages/runtime/src/params` owns binding resolution and deterministic graph-wide animation. These modules depend only on contracts or other runtime modules. Studio supplies its compatibility graph scope, while `PropAnimator` supplies the neutral runtime scope, including lazy `ch()` dependency resolution.
|
|
121
175
|
|
|
122
176
|
`packages/contracts/src/animation.ts` owns the serialized shape. A channel lives inside the node's `props`, not in a separate timeline object, because a parameter's animation belongs to the parameter; a document with a timeline section would need reconciling every time a node was renamed, deleted, or embedded.
|
|
123
177
|
|
|
124
|
-
The deterministic runtime has
|
|
178
|
+
The deterministic runtime has parameter animation and an explicit graph clock. `setFrame(frame)` and `setFps(fps)` re-resolve bound props without cooking, so inspection can scrub deterministically. `run({ frame, fps })` resolves every bound prop before node execution; the same graph at the same authored state, frame, and fps receives the same parameter values. `cascade run --frames` uses this path for definition-v1 graphs and passes each requested frame and fps into the run. The runtime never reads wall-clock time.
|
|
125
179
|
|
|
126
180
|
## Agent sessions
|
|
127
181
|
|
|
@@ -139,6 +193,14 @@ Document freshness is a watcher, not a poll of the agent. `server/src/graphWatch
|
|
|
139
193
|
|
|
140
194
|
Project node modules are trusted code. Capabilities describe support and portability; they are not a sandbox.
|
|
141
195
|
|
|
196
|
+
Studio binds to loopback by default. Remote access requires a specific
|
|
197
|
+
hostname or private interface address via `--host`; wildcard remote binds are
|
|
198
|
+
rejected. That non-loopback host becomes the default trusted browser hostname,
|
|
199
|
+
and repeatable `--trusted-host` values add exact browser authorities when the
|
|
200
|
+
bind address and public hostname differ, including a reverse proxy to a
|
|
201
|
+
loopback bind. Every reachable peer on that trusted interface can access the
|
|
202
|
+
project APIs, so this mode is intended for an authenticated VPN or trusted LAN.
|
|
203
|
+
|
|
142
204
|
All project HTTP APIs require an exact allowed Host. Origin is validated when
|
|
143
205
|
present and hostile or null Origins are rejected; same-origin GETs may omit it.
|
|
144
206
|
Filesystem resolution checks lexical paths and canonical existing targets or
|
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,69 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes to Cascade. Newest first.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 0.5.1 — 2026-09-09
|
|
6
|
+
|
|
7
|
+
- Prepared the 0.5 browser-player release for npm, with updated README and
|
|
8
|
+
cascade.field.io documentation covering web embeds, geometry, subnets,
|
|
9
|
+
particles, Feedback, scenes, animation and bounded Dawn renders for agents.
|
|
10
|
+
- Clarified browser/server execution limits, current wireframe/point rendering,
|
|
11
|
+
explicit asset packaging and same-origin player controls. The npm homepage
|
|
12
|
+
now points to cascade.field.io.
|
|
13
|
+
|
|
14
|
+
## 0.5.0 — 2026-09-09
|
|
15
|
+
|
|
16
|
+
### Browser player
|
|
17
|
+
|
|
18
|
+
- `cascade build <graph> --out <new-directory>` exports definition-v1 graphs as
|
|
19
|
+
static pages with a lightweight iframe embed API. Browser execution supports
|
|
20
|
+
assets and WebGPU; server capabilities and dynamic modules are rejected at
|
|
21
|
+
build time. No Studio server is required. See [Web player](doc/WEB_PLAYER.md).
|
|
22
|
+
- Each embed owns its runtime, IO bridge and generated assets. Playback and
|
|
23
|
+
edits serialize, failed cooks pause playback, and disposal releases resources.
|
|
24
|
+
Generated images have immutable paths and explicit retention limits.
|
|
25
|
+
- Browser image loading now decodes bridged assets correctly, including SVG
|
|
26
|
+
bitmaps. Studio and the player share browser GPU acquisition.
|
|
27
|
+
|
|
28
|
+
### Runtime correctness and performance
|
|
29
|
+
|
|
30
|
+
- POP checkpoint caching enforces its 64-entry bound even for one simulation,
|
|
31
|
+
copies mutable particle state at the boundary, and replays the trail window
|
|
32
|
+
so warm and cold renders agree. Malformed field and trail data report errors.
|
|
33
|
+
- Nested Feedback runs children only in their owning loop, orders dependencies
|
|
34
|
+
across container boundaries, publishes history consistently, and clears
|
|
35
|
+
transient state after failures or cancellation.
|
|
36
|
+
|
|
37
|
+
### Documentation and verification
|
|
38
|
+
|
|
39
|
+
- Updated architecture, authoring and agent guides for geometry, simulations,
|
|
40
|
+
scenes and static deployment. Added real-browser embed and packed-consumer
|
|
41
|
+
checks alongside focused runtime and IO regressions.
|
|
42
|
+
- Retired archived Quill examples with a recoverable backup; removed incidental
|
|
43
|
+
Quill examples from current guidance while retaining removed-node rejection tests.
|
|
44
|
+
- Streamlined shared player image decoding, MIME inference and cleanup error
|
|
45
|
+
handling without changing the public player contract.
|
|
46
|
+
- Removed unused Studio component props and consolidated CLI execution-style
|
|
47
|
+
checks. Empty/dynamic fallback and mixed-graph rejection remain unchanged.
|
|
48
|
+
- Deleted the unreachable WindowManager UI and its private window/tab components;
|
|
49
|
+
Dockview remains Studio's sole layout host. Removed the commented-out Canvas
|
|
50
|
+
sample initializer. The active Graph/Node compatibility engine is unchanged.
|
|
51
|
+
|
|
52
|
+
## 0.4.0 — 2026-09-09
|
|
53
|
+
|
|
54
|
+
### Documentation
|
|
55
|
+
|
|
56
|
+
- Updated current guides and generated project instructions for definition-v1
|
|
57
|
+
animation, stored `props`, instance identity, vector metadata, and the shared
|
|
58
|
+
GPU capability. Clarified host requirements, Studio's remaining runtime
|
|
59
|
+
migration, export limitations, and the distinction between implemented
|
|
60
|
+
workflows and future product directions.
|
|
61
|
+
|
|
62
|
+
### Animation
|
|
63
|
+
|
|
64
|
+
- The deterministic runtime resolves expressions and keyframe channels at an
|
|
65
|
+
explicit frame through the shared parameter resolver. `cascade run --frames`
|
|
66
|
+
can render fully definition-v1 graphs with compatible Node-host capabilities;
|
|
67
|
+
mixed definition-v1/dynamic graphs remain unsupported by the CLI.
|
|
6
68
|
|
|
7
69
|
### Node authoring
|
|
8
70
|
|
|
@@ -27,6 +89,41 @@ Notable changes to Cascade. Newest first.
|
|
|
27
89
|
|
|
28
90
|
- **The CLI build resolves `@cascade/runtime/params`.** `src/nodes/Node.ts` imports `resolvePropBinding` from it, the browser build resolved it through `vite.config.ts`, and the CLI build had no alias — so the CLI, which is what the sketches actually run, was the broken half.
|
|
29
91
|
|
|
92
|
+
### Camera
|
|
93
|
+
|
|
94
|
+
- **A camera is a core type, and it is Houdini's camera.** `camera` joins `CORE_TYPES`, `cascade.core.Camera` emits one, and every derivation — basis, view and projection matrices, horizontal and vertical angle — lives in `cascade/runtime/camera` so no renderer derives it twice. Following `/obj/cam` costs the two things the obvious design would have done instead: there is **no field of view** (`focal` and `aperture` in millimetres, angle derived — Houdini's 50 mm on 41.4214 mm is exactly 45°), and the orientation is **`translate` and `rotate`** rather than eye-and-target, looking down its own **-Z** with **+Y** up, with look-at layered on top as an override. `resolution` is on the camera because Houdini derives the vertical aperture from the frame shape; it is one `vec2i` rather than `resx`/`resy` because the vec rule is the more specific one. Matching a frame is therefore always one number, never two.
|
|
95
|
+
- `rotate.z` is a roll about the camera's own view direction. The first two rotation orders tried were indistinguishable from this one by every test in the suite — with `rotate.z` at zero all three agree exactly — so the test that separates them asserts that roll changes the up and leaves the view direction alone.
|
|
96
|
+
|
|
97
|
+
### Series
|
|
98
|
+
|
|
99
|
+
- **A series is a graph plus an ordered list of parameter sets** (`CascadeSeries`, `runSeries`), cooked once per set and addressed by **record id, never index**, because a filter change reorders a set and a judgement pinned to a position silently becomes a different picture. `CascadePreset` and `applyPreset` already were the parameter set and had no callers. There is no marked region: the affected subgraph is derived from the overrides, so nothing can be marked wrongly.
|
|
100
|
+
- A parameter set is **sparse**, so every instance cooks from a baseline captured before the first `applyPreset` — otherwise an instance that overrides nothing inherits the previous one's values, which is accidental feedback in a mechanism specified as having none, and it presents as a flaky renderer rather than as a bug. `first` reorders the work and never the results, so a gallery fills in as instances land without the list reshuffling under a selection.
|
|
101
|
+
|
|
102
|
+
### Capabilities
|
|
103
|
+
|
|
104
|
+
- **Studio can reach the shell.** The server has had an allowlist-gated `/api/shell` for a while and Studio never wired it as a node capability, so a definition declaring `capabilities: ['shell']` ran through `cascade run` and threw in the browser — a node marked `runsOn: 'portable'` that runs in one host is what `runsOn` exists to prevent. A `CascadeAbortSignal` is bridged to a DOM one rather than serialised; a 403 re-handshakes exactly once and then reports, naming the Allowed Commands editor rather than a status code.
|
|
105
|
+
|
|
106
|
+
### Correctness
|
|
107
|
+
|
|
108
|
+
- **A `vec3` prop stays a `vec3`.** `isColorValue` answers true for any three- or four-number array and the deserialise path had no `type === 'color'` guard, so every vector prop in every sketch was rewritten on load — `[0.55, 0.12, 1.95]` reached `execute` as a colour object, coerced and divided by 255. A guard existed one branch away and never ran, because a **project** module's definition arrives asynchronously and `node.parameters` is empty at load. Coercion is now decided by ambiguity: objects and strings still normalise, arrays only where the prop is already declared a colour.
|
|
109
|
+
- **An error in the log says what it is.** The Log panel `JSON.stringify`s any object and `Error.message` is non-enumerable, so a `TypeError` and a `GPUPipelineError` were equally invisible as `{}`.
|
|
110
|
+
- **Selecting a failing node no longer cooks it forever.** The Viewer's rAF pump is throttled to 100 ms and polls its watched node while dirty; an execute that throws never reaches `clean`, so it ran a full `scheduler.flush()` ten times a second, re-fetching inputs over the network, at 61 fps and never looking wrong. `Node.hasSettledFailure` is what the poll now skips — deliberately not folded into `isDirty`, because an explicit `requestOutput` still retries and that is the transient GPU and network case.
|
|
111
|
+
- **Renaming a node is a double click.** The name label sits in the middle of the node body and a single click opened the rename editor, so aiming at a node to select it renamed it instead, in memory only and discarded on reload.
|
|
112
|
+
- **A proxied Studio can save.** `https` origins are accepted and default ports matched, so a reverse-proxied or Tailscale-served Studio can POST — which is also what unblocks WebGPU, the clipboard and the microphone, all of which need a secure context.
|
|
113
|
+
|
|
114
|
+
### Headless GPU
|
|
115
|
+
|
|
116
|
+
- Optional pinned Dawn (`webgpu@0.6.0`) in the CLI, loaded only for GPU execution.
|
|
117
|
+
Browser and Node hosts reuse shared device/cache lifecycle; portable and server
|
|
118
|
+
definitions may declare `gpu`. Browser-only nodes remain browser-only.
|
|
119
|
+
- Explicit `cascade/gpu` RGBA8 texture readback, with padded-row removal and
|
|
120
|
+
cancellation cleanup. Graph texture transport remains outside this stage.
|
|
121
|
+
- `run --frames ... --json` returns an image manifest and adapter metadata;
|
|
122
|
+
`--timeout <ms>` runs a supervised render process for agent/test callers.
|
|
123
|
+
Dedicated opt-in hardware and packed-package gates exercise real GPU output.
|
|
124
|
+
- Documented the decision, local/unreleased status, CLI manifest contract,
|
|
125
|
+
verification evidence and platform limits in [Headless GPU](doc/HEADLESS_GPU.md).
|
|
126
|
+
|
|
30
127
|
## 0.3.1
|
|
31
128
|
|
|
32
129
|
### Fixed
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Contributing to Cascade
|
|
2
|
+
|
|
3
|
+
Cascade is a free, MIT-licensed creative graph platform. Contributions can be
|
|
4
|
+
bug reports, reproducible sketches, documentation, tests, or code. Core
|
|
5
|
+
development does not require an AI provider or a paid service account.
|
|
6
|
+
|
|
7
|
+
## Find the owning layer
|
|
8
|
+
|
|
9
|
+
Read [AGENTS.md](AGENTS.md) for repository conventions, [DESIGN.md](DESIGN.md)
|
|
10
|
+
for product decisions, and [ARCHITECTURE.md](ARCHITECTURE.md) for dependencies.
|
|
11
|
+
|
|
12
|
+
- `packages/contracts/` owns public types and serialized formats.
|
|
13
|
+
- `packages/runtime/` owns environment-neutral execution mechanisms.
|
|
14
|
+
- `server/` owns project files, compilation, processes, and host transports.
|
|
15
|
+
- `src/editor/` owns Studio interactions and presentation.
|
|
16
|
+
- `src/player/` owns the standalone browser host and embed controls.
|
|
17
|
+
- Sketch repositories own creative algorithms, providers, and project panels.
|
|
18
|
+
|
|
19
|
+
Keep provider SDKs and client-specific data in projects. Do not add dependencies
|
|
20
|
+
or packages without a demonstrated need and an agreed scope.
|
|
21
|
+
|
|
22
|
+
## Develop and verify
|
|
23
|
+
|
|
24
|
+
Use Node.js 22.13 or newer. Install dependencies with `npm install`; the core
|
|
25
|
+
uses TypeScript 6. `npm run dev` starts the Studio development frontend.
|
|
26
|
+
Project-host workflows are exercised through a built CLI and a project folder.
|
|
27
|
+
|
|
28
|
+
Add a focused regression test for a behavior change, make the smallest change
|
|
29
|
+
at the owning layer, and run that test first. Use the applicable repository gates:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm run check
|
|
33
|
+
npm run test:run
|
|
34
|
+
npm --prefix server run build
|
|
35
|
+
npm run build
|
|
36
|
+
npm run build:cli
|
|
37
|
+
git diff --check
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`npm run build` also runs `build:cli` through its postbuild hook. Keep a final
|
|
41
|
+
CLI build after any separate Vite build because Vite refreshes `dist/`. Coordinate
|
|
42
|
+
rebuilds when running Studio servers serve from that checkout.
|
|
43
|
+
Do not run package builds concurrently with tests that read generated package
|
|
44
|
+
files: the builds replace those directories while tests may be importing them.
|
|
45
|
+
|
|
46
|
+
For public API or packaging changes, run `npm run test:package`, which exercises
|
|
47
|
+
the packed distribution from a temporary consumer. Built-in node-definition or
|
|
48
|
+
registry changes also require `npm run build:node-reference`; include its result.
|
|
49
|
+
|
|
50
|
+
For player changes, run `npm run test:player` after building the CLI. It opens
|
|
51
|
+
an isolated headless Chrome profile and checks actual pixels, multiple embeds,
|
|
52
|
+
playback and disposal on a static server. Set `CASCADE_CHROME` to the Chrome
|
|
53
|
+
executable on non-macOS systems. `CASCADE_TEST_PLAYER=1 npm run test:package`
|
|
54
|
+
also runs that proof against the installed tarball. GPU package verification
|
|
55
|
+
is opt-in separately with `CASCADE_TEST_DAWN=1`.
|
|
56
|
+
|
|
57
|
+
For prose-only changes, verify source claims, links, examples, and diff hygiene.
|
|
58
|
+
When changing generated project instructions in `server/src/projectTemplate.ts`,
|
|
59
|
+
also run `npx --no-install vitest run tests/project-template.test.ts`.
|
|
60
|
+
|
|
61
|
+
## Report useful evidence
|
|
62
|
+
|
|
63
|
+
A bug report should identify the Cascade version and whether it is a published
|
|
64
|
+
package or local checkout, the host/browser and relevant GPU, the smallest
|
|
65
|
+
reproducing graph, and expected versus observed output. Include safe fixtures
|
|
66
|
+
instead of credentials or private client data. A static check passing is not
|
|
67
|
+
proof that a graph rendered successfully.
|
|
68
|
+
|
|
69
|
+
For visual changes, preserve the inputs, seed, frame/fps, dimensions, and code
|
|
70
|
+
revision used for comparison. Compare decoded pixels or geometry where useful;
|
|
71
|
+
file size and image-wide averages do not establish visual equivalence.
|
|
72
|
+
|
|
73
|
+
## Documentation and releases
|
|
74
|
+
|
|
75
|
+
Update current instructions alongside behavior changes. Keep historical notes
|
|
76
|
+
dated and mark proposals as unimplemented. Update the root
|
|
77
|
+
[CHANGELOG.md](CHANGELOG.md); `spec/CHANGELOG.md` preserves earlier history.
|
|
78
|
+
Never edit the generated [node reference](doc/NODE_REFERENCE.md) by hand.
|
|
79
|
+
|
|
80
|
+
Release/version rules live in [AGENTS.md](AGENTS.md). Publishing and deployment
|
|
81
|
+
are separate maintainer actions; a documentation update does not publish a release.
|
|
82
|
+
|
|
83
|
+
With an explicit release request, update the README, feature guides, changelog,
|
|
84
|
+
root package/lock version and `site/index.html` together. Run the checks above
|
|
85
|
+
and `CASCADE_TEST_PLAYER=1 CASCADE_TEST_DAWN=1 npm run test:package` on a supported
|
|
86
|
+
GPU machine before publishing. The packed test checks a fresh consumer, browser
|
|
87
|
+
embeds, native GPU output and the optional-renderer-absent path.
|
|
88
|
+
|
|
89
|
+
The public package is `@field/cascade` (`npm publish --access public`). Check
|
|
90
|
+
`npm whoami` and `npm view @field/cascade dist-tags` first; verify the published
|
|
91
|
+
version and a fresh installation afterward. Git push, npm publication and the
|
|
92
|
+
website deployment are separate operations, not an automatic release pipeline.
|
|
93
|
+
|
|
94
|
+
The documentation website is the static **`site/` directory**, not Studio's
|
|
95
|
+
`dist/`. Its existing Vercel project is `field-io/cascade`:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
vercel link --cwd site --project cascade --scope field-io --yes
|
|
99
|
+
vercel deploy --cwd site --scope field-io --prod --yes
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Confirm the linked project before deployment and check `https://cascade.field.io`
|
|
103
|
+
afterward. Do not deploy the repository root or expose a Studio server as the
|
|
104
|
+
public site. `.vercel` is local deployment metadata and stays ignored.
|
package/DESIGN.md
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
## Source of truth
|
|
4
4
|
|
|
5
5
|
- Status: Active
|
|
6
|
-
- Last refreshed: 2026-09-
|
|
7
|
-
- Primary product surfaces: reusable graph runtime, optional Studio workbench, headless Node/browser hosts, Inspector, Viewer, Timeline, agent console, node ports, project-defined workbenches
|
|
8
|
-
- Evidence reviewed: `VISION.md`, `ARCHITECTURE.md`, `CHANGELOG.md`, `spec/CASCADE_SUBNET_AND_SHELL_SPEC.md`, `src/types/coreTypes.ts`, `src/editor/Inspector.svelte`, `src/editor/Viewer.svelte`, `src/editor/panels/TimelinePanel.svelte`, `src/editor/panels/AgentPanel.svelte`, `src/editor/components/PortEditor.svelte`, `src/editor/components/typeRenderers.ts`, `packages/runtime/src/expressions/`, `packages/runtime/src/animation/`, `server/src/agent/`, and
|
|
6
|
+
- Last refreshed: 2026-09-09 (0.4.0 checkout; player work is unreleased)
|
|
7
|
+
- Primary product surfaces: reusable graph runtime, optional Studio workbench, headless Node/browser hosts, static browser player, Inspector, 2D/3D Viewer, Timeline, agent console, node ports, project-defined workbenches
|
|
8
|
+
- Evidence reviewed: `VISION.md`, `ARCHITECTURE.md`, `CHANGELOG.md`, `spec/CASCADE_SUBNET_AND_SHELL_SPEC.md`, `src/types/coreTypes.ts`, `src/editor/Inspector.svelte`, `src/editor/Viewer.svelte`, `src/editor/panels/TimelinePanel.svelte`, `src/editor/panels/AgentPanel.svelte`, `src/editor/components/PortEditor.svelte`, `src/editor/components/typeRenderers.ts`, `src/browser/gpu.ts`, `src/player/`, `packages/runtime/src/runtime.ts`, `packages/runtime/src/params/`, `packages/runtime/src/expressions/`, `packages/runtime/src/animation/`, `server/src/agent/`, `server/src/security.ts`, and `server/src/cliCommands.ts`
|
|
9
|
+
|
|
10
|
+
This document contains both current product rules and intended direction. Sections labelled **Current** describe implemented behavior in the repository. Sections labelled **Target** or **Planned** describe design direction and are not a release commitment. Open questions remain undecided until accepted in a specification or implementation plan.
|
|
9
11
|
|
|
10
12
|
## Brand
|
|
11
13
|
|
|
@@ -29,22 +31,23 @@
|
|
|
29
31
|
|
|
30
32
|
- Primary navigation: canvas selection determines Inspector and Viewer context
|
|
31
33
|
- Core screens: Graph, Inspector, Viewer, Timeline, Definition, Agent console, Logs/diagnostics
|
|
34
|
+
- The standalone player presents the artwork and minimal playback/error controls, not the graph editor. It launches as a static page or embeds in an iframe. Programmatic controls are same-origin; a cross-origin iframe is display/playback only.
|
|
32
35
|
- Content hierarchy: value preview first, type and shape metadata second, expandable raw structure last
|
|
33
36
|
|
|
34
37
|
## Design principles
|
|
35
38
|
|
|
36
39
|
- One type, one presentation contract: the same type vocabulary drives ports, Inspector, and Viewer.
|
|
37
40
|
- Progressive disclosure: compact summaries in dense panels; richer previews and metadata in Viewer; raw JSON only on demand.
|
|
38
|
-
- Edit only what can be authored honestly: inputs may edit portable values; connected inputs and outputs are read-only
|
|
39
|
-
- Expensive context changes stay explicit:
|
|
41
|
+
- Edit only what can be authored honestly: inputs may edit portable values; connected inputs and outputs are read-only. Future live GPU texture values should be inspected rather than fabricated through form fields.
|
|
42
|
+
- Expensive context changes stay explicit: server materialization, file writes and GPU readback are requested operations, never invisible UI coercions. Graph texture connections remain future work.
|
|
40
43
|
- Project types extend by registration, not central switch statements.
|
|
41
44
|
- The graph runtime is a product surface independent from Studio. Headless hosts consume it now; Studio's compatibility graph has one scheduler/controller boundary but still requires a deliberate built-in and structural-command migration before it consumes the neutral runtime directly.
|
|
42
45
|
- Node metadata is deterministic. A literal exported definition declares ports, properties, types, execution locus, and capabilities; `execute` performs computation only.
|
|
43
|
-
- A parameter is one store with three bindings. A value, an expression, and a keyframe channel live on the same parameter and
|
|
46
|
+
- A parameter is one store with three bindings. A value, an expression, and a keyframe channel live on the same parameter and use the shared `resolvePropBinding` rule in a fixed order: channel, then expression, then value. Studio calls that rule from `Node.evalParm`; the neutral runtime calls it through `PropAnimator`. Two stores is what 0.3.0 removed — `param()` wrote to one and every binding read the other, so no parameter a sketch actually declared could carry an expression or a key, and nothing errored. A stronger binding hides a weaker one rather than destroying it, so emptying a channel returns the expression that was already there.
|
|
44
47
|
- Time is an expression, not a node. A parameter holding `sin($T) * 40` is the whole of an oscillator, which is why there is no oscillator node and why portable nodes still must not read ambient time or randomness themselves. The variables and the function names are Houdini's, because the people this is for already have them in their hands; the one deliberate divergence is that bare trigonometry is in radians, with `sind`/`cosd`/`tand` provided for formulae carried across.
|
|
45
48
|
- An agent run belongs to the server, not to the browser looking at it. Closing a tab detaches a reader; the transcript is buffered with sequence numbers so reopening replays what was missed and says how much it dropped. The alternative — a run owned by an HTTP request — kills the agent mid-edit on a reload, which is what 0.3.0 fixed.
|
|
46
49
|
- Rendering offline stops at a numbered image sequence. Handing frames to an encoder is a separate decision with its own dependency, and a directory of frames is the input every encoder already takes.
|
|
47
|
-
- Hosts provide explicit capabilities. File, Python, media,
|
|
50
|
+
- Hosts provide explicit capabilities. File, Python, media, GPU, and shell access are never ambient runtime assumptions. Provider-specific AI abstractions belong to projects or embedding hosts, not Cascade core.
|
|
48
51
|
- Neutral-runtime graph loads are atomic. Compatibility Studio collapse/extract are a known migration gap and must move behind transactional structural commands before that guarantee applies to every editor operation.
|
|
49
52
|
- Tradeoff: geometry editors favor transparent structured editing and previews over specialized CAD interactions in this pass.
|
|
50
53
|
|
|
@@ -53,9 +56,10 @@
|
|
|
53
56
|
- `@cascade/contracts` is the dependency-free source of truth for graph documents, core and namespaced types, deterministic node definitions, diagnostics, run results, capabilities, and schemas.
|
|
54
57
|
- `@cascade/runtime` is the deterministic environment-neutral graph loader, validator, scheduler, serializer, trigger engine, and hierarchy implementation. It depends only on contracts; dynamic compatibility remains in Studio/CLI during migration.
|
|
55
58
|
- The root `cascade` package is the sole published distribution and CLI owner. It exposes `cascade/contracts`, `cascade/contracts/schema`, `cascade/runtime`, `cascade/runtime/node`, `cascade/runtime/browser`, `cascade/runtime/expressions`, `cascade/runtime/animation`, `cascade/runtime/definition/extract`, `cascade/io`, `cascade/net`, `cascade/stage`, and the compatibility `cascade/shell` entry point.
|
|
56
|
-
- Node and browser hosts inject only the capabilities they support.
|
|
59
|
+
- Node and browser hosts inject only the capabilities they support. GPU can be supplied by browser WebGPU or optional Dawn; file, Python and shell remain server-only. A portable declaration still requires compatible capabilities.
|
|
57
60
|
- The Studio owns canvas/view classes and a single `StudioGraphController`; its compatibility `Graph`/`Node` engine is still being reduced. Custom frontends and backend services use the neutral runtime directly and do not load editor code.
|
|
58
|
-
- **
|
|
61
|
+
- **Current GPU stage:** Studio and the optional Dawn CLI host share device/cache lifecycle through the neutral runtime. Each declaring node gets a cache namespace. Explicit RGBA8 readback supports image export in either host; graph ports still exchange images. GPU-resident intermediate connections remain a later stage.
|
|
62
|
+
- **Web technology is the default renderer, and Python is the exception.** Canvas 2D, WebGL and WebGPU first; reach for a Python stage for libraries or tools that cannot reasonably run in the browser. Marcus's ruling, 2026-09-07: *"Cascade should prefer web tech canvas/webgpu to keep things smooth and fast. only use Python for exotic ML libraries and similar things that can't be easily pushed to the browser."* The reason is interaction: process startup, transport, and serialization can dominate a cook. Persistent workers avoid repeated process/model startup, but still have transfer costs. Existing project Python renderers need deliberate parity-tested migrations; this direction does not mean those implementations are already gone.
|
|
59
63
|
- Python interoperability remains a host capability for exotic libraries and compute stages. Exchange values cross explicit typed node boundaries rather than leaking Python process details into the neutral runtime.
|
|
60
64
|
- Internal packages remain two workspaces until independent versioning or external consumption justifies separate publication. More npm packages are not a goal by themselves.
|
|
61
65
|
|
|
@@ -72,9 +76,11 @@
|
|
|
72
76
|
|
|
73
77
|
## Headless and deployment model
|
|
74
78
|
|
|
75
|
-
- `createRuntime()` is the common entry point for
|
|
79
|
+
- `createRuntime()` is the common entry point for deterministic Node services, UI-free browser embeds, tests, and custom frontends. Studio still runs through its compatibility `Graph`/`Node` engine and controller while that migration continues.
|
|
76
80
|
- Registration is sealed after the first graph load. A loaded graph supports inspect, input/property/preset mutation, trigger, run, cancel, subscription, output retrieval, and disposal without editor dependencies.
|
|
81
|
+
- A loaded deterministic graph owns an explicit caller-controlled clock. `setFrame()` and `setFps()` re-resolve animated props for inspection without cooking; `run({ frame, fps })` resolves the same bindings before execution. The runtime never reads ambient time.
|
|
77
82
|
- One run is active per graph; there is no hidden run queue. API misuse rejects, while graph execution resolves to an explicit success/failure/cancelled result.
|
|
83
|
+
- Browser-player playback coalesces requested frames; it must not queue unbounded work. Failure pauses playback and exposes its diagnostic. Static assets and generated images are realm-owned; immutable image references preserve Feedback history, and explicit resource limits prevent unbounded retention.
|
|
78
84
|
- A graph may run wholly in a backend, wholly in a compatible browser, or across an explicitly designed bridge. The runtime never silently moves a stage between hosts.
|
|
79
85
|
- File loading/saving, format versioning, presets, project paths, and workspace conveniences belong to stable platform services around the neutral runtime, not to individual generative algorithms.
|
|
80
86
|
|
|
@@ -82,7 +88,7 @@
|
|
|
82
88
|
|
|
83
89
|
- User node modules are trusted project code, not a sandbox. Deterministic definitions and architecture checks prevent common hidden-state designs and improve inspection, tooling, and portability; hard isolation would additionally require a separate realm or worker per node instance.
|
|
84
90
|
- Shell is a server-only capability backed by one project-scoped service. Projects invoke configured aliases as a fixed executable plus argument array with `shell: false`; arbitrary executables, interpolation, unsafe working directories, dangerous request-time environment overrides, and unbounded output are rejected. The subprocess inherits the server environment before project and allowlisted request overrides are applied.
|
|
85
|
-
-
|
|
91
|
+
- Sensitive browser transport is enabled for loopback and for an explicitly configured exact trusted host. Every request passes exact Host validation and Origin validation when present; sensitive routes also require a process-lifetime random capability token, apply route-local request limits, and avoid logging tokens, paths, arguments, environment, stdin, stdout, or stderr. Remote Studio rejects wildcard binds and grants every peer that can reach the trusted private interface the same project access.
|
|
86
92
|
- Timeout, cancellation, and output limits terminate the full process tree and wait for closure before reporting completion.
|
|
87
93
|
|
|
88
94
|
## Agent workflow contract
|
|
@@ -102,12 +108,14 @@
|
|
|
102
108
|
|
|
103
109
|
## Components
|
|
104
110
|
|
|
105
|
-
-
|
|
106
|
-
-
|
|
111
|
+
- **Current:** `PortEditor`, `JsonTree`, `ColorPicker`, `CoreValue`, `StructuredValue`, Viewer image zoom/pan, geometry summaries/previews, `SceneViewport` with orbit/track/dolly camera controls, and the type renderer registry. Scene rendering currently shows wireframes and points; lights are represented but do not imply shaded rendering.
|
|
112
|
+
- **Planned:** a shared type-value presentation shell, structured JSON editing, richer image/asset inspection, a Viewer output list, and texture inspection after texture values exist.
|
|
107
113
|
- Variants and states: `compact`, `inspect`, `view`; editable/read-only; empty/loading/error/stale; connected source; truncated/expanded
|
|
108
114
|
- Token/component ownership: `coreTypes.ts` owns semantic type metadata; the presentation registry owns components; Inspector/Viewer only choose context and mode
|
|
109
115
|
|
|
110
|
-
###
|
|
116
|
+
### Target core type presentation contract
|
|
117
|
+
|
|
118
|
+
This table defines the intended presentation contract. Individual rows may be only partially implemented; it does not imply that texture ports or every specialized editor currently exists.
|
|
111
119
|
|
|
112
120
|
| Family | Inspector/editor | Viewer |
|
|
113
121
|
| --- | --- | --- |
|
|
@@ -135,6 +143,7 @@
|
|
|
135
143
|
- Supported breakpoints/devices: desktop-first; Inspector remains usable from 240px width; Viewer adapts to Dockview panel size
|
|
136
144
|
- Layout adaptations: vector/matrix fields wrap or scroll; Viewer metadata collapses beneath previews; structured trees virtualize or truncate large collections
|
|
137
145
|
- Touch/hover differences: no essential information exists only in hover tooltips
|
|
146
|
+
- Player embeds fit their container; resize changes the view size, not authored graph resolution. Start paused unless autoplay is requested. Controls need native keyboard semantics and errors remain readable over the artwork.
|
|
138
147
|
|
|
139
148
|
## Interaction states
|
|
140
149
|
|
|
@@ -161,6 +170,6 @@
|
|
|
161
170
|
|
|
162
171
|
## Open questions
|
|
163
172
|
|
|
164
|
-
- [ ] Whether
|
|
173
|
+
- [ ] Whether scene rendering needs shaded GPU surfaces beyond the current CPU wireframe/point view / product / medium impact
|
|
165
174
|
- [ ] Whether project packages can eventually ship Svelte renderers directly rather than app-side registration / architecture / high impact
|
|
166
175
|
- [ ] Whether large structured values need virtualization beyond bounded initial expansion / performance / medium impact
|