@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/tools/preview-main.mjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { app, BrowserWindow } from 'electron'
|
|
3
3
|
import { readFile, writeFile } from 'fs/promises'
|
|
4
4
|
import { watchFile } from 'fs'
|
|
5
|
+
import { createServer } from 'http'
|
|
5
6
|
import { parseArgs } from 'util'
|
|
6
7
|
import * as TOON from '@toon-format/toon'
|
|
7
8
|
|
|
@@ -14,6 +15,7 @@ const { values } = parseArgs({
|
|
|
14
15
|
'test-id': { type: 'string' },
|
|
15
16
|
'test-title-like': { type: 'string' },
|
|
16
17
|
'no-keep-open': { type: 'boolean' },
|
|
18
|
+
'cdp-port': { type: 'string' },
|
|
17
19
|
},
|
|
18
20
|
strict: true,
|
|
19
21
|
allowPositionals: true,
|
|
@@ -42,13 +44,17 @@ let config = JSON.parse(await readFile(`${cwd}/.bricks/build/application-config.
|
|
|
42
44
|
let testId = values['test-id'] || null
|
|
43
45
|
if (!testId && values['test-title-like']) {
|
|
44
46
|
const titleLike = values['test-title-like'].toLowerCase()
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
const automationMap = config.automation_map || {}
|
|
48
|
+
for (const group of Object.values(automationMap)) {
|
|
49
|
+
const found = Object.entries(group.map || {}).find(([, test]) =>
|
|
50
|
+
test.title?.toLowerCase().includes(titleLike),
|
|
51
|
+
)
|
|
52
|
+
if (found) {
|
|
53
|
+
;[testId] = found
|
|
54
|
+
break
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!testId) {
|
|
52
58
|
throw new Error(`No automation found matching title: ${values['test-title-like']}`)
|
|
53
59
|
}
|
|
54
60
|
}
|
|
@@ -66,6 +72,133 @@ const previewUrlMap = {
|
|
|
66
72
|
const previewUrl = previewUrlMap[stage]
|
|
67
73
|
if (!previewUrl) throw new Error(`Invalid BRICKS_STAGE: ${stage}`)
|
|
68
74
|
|
|
75
|
+
// --- CDP WebSocket Server ---
|
|
76
|
+
// Bridges external CDP clients to the preview's postMessage-based CDP bridge.
|
|
77
|
+
// Usage: --cdp-port 9222
|
|
78
|
+
|
|
79
|
+
const startCdpServer = async (mainWindow, port) => {
|
|
80
|
+
const { WebSocketServer } = await import('ws')
|
|
81
|
+
const clients = new Set()
|
|
82
|
+
|
|
83
|
+
// Inject a listener in the preview that forwards CDP responses/events via console
|
|
84
|
+
const injectCdpRelay = () =>
|
|
85
|
+
mainWindow.webContents.executeJavaScript(`
|
|
86
|
+
if (!window.__cdpRelayInstalled) {
|
|
87
|
+
window.__cdpRelayInstalled = true
|
|
88
|
+
window.addEventListener('message', (evt) => {
|
|
89
|
+
try {
|
|
90
|
+
const d = typeof evt.data === 'string' ? JSON.parse(evt.data) : evt.data
|
|
91
|
+
if (d && (d.type === 'cdp-response' || d.type === 'cdp-event'))
|
|
92
|
+
console.log('[CDP]' + JSON.stringify(d))
|
|
93
|
+
} catch {}
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
`)
|
|
97
|
+
|
|
98
|
+
// Capture CDP messages from the preview's console output
|
|
99
|
+
mainWindow.webContents.on('console-message', (_event, ...rest) => {
|
|
100
|
+
const message = typeof rest[0] === 'object' ? rest[0].message : rest[1]
|
|
101
|
+
if (!message?.startsWith('[CDP]')) return
|
|
102
|
+
try {
|
|
103
|
+
const data = JSON.parse(message.slice(5))
|
|
104
|
+
// Translate to standard CDP wire format (strip internal type field)
|
|
105
|
+
const wireMsg =
|
|
106
|
+
data.type === 'cdp-response'
|
|
107
|
+
? { id: data.id, result: data.result, error: data.error }
|
|
108
|
+
: { method: data.method, params: data.params }
|
|
109
|
+
if (data.sessionId) wireMsg.sessionId = data.sessionId
|
|
110
|
+
const payload = JSON.stringify(wireMsg)
|
|
111
|
+
for (const c of clients) if (c.readyState === 1) c.send(payload)
|
|
112
|
+
} catch {}
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
// Find an available port before binding
|
|
116
|
+
const findPort = (p) =>
|
|
117
|
+
new Promise((resolve) => {
|
|
118
|
+
const probe = createServer()
|
|
119
|
+
probe.once('error', () => {
|
|
120
|
+
if (p < port + 100) resolve(findPort(p + 1))
|
|
121
|
+
else resolve(null)
|
|
122
|
+
})
|
|
123
|
+
probe.listen(p, () => probe.close(() => resolve(p)))
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
const actualPort = await findPort(port)
|
|
127
|
+
if (!actualPort) {
|
|
128
|
+
console.warn(`CDP server: no available port in range ${port}-${port + 99}`)
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// HTTP discovery endpoints (chrome://inspect, Playwright, etc.)
|
|
133
|
+
const httpServer = createServer((req, res) => {
|
|
134
|
+
if (req.url === '/json/list' || req.url === '/json') {
|
|
135
|
+
res.writeHead(200, { 'Content-Type': 'application/json' })
|
|
136
|
+
res.end(
|
|
137
|
+
JSON.stringify([
|
|
138
|
+
{
|
|
139
|
+
description: 'BRICKS Preview (CTOR Preview)',
|
|
140
|
+
id: 'bricks-preview',
|
|
141
|
+
title: 'BRICKS Preview',
|
|
142
|
+
type: 'page',
|
|
143
|
+
url: previewUrl,
|
|
144
|
+
webSocketDebuggerUrl: `ws://localhost:${actualPort}/ws`,
|
|
145
|
+
},
|
|
146
|
+
]),
|
|
147
|
+
)
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
if (req.url === '/json/version') {
|
|
151
|
+
res.writeHead(200, { 'Content-Type': 'application/json' })
|
|
152
|
+
res.end(JSON.stringify({ Browser: 'BRICKS Preview', 'Protocol-Version': '1.3' }))
|
|
153
|
+
return
|
|
154
|
+
}
|
|
155
|
+
// bricks-cli discovery endpoint
|
|
156
|
+
if (req.url === '/devtools/info') {
|
|
157
|
+
res.writeHead(200, { 'Content-Type': 'application/json' })
|
|
158
|
+
res.end(
|
|
159
|
+
JSON.stringify({
|
|
160
|
+
name: 'BRICKS Preview',
|
|
161
|
+
port: actualPort,
|
|
162
|
+
protocols: ['cdp'],
|
|
163
|
+
hasPasscode: false,
|
|
164
|
+
}),
|
|
165
|
+
)
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
res.writeHead(404)
|
|
169
|
+
res.end()
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
const wss = new WebSocketServer({ server: httpServer, path: '/ws' })
|
|
173
|
+
wss.on('connection', (ws) => {
|
|
174
|
+
clients.add(ws)
|
|
175
|
+
injectCdpRelay()
|
|
176
|
+
|
|
177
|
+
ws.on('message', (raw) => {
|
|
178
|
+
try {
|
|
179
|
+
const req = JSON.parse(raw.toString())
|
|
180
|
+
const cdpReq = JSON.stringify({
|
|
181
|
+
type: 'cdp-request',
|
|
182
|
+
id: req.id,
|
|
183
|
+
method: req.method,
|
|
184
|
+
params: req.params || {},
|
|
185
|
+
sessionId: req.sessionId,
|
|
186
|
+
})
|
|
187
|
+
mainWindow.webContents.executeJavaScript(`window.postMessage(${JSON.stringify(cdpReq)})`)
|
|
188
|
+
} catch {}
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
ws.on('close', () => clients.delete(ws))
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
httpServer.listen(actualPort, () => {
|
|
195
|
+
console.log(`CDP server: ws://localhost:${actualPort}/ws`)
|
|
196
|
+
console.log(
|
|
197
|
+
`Inspect: devtools://devtools/bundled/inspector.html?ws=localhost:${actualPort}/ws`,
|
|
198
|
+
)
|
|
199
|
+
})
|
|
200
|
+
}
|
|
201
|
+
|
|
69
202
|
app.on('ready', () => {
|
|
70
203
|
let show = true
|
|
71
204
|
if (takeScreenshotConfig && !takeScreenshotConfig.noHeadless) show = false
|
|
@@ -120,12 +253,16 @@ app.on('ready', () => {
|
|
|
120
253
|
})
|
|
121
254
|
`)
|
|
122
255
|
}
|
|
256
|
+
// Start CDP WebSocket server if requested
|
|
257
|
+
const cdpPort = values['cdp-port'] ? parseInt(values['cdp-port'], 10) : null
|
|
258
|
+
if (cdpPort) startCdpServer(mainWindow, cdpPort)
|
|
123
259
|
})
|
|
124
260
|
|
|
125
261
|
// Capture console messages from the preview
|
|
126
262
|
if (testId) {
|
|
127
|
-
mainWindow.webContents.on('console-message', (
|
|
128
|
-
|
|
263
|
+
mainWindow.webContents.on('console-message', (_event, ...rest) => {
|
|
264
|
+
const message = typeof rest[0] === 'object' ? rest[0].message : rest[1]
|
|
265
|
+
if (message?.startsWith('[TEST_RESULT]')) {
|
|
129
266
|
const data = JSON.parse(message.replace('[TEST_RESULT]', ''))
|
|
130
267
|
console.log(`[TEST_RESULT_TOON]${TOON.encode(data.result)}`)
|
|
131
268
|
if (!takeScreenshotConfig && noKeepOpen) app.quit()
|
package/tools/preview.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $ } from 'bun'
|
|
2
|
-
import { watch } from 'fs'
|
|
2
|
+
import { watch, unlinkSync } from 'fs'
|
|
3
3
|
import type { FSWatcher } from 'fs'
|
|
4
4
|
import { parseArgs } from 'util'
|
|
5
5
|
import debounce from 'lodash/debounce'
|
|
@@ -19,6 +19,8 @@ const { values } = parseArgs({
|
|
|
19
19
|
'test-id': { type: 'string' },
|
|
20
20
|
'test-title-like': { type: 'string' },
|
|
21
21
|
'no-keep-open': { type: 'boolean' },
|
|
22
|
+
'cdp-port': { type: 'string' },
|
|
23
|
+
'no-cdp': { type: 'boolean' },
|
|
22
24
|
},
|
|
23
25
|
strict: true,
|
|
24
26
|
allowPositionals: true,
|
|
@@ -62,11 +64,16 @@ if (values['no-keep-open']) {
|
|
|
62
64
|
args.push('--no-keep-open')
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
if (!values['no-cdp']) {
|
|
68
|
+
const cdpPort = parseInt(values['cdp-port'] || '', 10) || 19852
|
|
69
|
+
args.push('--cdp-port', String(cdpPort))
|
|
70
|
+
}
|
|
71
|
+
|
|
65
72
|
const useTypecheck = !values['skip-typecheck']
|
|
66
73
|
|
|
67
74
|
const compile = async () => {
|
|
68
75
|
if (useTypecheck) await $`bun typecheck`
|
|
69
|
-
await $`bun compile`
|
|
76
|
+
await $`bun compile.ts`
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
await compile()
|
|
@@ -80,6 +87,14 @@ if (needWatcher) {
|
|
|
80
87
|
})
|
|
81
88
|
}
|
|
82
89
|
|
|
90
|
+
const devtoolsInfoPath = `${cwd}/.bricks/devtools.json`
|
|
91
|
+
|
|
92
|
+
const cleanupDevtoolsInfo = () => {
|
|
93
|
+
try {
|
|
94
|
+
unlinkSync(devtoolsInfoPath)
|
|
95
|
+
} catch {}
|
|
96
|
+
}
|
|
97
|
+
|
|
83
98
|
const proc = Bun.spawn(['bunx', '--bun', 'electron', `${__dirname}/preview-main.mjs`, ...args], {
|
|
84
99
|
env: { ...process.env, BRICKS_STAGE: app.stage || 'production' },
|
|
85
100
|
stdout: 'pipe',
|
|
@@ -102,6 +117,18 @@ const processOutput = async () => {
|
|
|
102
117
|
const toonData = line.replace('[TEST_RESULT_TOON]', '')
|
|
103
118
|
console.log(toonData)
|
|
104
119
|
} else if (line) {
|
|
120
|
+
// Detect CDP server startup from preview-main output
|
|
121
|
+
const cdpMatch = line.match(/^CDP server: ws:\/\/localhost:(\d+)/)
|
|
122
|
+
if (cdpMatch) {
|
|
123
|
+
const info = {
|
|
124
|
+
port: parseInt(cdpMatch[1], 10),
|
|
125
|
+
pid: proc.pid,
|
|
126
|
+
address: 'localhost',
|
|
127
|
+
name: `${app.name || 'Unnamed'} (CTOR Preview)`,
|
|
128
|
+
startedAt: new Date().toISOString(),
|
|
129
|
+
}
|
|
130
|
+
Bun.write(devtoolsInfoPath, JSON.stringify(info, null, 2))
|
|
131
|
+
}
|
|
105
132
|
console.log(line)
|
|
106
133
|
}
|
|
107
134
|
})
|
|
@@ -112,4 +139,5 @@ const processOutput = async () => {
|
|
|
112
139
|
await processOutput()
|
|
113
140
|
await proc.exited
|
|
114
141
|
|
|
142
|
+
cleanupDevtoolsInfo()
|
|
115
143
|
if (watcher) watcher.close()
|
package/tools/pull.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { $ } from 'bun'
|
|
2
|
-
import { format } from '
|
|
2
|
+
import { format } from 'oxfmt'
|
|
3
3
|
|
|
4
4
|
const cwd = process.cwd()
|
|
5
|
+
const args = process.argv.slice(2)
|
|
6
|
+
const force = args.includes('--force') || args.includes('-f')
|
|
5
7
|
|
|
6
8
|
// Check git status
|
|
7
9
|
const { exitCode } = await $`cd ${cwd} && git status`.nothrow()
|
|
@@ -9,8 +11,15 @@ const isGitRepo = exitCode === 0
|
|
|
9
11
|
|
|
10
12
|
if (isGitRepo) {
|
|
11
13
|
const unstagedChanges = await $`cd ${cwd} && git diff --name-only --diff-filter=ACMR`.text()
|
|
12
|
-
if (unstagedChanges)
|
|
13
|
-
|
|
14
|
+
if (unstagedChanges) {
|
|
15
|
+
if (force) {
|
|
16
|
+
console.log('Force mode: committing unstaged changes before pull...')
|
|
17
|
+
await $`cd ${cwd} && git add .`
|
|
18
|
+
await $`cd ${cwd} && git commit -m ${'chore(force-pull): saved unstaged changes before pull'}`
|
|
19
|
+
} else {
|
|
20
|
+
throw new Error('Unstaged changes found, please commit or stash your changes before pulling')
|
|
21
|
+
}
|
|
22
|
+
}
|
|
14
23
|
} else {
|
|
15
24
|
const confirmContinue = prompt(
|
|
16
25
|
'No git repository found, so it will not be safe to pull, continue? (y/n)',
|
|
@@ -25,6 +34,7 @@ const isModule = app.type === 'module'
|
|
|
25
34
|
const command = isModule ? 'module' : 'app'
|
|
26
35
|
|
|
27
36
|
// Fetch project files using CLI
|
|
37
|
+
console.log(`Pulling ${command} project (${app.id})...`)
|
|
28
38
|
const result = await $`bricks ${command} project-pull ${app.id} --json`.quiet().nothrow()
|
|
29
39
|
|
|
30
40
|
if (result.exitCode !== 0) {
|
|
@@ -40,7 +50,8 @@ if (result.exitCode !== 0) {
|
|
|
40
50
|
const { files, lastCommitId } = JSON.parse(result.stdout.toString())
|
|
41
51
|
|
|
42
52
|
let useMain = false
|
|
43
|
-
if (isGitRepo) {
|
|
53
|
+
if (isGitRepo && !force) {
|
|
54
|
+
console.log(`Checking commit ${lastCommitId}...`)
|
|
44
55
|
const found = (await $`cd ${cwd} && git rev-list -1 ${lastCommitId}`.nothrow().text())
|
|
45
56
|
.trim()
|
|
46
57
|
.match(/^[\da-f]{40}$/)
|
|
@@ -63,7 +74,7 @@ if (isGitRepo) {
|
|
|
63
74
|
}
|
|
64
75
|
}
|
|
65
76
|
|
|
66
|
-
const
|
|
77
|
+
const oxfmtConfig = await Bun.file(`${cwd}/.oxfmtrc.json`)
|
|
67
78
|
.json()
|
|
68
79
|
.catch(() => ({
|
|
69
80
|
trailingComma: 'all',
|
|
@@ -74,25 +85,32 @@ const prettierConfig = await Bun.file(`${cwd}/.prettierrc`)
|
|
|
74
85
|
}))
|
|
75
86
|
|
|
76
87
|
await Promise.all(
|
|
77
|
-
files.map(async (file: { name: string; input: string; formatable?: boolean }) =>
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
file.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
)
|
|
84
|
-
),
|
|
88
|
+
files.map(async (file: { name: string; input: string; formatable?: boolean }) => {
|
|
89
|
+
let content = file.input
|
|
90
|
+
if (file.formatable) {
|
|
91
|
+
const result = await format(file.name, file.input, oxfmtConfig)
|
|
92
|
+
content = result.code
|
|
93
|
+
}
|
|
94
|
+
return Bun.write(`${cwd}/${file.name}`, content)
|
|
95
|
+
}),
|
|
85
96
|
)
|
|
86
97
|
|
|
87
98
|
if (isGitRepo) {
|
|
88
99
|
await $`cd ${cwd} && git add .`
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
100
|
+
const hasChanges = !!(await $`cd ${cwd} && git diff --cached --name-only`.text()).trim()
|
|
101
|
+
if (hasChanges) {
|
|
102
|
+
const commitMsg = force
|
|
103
|
+
? `chore(force-pull): apply force pull-${command}`
|
|
104
|
+
: isModule
|
|
105
|
+
? 'chore(project): apply file changes from BRICKS module'
|
|
106
|
+
: 'chore(project): apply file changes from BRICKS application'
|
|
107
|
+
await $`cd ${cwd} && git commit -m ${commitMsg}`
|
|
108
|
+
}
|
|
109
|
+
if (!force && !useMain) {
|
|
94
110
|
await $`cd ${cwd} && git merge main`
|
|
95
111
|
}
|
|
96
112
|
}
|
|
97
113
|
|
|
98
|
-
console.log(
|
|
114
|
+
console.log(
|
|
115
|
+
`${isModule ? 'Module' : 'App'} project pulled: ${files.length} files${force ? ' (force)' : ''}`,
|
|
116
|
+
)
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"lib": ["ESNext"],
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleDetection": "force",
|
|
7
|
+
"allowJs": true,
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"moduleResolution": "bundler",
|
|
10
|
+
"allowImportingTsExtensions": true,
|
|
11
|
+
"verbatimModuleSyntax": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
},
|
|
15
|
+
"exclude": ["node_modules"],
|
|
16
|
+
}
|
package/types/animation.ts
CHANGED
|
@@ -61,8 +61,10 @@ export interface AnimationDecayConfig {
|
|
|
61
61
|
export interface AnimationDef {
|
|
62
62
|
__typename: 'Animation'
|
|
63
63
|
id: string
|
|
64
|
+
alias?: string
|
|
64
65
|
title: string
|
|
65
66
|
description?: string
|
|
67
|
+
hideShortRef?: boolean
|
|
66
68
|
runType?: 'once' | 'loop'
|
|
67
69
|
property:
|
|
68
70
|
| 'transform.translateX'
|
|
@@ -80,8 +82,10 @@ export interface AnimationDef {
|
|
|
80
82
|
export interface AnimationComposeDef {
|
|
81
83
|
__typename: 'AnimationCompose'
|
|
82
84
|
id: string
|
|
85
|
+
alias?: string
|
|
83
86
|
title: string
|
|
84
87
|
description?: string
|
|
88
|
+
hideShortRef?: boolean
|
|
85
89
|
runType?: 'once' | 'loop'
|
|
86
90
|
composeType: 'parallel' | 'sequence'
|
|
87
91
|
items: Array<() => Animation>
|
package/types/automation.ts
CHANGED
|
@@ -45,7 +45,7 @@ export interface TestCaseJumpCondition {
|
|
|
45
45
|
operator?: JumpConditionOperator
|
|
46
46
|
value?: any
|
|
47
47
|
// The test case to jump to (getter function for dynamic IDs or string for static IDs)
|
|
48
|
-
jump_to
|
|
48
|
+
jump_to?: string | (() => TestCase)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/**
|
|
@@ -182,6 +182,7 @@ export interface TestCase {
|
|
|
182
182
|
__typename: 'TestCase'
|
|
183
183
|
id: string
|
|
184
184
|
name: string
|
|
185
|
+
hideShortRef?: boolean
|
|
185
186
|
run: TestMethodRun
|
|
186
187
|
exit_on_failed: boolean
|
|
187
188
|
commented: boolean
|
|
@@ -203,6 +204,7 @@ export interface AutomationTest {
|
|
|
203
204
|
__typename: 'AutomationTest'
|
|
204
205
|
id: string
|
|
205
206
|
title: string
|
|
207
|
+
hideShortRef?: boolean
|
|
206
208
|
timeout: number
|
|
207
209
|
trigger_type?: TestTriggerType
|
|
208
210
|
cron?: string // Cron expression when trigger_type is 'cron'
|
|
@@ -220,6 +222,7 @@ export interface AutomationTestMap {
|
|
|
220
222
|
__typename: 'AutomationTestMap'
|
|
221
223
|
id: string
|
|
222
224
|
title: string
|
|
225
|
+
hideShortRef?: boolean
|
|
223
226
|
createdAt: number
|
|
224
227
|
tests: AutomationTest[]
|
|
225
228
|
}
|
package/types/brick-base.ts
CHANGED
|
@@ -59,7 +59,7 @@ export interface BrickBasicProperty {
|
|
|
59
59
|
shadowOffsetWidth?: number | DataLink
|
|
60
60
|
/* The brick shadow offset height */
|
|
61
61
|
shadowOffsetHeight?: number | DataLink
|
|
62
|
-
/* Brick pressable.
|
|
62
|
+
/* Brick pressable.
|
|
63
63
|
Disabled: Disabled even if event or animation is set.
|
|
64
64
|
Bypass: Disable and bypass the touch event on the brick. */
|
|
65
65
|
pressable?: 'enabled' | 'disabled' | 'bypass' | DataLink
|
package/types/bricks/Camera.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/* Auto generated by build script
|
|
1
|
+
/* Auto generated by build script
|
|
2
|
+
*
|
|
3
|
+
* Camera view with photo capture and barcode scanning capabilities
|
|
4
|
+
*/
|
|
2
5
|
import type { SwitchCondInnerStateCurrentCanvas, SwitchCondData, SwitchDef } from '../switch'
|
|
3
6
|
import type { Data, DataLink } from '../data'
|
|
4
7
|
import type { Animation, AnimationBasicEvents } from '../animation'
|
|
@@ -12,6 +15,7 @@ import type {
|
|
|
12
15
|
EventProperty,
|
|
13
16
|
} from '../common'
|
|
14
17
|
import type { BrickBasicProperty, BrickBasicEvents, BrickBasicEventsForItem } from '../brick-base'
|
|
18
|
+
import type { TemplateEventPropsMap } from '../../utils/event-props'
|
|
15
19
|
|
|
16
20
|
/* Take picture on the Camera */
|
|
17
21
|
export type BrickCameraActionTakePicture = ActionWithParams & {
|
|
@@ -151,31 +155,62 @@ Default property:
|
|
|
151
155
|
}
|
|
152
156
|
events?: BrickBasicEvents & {
|
|
153
157
|
/* Event of the Camera state change */
|
|
154
|
-
stateChange?: Array<EventAction
|
|
158
|
+
stateChange?: Array<EventAction<string & keyof TemplateEventPropsMap['Camera']['stateChange']>>
|
|
155
159
|
/* Event of the Camera record start */
|
|
156
160
|
recordStart?: Array<EventAction>
|
|
157
161
|
/* Event of the Camera record end */
|
|
158
162
|
recordEnd?: Array<EventAction>
|
|
159
163
|
/* Event of the Camera barcode read */
|
|
160
|
-
barcodeRead?: Array<EventAction
|
|
164
|
+
barcodeRead?: Array<EventAction<string & keyof TemplateEventPropsMap['Camera']['barcodeRead']>>
|
|
161
165
|
/* Event of the Camera picture taken */
|
|
162
|
-
pictureTaken?: Array<
|
|
166
|
+
pictureTaken?: Array<
|
|
167
|
+
EventAction<string & keyof TemplateEventPropsMap['Camera']['pictureTaken']>
|
|
168
|
+
>
|
|
163
169
|
/* Event of the Camera record finished */
|
|
164
|
-
recordFinish?: Array<
|
|
170
|
+
recordFinish?: Array<
|
|
171
|
+
EventAction<string & keyof TemplateEventPropsMap['Camera']['recordFinish']>
|
|
172
|
+
>
|
|
165
173
|
/* Event of the Camera mount error */
|
|
166
|
-
mountError?: Array<EventAction
|
|
174
|
+
mountError?: Array<EventAction<string & keyof TemplateEventPropsMap['Camera']['mountError']>>
|
|
167
175
|
}
|
|
168
176
|
outlets?: {
|
|
169
177
|
/* Camera device and format information */
|
|
170
|
-
info?: () => Data
|
|
178
|
+
info?: () => Data<{ [key: string]: any }>
|
|
171
179
|
/* Picture taken result */
|
|
172
|
-
pictureTaken?: () => Data
|
|
180
|
+
pictureTaken?: () => Data<{
|
|
181
|
+
width?: number
|
|
182
|
+
height?: number
|
|
183
|
+
uri?: string
|
|
184
|
+
base64?: string
|
|
185
|
+
[key: string]: any
|
|
186
|
+
}>
|
|
173
187
|
/* Record video result */
|
|
174
|
-
recordVideo?: () => Data
|
|
188
|
+
recordVideo?: () => Data<{
|
|
189
|
+
uri?: string
|
|
190
|
+
[key: string]: any
|
|
191
|
+
}>
|
|
175
192
|
/* Barcode read result */
|
|
176
|
-
barcodeRead?: () => Data
|
|
193
|
+
barcodeRead?: () => Data<{
|
|
194
|
+
type?: string
|
|
195
|
+
data?: string
|
|
196
|
+
rawData?: string
|
|
197
|
+
bounds?: {
|
|
198
|
+
origin?: {
|
|
199
|
+
x?: number
|
|
200
|
+
y?: number
|
|
201
|
+
[key: string]: any
|
|
202
|
+
}
|
|
203
|
+
size?: {
|
|
204
|
+
width?: number
|
|
205
|
+
height?: number
|
|
206
|
+
[key: string]: any
|
|
207
|
+
}
|
|
208
|
+
[key: string]: any
|
|
209
|
+
}
|
|
210
|
+
[key: string]: any
|
|
211
|
+
}>
|
|
177
212
|
/* Faces detected result */
|
|
178
|
-
faceDetected?: () => Data
|
|
213
|
+
faceDetected?: () => Data<Array<{ [key: string]: any }>>
|
|
179
214
|
}
|
|
180
215
|
animation?: AnimationBasicEvents & {
|
|
181
216
|
stateChange?: Animation
|
|
@@ -188,11 +223,11 @@ Default property:
|
|
|
188
223
|
}
|
|
189
224
|
}
|
|
190
225
|
|
|
191
|
-
/* Camera view
|
|
226
|
+
/* Camera view with photo capture and barcode scanning capabilities */
|
|
192
227
|
export type BrickCamera = Brick &
|
|
193
228
|
BrickCameraDef & {
|
|
194
229
|
templateKey: 'BRICK_CAMERA'
|
|
195
|
-
switches
|
|
230
|
+
switches?: Array<
|
|
196
231
|
SwitchDef &
|
|
197
232
|
BrickCameraDef & {
|
|
198
233
|
conds?: Array<{
|
package/types/bricks/Chart.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/* Auto generated by build script
|
|
1
|
+
/* Auto generated by build script
|
|
2
|
+
*
|
|
3
|
+
* Chart brick, based on [Apache ECharts](https://echarts.apache.org/en/index.html).
|
|
4
|
+
*/
|
|
2
5
|
import type { SwitchCondInnerStateCurrentCanvas, SwitchCondData, SwitchDef } from '../switch'
|
|
3
6
|
import type { Data, DataLink } from '../data'
|
|
4
7
|
import type { Animation, AnimationBasicEvents } from '../animation'
|
|
@@ -12,6 +15,7 @@ import type {
|
|
|
12
15
|
EventProperty,
|
|
13
16
|
} from '../common'
|
|
14
17
|
import type { BrickBasicProperty, BrickBasicEvents, BrickBasicEventsForItem } from '../brick-base'
|
|
18
|
+
import type { TemplateEventPropsMap } from '../../utils/event-props'
|
|
15
19
|
|
|
16
20
|
/* Data highlight */
|
|
17
21
|
export type BrickChartActionDataHighlight = ActionWithParams & {
|
|
@@ -332,9 +336,11 @@ Default property:
|
|
|
332
336
|
/* Event of chart render */
|
|
333
337
|
onRender?: Array<EventAction>
|
|
334
338
|
/* Event of data point on press */
|
|
335
|
-
onPress?: Array<EventAction
|
|
339
|
+
onPress?: Array<EventAction<string & keyof TemplateEventPropsMap['Chart']['onPress']>>
|
|
336
340
|
/* Event of legend select changed */
|
|
337
|
-
onLegendSelectChanged?: Array<
|
|
341
|
+
onLegendSelectChanged?: Array<
|
|
342
|
+
EventAction<string & keyof TemplateEventPropsMap['Chart']['onLegendSelectChanged']>
|
|
343
|
+
>
|
|
338
344
|
}
|
|
339
345
|
animation?: AnimationBasicEvents & {
|
|
340
346
|
onRender?: Animation
|
|
@@ -347,7 +353,7 @@ Default property:
|
|
|
347
353
|
export type BrickChart = Brick &
|
|
348
354
|
BrickChartDef & {
|
|
349
355
|
templateKey: 'BRICK_CHART'
|
|
350
|
-
switches
|
|
356
|
+
switches?: Array<
|
|
351
357
|
SwitchDef &
|
|
352
358
|
BrickChartDef & {
|
|
353
359
|
conds?: Array<{
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/* Auto generated by build script
|
|
1
|
+
/* Auto generated by build script
|
|
2
|
+
*
|
|
3
|
+
* Generative Media brick - Generate images and videos using AI
|
|
4
|
+
*/
|
|
2
5
|
import type { SwitchCondInnerStateCurrentCanvas, SwitchCondData, SwitchDef } from '../switch'
|
|
3
6
|
import type { Data, DataLink } from '../data'
|
|
4
7
|
import type { Animation, AnimationBasicEvents } from '../animation'
|
|
@@ -12,6 +15,7 @@ import type {
|
|
|
12
15
|
EventProperty,
|
|
13
16
|
} from '../common'
|
|
14
17
|
import type { BrickBasicProperty, BrickBasicEvents, BrickBasicEventsForItem } from '../brick-base'
|
|
18
|
+
import type { TemplateEventPropsMap } from '../../utils/event-props'
|
|
15
19
|
|
|
16
20
|
interface GenerativeMediaDef {
|
|
17
21
|
/*
|
|
@@ -191,33 +195,45 @@ Default property:
|
|
|
191
195
|
/* Event of the brick blur (Use TV Device with controller) */
|
|
192
196
|
generativeMediaOnBlur?: Array<EventAction>
|
|
193
197
|
/* Event when media generation succeeds */
|
|
194
|
-
onSuccess?: Array<
|
|
198
|
+
onSuccess?: Array<
|
|
199
|
+
EventAction<string & keyof TemplateEventPropsMap['GenerativeMedia']['onSuccess']>
|
|
200
|
+
>
|
|
195
201
|
/* Event when media generation fails */
|
|
196
|
-
onError?: Array<EventAction
|
|
202
|
+
onError?: Array<EventAction<string & keyof TemplateEventPropsMap['GenerativeMedia']['onError']>>
|
|
197
203
|
/* Event when media prompt request starts */
|
|
198
|
-
promptStart?: Array<
|
|
204
|
+
promptStart?: Array<
|
|
205
|
+
EventAction<string & keyof TemplateEventPropsMap['GenerativeMedia']['promptStart']>
|
|
206
|
+
>
|
|
199
207
|
/* Event when media prompt request succeeds */
|
|
200
|
-
promptSuccess?: Array<
|
|
208
|
+
promptSuccess?: Array<
|
|
209
|
+
EventAction<string & keyof TemplateEventPropsMap['GenerativeMedia']['promptSuccess']>
|
|
210
|
+
>
|
|
201
211
|
/* Event when media prompt request fails */
|
|
202
|
-
promptError?: Array<
|
|
212
|
+
promptError?: Array<
|
|
213
|
+
EventAction<string & keyof TemplateEventPropsMap['GenerativeMedia']['promptError']>
|
|
214
|
+
>
|
|
203
215
|
/* Event when media loading starts */
|
|
204
216
|
loadStart?: Array<EventAction>
|
|
205
217
|
/* Event when media loading succeeds */
|
|
206
|
-
loadSuccess?: Array<
|
|
218
|
+
loadSuccess?: Array<
|
|
219
|
+
EventAction<string & keyof TemplateEventPropsMap['GenerativeMedia']['loadSuccess']>
|
|
220
|
+
>
|
|
207
221
|
/* Event when media loading fails */
|
|
208
|
-
loadError?: Array<
|
|
222
|
+
loadError?: Array<
|
|
223
|
+
EventAction<string & keyof TemplateEventPropsMap['GenerativeMedia']['loadError']>
|
|
224
|
+
>
|
|
209
225
|
}
|
|
210
226
|
outlets?: {
|
|
211
227
|
/* Brick is pressing */
|
|
212
|
-
brickPressing?: () => Data
|
|
228
|
+
brickPressing?: () => Data<boolean>
|
|
213
229
|
/* Brick is focusing (Use TV Device with controller) */
|
|
214
|
-
brickFocusing?: () => Data
|
|
230
|
+
brickFocusing?: () => Data<boolean>
|
|
215
231
|
/* Generated media URL */
|
|
216
|
-
url?: () => Data
|
|
232
|
+
url?: () => Data<string>
|
|
217
233
|
/* Generated media error */
|
|
218
|
-
error?: () => Data
|
|
234
|
+
error?: () => Data<string>
|
|
219
235
|
/* Loading state */
|
|
220
|
-
loading?: () => Data
|
|
236
|
+
loading?: () => Data<boolean>
|
|
221
237
|
}
|
|
222
238
|
animation?: AnimationBasicEvents & {
|
|
223
239
|
generativeMediaOnPress?: Animation
|
|
@@ -241,7 +257,7 @@ Default property:
|
|
|
241
257
|
export type GenerativeMedia = Brick &
|
|
242
258
|
GenerativeMediaDef & {
|
|
243
259
|
templateKey: 'BRICK_GENERATIVE_MEDIA'
|
|
244
|
-
switches
|
|
260
|
+
switches?: Array<
|
|
245
261
|
SwitchDef &
|
|
246
262
|
GenerativeMediaDef & {
|
|
247
263
|
conds?: Array<{
|