@fugood/bricks-project 2.23.0-beta.7 → 2.23.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/api/instance.ts +37 -5
- package/compile/action-name-map.ts +81 -0
- package/compile/index.ts +164 -63
- package/compile/util.ts +13 -4
- package/package.json +8 -4
- package/skills/bricks-project/SKILL.md +32 -0
- package/skills/bricks-project/rules/animation.md +159 -0
- package/skills/bricks-project/rules/architecture-patterns.md +62 -0
- package/skills/bricks-project/rules/automations.md +175 -0
- package/skills/bricks-project/rules/buttress.md +153 -0
- package/skills/bricks-project/rules/data-calculation.md +208 -0
- package/skills/bricks-project/rules/local-sync.md +129 -0
- package/skills/bricks-project/rules/media-flow.md +158 -0
- package/skills/bricks-project/rules/remote-data-bank.md +196 -0
- package/skills/bricks-project/rules/standby-transition.md +124 -0
- package/skills/rive-marketplace/SKILL.md +99 -0
- package/tools/deploy.ts +74 -12
- package/tools/icons/.gitattributes +1 -0
- package/tools/icons/fa6pro-glyphmap.json +4686 -0
- package/tools/icons/fa6pro-meta.json +26127 -0
- package/tools/mcp-server.ts +812 -8
- package/tools/postinstall.ts +33 -13
- package/tools/preview-main.mjs +53 -4
- package/tools/preview.ts +53 -6
- package/tools/pull.ts +37 -16
- package/types/automation.ts +232 -0
- package/types/brick-base.ts +1 -0
- package/types/bricks/Camera.ts +26 -10
- package/types/bricks/Chart.ts +1 -0
- package/types/bricks/GenerativeMedia.ts +21 -3
- package/types/bricks/Icon.ts +1 -0
- package/types/bricks/Image.ts +6 -0
- package/types/bricks/Items.ts +1 -0
- package/types/bricks/Lottie.ts +1 -0
- package/types/bricks/Maps.ts +254 -0
- package/types/bricks/QrCode.ts +1 -0
- package/types/bricks/Rect.ts +1 -0
- package/types/bricks/RichText.ts +1 -0
- package/types/bricks/Rive.ts +1 -0
- package/types/bricks/Slideshow.ts +1 -0
- package/types/bricks/Svg.ts +1 -0
- package/types/bricks/Text.ts +1 -0
- package/types/bricks/TextInput.ts +1 -0
- package/types/bricks/Video.ts +1 -0
- package/types/bricks/VideoStreaming.ts +1 -0
- package/types/bricks/WebRtcStream.ts +1 -0
- package/types/bricks/WebView.ts +8 -1
- package/types/bricks/index.ts +2 -0
- package/types/canvas.ts +1 -0
- package/types/common.ts +2 -0
- package/types/data-calc-command.ts +7003 -0
- package/types/data-calc-script.ts +21 -0
- package/types/data-calc.ts +3 -6977
- package/types/data.ts +3 -0
- package/types/generators/AlarmClock.ts +2 -0
- package/types/generators/Assistant.ts +30 -6
- package/types/generators/BleCentral.ts +2 -0
- package/types/generators/BlePeripheral.ts +2 -0
- package/types/generators/CanvasMap.ts +2 -0
- package/types/generators/CastlesPay.ts +2 -0
- package/types/generators/DataBank.ts +2 -0
- package/types/generators/File.ts +2 -0
- package/types/generators/GraphQl.ts +2 -0
- package/types/generators/Http.ts +84 -2
- package/types/generators/HttpServer.ts +5 -1
- package/types/generators/Information.ts +2 -0
- package/types/generators/Intent.ts +51 -0
- package/types/generators/Iterator.ts +11 -2
- package/types/generators/Keyboard.ts +2 -0
- package/types/generators/LlmAnthropicCompat.ts +2 -0
- package/types/generators/LlmAppleBuiltin.ts +144 -0
- package/types/generators/LlmGgml.ts +29 -5
- package/types/generators/LlmOnnx.ts +2 -0
- package/types/generators/LlmOpenAiCompat.ts +2 -0
- package/types/generators/LlmQualcommAiEngine.ts +2 -0
- package/types/generators/Mcp.ts +6 -4
- package/types/generators/McpServer.ts +8 -6
- package/types/generators/MediaFlow.ts +2 -0
- package/types/generators/MqttBroker.ts +2 -0
- package/types/generators/MqttClient.ts +2 -0
- package/types/generators/Question.ts +9 -0
- package/types/generators/RealtimeTranscription.ts +4 -2
- package/types/generators/RerankerGgml.ts +23 -16
- package/types/generators/SerialPort.ts +2 -0
- package/types/generators/SoundPlayer.ts +2 -0
- package/types/generators/SoundRecorder.ts +2 -0
- package/types/generators/SpeechToTextGgml.ts +14 -4
- package/types/generators/SpeechToTextOnnx.ts +2 -0
- package/types/generators/SpeechToTextPlatform.ts +2 -0
- package/types/generators/SqLite.ts +32 -1
- package/types/generators/Step.ts +2 -0
- package/types/generators/SttAppleBuiltin.ts +117 -0
- package/types/generators/Tcp.ts +2 -0
- package/types/generators/TcpServer.ts +5 -1
- package/types/generators/TextToSpeechApple.ts +113 -0
- package/types/generators/TextToSpeechAppleBuiltin.ts +114 -0
- package/types/generators/TextToSpeechGgml.ts +24 -3
- package/types/generators/TextToSpeechOnnx.ts +2 -0
- package/types/generators/TextToSpeechOpenAiLike.ts +2 -0
- package/types/generators/ThermalPrinter.ts +2 -0
- package/types/generators/Tick.ts +5 -1
- package/types/generators/TtsAppleBuiltin.ts +105 -0
- package/types/generators/Udp.ts +2 -0
- package/types/generators/VadGgml.ts +4 -2
- package/types/generators/VectorStore.ts +15 -2
- package/types/generators/Watchdog.ts +2 -0
- package/types/generators/WebCrawler.ts +2 -0
- package/types/generators/WebRtc.ts +4 -2
- package/types/generators/WebSocket.ts +2 -0
- package/types/generators/index.ts +3 -0
- package/types/index.ts +3 -0
- package/types/system.ts +48 -6
- package/utils/calc.ts +5 -1
- package/utils/data.ts +1 -0
- package/utils/event-props.ts +85 -2
- package/utils/id.ts +3 -1
package/api/instance.ts
CHANGED
|
@@ -66,17 +66,31 @@ export const deployApp = async (
|
|
|
66
66
|
appId: string,
|
|
67
67
|
config: Config,
|
|
68
68
|
lastCommitId?: string,
|
|
69
|
+
changelogs?: string,
|
|
70
|
+
version?: string,
|
|
69
71
|
) => {
|
|
70
72
|
const app = await pullApp(stage, appId)
|
|
71
73
|
if (app.config?.bricks_project_last_commit_id === lastCommitId)
|
|
72
74
|
throw new Error('No changes to deploy')
|
|
73
75
|
|
|
76
|
+
const versionName = version || app.name || 'Untitled'
|
|
77
|
+
const releaseNote = changelogs
|
|
78
|
+
? `${changelogs}\n\nRelease by BRICKS Project`
|
|
79
|
+
: 'Release by BRICKS Project'
|
|
80
|
+
|
|
74
81
|
const { errors } = await doGQL(
|
|
75
82
|
stage,
|
|
76
|
-
`mutation
|
|
83
|
+
`mutation BRICKS_PROJECT_releaseApplication(
|
|
84
|
+
$id: ID!,
|
|
85
|
+
$config: String,
|
|
86
|
+
$releaseCurrentVersion: String,
|
|
87
|
+
$releaseCurrentVersionNote: String
|
|
88
|
+
) {
|
|
77
89
|
updateApplication(
|
|
78
90
|
id: $id,
|
|
79
|
-
config: $config
|
|
91
|
+
config: $config,
|
|
92
|
+
releaseCurrentVersion: $releaseCurrentVersion,
|
|
93
|
+
releaseCurrentVersionNote: $releaseCurrentVersionNote
|
|
80
94
|
) {
|
|
81
95
|
_id
|
|
82
96
|
name
|
|
@@ -86,9 +100,11 @@ export const deployApp = async (
|
|
|
86
100
|
id: appId,
|
|
87
101
|
config: JSON.stringify({
|
|
88
102
|
...config,
|
|
89
|
-
title:
|
|
103
|
+
title: versionName,
|
|
90
104
|
bricks_project_last_commit_id: lastCommitId,
|
|
91
105
|
}),
|
|
106
|
+
releaseCurrentVersion: versionName,
|
|
107
|
+
releaseCurrentVersionNote: releaseNote,
|
|
92
108
|
},
|
|
93
109
|
)
|
|
94
110
|
if (errors) throw new Error(errors[0].message)
|
|
@@ -137,18 +153,32 @@ export const deployModule = async (
|
|
|
137
153
|
modId: string,
|
|
138
154
|
config: Config,
|
|
139
155
|
lastCommitId?: string,
|
|
156
|
+
changelogs?: string,
|
|
157
|
+
version?: string,
|
|
140
158
|
) => {
|
|
141
159
|
const mod = await pullModule(stage, modId)
|
|
142
160
|
if (mod.config?.bricks_project_last_commit_id === lastCommitId)
|
|
143
161
|
throw new Error('No changes to deploy')
|
|
144
162
|
|
|
163
|
+
const versionName = version || mod.name || 'Untitled'
|
|
164
|
+
const releaseNote = changelogs
|
|
165
|
+
? `${changelogs}\n\nRelease by BRICKS Project`
|
|
166
|
+
: 'Release by BRICKS Project'
|
|
167
|
+
|
|
145
168
|
const { errors } = await doGQL(
|
|
146
169
|
stage,
|
|
147
|
-
`mutation
|
|
170
|
+
`mutation BRICKS_PROJECT_releaseModule(
|
|
171
|
+
$id: ID!,
|
|
172
|
+
$config: String,
|
|
173
|
+
$releaseCurrentVersion: String,
|
|
174
|
+
$releaseCurrentVersionNote: String
|
|
175
|
+
) {
|
|
148
176
|
updateModule(
|
|
149
177
|
id: $id
|
|
150
178
|
config: $config
|
|
151
179
|
validateConfig: true
|
|
180
|
+
releaseCurrentVersion: $releaseCurrentVersion
|
|
181
|
+
releaseCurrentVersionNote: $releaseCurrentVersionNote
|
|
152
182
|
) {
|
|
153
183
|
_id
|
|
154
184
|
name
|
|
@@ -158,9 +188,11 @@ export const deployModule = async (
|
|
|
158
188
|
id: modId,
|
|
159
189
|
config: JSON.stringify({
|
|
160
190
|
...config,
|
|
161
|
-
title:
|
|
191
|
+
title: versionName,
|
|
162
192
|
bricks_project_last_commit_id: lastCommitId,
|
|
163
193
|
}),
|
|
194
|
+
releaseCurrentVersion: versionName,
|
|
195
|
+
releaseCurrentVersionNote: releaseNote,
|
|
164
196
|
},
|
|
165
197
|
)
|
|
166
198
|
if (errors) throw new Error(errors[0].message)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* Auto generated by build script */
|
|
2
|
+
|
|
1
3
|
// NOTE: The action parameter name convertion is not 1:1 mapping case conversion, so we need to define the mapping here
|
|
2
4
|
// This may be improved in the future
|
|
3
5
|
export const templateActionNameMap = {
|
|
@@ -302,6 +304,28 @@ export const templateActionNameMap = {
|
|
|
302
304
|
maxDuration: 'BRICK_CAMERA_MAX_DURATION',
|
|
303
305
|
maxFileSize: 'BRICK_CAMERA_MAX_FILE_SIZE',
|
|
304
306
|
},
|
|
307
|
+
BRICK_CAMERA_FOCUS: {
|
|
308
|
+
focusX: 'BRICK_CAMERA_FOCUS_X',
|
|
309
|
+
focusY: 'BRICK_CAMERA_FOCUS_Y',
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
|
|
313
|
+
BRICK_MAPS: {
|
|
314
|
+
BRICK_MAPS_PAN: {
|
|
315
|
+
panDirection: 'BRICK_MAPS_PAN_DIRECTION',
|
|
316
|
+
},
|
|
317
|
+
BRICK_MAPS_NAVIGATE_TO: {
|
|
318
|
+
targetLatitude: 'BRICK_MAPS_TARGET_LATITUDE',
|
|
319
|
+
targetLongitude: 'BRICK_MAPS_TARGET_LONGITUDE',
|
|
320
|
+
targetZoom: 'BRICK_MAPS_TARGET_ZOOM',
|
|
321
|
+
},
|
|
322
|
+
BRICK_MAPS_FOCUS_MARKER: {
|
|
323
|
+
markerId: 'BRICK_MAPS_MARKER_ID',
|
|
324
|
+
},
|
|
325
|
+
BRICK_MAPS_FIT_TO_MARKERS: {
|
|
326
|
+
edgePadding: 'BRICK_MAPS_EDGE_PADDING',
|
|
327
|
+
animated: 'BRICK_MAPS_ANIMATED',
|
|
328
|
+
},
|
|
305
329
|
},
|
|
306
330
|
|
|
307
331
|
GENERATOR_FILE: {
|
|
@@ -357,6 +381,23 @@ export const templateActionNameMap = {
|
|
|
357
381
|
variables: 'GENERATOR_GRAPHQL_VARIABLES',
|
|
358
382
|
},
|
|
359
383
|
},
|
|
384
|
+
GENERATOR_HTTP: {
|
|
385
|
+
GENERATOR_HTTP_RUN_REQUEST: {
|
|
386
|
+
url: 'GENERATOR_HTTP_URL',
|
|
387
|
+
method: 'GENERATOR_HTTP_METHOD',
|
|
388
|
+
headers: 'GENERATOR_HTTP_HEADERS',
|
|
389
|
+
body: 'GENERATOR_HTTP_BODY',
|
|
390
|
+
timeout: 'GENERATOR_HTTP_TIMEOUT',
|
|
391
|
+
mode: 'GENERATOR_HTTP_MODE',
|
|
392
|
+
credentials: 'GENERATOR_HTTP_CREDENTIALS',
|
|
393
|
+
redirect: 'GENERATOR_HTTP_REDIRECT',
|
|
394
|
+
referrer: 'GENERATOR_HTTP_REFERRER',
|
|
395
|
+
resType: 'GENERATOR_HTTP_RES_TYPE',
|
|
396
|
+
resSelector: 'GENERATOR_HTTP_RES_SELECTOR',
|
|
397
|
+
eventStream: 'GENERATOR_HTTP_EVENT_STREAM',
|
|
398
|
+
eventName: 'GENERATOR_HTTP_EVENT_NAME',
|
|
399
|
+
},
|
|
400
|
+
},
|
|
360
401
|
|
|
361
402
|
GENERATOR_WEB_SOCKET: {
|
|
362
403
|
GENERATOR_WEB_SOCKET_EMIT: {
|
|
@@ -484,6 +525,16 @@ export const templateActionNameMap = {
|
|
|
484
525
|
packageName: 'GENERATOR_INTENT_PACKAGE_NAME',
|
|
485
526
|
category: 'GENERATOR_INTENT_CATEGORY',
|
|
486
527
|
},
|
|
528
|
+
GENERATOR_INTENT_START_SERVICE: {
|
|
529
|
+
action: 'GENERATOR_INTENT_ACTION',
|
|
530
|
+
data: 'GENERATOR_INTENT_DATA',
|
|
531
|
+
type: 'GENERATOR_INTENT_TYPE',
|
|
532
|
+
extra: 'GENERATOR_INTENT_EXTRA',
|
|
533
|
+
className: 'GENERATOR_INTENT_CLASS_NAME',
|
|
534
|
+
packageName: 'GENERATOR_INTENT_PACKAGE_NAME',
|
|
535
|
+
category: 'GENERATOR_INTENT_CATEGORY',
|
|
536
|
+
foreground: 'GENERATOR_INTENT_FOREGROUND',
|
|
537
|
+
},
|
|
487
538
|
},
|
|
488
539
|
GENERATOR_CASTLES_PAY: {
|
|
489
540
|
GENERATOR_CASTLES_PAY_SALE: {
|
|
@@ -512,6 +563,13 @@ export const templateActionNameMap = {
|
|
|
512
563
|
params: 'GENERATOR_SQLITE_PARAMS',
|
|
513
564
|
paramsString: 'GENERATOR_SQLITE_PARAMS_STRING',
|
|
514
565
|
},
|
|
566
|
+
GENERATOR_SQLITE_TRANSACTION: {
|
|
567
|
+
statements: 'GENERATOR_SQLITE_STATEMENTS',
|
|
568
|
+
},
|
|
569
|
+
GENERATOR_SQLITE_BATCH_EXECUTE: {
|
|
570
|
+
sql: 'GENERATOR_SQLITE_SQL',
|
|
571
|
+
batchParams: 'GENERATOR_SQLITE_BATCH_PARAMS',
|
|
572
|
+
},
|
|
515
573
|
},
|
|
516
574
|
|
|
517
575
|
GENERATOR_MCP: {
|
|
@@ -747,6 +805,29 @@ export const templateActionNameMap = {
|
|
|
747
805
|
toolChoice: 'GENERATOR_ANTHROPIC_LLM_TOOL_CHOICE',
|
|
748
806
|
},
|
|
749
807
|
},
|
|
808
|
+
GENERATOR_APPLE_LLM: {
|
|
809
|
+
GENERATOR_APPLE_LLM_COMPLETION: {
|
|
810
|
+
messages: 'GENERATOR_APPLE_LLM_MESSAGES',
|
|
811
|
+
maxTokens: 'GENERATOR_APPLE_LLM_MAX_TOKENS',
|
|
812
|
+
temperature: 'GENERATOR_APPLE_LLM_TEMPERATURE',
|
|
813
|
+
topP: 'GENERATOR_APPLE_LLM_TOP_P',
|
|
814
|
+
},
|
|
815
|
+
},
|
|
816
|
+
GENERATOR_APPLE_STT: {
|
|
817
|
+
GENERATOR_APPLE_STT_TRANSCRIBE_FILE: {
|
|
818
|
+
fileUrl: 'GENERATOR_APPLE_STT_FILE_URL',
|
|
819
|
+
language: 'GENERATOR_APPLE_STT_LANGUAGE',
|
|
820
|
+
},
|
|
821
|
+
GENERATOR_APPLE_STT_TRANSCRIBE_DATA: {
|
|
822
|
+
data: 'GENERATOR_APPLE_STT_DATA',
|
|
823
|
+
language: 'GENERATOR_APPLE_STT_LANGUAGE',
|
|
824
|
+
},
|
|
825
|
+
},
|
|
826
|
+
GENERATOR_APPLE_TTS: {
|
|
827
|
+
GENERATOR_APPLE_TTS_GENERATE: {
|
|
828
|
+
text: 'GENERATOR_APPLE_TTS_TEXT',
|
|
829
|
+
},
|
|
830
|
+
},
|
|
750
831
|
GENERATOR_ASSISTANT: {
|
|
751
832
|
GENERATOR_ASSISTANT_ADD_MESSAGE: {
|
|
752
833
|
role: 'GENERATOR_ASSISTANT_ROLE',
|
package/compile/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-underscore-dangle -- Uses __typename, __actionName, etc. for type system */
|
|
1
2
|
import _ from 'lodash'
|
|
2
3
|
import { parse as parseAST } from 'acorn'
|
|
3
4
|
import type { ExportNamedDeclaration, FunctionDeclaration } from 'acorn'
|
|
@@ -12,7 +13,6 @@ import type {
|
|
|
12
13
|
Animation,
|
|
13
14
|
AnimationDef,
|
|
14
15
|
AnimationComposeDef,
|
|
15
|
-
EventAction,
|
|
16
16
|
ActionWithDataParams,
|
|
17
17
|
ActionWithParams,
|
|
18
18
|
BrickItems,
|
|
@@ -24,10 +24,13 @@ import type {
|
|
|
24
24
|
DataCalculationData,
|
|
25
25
|
DataCommand,
|
|
26
26
|
Brick,
|
|
27
|
-
Generator,
|
|
28
27
|
Canvas,
|
|
29
28
|
Subspace,
|
|
30
|
-
|
|
29
|
+
AutomationMap,
|
|
30
|
+
AutomationTestMap,
|
|
31
|
+
AutomationTest,
|
|
32
|
+
TestCase,
|
|
33
|
+
TestVariable,
|
|
31
34
|
} from '../types'
|
|
32
35
|
|
|
33
36
|
const compileProperty = (property, errorReference: string, result = {}) => {
|
|
@@ -58,7 +61,7 @@ const compileEventActionValue = (templateKey, eventKey, value, errorReference) =
|
|
|
58
61
|
const props = tmplEventProperties?.[eventKey]
|
|
59
62
|
if (!props) return compileProperty(value, errorReference)
|
|
60
63
|
if (props.includes(value)) return value
|
|
61
|
-
if (value?.startsWith(templateKey)) {
|
|
64
|
+
if (typeof value === 'string' && value?.startsWith(templateKey)) {
|
|
62
65
|
console.warn(
|
|
63
66
|
`[Warning] Value start with template key but there is no event property: ${value} ${errorReference}`,
|
|
64
67
|
)
|
|
@@ -66,25 +69,22 @@ const compileEventActionValue = (templateKey, eventKey, value, errorReference) =
|
|
|
66
69
|
return compileProperty(value, errorReference)
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
const convertOutletKey = (templateKey: string, key: string) =>
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
+
const convertOutletKey = (templateKey: string, key: string) =>
|
|
73
|
+
`${templateKey}_${_.snakeCase(key).toUpperCase()}`
|
|
72
74
|
|
|
73
75
|
const compileOutlets = (
|
|
74
76
|
templateKey: string,
|
|
75
77
|
outlets: { [key: string]: () => Data },
|
|
76
78
|
errorReference: string,
|
|
77
|
-
) =>
|
|
78
|
-
|
|
79
|
+
) =>
|
|
80
|
+
Object.entries(outlets).reduce((acc, [key, data]) => {
|
|
79
81
|
if (!data()?.id) throw new Error(`Invalid data reference ${errorReference}`)
|
|
80
82
|
acc[convertOutletKey(templateKey, key)] = data().id
|
|
81
83
|
return acc
|
|
82
84
|
}, {})
|
|
83
|
-
}
|
|
84
85
|
|
|
85
|
-
const convertEventKey = (templateKey: string, key: string) =>
|
|
86
|
-
|
|
87
|
-
}
|
|
86
|
+
const convertEventKey = (templateKey: string, key: string) =>
|
|
87
|
+
`${templateKey ? `${templateKey}_` : ''}${_.snakeCase(key).toUpperCase()}`
|
|
88
88
|
|
|
89
89
|
const basicAnimationEvents = ['show', 'standby', 'breatheStart']
|
|
90
90
|
|
|
@@ -92,14 +92,13 @@ const compileAnimations = (
|
|
|
92
92
|
templateKey: string,
|
|
93
93
|
animations: { [key: string]: Animation },
|
|
94
94
|
errorReference: string,
|
|
95
|
-
) =>
|
|
96
|
-
|
|
95
|
+
) =>
|
|
96
|
+
Object.entries(animations).reduce((acc, [key, animation]) => {
|
|
97
97
|
if (!animation?.id) throw new Error(`Invalid animation reference ${errorReference}`)
|
|
98
98
|
acc[convertEventKey(basicAnimationEvents.includes(key) ? 'BRICK' : templateKey, key)] =
|
|
99
99
|
`ANIMATION#${animation.id}`
|
|
100
100
|
return acc
|
|
101
101
|
}, {})
|
|
102
|
-
}
|
|
103
102
|
|
|
104
103
|
const compileActionParam = (templateKey: string, actionName: string, paramName: string) =>
|
|
105
104
|
templateActionNameMap[templateKey]?.[actionName]?.[paramName] || paramName
|
|
@@ -190,7 +189,7 @@ const compileSwitchConds = (templateKey, conds, errorReference) =>
|
|
|
190
189
|
result.key = cond.data().id
|
|
191
190
|
result.value = cond.value
|
|
192
191
|
} else if (item.cond.__typename === 'SwitchCondInnerStateOutlet') {
|
|
193
|
-
const cond = item
|
|
192
|
+
const { cond } = item
|
|
194
193
|
result.type = 'inner_state'
|
|
195
194
|
result.key = convertOutletKey(templateKey, cond.outlet)
|
|
196
195
|
result.value = cond.value
|
|
@@ -205,35 +204,33 @@ const compileSwitchConds = (templateKey, conds, errorReference) =>
|
|
|
205
204
|
return result
|
|
206
205
|
})
|
|
207
206
|
|
|
208
|
-
const compileApplicationSettings = (settings: Application['settings']) => {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
}
|
|
207
|
+
const compileApplicationSettings = (settings: Application['settings']) => ({
|
|
208
|
+
internet_reachability_url: settings?.internetReachabilityUrl,
|
|
209
|
+
enable_data_lock: settings?.enableDataLock,
|
|
210
|
+
show_deprecated_features: settings?.showDeprecatedFeatures,
|
|
211
|
+
enable_unstable_bricks: settings?.enableUnstableFeatures,
|
|
212
|
+
runtime_cache_options: settings?.runtimeCacheOptions
|
|
213
|
+
? {
|
|
214
|
+
disabled: settings.runtimeCacheOptions.disabled,
|
|
215
|
+
behavior: settings.runtimeCacheOptions.behavior,
|
|
216
|
+
retry_attempt_for_failure: settings.runtimeCacheOptions.retryAttemptForFailure,
|
|
217
|
+
}
|
|
218
|
+
: undefined,
|
|
219
|
+
tv_options: settings?.tvOptions
|
|
220
|
+
? {
|
|
221
|
+
disabled_selectable: settings.tvOptions.disabledSelectable,
|
|
222
|
+
selectable_color: settings.tvOptions.selectableColor,
|
|
223
|
+
selectable_border: settings.tvOptions.selectableBorder,
|
|
224
|
+
}
|
|
225
|
+
: undefined,
|
|
226
|
+
ai: settings?.ai
|
|
227
|
+
? {
|
|
228
|
+
use_anthropic_api_key_system_data: settings.ai.useAnthropicApiKeySystemData,
|
|
229
|
+
use_openai_api_key_system_data: settings.ai.useOpenAiApiKeySystemData,
|
|
230
|
+
use_gemini_api_key_system_data: settings.ai.useGeminiApiKeySystemData,
|
|
231
|
+
}
|
|
232
|
+
: undefined,
|
|
233
|
+
})
|
|
237
234
|
|
|
238
235
|
const animationTypeMap = {
|
|
239
236
|
AnimationTimingConfig: 'timing',
|
|
@@ -325,6 +322,103 @@ const compileModule = (subspace: Subspace) => {
|
|
|
325
322
|
}
|
|
326
323
|
}
|
|
327
324
|
|
|
325
|
+
/**
|
|
326
|
+
* Compile a run array element - if it's a getter function, call it and extract the id
|
|
327
|
+
* Note: All entity ids already include their prefix (e.g., SUBSPACE_xxx, BRICK_xxx, PROPERTY_BANK_DATA_NODE_xxx)
|
|
328
|
+
*/
|
|
329
|
+
function compileRunElement(element: unknown): unknown {
|
|
330
|
+
if (typeof element !== 'function') return element
|
|
331
|
+
|
|
332
|
+
const result = element()
|
|
333
|
+
if (result && typeof result === 'object' && 'id' in result) {
|
|
334
|
+
return (result as { id: string }).id
|
|
335
|
+
}
|
|
336
|
+
return result
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Compile a run array - resolve getter functions and extract ids with prefixes
|
|
341
|
+
*/
|
|
342
|
+
function compileRunArray(run: unknown[]): unknown[] {
|
|
343
|
+
return run.map(compileRunElement)
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Compile typed TestCase to raw format (strips __typename)
|
|
348
|
+
*/
|
|
349
|
+
const compileTestCase = (testCase: TestCase) => ({
|
|
350
|
+
id: testCase.id,
|
|
351
|
+
name: testCase.name,
|
|
352
|
+
run: compileRunArray(testCase.run),
|
|
353
|
+
exit_on_failed: testCase.exit_on_failed,
|
|
354
|
+
commented: testCase.commented,
|
|
355
|
+
pre_delay: testCase.pre_delay,
|
|
356
|
+
post_delay: testCase.post_delay,
|
|
357
|
+
post_delay_rule: testCase.post_delay_rule,
|
|
358
|
+
jump_cond: testCase.jump_cond.map((cond) => ({
|
|
359
|
+
type: cond.type,
|
|
360
|
+
status: cond.status,
|
|
361
|
+
variable: cond.variable,
|
|
362
|
+
operator: cond.operator,
|
|
363
|
+
value: cond.value,
|
|
364
|
+
jump_to: cond.jump_to,
|
|
365
|
+
})),
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Compile typed TestVariable to raw format (strips __typename)
|
|
370
|
+
*/
|
|
371
|
+
const compileTestVariable = (variable: TestVariable) => ({
|
|
372
|
+
id: variable.id,
|
|
373
|
+
name: variable.name,
|
|
374
|
+
type: variable.type,
|
|
375
|
+
value: variable.value,
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Convert an array of items with id property to an id-keyed record
|
|
380
|
+
*/
|
|
381
|
+
const arrayToIdMap = <T extends { id: string }, R>(
|
|
382
|
+
items: T[],
|
|
383
|
+
transform: (item: T) => R,
|
|
384
|
+
): Record<string, R> => Object.fromEntries(items.map((item) => [item.id, transform(item)]))
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Compile typed AutomationTest to raw format
|
|
388
|
+
*/
|
|
389
|
+
const compileAutomationTest = (test: AutomationTest) => ({
|
|
390
|
+
id: test.id,
|
|
391
|
+
title: test.title,
|
|
392
|
+
timeout: test.timeout,
|
|
393
|
+
trigger_type: test.trigger_type,
|
|
394
|
+
cron: test.cron,
|
|
395
|
+
skip_trigger_type_check: test.skip_trigger_type_check,
|
|
396
|
+
local_sync: test.local_sync,
|
|
397
|
+
meta: test.meta,
|
|
398
|
+
case_map: arrayToIdMap(test.cases, compileTestCase),
|
|
399
|
+
var_map: arrayToIdMap(test.variables, compileTestVariable),
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Compile typed AutomationTestMap to raw format
|
|
404
|
+
*/
|
|
405
|
+
const compileAutomationTestMap = (testMap: AutomationTestMap) => ({
|
|
406
|
+
title: testMap.title,
|
|
407
|
+
createdAt: testMap.createdAt,
|
|
408
|
+
map: arrayToIdMap(testMap.tests, compileAutomationTest),
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Compile typed AutomationMap to raw automation_map format
|
|
413
|
+
*/
|
|
414
|
+
const compileAutomation = (automationMap: AutomationMap) =>
|
|
415
|
+
Object.fromEntries(
|
|
416
|
+
Object.entries(automationMap).map(([mapId, testMap]) => [
|
|
417
|
+
mapId,
|
|
418
|
+
compileAutomationTestMap(testMap),
|
|
419
|
+
]),
|
|
420
|
+
)
|
|
421
|
+
|
|
328
422
|
export const compile = async (app: Application) => {
|
|
329
423
|
await new Promise((resolve) => setImmediate(resolve, 0))
|
|
330
424
|
const config = {
|
|
@@ -338,7 +432,7 @@ export const compile = async (app: Application) => {
|
|
|
338
432
|
brick: !subspace.unexpanded.brick,
|
|
339
433
|
generator: !subspace.unexpanded.generator,
|
|
340
434
|
canvas: subspace.unexpanded.canvas?.reduce((acc, canvas) => {
|
|
341
|
-
acc[canvas.id] = canvas?.id
|
|
435
|
+
acc[canvas.id] = !canvas?.id
|
|
342
436
|
return acc
|
|
343
437
|
}, {}),
|
|
344
438
|
property_bank: !subspace.unexpanded.data,
|
|
@@ -377,12 +471,12 @@ export const compile = async (app: Application) => {
|
|
|
377
471
|
animationRunType: animationDef.runType,
|
|
378
472
|
compose_type: animationDef.composeType,
|
|
379
473
|
item_list: animationDef.items.map((item, index) => {
|
|
380
|
-
const
|
|
381
|
-
if (!
|
|
474
|
+
const innerAnimation = item()
|
|
475
|
+
if (!innerAnimation?.id)
|
|
382
476
|
throw new Error(
|
|
383
|
-
`Invalid animation index: ${index} (animation: ${
|
|
477
|
+
`Invalid animation index: ${index} (animation: ${innerAnimation.id}, subspace ${subspace.id})`,
|
|
384
478
|
)
|
|
385
|
-
return { animation_id:
|
|
479
|
+
return { animation_id: innerAnimation.id }
|
|
386
480
|
}),
|
|
387
481
|
}
|
|
388
482
|
}
|
|
@@ -461,7 +555,7 @@ export const compile = async (app: Application) => {
|
|
|
461
555
|
property.brickList = brickList
|
|
462
556
|
} else {
|
|
463
557
|
// Not supported Data for brickList
|
|
464
|
-
throw new
|
|
558
|
+
throw new TypeError('Not supported Data for brickList directly')
|
|
465
559
|
}
|
|
466
560
|
if (Array.isArray(brickItems.brickDetails)) {
|
|
467
561
|
const brickDetails = (brickItems.brickDetails || []).map((item, index) =>
|
|
@@ -470,7 +564,7 @@ export const compile = async (app: Application) => {
|
|
|
470
564
|
property.brickDetails = brickDetails
|
|
471
565
|
} else {
|
|
472
566
|
// Not supported Data for brickList
|
|
473
|
-
throw new
|
|
567
|
+
throw new TypeError('Not supported Data for brickList directly')
|
|
474
568
|
}
|
|
475
569
|
}
|
|
476
570
|
map[brick.id] = {
|
|
@@ -677,6 +771,8 @@ export const compile = async (app: Application) => {
|
|
|
677
771
|
camelCase: false,
|
|
678
772
|
errorReference: `(data: ${data.id}, subspace ${subspace.id})`,
|
|
679
773
|
}),
|
|
774
|
+
hit_equal: data.hit_equal,
|
|
775
|
+
hit_regex: data.hit_regex,
|
|
680
776
|
}
|
|
681
777
|
return map
|
|
682
778
|
}, {}),
|
|
@@ -694,7 +790,7 @@ export const compile = async (app: Application) => {
|
|
|
694
790
|
if (!acc[port.key]) acc[port.key] = null
|
|
695
791
|
|
|
696
792
|
let sourceId
|
|
697
|
-
|
|
793
|
+
const sourceNode = port.source()
|
|
698
794
|
if (sourceNode?.__typename === 'DataCalculationData')
|
|
699
795
|
sourceId = (sourceNode as DataCalculationData).data().id
|
|
700
796
|
if (sourceNode?.__typename === 'DataCommand') sourceId = sourceNode.id
|
|
@@ -715,7 +811,7 @@ export const compile = async (app: Application) => {
|
|
|
715
811
|
if (!acc[port.key]) acc[port.key] = null
|
|
716
812
|
|
|
717
813
|
let targetId
|
|
718
|
-
|
|
814
|
+
const targetNode = port.target()
|
|
719
815
|
if (targetNode?.__typename === 'DataCalculationData')
|
|
720
816
|
targetId = (targetNode as DataCalculationData).data().id
|
|
721
817
|
if (targetNode?.__typename === 'DataCommand') targetId = targetNode.id
|
|
@@ -770,9 +866,9 @@ export const compile = async (app: Application) => {
|
|
|
770
866
|
type: `command-node-${type}`,
|
|
771
867
|
properties: {
|
|
772
868
|
command: commandNode.__commandName,
|
|
773
|
-
args: args.reduce((
|
|
774
|
-
|
|
775
|
-
return
|
|
869
|
+
args: args.reduce((argsAcc, input) => {
|
|
870
|
+
argsAcc[input.key] = input.source
|
|
871
|
+
return argsAcc
|
|
776
872
|
}, {}),
|
|
777
873
|
},
|
|
778
874
|
in: generateInputPorts(inputs),
|
|
@@ -784,12 +880,12 @@ export const compile = async (app: Application) => {
|
|
|
784
880
|
calc.editor_info = mapCalc.editorInfo.reduce((acc, editorInfo) => {
|
|
785
881
|
acc[getNodeId(editorInfo.node)] = {
|
|
786
882
|
position: editorInfo.position,
|
|
787
|
-
points: editorInfo.points.reduce((
|
|
883
|
+
points: editorInfo.points.reduce((pointsAcc, point) => {
|
|
788
884
|
const sourceId = getNodeId(point.source)
|
|
789
885
|
const targetId = getNodeId(point.target)
|
|
790
886
|
const key = `${sourceId}-${point.sourceOutputKey}-${targetId}-${point.targetInputKey}`
|
|
791
|
-
|
|
792
|
-
return
|
|
887
|
+
pointsAcc[key] = point.positions
|
|
888
|
+
return pointsAcc
|
|
793
889
|
}, {}),
|
|
794
890
|
}
|
|
795
891
|
return acc
|
|
@@ -864,8 +960,13 @@ export const compile = async (app: Application) => {
|
|
|
864
960
|
root_subspace_id: app.rootSubspace.id,
|
|
865
961
|
fonts: app.fonts,
|
|
866
962
|
...compileApplicationSettings(app.settings),
|
|
867
|
-
|
|
868
|
-
|
|
963
|
+
// Use typed automationMap if available, otherwise fall back to TEMP metadata
|
|
964
|
+
test_map: app.automationMap
|
|
965
|
+
? compileAutomation(app.automationMap)['AUTOMATION_MAP_DEFAULT']?.map || {}
|
|
966
|
+
: app.metadata?.TEMP_test_map || {},
|
|
967
|
+
automation_map: app.automationMap
|
|
968
|
+
? compileAutomation(app.automationMap)
|
|
969
|
+
: app.metadata?.TEMP_automation_map || {},
|
|
869
970
|
}
|
|
870
971
|
return config
|
|
871
972
|
}
|
package/compile/util.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { makeId } from '../utils/id'
|
|
|
3
3
|
type ScriptConfig = {
|
|
4
4
|
inputs: Record<string, string>
|
|
5
5
|
enable_async: boolean
|
|
6
|
+
trigger_mode?: 'auto' | 'manual'
|
|
6
7
|
disabled_triggers: Record<string, boolean>
|
|
7
8
|
output: string | null
|
|
8
9
|
outputs: Record<string, string[]>
|
|
@@ -13,6 +14,8 @@ type ScriptConfig = {
|
|
|
13
14
|
const errorMsg = 'Not allow duplicate set property id between inputs / outputs / output / error.'
|
|
14
15
|
|
|
15
16
|
export const validateConfig = (config: ScriptConfig) => {
|
|
17
|
+
// Skip input/output overlap validation in manual mode (allows same data node in both)
|
|
18
|
+
if (config.trigger_mode === 'manual') return
|
|
16
19
|
if (config.error && config.inputs[config.error]) {
|
|
17
20
|
throw new Error(`${errorMsg}. key: error`)
|
|
18
21
|
}
|
|
@@ -87,7 +90,8 @@ export const generateCalulationMap = (config: ScriptConfig, opts?: { snapshotMod
|
|
|
87
90
|
{
|
|
88
91
|
id: key,
|
|
89
92
|
port: 'value',
|
|
90
|
-
disable_trigger_command:
|
|
93
|
+
disable_trigger_command:
|
|
94
|
+
config.trigger_mode === 'manual' || config.disabled_triggers?.[key] || undefined,
|
|
91
95
|
},
|
|
92
96
|
],
|
|
93
97
|
},
|
|
@@ -152,6 +156,8 @@ export const generateCalulationMap = (config: ScriptConfig, opts?: { snapshotMod
|
|
|
152
156
|
points: {},
|
|
153
157
|
}
|
|
154
158
|
pbList.forEach((pb, pbIndex) => {
|
|
159
|
+
// Check if this data node already exists (it might be used as both input and output)
|
|
160
|
+
const existingNode = acc.map[pb] || inputs.map[pb]
|
|
155
161
|
acc.map[pb] = {
|
|
156
162
|
type: 'data-node',
|
|
157
163
|
properties: {},
|
|
@@ -164,7 +170,8 @@ export const generateCalulationMap = (config: ScriptConfig, opts?: { snapshotMod
|
|
|
164
170
|
],
|
|
165
171
|
},
|
|
166
172
|
out: {
|
|
167
|
-
value
|
|
173
|
+
// Preserve existing out.value if node is also used as input
|
|
174
|
+
value: existingNode?.out?.value ?? null,
|
|
168
175
|
},
|
|
169
176
|
}
|
|
170
177
|
acc.editorInfo[pb] = {
|
|
@@ -292,7 +299,8 @@ export const generateCalulationMap = (config: ScriptConfig, opts?: { snapshotMod
|
|
|
292
299
|
],
|
|
293
300
|
},
|
|
294
301
|
out: {
|
|
295
|
-
value
|
|
302
|
+
// Preserve existing out.value if node is also used as input
|
|
303
|
+
value: inputs.map[config.error]?.out?.value ?? null,
|
|
296
304
|
},
|
|
297
305
|
},
|
|
298
306
|
}),
|
|
@@ -309,7 +317,8 @@ export const generateCalulationMap = (config: ScriptConfig, opts?: { snapshotMod
|
|
|
309
317
|
],
|
|
310
318
|
},
|
|
311
319
|
out: {
|
|
312
|
-
value
|
|
320
|
+
// Preserve existing out.value if node is also used as input
|
|
321
|
+
value: inputs.map[config.output]?.out?.value ?? null,
|
|
313
322
|
},
|
|
314
323
|
},
|
|
315
324
|
}),
|
package/package.json
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fugood/bricks-project",
|
|
3
|
-
"version": "2.23.0
|
|
3
|
+
"version": "2.23.0",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"build": "
|
|
6
|
+
"build": "bun scripts/build.js"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
+
"@fugood/bricks-cli": "^2.23.0",
|
|
10
|
+
"@huggingface/gguf": "^0.3.2",
|
|
9
11
|
"@modelcontextprotocol/sdk": "^1.15.0",
|
|
12
|
+
"@toon-format/toon": "^2.1.0",
|
|
10
13
|
"@types/escodegen": "^0.0.10",
|
|
11
14
|
"@types/lodash": "^4.17.12",
|
|
12
15
|
"acorn": "^8.13.0",
|
|
13
|
-
"escodegen": "
|
|
16
|
+
"escodegen": "2.1.0",
|
|
17
|
+
"fuse.js": "^7.0.0",
|
|
14
18
|
"lodash": "^4.17.4",
|
|
15
19
|
"uuid": "^8.3.1"
|
|
16
20
|
},
|
|
17
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "398352b9923f97e914ac60acab519ca014aa6fb8"
|
|
18
22
|
}
|