@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.
@@ -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
- return `${templateKey}_${_.snakeCase(key).toUpperCase()}`
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
- return Object.entries(outlets).reduce((acc, [key, data]) => {
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
- return `${templateKey ? `${templateKey}_` : ''}${_.snakeCase(key).toUpperCase()}`
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
- return Object.entries(animations).reduce((acc, [key, animation]) => {
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.cond
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
- return {
210
- internet_reachability_url: settings?.internetReachabilityUrl,
211
- enable_data_lock: settings?.enableDataLock,
212
- show_deprecated_features: settings?.showDeprecatedFeatures,
213
- enable_unstable_bricks: settings?.enableUnstableFeatures,
214
- runtime_cache_options: settings?.runtimeCacheOptions
215
- ? {
216
- disabled: settings.runtimeCacheOptions.disabled,
217
- behavior: settings.runtimeCacheOptions.behavior,
218
- retry_attempt_for_failure: settings.runtimeCacheOptions.retryAttemptForFailure,
219
- }
220
- : undefined,
221
- tv_options: settings?.tvOptions
222
- ? {
223
- disabled_selectable: settings.tvOptions.disabledSelectable,
224
- selectable_color: settings.tvOptions.selectableColor,
225
- selectable_border: settings.tvOptions.selectableBorder,
226
- }
227
- : undefined,
228
- ai: settings?.ai
229
- ? {
230
- use_anthropic_api_key_system_data: settings.ai.useAnthropicApiKeySystemData,
231
- use_openai_api_key_system_data: settings.ai.useOpenAiApiKeySystemData,
232
- use_gemini_api_key_system_data: settings.ai.useGeminiApiKeySystemData,
233
- }
234
- : undefined,
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 ? false : true
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 animation = item()
381
- if (!animation?.id)
372
+ const innerAnimation = item()
373
+ if (!innerAnimation?.id)
382
374
  throw new Error(
383
- `Invalid animation index: ${index} (animation: ${animation.id}, subspace ${subspace.id})`,
375
+ `Invalid animation index: ${index} (animation: ${innerAnimation.id}, subspace ${subspace.id})`,
384
376
  )
385
- return { animation_id: 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 Error('Not supported Data for brickList directly')
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 Error('Not supported Data for brickList directly')
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
- let sourceNode = port.source()
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
- let targetNode = port.target()
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((acc, input) => {
774
- acc[input.key] = input.source
775
- return acc
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((acc, point) => {
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
- acc[key] = point.positions
792
- return acc
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.25",
3
+ "version": "2.23.0-beta.27",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
- "build": "node scripts/build.js"
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": "^2.1.0",
13
+ "escodegen": "2.1.0",
14
14
  "lodash": "^4.17.4",
15
15
  "uuid": "^8.3.1"
16
16
  },
17
- "gitHead": "89d05d356e4deae1c06afd6db781e2b83c547991"
17
+ "gitHead": "40d4c0f3e77bbb2985ad1aa695103558bd1d5648"
18
18
  }
@@ -8,7 +8,7 @@ const server = new McpServer({
8
8
  version: '1.0.0',
9
9
  })
10
10
 
11
- const dirname = import.meta.dirname
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() + '\n' + err.stderr.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() + '\n' + err.stderr.toString()
64
+ log = `${err.stdout.toString()}\n${err.stderr.toString()}`
65
65
  error = true
66
66
  }
67
67
  let screenshotBase64: any = null
@@ -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
- for (const file of libFiles) {
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
@@ -25,7 +25,7 @@ const cwd = process.cwd()
25
25
 
26
26
  const app = await Bun.file(`${cwd}/application.json`).json()
27
27
 
28
- let args: string[] = []
28
+ const args: string[] = []
29
29
  if (values['clear-cache']) args.push('--clear-cache')
30
30
 
31
31
  let needWatcher = true
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(/^[a-f0-9]{40}$/)
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
- return `00000000-0000-0000-0000-${(count++).toString().padStart(12, '0')}`
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