@field/cascade 0.7.1 → 0.10.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.
- package/AGENTS.md +17 -1
- package/CHANGELOG.md +260 -0
- package/DESIGN.md +14 -0
- package/README.md +41 -25
- package/dist/assets/CodeEditor-DSZBpzdy.js +623 -0
- package/dist/assets/CodePanel-sY6sZa7B.js +2 -0
- package/dist/assets/CustomNodeDialog-BRKnqZhp.js +1 -0
- package/dist/assets/{ExportDialog-BJu2Bpvv.js → ExportDialog-C7dVGua4.js} +2 -2
- package/dist/assets/OpenGraphDialog-ZsgL-iwr.js +1 -0
- package/dist/assets/ProjectSettings-Cw17nNe3.js +2 -0
- package/dist/assets/SettingsDialog-p25h3tj0.js +1 -0
- package/dist/assets/VersionHistoryDialog-DzFLUotB.js +3 -0
- package/dist/assets/{core-DlkL34JF.js → core-BICrEt0y.js} +8 -8
- package/dist/assets/{cssMode-DaSSFZYi.js → cssMode-D7TXw57I.js} +1 -1
- package/dist/assets/definitions-DUww2Rt-.js +1 -0
- package/dist/assets/{editor.api-CHUMRaMm.js → editor.api-DvkCO3ko.js} +1 -1
- package/dist/assets/{freemarker2-DQ604q2A.js → freemarker2-BA2lxsF1.js} +1 -1
- package/dist/assets/geo-C2RHOVHC.js +1 -0
- package/dist/assets/{handlebars-09pcWz8x.js → handlebars-BcDiyPd8.js} +1 -1
- package/dist/assets/{html-DtIKrZiD.js → html-C7O4TyhX.js} +1 -1
- package/dist/assets/{htmlMode-DgJ_4m1_.js → htmlMode-WaDGF3Mj.js} +1 -1
- package/dist/assets/{image-CtUE4_I-.js → image-DR4oeyJB.js} +3 -3
- package/dist/assets/index-7vae6YFC.css +1 -0
- package/dist/assets/index-DyvDC6pS.js +219 -0
- package/dist/assets/index-client-DqYmKstU.js +1 -0
- package/dist/assets/{javascript-kbIBYYGo.js → javascript-CpIEK7tz.js} +1 -1
- package/dist/assets/{jsonMode-DblCG64t.js → jsonMode-B2FltW0f.js} +1 -1
- package/dist/assets/legacy-CTEeXeqF.js +2 -0
- package/dist/assets/{liquid-D-qdTGhQ.js → liquid-CN6FFHZE.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-Bc6azcFQ.js → lspLanguageFeatures-QhV9XtLp.js} +1 -1
- package/dist/assets/math-DaDEgWKt.js +1 -0
- package/dist/assets/{mdx-TXg4xsyD.js → mdx-DE89pafV.js} +1 -1
- package/dist/assets/pop-pLH7L0PW.js +1 -0
- package/dist/assets/{python-C4SGyXJW.js → python-ByTllTB9.js} +1 -1
- package/dist/assets/{razor-BZ-lEgY9.js → razor-USYlRRCE.js} +1 -1
- package/dist/assets/studioScenes-8sq9FfFg.js +1 -0
- package/dist/assets/{tsMode-BoaO1D7x.js → tsMode-BXpN8iUz.js} +1 -1
- package/dist/assets/{typescript-D87dYk9k.js → typescript-DInBjGQQ.js} +1 -1
- package/dist/assets/{workers-ZrST7klJ.js → workers-C7Ye5B7D.js} +1 -1
- package/dist/assets/{xml-DT6r4F7G.js → xml-U0Uocqyo.js} +1 -1
- package/dist/assets/{yaml-DxmQ8XYb.js → yaml-CBw_PVYf.js} +1 -1
- package/dist/cli/index.js +20070 -3487
- package/dist/cli/runtime/stage.ts +70 -10
- package/dist/contracts/bundle.d.ts +75 -0
- package/dist/contracts/bundle.js +112 -0
- package/dist/contracts/definition.d.ts +67 -4
- package/dist/contracts/document.d.ts +29 -0
- package/dist/contracts/editor.d.ts +172 -0
- package/dist/contracts/editor.js +2 -0
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.js +2 -0
- package/dist/contracts/validate.js +59 -3
- package/dist/contracts/values.d.ts +3 -3
- package/dist/contracts/values.js +1 -0
- package/dist/index.html +6 -4
- package/dist/player/app.js +17 -5
- package/dist/player/editor.js +1894 -0
- package/dist/player/editorEngine.js +477 -0
- package/dist/runtime/builtins/core/bundle.d.ts +70 -0
- package/dist/runtime/builtins/core/bundle.js +81 -0
- package/dist/runtime/builtins/core/index.d.ts +3 -2
- package/dist/runtime/builtins/core/index.js +6 -2
- package/dist/runtime/builtins/core/routing.d.ts +27 -0
- package/dist/runtime/builtins/core/routing.js +28 -0
- package/dist/runtime/edit/document.d.ts +94 -0
- package/dist/runtime/edit/document.js +194 -0
- package/dist/runtime/edit/graphEditor.d.ts +223 -0
- package/dist/runtime/edit/graphEditor.js +893 -0
- package/dist/runtime/edit/index.d.ts +12 -0
- package/dist/runtime/edit/index.js +6 -0
- package/dist/runtime/edit/layout.d.ts +50 -0
- package/dist/runtime/edit/layout.js +126 -0
- package/dist/runtime/edit/operations.d.ts +65 -0
- package/dist/runtime/edit/operations.js +57 -0
- package/dist/runtime/edit/parameters.d.ts +75 -0
- package/dist/runtime/edit/parameters.js +284 -0
- package/dist/runtime/edit/read.d.ts +35 -0
- package/dist/runtime/edit/read.js +65 -0
- package/dist/runtime/editor/index.d.ts +104 -0
- package/dist/runtime/editor/index.js +439 -0
- package/dist/runtime/expressions/bundlePaths.d.ts +37 -0
- package/dist/runtime/expressions/bundlePaths.js +55 -0
- package/dist/runtime/expressions/index.d.ts +2 -0
- package/dist/runtime/expressions/index.js +1 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/params/animator.d.ts +5 -0
- package/dist/runtime/params/animator.js +16 -0
- package/dist/runtime/runtime.js +238 -12
- package/dist/runtime/seed.d.ts +29 -0
- package/dist/runtime/seed.js +52 -0
- package/dist/runtime/types.d.ts +12 -0
- package/dist/stage.js +40 -9
- package/dist/studio/panel.d.ts +2 -0
- package/doc/CLI_REFERENCE.md +100 -0
- package/doc/EDITOR_EXPORT.md +226 -0
- package/doc/HEADLESS_GPU.md +27 -0
- package/doc/MCP.md +53 -0
- package/doc/NODE_REFERENCE.md +66 -0
- package/doc/PROJECT_AUTHORING.md +137 -0
- package/package.json +15 -6
- package/dist/assets/CodeEditor-D-N0C2jT.js +0 -623
- package/dist/assets/CodePanel-EN411mp5.js +0 -2
- package/dist/assets/CustomNodeDialog-6z2n27VV.js +0 -1
- package/dist/assets/OpenGraphDialog-fMZjzIR3.js +0 -1
- package/dist/assets/ProjectSettings-BQ8PGNqo.js +0 -2
- package/dist/assets/SettingsDialog-IbYLm8Bx.js +0 -1
- package/dist/assets/VersionHistoryDialog-Bgh-q5Jg.js +0 -3
- package/dist/assets/definitions-CQBdsJYJ.js +0 -1
- package/dist/assets/geo-DcmMAcqM.js +0 -1
- package/dist/assets/index-CnylT98t.js +0 -212
- package/dist/assets/index-client-BoJgsN9M.js +0 -1
- package/dist/assets/index-ilgbOu6G.css +0 -1
- package/dist/assets/legacy-CAj2_7QE.js +0 -2
- package/dist/assets/math-CY11tkoN.js +0 -1
- package/dist/assets/pop-Dr5-ARqQ.js +0 -1
- package/dist/assets/projectSettingsApi-C1WvIwfP.js +0 -1
package/AGENTS.md
CHANGED
|
@@ -37,11 +37,19 @@ 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
|
+
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
|
+
|
|
40
42
|
`cascade build <graph.cascade> --out <new-directory>` exports a static browser
|
|
41
43
|
player. Use repeatable `--asset <project-relative-file>` for inputs whose paths
|
|
42
44
|
are computed in code. Read `doc/WEB_PLAYER.md` before exporting: server stages
|
|
43
45
|
and dynamic modules are not supported, assets must be explicit, and an existing
|
|
44
46
|
output directory is never overwritten. Serve the result over HTTP, not file://.
|
|
47
|
+
`cascade export <graph.cascade> (--plan | --out <dir>)` exports the graph's
|
|
48
|
+
`editor` section (published parameters, outputs, presets) as a shareable static
|
|
49
|
+
editor. Read `doc/EDITOR_EXPORT.md` first. The export is an allowlist: live
|
|
50
|
+
sources must be frozen (`cascade freeze`), and `licensed/`, hidden and
|
|
51
|
+
gitignored files are refused. Scenes round-trip through the editor, Studio and
|
|
52
|
+
`cascade run --scene`.
|
|
45
53
|
The player is an application host under `src/player`, not another graph engine.
|
|
46
54
|
Each embed owns an iframe realm, assets, IO bridge and GPU lifecycle. No Studio
|
|
47
55
|
imports or `/api/*` dependency may enter the static deployment.
|
|
@@ -71,6 +79,14 @@ curl -fsS http://KURO:3030/health
|
|
|
71
79
|
curl -fsS http://KURO:3030/api/graph
|
|
72
80
|
```
|
|
73
81
|
|
|
82
|
+
For a Studio that should stay up, use `cascade serve` instead of a `screen`:
|
|
83
|
+
`cascade serve start <project> --host KURO --port 3030`, then
|
|
84
|
+
`cascade serve status [project] --json`, `logs`, `restart` and `stop`. It keeps
|
|
85
|
+
one supervisor per project, restarts a crashed Studio, and stops the Python
|
|
86
|
+
worker with it. If the host is unavailable (Tailscale down) Studio binds
|
|
87
|
+
`127.0.0.1` and moves back when the host returns; `status` shows the actual
|
|
88
|
+
binding. Never stop or restart a served Studio you did not start.
|
|
89
|
+
|
|
74
90
|
Remote access is explicit: a specific non-loopback `--host` is also the default
|
|
75
91
|
trusted browser hostname. Use `--trusted-host` only when the bind address and
|
|
76
92
|
browser hostname differ. Hostnames are exact and case-insensitive; wildcard
|
|
@@ -212,7 +228,7 @@ the TypeScript 7 preview until it is stable and the repository gates pass.
|
|
|
212
228
|
1. Add or update a focused regression test.
|
|
213
229
|
2. Make the smallest change at the owning layer.
|
|
214
230
|
3. Prefer deletion or an existing utility over another wrapper.
|
|
215
|
-
4. Run the focused test, then `npm run check`, `npm run test:run`, `npm --prefix server run build`, `npm run build`, and `npm run build:cli` when the affected surface warrants it.
|
|
231
|
+
4. Run the focused test, then `npm run check`, `npm run test:run`, `npm --prefix server run build`, `npm run build`, and `npm run build:cli` when the affected surface warrants it. Both builds write to a staging directory and replace `dist/` only on success, so a failed build leaves the previous CLI working.
|
|
216
232
|
5. For package/public API changes, also test the packed tarball from an empty temporary project.
|
|
217
233
|
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. `build:cli` runs it too, so a full build will produce the diff whether or not you meant to. Nothing tests that the committed file is current, so a stale one ships silently — and it is the first thing a project's agent reads.
|
|
218
234
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,266 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes to Cascade. Newest first.
|
|
4
4
|
|
|
5
|
+
## 0.10.0 — 2026-10-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **The timeline is saved with the graph.** `timeline: { fps, start, end,
|
|
10
|
+
loop }` in the document: Studio's Timeline opens on it and writes it back,
|
|
11
|
+
the runtime uses its fps, and `cascade run --frames timeline` renders its
|
|
12
|
+
range.
|
|
13
|
+
- **`run --frames … --mp4 <file> [--crf N]`** encodes the rendered sequence
|
|
14
|
+
with ffmpeg as H.264 yuv420p at the run's fps, and reports it as `video` in
|
|
15
|
+
the `--json` manifest.
|
|
16
|
+
- **Stage cache keys Cascade owns.** Every Python stage call, Studio or
|
|
17
|
+
headless, is keyed on the stage code (a hash of `exec.stages.sources`), the
|
|
18
|
+
arguments with input files replaced by their content hash, and the Cascade
|
|
19
|
+
version, and its cache state (`hit`, `miss`, `off`) and key are reported on
|
|
20
|
+
every call: in the server log, in `run --json` under `stages`, and in the run
|
|
21
|
+
trace. `exec.stages.cache` turns on a core result cache that verifies the
|
|
22
|
+
files a stored result names before serving it.
|
|
23
|
+
- **Run traces.** Every `cascade run` writes `.cascade/runs/<time>-<graph>.json`
|
|
24
|
+
with each node's time and its stage calls. `run --json` works without
|
|
25
|
+
`--frames`.
|
|
26
|
+
- **Seeds.** `context.seed` (from the document's `seed` and the node id) and
|
|
27
|
+
`context.random()` in both hosts; `cascade run --seed N`.
|
|
28
|
+
- **`cascade parity <graph> [--node] [--tolerance] [--json]`** cooks headless
|
|
29
|
+
twice and through Studio's executor with caches off and reports every node
|
|
30
|
+
output side by side.
|
|
31
|
+
- **Locks and replay.** `cascade lock <graph> <node> --name <name>` records one
|
|
32
|
+
render in `locks/<id>.json`: the graph as cooked, every prop and seed, input
|
|
33
|
+
file hashes, the project's source code (stored by hash in
|
|
34
|
+
`.cascade/objects/`), versions and git state, and a fingerprint of every
|
|
35
|
+
output. `cascade replay <id>` rebuilds that code in a throwaway copy of the
|
|
36
|
+
project and compares fingerprints, without a worktree; `--live` uses the
|
|
37
|
+
current code instead. `cascade lock verify` replays every lock and
|
|
38
|
+
`cascade locks` lists them. All take `--json`.
|
|
39
|
+
|
|
40
|
+
- **`cascade serve`.** `start | stop | restart | status | logs | install |
|
|
41
|
+
uninstall [project]` runs Studio as a supervised background service: one
|
|
42
|
+
lock, record and log per project under `~/.cascade/serve/`, restart with
|
|
43
|
+
backoff after a crash, and a stop that takes the Python worker with it.
|
|
44
|
+
`status --json` reports port, actual host, pids, uptime, version and worker
|
|
45
|
+
state. `install` writes and loads a macOS launchd job.
|
|
46
|
+
- **Host fallback.** When `--host` does not resolve (a MagicDNS name while
|
|
47
|
+
Tailscale is down) or is not on this machine (`EADDRNOTAVAIL`), Studio binds
|
|
48
|
+
`127.0.0.1` (or `--fallback-host`, repeatable) instead of crashing, and moves
|
|
49
|
+
back to the preferred host when it returns.
|
|
50
|
+
- **Graph editing from the CLI.** `cascade graph create|read|list`, `node add|rm`, `connect`, `disconnect`, `set` (value, `--expr`, `--key frame=value`, `--unset`), `subnet create|move|dissolve` and `cascade edit` for a batch. Each edit is checked with the same code as `cascade check`, written atomically in the file's own formatting, and leaves a minimal diff: an edit and its inverse leave the file byte-identical. New nodes get stable kebab-case ids and are placed along the graph's flow when wired; wires across a subnet boundary go through named `Input`/`Output` nodes. See `doc/CLI_REFERENCE.md`.
|
|
51
|
+
- **`--json` on every command**: one `{ ok, data, warnings }` envelope on stdout.
|
|
52
|
+
- **`cascade mcp`**: the same operations as MCP tools over stdio (graph read/list, node add/remove, connect, set, subnets, check, cook, render, export; lock and replay once they land). See `doc/MCP.md`.
|
|
53
|
+
- The editing API (`GraphEditor`, `readGraph`, the operation types) is exported from `@field/cascade/runtime`.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- `cascade run --frames --json` prints its manifest inside the envelope, as `data`, rather than at the top level.
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
61
|
+
- **Headless frame renders no longer start Python per stage per frame.**
|
|
62
|
+
`cascade run` uses the project's warm worker for the whole run, and frames
|
|
63
|
+
after the first re-cook only what the frame changed (`reuse: "strict"`;
|
|
64
|
+
`--fresh` cooks everything). cloud-plots' morph, frames 1–60: 588 s to 5 s,
|
|
65
|
+
byte-identical.
|
|
66
|
+
|
|
67
|
+
- **An edited stage no longer runs its old code in a live Studio.** The warm
|
|
68
|
+
Python worker restarts before the next request when its stage sources
|
|
69
|
+
change, with Python's bytecode cache keyed by the code hash so a quick
|
|
70
|
+
same-length edit is not served from an old `.pyc`.
|
|
71
|
+
|
|
72
|
+
- **A failed build keeps the previous `dist/`.** `npm run build` and
|
|
73
|
+
`build:cli` build into `.dist-staging/` and swap it in only when every step
|
|
74
|
+
passed; the log names the step that failed.
|
|
75
|
+
|
|
76
|
+
## 0.9.2 — 2026-10-12
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- **Exported editors work on phones.** The preview is full width at the top,
|
|
81
|
+
with pinch, pan and double-tap to fit. Controls sit in a bottom sheet with
|
|
82
|
+
three snap points and folded groups, sized for thumbs (44 px targets, 16 px
|
|
83
|
+
text, steppers). The header is one row with a ⋯ menu. Safe-area insets and
|
|
84
|
+
`100dvh` keep everything clear of Safari's toolbar. Exports and scenes use the
|
|
85
|
+
share sheet, with a download as the fallback. Landscape uses a side panel, and
|
|
86
|
+
desktop is unchanged.
|
|
87
|
+
- **`editor.peek` and `editor.draft`.** These choose the controls kept in reach
|
|
88
|
+
at the sheet's lowest point, and the values cooked while a slider is dragged
|
|
89
|
+
(a lower density, say).
|
|
90
|
+
|
|
91
|
+
## 0.9.1 — 2026-10-11
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
|
|
95
|
+
- **Share from the Inspector.** Studio's Inspector has a `share` toggle per
|
|
96
|
+
parameter that publishes it to the exported editor, with label, group and
|
|
97
|
+
min/max/step fields.
|
|
98
|
+
|
|
99
|
+
### Changed
|
|
100
|
+
|
|
101
|
+
- **The exported editor cooks in a module worker** (`editor-worker.js`), so a
|
|
102
|
+
slow stage no longer freezes the page while someone drags a slider.
|
|
103
|
+
|
|
104
|
+
### Fixed
|
|
105
|
+
|
|
106
|
+
- **A fresh tree builds.** `npm run build` compiles the workspace packages
|
|
107
|
+
before vite, and no longer leaves `dist/` without a CLI.
|
|
108
|
+
|
|
109
|
+
## 0.9.0 — 2026-10-11
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- **Shareable editors (0.9.0).** `cascade export <graph> --out <dir>` builds a
|
|
114
|
+
static editor site from a graph's new `editor` section. It has the published
|
|
115
|
+
parameters (with a UI generated from their types), presets, scene files, one
|
|
116
|
+
export button per declared output, and a read-only inspect view of every
|
|
117
|
+
stage. `--plan` prints the manifest without building, and
|
|
118
|
+
`--deploy vercel` deploys the site and checks that Vercel Authentication is
|
|
119
|
+
on.
|
|
120
|
+
|
|
121
|
+
The export is an allowlist. It ships the subgraph the outputs need and the
|
|
122
|
+
selected assets, and nothing else. It refuses Python and dynamic nodes,
|
|
123
|
+
wired-in live sources, `licensed/`, hidden and gitignored files. It scans the
|
|
124
|
+
built site for credentials, local paths and backend URLs.
|
|
125
|
+
`cascade freeze` snapshots chosen fields of a live source, and
|
|
126
|
+
`cascade publish` marks a prop as a parameter. Scenes (`*.scene.json`) open
|
|
127
|
+
in the editor, in Studio (File › Open/Save Scene) and in the CLI
|
|
128
|
+
(`cascade scene`, `cascade run --scene --write`), with versioned,
|
|
129
|
+
degrade-gracefully matching.
|
|
130
|
+
|
|
131
|
+
The runtime gains `run({ reuse: true })`, an early cutoff for hosts that
|
|
132
|
+
re-run on every edit, and `cascade.core.Frozen`. Node definitions gain
|
|
133
|
+
`source: "live"`. See `doc/EDITOR_EXPORT.md`.
|
|
134
|
+
|
|
135
|
+
- **Bundle ports.** A node can export one `bundle` port carrying named fields
|
|
136
|
+
instead of a dozen loose outputs. A producer declares `fields` (name to type)
|
|
137
|
+
and an optional `schema`; a consumer declares the `fields` it reads, sees only
|
|
138
|
+
those, and in Studio re-cooks only when one of them changed (per-field
|
|
139
|
+
versions on top of early cutoff). Expressions read a wired bundle's fields
|
|
140
|
+
with `ch("format.dpi")`. `cascade.core.Pick` and `cascade.core.Pack` convert
|
|
141
|
+
between bundles and single values. `cascade check` reports unknown fields with
|
|
142
|
+
the nearest declared name, and refuses an absolute read of another node's
|
|
143
|
+
bundle. Studio draws a bundle as one neutral port whose hover and Inspector
|
|
144
|
+
list its fields and values. Bundles reach Python stages as dicts. See
|
|
145
|
+
"Bundle ports" in `doc/PROJECT_AUTHORING.md`.
|
|
146
|
+
|
|
147
|
+
- **Node previews on the canvas.** A project that sets
|
|
148
|
+
`settings.nodePreviews: true` in `cascade.json` shows each node's first
|
|
149
|
+
output as a readable preview card on the graph, refreshed per node cook. The
|
|
150
|
+
same settings can carry a `workspace` used as the first-open dock layout when
|
|
151
|
+
the browser has none saved; a layout that fails to load falls back to the
|
|
152
|
+
built-in one.
|
|
153
|
+
|
|
154
|
+
- **Groups own their contents.** A group frame keeps an explicit
|
|
155
|
+
`containedElements` list, separate from subnet parenting. Drag the frame
|
|
156
|
+
header to move its members (nested contents move once); drop an item's
|
|
157
|
+
centre inside a frame to add it, outside to remove it, and the smallest
|
|
158
|
+
enclosing frame wins. The target frame highlights before release, and
|
|
159
|
+
membership and positions share one undo step. Deleting a frame leaves its
|
|
160
|
+
contents. View → Clean Up Layout now treats each group as a cluster: it lays
|
|
161
|
+
out members first, fits the frame, then places the groups.
|
|
162
|
+
|
|
163
|
+
- **The Agent console keeps a Codex conversation, and panels can hand it a
|
|
164
|
+
draft.** A Codex console resumes the thread id from `thread.started`, so
|
|
165
|
+
later prompts continue one conversation per sketch as Claude's do; project
|
|
166
|
+
`--sandbox` flags are normalised for `exec resume`. Codex item events
|
|
167
|
+
(assistant messages, commands with their output, file changes) render in the
|
|
168
|
+
console. Project panels get `api.openAgent(prompt)`, which opens the Agent
|
|
169
|
+
panel with a draft to review and send, never sending it.
|
|
170
|
+
|
|
171
|
+
### Changed
|
|
172
|
+
|
|
173
|
+
- **Dragging a node re-renders only what moved.** Each node reads its position
|
|
174
|
+
through its own motion store, and the graph is published once when the drag
|
|
175
|
+
ends rather than copied every frame. At 100 nodes a pointer move costs 1.6 ms
|
|
176
|
+
of script instead of 8.9 (5.6 ms of task time instead of 13.1).
|
|
177
|
+
|
|
178
|
+
- **Node drags apply once per frame.** Moving a node or a selection batches
|
|
179
|
+
pointer moves to one update per animation frame instead of one per event.
|
|
180
|
+
|
|
181
|
+
- **Identical output stops invalidating the graph below it.** A node that
|
|
182
|
+
re-cooks and commits the same values (compared structurally; the same
|
|
183
|
+
object reference counts as changed, since it may be mutated in place) keeps
|
|
184
|
+
its output version, and a node stale only because of that upstream re-cook
|
|
185
|
+
is skipped. A node whose own parameters, code or wiring changed always
|
|
186
|
+
cooks, and `node.earlyCutoff = false` opts a node out. The cook status
|
|
187
|
+
carries the count as `cutOff`. Python projects get the matching half by
|
|
188
|
+
keying their stage cache on content; cloud-plots does (see its
|
|
189
|
+
`runtime/node_cli.py`). There, a no-op edit to `area-filter-mask` now costs
|
|
190
|
+
2 stage calls and 47 ms instead of 13 calls and 866 ms.
|
|
191
|
+
|
|
192
|
+
- **What a Viewer shows cooks first.** A pass ran in plain topological order,
|
|
193
|
+
so a sink nobody was looking at (an export, a plot check, the mockup) could
|
|
194
|
+
run ahead of the node on screen. Now the selected or pinned node of each open
|
|
195
|
+
Viewer and everything it depends on cook first, and the rest of the pass runs
|
|
196
|
+
after, in the same order as before. With no Viewer (the CLI, tests, cook-all)
|
|
197
|
+
nothing changes. On cloud-plots, a Viewer on `hatch-curves` showed its result
|
|
198
|
+
after 3.4 s instead of 7.4 s on a cold cook.
|
|
199
|
+
|
|
200
|
+
- **An edit cancels the stage it supersedes.** Changing a parameter while a
|
|
201
|
+
long Python stage runs used to wait for that stage, and then for every
|
|
202
|
+
request queued behind it. Now the superseded cook is aborted: its request is
|
|
203
|
+
withdrawn from the worker (dropped if queued, interrupted with SIGINT if
|
|
204
|
+
running, killed if it does not answer), its result is never applied, and the
|
|
205
|
+
pass restarts from the edit. The cook strip shows how many cooks were
|
|
206
|
+
superseded. Measured on cloud-plots, an edit during a 12 s stage now lands in
|
|
207
|
+
0.6 s instead of 10.9 s. Project workers should answer an interrupt with
|
|
208
|
+
`{"cancelled": true}` to stay warm; see `doc/PROJECT_AUTHORING.md`.
|
|
209
|
+
|
|
210
|
+
### Fixed
|
|
211
|
+
|
|
212
|
+
- **Three wire and runtime fixes.** Studio's browser-shell adapter sends
|
|
213
|
+
execution options (stdin, timeout, cwd, env) at the top level of the
|
|
214
|
+
`/api/shell` body again; nested under `options` the route dropped them. A
|
|
215
|
+
Switch node's `index` is a document prop, serializes, and re-routes on cook.
|
|
216
|
+
Project CLI instances of one module share a single executor build, so one
|
|
217
|
+
cannot import the `.mjs` while another rewrites it.
|
|
218
|
+
|
|
219
|
+
## 0.8.0 — 2026-10-10
|
|
220
|
+
|
|
221
|
+
### Added
|
|
222
|
+
|
|
223
|
+
- **Number fields scrub.** Middle-drag any numeric field (vector components,
|
|
224
|
+
ints, a scalar's number box, colour channels) to drag its value, Houdini
|
|
225
|
+
style. On a trackpad, drag the X/Y/Z letter or the parameter's name, or
|
|
226
|
+
Option-drag the field. Shift is 10× coarser, Cmd/Ctrl 10× finer, Esc restores
|
|
227
|
+
the start value, and a whole drag is one undo step. Vectors with a range show
|
|
228
|
+
a hairline marking where the value sits.
|
|
229
|
+
- **Drag a node onto a Viewer to pin it there.** Drag a node out of the graph
|
|
230
|
+
panel, or Cmd-drag it, and drop it on a Viewer: the Viewer shows that node and
|
|
231
|
+
locks to it. Click the lock to follow the selection again. Each Viewer locks
|
|
232
|
+
on its own, and locks survive a reload.
|
|
233
|
+
|
|
234
|
+
### Changed
|
|
235
|
+
|
|
236
|
+
- **The graph stays calm until you select.** Wires idle at half opacity. A
|
|
237
|
+
selection brings its node and wires to full strength and fades the rest;
|
|
238
|
+
hover previews the same. Wires now draw under nodes, so they no longer cross
|
|
239
|
+
names or take clicks. The levels are the `--graph-*` variables in
|
|
240
|
+
`src/editor/theme.css`.
|
|
241
|
+
- **Dragging a parameter's name into the agent console is now Option-drag**,
|
|
242
|
+
because a plain drag on the name scrubs.
|
|
243
|
+
|
|
244
|
+
### Fixed
|
|
245
|
+
|
|
246
|
+
- **The workspace stays as you left it.** Panel layout, every Viewer and what
|
|
247
|
+
each one is pinned to are saved with the project, beside the graph as
|
|
248
|
+
`<name>.workspace.json`, on every change rather than every 30 s. Before, one
|
|
249
|
+
browser key held the layout for every project on the same host and port, so
|
|
250
|
+
opening another project unpinned your Viewers, a reload soon after arranging
|
|
251
|
+
lost the arrangement, and `localhost`, `127.0.0.1` and a Tailscale name each
|
|
252
|
+
had their own layout. A pinned node that is not in the loaded graph now shows
|
|
253
|
+
as missing and keeps the pin, instead of the Viewer quietly following the
|
|
254
|
+
selection. A layout that fails to restore is kept as
|
|
255
|
+
`<name>.workspace.failed.json`.
|
|
256
|
+
- **Studio no longer wakes the GPU while idle.** The Viewer requested an
|
|
257
|
+
animation frame on every frame whenever anything was on display, which kept
|
|
258
|
+
the compositor ticking at display rate. It now redraws on a cook or a
|
|
259
|
+
selection change and stops while the tab is hidden: 10 s idle went from 1,250
|
|
260
|
+
frame callbacks to none.
|
|
261
|
+
- **A scrub label no longer throws when its node goes null on teardown.**
|
|
262
|
+
- **The Pinterest extension no longer puts Save buttons over canvases.** Studio
|
|
263
|
+
sets `<meta name="pinterest" content="nopin">`.
|
|
264
|
+
|
|
5
265
|
## 0.7.1 — 2026-09-12
|
|
6
266
|
|
|
7
267
|
### Added
|
package/DESIGN.md
CHANGED
|
@@ -109,6 +109,8 @@ This document contains both current product rules and intended direction. Sectio
|
|
|
109
109
|
## Components
|
|
110
110
|
|
|
111
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
|
+
- **Canvas previews:** Projects may opt into readable first-output previews on graph nodes with `settings.nodePreviews: true` in `cascade.json`. The canvas reuses `CoreValue` in compact, read-only mode, including project type renderers; the default remains the compact computational graph. A serialized Dockview layout in `settings.workspace` may also suggest the first-open workspace, but a browser's saved layout always wins.
|
|
113
|
+
- **Group-aware cleanup:** View → Clean Up Layout treats each group as a visual cluster. It arranges and measures members first, fits the frame around them, then places clusters in the graph's top-to-bottom flow. Nested groups stay nested, wide source ranks wrap, and standalone notes move to a clear margin. The command changes positions and group sizes only; membership and subnet hierarchy remain authored data.
|
|
112
114
|
- **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.
|
|
113
115
|
- Variants and states: `compact`, `inspect`, `view`; editable/read-only; empty/loading/error/stale; connected source; truncated/expanded
|
|
114
116
|
- Token/component ownership: `coreTypes.ts` owns semantic type metadata; the presentation registry owns components; Inspector/Viewer only choose context and mode
|
|
@@ -173,3 +175,15 @@ This table defines the intended presentation contract. Individual rows may be on
|
|
|
173
175
|
- [ ] Whether scene rendering needs shaded GPU surfaces beyond the current CPU wireframe/point view / product / medium impact
|
|
174
176
|
- [ ] Whether project packages can eventually ship Svelte renderers directly rather than app-side registration / architecture / high impact
|
|
175
177
|
- [ ] Whether large structured values need virtualization beyond bounded initial expansion / performance / medium impact
|
|
178
|
+
|
|
179
|
+
## Canvas groups
|
|
180
|
+
|
|
181
|
+
Groups own explicit `containedElements` independently of subnet parenting. Drag
|
|
182
|
+
a frame header to move its members together. Dropping an item’s centre inside a
|
|
183
|
+
frame adds it; dropping outside removes it; the smallest enclosing frame wins
|
|
184
|
+
when frames overlap. The target frame highlights before release. Moving a frame
|
|
185
|
+
does not collect stationary items it passes over. Nested contents move once.
|
|
186
|
+
Membership and positions persist together and share a gesture’s undo snapshot.
|
|
187
|
+
Deleting a frame leaves its contents alive. Unselected wires are neutral grey;
|
|
188
|
+
selection restores their type colour. Preview cards use one surface with
|
|
189
|
+
controls appearing on hover or selection.
|
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ under the MIT license. [Getting started and features](https://cascade.field.io).
|
|
|
11
11
|
- Deterministic custom-node definitions that tools can inspect without running user code.
|
|
12
12
|
- An environment-neutral runtime for Node services and UI-free browser applications.
|
|
13
13
|
- A standalone browser player: build static pages and embeddable sketches without a Studio server.
|
|
14
|
+
- Shareable editors: `cascade export` builds a static site where someone else can change published parameters, save scenes and export, without Studio or an account.
|
|
14
15
|
- A Studio compatibility controller that already presents deterministic definitions alongside dynamic project nodes while its graph engine migrates to the neutral runtime.
|
|
15
16
|
- Project-native `.cascade` files, assets, presets, and Git-backed version history.
|
|
16
17
|
- Nested subnets with persistent hierarchy.
|
|
@@ -25,31 +26,45 @@ under the MIT license. [Getting started and features](https://cascade.field.io).
|
|
|
25
26
|
|
|
26
27
|
Cascade separates the generative algorithm from the platform. Custom nodes describe stages of a pipeline; the runtime schedules and validates them; hosts supply environment-specific capabilities; Studio is only one possible frontend.
|
|
27
28
|
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install -g @field/cascade
|
|
33
|
+
cascade new my-sketch # scaffolds ~/Documents/Cascade/my-sketch and opens Studio
|
|
34
|
+
cd ~/Documents/Cascade/my-sketch && npm install
|
|
35
|
+
cascade . # reopen it later
|
|
36
|
+
cascade run index.cascade --frames 1 --json # render headlessly
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The npm package is at 0.8.0. The 0.9 commands below (`export`, `publish`, `freeze`, `scene`) need a checkout of this repository until 0.9 is published.
|
|
40
|
+
|
|
41
|
+
## New in 0.9: shareable editors
|
|
42
|
+
|
|
43
|
+
`cascade export` turns a graph into a small static website: a viewer, the parameters you chose to publish, presets, scene files and an export button per output. Send the link and someone without Studio can change your scene, save it as a scene file and send it back.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cascade publish index.cascade spec.capMm --label "Cap height" --min 3 --max 60 --unit mm
|
|
47
|
+
cascade freeze index.cascade moment --output moment --fields photos[0],instant
|
|
48
|
+
cascade export index.cascade --plan # what ships and what stays
|
|
49
|
+
cascade export index.cascade --out export/site
|
|
50
|
+
cascade export index.cascade --out export/site --deploy vercel --project my-editor
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
In Studio, the `share` toggle beside a parameter in the Inspector publishes it, with a label, group and range. Scenes (`*.scene.json`) open in the editor, in Studio and in the CLI (`cascade scene`, `cascade run --scene`). The editor cooks in a module worker, so a slow stage does not stall the page.
|
|
54
|
+
|
|
55
|
+
<img src="https://cascade.field.io/img/inspector-share@2x.webp" width="360" alt="The Studio Inspector with share buttons beside each parameter">
|
|
56
|
+
|
|
57
|
+
The export is an allowlist. It ships the subgraph the outputs need and the assets you name, refuses live sources until you freeze the fields you want, refuses Python, licensed and ignored files, and scans the built site for credentials and local paths. Read [Shareable editors](doc/EDITOR_EXPORT.md) before sharing anything.
|
|
58
|
+
|
|
59
|
+
**Cloud Type** is the first exported editor: the dotted headline generator for FIELD's Human First book. Try it at [cloud-type.vercel.app](https://cloud-type.vercel.app); the project is at [marcuswendt/cloud-type](https://github.com/marcuswendt/cloud-type).
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
Large graphs stay readable when they open as a few stages with the detail in subnets. The cloud-plots print graph has 98 nodes and opens as seven.
|
|
64
|
+
|
|
65
|
+

|
|
66
|
+
|
|
67
|
+
0.9.1 also fixes a fresh checkout's build: `npm run build` compiles the workspace packages before vite, so `dist/` is never left without a CLI. See the [changelog](CHANGELOG.md).
|
|
53
68
|
|
|
54
69
|
## Install
|
|
55
70
|
|
|
@@ -426,6 +441,7 @@ trusted-host session; an untrusted remote bind does not expose them.
|
|
|
426
441
|
- [Design source of truth](DESIGN.md)
|
|
427
442
|
- [Architecture](ARCHITECTURE.md)
|
|
428
443
|
- [Browser player](doc/WEB_PLAYER.md)
|
|
444
|
+
- [Shareable editors](doc/EDITOR_EXPORT.md)
|
|
429
445
|
- [September quality review and sketch verification](doc/QUALITY_REVIEW_2026-09.md)
|
|
430
446
|
- [Subnet and shell specification](spec/CASCADE_SUBNET_AND_SHELL_SPEC.md)
|
|
431
447
|
|