@fugood/bricks-ctor 2.25.0-beta.7 → 2.25.0-beta.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/package.json +4 -24
  2. package/tools/__tests__/legacy-forwarder.test.js +91 -0
  3. package/tools/_forward.ts +26 -0
  4. package/tools/deploy.ts +3 -164
  5. package/tools/mcp-server.ts +3 -27
  6. package/tools/postinstall.ts +3 -234
  7. package/tools/pull.ts +3 -121
  8. package/tools/push-config.ts +4 -0
  9. package/tools/simulator.ts +4 -0
  10. package/compile/action-name-map.ts +0 -1015
  11. package/compile/index.ts +0 -1278
  12. package/compile/util.ts +0 -358
  13. package/index.ts +0 -6
  14. package/skills/bricks-ctor/SKILL.md +0 -32
  15. package/skills/bricks-ctor/rules/animation.md +0 -159
  16. package/skills/bricks-ctor/rules/architecture-patterns.md +0 -69
  17. package/skills/bricks-ctor/rules/automations.md +0 -221
  18. package/skills/bricks-ctor/rules/buttress.md +0 -156
  19. package/skills/bricks-ctor/rules/data-calculation.md +0 -209
  20. package/skills/bricks-ctor/rules/local-sync.md +0 -129
  21. package/skills/bricks-ctor/rules/media-flow.md +0 -158
  22. package/skills/bricks-ctor/rules/remote-data-bank.md +0 -196
  23. package/skills/bricks-ctor/rules/standby-transition.md +0 -124
  24. package/skills/bricks-design/LICENSE.txt +0 -180
  25. package/skills/bricks-design/SKILL.md +0 -66
  26. package/skills/rive-marketplace/SKILL.md +0 -99
  27. package/tools/_git-author.ts +0 -29
  28. package/tools/_shell.ts +0 -173
  29. package/tools/icons/.gitattributes +0 -1
  30. package/tools/icons/fa6pro-glyphmap.json +0 -4686
  31. package/tools/icons/fa6pro-meta.json +0 -1
  32. package/tools/mcp-tools/compile.ts +0 -92
  33. package/tools/mcp-tools/huggingface.ts +0 -762
  34. package/tools/mcp-tools/icons.ts +0 -81
  35. package/tools/mcp-tools/lottie.ts +0 -102
  36. package/tools/mcp-tools/media.ts +0 -110
  37. package/tools/preview-main.mjs +0 -293
  38. package/tools/preview.ts +0 -150
  39. package/types/animation.ts +0 -100
  40. package/types/automation.ts +0 -235
  41. package/types/brick-base.ts +0 -80
  42. package/types/bricks/Camera.ts +0 -246
  43. package/types/bricks/Chart.ts +0 -372
  44. package/types/bricks/GenerativeMedia.ts +0 -290
  45. package/types/bricks/Icon.ts +0 -98
  46. package/types/bricks/Image.ts +0 -126
  47. package/types/bricks/Items.ts +0 -476
  48. package/types/bricks/Lottie.ts +0 -168
  49. package/types/bricks/Maps.ts +0 -262
  50. package/types/bricks/QrCode.ts +0 -117
  51. package/types/bricks/Rect.ts +0 -150
  52. package/types/bricks/RichText.ts +0 -128
  53. package/types/bricks/Rive.ts +0 -220
  54. package/types/bricks/Sketch.ts +0 -254
  55. package/types/bricks/Slideshow.ts +0 -201
  56. package/types/bricks/Svg.ts +0 -99
  57. package/types/bricks/Text.ts +0 -148
  58. package/types/bricks/TextInput.ts +0 -242
  59. package/types/bricks/Video.ts +0 -175
  60. package/types/bricks/VideoStreaming.ts +0 -112
  61. package/types/bricks/WebRtcStream.ts +0 -65
  62. package/types/bricks/WebView.ts +0 -168
  63. package/types/bricks/index.ts +0 -22
  64. package/types/canvas.ts +0 -82
  65. package/types/common.ts +0 -144
  66. package/types/data-calc-command.ts +0 -7005
  67. package/types/data-calc-script.ts +0 -21
  68. package/types/data-calc.ts +0 -11
  69. package/types/data.ts +0 -95
  70. package/types/generators/AlarmClock.ts +0 -110
  71. package/types/generators/Assistant.ts +0 -621
  72. package/types/generators/BleCentral.ts +0 -247
  73. package/types/generators/BlePeripheral.ts +0 -208
  74. package/types/generators/CanvasMap.ts +0 -74
  75. package/types/generators/CastlesPay.ts +0 -87
  76. package/types/generators/DataBank.ts +0 -160
  77. package/types/generators/File.ts +0 -432
  78. package/types/generators/GraphQl.ts +0 -132
  79. package/types/generators/Http.ts +0 -222
  80. package/types/generators/HttpServer.ts +0 -176
  81. package/types/generators/Information.ts +0 -103
  82. package/types/generators/Intent.ts +0 -168
  83. package/types/generators/Iterator.ts +0 -108
  84. package/types/generators/Keyboard.ts +0 -105
  85. package/types/generators/LlmAnthropicCompat.ts +0 -212
  86. package/types/generators/LlmAppleBuiltin.ts +0 -159
  87. package/types/generators/LlmGgml.ts +0 -861
  88. package/types/generators/LlmMediaTekNeuroPilot.ts +0 -235
  89. package/types/generators/LlmMlx.ts +0 -227
  90. package/types/generators/LlmOnnx.ts +0 -213
  91. package/types/generators/LlmOpenAiCompat.ts +0 -312
  92. package/types/generators/LlmQualcommAiEngine.ts +0 -247
  93. package/types/generators/Mcp.ts +0 -637
  94. package/types/generators/McpServer.ts +0 -289
  95. package/types/generators/MediaFlow.ts +0 -170
  96. package/types/generators/MqttBroker.ts +0 -141
  97. package/types/generators/MqttClient.ts +0 -141
  98. package/types/generators/Question.ts +0 -408
  99. package/types/generators/RealtimeTranscription.ts +0 -287
  100. package/types/generators/RerankerGgml.ts +0 -191
  101. package/types/generators/SerialPort.ts +0 -151
  102. package/types/generators/SoundPlayer.ts +0 -94
  103. package/types/generators/SoundRecorder.ts +0 -130
  104. package/types/generators/SpeechToTextGgml.ts +0 -419
  105. package/types/generators/SpeechToTextOnnx.ts +0 -236
  106. package/types/generators/SpeechToTextPlatform.ts +0 -85
  107. package/types/generators/SqLite.ts +0 -159
  108. package/types/generators/Step.ts +0 -107
  109. package/types/generators/SttAppleBuiltin.ts +0 -130
  110. package/types/generators/Tcp.ts +0 -126
  111. package/types/generators/TcpServer.ts +0 -147
  112. package/types/generators/TextToSpeechAppleBuiltin.ts +0 -127
  113. package/types/generators/TextToSpeechGgml.ts +0 -221
  114. package/types/generators/TextToSpeechOnnx.ts +0 -178
  115. package/types/generators/TextToSpeechOpenAiLike.ts +0 -121
  116. package/types/generators/ThermalPrinter.ts +0 -191
  117. package/types/generators/Tick.ts +0 -83
  118. package/types/generators/Udp.ts +0 -120
  119. package/types/generators/VadGgml.ts +0 -250
  120. package/types/generators/VadOnnx.ts +0 -231
  121. package/types/generators/VadTraditional.ts +0 -138
  122. package/types/generators/VectorStore.ts +0 -257
  123. package/types/generators/Watchdog.ts +0 -107
  124. package/types/generators/WebCrawler.ts +0 -103
  125. package/types/generators/WebRtc.ts +0 -181
  126. package/types/generators/WebSocket.ts +0 -148
  127. package/types/generators/index.ts +0 -57
  128. package/types/index.ts +0 -13
  129. package/types/subspace.ts +0 -60
  130. package/types/switch.ts +0 -51
  131. package/types/system.ts +0 -707
  132. package/utils/calc.ts +0 -126
  133. package/utils/data.ts +0 -497
  134. package/utils/event-props.ts +0 -886
  135. package/utils/id.ts +0 -80
