@fugood/bricks-ctor 2.25.0-beta.5 → 2.25.0-beta.50
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/__tests__/config-diff.test.js +100 -0
- package/compile/__tests__/index.test.js +365 -0
- package/compile/__tests__/util.test.js +317 -0
- package/compile/action-name-map.ts +64 -0
- package/compile/config-diff.ts +155 -0
- package/compile/index.ts +273 -32
- package/compile/util.ts +26 -7
- package/package.json +7 -3
- package/skills/bricks-ctor/SKILL.md +23 -17
- package/skills/bricks-ctor/{rules → references}/animation.md +3 -2
- package/skills/bricks-ctor/{rules → references}/architecture-patterns.md +18 -0
- package/skills/bricks-ctor/{rules → references}/automations.md +11 -0
- package/skills/bricks-ctor/references/buttress.md +245 -0
- package/skills/bricks-ctor/references/data-calculation.md +239 -0
- package/skills/bricks-ctor/references/simulator.md +132 -0
- package/skills/bricks-ctor/references/source-editing-tools.md +81 -0
- package/skills/bricks-ctor/references/verification-toolchain.md +200 -0
- package/skills/bricks-design/SKILL.md +150 -45
- package/skills/bricks-design/references/architecture-truths.md +132 -0
- package/skills/bricks-design/references/avoiding-complexity.md +91 -0
- package/skills/bricks-design/references/design-critique.md +195 -0
- package/skills/bricks-design/references/design-languages.md +265 -0
- package/skills/bricks-design/references/performance.md +116 -0
- package/skills/bricks-design/references/presentation-and-slideshow.md +137 -0
- package/skills/bricks-design/references/translating-inputs.md +152 -0
- package/skills/bricks-design/references/variations-and-tweaks.md +124 -0
- package/skills/bricks-design/references/when-the-brief-is-branded.md +284 -0
- package/skills/bricks-design/references/when-the-brief-is-vague.md +85 -0
- package/skills/bricks-design/references/workflow.md +134 -0
- package/skills/bricks-ux/SKILL.md +114 -0
- package/skills/bricks-ux/references/accessibility.md +162 -0
- package/skills/bricks-ux/references/flow-states.md +175 -0
- package/skills/bricks-ux/references/interaction-archetypes.md +189 -0
- package/skills/bricks-ux/references/monitoring-screens.md +153 -0
- package/skills/bricks-ux/references/pressable-composition.md +126 -0
- package/skills/bricks-ux/references/user-journey.md +168 -0
- package/skills/bricks-ux/references/ux-critique.md +256 -0
- package/tools/__tests__/_cli-error.test.ts +35 -0
- package/tools/_cli-error.ts +17 -0
- package/tools/_edits-log.ts +41 -0
- package/tools/_git-author.ts +10 -2
- package/tools/_last-pushed-commit.ts +28 -0
- package/tools/_shell.ts +8 -1
- package/tools/deploy.ts +17 -6
- package/tools/mcp-env.ts +13 -0
- package/tools/mcp-server.ts +8 -0
- package/tools/mcp-tools/__tests__/data-calc-editing.test.js +516 -0
- package/tools/mcp-tools/__tests__/entry-editing.test.js +866 -0
- package/tools/mcp-tools/__tests__/huggingface.test.ts +49 -0
- package/tools/mcp-tools/__tests__/icons.test.ts +21 -0
- package/tools/mcp-tools/__tests__/mcp-env.test.js +19 -0
- package/tools/mcp-tools/_editing-helpers.ts +58 -0
- package/tools/mcp-tools/_verify.ts +50 -0
- package/tools/mcp-tools/compile.ts +21 -9
- package/tools/mcp-tools/data-calc-editing.ts +1349 -0
- package/tools/mcp-tools/entry-editing.ts +2336 -0
- package/tools/mcp-tools/huggingface.ts +23 -13
- package/tools/mcp-tools/icons.ts +23 -7
- package/tools/mcp-tools/media.ts +4 -1
- package/tools/postinstall.ts +80 -3
- package/tools/pull.ts +93 -22
- package/tools/push-config.ts +114 -0
- package/tools/{preview-main.mjs → simulator-main.mjs} +207 -12
- package/tools/simulator-preload.cjs +16 -0
- package/tools/{preview.ts → simulator.ts} +4 -4
- package/types/{animation.ts → animation.d.ts} +24 -8
- package/types/{automation.ts → automation.d.ts} +16 -20
- package/types/{brick-base.ts → brick-base.d.ts} +1 -1
- package/types/bricks/{Camera.ts → Camera.d.ts} +8 -8
- package/types/bricks/{Chart.ts → Chart.d.ts} +4 -4
- package/types/bricks/{GenerativeMedia.ts → GenerativeMedia.d.ts} +15 -15
- package/types/bricks/{Icon.ts → Icon.d.ts} +7 -7
- package/types/bricks/{Image.ts → Image.d.ts} +21 -9
- package/types/bricks/{Items.ts → Items.d.ts} +7 -7
- package/types/bricks/{Lottie.ts → Lottie.d.ts} +10 -10
- package/types/bricks/{Maps.ts → Maps.d.ts} +11 -11
- package/types/bricks/{QrCode.ts → QrCode.d.ts} +7 -7
- package/types/bricks/{Rect.ts → Rect.d.ts} +7 -7
- package/types/bricks/{RichText.ts → RichText.d.ts} +12 -9
- package/types/bricks/{Rive.ts → Rive.d.ts} +9 -9
- package/types/bricks/Scene3D.d.ts +676 -0
- package/types/bricks/{Sketch.ts → Sketch.d.ts} +6 -6
- package/types/bricks/{Slideshow.ts → Slideshow.d.ts} +7 -7
- package/types/bricks/{Svg.ts → Svg.d.ts} +7 -7
- package/types/bricks/{Text.ts → Text.d.ts} +9 -9
- package/types/bricks/{TextInput.ts → TextInput.d.ts} +10 -10
- package/types/bricks/{Video.ts → Video.d.ts} +12 -12
- package/types/bricks/{VideoStreaming.ts → VideoStreaming.d.ts} +10 -10
- package/types/bricks/{WebRtcStream.ts → WebRtcStream.d.ts} +1 -1
- package/types/bricks/{WebView.ts → WebView.d.ts} +4 -4
- package/types/bricks/{index.ts → index.d.ts} +1 -0
- package/types/{common.ts → common.d.ts} +3 -6
- package/types/data-calc-command/base.d.ts +57 -0
- package/types/data-calc-command/collection.d.ts +418 -0
- package/types/data-calc-command/color.d.ts +432 -0
- package/types/data-calc-command/constant.d.ts +50 -0
- package/types/data-calc-command/datetime.d.ts +147 -0
- package/types/data-calc-command/file.d.ts +129 -0
- package/types/data-calc-command/index.d.ts +13 -0
- package/types/data-calc-command/iteratee.d.ts +23 -0
- package/types/data-calc-command/logictype.d.ts +190 -0
- package/types/data-calc-command/math.d.ts +275 -0
- package/types/data-calc-command/object.d.ts +119 -0
- package/types/data-calc-command/sandbox.d.ts +66 -0
- package/types/data-calc-command/string.d.ts +407 -0
- package/types/{data-calc.ts → data-calc.d.ts} +1 -0
- package/types/{data.ts → data.d.ts} +4 -2
- package/types/generators/{Assistant.ts → Assistant.d.ts} +19 -0
- package/types/generators/{LlmGgml.ts → LlmGgml.d.ts} +43 -1
- package/types/generators/{LlmMlx.ts → LlmMlx.d.ts} +1 -0
- package/types/generators/{RerankerGgml.ts → RerankerGgml.d.ts} +5 -1
- package/types/generators/{SoundRecorder.ts → SoundRecorder.d.ts} +10 -1
- package/types/generators/{SpeechToTextGgml.ts → SpeechToTextGgml.d.ts} +6 -1
- package/types/generators/{SttAppleBuiltin.ts → SttAppleBuiltin.d.ts} +27 -4
- package/types/generators/{ThermalPrinter.ts → ThermalPrinter.d.ts} +9 -7
- package/types/generators/{VadGgml.ts → VadGgml.d.ts} +12 -2
- package/types/{subspace.ts → subspace.d.ts} +1 -1
- package/utils/__tests__/calc.test.js +25 -0
- package/utils/__tests__/id.test.js +154 -0
- package/utils/calc.ts +5 -1
- package/utils/data.ts +5 -7
- package/utils/event-props.ts +17 -0
- package/utils/id.ts +109 -56
- package/skills/bricks-ctor/rules/buttress.md +0 -156
- package/skills/bricks-ctor/rules/data-calculation.md +0 -209
- package/skills/bricks-design/LICENSE.txt +0 -180
- package/types/data-calc-command.ts +0 -7005
- /package/skills/bricks-ctor/{rules → references}/local-sync.md +0 -0
- /package/skills/bricks-ctor/{rules → references}/media-flow.md +0 -0
- /package/skills/bricks-ctor/{rules → references}/remote-data-bank.md +0 -0
- /package/skills/bricks-ctor/{rules → references}/standby-transition.md +0 -0
- /package/types/{canvas.ts → canvas.d.ts} +0 -0
- /package/types/{data-calc-script.ts → data-calc-script.d.ts} +0 -0
- /package/types/generators/{AlarmClock.ts → AlarmClock.d.ts} +0 -0
- /package/types/generators/{BleCentral.ts → BleCentral.d.ts} +0 -0
- /package/types/generators/{BlePeripheral.ts → BlePeripheral.d.ts} +0 -0
- /package/types/generators/{CanvasMap.ts → CanvasMap.d.ts} +0 -0
- /package/types/generators/{CastlesPay.ts → CastlesPay.d.ts} +0 -0
- /package/types/generators/{DataBank.ts → DataBank.d.ts} +0 -0
- /package/types/generators/{File.ts → File.d.ts} +0 -0
- /package/types/generators/{GraphQl.ts → GraphQl.d.ts} +0 -0
- /package/types/generators/{Http.ts → Http.d.ts} +0 -0
- /package/types/generators/{HttpServer.ts → HttpServer.d.ts} +0 -0
- /package/types/generators/{Information.ts → Information.d.ts} +0 -0
- /package/types/generators/{Intent.ts → Intent.d.ts} +0 -0
- /package/types/generators/{Iterator.ts → Iterator.d.ts} +0 -0
- /package/types/generators/{Keyboard.ts → Keyboard.d.ts} +0 -0
- /package/types/generators/{LlmAnthropicCompat.ts → LlmAnthropicCompat.d.ts} +0 -0
- /package/types/generators/{LlmAppleBuiltin.ts → LlmAppleBuiltin.d.ts} +0 -0
- /package/types/generators/{LlmMediaTekNeuroPilot.ts → LlmMediaTekNeuroPilot.d.ts} +0 -0
- /package/types/generators/{LlmOnnx.ts → LlmOnnx.d.ts} +0 -0
- /package/types/generators/{LlmOpenAiCompat.ts → LlmOpenAiCompat.d.ts} +0 -0
- /package/types/generators/{LlmQualcommAiEngine.ts → LlmQualcommAiEngine.d.ts} +0 -0
- /package/types/generators/{Mcp.ts → Mcp.d.ts} +0 -0
- /package/types/generators/{McpServer.ts → McpServer.d.ts} +0 -0
- /package/types/generators/{MediaFlow.ts → MediaFlow.d.ts} +0 -0
- /package/types/generators/{MqttBroker.ts → MqttBroker.d.ts} +0 -0
- /package/types/generators/{MqttClient.ts → MqttClient.d.ts} +0 -0
- /package/types/generators/{Question.ts → Question.d.ts} +0 -0
- /package/types/generators/{RealtimeTranscription.ts → RealtimeTranscription.d.ts} +0 -0
- /package/types/generators/{SerialPort.ts → SerialPort.d.ts} +0 -0
- /package/types/generators/{SoundPlayer.ts → SoundPlayer.d.ts} +0 -0
- /package/types/generators/{SpeechToTextOnnx.ts → SpeechToTextOnnx.d.ts} +0 -0
- /package/types/generators/{SpeechToTextPlatform.ts → SpeechToTextPlatform.d.ts} +0 -0
- /package/types/generators/{SqLite.ts → SqLite.d.ts} +0 -0
- /package/types/generators/{Step.ts → Step.d.ts} +0 -0
- /package/types/generators/{Tcp.ts → Tcp.d.ts} +0 -0
- /package/types/generators/{TcpServer.ts → TcpServer.d.ts} +0 -0
- /package/types/generators/{TextToSpeechAppleBuiltin.ts → TextToSpeechAppleBuiltin.d.ts} +0 -0
- /package/types/generators/{TextToSpeechGgml.ts → TextToSpeechGgml.d.ts} +0 -0
- /package/types/generators/{TextToSpeechOnnx.ts → TextToSpeechOnnx.d.ts} +0 -0
- /package/types/generators/{TextToSpeechOpenAiLike.ts → TextToSpeechOpenAiLike.d.ts} +0 -0
- /package/types/generators/{Tick.ts → Tick.d.ts} +0 -0
- /package/types/generators/{Udp.ts → Udp.d.ts} +0 -0
- /package/types/generators/{VadOnnx.ts → VadOnnx.d.ts} +0 -0
- /package/types/generators/{VadTraditional.ts → VadTraditional.d.ts} +0 -0
- /package/types/generators/{VectorStore.ts → VectorStore.d.ts} +0 -0
- /package/types/generators/{Watchdog.ts → Watchdog.d.ts} +0 -0
- /package/types/generators/{WebCrawler.ts → WebCrawler.d.ts} +0 -0
- /package/types/generators/{WebRtc.ts → WebRtc.d.ts} +0 -0
- /package/types/generators/{WebSocket.ts → WebSocket.d.ts} +0 -0
- /package/types/generators/{index.ts → index.d.ts} +0 -0
- /package/types/{index.ts → index.d.ts} +0 -0
- /package/types/{switch.ts → switch.d.ts} +0 -0
- /package/types/{system.ts → system.d.ts} +0 -0
package/utils/id.ts
CHANGED
|
@@ -1,80 +1,133 @@
|
|
|
1
1
|
import { v4 as uuid } from 'uuid'
|
|
2
|
+
import { createHash } from 'node:crypto'
|
|
3
|
+
import { readFileSync } from 'node:fs'
|
|
4
|
+
import { join } from 'node:path'
|
|
2
5
|
|
|
3
6
|
let count = 0
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
type IdType =
|
|
9
|
+
| 'animation'
|
|
10
|
+
| 'brick'
|
|
11
|
+
| 'canvas'
|
|
12
|
+
| 'generator'
|
|
13
|
+
| 'data'
|
|
14
|
+
| 'switch'
|
|
15
|
+
| 'property_bank_command'
|
|
16
|
+
| 'property_bank_calc'
|
|
17
|
+
| 'dynamic-brick'
|
|
18
|
+
| 'automation_map'
|
|
19
|
+
| 'test'
|
|
20
|
+
| 'test_case'
|
|
21
|
+
| 'test_var'
|
|
22
|
+
| 'subspace'
|
|
23
|
+
|
|
24
|
+
type IdOptions = {
|
|
25
|
+
snapshotMode?: boolean
|
|
10
26
|
}
|
|
11
27
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
const APPLICATION_ID_FALLBACK = 'unknown-application'
|
|
29
|
+
|
|
30
|
+
const usedStableAliases = new Set<string>()
|
|
31
|
+
let applicationIdCache: { cwd: string; id: string } | null = null
|
|
32
|
+
|
|
33
|
+
const readApplicationId = () => {
|
|
34
|
+
const cwd = process.cwd()
|
|
35
|
+
if (applicationIdCache?.cwd === cwd) return applicationIdCache.id
|
|
36
|
+
|
|
37
|
+
let id = APPLICATION_ID_FALLBACK
|
|
38
|
+
try {
|
|
39
|
+
const app = JSON.parse(readFileSync(join(cwd, 'application.json'), 'utf8'))
|
|
40
|
+
if (typeof app.id === 'string' && app.id) id = app.id
|
|
41
|
+
} catch {
|
|
42
|
+
// `makeId` is also used from tests and utilities outside project roots.
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
applicationIdCache = { cwd, id }
|
|
46
|
+
return id
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const hashToRandomBytes = (parts: string[]) => {
|
|
50
|
+
const hash = createHash('sha256').update(JSON.stringify(parts)).digest()
|
|
51
|
+
return new Uint8Array(hash.subarray(0, 16))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const makeStableUuid = (type: string, alias?: string) => {
|
|
55
|
+
const applicationId = readApplicationId()
|
|
56
|
+
const seed = alias ?? String(count)
|
|
57
|
+
if (alias === undefined) count += 1
|
|
58
|
+
|
|
59
|
+
if (alias !== undefined) {
|
|
60
|
+
const aliasKey = JSON.stringify([applicationId, type, alias])
|
|
61
|
+
if (usedStableAliases.has(aliasKey)) {
|
|
62
|
+
throw new Error(`Duplicate makeId alias '${alias}' for type '${type}'`)
|
|
63
|
+
}
|
|
64
|
+
usedStableAliases.add(aliasKey)
|
|
35
65
|
}
|
|
36
|
-
|
|
66
|
+
|
|
67
|
+
return uuid({
|
|
68
|
+
random: hashToRandomBytes([applicationId, type, seed]),
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const idPrefix = (type: IdType): string => {
|
|
37
73
|
switch (type) {
|
|
38
74
|
case 'animation':
|
|
39
|
-
|
|
40
|
-
break
|
|
75
|
+
return 'ANIMATION_'
|
|
41
76
|
case 'brick':
|
|
42
|
-
|
|
43
|
-
break
|
|
77
|
+
return 'BRICK_'
|
|
44
78
|
case 'dynamic-brick':
|
|
45
|
-
|
|
46
|
-
break
|
|
79
|
+
return 'DYNAMIC_BRICK_'
|
|
47
80
|
case 'canvas':
|
|
48
|
-
|
|
49
|
-
break
|
|
81
|
+
return 'CANVAS_'
|
|
50
82
|
case 'generator':
|
|
51
|
-
|
|
52
|
-
break
|
|
83
|
+
return 'GENERATOR_'
|
|
53
84
|
case 'data':
|
|
54
|
-
|
|
55
|
-
break
|
|
85
|
+
return 'PROPERTY_BANK_DATA_NODE_'
|
|
56
86
|
case 'switch':
|
|
57
|
-
|
|
58
|
-
break
|
|
87
|
+
return 'BRICK_STATE_GROUP_'
|
|
59
88
|
case 'property_bank_command':
|
|
60
|
-
|
|
61
|
-
break
|
|
89
|
+
return 'PROPERTY_BANK_COMMAND_NODE_'
|
|
62
90
|
case 'property_bank_calc':
|
|
63
|
-
|
|
64
|
-
break
|
|
91
|
+
return 'PROPERTY_BANK_COMMAND_MAP_'
|
|
65
92
|
case 'automation_map':
|
|
66
|
-
|
|
67
|
-
break
|
|
93
|
+
return 'AUTOMATION_MAP_'
|
|
68
94
|
case 'test':
|
|
69
|
-
|
|
70
|
-
break
|
|
95
|
+
return 'TEST_'
|
|
71
96
|
case 'test_case':
|
|
72
|
-
|
|
73
|
-
break
|
|
97
|
+
return 'TEST_CASE_'
|
|
74
98
|
case 'test_var':
|
|
75
|
-
|
|
76
|
-
break
|
|
99
|
+
return 'TEST_VAR_'
|
|
77
100
|
default:
|
|
101
|
+
return ''
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Make stable ids by default; explicit snapshotMode: false preserves the random escape hatch.
|
|
106
|
+
export const makeId = (type: IdType, aliasOrOpts?: string | IdOptions, opts?: IdOptions) => {
|
|
107
|
+
if (type === 'subspace') {
|
|
108
|
+
throw new Error('Currently subspace is not supported for ID generation, please use a fixed ID')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const alias = typeof aliasOrOpts === 'string' ? aliasOrOpts : undefined
|
|
112
|
+
const options = typeof aliasOrOpts === 'string' ? opts : (aliasOrOpts ?? opts)
|
|
113
|
+
|
|
114
|
+
const useCountFallback = aliasOrOpts === undefined && opts === undefined
|
|
115
|
+
const id =
|
|
116
|
+
alias !== undefined || options?.snapshotMode || useCountFallback
|
|
117
|
+
? makeStableUuid(type, alias)
|
|
118
|
+
: uuid()
|
|
119
|
+
return `${idPrefix(type)}${id}`
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Deterministic id derived solely from a caller-supplied seed. Unlike makeId it keeps no
|
|
123
|
+
// global state — no incrementing counter, no alias registry — so the same (type, seed)
|
|
124
|
+
// always maps to the same id on every compile and in any process. Compiled artifacts seed
|
|
125
|
+
// their ids this way (e.g. generateCalulationMap's command nodes, seeded by their calc id +
|
|
126
|
+
// structural role) so unchanged source recompiles byte-identically and editing one calc
|
|
127
|
+
// never shifts another's ids. The seed must be unique within a single config.
|
|
128
|
+
export const makeSeededId = (type: IdType, seed: string) => {
|
|
129
|
+
if (type === 'subspace') {
|
|
130
|
+
throw new Error('Currently subspace is not supported for ID generation, please use a fixed ID')
|
|
78
131
|
}
|
|
79
|
-
return `${
|
|
132
|
+
return `${idPrefix(type)}${uuid({ random: hashToRandomBytes([readApplicationId(), type, seed]) })}`
|
|
80
133
|
}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# Buttress (Remote Inference)
|
|
2
|
-
|
|
3
|
-
Backend system for offloading compute-intensive AI generator tasks from BRICKS devices to more powerful machines.
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
|
|
7
|
-
When mobile devices or embedded systems lack hardware for local AI inference (LLM, speech-to-text), Buttress transparently delegates work to a server with appropriate resources (GPU).
|
|
8
|
-
|
|
9
|
-
## How It Works
|
|
10
|
-
|
|
11
|
-
1. **Capability Exchange**: Client and server share hardware capabilities
|
|
12
|
-
2. **Strategy Selection**: System decides local vs. remote execution
|
|
13
|
-
3. **Transparent Offloading**: Generator operates same way, execution happens remotely
|
|
14
|
-
|
|
15
|
-
## Supported Generators
|
|
16
|
-
|
|
17
|
-
- LLM (GGML) (LlmMlx.ts) - Local Large Language Model inference with GGML
|
|
18
|
-
- LLM (MLX) (LlmGgml.ts) - Local Large Language Model inference with MLX
|
|
19
|
-
- Speech-to-Text (GGML) (SpeechToTextGgml.ts) - Local Speech-to-Text inference with GGML
|
|
20
|
-
|
|
21
|
-
## Client Configuration
|
|
22
|
-
|
|
23
|
-
In generator properties, configure Buttress settings:
|
|
24
|
-
|
|
25
|
-
| Setting | Description |
|
|
26
|
-
|---------|-------------|
|
|
27
|
-
| `Enabled` | Toggle Buttress offloading |
|
|
28
|
-
| `URL` | Buttress server URL (e.g., `http://192.168.1.100:2080`) |
|
|
29
|
-
| `Fallback Type` | Action if Buttress unavailable: `use-local` or `no-op` |
|
|
30
|
-
| `Strategy` | Execution preference |
|
|
31
|
-
|
|
32
|
-
### Strategy Options
|
|
33
|
-
|
|
34
|
-
| Strategy | Description |
|
|
35
|
-
|----------|-------------|
|
|
36
|
-
| `prefer-local` | Use local if capable, fallback to Buttress |
|
|
37
|
-
| `prefer-buttress` | Use Buttress if available, fallback to local |
|
|
38
|
-
| `prefer-best` | Auto-select based on capability comparison |
|
|
39
|
-
|
|
40
|
-
## Generator Configuration Example
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
import { makeId } from 'bricks-ctor'
|
|
44
|
-
|
|
45
|
-
const llmGenerator: GeneratorLLM = {
|
|
46
|
-
__typename: 'Generator',
|
|
47
|
-
templateKey: 'GENERATOR_LLM',
|
|
48
|
-
id: makeId('generator'),
|
|
49
|
-
title: 'Chat LLM',
|
|
50
|
-
description: '',
|
|
51
|
-
property: {
|
|
52
|
-
modelUrl: 'https://huggingface.co/ggml-org/gemma-3-12b-it-qat-GGUF/resolve/main/gemma-3-12b-it-qat-q4_0.gguf',
|
|
53
|
-
contextSize: 8192,
|
|
54
|
-
buttressConnectionSettings: {
|
|
55
|
-
enabled: true,
|
|
56
|
-
url: 'http://192.168.1.100:2080',
|
|
57
|
-
fallbackType: 'use-local',
|
|
58
|
-
strategy: 'prefer-best',
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
events: {},
|
|
62
|
-
switches: [],
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Server Setup
|
|
67
|
-
|
|
68
|
-
### Requirements
|
|
69
|
-
- [Bun](https://bun.sh) v1.3+
|
|
70
|
-
- GPU recommended for LLM/STT
|
|
71
|
-
|
|
72
|
-
### Installation
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
bun add -g @fugood/buttress-server
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Start Server
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
bricks-buttress
|
|
82
|
-
# or with config
|
|
83
|
-
bricks-buttress --config ./config.toml
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### CLI Options
|
|
87
|
-
|
|
88
|
-
| Option | Description |
|
|
89
|
-
|--------|-------------|
|
|
90
|
-
| `-p, --port` | Port (default: 2080) |
|
|
91
|
-
| `-c, --config` | TOML config file path |
|
|
92
|
-
| `-v, --version` | Show version |
|
|
93
|
-
| `-h, --help` | Show help |
|
|
94
|
-
|
|
95
|
-
### Environment Variables
|
|
96
|
-
|
|
97
|
-
| Variable | Description |
|
|
98
|
-
|----------|-------------|
|
|
99
|
-
| `HF_TOKEN` | Hugging Face token for model downloads |
|
|
100
|
-
| `ENABLE_OPENAI_COMPAT_ENDPOINT` | Set to `1` for OpenAI-compatible API |
|
|
101
|
-
|
|
102
|
-
## Server Configuration (TOML)
|
|
103
|
-
|
|
104
|
-
```toml
|
|
105
|
-
[server]
|
|
106
|
-
port = 2080
|
|
107
|
-
|
|
108
|
-
[runtime]
|
|
109
|
-
cache_dir = "./.buttress-cache"
|
|
110
|
-
n_threads = 6
|
|
111
|
-
flash_attn_type = "on"
|
|
112
|
-
cache_type_k = "q8_0"
|
|
113
|
-
cache_type_v = "q8_0"
|
|
114
|
-
|
|
115
|
-
# LLM Generator
|
|
116
|
-
[[generators]]
|
|
117
|
-
type = "ggml-llm"
|
|
118
|
-
[generators.backend]
|
|
119
|
-
variant_preference = ["cuda", "vulkan", "default"]
|
|
120
|
-
gpu_memory_fraction = 0.95
|
|
121
|
-
[generators.model]
|
|
122
|
-
repo_id = "ggml-org/gemma-3-12b-it-qat-GGUF"
|
|
123
|
-
download = true
|
|
124
|
-
n_ctx = 8192
|
|
125
|
-
|
|
126
|
-
# STT Generator
|
|
127
|
-
[[generators]]
|
|
128
|
-
type = "ggml-stt"
|
|
129
|
-
[generators.backend]
|
|
130
|
-
variant_preference = ["cuda", "vulkan", "default"]
|
|
131
|
-
[generators.model]
|
|
132
|
-
repo_id = "BricksDisplay/whisper-ggml"
|
|
133
|
-
filename = "ggml-small-q8_0.bin"
|
|
134
|
-
download = true
|
|
135
|
-
use_gpu = true
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Use Cases
|
|
139
|
-
|
|
140
|
-
### Resource-Constrained Devices
|
|
141
|
-
Digital signage with basic hardware offloads LLM to powerful server.
|
|
142
|
-
|
|
143
|
-
### Shared GPU Resources
|
|
144
|
-
Multiple devices share single GPU server for inference.
|
|
145
|
-
|
|
146
|
-
### Development Testing
|
|
147
|
-
Test AI features on lightweight dev machines by connecting to beefy server.
|
|
148
|
-
|
|
149
|
-
## Best Practices
|
|
150
|
-
|
|
151
|
-
1. **Network reliability**: Ensure stable LAN connection to Buttress server
|
|
152
|
-
2. **Fallback strategy**: Configure appropriate fallback for critical features
|
|
153
|
-
3. **Server monitoring**: Monitor Buttress server resource usage
|
|
154
|
-
4. **Model consistency**: Ensure client and server use compatible models
|
|
155
|
-
5. **Security**: Run Buttress on private network, not public internet
|
|
156
|
-
6. **Latency awareness**: Account for network latency in UX design
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
# Data Calculation (JS Sandbox)
|
|
2
|
-
|
|
3
|
-
Transform and compute Data Bank values using JavaScript scripts.
|
|
4
|
-
|
|
5
|
-
## DataCalculationScript
|
|
6
|
-
|
|
7
|
-
JavaScript code executed in a sandbox with access to inputs and outputs.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
import { makeId } from 'bricks-ctor'
|
|
11
|
-
|
|
12
|
-
const calculation: DataCalculationScript = {
|
|
13
|
-
__typename: 'DataCalculationScript',
|
|
14
|
-
id: makeId('property_bank_calc'),
|
|
15
|
-
title: 'Format Price',
|
|
16
|
-
description: 'Formats price with currency symbol',
|
|
17
|
-
note: '',
|
|
18
|
-
triggerMode: 'auto', // 'auto' | 'manual'
|
|
19
|
-
enableAsync: false,
|
|
20
|
-
// Inline code
|
|
21
|
-
code: `
|
|
22
|
-
const price = inputs.price || 0
|
|
23
|
-
const currency = inputs.currency || 'USD'
|
|
24
|
-
return new Intl.NumberFormat('en-US', {
|
|
25
|
-
style: 'currency',
|
|
26
|
-
currency,
|
|
27
|
-
}).format(price)
|
|
28
|
-
`,
|
|
29
|
-
// Or load from file (preferred for longer scripts)
|
|
30
|
-
// import { readFile } from 'node:fs/promises'
|
|
31
|
-
// code: await readFile(new URL('./format-price.sandbox.js', import.meta.url), 'utf8'),
|
|
32
|
-
inputs: [
|
|
33
|
-
{ key: 'price', data: () => priceData, trigger: true },
|
|
34
|
-
{ key: 'currency', data: () => currencyData, trigger: false },
|
|
35
|
-
],
|
|
36
|
-
output: () => formattedPriceData,
|
|
37
|
-
outputs: [], // Additional named outputs
|
|
38
|
-
error: null, // or () => errorData for error handling
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Trigger Modes
|
|
43
|
-
|
|
44
|
-
| Mode | Description |
|
|
45
|
-
|------|-------------|
|
|
46
|
-
| `auto` | Run when input values change (with trigger: true) |
|
|
47
|
-
| `manual` | Only run via `PROPERTY_BANK_COMMAND` action |
|
|
48
|
-
|
|
49
|
-
Use `manual` to prevent circular dependencies or for explicit control.
|
|
50
|
-
|
|
51
|
-
## Script Sandbox Features
|
|
52
|
-
|
|
53
|
-
Scripts run in `use strict` mode with a sandboxed set of globals and libraries.
|
|
54
|
-
|
|
55
|
-
### Built-in Globals
|
|
56
|
-
|
|
57
|
-
| Global | Description |
|
|
58
|
-
|--------|-------------|
|
|
59
|
-
| `inputs` | Object with input values |
|
|
60
|
-
| `console` | `{ log, error, warn, info }` for debugging |
|
|
61
|
-
| `Platform` | `{ OS, isTV, isPad, isVision, isElectron }` |
|
|
62
|
-
| `TextEncoder`, `TextDecoder` | Text encoding/decoding |
|
|
63
|
-
| `Buffer` | Node.js Buffer (without `allocUnsafe`) |
|
|
64
|
-
| `btoa`, `atob` | Base64 encoding/decoding |
|
|
65
|
-
|
|
66
|
-
### Available Libraries
|
|
67
|
-
|
|
68
|
-
**Utility**
|
|
69
|
-
| Library | Global | Description |
|
|
70
|
-
|---------|--------|-------------|
|
|
71
|
-
| [lodash](https://lodash.com) | `_`, `lodash` | Utility (sync: no debounce/delay/defer) |
|
|
72
|
-
| [voca](https://vocajs.com) | `voca` | String manipulation |
|
|
73
|
-
| [invariant](https://github.com/zertosh/invariant) | `invariant` | Assertions |
|
|
74
|
-
|
|
75
|
-
**Data & Encoding**
|
|
76
|
-
| Library | Global | Description |
|
|
77
|
-
|---------|--------|-------------|
|
|
78
|
-
| [json5](https://github.com/json5/json5) | `json5` | JSON5 parsing |
|
|
79
|
-
| [qs](https://github.com/ljharb/qs) | `qs` | Query string parsing |
|
|
80
|
-
| [url](https://github.com/defunctzombie/node-url) | `url` | URL parsing |
|
|
81
|
-
| [bytes](https://github.com/visionmedia/bytes.js) | `bytes` | Byte parsing/formatting |
|
|
82
|
-
| [ms](https://github.com/vercel/ms) | `ms` | Millisecond conversion |
|
|
83
|
-
| [base45](https://github.com/irony/base45) | `base45` | Base45 encoding |
|
|
84
|
-
| [iconv-lite](https://github.com/ashtuchkin/iconv-lite) | `iconv` | Character encoding |
|
|
85
|
-
|
|
86
|
-
**Math & Color**
|
|
87
|
-
| Library | Global | Description |
|
|
88
|
-
|---------|--------|-------------|
|
|
89
|
-
| [mathjs](https://mathjs.org) | `math`, `mathjs` | Math library |
|
|
90
|
-
| [chroma-js](https://gka.github.io/chroma.js) | `chroma` | Color manipulation |
|
|
91
|
-
|
|
92
|
-
**Date/Time**
|
|
93
|
-
| Library | Global | Description |
|
|
94
|
-
|---------|--------|-------------|
|
|
95
|
-
| [moment](https://momentjs.com) | `moment` | Date/time (auto parseFormat) |
|
|
96
|
-
|
|
97
|
-
**ID & Hash**
|
|
98
|
-
| Library | Global | Description |
|
|
99
|
-
|---------|--------|-------------|
|
|
100
|
-
| [nanoid](https://github.com/ai/nanoid) | `nanoid` | Unique ID generation |
|
|
101
|
-
| [md5](https://github.com/pvorb/node-md5) | `md5` | MD5 hashing |
|
|
102
|
-
|
|
103
|
-
**Crypto**
|
|
104
|
-
| Library | Global | Description |
|
|
105
|
-
|---------|--------|-------------|
|
|
106
|
-
| [crypto-browserify](https://github.com/crypto-browserify/crypto-browserify) | `crypto` | Crypto functions |
|
|
107
|
-
| [jsrsasign](https://github.com/kjur/jsrsasign) | `kjurJWS` | JWT/JWS signing |
|
|
108
|
-
| [cose-js](https://github.com/erdtman/COSE-JS) | `coseVerify` | COSE verification (sync) |
|
|
109
|
-
|
|
110
|
-
**Compression**
|
|
111
|
-
| Library | Global | Description |
|
|
112
|
-
|---------|--------|-------------|
|
|
113
|
-
| [fflate](https://github.com/101arrowz/fflate) | `fflate` | `{ zlibSync, unzlibSync, gzipSync, gunzipSync, compressSync, decompressSync, strFromU8 }` |
|
|
114
|
-
| [cbor](https://github.com/hildjj/node-cbor) | `cbor` | `{ encode, decode, decodeFirstSync, decodeAllSync }` |
|
|
115
|
-
|
|
116
|
-
**File & Document**
|
|
117
|
-
| Library | Global | Description |
|
|
118
|
-
|---------|--------|-------------|
|
|
119
|
-
| fs | `fs` | File system (limited, no download/upload) |
|
|
120
|
-
| [officeparser](https://github.com/nicktang) | `parseDocument` | Office document parsing (async) |
|
|
121
|
-
| [turndown](https://github.com/mixmark-io/turndown) | `TurndownService` | HTML to Markdown |
|
|
122
|
-
| [opencc-js](https://github.com/nk2028/opencc-js) | `OpenCC` | Chinese conversion `{ Converter, ConverterFactory, CustomConverter, Locale }` |
|
|
123
|
-
| [toon-format](https://github.com/nicktang) | `TOON` | TOON format parsing |
|
|
124
|
-
|
|
125
|
-
### Runtime Environment
|
|
126
|
-
|
|
127
|
-
| Platform | Engine |
|
|
128
|
-
|----------|--------|
|
|
129
|
-
| Android | Hermes engine sandbox |
|
|
130
|
-
| iOS | JavaScriptCore sandbox |
|
|
131
|
-
|
|
132
|
-
### Async Mode
|
|
133
|
-
|
|
134
|
-
Enable `enableAsync: true` to unlock additional capabilities:
|
|
135
|
-
|
|
136
|
-
**Additional async globals:**
|
|
137
|
-
- `Promise`, `setTimeout`, `setInterval`, `setImmediate`
|
|
138
|
-
- `clearTimeout`, `clearInterval`, `clearImmediate`
|
|
139
|
-
- `requestAnimationFrame`
|
|
140
|
-
- Full lodash (including `debounce`, `delay`, `defer`)
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
143
|
-
code: `
|
|
144
|
-
const result = await new Promise((resolve) => {
|
|
145
|
-
setTimeout(() => resolve(inputs.value * 2), 100)
|
|
146
|
-
})
|
|
147
|
-
return result
|
|
148
|
-
`,
|
|
149
|
-
enableAsync: true,
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Multiple Outputs
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
outputs: [
|
|
156
|
-
{ key: 'total', data: () => totalData },
|
|
157
|
-
{ key: 'tax', data: () => taxData },
|
|
158
|
-
{ key: 'subtotal', data: () => subtotalData },
|
|
159
|
-
],
|
|
160
|
-
code: `
|
|
161
|
-
const subtotal = inputs.price * inputs.quantity
|
|
162
|
-
const tax = subtotal * 0.1
|
|
163
|
-
const total = subtotal + tax
|
|
164
|
-
return { total, tax, subtotal }
|
|
165
|
-
`,
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## Triggering Manually
|
|
169
|
-
|
|
170
|
-
Use `PROPERTY_BANK_COMMAND` system action to trigger a manual calculation:
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
const triggerCalc: EventAction = {
|
|
174
|
-
handler: 'system',
|
|
175
|
-
action: {
|
|
176
|
-
__actionName: 'PROPERTY_BANK_COMMAND',
|
|
177
|
-
parent: 'System',
|
|
178
|
-
dataParams: [
|
|
179
|
-
{ input: () => computeTotalCalc }, // Reference to DataCalculation
|
|
180
|
-
],
|
|
181
|
-
},
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
## Best Practices
|
|
186
|
-
|
|
187
|
-
1. **Avoid circular deps**: Set non-triggering inputs (`trigger: false`) or use `manual` mode
|
|
188
|
-
2. **Error handling**: Always set `error` output for scripts that might fail
|
|
189
|
-
3. **Keep scripts pure**: Avoid side effects, return computed values
|
|
190
|
-
4. **Debounce rapid updates**: Use `manual` mode + timer for high-frequency inputs
|
|
191
|
-
|
|
192
|
-
## Anti-Patterns (AVOID)
|
|
193
|
-
|
|
194
|
-
See [Architecture Patterns](architecture-patterns.md) for the full pattern selection guide.
|
|
195
|
-
|
|
196
|
-
### Using Data Calc as an orchestrator
|
|
197
|
-
Scripts that manage state machines, control UI flow, or coordinate multi-step processes belong in Event Action Chains, not here.
|
|
198
|
-
|
|
199
|
-
**Symptom**: Script has if/else branches deciding "what happens next" or tracks "current step".
|
|
200
|
-
|
|
201
|
-
### Quick reference
|
|
202
|
-
|
|
203
|
-
| If you need to... | Use instead |
|
|
204
|
-
|---|---|
|
|
205
|
-
| Call an LLM / AI model | Generator (Assistant, LLM, HTTP) |
|
|
206
|
-
| Sequence multiple actions | Event Action Chain |
|
|
207
|
-
| Set a data value directly | PROPERTY_BANK system action |
|
|
208
|
-
| Compute a simple expression | PROPERTY_BANK_EXPRESSION |
|
|
209
|
-
| Transform/format/parse data | Data Calculation (correct use) |
|