@fugood/bricks-project 2.24.0-beta.4 → 2.24.0-beta.41
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/compile/action-name-map.ts +38 -0
- package/compile/index.ts +429 -160
- package/compile/util.ts +2 -0
- package/package.json +7 -3
- package/package.json.bak +27 -0
- package/skills/{bricks-project → bricks-ctor}/SKILL.md +2 -2
- package/skills/{bricks-project → bricks-ctor}/rules/animation.md +1 -1
- package/skills/{bricks-project → bricks-ctor}/rules/architecture-patterns.md +7 -0
- package/skills/bricks-ctor/rules/automations.md +221 -0
- package/skills/{bricks-project → bricks-ctor}/rules/buttress.md +10 -7
- package/skills/{bricks-project → bricks-ctor}/rules/data-calculation.md +1 -1
- package/skills/{bricks-project → bricks-ctor}/rules/local-sync.md +2 -2
- package/skills/{bricks-project → bricks-ctor}/rules/media-flow.md +3 -3
- package/skills/{bricks-project → bricks-ctor}/rules/remote-data-bank.md +6 -6
- package/skills/{bricks-project → bricks-ctor}/rules/standby-transition.md +1 -1
- package/skills/bricks-design/LICENSE.txt +180 -0
- package/skills/bricks-design/SKILL.md +66 -0
- package/tools/deploy.ts +66 -12
- package/tools/icons/fa6pro-meta.json +3669 -26125
- package/tools/mcp-server.ts +11 -878
- package/tools/mcp-tools/compile.ts +91 -0
- package/tools/mcp-tools/huggingface.ts +762 -0
- package/tools/mcp-tools/icons.ts +70 -0
- package/tools/mcp-tools/lottie.ts +102 -0
- package/tools/mcp-tools/media.ts +110 -0
- package/tools/postinstall.ts +137 -40
- package/tools/preview-main.mjs +146 -9
- package/tools/preview.ts +30 -2
- package/tools/pull.ts +37 -19
- package/tsconfig.json +16 -0
- package/types/animation.ts +4 -0
- package/types/automation.ts +4 -1
- package/types/brick-base.ts +1 -1
- package/types/bricks/Camera.ts +48 -13
- package/types/bricks/Chart.ts +10 -4
- package/types/bricks/GenerativeMedia.ts +30 -14
- package/types/bricks/Icon.ts +9 -5
- package/types/bricks/Image.ts +10 -6
- package/types/bricks/Items.ts +29 -15
- package/types/bricks/Lottie.ts +15 -7
- package/types/bricks/Maps.ts +16 -8
- package/types/bricks/QrCode.ts +9 -5
- package/types/bricks/Rect.ts +45 -6
- package/types/bricks/RichText.ts +9 -5
- package/types/bricks/Rive.ts +21 -11
- package/types/bricks/Slideshow.ts +20 -10
- package/types/bricks/Svg.ts +8 -4
- package/types/bricks/Text.ts +9 -5
- package/types/bricks/TextInput.ts +23 -13
- package/types/bricks/Video.ts +11 -7
- package/types/bricks/VideoStreaming.ts +8 -4
- package/types/bricks/WebRtcStream.ts +7 -3
- package/types/bricks/WebView.ts +12 -8
- package/types/canvas.ts +4 -2
- package/types/common.ts +19 -12
- package/types/data-calc-command.ts +2 -0
- package/types/data-calc.ts +1 -0
- package/types/data.ts +2 -0
- package/types/generators/AlarmClock.ts +17 -11
- package/types/generators/Assistant.ts +69 -18
- package/types/generators/BleCentral.ts +31 -11
- package/types/generators/BlePeripheral.ts +11 -7
- package/types/generators/CanvasMap.ts +10 -6
- package/types/generators/CastlesPay.ts +15 -7
- package/types/generators/DataBank.ts +44 -9
- package/types/generators/File.ts +109 -30
- package/types/generators/GraphQl.ts +12 -6
- package/types/generators/Http.ts +33 -10
- package/types/generators/HttpServer.ts +23 -15
- package/types/generators/Information.ts +9 -5
- package/types/generators/Intent.ts +15 -5
- package/types/generators/Iterator.ts +15 -11
- package/types/generators/Keyboard.ts +27 -13
- package/types/generators/LlmAnthropicCompat.ts +33 -11
- package/types/generators/LlmAppleBuiltin.ts +25 -10
- package/types/generators/LlmGgml.ts +140 -31
- package/types/generators/LlmMediaTekNeuroPilot.ts +235 -0
- package/types/generators/LlmMlx.ts +227 -0
- package/types/generators/LlmOnnx.ts +34 -14
- package/types/generators/LlmOpenAiCompat.ts +47 -11
- package/types/generators/LlmQualcommAiEngine.ts +45 -13
- package/types/generators/Mcp.ts +375 -34
- package/types/generators/McpServer.ts +58 -19
- package/types/generators/MediaFlow.ts +38 -12
- package/types/generators/MqttBroker.ts +29 -11
- package/types/generators/MqttClient.ts +19 -9
- package/types/generators/Question.ts +13 -9
- package/types/generators/RealtimeTranscription.ts +108 -19
- package/types/generators/RerankerGgml.ts +43 -12
- package/types/generators/SerialPort.ts +18 -10
- package/types/generators/SoundPlayer.ts +10 -4
- package/types/generators/SoundRecorder.ts +24 -9
- package/types/generators/SpeechToTextGgml.ts +52 -18
- package/types/generators/SpeechToTextOnnx.ts +18 -11
- package/types/generators/SpeechToTextPlatform.ts +15 -7
- package/types/generators/SqLite.ts +20 -10
- package/types/generators/Step.ts +9 -5
- package/types/generators/SttAppleBuiltin.ts +22 -9
- package/types/generators/Tcp.ts +13 -9
- package/types/generators/TcpServer.ts +20 -14
- package/types/generators/TextToSpeechAppleBuiltin.ts +21 -8
- package/types/generators/TextToSpeechGgml.ts +29 -11
- package/types/generators/TextToSpeechOnnx.ts +19 -12
- package/types/generators/TextToSpeechOpenAiLike.ts +14 -8
- package/types/generators/ThermalPrinter.ts +13 -9
- package/types/generators/Tick.ts +11 -7
- package/types/generators/Udp.ts +17 -8
- package/types/generators/VadGgml.ts +51 -14
- package/types/generators/VadOnnx.ts +42 -12
- package/types/generators/VadTraditional.ts +28 -13
- package/types/generators/VectorStore.ts +33 -12
- package/types/generators/Watchdog.ts +19 -10
- package/types/generators/WebCrawler.ts +11 -7
- package/types/generators/WebRtc.ts +30 -16
- package/types/generators/WebSocket.ts +11 -7
- package/types/generators/index.ts +2 -0
- package/types/subspace.ts +3 -0
- package/types/system.ts +1 -1
- package/utils/calc.ts +12 -8
- package/utils/event-props.ts +833 -1022
- package/utils/id.ts +4 -0
- package/api/index.ts +0 -1
- package/api/instance.ts +0 -213
- package/skills/bricks-project/rules/automations.md +0 -175
- package/types/generators/TextToSpeechApple.ts +0 -113
- package/types/generators/TtsAppleBuiltin.ts +0 -105
package/utils/id.ts
CHANGED
|
@@ -21,6 +21,7 @@ export const makeId = (
|
|
|
21
21
|
| 'property_bank_command'
|
|
22
22
|
| 'property_bank_calc'
|
|
23
23
|
| 'dynamic-brick'
|
|
24
|
+
| 'automation_map'
|
|
24
25
|
| 'test'
|
|
25
26
|
| 'test_case'
|
|
26
27
|
| 'test_var'
|
|
@@ -61,6 +62,9 @@ export const makeId = (
|
|
|
61
62
|
case 'property_bank_calc':
|
|
62
63
|
prefix = 'PROPERTY_BANK_COMMAND_MAP_'
|
|
63
64
|
break
|
|
65
|
+
case 'automation_map':
|
|
66
|
+
prefix = 'AUTOMATION_MAP_'
|
|
67
|
+
break
|
|
64
68
|
case 'test':
|
|
65
69
|
prefix = 'TEST_'
|
|
66
70
|
break
|
package/api/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './instance'
|
package/api/instance.ts
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
const apiUrlMap = {
|
|
2
|
-
production: 'https://display.bricks.tools/api/graphql-workspace',
|
|
3
|
-
beta: 'https://display-beta.bricks.tools/api/graphql-workspace',
|
|
4
|
-
development: 'http://localhost:3001/api/graphql-workspace',
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const workspaceToken = process.env.BRICKS_WORKSPACE_TOKEN
|
|
8
|
-
|
|
9
|
-
type Stage = 'production' | 'beta' | 'development'
|
|
10
|
-
|
|
11
|
-
const doGQL = async (stage: Stage, query: string, variables: Record<string, any>) => {
|
|
12
|
-
if (!workspaceToken) throw new Error('env BRICKS_WORKSPACE_TOKEN is not set')
|
|
13
|
-
|
|
14
|
-
const apiURL = apiUrlMap[stage]
|
|
15
|
-
if (!apiURL) throw new Error(`Invalid stage: ${stage}`)
|
|
16
|
-
|
|
17
|
-
const data = await fetch(apiURL, {
|
|
18
|
-
method: 'POST',
|
|
19
|
-
headers: {
|
|
20
|
-
'Content-Type': 'application/json',
|
|
21
|
-
Authorization: `Bearer ${workspaceToken}`,
|
|
22
|
-
},
|
|
23
|
-
body: JSON.stringify({ query, variables }),
|
|
24
|
-
}).then((res) => res.json())
|
|
25
|
-
|
|
26
|
-
if (data.error && data.error.message) throw new Error(data.error.message)
|
|
27
|
-
return data
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const pullApp = async (stage: Stage, appId: string) => {
|
|
31
|
-
const { data, errors } = await doGQL(
|
|
32
|
-
stage,
|
|
33
|
-
`query BRICKS_PROJECT_application($id: ID!) {
|
|
34
|
-
application(id: $id) {
|
|
35
|
-
_id
|
|
36
|
-
name
|
|
37
|
-
description
|
|
38
|
-
config
|
|
39
|
-
lock {
|
|
40
|
-
enabled
|
|
41
|
-
}
|
|
42
|
-
dev_ref {
|
|
43
|
-
is_dev
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}`,
|
|
47
|
-
{ id: appId },
|
|
48
|
-
)
|
|
49
|
-
if (errors) throw new Error(errors[0].message)
|
|
50
|
-
|
|
51
|
-
const app = data.application
|
|
52
|
-
if (!app) throw new Error('App not found')
|
|
53
|
-
if (app.lock.enabled) throw new Error('App is locked')
|
|
54
|
-
// TODO: Uncomment it on leaving experimental
|
|
55
|
-
// if (!app.dev_ref.is_dev)
|
|
56
|
-
// throw new Error(
|
|
57
|
-
// 'Currently BRICKS Project is experimental, please use the fork version of the app',
|
|
58
|
-
// )
|
|
59
|
-
return app
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
type Config = { title?: string }
|
|
63
|
-
|
|
64
|
-
export const deployApp = async (
|
|
65
|
-
stage: Stage,
|
|
66
|
-
appId: string,
|
|
67
|
-
config: Config,
|
|
68
|
-
lastCommitId?: string,
|
|
69
|
-
changelogs?: string,
|
|
70
|
-
version?: string,
|
|
71
|
-
) => {
|
|
72
|
-
const app = await pullApp(stage, appId)
|
|
73
|
-
if (app.config?.bricks_project_last_commit_id === lastCommitId)
|
|
74
|
-
throw new Error('No changes to deploy')
|
|
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
|
-
|
|
81
|
-
const { errors } = await doGQL(
|
|
82
|
-
stage,
|
|
83
|
-
`mutation BRICKS_PROJECT_releaseApplication(
|
|
84
|
-
$id: ID!,
|
|
85
|
-
$config: String,
|
|
86
|
-
$releaseCurrentVersion: String,
|
|
87
|
-
$releaseCurrentVersionNote: String
|
|
88
|
-
) {
|
|
89
|
-
updateApplication(
|
|
90
|
-
id: $id,
|
|
91
|
-
config: $config,
|
|
92
|
-
releaseCurrentVersion: $releaseCurrentVersion,
|
|
93
|
-
releaseCurrentVersionNote: $releaseCurrentVersionNote
|
|
94
|
-
) {
|
|
95
|
-
_id
|
|
96
|
-
name
|
|
97
|
-
}
|
|
98
|
-
}`,
|
|
99
|
-
{
|
|
100
|
-
id: appId,
|
|
101
|
-
config: JSON.stringify({
|
|
102
|
-
...config,
|
|
103
|
-
title: versionName,
|
|
104
|
-
bricks_project_last_commit_id: lastCommitId,
|
|
105
|
-
}),
|
|
106
|
-
releaseCurrentVersion: versionName,
|
|
107
|
-
releaseCurrentVersionNote: releaseNote,
|
|
108
|
-
},
|
|
109
|
-
)
|
|
110
|
-
if (errors) throw new Error(errors[0].message)
|
|
111
|
-
return true
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export const pullApplicationProject = async (stage: Stage, appId: string) => {
|
|
115
|
-
const { data, errors } = await doGQL(
|
|
116
|
-
stage,
|
|
117
|
-
`query BRICKS_PROJECT_applicationProject($id: ID!) {
|
|
118
|
-
UNSTABLE_applicationProject(id: $id, buildApplicationOnly: true)
|
|
119
|
-
}`,
|
|
120
|
-
{ id: appId },
|
|
121
|
-
)
|
|
122
|
-
if (errors) throw new Error(errors[0].message)
|
|
123
|
-
if (!data.UNSTABLE_applicationProject) throw new Error('Application not found')
|
|
124
|
-
return data.UNSTABLE_applicationProject
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export const pullModule = async (stage: Stage, modId: string) => {
|
|
128
|
-
const { data, errors } = await doGQL(
|
|
129
|
-
stage,
|
|
130
|
-
`query BRICKS_PROJECT_module($id: ID!) {
|
|
131
|
-
module(id: $id) {
|
|
132
|
-
_id
|
|
133
|
-
name
|
|
134
|
-
description
|
|
135
|
-
is_public
|
|
136
|
-
config
|
|
137
|
-
}
|
|
138
|
-
}`,
|
|
139
|
-
{ id: modId },
|
|
140
|
-
)
|
|
141
|
-
if (errors) throw new Error(errors[0].message)
|
|
142
|
-
const mod = data.module
|
|
143
|
-
if (!mod) throw new Error('Module not found')
|
|
144
|
-
if (mod.is_public)
|
|
145
|
-
throw new Error(
|
|
146
|
-
'Currently BRICKS Project is experimental, public module deployment is temporary not recommended',
|
|
147
|
-
)
|
|
148
|
-
return mod
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export const deployModule = async (
|
|
152
|
-
stage: Stage,
|
|
153
|
-
modId: string,
|
|
154
|
-
config: Config,
|
|
155
|
-
lastCommitId?: string,
|
|
156
|
-
changelogs?: string,
|
|
157
|
-
version?: string,
|
|
158
|
-
) => {
|
|
159
|
-
const mod = await pullModule(stage, modId)
|
|
160
|
-
if (mod.config?.bricks_project_last_commit_id === lastCommitId)
|
|
161
|
-
throw new Error('No changes to deploy')
|
|
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
|
-
|
|
168
|
-
const { errors } = await doGQL(
|
|
169
|
-
stage,
|
|
170
|
-
`mutation BRICKS_PROJECT_releaseModule(
|
|
171
|
-
$id: ID!,
|
|
172
|
-
$config: String,
|
|
173
|
-
$releaseCurrentVersion: String,
|
|
174
|
-
$releaseCurrentVersionNote: String
|
|
175
|
-
) {
|
|
176
|
-
updateModule(
|
|
177
|
-
id: $id
|
|
178
|
-
config: $config
|
|
179
|
-
validateConfig: true
|
|
180
|
-
releaseCurrentVersion: $releaseCurrentVersion
|
|
181
|
-
releaseCurrentVersionNote: $releaseCurrentVersionNote
|
|
182
|
-
) {
|
|
183
|
-
_id
|
|
184
|
-
name
|
|
185
|
-
}
|
|
186
|
-
}`,
|
|
187
|
-
{
|
|
188
|
-
id: modId,
|
|
189
|
-
config: JSON.stringify({
|
|
190
|
-
...config,
|
|
191
|
-
title: versionName,
|
|
192
|
-
bricks_project_last_commit_id: lastCommitId,
|
|
193
|
-
}),
|
|
194
|
-
releaseCurrentVersion: versionName,
|
|
195
|
-
releaseCurrentVersionNote: releaseNote,
|
|
196
|
-
},
|
|
197
|
-
)
|
|
198
|
-
if (errors) throw new Error(errors[0].message)
|
|
199
|
-
return true
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export const pullModuleProject = async (stage: Stage, modId: string) => {
|
|
203
|
-
const { data, errors } = await doGQL(
|
|
204
|
-
stage,
|
|
205
|
-
`query BRICKS_PROJECT_moduleProject($id: ID!) {
|
|
206
|
-
UNSTABLE_moduleProject(id: $id, buildApplicationOnly: true)
|
|
207
|
-
}`,
|
|
208
|
-
{ id: modId },
|
|
209
|
-
)
|
|
210
|
-
if (errors) throw new Error(errors[0].message)
|
|
211
|
-
if (!data.UNSTABLE_moduleProject) throw new Error('Module not found')
|
|
212
|
-
return data.UNSTABLE_moduleProject
|
|
213
|
-
}
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# Automations
|
|
2
|
-
|
|
3
|
-
E2E testing and scheduled execution for BRICKS applications. Simulates user behavior and validates application state.
|
|
4
|
-
|
|
5
|
-
## Automation Types
|
|
6
|
-
|
|
7
|
-
| Type | Description |
|
|
8
|
-
|------|-------------|
|
|
9
|
-
| `launch` | Run on application launch (restarts app when run manually) |
|
|
10
|
-
| `anytime` | Execute anytime via manual trigger |
|
|
11
|
-
| `cron` | Scheduled execution using crontab expressions |
|
|
12
|
-
|
|
13
|
-
## Simulation Actions
|
|
14
|
-
|
|
15
|
-
Automations can simulate:
|
|
16
|
-
- **Brick Press**: Tap/click on bricks
|
|
17
|
-
- **Key Events**: Key up/down for keyboard input
|
|
18
|
-
- **HTTP Request**: API calls
|
|
19
|
-
- **Execute Action**: Trigger system or generator actions
|
|
20
|
-
|
|
21
|
-
## Assertions
|
|
22
|
-
|
|
23
|
-
Automations can validate:
|
|
24
|
-
- **Brick Exists**: Check if brick is rendered
|
|
25
|
-
- **Event Triggered**: Verify event from Brick/Generator/Canvas
|
|
26
|
-
- **Canvas Changed**: Confirm canvas navigation
|
|
27
|
-
- **Property Assert**: Check Data Bank values
|
|
28
|
-
- **Property Updated**: Wait for property change
|
|
29
|
-
- **Match Screenshot**: Visual regression testing
|
|
30
|
-
|
|
31
|
-
## TypeScript Example
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
const testLoginFlow: AutomationTest = {
|
|
35
|
-
__typename: 'AutomationTest',
|
|
36
|
-
id: 'test-login-flow',
|
|
37
|
-
title: 'Test Login Flow',
|
|
38
|
-
timeout: 30000,
|
|
39
|
-
trigger_type: 'launch',
|
|
40
|
-
cases: [
|
|
41
|
-
{
|
|
42
|
-
__typename: 'TestCase',
|
|
43
|
-
id: 'wait-login-canvas',
|
|
44
|
-
name: 'Wait for login canvas',
|
|
45
|
-
run: ['wait_until_canvas_change', () => mainSubspace, () => loginCanvas, 5000],
|
|
46
|
-
exit_on_failed: true,
|
|
47
|
-
commented: false,
|
|
48
|
-
pre_delay: 0,
|
|
49
|
-
post_delay: 0,
|
|
50
|
-
jump_cond: [],
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
__typename: 'TestCase',
|
|
54
|
-
id: 'press-username',
|
|
55
|
-
name: 'Press username input',
|
|
56
|
-
run: ['brick_press', () => mainSubspace, () => usernameInput],
|
|
57
|
-
exit_on_failed: true,
|
|
58
|
-
commented: false,
|
|
59
|
-
pre_delay: 0,
|
|
60
|
-
post_delay: 100,
|
|
61
|
-
jump_cond: [],
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
__typename: 'TestCase',
|
|
65
|
-
id: 'assert-username',
|
|
66
|
-
name: 'Assert username value',
|
|
67
|
-
run: ['assert_property', () => mainSubspace, () => usernameData, 'testuser'],
|
|
68
|
-
exit_on_failed: true,
|
|
69
|
-
commented: false,
|
|
70
|
-
pre_delay: 0,
|
|
71
|
-
post_delay: 0,
|
|
72
|
-
jump_cond: [],
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
__typename: 'TestCase',
|
|
76
|
-
id: 'press-login',
|
|
77
|
-
name: 'Press login button',
|
|
78
|
-
run: ['brick_press', () => mainSubspace, () => loginButton],
|
|
79
|
-
exit_on_failed: true,
|
|
80
|
-
commented: false,
|
|
81
|
-
pre_delay: 0,
|
|
82
|
-
post_delay: 0,
|
|
83
|
-
jump_cond: [],
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
__typename: 'TestCase',
|
|
87
|
-
id: 'wait-dashboard',
|
|
88
|
-
name: 'Wait for dashboard',
|
|
89
|
-
run: ['wait_until_canvas_change', () => mainSubspace, () => dashboardCanvas, 10000],
|
|
90
|
-
exit_on_failed: true,
|
|
91
|
-
commented: false,
|
|
92
|
-
pre_delay: 0,
|
|
93
|
-
post_delay: 0,
|
|
94
|
-
jump_cond: [],
|
|
95
|
-
},
|
|
96
|
-
],
|
|
97
|
-
variables: [],
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## Test Methods
|
|
102
|
-
|
|
103
|
-
| Method | Signature | Description |
|
|
104
|
-
|--------|-----------|-------------|
|
|
105
|
-
| `brick_press` | `[subspace, brick, options?]` | Simulate brick press |
|
|
106
|
-
| `brick_exists` | `[subspace, brick, frame?]` | Check brick exists |
|
|
107
|
-
| `wait_until_brick_exists` | `[subspace, brick, timeout?, frame?]` | Wait for brick |
|
|
108
|
-
| `wait_until_event_trigger` | `[subspace, sender, eventKey, timeout?]` | Wait for event |
|
|
109
|
-
| `wait_until_canvas_change` | `[subspace, canvas, timeout?]` | Wait for canvas |
|
|
110
|
-
| `keydown` | `[keyCode, pressedKey?, flags?]` | Key down event |
|
|
111
|
-
| `keyup` | `[keyCode, pressedKey?, flags?]` | Key up event |
|
|
112
|
-
| `http_request` | `[url, options?]` | HTTP request |
|
|
113
|
-
| `assert_property` | `[subspace, property, value]` | Assert data value |
|
|
114
|
-
| `wait_until_property_change` | `[subspace, property, value, timeout?]` | Wait for value |
|
|
115
|
-
| `execute_action` | `[subspace, handler, action, params?, options?]` | Execute action |
|
|
116
|
-
| `match_screenshot` | `[name, threshold?, maxRetry?]` | Screenshot compare |
|
|
117
|
-
| `delay` | `[subspace?, property?, defaultValue?]` | Delay execution |
|
|
118
|
-
|
|
119
|
-
## Recording Automations
|
|
120
|
-
|
|
121
|
-
In BRICKS Editor Preview mode:
|
|
122
|
-
1. Perform operations normally
|
|
123
|
-
2. Open menu (right-bottom corner)
|
|
124
|
-
3. Select "Record Events as Automation"
|
|
125
|
-
4. Generated automation appears in Automations list
|
|
126
|
-
|
|
127
|
-
## Running Automations
|
|
128
|
-
|
|
129
|
-
### Manual Run
|
|
130
|
-
`Menu` → `Automations` → Select automation → `Run`
|
|
131
|
-
|
|
132
|
-
### On Launch
|
|
133
|
-
`Bind Device` → `Select Automation` (only `launch` or `cron` types)
|
|
134
|
-
|
|
135
|
-
### Scheduled (Cron)
|
|
136
|
-
`Bind Device` → `Cron Automation` (allows multi-select)
|
|
137
|
-
|
|
138
|
-
Use [crontab.guru](https://crontab.guru) to build cron expressions.
|
|
139
|
-
|
|
140
|
-
## Screenshot Testing
|
|
141
|
-
|
|
142
|
-
Visual regression testing with screenshot comparison:
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
{
|
|
146
|
-
__typename: 'TestCase',
|
|
147
|
-
id: 'screenshot-dashboard',
|
|
148
|
-
name: 'Match dashboard screenshot',
|
|
149
|
-
run: ['match_screenshot', 'dashboard-initial-state', 0.01, 3],
|
|
150
|
-
exit_on_failed: true,
|
|
151
|
-
commented: false,
|
|
152
|
-
pre_delay: 500, // Wait for UI to settle
|
|
153
|
-
post_delay: 0,
|
|
154
|
-
jump_cond: [],
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
Screenshots can be stored:
|
|
159
|
-
- Local file system
|
|
160
|
-
- Media Flow workspace
|
|
161
|
-
|
|
162
|
-
First run captures baseline. Use "Run with Update" to update baseline.
|
|
163
|
-
|
|
164
|
-
## Module Support
|
|
165
|
-
|
|
166
|
-
Automations work with Modules. Use Manual Run in Preview mode for module testing.
|
|
167
|
-
|
|
168
|
-
## Best Practices
|
|
169
|
-
|
|
170
|
-
1. **Test culture**: Create automations for every significant flow
|
|
171
|
-
2. **CI/CD integration**: Use `launch` automations for deployment validation
|
|
172
|
-
3. **Incremental waits**: Use `EXPECT_*` steps with appropriate timeouts
|
|
173
|
-
4. **Visual testing**: Add screenshot comparisons for critical UI states
|
|
174
|
-
5. **Cron monitoring**: Schedule health checks for production displays
|
|
175
|
-
6. **Isolation**: Each automation should be independent and idempotent
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/* Auto generated by build script */
|
|
2
|
-
import type { SwitchCondInnerStateCurrentCanvas, SwitchCondData, SwitchDef } from '../switch'
|
|
3
|
-
import type { Data, DataLink } from '../data'
|
|
4
|
-
import type {
|
|
5
|
-
Generator,
|
|
6
|
-
EventAction,
|
|
7
|
-
ActionWithDataParams,
|
|
8
|
-
ActionWithParams,
|
|
9
|
-
Action,
|
|
10
|
-
EventProperty,
|
|
11
|
-
} from '../common'
|
|
12
|
-
|
|
13
|
-
/* Load the TTS model */
|
|
14
|
-
export type GeneratorAppleTTSActionLoadModel = Action & {
|
|
15
|
-
__actionName: 'GENERATOR_APPLE_TTS_LOAD_MODEL'
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/* Generate audio */
|
|
19
|
-
export type GeneratorAppleTTSActionGenerate = ActionWithParams & {
|
|
20
|
-
__actionName: 'GENERATOR_APPLE_TTS_GENERATE'
|
|
21
|
-
params?: Array<{
|
|
22
|
-
input: 'text'
|
|
23
|
-
value?: string | DataLink | EventProperty
|
|
24
|
-
mapping?: string
|
|
25
|
-
}>
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/* Clean cache */
|
|
29
|
-
export type GeneratorAppleTTSActionCleanCache = Action & {
|
|
30
|
-
__actionName: 'GENERATOR_APPLE_TTS_CLEAN_CACHE'
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/* Cancel current generation and clear queue */
|
|
34
|
-
export type GeneratorAppleTTSActionCancel = Action & {
|
|
35
|
-
__actionName: 'GENERATOR_APPLE_TTS_CANCEL'
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
interface GeneratorAppleTTSDef {
|
|
39
|
-
/*
|
|
40
|
-
Default property:
|
|
41
|
-
{
|
|
42
|
-
"language": "en-US",
|
|
43
|
-
"outputType": "play",
|
|
44
|
-
"cacheGenerated": true,
|
|
45
|
-
"autoInferEnable": false,
|
|
46
|
-
"softBreakRegex": "^[^\\r\\n\\t\\f\\v]*([\\r\\n]+|[。!?!?.]\\B)",
|
|
47
|
-
"hardBreakTime": 500
|
|
48
|
-
}
|
|
49
|
-
*/
|
|
50
|
-
property?: {
|
|
51
|
-
/* Initialize the TTS context on generator initialization */
|
|
52
|
-
init?: boolean | DataLink
|
|
53
|
-
/* Voice identifier */
|
|
54
|
-
voice?: string | DataLink
|
|
55
|
-
/* Language/locale (e.g., 'en-US') */
|
|
56
|
-
language?: string | DataLink
|
|
57
|
-
/* Output mode */
|
|
58
|
-
outputType?: 'play' | 'file' | DataLink
|
|
59
|
-
/* Enable cache for generated audio */
|
|
60
|
-
cacheGenerated?: boolean | DataLink
|
|
61
|
-
/* Text to generate */
|
|
62
|
-
prompt?: string | DataLink
|
|
63
|
-
/* Auto inference when prompt changes */
|
|
64
|
-
autoInferEnable?: boolean | DataLink
|
|
65
|
-
/* Segmentation rule for auto inference */
|
|
66
|
-
softBreakRegex?: string | DataLink
|
|
67
|
-
/* Time to force inference when softBreakRegex is not satisfied */
|
|
68
|
-
hardBreakTime?: number | DataLink
|
|
69
|
-
}
|
|
70
|
-
events?: {
|
|
71
|
-
/* Event triggered when state change */
|
|
72
|
-
onContextStateChange?: Array<EventAction>
|
|
73
|
-
/* Event triggered when error occurs */
|
|
74
|
-
onError?: Array<EventAction>
|
|
75
|
-
}
|
|
76
|
-
outlets?: {
|
|
77
|
-
/* Context state */
|
|
78
|
-
contextState?: () => Data
|
|
79
|
-
/* Generated audio file */
|
|
80
|
-
generatedAudio?: () => Data
|
|
81
|
-
/* Generated audio file is playing */
|
|
82
|
-
generatedAudioPlaying?: () => Data
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/* Text-to-speech synthesis using Apple's native speech synthesis
|
|
87
|
-
|
|
88
|
-
## Features
|
|
89
|
-
- Native Apple speech synthesis
|
|
90
|
-
- Natural sounding voices
|
|
91
|
-
- Privacy-focused on-device processing
|
|
92
|
-
- Multiple voice options
|
|
93
|
-
- Requires iOS 13+ (native speech synthesis) */
|
|
94
|
-
export type GeneratorAppleTTS = Generator &
|
|
95
|
-
GeneratorAppleTTSDef & {
|
|
96
|
-
templateKey: 'GENERATOR_APPLE_TTS'
|
|
97
|
-
switches: Array<
|
|
98
|
-
SwitchDef &
|
|
99
|
-
GeneratorAppleTTSDef & {
|
|
100
|
-
conds?: Array<{
|
|
101
|
-
method: '==' | '!=' | '>' | '<' | '>=' | '<='
|
|
102
|
-
cond:
|
|
103
|
-
| SwitchCondInnerStateCurrentCanvas
|
|
104
|
-
| SwitchCondData
|
|
105
|
-
| {
|
|
106
|
-
__typename: 'SwitchCondInnerStateOutlet'
|
|
107
|
-
outlet: 'contextState' | 'generatedAudio' | 'generatedAudioPlaying'
|
|
108
|
-
value: any
|
|
109
|
-
}
|
|
110
|
-
}>
|
|
111
|
-
}
|
|
112
|
-
>
|
|
113
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import type { SwitchCondInnerStateCurrentCanvas, SwitchCondData, SwitchDef } from '../switch'
|
|
2
|
-
import type { Data, DataLink } from '../data'
|
|
3
|
-
import type { Generator, EventAction, ActionWithParams, Action, EventProperty } from '../common'
|
|
4
|
-
|
|
5
|
-
/* Load the TTS model */
|
|
6
|
-
export type GeneratorAppleTTSActionLoadModel = Action & {
|
|
7
|
-
__actionName: 'GENERATOR_APPLE_TTS_LOAD_MODEL'
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/* Generate audio */
|
|
11
|
-
export type GeneratorAppleTTSActionGenerate = ActionWithParams & {
|
|
12
|
-
__actionName: 'GENERATOR_APPLE_TTS_GENERATE'
|
|
13
|
-
params?: Array<{
|
|
14
|
-
input: 'text'
|
|
15
|
-
value?: string | DataLink | EventProperty
|
|
16
|
-
mapping?: string
|
|
17
|
-
}>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/* Clean cache */
|
|
21
|
-
export type GeneratorAppleTTSActionCleanCache = Action & {
|
|
22
|
-
__actionName: 'GENERATOR_APPLE_TTS_CLEAN_CACHE'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/* Cancel current generation and clear queue */
|
|
26
|
-
export type GeneratorAppleTTSActionCancel = Action & {
|
|
27
|
-
__actionName: 'GENERATOR_APPLE_TTS_CANCEL'
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface GeneratorAppleTTSDef {
|
|
31
|
-
/*
|
|
32
|
-
Default property:
|
|
33
|
-
{
|
|
34
|
-
"language": "en-US",
|
|
35
|
-
"outputType": "play",
|
|
36
|
-
"cacheGenerated": true,
|
|
37
|
-
"autoInferEnable": false,
|
|
38
|
-
"softBreakRegex": "^[^\\r\\n\\t\\f\\v]*([\\r\\n]+|[。!?!?.]\\B)",
|
|
39
|
-
"hardBreakTime": 500
|
|
40
|
-
}
|
|
41
|
-
*/
|
|
42
|
-
property?: {
|
|
43
|
-
/* Initialize the TTS context on generator initialization */
|
|
44
|
-
init?: boolean | DataLink
|
|
45
|
-
/* Voice identifier */
|
|
46
|
-
voice?: string | DataLink
|
|
47
|
-
/* Language/locale (e.g., 'en-US') */
|
|
48
|
-
language?: string | DataLink
|
|
49
|
-
/* Output mode */
|
|
50
|
-
outputType?: 'play' | 'file' | DataLink
|
|
51
|
-
/* Enable cache for generated audio */
|
|
52
|
-
cacheGenerated?: boolean | DataLink
|
|
53
|
-
/* Text to generate */
|
|
54
|
-
prompt?: string | DataLink
|
|
55
|
-
/* Auto inference when prompt changes */
|
|
56
|
-
autoInferEnable?: boolean | DataLink
|
|
57
|
-
/* Segmentation rule for auto inference */
|
|
58
|
-
softBreakRegex?: string | DataLink
|
|
59
|
-
/* Time to force inference when softBreakRegex is not satisfied */
|
|
60
|
-
hardBreakTime?: number | DataLink
|
|
61
|
-
}
|
|
62
|
-
events?: {
|
|
63
|
-
/* Event triggered when state change */
|
|
64
|
-
onContextStateChange?: Array<EventAction>
|
|
65
|
-
/* Event triggered when error occurs */
|
|
66
|
-
onError?: Array<EventAction>
|
|
67
|
-
}
|
|
68
|
-
outlets?: {
|
|
69
|
-
/* Context state */
|
|
70
|
-
contextState?: () => Data
|
|
71
|
-
/* Generated audio file */
|
|
72
|
-
generatedAudio?: () => Data
|
|
73
|
-
/* Generated audio file is playing */
|
|
74
|
-
generatedAudioPlaying?: () => Data
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/* Text-to-speech synthesis using Apple's native speech synthesis
|
|
79
|
-
|
|
80
|
-
## Features
|
|
81
|
-
- Native Apple speech synthesis
|
|
82
|
-
- Natural sounding voices
|
|
83
|
-
- Privacy-focused on-device processing
|
|
84
|
-
- Multiple voice options
|
|
85
|
-
- Requires iOS 13+ (native speech synthesis) */
|
|
86
|
-
export type GeneratorAppleTTS = Generator &
|
|
87
|
-
GeneratorAppleTTSDef & {
|
|
88
|
-
templateKey: 'GENERATOR_APPLE_TTS'
|
|
89
|
-
switches: Array<
|
|
90
|
-
SwitchDef &
|
|
91
|
-
GeneratorAppleTTSDef & {
|
|
92
|
-
conds?: Array<{
|
|
93
|
-
method: '==' | '!=' | '>' | '<' | '>=' | '<='
|
|
94
|
-
cond:
|
|
95
|
-
| SwitchCondInnerStateCurrentCanvas
|
|
96
|
-
| SwitchCondData
|
|
97
|
-
| {
|
|
98
|
-
__typename: 'SwitchCondInnerStateOutlet'
|
|
99
|
-
outlet: 'contextState' | 'generatedAudio' | 'generatedAudioPlaying'
|
|
100
|
-
value: any
|
|
101
|
-
}
|
|
102
|
-
}>
|
|
103
|
-
}
|
|
104
|
-
>
|
|
105
|
-
}
|