@fugood/bricks-project 2.23.0-beta.25 → 2.23.0-beta.27
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 +10 -0
- package/compile/index.ts +52 -60
- package/package.json +4 -4
- package/tools/mcp-server.ts +3 -3
- package/tools/postinstall.ts +2 -5
- package/tools/preview.ts +1 -1
- package/tools/pull.ts +1 -1
- package/types/bricks/GenerativeMedia.ts +14 -1
- package/types/generators/Intent.ts +49 -0
- package/utils/id.ts +3 -1
|
@@ -486,6 +486,16 @@ export const templateActionNameMap = {
|
|
|
486
486
|
packageName: 'GENERATOR_INTENT_PACKAGE_NAME',
|
|
487
487
|
category: 'GENERATOR_INTENT_CATEGORY',
|
|
488
488
|
},
|
|
489
|
+
GENERATOR_INTENT_START_SERVICE: {
|
|
490
|
+
action: 'GENERATOR_INTENT_ACTION',
|
|
491
|
+
data: 'GENERATOR_INTENT_DATA',
|
|
492
|
+
type: 'GENERATOR_INTENT_TYPE',
|
|
493
|
+
extra: 'GENERATOR_INTENT_EXTRA',
|
|
494
|
+
className: 'GENERATOR_INTENT_CLASS_NAME',
|
|
495
|
+
packageName: 'GENERATOR_INTENT_PACKAGE_NAME',
|
|
496
|
+
category: 'GENERATOR_INTENT_CATEGORY',
|
|
497
|
+
foreground: 'GENERATOR_INTENT_FOREGROUND',
|
|
498
|
+
},
|
|
489
499
|
},
|
|
490
500
|
GENERATOR_CASTLES_PAY: {
|
|
491
501
|
GENERATOR_CASTLES_PAY_SALE: {
|
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,8 @@ import type {
|
|
|
24
24
|
DataCalculationData,
|
|
25
25
|
DataCommand,
|
|
26
26
|
Brick,
|
|
27
|
-
Generator,
|
|
28
27
|
Canvas,
|
|
29
28
|
Subspace,
|
|
30
|
-
EventActionForItem,
|
|
31
29
|
} from '../types'
|
|
32
30
|
|
|
33
31
|
const compileProperty = (property, errorReference: string, result = {}) => {
|
|
@@ -66,25 +64,22 @@ const compileEventActionValue = (templateKey, eventKey, value, errorReference) =
|
|
|
66
64
|
return compileProperty(value, errorReference)
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
const convertOutletKey = (templateKey: string, key: string) =>
|
|
70
|
-
|
|
71
|
-
}
|
|
67
|
+
const convertOutletKey = (templateKey: string, key: string) =>
|
|
68
|
+
`${templateKey}_${_.snakeCase(key).toUpperCase()}`
|
|
72
69
|
|
|
73
70
|
const compileOutlets = (
|
|
74
71
|
templateKey: string,
|
|
75
72
|
outlets: { [key: string]: () => Data },
|
|
76
73
|
errorReference: string,
|
|
77
|
-
) =>
|
|
78
|
-
|
|
74
|
+
) =>
|
|
75
|
+
Object.entries(outlets).reduce((acc, [key, data]) => {
|
|
79
76
|
if (!data()?.id) throw new Error(`Invalid data reference ${errorReference}`)
|
|
80
77
|
acc[convertOutletKey(templateKey, key)] = data().id
|
|
81
78
|
return acc
|
|
82
79
|
}, {})
|
|
83
|
-
}
|
|
84
80
|
|
|
85
|
-
const convertEventKey = (templateKey: string, key: string) =>
|
|
86
|
-
|
|
87
|
-
}
|
|
81
|
+
const convertEventKey = (templateKey: string, key: string) =>
|
|
82
|
+
`${templateKey ? `${templateKey}_` : ''}${_.snakeCase(key).toUpperCase()}`
|
|
88
83
|
|
|
89
84
|
const basicAnimationEvents = ['show', 'standby', 'breatheStart']
|
|
90
85
|
|
|
@@ -92,14 +87,13 @@ const compileAnimations = (
|
|
|
92
87
|
templateKey: string,
|
|
93
88
|
animations: { [key: string]: Animation },
|
|
94
89
|
errorReference: string,
|
|
95
|
-
) =>
|
|
96
|
-
|
|
90
|
+
) =>
|
|
91
|
+
Object.entries(animations).reduce((acc, [key, animation]) => {
|
|
97
92
|
if (!animation?.id) throw new Error(`Invalid animation reference ${errorReference}`)
|
|
98
93
|
acc[convertEventKey(basicAnimationEvents.includes(key) ? 'BRICK' : templateKey, key)] =
|
|
99
94
|
`ANIMATION#${animation.id}`
|
|
100
95
|
return acc
|
|
101
96
|
}, {})
|
|
102
|
-
}
|
|
103
97
|
|
|
104
98
|
const compileActionParam = (templateKey: string, actionName: string, paramName: string) =>
|
|
105
99
|
templateActionNameMap[templateKey]?.[actionName]?.[paramName] || paramName
|
|
@@ -190,7 +184,7 @@ const compileSwitchConds = (templateKey, conds, errorReference) =>
|
|
|
190
184
|
result.key = cond.data().id
|
|
191
185
|
result.value = cond.value
|
|
192
186
|
} else if (item.cond.__typename === 'SwitchCondInnerStateOutlet') {
|
|
193
|
-
const cond = item
|
|
187
|
+
const { cond } = item
|
|
194
188
|
result.type = 'inner_state'
|
|
195
189
|
result.key = convertOutletKey(templateKey, cond.outlet)
|
|
196
190
|
result.value = cond.value
|
|
@@ -205,35 +199,33 @@ const compileSwitchConds = (templateKey, conds, errorReference) =>
|
|
|
205
199
|
return result
|
|
206
200
|
})
|
|
207
201
|
|
|
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
|
-
}
|
|
202
|
+
const compileApplicationSettings = (settings: Application['settings']) => ({
|
|
203
|
+
internet_reachability_url: settings?.internetReachabilityUrl,
|
|
204
|
+
enable_data_lock: settings?.enableDataLock,
|
|
205
|
+
show_deprecated_features: settings?.showDeprecatedFeatures,
|
|
206
|
+
enable_unstable_bricks: settings?.enableUnstableFeatures,
|
|
207
|
+
runtime_cache_options: settings?.runtimeCacheOptions
|
|
208
|
+
? {
|
|
209
|
+
disabled: settings.runtimeCacheOptions.disabled,
|
|
210
|
+
behavior: settings.runtimeCacheOptions.behavior,
|
|
211
|
+
retry_attempt_for_failure: settings.runtimeCacheOptions.retryAttemptForFailure,
|
|
212
|
+
}
|
|
213
|
+
: undefined,
|
|
214
|
+
tv_options: settings?.tvOptions
|
|
215
|
+
? {
|
|
216
|
+
disabled_selectable: settings.tvOptions.disabledSelectable,
|
|
217
|
+
selectable_color: settings.tvOptions.selectableColor,
|
|
218
|
+
selectable_border: settings.tvOptions.selectableBorder,
|
|
219
|
+
}
|
|
220
|
+
: undefined,
|
|
221
|
+
ai: settings?.ai
|
|
222
|
+
? {
|
|
223
|
+
use_anthropic_api_key_system_data: settings.ai.useAnthropicApiKeySystemData,
|
|
224
|
+
use_openai_api_key_system_data: settings.ai.useOpenAiApiKeySystemData,
|
|
225
|
+
use_gemini_api_key_system_data: settings.ai.useGeminiApiKeySystemData,
|
|
226
|
+
}
|
|
227
|
+
: undefined,
|
|
228
|
+
})
|
|
237
229
|
|
|
238
230
|
const animationTypeMap = {
|
|
239
231
|
AnimationTimingConfig: 'timing',
|
|
@@ -338,7 +330,7 @@ export const compile = async (app: Application) => {
|
|
|
338
330
|
brick: !subspace.unexpanded.brick,
|
|
339
331
|
generator: !subspace.unexpanded.generator,
|
|
340
332
|
canvas: subspace.unexpanded.canvas?.reduce((acc, canvas) => {
|
|
341
|
-
acc[canvas.id] = canvas?.id
|
|
333
|
+
acc[canvas.id] = !canvas?.id
|
|
342
334
|
return acc
|
|
343
335
|
}, {}),
|
|
344
336
|
property_bank: !subspace.unexpanded.data,
|
|
@@ -377,12 +369,12 @@ export const compile = async (app: Application) => {
|
|
|
377
369
|
animationRunType: animationDef.runType,
|
|
378
370
|
compose_type: animationDef.composeType,
|
|
379
371
|
item_list: animationDef.items.map((item, index) => {
|
|
380
|
-
const
|
|
381
|
-
if (!
|
|
372
|
+
const innerAnimation = item()
|
|
373
|
+
if (!innerAnimation?.id)
|
|
382
374
|
throw new Error(
|
|
383
|
-
`Invalid animation index: ${index} (animation: ${
|
|
375
|
+
`Invalid animation index: ${index} (animation: ${innerAnimation.id}, subspace ${subspace.id})`,
|
|
384
376
|
)
|
|
385
|
-
return { animation_id:
|
|
377
|
+
return { animation_id: innerAnimation.id }
|
|
386
378
|
}),
|
|
387
379
|
}
|
|
388
380
|
}
|
|
@@ -461,7 +453,7 @@ export const compile = async (app: Application) => {
|
|
|
461
453
|
property.brickList = brickList
|
|
462
454
|
} else {
|
|
463
455
|
// Not supported Data for brickList
|
|
464
|
-
throw new
|
|
456
|
+
throw new TypeError('Not supported Data for brickList directly')
|
|
465
457
|
}
|
|
466
458
|
if (Array.isArray(brickItems.brickDetails)) {
|
|
467
459
|
const brickDetails = (brickItems.brickDetails || []).map((item, index) =>
|
|
@@ -470,7 +462,7 @@ export const compile = async (app: Application) => {
|
|
|
470
462
|
property.brickDetails = brickDetails
|
|
471
463
|
} else {
|
|
472
464
|
// Not supported Data for brickList
|
|
473
|
-
throw new
|
|
465
|
+
throw new TypeError('Not supported Data for brickList directly')
|
|
474
466
|
}
|
|
475
467
|
}
|
|
476
468
|
map[brick.id] = {
|
|
@@ -694,7 +686,7 @@ export const compile = async (app: Application) => {
|
|
|
694
686
|
if (!acc[port.key]) acc[port.key] = null
|
|
695
687
|
|
|
696
688
|
let sourceId
|
|
697
|
-
|
|
689
|
+
const sourceNode = port.source()
|
|
698
690
|
if (sourceNode?.__typename === 'DataCalculationData')
|
|
699
691
|
sourceId = (sourceNode as DataCalculationData).data().id
|
|
700
692
|
if (sourceNode?.__typename === 'DataCommand') sourceId = sourceNode.id
|
|
@@ -715,7 +707,7 @@ export const compile = async (app: Application) => {
|
|
|
715
707
|
if (!acc[port.key]) acc[port.key] = null
|
|
716
708
|
|
|
717
709
|
let targetId
|
|
718
|
-
|
|
710
|
+
const targetNode = port.target()
|
|
719
711
|
if (targetNode?.__typename === 'DataCalculationData')
|
|
720
712
|
targetId = (targetNode as DataCalculationData).data().id
|
|
721
713
|
if (targetNode?.__typename === 'DataCommand') targetId = targetNode.id
|
|
@@ -770,9 +762,9 @@ export const compile = async (app: Application) => {
|
|
|
770
762
|
type: `command-node-${type}`,
|
|
771
763
|
properties: {
|
|
772
764
|
command: commandNode.__commandName,
|
|
773
|
-
args: args.reduce((
|
|
774
|
-
|
|
775
|
-
return
|
|
765
|
+
args: args.reduce((argsAcc, input) => {
|
|
766
|
+
argsAcc[input.key] = input.source
|
|
767
|
+
return argsAcc
|
|
776
768
|
}, {}),
|
|
777
769
|
},
|
|
778
770
|
in: generateInputPorts(inputs),
|
|
@@ -784,12 +776,12 @@ export const compile = async (app: Application) => {
|
|
|
784
776
|
calc.editor_info = mapCalc.editorInfo.reduce((acc, editorInfo) => {
|
|
785
777
|
acc[getNodeId(editorInfo.node)] = {
|
|
786
778
|
position: editorInfo.position,
|
|
787
|
-
points: editorInfo.points.reduce((
|
|
779
|
+
points: editorInfo.points.reduce((pointsAcc, point) => {
|
|
788
780
|
const sourceId = getNodeId(point.source)
|
|
789
781
|
const targetId = getNodeId(point.target)
|
|
790
782
|
const key = `${sourceId}-${point.sourceOutputKey}-${targetId}-${point.targetInputKey}`
|
|
791
|
-
|
|
792
|
-
return
|
|
783
|
+
pointsAcc[key] = point.positions
|
|
784
|
+
return pointsAcc
|
|
793
785
|
}, {}),
|
|
794
786
|
}
|
|
795
787
|
return acc
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fugood/bricks-project",
|
|
3
|
-
"version": "2.23.0-beta.
|
|
3
|
+
"version": "2.23.0-beta.27",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"build": "
|
|
6
|
+
"build": "bun scripts/build.js"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@modelcontextprotocol/sdk": "^1.15.0",
|
|
10
10
|
"@types/escodegen": "^0.0.10",
|
|
11
11
|
"@types/lodash": "^4.17.12",
|
|
12
12
|
"acorn": "^8.13.0",
|
|
13
|
-
"escodegen": "
|
|
13
|
+
"escodegen": "2.1.0",
|
|
14
14
|
"lodash": "^4.17.4",
|
|
15
15
|
"uuid": "^8.3.1"
|
|
16
16
|
},
|
|
17
|
-
"gitHead": "
|
|
17
|
+
"gitHead": "40d4c0f3e77bbb2985ad1aa695103558bd1d5648"
|
|
18
18
|
}
|
package/tools/mcp-server.ts
CHANGED
|
@@ -8,7 +8,7 @@ const server = new McpServer({
|
|
|
8
8
|
version: '1.0.0',
|
|
9
9
|
})
|
|
10
10
|
|
|
11
|
-
const dirname = import.meta
|
|
11
|
+
const { dirname } = import.meta
|
|
12
12
|
const projectDir = String(dirname).split('/node_modules/')[0]
|
|
13
13
|
|
|
14
14
|
server.tool('compile', {}, async () => {
|
|
@@ -16,7 +16,7 @@ server.tool('compile', {}, async () => {
|
|
|
16
16
|
try {
|
|
17
17
|
log = await $`bun compile`.cwd(projectDir).text()
|
|
18
18
|
} catch (err) {
|
|
19
|
-
log = err.stdout.toString()
|
|
19
|
+
log = `${err.stdout.toString()}\n${err.stderr.toString()}`
|
|
20
20
|
}
|
|
21
21
|
return {
|
|
22
22
|
content: [{ type: 'text', text: log || 'Compiled successfully' }],
|
|
@@ -61,7 +61,7 @@ server.tool(
|
|
|
61
61
|
]
|
|
62
62
|
log = await $`bunx --bun electron ${dirname}/preview-main.mjs ${args}`.cwd(projectDir).text()
|
|
63
63
|
} catch (err) {
|
|
64
|
-
log = err.stdout.toString()
|
|
64
|
+
log = `${err.stdout.toString()}\n${err.stderr.toString()}`
|
|
65
65
|
error = true
|
|
66
66
|
}
|
|
67
67
|
let screenshotBase64: any = null
|
package/tools/postinstall.ts
CHANGED
|
@@ -17,13 +17,10 @@ const skipCopyProject = process.argv.includes('--skip-copy-project')
|
|
|
17
17
|
if (skipCopyProject) {
|
|
18
18
|
console.log('Skipping copy of files to project/')
|
|
19
19
|
} else {
|
|
20
|
-
|
|
21
20
|
const libFiles = ['types', 'utils', 'index.ts']
|
|
22
|
-
|
|
21
|
+
|
|
23
22
|
await $`mkdir -p ${cwd}/project`
|
|
24
|
-
|
|
25
|
-
await $`cp -r ${__dirname}/../${file} ${cwd}/project`
|
|
26
|
-
}
|
|
23
|
+
await Promise.all(libFiles.map((file) => $`cp -r ${__dirname}/../${file} ${cwd}/project`))
|
|
27
24
|
console.log('Copied files to project/')
|
|
28
25
|
}
|
|
29
26
|
|
package/tools/preview.ts
CHANGED
package/tools/pull.ts
CHANGED
|
@@ -24,7 +24,7 @@ let useMain = false
|
|
|
24
24
|
if (isGitRepo) {
|
|
25
25
|
const found = (await $`cd ${cwd} && git rev-list -1 ${lastCommitId}`.nothrow().text())
|
|
26
26
|
.trim()
|
|
27
|
-
.match(/^[
|
|
27
|
+
.match(/^[\da-f]{40}$/)
|
|
28
28
|
|
|
29
29
|
const commitId = (await $`cd ${cwd} && git rev-parse HEAD`.text()).trim()
|
|
30
30
|
|
|
@@ -21,7 +21,10 @@ Default property:
|
|
|
21
21
|
"type": "image",
|
|
22
22
|
"resizeMode": "cover",
|
|
23
23
|
"provider": "openai",
|
|
24
|
-
"freepikClassicImageSize": "square_1_1"
|
|
24
|
+
"freepikClassicImageSize": "square_1_1",
|
|
25
|
+
"geminiVeoModel": "veo-3.1-generate-preview",
|
|
26
|
+
"geminiVeoResolution": "720p",
|
|
27
|
+
"geminiVeoDuration": 8
|
|
25
28
|
}
|
|
26
29
|
*/
|
|
27
30
|
property?: BrickBasicProperty & {
|
|
@@ -163,6 +166,16 @@ Default property:
|
|
|
163
166
|
geminiAspectRatio?: '1:1' | '16:9' | '9:16' | '3:2' | '2:3' | DataLink
|
|
164
167
|
/* Gemini model to use for image generation */
|
|
165
168
|
geminiModel?: 'gemini-2.5-flash-image' | 'gemini-3-pro-image-preview' | DataLink
|
|
169
|
+
/* Gemini Veo model to use for video generation */
|
|
170
|
+
geminiVeoModel?: 'veo-3.1-generate-preview' | 'veo-3.1-fast-generate-preview' | DataLink
|
|
171
|
+
/* Gemini Veo video resolution (720p or 1080p) */
|
|
172
|
+
geminiVeoResolution?: '720p' | '1080p' | DataLink
|
|
173
|
+
/* Gemini Veo video duration in seconds (4, 6, 8) */
|
|
174
|
+
geminiVeoDuration?: 4 | 6 | 8 | DataLink
|
|
175
|
+
/* Gemini Veo negative prompt (attributes to avoid) */
|
|
176
|
+
geminiVeoNegativePrompt?: string | DataLink
|
|
177
|
+
/* Gemini Veo person generation control */
|
|
178
|
+
geminiVeoPersonGeneration?: 'allow_all' | 'allow_adult' | DataLink
|
|
166
179
|
}
|
|
167
180
|
events?: BrickBasicEvents & {
|
|
168
181
|
/* Event of the brick press */
|
|
@@ -52,6 +52,53 @@ export type GeneratorIntentActionSendIntent = ActionWithParams & {
|
|
|
52
52
|
>
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/* Start intent service */
|
|
56
|
+
export type GeneratorIntentActionStartService = ActionWithParams & {
|
|
57
|
+
__actionName: 'GENERATOR_INTENT_START_SERVICE'
|
|
58
|
+
params?: Array<
|
|
59
|
+
| {
|
|
60
|
+
input: 'action'
|
|
61
|
+
value?: string | DataLink | EventProperty
|
|
62
|
+
mapping?: string
|
|
63
|
+
}
|
|
64
|
+
| {
|
|
65
|
+
input: 'data'
|
|
66
|
+
value?: string | DataLink | EventProperty
|
|
67
|
+
mapping?: string
|
|
68
|
+
}
|
|
69
|
+
| {
|
|
70
|
+
input: 'type'
|
|
71
|
+
value?: string | DataLink | EventProperty
|
|
72
|
+
mapping?: string
|
|
73
|
+
}
|
|
74
|
+
| {
|
|
75
|
+
input: 'extra'
|
|
76
|
+
value?: {} | DataLink | EventProperty
|
|
77
|
+
mapping?: string
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
input: 'className'
|
|
81
|
+
value?: string | DataLink | EventProperty
|
|
82
|
+
mapping?: string
|
|
83
|
+
}
|
|
84
|
+
| {
|
|
85
|
+
input: 'packageName'
|
|
86
|
+
value?: string | DataLink | EventProperty
|
|
87
|
+
mapping?: string
|
|
88
|
+
}
|
|
89
|
+
| {
|
|
90
|
+
input: 'category'
|
|
91
|
+
value?: string | DataLink | EventProperty
|
|
92
|
+
mapping?: string
|
|
93
|
+
}
|
|
94
|
+
| {
|
|
95
|
+
input: 'foreground'
|
|
96
|
+
value?: boolean | DataLink | EventProperty
|
|
97
|
+
mapping?: string
|
|
98
|
+
}
|
|
99
|
+
>
|
|
100
|
+
}
|
|
101
|
+
|
|
55
102
|
interface GeneratorIntentDef {
|
|
56
103
|
/*
|
|
57
104
|
Default property:
|
|
@@ -72,6 +119,8 @@ Default property:
|
|
|
72
119
|
packageName?: string | DataLink
|
|
73
120
|
/* Intent category */
|
|
74
121
|
category?: string | DataLink
|
|
122
|
+
/* Intent start foreground service */
|
|
123
|
+
foregroundService?: boolean | DataLink
|
|
75
124
|
}
|
|
76
125
|
events?: {
|
|
77
126
|
/* On intent return a result trigger */
|
package/utils/id.ts
CHANGED
|
@@ -4,7 +4,9 @@ let count = 0
|
|
|
4
4
|
|
|
5
5
|
// Used for snapshot mode
|
|
6
6
|
const countUUID = () => {
|
|
7
|
-
|
|
7
|
+
const current = count
|
|
8
|
+
count += 1
|
|
9
|
+
return `00000000-0000-0000-0000-${current.toString().padStart(12, '0')}`
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
// Make a random id if not want to use fixed id
|