@field/cascade 0.2.22 → 0.3.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 +47 -7
- package/ARCHITECTURE.md +30 -2
- package/CHANGELOG.md +89 -0
- package/DESIGN.md +10 -5
- package/README.md +103 -7
- package/dist/assets/CodeEditor-BADFbTJS.js +623 -0
- package/dist/assets/CodePanel-faK6PRfz.js +2 -0
- package/dist/assets/CustomNodeDialog-DhlKuviy.js +1 -0
- package/dist/assets/{ExportDialog-DWN4nhXI.js → ExportDialog-BJu2Bpvv.js} +2 -2
- package/dist/assets/ProjectSettings-D6a6kjqR.js +2 -0
- package/dist/assets/SettingsDialog-DJZdIvLC.js +1 -0
- package/dist/assets/VersionHistoryDialog-C1X3HOhc.js +3 -0
- package/dist/assets/{core-Bji4aZUU.js → core-CiuiuWZi.js} +29 -38
- package/dist/assets/{cssMode-B6Z_Q1Kh.js → cssMode-D-NwZSMJ.js} +1 -1
- package/dist/assets/{editor.api-jMoW_43X.js → editor.api-DT3WEvBd.js} +1 -1
- package/dist/assets/{freemarker2-DvvPV6m5.js → freemarker2-eKNYQaiz.js} +1 -1
- package/dist/assets/geo-DUvVbLnx.js +1 -0
- package/dist/assets/{handlebars-B8rfuSIa.js → handlebars-C2w1ggK2.js} +1 -1
- package/dist/assets/{html-DyHm6JCp.js → html-DQb41jyo.js} +1 -1
- package/dist/assets/{htmlMode-E9XLWE5u.js → htmlMode-IhNlh6Lv.js} +1 -1
- package/dist/assets/{image-BUcQC7PG.js → image-DMCXBY-_.js} +26 -40
- package/dist/assets/index-BDV5xGBZ.css +1 -0
- package/dist/assets/index-HTCN44kj.js +212 -0
- package/dist/assets/index-client-BoJgsN9M.js +1 -0
- package/dist/assets/{javascript-C_bM5PCN.js → javascript-BIT6jMLC.js} +1 -1
- package/dist/assets/{jsonMode-BdyVS7G4.js → jsonMode-CNfyB1ro.js} +1 -1
- package/dist/assets/{legacy-DIu3XRwl.js → legacy-CAj2_7QE.js} +2 -2
- package/dist/assets/{liquid-CDkn3spA.js → liquid-CmSmJmOG.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-AB5DMAsr.js → lspLanguageFeatures-BqMm3uMP.js} +1 -1
- package/dist/assets/{mdx-BvH_NjDN.js → mdx-6r6YgOFw.js} +1 -1
- package/dist/assets/{nodeTypeUtils-CweA3NHd.js → nodeTypeUtils-BBA1JqHx.js} +1 -1
- package/dist/assets/{python-B7uii4fi.js → python-x1H0TQuI.js} +1 -1
- package/dist/assets/{razor-Z48fWdJc.js → razor-Dzl1vZFm.js} +1 -1
- package/dist/assets/{tsMode-BDgacVG4.js → tsMode-n6DMMe3a.js} +1 -1
- package/dist/assets/{typescript-Derb6Oqa.js → typescript-ziEz65xN.js} +1 -1
- package/dist/assets/{workers-BtoMX_pm.js → workers-D-qUdp-r.js} +1 -1
- package/dist/assets/{xml-B1CaFSrG.js → xml-DMZjt5lE.js} +1 -1
- package/dist/assets/{yaml-HmIeA0KH.js → yaml-DFe5qZSO.js} +1 -1
- package/dist/cli/index.js +16194 -10195
- package/dist/cli/runtime/io.ts +93 -7
- package/dist/contracts/animation.d.ts +40 -0
- package/dist/contracts/animation.js +14 -0
- package/dist/contracts/definition.d.ts +39 -1
- package/dist/contracts/document.d.ts +15 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/validate.d.ts +10 -1
- package/dist/contracts/validate.js +9 -1
- package/dist/graphs/default.cascade +1 -1
- package/dist/index.html +5 -5
- package/dist/io.d.ts +196 -0
- package/dist/io.js +303 -0
- package/dist/net.d.ts +1 -0
- package/dist/net.js +28 -0
- package/dist/runtime/animation/channel.d.ts +108 -0
- package/dist/runtime/animation/channel.js +204 -0
- package/dist/runtime/animation/frameRange.d.ts +78 -0
- package/dist/runtime/animation/frameRange.js +76 -0
- package/dist/runtime/animation/index.d.ts +10 -0
- package/dist/runtime/animation/index.js +8 -0
- package/dist/runtime/builtins/core/random.d.ts +1 -1
- package/dist/runtime/builtins/core/remap.d.ts +1 -1
- package/dist/runtime/builtins/geo/copyToPoints.d.ts +1 -1
- package/dist/runtime/builtins/geo/copyToPoints.js +1 -1
- package/dist/runtime/builtins/geo/generators.d.ts +1 -1
- package/dist/runtime/builtins/geo/merge.d.ts +1 -1
- package/dist/runtime/builtins/geo/svgExport.d.ts +1 -1
- package/dist/runtime/builtins/geo/svgExport.js +1 -1
- package/dist/runtime/builtins/geo/transform.d.ts +1 -1
- package/dist/runtime/builtins/geo/transform.js +1 -1
- package/dist/runtime/definition/architecture.d.ts +1 -1
- package/dist/runtime/definition/extract.d.ts +1 -1
- package/dist/runtime/definition/extract.js +1 -1
- package/dist/runtime/error.d.ts +1 -1
- package/dist/runtime/expressions/evaluator.d.ts +53 -0
- package/dist/runtime/expressions/evaluator.js +193 -0
- package/dist/runtime/expressions/index.d.ts +15 -0
- package/dist/runtime/expressions/index.js +12 -0
- package/dist/runtime/expressions/math.d.ts +75 -0
- package/dist/runtime/expressions/math.js +140 -0
- package/dist/runtime/expressions/preprocess.d.ts +33 -0
- package/dist/runtime/expressions/preprocess.js +102 -0
- package/dist/runtime/expressions/scope.d.ts +27 -0
- package/dist/runtime/expressions/scope.js +10 -0
- package/dist/runtime/expressions/time.d.ts +54 -0
- package/dist/runtime/expressions/time.js +71 -0
- package/dist/runtime/expressions/types.d.ts +66 -0
- package/dist/runtime/expressions/types.js +9 -0
- package/dist/runtime/geometry/attributes.d.ts +2 -2
- package/dist/runtime/geometry/attributes.js +1 -1
- package/dist/runtime/geometry/builder.d.ts +1 -1
- package/dist/runtime/geometry/builder.js +1 -1
- package/dist/runtime/geometry/copy.d.ts +1 -1
- package/dist/runtime/geometry/copy.js +1 -1
- package/dist/runtime/geometry/generate.d.ts +1 -1
- package/dist/runtime/geometry/groups.d.ts +1 -1
- package/dist/runtime/geometry/groups.js +1 -1
- package/dist/runtime/geometry/matrix.d.ts +1 -1
- package/dist/runtime/geometry/merge.d.ts +1 -1
- package/dist/runtime/geometry/merge.js +1 -1
- package/dist/runtime/geometry/primitives.d.ts +1 -1
- package/dist/runtime/geometry/primitives.js +1 -1
- package/dist/runtime/geometry/promote.d.ts +1 -1
- package/dist/runtime/geometry/promote.js +1 -1
- package/dist/runtime/geometry/resample.d.ts +1 -1
- package/dist/runtime/geometry/resample.js +1 -1
- package/dist/runtime/geometry/svg.d.ts +1 -1
- package/dist/runtime/geometry/svg.js +1 -1
- package/dist/runtime/geometry/transform.d.ts +1 -1
- package/dist/runtime/geometry/transform.js +1 -1
- package/dist/runtime/index.d.ts +4 -1
- package/dist/runtime/index.js +4 -1
- package/dist/runtime/params/animator.d.ts +74 -0
- package/dist/runtime/params/animator.js +137 -0
- package/dist/runtime/params/index.d.ts +11 -0
- package/dist/runtime/params/index.js +9 -0
- package/dist/runtime/params/resolve.d.ts +73 -0
- package/dist/runtime/params/resolve.js +62 -0
- package/dist/runtime/runtime.d.ts +22 -0
- package/dist/runtime/runtime.js +242 -14
- package/dist/runtime/types.d.ts +30 -4
- package/dist/shell.d.ts +3 -3
- package/doc/NODE_REFERENCE.md +395 -0
- package/doc/PROJECT_AUTHORING.md +148 -6
- package/package.json +26 -3
- package/dist/assets/CodeEditor-DoaNEUaM.js +0 -641
- package/dist/assets/CodePanel-B0_2XJ-t.js +0 -2
- package/dist/assets/CustomNodeDialog-026lzecD.js +0 -1
- package/dist/assets/ProjectSettings-BzT164Yx.js +0 -2
- package/dist/assets/SettingsDialog-DmHb1V0r.js +0 -1
- package/dist/assets/VersionHistoryDialog-hH6VsXLX.js +0 -3
- package/dist/assets/geo-CXmCtzMM.js +0 -2
- package/dist/assets/index-BXYXSdgh.js +0 -224
- package/dist/assets/index-CrNke7SW.css +0 -1
- package/dist/assets/index-client-DN_FvjN8.js +0 -1
- package/dist/assets/quill-DjZ69wL_.js +0 -121
- package/dist/cli/index.js.map +0 -7
- package/dist/contracts/capabilities.d.ts.map +0 -1
- package/dist/contracts/capabilities.js.map +0 -1
- package/dist/contracts/color.d.ts.map +0 -1
- package/dist/contracts/color.js.map +0 -1
- package/dist/contracts/definition.d.ts.map +0 -1
- package/dist/contracts/definition.js.map +0 -1
- package/dist/contracts/document.d.ts.map +0 -1
- package/dist/contracts/document.js.map +0 -1
- package/dist/contracts/geometry.d.ts.map +0 -1
- package/dist/contracts/geometry.js.map +0 -1
- package/dist/contracts/index.d.ts.map +0 -1
- package/dist/contracts/index.js.map +0 -1
- package/dist/contracts/schema.d.ts.map +0 -1
- package/dist/contracts/schema.js.map +0 -1
- package/dist/contracts/validate.d.ts.map +0 -1
- package/dist/contracts/validate.js.map +0 -1
- package/dist/contracts/values.d.ts.map +0 -1
- package/dist/contracts/values.js.map +0 -1
- package/dist/graphs/default-orig.cascade +0 -128
- package/dist/runtime/browser.d.ts.map +0 -1
- package/dist/runtime/browser.js.map +0 -1
- package/dist/runtime/builtins/core/index.d.ts.map +0 -1
- package/dist/runtime/builtins/core/index.js.map +0 -1
- package/dist/runtime/builtins/core/random.d.ts.map +0 -1
- package/dist/runtime/builtins/core/random.js.map +0 -1
- package/dist/runtime/builtins/core/remap.d.ts.map +0 -1
- package/dist/runtime/builtins/core/remap.js.map +0 -1
- package/dist/runtime/builtins/core/routing.d.ts.map +0 -1
- package/dist/runtime/builtins/core/routing.js.map +0 -1
- package/dist/runtime/builtins/core/structural.d.ts.map +0 -1
- package/dist/runtime/builtins/core/structural.js.map +0 -1
- package/dist/runtime/builtins/geo/copyToPoints.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/copyToPoints.js.map +0 -1
- package/dist/runtime/builtins/geo/definitions.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/definitions.js.map +0 -1
- package/dist/runtime/builtins/geo/generators.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/generators.js.map +0 -1
- package/dist/runtime/builtins/geo/index.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/index.js.map +0 -1
- package/dist/runtime/builtins/geo/merge.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/merge.js.map +0 -1
- package/dist/runtime/builtins/geo/namespace.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/namespace.js.map +0 -1
- package/dist/runtime/builtins/geo/svgExport.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/svgExport.js.map +0 -1
- package/dist/runtime/builtins/geo/transform.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/transform.js.map +0 -1
- package/dist/runtime/builtins/index.d.ts.map +0 -1
- package/dist/runtime/builtins/index.js.map +0 -1
- package/dist/runtime/definition/architecture.d.ts.map +0 -1
- package/dist/runtime/definition/architecture.js.map +0 -1
- package/dist/runtime/definition/extract.d.ts.map +0 -1
- package/dist/runtime/definition/extract.js.map +0 -1
- package/dist/runtime/error.d.ts.map +0 -1
- package/dist/runtime/error.js.map +0 -1
- package/dist/runtime/geometry/attributes.d.ts.map +0 -1
- package/dist/runtime/geometry/attributes.js.map +0 -1
- package/dist/runtime/geometry/builder.d.ts.map +0 -1
- package/dist/runtime/geometry/builder.js.map +0 -1
- package/dist/runtime/geometry/copy.d.ts.map +0 -1
- package/dist/runtime/geometry/copy.js.map +0 -1
- package/dist/runtime/geometry/generate.d.ts.map +0 -1
- package/dist/runtime/geometry/generate.js.map +0 -1
- package/dist/runtime/geometry/groups.d.ts.map +0 -1
- package/dist/runtime/geometry/groups.js.map +0 -1
- package/dist/runtime/geometry/index.d.ts.map +0 -1
- package/dist/runtime/geometry/index.js.map +0 -1
- package/dist/runtime/geometry/matrix.d.ts.map +0 -1
- package/dist/runtime/geometry/matrix.js.map +0 -1
- package/dist/runtime/geometry/merge.d.ts.map +0 -1
- package/dist/runtime/geometry/merge.js.map +0 -1
- package/dist/runtime/geometry/primitives.d.ts.map +0 -1
- package/dist/runtime/geometry/primitives.js.map +0 -1
- package/dist/runtime/geometry/promote.d.ts.map +0 -1
- package/dist/runtime/geometry/promote.js.map +0 -1
- package/dist/runtime/geometry/resample.d.ts.map +0 -1
- package/dist/runtime/geometry/resample.js.map +0 -1
- package/dist/runtime/geometry/svg.d.ts.map +0 -1
- package/dist/runtime/geometry/svg.js.map +0 -1
- package/dist/runtime/geometry/transform.d.ts.map +0 -1
- package/dist/runtime/geometry/transform.js.map +0 -1
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/node.d.ts.map +0 -1
- package/dist/runtime/node.js.map +0 -1
- package/dist/runtime/runtime.d.ts.map +0 -1
- package/dist/runtime/runtime.js.map +0 -1
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/types.js.map +0 -1
- package/dist/shell.js.map +0 -7
- package/dist/stage.js.map +0 -7
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# Node reference
|
|
2
|
+
|
|
3
|
+
**Generated by `scripts/build-node-reference.mjs`. Do not edit — regenerate it.**
|
|
4
|
+
|
|
5
|
+
Read this before searching the codebase for what a node does. It exists because
|
|
6
|
+
that search is expensive and this file is not: the whole catalogue below is under
|
|
7
|
+
8,000 characters, and working it out by reading source cost one agent about twenty
|
|
8
|
+
tool calls, two of which were the same 1,676-line file.
|
|
9
|
+
|
|
10
|
+
For the `.cascade` document format, expressions, and how to write a node, see
|
|
11
|
+
`AGENTS.md`. **Note in particular that anything time-based is an expression
|
|
12
|
+
rather than a node** — `sin($T) * 40` in a parameter — so there is no oscillator
|
|
13
|
+
node and none is needed.
|
|
14
|
+
|
|
15
|
+
## Deterministic nodes, with full declarations
|
|
16
|
+
|
|
17
|
+
These are definition-v1: their declarations are literal, so what follows is
|
|
18
|
+
exact rather than a description.
|
|
19
|
+
|
|
20
|
+
### `cascade.core.Input`
|
|
21
|
+
|
|
22
|
+
Input — Defines a public graph or subnet input
|
|
23
|
+
|
|
24
|
+
Runs on `portable`.
|
|
25
|
+
|
|
26
|
+
**Inputs**
|
|
27
|
+
|
|
28
|
+
| name | type | default | range |
|
|
29
|
+
| --- | --- | --- | --- |
|
|
30
|
+
| `value` | `any` | `null` | |
|
|
31
|
+
|
|
32
|
+
**Props**
|
|
33
|
+
|
|
34
|
+
| name | type | default | range |
|
|
35
|
+
| --- | --- | --- | --- |
|
|
36
|
+
| `inputIndex` | `int` | `0` | |
|
|
37
|
+
| `inputName` | `string` | `""` | |
|
|
38
|
+
| `dataType` | `string` | `"any"` | |
|
|
39
|
+
|
|
40
|
+
**Outputs**
|
|
41
|
+
|
|
42
|
+
| name | type | default | range |
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
|
+
| `output` | `any` | | |
|
|
45
|
+
|
|
46
|
+
### `cascade.core.Merge`
|
|
47
|
+
|
|
48
|
+
Merge — Collects inputs into an array
|
|
49
|
+
|
|
50
|
+
Runs on `portable`.
|
|
51
|
+
|
|
52
|
+
**Inputs**
|
|
53
|
+
|
|
54
|
+
| name | type | default | range |
|
|
55
|
+
| --- | --- | --- | --- |
|
|
56
|
+
| `inputs` | `any` | | |
|
|
57
|
+
|
|
58
|
+
**Props**
|
|
59
|
+
|
|
60
|
+
| name | type | default | range |
|
|
61
|
+
| --- | --- | --- | --- |
|
|
62
|
+
| `append` | `bool` | `false` | |
|
|
63
|
+
|
|
64
|
+
**Outputs**
|
|
65
|
+
|
|
66
|
+
| name | type | default | range |
|
|
67
|
+
| --- | --- | --- | --- |
|
|
68
|
+
| `output` | `array` | | |
|
|
69
|
+
|
|
70
|
+
### `cascade.core.Null`
|
|
71
|
+
|
|
72
|
+
Null — Passes its input through unchanged
|
|
73
|
+
|
|
74
|
+
Runs on `portable`.
|
|
75
|
+
|
|
76
|
+
**Inputs**
|
|
77
|
+
|
|
78
|
+
| name | type | default | range |
|
|
79
|
+
| --- | --- | --- | --- |
|
|
80
|
+
| `input` | `any` | `null` | |
|
|
81
|
+
|
|
82
|
+
**Outputs**
|
|
83
|
+
|
|
84
|
+
| name | type | default | range |
|
|
85
|
+
| --- | --- | --- | --- |
|
|
86
|
+
| `output` | `any` | | |
|
|
87
|
+
|
|
88
|
+
### `cascade.core.Output`
|
|
89
|
+
|
|
90
|
+
Output — Defines a public graph or subnet output
|
|
91
|
+
|
|
92
|
+
Runs on `portable`.
|
|
93
|
+
|
|
94
|
+
**Inputs**
|
|
95
|
+
|
|
96
|
+
| name | type | default | range |
|
|
97
|
+
| --- | --- | --- | --- |
|
|
98
|
+
| `input` | `any` | `null` | |
|
|
99
|
+
|
|
100
|
+
**Props**
|
|
101
|
+
|
|
102
|
+
| name | type | default | range |
|
|
103
|
+
| --- | --- | --- | --- |
|
|
104
|
+
| `outputIndex` | `int` | `0` | |
|
|
105
|
+
| `outputName` | `string` | `""` | |
|
|
106
|
+
| `dataType` | `string` | `"any"` | |
|
|
107
|
+
|
|
108
|
+
**Outputs**
|
|
109
|
+
|
|
110
|
+
| name | type | default | range |
|
|
111
|
+
| --- | --- | --- | --- |
|
|
112
|
+
| `output` | `any` | | |
|
|
113
|
+
|
|
114
|
+
### `cascade.core.Random`
|
|
115
|
+
|
|
116
|
+
Random — Generate a deterministic unit value from an explicit seed.
|
|
117
|
+
|
|
118
|
+
Runs on `portable`.
|
|
119
|
+
|
|
120
|
+
**Inputs**
|
|
121
|
+
|
|
122
|
+
| name | type | default | range |
|
|
123
|
+
| --- | --- | --- | --- |
|
|
124
|
+
| `seed` | `int` | `0` | |
|
|
125
|
+
| `sample` | `int` | `0` | |
|
|
126
|
+
|
|
127
|
+
**Outputs**
|
|
128
|
+
|
|
129
|
+
| name | type | default | range |
|
|
130
|
+
| --- | --- | --- | --- |
|
|
131
|
+
| `value` | `float` | | |
|
|
132
|
+
|
|
133
|
+
### `cascade.core.Remap`
|
|
134
|
+
|
|
135
|
+
Remap — Map a number from one range into another.
|
|
136
|
+
|
|
137
|
+
Runs on `portable`.
|
|
138
|
+
|
|
139
|
+
**Inputs**
|
|
140
|
+
|
|
141
|
+
| name | type | default | range |
|
|
142
|
+
| --- | --- | --- | --- |
|
|
143
|
+
| `value` | `float` | `0` | |
|
|
144
|
+
| `inMin` | `float` | `0` | |
|
|
145
|
+
| `inMax` | `float` | `1` | |
|
|
146
|
+
| `outMin` | `float` | `0` | |
|
|
147
|
+
| `outMax` | `float` | `1` | |
|
|
148
|
+
|
|
149
|
+
**Props**
|
|
150
|
+
|
|
151
|
+
| name | type | default | range |
|
|
152
|
+
| --- | --- | --- | --- |
|
|
153
|
+
| `clamp` | `bool` | `false` | |
|
|
154
|
+
|
|
155
|
+
**Outputs**
|
|
156
|
+
|
|
157
|
+
| name | type | default | range |
|
|
158
|
+
| --- | --- | --- | --- |
|
|
159
|
+
| `result` | `float` | | |
|
|
160
|
+
|
|
161
|
+
### `cascade.core.Select`
|
|
162
|
+
|
|
163
|
+
Select — Selects an array item by index
|
|
164
|
+
|
|
165
|
+
Runs on `portable`.
|
|
166
|
+
|
|
167
|
+
**Inputs**
|
|
168
|
+
|
|
169
|
+
| name | type | default | range |
|
|
170
|
+
| --- | --- | --- | --- |
|
|
171
|
+
| `array` | `array` | `[]` | |
|
|
172
|
+
|
|
173
|
+
**Props**
|
|
174
|
+
|
|
175
|
+
| name | type | default | range |
|
|
176
|
+
| --- | --- | --- | --- |
|
|
177
|
+
| `index` | `int` | `0` | |
|
|
178
|
+
| `wrap` | `bool` | `true` | |
|
|
179
|
+
|
|
180
|
+
**Outputs**
|
|
181
|
+
|
|
182
|
+
| name | type | default | range |
|
|
183
|
+
| --- | --- | --- | --- |
|
|
184
|
+
| `item` | `any` | | |
|
|
185
|
+
| `count` | `int` | | |
|
|
186
|
+
|
|
187
|
+
### `cascade.core.Subnet`
|
|
188
|
+
|
|
189
|
+
Subnet — Contains a nested deterministic graph
|
|
190
|
+
|
|
191
|
+
Runs on `portable`.
|
|
192
|
+
|
|
193
|
+
### `cascade.core.Switch`
|
|
194
|
+
|
|
195
|
+
Switch — Selects one input by index
|
|
196
|
+
|
|
197
|
+
Runs on `portable`.
|
|
198
|
+
|
|
199
|
+
**Inputs**
|
|
200
|
+
|
|
201
|
+
| name | type | default | range |
|
|
202
|
+
| --- | --- | --- | --- |
|
|
203
|
+
| `inputs` | `any` | | |
|
|
204
|
+
|
|
205
|
+
**Props**
|
|
206
|
+
|
|
207
|
+
| name | type | default | range |
|
|
208
|
+
| --- | --- | --- | --- |
|
|
209
|
+
| `index` | `int` | `0` | |
|
|
210
|
+
|
|
211
|
+
**Outputs**
|
|
212
|
+
|
|
213
|
+
| name | type | default | range |
|
|
214
|
+
| --- | --- | --- | --- |
|
|
215
|
+
| `output` | `any` | | |
|
|
216
|
+
|
|
217
|
+
### `cascade.geo.Circle`
|
|
218
|
+
|
|
219
|
+
Circle — A closed circle, as one cubic Bezier chain or as a polygon of divisions segments.
|
|
220
|
+
|
|
221
|
+
Runs on `portable`.
|
|
222
|
+
|
|
223
|
+
**Inputs**
|
|
224
|
+
|
|
225
|
+
| name | type | default | range |
|
|
226
|
+
| --- | --- | --- | --- |
|
|
227
|
+
| `center` | `vec2` | `[0,0]` | |
|
|
228
|
+
| `radius` | `vec2` | `[1,1]` | |
|
|
229
|
+
| `divisions` | `int` | `32` | |
|
|
230
|
+
|
|
231
|
+
**Props**
|
|
232
|
+
|
|
233
|
+
| name | type | default | range |
|
|
234
|
+
| --- | --- | --- | --- |
|
|
235
|
+
| `type` | `string` | `"bezier"` | |
|
|
236
|
+
|
|
237
|
+
**Outputs**
|
|
238
|
+
|
|
239
|
+
| name | type | default | range |
|
|
240
|
+
| --- | --- | --- | --- |
|
|
241
|
+
| `geometry` | `geometry` | | |
|
|
242
|
+
|
|
243
|
+
### `cascade.geo.CopyToPoints`
|
|
244
|
+
|
|
245
|
+
Copy to Points — Instance one geometry onto every point of another.
|
|
246
|
+
|
|
247
|
+
Runs on `portable`.
|
|
248
|
+
|
|
249
|
+
**Inputs**
|
|
250
|
+
|
|
251
|
+
| name | type | default | range |
|
|
252
|
+
| --- | --- | --- | --- |
|
|
253
|
+
| `source` | `geometry` | | |
|
|
254
|
+
| `target` | `geometry` | | |
|
|
255
|
+
|
|
256
|
+
**Props**
|
|
257
|
+
|
|
258
|
+
| name | type | default | range |
|
|
259
|
+
| --- | --- | --- | --- |
|
|
260
|
+
| `targetGroup` | `string` | `""` | |
|
|
261
|
+
| `useTargetOrientations` | `bool` | `true` | |
|
|
262
|
+
|
|
263
|
+
**Outputs**
|
|
264
|
+
|
|
265
|
+
| name | type | default | range |
|
|
266
|
+
| --- | --- | --- | --- |
|
|
267
|
+
| `geometry` | `geometry` | | |
|
|
268
|
+
|
|
269
|
+
### `cascade.geo.Merge`
|
|
270
|
+
|
|
271
|
+
Merge — Concatenate geometries, taking the union of their attributes.
|
|
272
|
+
|
|
273
|
+
Runs on `portable`.
|
|
274
|
+
|
|
275
|
+
**Inputs**
|
|
276
|
+
|
|
277
|
+
| name | type | default | range |
|
|
278
|
+
| --- | --- | --- | --- |
|
|
279
|
+
| `inputs` | `geometry` | | |
|
|
280
|
+
|
|
281
|
+
**Outputs**
|
|
282
|
+
|
|
283
|
+
| name | type | default | range |
|
|
284
|
+
| --- | --- | --- | --- |
|
|
285
|
+
| `geometry` | `geometry` | | |
|
|
286
|
+
|
|
287
|
+
### `cascade.geo.Rectangle`
|
|
288
|
+
|
|
289
|
+
Rectangle — A closed four-point polygon, counter-clockwise from bottom-left.
|
|
290
|
+
|
|
291
|
+
Runs on `portable`.
|
|
292
|
+
|
|
293
|
+
**Inputs**
|
|
294
|
+
|
|
295
|
+
| name | type | default | range |
|
|
296
|
+
| --- | --- | --- | --- |
|
|
297
|
+
| `size` | `vec2` | `[1,1]` | |
|
|
298
|
+
| `center` | `vec2` | `[0,0]` | |
|
|
299
|
+
|
|
300
|
+
**Outputs**
|
|
301
|
+
|
|
302
|
+
| name | type | default | range |
|
|
303
|
+
| --- | --- | --- | --- |
|
|
304
|
+
| `geometry` | `geometry` | | |
|
|
305
|
+
|
|
306
|
+
### `cascade.geo.SvgExport`
|
|
307
|
+
|
|
308
|
+
SVG Export — Write geometry as an SVG document, one group element per group.
|
|
309
|
+
|
|
310
|
+
Runs on `portable`.
|
|
311
|
+
|
|
312
|
+
**Inputs**
|
|
313
|
+
|
|
314
|
+
| name | type | default | range |
|
|
315
|
+
| --- | --- | --- | --- |
|
|
316
|
+
| `geometry` | `geometry` | | |
|
|
317
|
+
|
|
318
|
+
**Props**
|
|
319
|
+
|
|
320
|
+
| name | type | default | range |
|
|
321
|
+
| --- | --- | --- | --- |
|
|
322
|
+
| `filename` | `string` | `"geometry.svg"` | |
|
|
323
|
+
| `width` | `float` | `0` | |
|
|
324
|
+
| `height` | `float` | `0` | |
|
|
325
|
+
| `margin` | `float` | `0` | |
|
|
326
|
+
| `stroke` | `color` | `[0,0,0,1]` | |
|
|
327
|
+
| `strokeWidth` | `float` | `1` | |
|
|
328
|
+
| `opacity` | `float` | `1` | 0…1 |
|
|
329
|
+
| `fillMode` | `string` | `"none"` | |
|
|
330
|
+
| `fill` | `color` | `[1,1,1,1]` | |
|
|
331
|
+
| `pointRadius` | `float` | `0.5` | |
|
|
332
|
+
| `precision` | `int` | `3` | 0…15 |
|
|
333
|
+
|
|
334
|
+
**Outputs**
|
|
335
|
+
|
|
336
|
+
| name | type | default | range |
|
|
337
|
+
| --- | --- | --- | --- |
|
|
338
|
+
| `svg` | `string` | | |
|
|
339
|
+
| `asset` | `asset` | | |
|
|
340
|
+
|
|
341
|
+
### `cascade.geo.Transform`
|
|
342
|
+
|
|
343
|
+
Transform — Translate, rotate and scale geometry about a pivot.
|
|
344
|
+
|
|
345
|
+
Runs on `portable`.
|
|
346
|
+
|
|
347
|
+
**Inputs**
|
|
348
|
+
|
|
349
|
+
| name | type | default | range |
|
|
350
|
+
| --- | --- | --- | --- |
|
|
351
|
+
| `geometry` | `geometry` | | |
|
|
352
|
+
| `translate` | `vec2` | `[0,0]` | |
|
|
353
|
+
| `rotate` | `float` | `0` | |
|
|
354
|
+
| `scale` | `vec2` | `[1,1]` | |
|
|
355
|
+
| `pivot` | `vec2` | `[0,0]` | |
|
|
356
|
+
|
|
357
|
+
**Outputs**
|
|
358
|
+
|
|
359
|
+
| name | type | default | range |
|
|
360
|
+
| --- | --- | --- | --- |
|
|
361
|
+
| `geometry` | `geometry` | | |
|
|
362
|
+
|
|
363
|
+
## Studio node libraries
|
|
364
|
+
|
|
365
|
+
Class-based nodes, available in Studio. Their parameters are declared in the
|
|
366
|
+
class rather than in a literal, so they are listed here by name only — select
|
|
367
|
+
one in Studio and read the **Definition** panel for its ports, or open the class
|
|
368
|
+
under `src/nodes/<library>/nodes/`.
|
|
369
|
+
|
|
370
|
+
### Core — `cascade.core.*`
|
|
371
|
+
|
|
372
|
+
**Routing.** `Switch` (Switch between multiple inputs by index), `Merge` (Combine multiple inputs into an array), `Null` (Pass an input through unchanged)
|
|
373
|
+
|
|
374
|
+
**Utility.** `Random` (Generate a deterministic value from a seed), `Remap` (Map a number from one range into another), `Select` (Pick an item from an array by index), `Freeze` (Capture and lock a value)
|
|
375
|
+
|
|
376
|
+
**Network.** `Subnet` (Network container for organizing nodes), `Input` (External input to a subnet), `Output` (Defines subnet output)
|
|
377
|
+
|
|
378
|
+
### Geometry — `cascade.geo.*`
|
|
379
|
+
|
|
380
|
+
**Geometry.** `cascade.geo.Rectangle` (A closed four-point polygon, counter-clockwise from bottom-left.), `cascade.geo.Circle` (A closed circle, as one cubic Bezier chain or as a polygon of divisions segments.), `cascade.geo.Transform` (Translate, rotate and scale geometry about a pivot.), `cascade.geo.Merge` (Concatenate geometries, taking the union of their attributes.), `cascade.geo.CopyToPoints` (Instance one geometry onto every point of another.), `cascade.geo.SvgExport` (Write geometry as an SVG document, one group element per group.)
|
|
381
|
+
|
|
382
|
+
### Image — `cascade.image.*`
|
|
383
|
+
|
|
384
|
+
**Create.** `Image` (Load images from files), `Color` (Create a solid color canvas), `Checkers` (Generate a checkerboard pattern), `Noise` (Generate procedural noise patterns), `Ramp` (Generate color ramps), `Text` (Render text with customizable font and style)
|
|
385
|
+
|
|
386
|
+
**Filter.** `Blur` (Gaussian blur), `NormalMap` (Compute normal map from height map)
|
|
387
|
+
|
|
388
|
+
**Transform.** `Transform` (2D rotation, translation, and scaling), `Resize` (Scale or resize an image)
|
|
389
|
+
|
|
390
|
+
**Composite.** `Composite` (Blend two images together)
|
|
391
|
+
## A project's own nodes
|
|
392
|
+
|
|
393
|
+
Not listed here, because they belong to the project rather than to Cascade. Ask
|
|
394
|
+
the running server: `GET /api/nodes` returns each module with its `runsOn` and
|
|
395
|
+
icon, and `GET /api/nodes/<name>/index.ts` returns its source.
|
package/doc/PROJECT_AUTHORING.md
CHANGED
|
@@ -37,6 +37,7 @@ The portable project shape is:
|
|
|
37
37
|
my-artwork/
|
|
38
38
|
├── cascade.json
|
|
39
39
|
├── index.cascade
|
|
40
|
+
├── AGENTS.md # written by `cascade new`, for agents working in the project
|
|
40
41
|
├── nodes/
|
|
41
42
|
├── panels/ # optional Studio-only extensions
|
|
42
43
|
├── assets/
|
|
@@ -153,6 +154,19 @@ The proxy accepts HTTPS only, refuses undeclared hosts, strips caller-supplied a
|
|
|
153
154
|
|
|
154
155
|
## Add a custom node
|
|
155
156
|
|
|
157
|
+
Before writing one, check whether you need one. A parameter can hold an expression, so anything time-based is usually a parameter rather than a node. See [Animate a parameter](#animate-a-parameter). A node earns its place when it produces geometry or pixels, or when several parameters share a computation. The built-in library is listed in `NODE_REFERENCE.md`, generated from the definitions themselves; read that before searching for what a node does.
|
|
158
|
+
|
|
159
|
+
There are two styles. Write **definition-v1** for anything new; the dynamic style is what existing project nodes use and it still cooks everywhere.
|
|
160
|
+
|
|
161
|
+
| | Cooked by | Checked by |
|
|
162
|
+
| --- | --- | --- |
|
|
163
|
+
| **definition-v1**: a literal `definition` plus `execute(context)` | the deterministic runtime through `cascade run`, and Studio, which builds the ports from the literal | `cascade check`, which requires this style |
|
|
164
|
+
| **dynamic**: `execute(node, graph)` declaring its own ports and parameters | Studio, and `cascade run` including `--frames` | `cascade validate` and a cook |
|
|
165
|
+
|
|
166
|
+
Studio cooks both, and a Studio graph may mix them. `cascade run` picks one host per document: a graph whose project modules are all definition-v1 runs through the deterministic runtime, and anything else runs through the compatibility engine — which is also why `--frames` is refused on an all-definition-v1 graph, the deterministic runtime owning its own clock. The `AGENTS.md` that `cascade new` writes into a project states which style that project expects, and it is the file to believe over this one for a specific project.
|
|
167
|
+
|
|
168
|
+
### definition-v1
|
|
169
|
+
|
|
156
170
|
Create `nodes/Multiply/index.ts`. The directory name defines the module ID `project.Multiply`.
|
|
157
171
|
|
|
158
172
|
```ts
|
|
@@ -177,7 +191,62 @@ export function execute(context: NodeExecutionContext<typeof definition>) {
|
|
|
177
191
|
}
|
|
178
192
|
```
|
|
179
193
|
|
|
180
|
-
The definition is the complete static interface. Cascade and code agents can inspect it without importing the module, build the node UI, validate graph connections, and type-check `execute`.
|
|
194
|
+
The definition is the complete static interface. Cascade and code agents can inspect it without importing the module, build the node UI, validate graph connections, and type-check `execute`. In this style `execute` computes and nothing else: it does not create ports, props, or types.
|
|
195
|
+
|
|
196
|
+
Parameters are declared as `props`, beside `inputs` and `outputs`, and each takes a `type` and a `default` plus optional `label`, `description`, `min`, `max`, `step`, `control`, `options`, and `accept`:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
export const definition = {
|
|
200
|
+
apiVersion: 1,
|
|
201
|
+
label: 'Blend',
|
|
202
|
+
runsOn: 'portable',
|
|
203
|
+
inputs: { value: { kind: 'data', type: 'float', default: 0 } },
|
|
204
|
+
props: { blend: { type: 'float', default: 0.5, min: 0, max: 1, label: 'Blend' } },
|
|
205
|
+
outputs: { result: { kind: 'data', type: 'float' } }
|
|
206
|
+
} as const satisfies NodeDefinition;
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### Prefer the vector types
|
|
210
|
+
|
|
211
|
+
Anything with an x and a y is **one** `vec2`, not two floats. `vec3` and `vec4` likewise, with `vec2i`, `vec3i` and `vec4i` for integer counts and pixel sizes. Positions, offsets, sizes, scales, resolutions and colours with alpha are single ports.
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
// Two props that are really one value
|
|
215
|
+
props: { offset_x: { type: 'float', default: 0 }, offset_y: { type: 'float', default: 0 } }
|
|
216
|
+
|
|
217
|
+
// One prop the type system understands
|
|
218
|
+
props: { offset: { type: 'vec2', default: [0, 0] } }
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The reason is not tidiness. Two floats cannot connect to a `vec2` output, take two Inspector rows instead of one control, need two keyframes to animate one movement, and allow a graph to carry an x without its y. The type system knows what a `vec2` is; nothing tells it that `offset_x` and `offset_y` belong together.
|
|
222
|
+
|
|
223
|
+
Keep them separate only when the components differ in kind or in range — a `width` and a `depth` that mean different things are two props, not a `vec2`.
|
|
224
|
+
|
|
225
|
+
### dynamic
|
|
226
|
+
|
|
227
|
+
A dynamic module declares its interface imperatively, inside `execute`, which runs once to discover the interface and again on every cook. There is no `definition` export; `runsOn` and `icon` are plain exports.
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
import { saveImage, cachePath } from 'cascade/io';
|
|
231
|
+
|
|
232
|
+
export const icon = 'Circle'; // a Lucide icon name
|
|
233
|
+
export const runsOn = 'portable'; // 'portable' | 'browser' | 'server'
|
|
234
|
+
|
|
235
|
+
export async function execute(node: any) {
|
|
236
|
+
const size = node.param('size', 1024, { min: 16, max: 4096, step: 16, type: 'int' }).value;
|
|
237
|
+
const input = node.in('value', 0, { type: 'float' }).value;
|
|
238
|
+
const out = node.out('image', 'param', { type: 'image' });
|
|
239
|
+
|
|
240
|
+
const canvas = new OffscreenCanvas(size, size);
|
|
241
|
+
// ... draw ...
|
|
242
|
+
const path = await saveImage(canvas, cachePath(node.id, '.png'));
|
|
243
|
+
out.setValue({ path, size: [size, size], channels: 'rgb', depth: 'u8', space: 'srgb' });
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
`param()` is a method on the node the engine hands to `execute`, not an import. It is re-declared on every cook, so it never resets a value, an expression, or a keyframe someone set: reading `.value` gives the *resolved* value for the current frame, whichever of the three bindings is in force. Top-level statements outside `execute` do not run, because the loader imports a real ES module and needs the `execute` export.
|
|
248
|
+
|
|
249
|
+
Prefer `new OffscreenCanvas(width, height)` to `document.createElement('canvas')` when both hosts could run the node, and keep `runsOn: 'browser'` for code that genuinely needs the page. Web technology comes first, meaning Canvas 2D, WebGL and WebGPU. A Python stage is for work that cannot run in a browser at all, such as an exotic ML library. A Python stage costs a process spawn and a round trip per cook, which is invisible on one still frame and fatal to dragging a parameter or playing an animation.
|
|
181
250
|
|
|
182
251
|
Choose the narrowest execution locus:
|
|
183
252
|
|
|
@@ -231,8 +300,65 @@ Keep implementation nodes behind that boundary so a server or custom frontend
|
|
|
231
300
|
does not depend on internal IDs. A child Input/Output node's index defines the
|
|
232
301
|
matching `input_N`/`output_N` port on its parent Subnet.
|
|
233
302
|
|
|
234
|
-
Portable nodes must not read ambient time or randomness.
|
|
235
|
-
|
|
303
|
+
Portable nodes must not read ambient time or randomness. Time reaches a node as
|
|
304
|
+
an expression or a keyframe on a parameter, or through a root input; variation
|
|
305
|
+
comes from seeded `Random`.
|
|
306
|
+
|
|
307
|
+
`NODE_REFERENCE.md` carries the full declarations for these and for the
|
|
308
|
+
`cascade.geo.*` set, generated from the definitions, so the table above is a
|
|
309
|
+
summary rather than the source.
|
|
310
|
+
|
|
311
|
+
## Animate a parameter
|
|
312
|
+
|
|
313
|
+
A parameter holds up to three things, and they resolve in one order: a **keyframe channel** first, then an **expression**, then the stored **value**. A channel therefore overrides an expression without erasing it: empty the channel and the expression comes back.
|
|
314
|
+
|
|
315
|
+
Expressions use Houdini's variables:
|
|
316
|
+
|
|
317
|
+
| | |
|
|
318
|
+
| --- | --- |
|
|
319
|
+
| `$F` | frame, integer |
|
|
320
|
+
| `$FF` | frame, fractional |
|
|
321
|
+
| `$T` | seconds, zero on the first frame — `($FF - 1) / $FPS` |
|
|
322
|
+
| `$FPS` | rate |
|
|
323
|
+
| `ch("NODE/parm")`, `ch("./parm")` | read another parameter; `chs()` for a string, `chv()` for a vector |
|
|
324
|
+
|
|
325
|
+
The maths library is in scope bare, so `sin(x)` rather than `Math.sin(x)`, with `PI`, `TAU` and `E`. Note that **angles are radians**; `sind`, `cosd`, `tand`, `radians()` and `degrees()` are there for formulae carried over from Houdini. `fit`, `fit01`, `clamp`, `lerp`, `smooth`, `noise`, `random`, `padzero`, `opexist` and `opinput` are available too.
|
|
326
|
+
|
|
327
|
+
So "oscillate the angle" is `sin($T) * 40` in the `angle` parameter. There is no oscillator node and none is needed. Only `ch()`, `chs()` and `chv()` create a dependency, so a parameter that reads another one recooks when it changes.
|
|
328
|
+
|
|
329
|
+
Keyframes are set on a parameter in the Inspector: **alt-click** sets a key at the playhead, **ctrl-click** deletes the key on the current frame, **right-click** opens the Timeline focused on that channel, and the diamond beside the parameter toggles a key for anyone not using a modifier. Interpolation belongs to the key on the left of a segment and is `constant`, `linear`, or `smooth`. Smooth is the default: a Hermite curve with automatic tangents, flat at the first and last key. Outside the keyed range the channel holds its end values.
|
|
330
|
+
|
|
331
|
+
In the document, a channel sits in the node's `props` next to the value and the expression, and `interpolation` is omitted where it is the `smooth` default:
|
|
332
|
+
|
|
333
|
+
```json
|
|
334
|
+
"props": {
|
|
335
|
+
"angle": {
|
|
336
|
+
"value": 12,
|
|
337
|
+
"expression": "sin($T) * 40",
|
|
338
|
+
"channel": { "keys": [{ "frame": 1, "value": 0, "interpolation": "linear" }, { "frame": 48, "value": 360 }] }
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
`params` holds plain values; a binding needs the object form under `props`. Playback settings, the frame range and loop, belong to the Timeline panel and are not saved with the document.
|
|
344
|
+
|
|
345
|
+
## Run a coding agent in the project
|
|
346
|
+
|
|
347
|
+
Studio can run a coding agent in the project directory, editing the same `nodes/` and `.cascade` files the open graph came from. The document is saved before the prompt is sent, and a watcher reloads the graph in place when the agent rewrites it, so nothing needs a page reload. Studio declines that reload while there are unsaved edits rather than choosing a winner.
|
|
348
|
+
|
|
349
|
+
The project decides what may be launched, in `cascade.json`, using the same `commands` allowlist as shell aliases. A scaffolded project ships without one, so nothing is launchable until it is added:
|
|
350
|
+
|
|
351
|
+
```json
|
|
352
|
+
{
|
|
353
|
+
"name": "My Artwork",
|
|
354
|
+
"commands": { "claude": "claude" },
|
|
355
|
+
"agent": { "claude": { "args": ["--permission-mode", "acceptEdits"] } }
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
An alias maps to an absolute path, a `~`-relative path, or a bare name on `PATH`; project-relative paths are refused. `agent.<alias>.args` adds fixed flags. `claude` defaults to `--permission-mode acceptEdits`, and an explicit empty array launches it bare. The routes are only available on loopback or in an explicitly enabled trusted-host session.
|
|
360
|
+
|
|
361
|
+
The run belongs to the server rather than the browser: closing the tab leaves the agent working, and reopening the panel replays the buffered transcript and rejoins the stream. Node and parameter names are drag sources carrying their expression address, `TRANSFORM` for a node and `TRANSFORM/tx` for its parameter, so a path can be dragged into the console instead of retyped.
|
|
236
362
|
|
|
237
363
|
## Integrate external services and AI
|
|
238
364
|
|
|
@@ -344,6 +470,22 @@ cascade inspect index.cascade
|
|
|
344
470
|
cascade run index.cascade
|
|
345
471
|
```
|
|
346
472
|
|
|
473
|
+
`cascade check` reads definition-v1 modules statically; `cascade validate` checks the document, hierarchy and connections. Neither renders anything, so a green read proves the graph loads and not that it draws. Check a change by running it.
|
|
474
|
+
|
|
475
|
+
Render frames offline with the same command:
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
cascade run index.cascade --frames 1-100
|
|
479
|
+
cascade run index.cascade --frames 1-100x2 --fps 25 --out frames
|
|
480
|
+
cascade run index.cascade --frames 42 --entry-node logo-1024
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
`--frames` takes a range, a stepped range, or a single frame, and refuses a range it cannot parse rather than repairing it. Files are written as `<out>/<node id>.<frame>.<ext>`, zero-padded to at least four digits, into `renders/` unless `--out` says otherwise. One rule whether the graph has one output or three. Every image output with nothing connected downstream is saved, or the outputs of `--entry-node` when one is named. Cascade stops at the image sequence; a directory of numbered frames is what an encoder takes.
|
|
484
|
+
|
|
485
|
+
Offline, drawing goes through Skia: the optional `@napi-rs/canvas` supplies `OffscreenCanvas`, `Image`, `Path2D` and the rest as globals in the Node process, deliberately not `document`, because that is how a node tells which host it is in. This is why a node that draws on an `OffscreenCanvas` needs no second implementation for headless runs, and why the built-in `cascade.image.*` nodes render under `cascade run` as well as in Studio. A graph that draws nothing runs without the renderer installed.
|
|
486
|
+
|
|
487
|
+
`--frames` renders dynamic graphs. A definition-v1 graph runs through the deterministic runtime, which owns its own clock and has no parameter animation, and the flag is refused rather than silently rendering the first frame repeatedly.
|
|
488
|
+
|
|
347
489
|
Applications can use `createRuntime()` from `cascade/runtime` directly. Register node modules and host capabilities, load the graph, mutate inputs or presets, run or trigger it, read outputs, then dispose it. This path loads no Svelte or Studio code and works in a backend service or a custom browser application.
|
|
348
490
|
|
|
349
491
|
Server and browser hosts are deliberately explicit. A graph that uses Python or shell stages belongs on the server or behind an application-defined bridge; the runtime does not silently move computation between environments.
|
|
@@ -353,8 +495,8 @@ Server and browser hosts are deliberately explicit. A graph that uses Python or
|
|
|
353
495
|
Before committing a custom node or graph:
|
|
354
496
|
|
|
355
497
|
1. Type-check the project with its normal TypeScript command.
|
|
356
|
-
2. Run `cascade validate <graph
|
|
357
|
-
3. Run the graph headlessly when its capabilities are available.
|
|
498
|
+
2. Run `cascade validate <graph>`, and `cascade check <graph>` for a definition-v1 project, to check the document plus static definitions, types, hierarchy, and connections without rendering.
|
|
499
|
+
3. Run the graph headlessly when its capabilities are available. This is the step that catches a document that loads, reports its nodes, and draws nothing. The characteristic failure here is silent, so a static pass alone proves little.
|
|
358
500
|
4. Open Studio only for visual inspection or authoring that benefits from the graph UI.
|
|
359
501
|
|
|
360
|
-
|
|
502
|
+
Dynamic modules are not deprecated and 0.3.0 stopped calling them legacy: the two styles are cooked by different hosts, and a project's own `AGENTS.md` says which one it expects. Convert a node when you need what the other style gives, static inspection and `cascade check` on one side or Studio cooking and `--frames` on the other, rather than on a schedule.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@field/cascade",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Visual programming for generative art",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "FIELD.IO <marcus@field.io>",
|
|
@@ -25,9 +25,12 @@
|
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"dist",
|
|
28
|
+
"!dist/**/*.map",
|
|
29
|
+
"CHANGELOG.md",
|
|
28
30
|
"AGENTS.md",
|
|
29
31
|
"ARCHITECTURE.md",
|
|
30
32
|
"DESIGN.md",
|
|
33
|
+
"doc/NODE_REFERENCE.md",
|
|
31
34
|
"doc/PROJECT_AUTHORING.md",
|
|
32
35
|
"README.md",
|
|
33
36
|
"LICENSE"
|
|
@@ -60,6 +63,14 @@
|
|
|
60
63
|
"types": "./dist/runtime/browser.d.ts",
|
|
61
64
|
"default": "./dist/runtime/browser.js"
|
|
62
65
|
},
|
|
66
|
+
"./runtime/expressions": {
|
|
67
|
+
"types": "./dist/runtime/expressions/index.d.ts",
|
|
68
|
+
"default": "./dist/runtime/expressions/index.js"
|
|
69
|
+
},
|
|
70
|
+
"./runtime/animation": {
|
|
71
|
+
"types": "./dist/runtime/animation/index.d.ts",
|
|
72
|
+
"default": "./dist/runtime/animation/index.js"
|
|
73
|
+
},
|
|
63
74
|
"./runtime/definition/extract": {
|
|
64
75
|
"types": "./dist/runtime/definition/extract.d.ts",
|
|
65
76
|
"default": "./dist/runtime/definition/extract.js"
|
|
@@ -68,6 +79,14 @@
|
|
|
68
79
|
"types": "./dist/shell.d.ts",
|
|
69
80
|
"default": "./dist/shell.js"
|
|
70
81
|
},
|
|
82
|
+
"./io": {
|
|
83
|
+
"types": "./dist/io.d.ts",
|
|
84
|
+
"default": "./dist/io.js"
|
|
85
|
+
},
|
|
86
|
+
"./net": {
|
|
87
|
+
"types": "./dist/net.d.ts",
|
|
88
|
+
"default": "./dist/net.js"
|
|
89
|
+
},
|
|
71
90
|
"./stage": {
|
|
72
91
|
"types": "./dist/stage.d.ts",
|
|
73
92
|
"default": "./dist/stage.js"
|
|
@@ -84,14 +103,15 @@
|
|
|
84
103
|
"build:packages": "npm run build --workspace @cascade/contracts && npm run build --workspace @cascade/runtime && node scripts/copy-package-builds.mjs",
|
|
85
104
|
"check:packages": "npm run check --workspace @cascade/contracts && npm run build --workspace @cascade/contracts && npm run check --workspace @cascade/runtime",
|
|
86
105
|
"test:packages": "npm run test --workspace @cascade/contracts && npm run test --workspace @cascade/runtime",
|
|
87
|
-
"build:cli": "npm run build:packages && node scripts/build-cli.mjs",
|
|
106
|
+
"build:cli": "npm run build:packages && node scripts/build-cli.mjs && npm run build:node-reference",
|
|
88
107
|
"prepack": "npm run build",
|
|
89
108
|
"preview": "vite preview",
|
|
90
109
|
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
91
110
|
"test": "vitest",
|
|
92
111
|
"test:run": "vitest run",
|
|
93
112
|
"test:coverage": "vitest run --coverage",
|
|
94
|
-
"test:package": "node scripts/smoke-package.mjs"
|
|
113
|
+
"test:package": "node scripts/smoke-package.mjs",
|
|
114
|
+
"build:node-reference": "tsx scripts/build-node-reference.mjs"
|
|
95
115
|
},
|
|
96
116
|
"dependencies": {
|
|
97
117
|
"esbuild": "^0.28.2",
|
|
@@ -122,5 +142,8 @@
|
|
|
122
142
|
},
|
|
123
143
|
"overrides": {
|
|
124
144
|
"dompurify": "$dompurify"
|
|
145
|
+
},
|
|
146
|
+
"optionalDependencies": {
|
|
147
|
+
"@napi-rs/canvas": "^1.0.8"
|
|
125
148
|
}
|
|
126
149
|
}
|