@fugood/bricks-ctor 2.25.0-beta.60 → 2.25.0-beta.61
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/package.json +4 -28
- package/tools/deploy.ts +19 -176
- package/tools/mcp-server.ts +16 -33
- package/tools/postinstall.ts +21 -292
- package/tools/pull.ts +15 -195
- package/tools/push-config.ts +18 -113
- package/tools/simulator.ts +19 -148
- package/compile/__tests__/config-diff.test.js +0 -100
- package/compile/__tests__/index.test.js +0 -461
- package/compile/__tests__/util.test.js +0 -450
- package/compile/action-name-map.ts +0 -1079
- package/compile/config-diff.ts +0 -155
- package/compile/index.ts +0 -1594
- package/compile/util.ts +0 -482
- package/index.ts +0 -6
- package/skills/bricks-ctor/SKILL.md +0 -38
- package/skills/bricks-ctor/references/animation.md +0 -160
- package/skills/bricks-ctor/references/architecture-patterns.md +0 -88
- package/skills/bricks-ctor/references/automations.md +0 -232
- package/skills/bricks-ctor/references/buttress.md +0 -245
- package/skills/bricks-ctor/references/data-calculation.md +0 -252
- package/skills/bricks-ctor/references/local-sync.md +0 -129
- package/skills/bricks-ctor/references/media-flow.md +0 -165
- package/skills/bricks-ctor/references/remote-data-bank.md +0 -196
- package/skills/bricks-ctor/references/simulator.md +0 -132
- package/skills/bricks-ctor/references/source-editing-tools.md +0 -81
- package/skills/bricks-ctor/references/standby-transition.md +0 -124
- package/skills/bricks-ctor/references/verification-toolchain.md +0 -200
- package/skills/bricks-design/SKILL.md +0 -171
- package/skills/bricks-design/references/architecture-truths.md +0 -132
- package/skills/bricks-design/references/avoiding-complexity.md +0 -91
- package/skills/bricks-design/references/design-critique.md +0 -195
- package/skills/bricks-design/references/design-languages.md +0 -265
- package/skills/bricks-design/references/performance.md +0 -116
- package/skills/bricks-design/references/presentation-and-slideshow.md +0 -137
- package/skills/bricks-design/references/translating-inputs.md +0 -152
- package/skills/bricks-design/references/variations-and-tweaks.md +0 -124
- package/skills/bricks-design/references/when-the-brief-is-branded.md +0 -284
- package/skills/bricks-design/references/when-the-brief-is-vague.md +0 -85
- package/skills/bricks-design/references/workflow.md +0 -134
- package/skills/bricks-ux/SKILL.md +0 -114
- package/skills/bricks-ux/references/accessibility.md +0 -162
- package/skills/bricks-ux/references/flow-states.md +0 -175
- package/skills/bricks-ux/references/interaction-archetypes.md +0 -189
- package/skills/bricks-ux/references/monitoring-screens.md +0 -153
- package/skills/bricks-ux/references/pressable-composition.md +0 -126
- package/skills/bricks-ux/references/user-journey.md +0 -168
- package/skills/bricks-ux/references/ux-critique.md +0 -256
- package/skills/rive-marketplace/SKILL.md +0 -99
- package/tools/__tests__/_cli-error.test.ts +0 -35
- package/tools/__tests__/_mcp-config.test.ts +0 -67
- package/tools/__tests__/pull.test.ts +0 -108
- package/tools/_cli-error.ts +0 -17
- package/tools/_edits-log.ts +0 -41
- package/tools/_git-author.ts +0 -37
- package/tools/_last-pushed-commit.ts +0 -28
- package/tools/_mcp-config.ts +0 -42
- package/tools/_shell.ts +0 -180
- package/tools/icons/.gitattributes +0 -1
- package/tools/icons/fa6pro-glyphmap.json +0 -4686
- package/tools/icons/fa6pro-meta.json +0 -1
- package/tools/mcp-env.ts +0 -13
- package/tools/mcp-tools/__tests__/data-calc-editing.test.js +0 -516
- package/tools/mcp-tools/__tests__/entry-editing.test.js +0 -866
- package/tools/mcp-tools/__tests__/huggingface.test.ts +0 -49
- package/tools/mcp-tools/__tests__/icons.test.ts +0 -21
- package/tools/mcp-tools/__tests__/mcp-env.test.js +0 -19
- package/tools/mcp-tools/_editing-helpers.ts +0 -98
- package/tools/mcp-tools/_verify.ts +0 -50
- package/tools/mcp-tools/compile.ts +0 -104
- package/tools/mcp-tools/data-calc-editing.ts +0 -1311
- package/tools/mcp-tools/entry-editing.ts +0 -2297
- package/tools/mcp-tools/huggingface.ts +0 -772
- package/tools/mcp-tools/icons.ts +0 -97
- package/tools/mcp-tools/lottie.ts +0 -102
- package/tools/mcp-tools/media.ts +0 -113
- package/tools/simulator-main.mjs +0 -488
- package/tools/simulator-preload.cjs +0 -16
- package/types/animation.d.ts +0 -116
- package/types/automation.d.ts +0 -231
- package/types/brick-base.d.ts +0 -80
- package/types/bricks/Camera.d.ts +0 -246
- package/types/bricks/Chart.d.ts +0 -372
- package/types/bricks/GenerativeMedia.d.ts +0 -290
- package/types/bricks/Icon.d.ts +0 -98
- package/types/bricks/Image.d.ts +0 -126
- package/types/bricks/Items.d.ts +0 -480
- package/types/bricks/Lottie.d.ts +0 -168
- package/types/bricks/Maps.d.ts +0 -262
- package/types/bricks/QrCode.d.ts +0 -117
- package/types/bricks/Rect.d.ts +0 -150
- package/types/bricks/RichText.d.ts +0 -131
- package/types/bricks/Rive.d.ts +0 -220
- package/types/bricks/Scene3D.d.ts +0 -676
- package/types/bricks/Sketch.d.ts +0 -256
- package/types/bricks/Slideshow.d.ts +0 -201
- package/types/bricks/Svg.d.ts +0 -99
- package/types/bricks/Text.d.ts +0 -148
- package/types/bricks/TextInput.d.ts +0 -242
- package/types/bricks/Video.d.ts +0 -242
- package/types/bricks/VideoStreaming.d.ts +0 -112
- package/types/bricks/WebRtcStream.d.ts +0 -65
- package/types/bricks/WebView.d.ts +0 -168
- package/types/bricks/index.d.ts +0 -23
- package/types/canvas.d.ts +0 -82
- package/types/common.d.ts +0 -141
- package/types/data-calc-command/base.d.ts +0 -57
- package/types/data-calc-command/collection.d.ts +0 -418
- package/types/data-calc-command/color.d.ts +0 -432
- package/types/data-calc-command/constant.d.ts +0 -50
- package/types/data-calc-command/datetime.d.ts +0 -147
- package/types/data-calc-command/file.d.ts +0 -129
- package/types/data-calc-command/index.d.ts +0 -13
- package/types/data-calc-command/iteratee.d.ts +0 -23
- package/types/data-calc-command/logictype.d.ts +0 -190
- package/types/data-calc-command/math.d.ts +0 -275
- package/types/data-calc-command/object.d.ts +0 -119
- package/types/data-calc-command/sandbox.d.ts +0 -66
- package/types/data-calc-command/string.d.ts +0 -407
- package/types/data-calc-script.d.ts +0 -21
- package/types/data-calc.d.ts +0 -12
- package/types/data.d.ts +0 -97
- package/types/generators/AlarmClock.d.ts +0 -110
- package/types/generators/Assistant.d.ts +0 -640
- package/types/generators/BleCentral.d.ts +0 -247
- package/types/generators/BlePeripheral.d.ts +0 -208
- package/types/generators/CanvasMap.d.ts +0 -74
- package/types/generators/CastlesPay.d.ts +0 -87
- package/types/generators/DataBank.d.ts +0 -160
- package/types/generators/File.d.ts +0 -432
- package/types/generators/GraphQl.d.ts +0 -132
- package/types/generators/Http.d.ts +0 -222
- package/types/generators/HttpServer.d.ts +0 -230
- package/types/generators/Information.d.ts +0 -103
- package/types/generators/Intent.d.ts +0 -168
- package/types/generators/Iterator.d.ts +0 -108
- package/types/generators/Keyboard.d.ts +0 -105
- package/types/generators/LlmAnthropicCompat.d.ts +0 -212
- package/types/generators/LlmAppleBuiltin.d.ts +0 -159
- package/types/generators/LlmGgml.d.ts +0 -903
- package/types/generators/LlmMediaTekNeuroPilot.d.ts +0 -235
- package/types/generators/LlmMlx.d.ts +0 -228
- package/types/generators/LlmOnnx.d.ts +0 -213
- package/types/generators/LlmOpenAiCompat.d.ts +0 -312
- package/types/generators/LlmQualcommAiEngine.d.ts +0 -247
- package/types/generators/Mcp.d.ts +0 -637
- package/types/generators/McpServer.d.ts +0 -289
- package/types/generators/MediaFlow.d.ts +0 -170
- package/types/generators/MqttBroker.d.ts +0 -141
- package/types/generators/MqttClient.d.ts +0 -141
- package/types/generators/Question.d.ts +0 -408
- package/types/generators/RealtimeTranscription.d.ts +0 -287
- package/types/generators/RerankerGgml.d.ts +0 -195
- package/types/generators/SerialPort.d.ts +0 -151
- package/types/generators/SoundPlayer.d.ts +0 -94
- package/types/generators/SoundRecorder.d.ts +0 -139
- package/types/generators/SpeechToTextGgml.d.ts +0 -424
- package/types/generators/SpeechToTextOnnx.d.ts +0 -236
- package/types/generators/SpeechToTextPlatform.d.ts +0 -85
- package/types/generators/SqLite.d.ts +0 -159
- package/types/generators/Step.d.ts +0 -107
- package/types/generators/SttAppleBuiltin.d.ts +0 -153
- package/types/generators/Tcp.d.ts +0 -126
- package/types/generators/TcpServer.d.ts +0 -147
- package/types/generators/TextToSpeechAppleBuiltin.d.ts +0 -127
- package/types/generators/TextToSpeechGgml.d.ts +0 -221
- package/types/generators/TextToSpeechOnnx.d.ts +0 -178
- package/types/generators/TextToSpeechOpenAiLike.d.ts +0 -121
- package/types/generators/ThermalPrinter.d.ts +0 -193
- package/types/generators/Tick.d.ts +0 -83
- package/types/generators/Udp.d.ts +0 -120
- package/types/generators/VadGgml.d.ts +0 -260
- package/types/generators/VadOnnx.d.ts +0 -231
- package/types/generators/VadTraditional.d.ts +0 -138
- package/types/generators/VectorStore.d.ts +0 -257
- package/types/generators/Watchdog.d.ts +0 -107
- package/types/generators/WebCrawler.d.ts +0 -103
- package/types/generators/WebRtc.d.ts +0 -181
- package/types/generators/WebSocket.d.ts +0 -148
- package/types/generators/index.d.ts +0 -57
- package/types/index.d.ts +0 -13
- package/types/subspace.d.ts +0 -60
- package/types/switch.d.ts +0 -51
- package/types/system.d.ts +0 -707
- package/utils/__tests__/calc.test.js +0 -25
- package/utils/__tests__/id.test.js +0 -154
- package/utils/calc.ts +0 -130
- package/utils/data.ts +0 -495
- package/utils/event-props.ts +0 -912
- package/utils/id.ts +0 -133
package/compile/util.ts
DELETED
|
@@ -1,482 +0,0 @@
|
|
|
1
|
-
import { makeSeededId } from '../utils/id'
|
|
2
|
-
|
|
3
|
-
type ScriptConfig = {
|
|
4
|
-
title?: string
|
|
5
|
-
note?: string
|
|
6
|
-
inputs: Record<string, string>
|
|
7
|
-
enable_async: boolean
|
|
8
|
-
trigger_mode?: 'auto' | 'manual'
|
|
9
|
-
disabled_triggers: Record<string, boolean>
|
|
10
|
-
output: string | null
|
|
11
|
-
outputs: Record<string, string[]>
|
|
12
|
-
error: string | null
|
|
13
|
-
code: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const errorMsg = 'Not allow duplicate set property id between inputs / outputs / output / error.'
|
|
17
|
-
|
|
18
|
-
export const validateConfig = (config: ScriptConfig) => {
|
|
19
|
-
// Skip input/output overlap validation in manual mode (allows same data node in both)
|
|
20
|
-
if (config.trigger_mode === 'manual') return
|
|
21
|
-
// `inputs` is keyed by data-node id with the OBJECT_SET path as the *value*. The overlap
|
|
22
|
-
// check is "is this id also an input?" — a key-existence question — so test key presence,
|
|
23
|
-
// not the path's truthiness. An empty path ('' = OBJECT_SET's default "set whole object")
|
|
24
|
-
// is a legitimate input value that would otherwise slip the overlap guard.
|
|
25
|
-
const isInput = (id: string) => Object.prototype.hasOwnProperty.call(config.inputs, id)
|
|
26
|
-
if (config.error && isInput(config.error)) {
|
|
27
|
-
throw new Error(`${errorMsg}. key: error`)
|
|
28
|
-
}
|
|
29
|
-
if (config.output && isInput(config.output)) {
|
|
30
|
-
throw new Error(`${errorMsg}. key: output`)
|
|
31
|
-
}
|
|
32
|
-
if (Object.values(config.outputs).some((value) => value.some(isInput))) {
|
|
33
|
-
throw new Error(`${errorMsg}. key: outputs`)
|
|
34
|
-
}
|
|
35
|
-
// The same data-node id reused across the output-side targets (output / error / outputs)
|
|
36
|
-
// also collides: generateCalulationMap spreads their node objects last-wins, so the later
|
|
37
|
-
// one silently overwrites the earlier wiring (e.g. error == output drops the error change
|
|
38
|
-
// link). The checks above only compare against `inputs`, so guard the output-side pairs
|
|
39
|
-
// too. (The same id appearing in multiple `outputs` entries is a supported last-wins case
|
|
40
|
-
// and stays allowed.)
|
|
41
|
-
if (config.error && config.output && config.error === config.output) {
|
|
42
|
-
throw new Error(`${errorMsg}. key: error/output`)
|
|
43
|
-
}
|
|
44
|
-
const outputsIds = Object.values(config.outputs).flat()
|
|
45
|
-
if (config.output && outputsIds.includes(config.output)) {
|
|
46
|
-
throw new Error(`${errorMsg}. key: output/outputs`)
|
|
47
|
-
}
|
|
48
|
-
if (config.error && outputsIds.includes(config.error)) {
|
|
49
|
-
throw new Error(`${errorMsg}. key: error/outputs`)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const padding = 15
|
|
54
|
-
const layerXInterval = 300
|
|
55
|
-
const layerYInterval = 150
|
|
56
|
-
|
|
57
|
-
// Direction A — first-class script node (see local-plan/PLAN-data-calculation-refactor.md).
|
|
58
|
-
//
|
|
59
|
-
// `generateCalulationMap` keeps emitting the legacy OBJECT_SET → SANDBOX_RUN_JAVASCRIPT →
|
|
60
|
-
// SANDBOX_GET_*/OBJECT_GET expansion in `map` (consumed by older runtimes). In parallel,
|
|
61
|
-
// `generateScriptMap` derives an equivalent single-node graph in `script_map` that a newer
|
|
62
|
-
// runtime prefers: one `command-node-script` node that assembles `inputs` from keyed input
|
|
63
|
-
// ports and fans out `error` / `output` / each `outputs` path directly to the target data
|
|
64
|
-
// nodes. Both are byte-stable functions of `script_config`, so codegen (which only reads
|
|
65
|
-
// `script_config`) round-trips losslessly and recompiling unchanged source re-derives an
|
|
66
|
-
// identical `script_map`.
|
|
67
|
-
//
|
|
68
|
-
// Trigger semantics stay edge-level (`disable_trigger_command` on the script node's input
|
|
69
|
-
// edges, same as the legacy OBJECT_SET inputs) so the circular-reference check and the
|
|
70
|
-
// manual-trigger overlay keep working unchanged — only the node count collapses N+3 → 1.
|
|
71
|
-
const generateScriptMap = (config: ScriptConfig, calcId: string) => {
|
|
72
|
-
const scriptId = makeSeededId('property_bank_command', `${calcId}:script`)
|
|
73
|
-
const map: Record<string, any> = {}
|
|
74
|
-
|
|
75
|
-
// Compiled run-time config for the script node. `inputs` maps each input port name (the
|
|
76
|
-
// source data-node id) to its OBJECT_SET path; `outputs` maps each fan-out port name to the
|
|
77
|
-
// OBJECT_GET path it extracts from the return value. The runtime reads these from
|
|
78
|
-
// properties.args, keeping the node `value` reserved purely for incoming input-port values.
|
|
79
|
-
const inputArgs: Record<string, string> = {}
|
|
80
|
-
const outputArgs: Record<string, string> = {}
|
|
81
|
-
|
|
82
|
-
const scriptIn: Record<string, any> = {}
|
|
83
|
-
const scriptOut: Record<string, any> = {}
|
|
84
|
-
|
|
85
|
-
// One in-port per input, keyed by the source data-node id (unique per input, so each input
|
|
86
|
-
// keeps its own `disable_trigger_command` flag — a shared path could not). Manual mode
|
|
87
|
-
// disables every input edge; auto mode honours per-key `disabled_triggers`.
|
|
88
|
-
Object.entries(config.inputs).forEach(([dataNodeId, path]) => {
|
|
89
|
-
inputArgs[dataNodeId] = path
|
|
90
|
-
scriptIn[dataNodeId] = [
|
|
91
|
-
{
|
|
92
|
-
id: dataNodeId,
|
|
93
|
-
port: 'value',
|
|
94
|
-
disable_trigger_command:
|
|
95
|
-
config.trigger_mode === 'manual' || config.disabled_triggers?.[dataNodeId] || undefined,
|
|
96
|
-
},
|
|
97
|
-
]
|
|
98
|
-
map[dataNodeId] = {
|
|
99
|
-
type: 'data-node',
|
|
100
|
-
properties: {},
|
|
101
|
-
in: { change: null },
|
|
102
|
-
out: { value: [{ id: scriptId, port: dataNodeId }] },
|
|
103
|
-
}
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
// Wire an output target data-node's `change` port back from a script out-port, preserving
|
|
107
|
-
// any `out.value` it already has (a node reused as both input and output — allowed in manual
|
|
108
|
-
// mode). Mirrors the last-wins reuse handling in generateCalulationMap's outputs section.
|
|
109
|
-
const wireOutputTarget = (dataNodeId: string, scriptPort: string) => {
|
|
110
|
-
const existing = map[dataNodeId]
|
|
111
|
-
map[dataNodeId] = {
|
|
112
|
-
type: 'data-node',
|
|
113
|
-
properties: {},
|
|
114
|
-
in: { change: [{ id: scriptId, port: scriptPort }] },
|
|
115
|
-
out: { value: existing?.out?.value ?? null },
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (config.error) {
|
|
120
|
-
scriptOut.error = [{ id: config.error, port: 'change' }]
|
|
121
|
-
wireOutputTarget(config.error, 'error')
|
|
122
|
-
}
|
|
123
|
-
if (config.output) {
|
|
124
|
-
scriptOut.output = [{ id: config.output, port: 'change' }]
|
|
125
|
-
wireOutputTarget(config.output, 'output')
|
|
126
|
-
}
|
|
127
|
-
// `out:`-prefixed port names keep `outputs` paths from colliding with the reserved
|
|
128
|
-
// `error` / `output` ports (a path could legitimately be the string "output").
|
|
129
|
-
Object.entries(config.outputs).forEach(([path, pbList]) => {
|
|
130
|
-
const portName = `out:${path}`
|
|
131
|
-
outputArgs[portName] = path
|
|
132
|
-
scriptOut[portName] = pbList.map((pb) => ({ id: pb, port: 'change' }))
|
|
133
|
-
pbList.forEach((pb) => wireOutputTarget(pb, portName))
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
map[scriptId] = {
|
|
137
|
-
type: 'command-node-script',
|
|
138
|
-
title: 'Command: SCRIPT_RUN',
|
|
139
|
-
properties: {
|
|
140
|
-
command: 'SCRIPT_RUN',
|
|
141
|
-
args: {
|
|
142
|
-
code: config.code,
|
|
143
|
-
enable_async: config.enable_async,
|
|
144
|
-
inputs: inputArgs,
|
|
145
|
-
outputs: outputArgs,
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
in: scriptIn,
|
|
149
|
-
out: scriptOut,
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return map
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// `calcId` (the owning script calc's stable id) seeds every derived command-node id, so an
|
|
156
|
-
// unchanged calc recompiles to identical ids and editing one calc never shifts another's —
|
|
157
|
-
// keeping the compiled config byte-stable for change detection. See makeSeededId in utils/id.
|
|
158
|
-
export const generateCalulationMap = (config: ScriptConfig, calcId: string) => {
|
|
159
|
-
validateConfig(config)
|
|
160
|
-
const sandboxId = makeSeededId('property_bank_command', `${calcId}:sandbox-run`)
|
|
161
|
-
const sandboxErrorId = makeSeededId('property_bank_command', `${calcId}:sandbox-error`)
|
|
162
|
-
const sandboxResultId = makeSeededId('property_bank_command', `${calcId}:sandbox-result`)
|
|
163
|
-
|
|
164
|
-
const inputs = Object.entries(config.inputs).reduce(
|
|
165
|
-
(acc, [key, value], index) => {
|
|
166
|
-
const commandId = makeSeededId('property_bank_command', `${calcId}:input:${key}`)
|
|
167
|
-
acc.map[key] = {
|
|
168
|
-
type: 'data-node',
|
|
169
|
-
properties: {},
|
|
170
|
-
in: {
|
|
171
|
-
change: null,
|
|
172
|
-
},
|
|
173
|
-
out: {
|
|
174
|
-
value: [
|
|
175
|
-
{
|
|
176
|
-
id: commandId,
|
|
177
|
-
port: 'value',
|
|
178
|
-
},
|
|
179
|
-
],
|
|
180
|
-
},
|
|
181
|
-
}
|
|
182
|
-
acc.editorInfo[key] = {
|
|
183
|
-
position: { x: padding, y: index * layerYInterval + padding },
|
|
184
|
-
points: {},
|
|
185
|
-
}
|
|
186
|
-
if (acc.prevCommandId) {
|
|
187
|
-
acc.map[acc.prevCommandId].out.result = [
|
|
188
|
-
{
|
|
189
|
-
id: commandId,
|
|
190
|
-
port: 'obj',
|
|
191
|
-
},
|
|
192
|
-
]
|
|
193
|
-
}
|
|
194
|
-
acc.map[commandId] = {
|
|
195
|
-
type: 'command-node-object',
|
|
196
|
-
title: 'Command: OBJECT_SET',
|
|
197
|
-
properties: {
|
|
198
|
-
command: 'OBJECT_SET',
|
|
199
|
-
args: {
|
|
200
|
-
path: value,
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
in: {
|
|
204
|
-
obj: acc.prevCommandId
|
|
205
|
-
? [
|
|
206
|
-
{
|
|
207
|
-
id: acc.prevCommandId,
|
|
208
|
-
port: 'result',
|
|
209
|
-
},
|
|
210
|
-
]
|
|
211
|
-
: null,
|
|
212
|
-
path: null,
|
|
213
|
-
value: [
|
|
214
|
-
{
|
|
215
|
-
id: key,
|
|
216
|
-
port: 'value',
|
|
217
|
-
disable_trigger_command:
|
|
218
|
-
config.trigger_mode === 'manual' || config.disabled_triggers?.[key] || undefined,
|
|
219
|
-
},
|
|
220
|
-
],
|
|
221
|
-
},
|
|
222
|
-
out: {
|
|
223
|
-
result: [
|
|
224
|
-
{
|
|
225
|
-
id: sandboxId,
|
|
226
|
-
port: 'inputs',
|
|
227
|
-
},
|
|
228
|
-
],
|
|
229
|
-
},
|
|
230
|
-
}
|
|
231
|
-
acc.editorInfo[commandId] = {
|
|
232
|
-
position: { x: layerXInterval, y: index * layerYInterval + padding },
|
|
233
|
-
points: {},
|
|
234
|
-
}
|
|
235
|
-
acc.prevCommandId = commandId
|
|
236
|
-
return acc
|
|
237
|
-
},
|
|
238
|
-
{ map: {}, editorInfo: {}, prevCommandId: null } as {
|
|
239
|
-
map: Record<string, any>
|
|
240
|
-
editorInfo: Record<string, any>
|
|
241
|
-
prevCommandId: string | null
|
|
242
|
-
},
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
let y = 0
|
|
246
|
-
const outputs = Object.entries(config.outputs).reduce(
|
|
247
|
-
(acc, [key, pbList], index) => {
|
|
248
|
-
const commandId = makeSeededId('property_bank_command', `${calcId}:output:${key}`)
|
|
249
|
-
acc.commandIdList.push(commandId)
|
|
250
|
-
acc.map[commandId] = {
|
|
251
|
-
type: 'command-node-object',
|
|
252
|
-
title: 'Command: OBJECT_GET',
|
|
253
|
-
properties: {
|
|
254
|
-
command: 'OBJECT_GET',
|
|
255
|
-
args: {
|
|
256
|
-
path: key,
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
in: {
|
|
260
|
-
obj: [
|
|
261
|
-
{
|
|
262
|
-
id: sandboxResultId,
|
|
263
|
-
port: 'result',
|
|
264
|
-
},
|
|
265
|
-
],
|
|
266
|
-
path: null,
|
|
267
|
-
},
|
|
268
|
-
out: {
|
|
269
|
-
result: pbList.map((pb) => ({
|
|
270
|
-
id: pb,
|
|
271
|
-
port: 'change',
|
|
272
|
-
})),
|
|
273
|
-
},
|
|
274
|
-
}
|
|
275
|
-
acc.editorInfo[commandId] = {
|
|
276
|
-
position: {
|
|
277
|
-
x: layerXInterval * 3,
|
|
278
|
-
y: index * layerYInterval + padding,
|
|
279
|
-
},
|
|
280
|
-
points: {},
|
|
281
|
-
}
|
|
282
|
-
pbList.forEach((pb, pbIndex) => {
|
|
283
|
-
// Check if this data node already exists (it might be used as both input and output)
|
|
284
|
-
const existingNode = acc.map[pb] || inputs.map[pb]
|
|
285
|
-
acc.map[pb] = {
|
|
286
|
-
type: 'data-node',
|
|
287
|
-
properties: {},
|
|
288
|
-
in: {
|
|
289
|
-
change: [
|
|
290
|
-
{
|
|
291
|
-
id: commandId,
|
|
292
|
-
port: 'result',
|
|
293
|
-
},
|
|
294
|
-
],
|
|
295
|
-
},
|
|
296
|
-
out: {
|
|
297
|
-
// Preserve existing out.value if node is also used as input
|
|
298
|
-
value: existingNode?.out?.value ?? null,
|
|
299
|
-
},
|
|
300
|
-
}
|
|
301
|
-
acc.editorInfo[pb] = {
|
|
302
|
-
position: {
|
|
303
|
-
x: layerXInterval * 4,
|
|
304
|
-
y: padding + y + index * layerYInterval + pbIndex * layerYInterval,
|
|
305
|
-
},
|
|
306
|
-
points: {},
|
|
307
|
-
}
|
|
308
|
-
if (pbIndex > 0) y += layerYInterval
|
|
309
|
-
})
|
|
310
|
-
return acc
|
|
311
|
-
},
|
|
312
|
-
{ map: {}, editorInfo: {}, commandIdList: [] } as {
|
|
313
|
-
map: Record<string, any>
|
|
314
|
-
editorInfo: Record<string, any>
|
|
315
|
-
commandIdList: string[]
|
|
316
|
-
},
|
|
317
|
-
)
|
|
318
|
-
|
|
319
|
-
return {
|
|
320
|
-
// Newer runtimes prefer this single-node graph; older runtimes fall back to `map` below.
|
|
321
|
-
script_map: generateScriptMap(config, calcId),
|
|
322
|
-
map: {
|
|
323
|
-
...inputs.map,
|
|
324
|
-
[sandboxId]: {
|
|
325
|
-
type: 'command-node-sandbox',
|
|
326
|
-
title: 'Command: SANDBOX_RUN_JAVASCRIPT',
|
|
327
|
-
properties: {
|
|
328
|
-
command: 'SANDBOX_RUN_JAVASCRIPT',
|
|
329
|
-
args: {
|
|
330
|
-
code: config.code,
|
|
331
|
-
enable_async: config.enable_async,
|
|
332
|
-
},
|
|
333
|
-
},
|
|
334
|
-
in: {
|
|
335
|
-
code: null,
|
|
336
|
-
inputs: inputs.prevCommandId
|
|
337
|
-
? [
|
|
338
|
-
{
|
|
339
|
-
id: inputs.prevCommandId,
|
|
340
|
-
port: 'result',
|
|
341
|
-
},
|
|
342
|
-
]
|
|
343
|
-
: [],
|
|
344
|
-
},
|
|
345
|
-
out: {
|
|
346
|
-
result: [
|
|
347
|
-
{
|
|
348
|
-
id: sandboxErrorId,
|
|
349
|
-
port: 'result',
|
|
350
|
-
},
|
|
351
|
-
{
|
|
352
|
-
id: sandboxResultId,
|
|
353
|
-
port: 'result',
|
|
354
|
-
},
|
|
355
|
-
],
|
|
356
|
-
},
|
|
357
|
-
},
|
|
358
|
-
[sandboxErrorId]: {
|
|
359
|
-
type: 'command-node-sandbox',
|
|
360
|
-
title: 'Command: SANDBOX_GET_ERROR',
|
|
361
|
-
properties: {
|
|
362
|
-
command: 'SANDBOX_GET_ERROR',
|
|
363
|
-
},
|
|
364
|
-
in: {
|
|
365
|
-
result: [
|
|
366
|
-
{
|
|
367
|
-
id: sandboxId,
|
|
368
|
-
port: 'result',
|
|
369
|
-
},
|
|
370
|
-
],
|
|
371
|
-
},
|
|
372
|
-
out: {
|
|
373
|
-
result: config.error
|
|
374
|
-
? [
|
|
375
|
-
{
|
|
376
|
-
id: config.error,
|
|
377
|
-
port: 'change',
|
|
378
|
-
},
|
|
379
|
-
]
|
|
380
|
-
: [],
|
|
381
|
-
},
|
|
382
|
-
},
|
|
383
|
-
[sandboxResultId]: {
|
|
384
|
-
type: 'command-node-sandbox',
|
|
385
|
-
title: 'Command: SANDBOX_GET_RETURN_VALUE',
|
|
386
|
-
properties: {
|
|
387
|
-
command: 'SANDBOX_GET_RETURN_VALUE',
|
|
388
|
-
},
|
|
389
|
-
in: {
|
|
390
|
-
result: [
|
|
391
|
-
{
|
|
392
|
-
id: sandboxId,
|
|
393
|
-
port: 'result',
|
|
394
|
-
},
|
|
395
|
-
],
|
|
396
|
-
},
|
|
397
|
-
out: {
|
|
398
|
-
result: (config.output
|
|
399
|
-
? [
|
|
400
|
-
{
|
|
401
|
-
id: config.output,
|
|
402
|
-
port: 'change',
|
|
403
|
-
},
|
|
404
|
-
]
|
|
405
|
-
: []
|
|
406
|
-
).concat(
|
|
407
|
-
outputs.commandIdList.map((commandId) => ({
|
|
408
|
-
id: commandId,
|
|
409
|
-
port: 'obj',
|
|
410
|
-
})),
|
|
411
|
-
),
|
|
412
|
-
},
|
|
413
|
-
},
|
|
414
|
-
|
|
415
|
-
...(config.error && {
|
|
416
|
-
[config.error]: {
|
|
417
|
-
type: 'data-node',
|
|
418
|
-
properties: {},
|
|
419
|
-
in: {
|
|
420
|
-
change: [
|
|
421
|
-
{
|
|
422
|
-
id: sandboxErrorId,
|
|
423
|
-
port: 'result',
|
|
424
|
-
},
|
|
425
|
-
],
|
|
426
|
-
},
|
|
427
|
-
out: {
|
|
428
|
-
// Preserve existing out.value if node is also used as input
|
|
429
|
-
value: inputs.map[config.error]?.out?.value ?? null,
|
|
430
|
-
},
|
|
431
|
-
},
|
|
432
|
-
}),
|
|
433
|
-
...(config.output && {
|
|
434
|
-
[config.output]: {
|
|
435
|
-
type: 'data-node',
|
|
436
|
-
properties: {},
|
|
437
|
-
in: {
|
|
438
|
-
change: [
|
|
439
|
-
{
|
|
440
|
-
id: sandboxResultId,
|
|
441
|
-
port: 'result',
|
|
442
|
-
},
|
|
443
|
-
],
|
|
444
|
-
},
|
|
445
|
-
out: {
|
|
446
|
-
// Preserve existing out.value if node is also used as input
|
|
447
|
-
value: inputs.map[config.output]?.out?.value ?? null,
|
|
448
|
-
},
|
|
449
|
-
},
|
|
450
|
-
}),
|
|
451
|
-
...outputs.map,
|
|
452
|
-
},
|
|
453
|
-
editor_info: {
|
|
454
|
-
...inputs.editorInfo,
|
|
455
|
-
[sandboxId]: {
|
|
456
|
-
position: { x: layerXInterval * 2, y: padding },
|
|
457
|
-
points: {},
|
|
458
|
-
},
|
|
459
|
-
[sandboxErrorId]: {
|
|
460
|
-
position: { x: layerXInterval * 2, y: layerYInterval },
|
|
461
|
-
points: {},
|
|
462
|
-
},
|
|
463
|
-
[sandboxResultId]: {
|
|
464
|
-
position: { x: layerXInterval * 2, y: layerYInterval * 2 },
|
|
465
|
-
points: {},
|
|
466
|
-
},
|
|
467
|
-
...(config.error && {
|
|
468
|
-
[config.error]: {
|
|
469
|
-
position: { x: layerXInterval * 2, y: layerYInterval * 3 },
|
|
470
|
-
points: {},
|
|
471
|
-
},
|
|
472
|
-
}),
|
|
473
|
-
...(config.output && {
|
|
474
|
-
[config.output]: {
|
|
475
|
-
position: { x: layerXInterval * 2, y: layerYInterval * 4 },
|
|
476
|
-
points: {},
|
|
477
|
-
},
|
|
478
|
-
}),
|
|
479
|
-
...outputs.editorInfo,
|
|
480
|
-
},
|
|
481
|
-
}
|
|
482
|
-
}
|
package/index.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export type * from './types'
|
|
2
|
-
|
|
3
|
-
export { makeId } from './utils/id'
|
|
4
|
-
export { generateDataCalculationMapEditorInfo } from './utils/calc'
|
|
5
|
-
export { linkData, useSystemData, createCanvasIdRef } from './utils/data'
|
|
6
|
-
export { templateEventPropsMap } from './utils/event-props'
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: bricks-ctor
|
|
3
|
-
description: Advanced BRICKS configuration knowledge. Covers Standby Transition, Automations (E2E testing), Data Calculation (JS sandbox libraries), Local Sync, Remote Data Bank, Media Flow, Buttress (remote inference), and the verification toolchain (compile, harness-specific preview tool, on-device DevTools, definition-of-done gate). Triggers on multi-device sync, cloud data, media assets, AI offloading, E2E testing, canvas transitions, or verifying project work before declaring done.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# BRICKS Ctor - Advanced Features
|
|
7
|
-
|
|
8
|
-
This skill covers advanced BRICKS features not in the main project instructions.
|
|
9
|
-
|
|
10
|
-
## Rules Index
|
|
11
|
-
|
|
12
|
-
| Rule | Description |
|
|
13
|
-
|------|-------------|
|
|
14
|
-
| [Architecture Patterns](references/architecture-patterns.md) | **Read first** — decompose flows and select patterns |
|
|
15
|
-
| [Source-Editing Tools](references/source-editing-tools.md) | MCP tools for editing entries and data-calcs by AST (new/edit/remove, value grammar, verify) |
|
|
16
|
-
| [Animation](references/animation.md) | Animation system for brick transforms and opacity |
|
|
17
|
-
| [Standby Transition](references/standby-transition.md) | Canvas enter/exit animations |
|
|
18
|
-
| [Automations](references/automations.md) | E2E testing and scheduled tasks |
|
|
19
|
-
| [Data Calculation](references/data-calculation.md) | Wiring contract, trigger semantics, JS sandbox (25+ libraries) |
|
|
20
|
-
| [Local Sync](references/local-sync.md) | LAN device synchronization |
|
|
21
|
-
| [Remote Data Bank](references/remote-data-bank.md) | Cloud data sync and API access |
|
|
22
|
-
| [Media Flow](references/media-flow.md) | Media asset management |
|
|
23
|
-
| [Buttress](references/buttress.md) | Remote inference for AI generators |
|
|
24
|
-
| [Verification Toolchain](references/verification-toolchain.md) | Definition of done, compile, preview tool selection, on-device DevTools, Path 1/2/3 decision rule |
|
|
25
|
-
| [Simulator](references/simulator.md) | Path 1 fidelity — Simulator feature support, fallbacks (Camera/LLM/STT/Vector Store, Buttress disabled), when a green run is enough vs. Path 2 |
|
|
26
|
-
|
|
27
|
-
## Quick Reference
|
|
28
|
-
|
|
29
|
-
- **Complex flows**: See [Architecture Patterns](references/architecture-patterns.md) for decomposing multi-step workflows
|
|
30
|
-
- **Editing entries/data-calcs**: See [Source-Editing Tools](references/source-editing-tools.md) — prefer the MCP editing tools over hand-editing `subspaces/**`
|
|
31
|
-
- **Multi-device**: See [Local Sync](references/local-sync.md) for LAN coordination
|
|
32
|
-
- **Cloud data**: See [Remote Data Bank](references/remote-data-bank.md) for sync and API access
|
|
33
|
-
- **Media assets**: See [Media Flow](references/media-flow.md) for centralized asset management
|
|
34
|
-
- **AI offloading**: See [Buttress](references/buttress.md) for GPU server delegation
|
|
35
|
-
- **E2E testing**: See [Automations](references/automations.md) for test automation
|
|
36
|
-
- **Enter animations**: See [Standby Transition](references/standby-transition.md) for canvas transitions
|
|
37
|
-
- **Verification before done**: See [Verification Toolchain](references/verification-toolchain.md) for the definition-of-done gate and Path 1/2/3 decision rule
|
|
38
|
-
- **Simulator fidelity**: See [Simulator](references/simulator.md) for what the Simulator fakes (Camera, AI generators, Buttress) and when to escalate to a real device
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
# Animation
|
|
2
|
-
|
|
3
|
-
BRICKS Animation system for animating brick transforms and opacity. Animations are defined at the Subspace level and triggered via events or Dynamic Animation actions.
|
|
4
|
-
|
|
5
|
-
## Animation Types
|
|
6
|
-
|
|
7
|
-
### Timing Animation
|
|
8
|
-
Standard duration-based animation with easing.
|
|
9
|
-
|
|
10
|
-
```typescript
|
|
11
|
-
import { makeId } from 'bricks-ctor'
|
|
12
|
-
|
|
13
|
-
const fadeIn: AnimationDef = {
|
|
14
|
-
__typename: 'Animation',
|
|
15
|
-
id: makeId('animation'),
|
|
16
|
-
title: 'Fade In',
|
|
17
|
-
runType: 'once', // 'once' | 'loop'
|
|
18
|
-
property: 'opacity',
|
|
19
|
-
config: {
|
|
20
|
-
__type: 'AnimationTimingConfig',
|
|
21
|
-
toValue: 1,
|
|
22
|
-
duration: 300, // ms
|
|
23
|
-
easing: 'easeOutCubic',
|
|
24
|
-
delay: 0, // ms
|
|
25
|
-
isInteraction: true,
|
|
26
|
-
},
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### Spring Animation
|
|
31
|
-
Physics-based spring animation.
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
const bounce: AnimationDef = {
|
|
35
|
-
__typename: 'Animation',
|
|
36
|
-
id: makeId('animation'),
|
|
37
|
-
title: 'Bounce In',
|
|
38
|
-
property: 'transform.scale',
|
|
39
|
-
config: {
|
|
40
|
-
__type: 'AnimationSpringConfig',
|
|
41
|
-
toValue: 1,
|
|
42
|
-
friction: 7,
|
|
43
|
-
tension: 40,
|
|
44
|
-
},
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Use one spring parameter family per config: `tension/friction`, `speed/bounciness`, or
|
|
49
|
-
`stiffness/damping/mass`.
|
|
50
|
-
|
|
51
|
-
### Decay Animation
|
|
52
|
-
Velocity-based deceleration animation.
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
const slideOut: AnimationDef = {
|
|
56
|
-
__typename: 'Animation',
|
|
57
|
-
id: makeId('animation'),
|
|
58
|
-
title: 'Slide Out',
|
|
59
|
-
property: 'transform.translateX',
|
|
60
|
-
config: {
|
|
61
|
-
__type: 'AnimationDecayConfig',
|
|
62
|
-
toValue: 500,
|
|
63
|
-
velocity: 0.5,
|
|
64
|
-
deceleration: 0.997,
|
|
65
|
-
isInteraction: true,
|
|
66
|
-
},
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Animatable Properties
|
|
71
|
-
|
|
72
|
-
| Property | Description |
|
|
73
|
-
|----------|-------------|
|
|
74
|
-
| `transform.translateX` | Horizontal position offset |
|
|
75
|
-
| `transform.translateY` | Vertical position offset |
|
|
76
|
-
| `transform.scale` | Uniform scale |
|
|
77
|
-
| `transform.scaleX` | Horizontal scale |
|
|
78
|
-
| `transform.scaleY` | Vertical scale |
|
|
79
|
-
| `transform.rotate` | Rotation (degrees) |
|
|
80
|
-
| `transform.rotateX` | X-axis rotation |
|
|
81
|
-
| `transform.rotateY` | Y-axis rotation |
|
|
82
|
-
| `opacity` | Transparency (0-1) |
|
|
83
|
-
|
|
84
|
-
## Easing Functions
|
|
85
|
-
|
|
86
|
-
Standard easing from [easings.net](https://easings.net):
|
|
87
|
-
- `easeInSine`, `easeOutSine`, `easeInOutSine`
|
|
88
|
-
- `easeInQuad`, `easeOutQuad`, `easeInOutQuad`
|
|
89
|
-
- `easeInCubic`, `easeOutCubic`, `easeInOutCubic`
|
|
90
|
-
- `easeInQuart`, `easeOutQuart`, `easeInOutQuart`
|
|
91
|
-
- `easeInQuint`, `easeOutQuint`, `easeInOutQuint`
|
|
92
|
-
- `easeInExpo`, `easeOutExpo`, `easeInOutExpo`
|
|
93
|
-
- `easeInCirc`, `easeOutCirc`, `easeInOutCirc`
|
|
94
|
-
- `easeInBack`, `easeOutBack`, `easeInOutBack`
|
|
95
|
-
- `easeInElastic`, `easeOutElastic`, `easeInOutElastic`
|
|
96
|
-
- `easeInBounce`, `easeOutBounce`, `easeInOutBounce`
|
|
97
|
-
- Custom: `'cubic-bezier(x1, y1, x2, y2)'`
|
|
98
|
-
|
|
99
|
-
## Composed Animations
|
|
100
|
-
|
|
101
|
-
Combine multiple animations in parallel or sequence.
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
const enterAnimation: AnimationComposeDef = {
|
|
105
|
-
__typename: 'AnimationCompose',
|
|
106
|
-
id: makeId('animation'),
|
|
107
|
-
title: 'Enter Animation',
|
|
108
|
-
runType: 'once',
|
|
109
|
-
composeType: 'parallel', // 'parallel' | 'sequence'
|
|
110
|
-
items: [
|
|
111
|
-
() => fadeIn,
|
|
112
|
-
() => scaleUp,
|
|
113
|
-
],
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Brick Animation Events
|
|
118
|
-
|
|
119
|
-
Bricks support automatic animation binding:
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
// In brick definition
|
|
123
|
-
animations: {
|
|
124
|
-
showStart: () => fadeInAnimation, // On brick first render
|
|
125
|
-
standby: () => standbyAnimation, // After standby transition
|
|
126
|
-
breatheStart: () => pulseAnimation, // Breathing effect (looping)
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## Dynamic Animation (Runtime)
|
|
131
|
-
|
|
132
|
-
Trigger animations programmatically via System Action:
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
const runAnimation: EventAction = {
|
|
136
|
-
handler: 'system',
|
|
137
|
-
action: {
|
|
138
|
-
__actionName: 'DYNAMIC_ANIMATION',
|
|
139
|
-
parent: 'System',
|
|
140
|
-
params: [
|
|
141
|
-
{ input: 'brickId', value: () => targetBrick },
|
|
142
|
-
{ input: 'animationId', value: () => pulseAnimation },
|
|
143
|
-
{ input: 'runType', value: 'once' }, // 'once' | 'loop'
|
|
144
|
-
{ input: 'resetInitialValue', value: false },
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
Related actions:
|
|
151
|
-
- `DYNAMIC_ANIMATION_RESET` - Reset animation state
|
|
152
|
-
- `DYNAMIC_ANIMATION_STOP` - Stop running animation
|
|
153
|
-
|
|
154
|
-
## Best Practices
|
|
155
|
-
|
|
156
|
-
1. **Performance**: Keep animations simple, prefer `opacity` and `transform` over layout changes
|
|
157
|
-
2. **Timing**: Use `easeOut` for enter animations, `easeIn` for exit
|
|
158
|
-
3. **Spring animations**: Good for natural, bouncy UI elements
|
|
159
|
-
4. **Looping**: Use `runType: 'loop'` for attention-grabbing elements
|
|
160
|
-
5. **Composition**: Use `sequence` for staged reveals, `parallel` for coordinated effects
|