package/compile/util.ts DELETED
@@ -1,358 +0,0 @@
1
- import { makeId } 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
- if (config.error && config.inputs[config.error]) {
22
- throw new Error(`${errorMsg}. key: error`)
23
- }
24
- if (config.output && config.inputs[config.output]) {
25
- throw new Error(`${errorMsg}. key: output`)
26
- }
27
- if (Object.values(config.outputs).some((value) => value.some((id) => config.inputs[id]))) {
28
- throw new Error(`${errorMsg}. key: outputs`)
29
- }
30
- }
31
-
32
- const padding = 15
33
- const layerXInterval = 300
34
- const layerYInterval = 150
35
-
36
- export const generateCalulationMap = (config: ScriptConfig, opts?: { snapshotMode?: boolean }) => {
37
- validateConfig(config)
38
- const sandboxId = makeId('property_bank_command', opts)
39
- const sandboxErrorId = makeId('property_bank_command', opts)
40
- const sandboxResultId = makeId('property_bank_command', opts)
41
-
42
- const inputs = Object.entries(config.inputs).reduce(
43
- (acc, [key, value], index) => {
44
- const commandId = makeId('property_bank_command', opts)
45
- acc.map[key] = {
46
- type: 'data-node',
47
- properties: {},
48
- in: {
49
- change: null,
50
- },
51
- out: {
52
- value: [
53
- {
54
- id: commandId,
55
- port: 'value',
56
- },
57
- ],
58
- },
59
- }
60
- acc.editorInfo[key] = {
61
- position: { x: padding, y: index * layerYInterval + padding },
62
- points: {},
63
- }
64
- if (acc.prevCommandId) {
65
- acc.map[acc.prevCommandId].out.result = [
66
- {
67
- id: commandId,
68
- port: 'obj',
69
- },
70
- ]
71
- }
72
- acc.map[commandId] = {
73
- type: 'command-node-object',
74
- title: 'Command: OBJECT_SET',
75
- properties: {
76
- command: 'OBJECT_SET',
77
- args: {
78
- path: value,
79
- },
80
- },
81
- in: {
82
- obj: acc.prevCommandId
83
- ? [
84
- {
85
- id: acc.prevCommandId,
86
- port: 'result',
87
- },
88
- ]
89
- : null,
90
- path: null,
91
- value: [
92
- {
93
- id: key,
94
- port: 'value',
95
- disable_trigger_command:
96
- config.trigger_mode === 'manual' || config.disabled_triggers?.[key] || undefined,
97
- },
98
- ],
99
- },
100
- out: {
101
- result: [
102
- {
103
- id: sandboxId,
104
- port: 'inputs',
105
- },
106
- ],
107
- },
108
- }
109
- acc.editorInfo[commandId] = {
110
- position: { x: layerXInterval, y: index * layerYInterval + padding },
111
- points: {},
112
- }
113
- acc.prevCommandId = commandId
114
- return acc
115
- },
116
- { map: {}, editorInfo: {}, prevCommandId: null } as {
117
- map: Record<string, any>
118
- editorInfo: Record<string, any>
119
- prevCommandId: string | null
120
- },
121
- )
122
-
123
- let y = 0
124
- const outputs = Object.entries(config.outputs).reduce(
125
- (acc, [key, pbList], index) => {
126
- const commandId = makeId('property_bank_command', opts)
127
- acc.commandIdList.push(commandId)
128
- acc.map[commandId] = {
129
- type: 'command-node-object',
130
- title: 'Command: OBJECT_GET',
131
- properties: {
132
- command: 'OBJECT_GET',
133
- args: {
134
- path: key,
135
- },
136
- },
137
- in: {
138
- obj: [
139
- {
140
- id: sandboxResultId,
141
- port: 'result',
142
- },
143
- ],
144
- path: null,
145
- },
146
- out: {
147
- result: pbList.map((pb) => ({
148
- id: pb,
149
- port: 'change',
150
- })),
151
- },
152
- }
153
- acc.editorInfo[commandId] = {
154
- position: {
155
- x: layerXInterval * 3,
156
- y: index * layerYInterval + padding,
157
- },
158
- points: {},
159
- }
160
- pbList.forEach((pb, pbIndex) => {
161
- // Check if this data node already exists (it might be used as both input and output)
162
- const existingNode = acc.map[pb] || inputs.map[pb]
163
- acc.map[pb] = {
164
- type: 'data-node',
165
- properties: {},
166
- in: {
167
- change: [
168
- {
169
- id: commandId,
170
- port: 'result',
171
- },
172
- ],
173
- },
174
- out: {
175
- // Preserve existing out.value if node is also used as input
176
- value: existingNode?.out?.value ?? null,
177
- },
178
- }
179
- acc.editorInfo[pb] = {
180
- position: {
181
- x: layerXInterval * 4,
182
- y: padding + y + index * layerYInterval + pbIndex * layerYInterval,
183
- },
184
- points: {},
185
- }
186
- if (pbIndex > 0) y += layerYInterval
187
- })
188
- return acc
189
- },
190
- { map: {}, editorInfo: {}, commandIdList: [] } as {
191
- map: Record<string, any>
192
- editorInfo: Record<string, any>
193
- commandIdList: string[]
194
- },
195
- )
196
-
197
- return {
198
- map: {
199
- ...inputs.map,
200
- [sandboxId]: {
201
- type: 'command-node-sandbox',
202
- title: 'Command: SANDBOX_RUN_JAVASCRIPT',
203
- properties: {
204
- command: 'SANDBOX_RUN_JAVASCRIPT',
205
- args: {
206
- code: config.code,
207
- enable_async: config.enable_async,
208
- },
209
- },
210
- in: {
211
- code: null,
212
- inputs: inputs.prevCommandId
213
- ? [
214
- {
215
- id: inputs.prevCommandId,
216
- port: 'result',
217
- },
218
- ]
219
- : [],
220
- },
221
- out: {
222
- result: [
223
- {
224
- id: sandboxErrorId,
225
- port: 'result',
226
- },
227
- {
228
- id: sandboxResultId,
229
- port: 'result',
230
- },
231
- ],
232
- },
233
- },
234
- [sandboxErrorId]: {
235
- type: 'command-node-sandbox',
236
- title: 'Command: SANDBOX_GET_ERROR',
237
- properties: {
238
- command: 'SANDBOX_GET_ERROR',
239
- },
240
- in: {
241
- result: [
242
- {
243
- id: sandboxId,
244
- port: 'result',
245
- },
246
- ],
247
- },
248
- out: {
249
- result: config.error
250
- ? [
251
- {
252
- id: config.error,
253
- port: 'change',
254
- },
255
- ]
256
- : [],
257
- },
258
- },
259
- [sandboxResultId]: {
260
- type: 'command-node-sandbox',
261
- title: 'Command: SANDBOX_GET_RETURN_VALUE',
262
- properties: {
263
- command: 'SANDBOX_GET_RETURN_VALUE',
264
- },
265
- in: {
266
- result: [
267
- {
268
- id: sandboxId,
269
- port: 'result',
270
- },
271
- ],
272
- },
273
- out: {
274
- result: (config.output
275
- ? [
276
- {
277
- id: config.output,
278
- port: 'change',
279
- },
280
- ]
281
- : []
282
- ).concat(
283
- outputs.commandIdList.map((commandId) => ({
284
- id: commandId,
285
- port: 'obj',
286
- })),
287
- ),
288
- },
289
- },
290
-
291
- ...(config.error && {
292
- [config.error]: {
293
- type: 'data-node',
294
- properties: {},
295
- in: {
296
- change: [
297
- {
298
- id: sandboxErrorId,
299
- port: 'result',
300
- },
301
- ],
302
- },
303
- out: {
304
- // Preserve existing out.value if node is also used as input
305
- value: inputs.map[config.error]?.out?.value ?? null,
306
- },
307
- },
308
- }),
309
- ...(config.output && {
310
- [config.output]: {
311
- type: 'data-node',
312
- properties: {},
313
- in: {
314
- change: [
315
- {
316
- id: sandboxResultId,
317
- port: 'result',
318
- },
319
- ],
320
- },
321
- out: {
322
- // Preserve existing out.value if node is also used as input
323
- value: inputs.map[config.output]?.out?.value ?? null,
324
- },
325
- },
326
- }),
327
- ...outputs.map,
328
- },
329
- editor_info: {
330
- ...inputs.editorInfo,
331
- [sandboxId]: {
332
- position: { x: layerXInterval * 2, y: padding },
333
- points: {},
334
- },
335
- [sandboxErrorId]: {
336
- position: { x: layerXInterval * 2, y: layerYInterval },
337
- points: {},
338
- },
339
- [sandboxResultId]: {
340
- position: { x: layerXInterval * 2, y: layerYInterval * 2 },
341
- points: {},
342
- },
343
- ...(config.error && {
344
- [config.error]: {
345
- position: { x: layerXInterval * 2, y: layerYInterval * 3 },
346
- points: {},
347
- },
348
- }),
349
- ...(config.output && {
350
- [config.output]: {
351
- position: { x: layerXInterval * 2, y: layerYInterval * 4 },
352
- points: {},
353
- },
354
- }),
355
- ...outputs.editorInfo,
356
- },
357
- }
358
- }
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,32 +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, and Buttress (remote inference). Triggers on multi-device sync, cloud data, media assets, AI offloading, E2E testing, or canvas transitions.
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](rules/architecture-patterns.md) | **Read first** — decompose flows and select patterns |
15
- | [Animation](rules/animation.md) | Animation system for brick transforms and opacity |
16
- | [Standby Transition](rules/standby-transition.md) | Canvas enter/exit animations |
17
- | [Automations](rules/automations.md) | E2E testing and scheduled tasks |
18
- | [Data Calculation](rules/data-calculation.md) | JS sandbox libraries (25+ available) |
19
- | [Local Sync](rules/local-sync.md) | LAN device synchronization |
20
- | [Remote Data Bank](rules/remote-data-bank.md) | Cloud data sync and API access |
21
- | [Media Flow](rules/media-flow.md) | Media asset management |
22
- | [Buttress](rules/buttress.md) | Remote inference for AI generators |
23
-
24
- ## Quick Reference
25
-
26
- - **Complex flows**: See [Architecture Patterns](rules/architecture-patterns.md) for decomposing multi-step workflows
27
- - **Multi-device**: See [Local Sync](rules/local-sync.md) for LAN coordination
28
- - **Cloud data**: See [Remote Data Bank](rules/remote-data-bank.md) for sync and API access
29
- - **Media assets**: See [Media Flow](rules/media-flow.md) for centralized asset management
30
- - **AI offloading**: See [Buttress](rules/buttress.md) for GPU server delegation
31
- - **E2E testing**: See [Automations](rules/automations.md) for test automation
32
- - **Enter animations**: See [Standby Transition](rules/standby-transition.md) for canvas transitions
@@ -1,159 +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
- speed: 12,
45
- bounciness: 8,
46
- },
47
- }
48
- ```
49
-
50
- ### Decay Animation
51
- Velocity-based deceleration animation.
52
-
53
- ```typescript
54
- const slideOut: AnimationDef = {
55
- __typename: 'Animation',
56
- id: makeId('animation'),
57
- title: 'Slide Out',
58
- property: 'transform.translateX',
59
- config: {
60
- __type: 'AnimationDecayConfig',
61
- toValue: 500,
62
- velocity: 0.5,
63
- deceleration: 0.997,
64
- isInteraction: true,
65
- },
66
- }
67
- ```
68
-
69
- ## Animatable Properties
70
-
71
- | Property | Description |
72
- |----------|-------------|
73
- | `transform.translateX` | Horizontal position offset |
74
- | `transform.translateY` | Vertical position offset |
75
- | `transform.scale` | Uniform scale |
76
- | `transform.scaleX` | Horizontal scale |
77
- | `transform.scaleY` | Vertical scale |
78
- | `transform.rotate` | Rotation (degrees) |
79
- | `transform.rotateX` | X-axis rotation |
80
- | `transform.rotateY` | Y-axis rotation |
81
- | `opacity` | Transparency (0-1) |
82
-
83
- ## Easing Functions
84
-
85
- Standard easing from [easings.net](https://easings.net):
86
- - `easeInSine`, `easeOutSine`, `easeInOutSine`
87
- - `easeInQuad`, `easeOutQuad`, `easeInOutQuad`
88
- - `easeInCubic`, `easeOutCubic`, `easeInOutCubic`
89
- - `easeInQuart`, `easeOutQuart`, `easeInOutQuart`
90
- - `easeInQuint`, `easeOutQuint`, `easeInOutQuint`
91
- - `easeInExpo`, `easeOutExpo`, `easeInOutExpo`
92
- - `easeInCirc`, `easeOutCirc`, `easeInOutCirc`
93
- - `easeInBack`, `easeOutBack`, `easeInOutBack`
94
- - `easeInElastic`, `easeOutElastic`, `easeInOutElastic`
95
- - `easeInBounce`, `easeOutBounce`, `easeInOutBounce`
96
- - Custom: `'cubic-bezier(x1, y1, x2, y2)'`
97
-
98
- ## Composed Animations
99
-
100
- Combine multiple animations in parallel or sequence.
101
-
102
- ```typescript
103
- const enterAnimation: AnimationComposeDef = {
104
- __typename: 'AnimationCompose',
105
- id: makeId('animation'),
106
- title: 'Enter Animation',
107
- runType: 'once',
108
- composeType: 'parallel', // 'parallel' | 'sequence'
109
- items: [
110
- () => fadeIn,
111
- () => scaleUp,
112
- ],
113
- }
114
- ```
115
-
116
- ## Brick Animation Events
117
-
118
- Bricks support automatic animation binding:
119
-
120
- ```typescript
121
- // In brick definition
122
- animations: {
123
- showStart: () => fadeInAnimation, // On brick first render
124
- standby: () => standbyAnimation, // After standby transition
125
- breatheStart: () => pulseAnimation, // Breathing effect (looping)
126
- }
127
- ```
128
-
129
- ## Dynamic Animation (Runtime)
130
-
131
- Trigger animations programmatically via System Action:
132
-
133
- ```typescript
134
- const runAnimation: EventAction = {
135
- handler: 'system',
136
- action: {
137
- __actionName: 'DYNAMIC_ANIMATION',
138
- parent: 'System',
139
- params: [
140
- { input: 'brickId', value: () => targetBrick },
141
- { input: 'animationId', value: () => pulseAnimation },
142
- { input: 'runType', value: 'once' }, // 'once' | 'loop'
143
- { input: 'resetInitialValue', value: false },
144
- ],
145
- },
146
- }
147
- ```
148
-
149
- Related actions:
150
- - `DYNAMIC_ANIMATION_RESET` - Reset animation state
151
- - `DYNAMIC_ANIMATION_STOP` - Stop running animation
152
-
153
- ## Best Practices
154
-
155
- 1. **Performance**: Keep animations simple, prefer `opacity` and `transform` over layout changes
156
- 2. **Timing**: Use `easeOut` for enter animations, `easeIn` for exit
157
- 3. **Spring animations**: Good for natural, bouncy UI elements
158
- 4. **Looping**: Use `runType: 'loop'` for attention-grabbing elements
159
- 5. **Composition**: Use `sequence` for staged reveals, `parallel` for coordinated effects
@@ -1,69 +0,0 @@
1
- # Architecture Patterns
2
-
3
- How to decompose complex flows into the right combination of BRICKS patterns.
4
-
5
- ## Pattern Selection Priority
6
-
7
- Prefer higher-priority patterns; only fall to lower when they genuinely can't solve the sub-problem:
8
-
9
- | Priority | Pattern | Use For |
10
- |----------|---------|---------|
11
- | 1 | Generator + Events | I/O, AI inference, external data |
12
- | 2 | Event Action Chains | Orchestration, sequential steps |
13
- | 3 | System Actions | State changes, navigation, UI triggers |
14
- | 4 | Data Calculation | Pure data transformation ONLY |
15
-
16
- ### Generators (Priority 1)
17
- For all external I/O and AI inference. Each generator emits events that naturally chain into actions.
18
- - **GeneratorAssistant**: multi-turn LLM conversations, function calling, built-in message history
19
- - **GeneratorLLM**: single-shot local inference (GGML)
20
- - **GeneratorHttp**: REST API calls
21
- - **GeneratorMqtt / GeneratorWebSocket**: real-time messaging
22
-
23
- ### Event Action Chains (Priority 2)
24
- The primary way to orchestrate multi-step flows. A single event can contain an array of EventActions executed sequentially.
25
- - Use `waitAsync: true` to await async actions before the next step
26
- - Use `dataParams` + `mapping` to pass event data downstream
27
- - This is the "glue" that wires generators, state, and UI together
28
-
29
- ### System Actions (Priority 3)
30
- Built-in commands for direct state and UI changes.
31
- - **PROPERTY_BANK**: set data value
32
- - **PROPERTY_BANK_EXPRESSION**: inline JS expression for simple compute
33
- - **CHANGE_CANVAS**: navigate to another canvas
34
- - **DYNAMIC_ANIMATION**: trigger animation
35
- - **ALERT / MESSAGE**: system feedback
36
-
37
- ### Data Calculation (Priority 4)
38
- ONLY for deriving, formatting, or aggregating values from other data. Not for orchestration, side effects, or flow control.
39
-
40
- ## Entity Aliases
41
-
42
- Set `alias` on entities to give them a stable, human-readable name:
43
- - Code generation uses alias as the variable name (e.g., `alias: 'submitBtn'` → `export const submitBtn`)
44
- - At runtime, devtools MCP tools accept alias instead of short ID and selectors can match by alias. Note: bricks-ctor does not directly interact with devtools MCP — aliases here primarily affect code generation
45
- - Aliases must be unique across the application — duplicates are excluded from resolution
46
-
47
- ## Flow Decomposition
48
-
49
- When the user describes a complex flow, decompose it BEFORE writing code:
50
-
51
- ### Step 1: Extract I/O boundaries
52
- Every external interaction maps to a Generator:
53
- - "call LLM" → GeneratorAssistant or GeneratorLLM
54
- - "fetch API" → GeneratorHttp
55
- - "speech to text" → GeneratorSpeechInference
56
-
57
- ### Step 2: Extract state transitions
58
- Every UI change maps to a System Action in an event chain:
59
- - "show loading" → PROPERTY_BANK on a boolean data
60
- - "go to result screen" → CHANGE_CANVAS
61
- - "animate in" → DYNAMIC_ANIMATION
62
-
63
- ### Step 3: Extract pure transformations
64
- Only actual data derivation maps to Data Calculation:
65
- - "format the response" → DataCalculationScript
66
- - "compute a score" → DataCalculationScript or DataCalculationMap
67
-
68
- ### Step 4: Wire with Event Action Chains
69
- Connect the pieces through events on generators and bricks.