@fugood/bricks-ctor 2.25.0-beta.60 → 2.25.0-beta.62
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/package.json +4 -28
- package/tools/__tests__/legacy-forwarder.test.js +91 -0
- package/tools/_forward.ts +26 -0
- package/tools/deploy.ts +3 -175
- package/tools/mcp-server.ts +3 -35
- package/tools/postinstall.ts +3 -291
- package/tools/pull.ts +3 -198
- package/tools/push-config.ts +3 -113
- package/tools/simulator.ts +3 -149
- package/compile/__tests__/config-diff.test.js +0 -100
- package/compile/__tests__/index.test.js +0 -461
- package/compile/__tests__/util.test.js +0 -450
- package/compile/action-name-map.ts +0 -1079
- package/compile/config-diff.ts +0 -155
- package/compile/index.ts +0 -1594
- package/compile/util.ts +0 -482
- package/index.ts +0 -6
- package/skills/bricks-ctor/SKILL.md +0 -38
- package/skills/bricks-ctor/references/animation.md +0 -160
- package/skills/bricks-ctor/references/architecture-patterns.md +0 -88
- package/skills/bricks-ctor/references/automations.md +0 -232
- package/skills/bricks-ctor/references/buttress.md +0 -245
- package/skills/bricks-ctor/references/data-calculation.md +0 -252
- package/skills/bricks-ctor/references/local-sync.md +0 -129
- package/skills/bricks-ctor/references/media-flow.md +0 -165
- package/skills/bricks-ctor/references/remote-data-bank.md +0 -196
- package/skills/bricks-ctor/references/simulator.md +0 -132
- package/skills/bricks-ctor/references/source-editing-tools.md +0 -81
- package/skills/bricks-ctor/references/standby-transition.md +0 -124
- package/skills/bricks-ctor/references/verification-toolchain.md +0 -200
- package/skills/bricks-design/SKILL.md +0 -171
- package/skills/bricks-design/references/architecture-truths.md +0 -132
- package/skills/bricks-design/references/avoiding-complexity.md +0 -91
- package/skills/bricks-design/references/design-critique.md +0 -195
- package/skills/bricks-design/references/design-languages.md +0 -265
- package/skills/bricks-design/references/performance.md +0 -116
- package/skills/bricks-design/references/presentation-and-slideshow.md +0 -137
- package/skills/bricks-design/references/translating-inputs.md +0 -152
- package/skills/bricks-design/references/variations-and-tweaks.md +0 -124
- package/skills/bricks-design/references/when-the-brief-is-branded.md +0 -284
- package/skills/bricks-design/references/when-the-brief-is-vague.md +0 -85
- package/skills/bricks-design/references/workflow.md +0 -134
- package/skills/bricks-ux/SKILL.md +0 -114
- package/skills/bricks-ux/references/accessibility.md +0 -162
- package/skills/bricks-ux/references/flow-states.md +0 -175
- package/skills/bricks-ux/references/interaction-archetypes.md +0 -189
- package/skills/bricks-ux/references/monitoring-screens.md +0 -153
- package/skills/bricks-ux/references/pressable-composition.md +0 -126
- package/skills/bricks-ux/references/user-journey.md +0 -168
- package/skills/bricks-ux/references/ux-critique.md +0 -256
- package/skills/rive-marketplace/SKILL.md +0 -99
- package/tools/__tests__/_cli-error.test.ts +0 -35
- package/tools/__tests__/_mcp-config.test.ts +0 -67
- package/tools/__tests__/pull.test.ts +0 -108
- package/tools/_cli-error.ts +0 -17
- package/tools/_edits-log.ts +0 -41
- package/tools/_git-author.ts +0 -37
- package/tools/_last-pushed-commit.ts +0 -28
- package/tools/_mcp-config.ts +0 -42
- package/tools/_shell.ts +0 -180
- package/tools/icons/.gitattributes +0 -1
- package/tools/icons/fa6pro-glyphmap.json +0 -4686
- package/tools/icons/fa6pro-meta.json +0 -1
- package/tools/mcp-env.ts +0 -13
- package/tools/mcp-tools/__tests__/data-calc-editing.test.js +0 -516
- package/tools/mcp-tools/__tests__/entry-editing.test.js +0 -866
- package/tools/mcp-tools/__tests__/huggingface.test.ts +0 -49
- package/tools/mcp-tools/__tests__/icons.test.ts +0 -21
- package/tools/mcp-tools/__tests__/mcp-env.test.js +0 -19
- package/tools/mcp-tools/_editing-helpers.ts +0 -98
- package/tools/mcp-tools/_verify.ts +0 -50
- package/tools/mcp-tools/compile.ts +0 -104
- package/tools/mcp-tools/data-calc-editing.ts +0 -1311
- package/tools/mcp-tools/entry-editing.ts +0 -2297
- package/tools/mcp-tools/huggingface.ts +0 -772
- package/tools/mcp-tools/icons.ts +0 -97
- package/tools/mcp-tools/lottie.ts +0 -102
- package/tools/mcp-tools/media.ts +0 -113
- package/tools/simulator-main.mjs +0 -488
- package/tools/simulator-preload.cjs +0 -16
- package/types/animation.d.ts +0 -116
- package/types/automation.d.ts +0 -231
- package/types/brick-base.d.ts +0 -80
- package/types/bricks/Camera.d.ts +0 -246
- package/types/bricks/Chart.d.ts +0 -372
- package/types/bricks/GenerativeMedia.d.ts +0 -290
- package/types/bricks/Icon.d.ts +0 -98
- package/types/bricks/Image.d.ts +0 -126
- package/types/bricks/Items.d.ts +0 -480
- package/types/bricks/Lottie.d.ts +0 -168
- package/types/bricks/Maps.d.ts +0 -262
- package/types/bricks/QrCode.d.ts +0 -117
- package/types/bricks/Rect.d.ts +0 -150
- package/types/bricks/RichText.d.ts +0 -131
- package/types/bricks/Rive.d.ts +0 -220
- package/types/bricks/Scene3D.d.ts +0 -676
- package/types/bricks/Sketch.d.ts +0 -256
- package/types/bricks/Slideshow.d.ts +0 -201
- package/types/bricks/Svg.d.ts +0 -99
- package/types/bricks/Text.d.ts +0 -148
- package/types/bricks/TextInput.d.ts +0 -242
- package/types/bricks/Video.d.ts +0 -242
- package/types/bricks/VideoStreaming.d.ts +0 -112
- package/types/bricks/WebRtcStream.d.ts +0 -65
- package/types/bricks/WebView.d.ts +0 -168
- package/types/bricks/index.d.ts +0 -23
- package/types/canvas.d.ts +0 -82
- package/types/common.d.ts +0 -141
- package/types/data-calc-command/base.d.ts +0 -57
- package/types/data-calc-command/collection.d.ts +0 -418
- package/types/data-calc-command/color.d.ts +0 -432
- package/types/data-calc-command/constant.d.ts +0 -50
- package/types/data-calc-command/datetime.d.ts +0 -147
- package/types/data-calc-command/file.d.ts +0 -129
- package/types/data-calc-command/index.d.ts +0 -13
- package/types/data-calc-command/iteratee.d.ts +0 -23
- package/types/data-calc-command/logictype.d.ts +0 -190
- package/types/data-calc-command/math.d.ts +0 -275
- package/types/data-calc-command/object.d.ts +0 -119
- package/types/data-calc-command/sandbox.d.ts +0 -66
- package/types/data-calc-command/string.d.ts +0 -407
- package/types/data-calc-script.d.ts +0 -21
- package/types/data-calc.d.ts +0 -12
- package/types/data.d.ts +0 -97
- package/types/generators/AlarmClock.d.ts +0 -110
- package/types/generators/Assistant.d.ts +0 -640
- package/types/generators/BleCentral.d.ts +0 -247
- package/types/generators/BlePeripheral.d.ts +0 -208
- package/types/generators/CanvasMap.d.ts +0 -74
- package/types/generators/CastlesPay.d.ts +0 -87
- package/types/generators/DataBank.d.ts +0 -160
- package/types/generators/File.d.ts +0 -432
- package/types/generators/GraphQl.d.ts +0 -132
- package/types/generators/Http.d.ts +0 -222
- package/types/generators/HttpServer.d.ts +0 -230
- package/types/generators/Information.d.ts +0 -103
- package/types/generators/Intent.d.ts +0 -168
- package/types/generators/Iterator.d.ts +0 -108
- package/types/generators/Keyboard.d.ts +0 -105
- package/types/generators/LlmAnthropicCompat.d.ts +0 -212
- package/types/generators/LlmAppleBuiltin.d.ts +0 -159
- package/types/generators/LlmGgml.d.ts +0 -903
- package/types/generators/LlmMediaTekNeuroPilot.d.ts +0 -235
- package/types/generators/LlmMlx.d.ts +0 -228
- package/types/generators/LlmOnnx.d.ts +0 -213
- package/types/generators/LlmOpenAiCompat.d.ts +0 -312
- package/types/generators/LlmQualcommAiEngine.d.ts +0 -247
- package/types/generators/Mcp.d.ts +0 -637
- package/types/generators/McpServer.d.ts +0 -289
- package/types/generators/MediaFlow.d.ts +0 -170
- package/types/generators/MqttBroker.d.ts +0 -141
- package/types/generators/MqttClient.d.ts +0 -141
- package/types/generators/Question.d.ts +0 -408
- package/types/generators/RealtimeTranscription.d.ts +0 -287
- package/types/generators/RerankerGgml.d.ts +0 -195
- package/types/generators/SerialPort.d.ts +0 -151
- package/types/generators/SoundPlayer.d.ts +0 -94
- package/types/generators/SoundRecorder.d.ts +0 -139
- package/types/generators/SpeechToTextGgml.d.ts +0 -424
- package/types/generators/SpeechToTextOnnx.d.ts +0 -236
- package/types/generators/SpeechToTextPlatform.d.ts +0 -85
- package/types/generators/SqLite.d.ts +0 -159
- package/types/generators/Step.d.ts +0 -107
- package/types/generators/SttAppleBuiltin.d.ts +0 -153
- package/types/generators/Tcp.d.ts +0 -126
- package/types/generators/TcpServer.d.ts +0 -147
- package/types/generators/TextToSpeechAppleBuiltin.d.ts +0 -127
- package/types/generators/TextToSpeechGgml.d.ts +0 -221
- package/types/generators/TextToSpeechOnnx.d.ts +0 -178
- package/types/generators/TextToSpeechOpenAiLike.d.ts +0 -121
- package/types/generators/ThermalPrinter.d.ts +0 -193
- package/types/generators/Tick.d.ts +0 -83
- package/types/generators/Udp.d.ts +0 -120
- package/types/generators/VadGgml.d.ts +0 -260
- package/types/generators/VadOnnx.d.ts +0 -231
- package/types/generators/VadTraditional.d.ts +0 -138
- package/types/generators/VectorStore.d.ts +0 -257
- package/types/generators/Watchdog.d.ts +0 -107
- package/types/generators/WebCrawler.d.ts +0 -103
- package/types/generators/WebRtc.d.ts +0 -181
- package/types/generators/WebSocket.d.ts +0 -148
- package/types/generators/index.d.ts +0 -57
- package/types/index.d.ts +0 -13
- package/types/subspace.d.ts +0 -60
- package/types/switch.d.ts +0 -51
- package/types/system.d.ts +0 -707
- package/utils/__tests__/calc.test.js +0 -25
- package/utils/__tests__/id.test.js +0 -154
- package/utils/calc.ts +0 -130
- package/utils/data.ts +0 -495
- package/utils/event-props.ts +0 -912
- package/utils/id.ts +0 -133
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { buildGGUFSplitFiles } from '../huggingface'
|
|
2
|
-
|
|
3
|
-
declare const describe: (name: string, fn: () => void) => void
|
|
4
|
-
declare const it: (name: string, fn: () => void) => void
|
|
5
|
-
declare const expect: (actual: unknown) => { toEqual: (expected: unknown) => void }
|
|
6
|
-
|
|
7
|
-
describe('buildGGUFSplitFiles', () => {
|
|
8
|
-
it('builds split GGUF files with indexed sibling metadata lookup', () => {
|
|
9
|
-
const siblings = [
|
|
10
|
-
{
|
|
11
|
-
rfilename: 'other-file.txt',
|
|
12
|
-
size: 999,
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
rfilename: 'model-00001-of-00003.gguf',
|
|
16
|
-
size: 1,
|
|
17
|
-
lfs: { sha256: 'one' },
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
rfilename: 'model-00002-of-00003.gguf',
|
|
21
|
-
size: 2,
|
|
22
|
-
lfs: { sha256: 'two' },
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
rfilename: 'model-00002-of-00003.gguf',
|
|
26
|
-
size: 22,
|
|
27
|
-
lfs: { sha256: 'two-late' },
|
|
28
|
-
},
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
expect(buildGGUFSplitFiles('model-00001-of-00003.gguf', '00003', siblings)).toEqual([
|
|
32
|
-
{
|
|
33
|
-
rfilename: 'model-00001-of-00003.gguf',
|
|
34
|
-
size: 1,
|
|
35
|
-
lfs: { sha256: 'one' },
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
rfilename: 'model-00002-of-00003.gguf',
|
|
39
|
-
size: 2,
|
|
40
|
-
lfs: { sha256: 'two' },
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
rfilename: 'model-00003-of-00003.gguf',
|
|
44
|
-
size: undefined,
|
|
45
|
-
lfs: undefined,
|
|
46
|
-
},
|
|
47
|
-
])
|
|
48
|
-
})
|
|
49
|
-
})
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { searchIcons } from '../icons'
|
|
2
|
-
|
|
3
|
-
declare const describe: (name: string, fn: () => void) => void
|
|
4
|
-
declare const test: (name: string, fn: () => void) => void
|
|
5
|
-
declare const expect: (actual: unknown) => {
|
|
6
|
-
toBe: (expected: unknown) => void
|
|
7
|
-
toHaveLength: (expected: number) => void
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
describe('icon_search helpers', () => {
|
|
11
|
-
test('searches the selected style corpus directly', () => {
|
|
12
|
-
const results = searchIcons('x', 10, 'brands')
|
|
13
|
-
|
|
14
|
-
expect(results).toHaveLength(10)
|
|
15
|
-
expect(results.every((result) => result.item.styles.includes('brands'))).toBe(true)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
test('keeps unstyled searches capped by limit', () => {
|
|
19
|
-
expect(searchIcons('arrow', 5)).toHaveLength(5)
|
|
20
|
-
})
|
|
21
|
-
})
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { isTruthyEnv, shouldRegisterEditingTools } from '../../mcp-env'
|
|
2
|
-
|
|
3
|
-
describe('mcp env helpers', () => {
|
|
4
|
-
test('recognizes explicit truthy env values', () => {
|
|
5
|
-
for (const value of ['1', 'true', 'TRUE', 'yes', 'on', ' on ']) {
|
|
6
|
-
expect(isTruthyEnv(value)).toBe(true)
|
|
7
|
-
}
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
test('does not enable editing tools by default', () => {
|
|
11
|
-
expect(shouldRegisterEditingTools({})).toBe(false)
|
|
12
|
-
expect(shouldRegisterEditingTools({ BRICKS_CTOR_ENABLE_EDITING_TOOLS: '0' })).toBe(false)
|
|
13
|
-
expect(shouldRegisterEditingTools({ BRICKS_CTOR_ENABLE_EDITING_TOOLS: 'false' })).toBe(false)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
test('enables editing tools when explicitly requested', () => {
|
|
17
|
-
expect(shouldRegisterEditingTools({ BRICKS_CTOR_ENABLE_EDITING_TOOLS: '1' })).toBe(true)
|
|
18
|
-
})
|
|
19
|
-
})
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import * as t from '@babel/types'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
|
|
4
|
-
export const oxfmtOptions = {
|
|
5
|
-
trailingComma: 'all',
|
|
6
|
-
tabWidth: 2,
|
|
7
|
-
semi: false,
|
|
8
|
-
singleQuote: true,
|
|
9
|
-
printWidth: 100,
|
|
10
|
-
} as const
|
|
11
|
-
|
|
12
|
-
export const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
13
|
-
Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
|
14
|
-
|
|
15
|
-
export const isIdentifierName = (value: string) => /^[$A-Z_a-z][$\w]*$/.test(value)
|
|
16
|
-
|
|
17
|
-
export const normalizeRelPath = (file: string) => file.replace(/\\/g, '/').replace(/^\.\/+/, '')
|
|
18
|
-
|
|
19
|
-
export const projectRelativePath = (projectDir: string, absPath: string) =>
|
|
20
|
-
normalizeRelPath(path.relative(projectDir, absPath))
|
|
21
|
-
|
|
22
|
-
export const getPropertyKeyName = (key: t.Expression | t.PrivateName) => {
|
|
23
|
-
if (t.isIdentifier(key)) return key.name
|
|
24
|
-
if (t.isStringLiteral(key) || t.isNumericLiteral(key)) return String(key.value)
|
|
25
|
-
return null
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const makeObjectKey = (key: string) =>
|
|
29
|
-
isIdentifierName(key) ? t.identifier(key) : t.stringLiteral(key)
|
|
30
|
-
|
|
31
|
-
export const getObjectProperty = (object: t.ObjectExpression, key: string) =>
|
|
32
|
-
object.properties.find((property): property is t.ObjectProperty => {
|
|
33
|
-
if (!t.isObjectProperty(property)) return false
|
|
34
|
-
return getPropertyKeyName(property.key) === key
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
export const getStringProperty = (object: t.ObjectExpression, key: string) => {
|
|
38
|
-
const property = getObjectProperty(object, key)
|
|
39
|
-
if (!property || !t.isStringLiteral(property.value)) return undefined
|
|
40
|
-
return property.value.value
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export const setObjectProperty = (object: t.ObjectExpression, key: string, value: t.Expression) => {
|
|
44
|
-
const existing = getObjectProperty(object, key)
|
|
45
|
-
if (existing) {
|
|
46
|
-
existing.value = value
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
object.properties.push(t.objectProperty(makeObjectKey(key), value))
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const removeObjectProperty = (object: t.ObjectExpression, key: string) => {
|
|
53
|
-
const index = object.properties.findIndex((property) => {
|
|
54
|
-
if (!t.isObjectProperty(property)) return false
|
|
55
|
-
return getPropertyKeyName(property.key) === key
|
|
56
|
-
})
|
|
57
|
-
if (index >= 0) object.properties.splice(index, 1)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export const insertImport = (ast: t.File, declaration: t.ImportDeclaration) => {
|
|
61
|
-
const body = ast.program.body
|
|
62
|
-
const lastImportIndex = body.findLastIndex((statement) => t.isImportDeclaration(statement))
|
|
63
|
-
body.splice(lastImportIndex + 1, 0, declaration)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export const ensureBricksCtorImport = (
|
|
67
|
-
ast: t.File,
|
|
68
|
-
importKind: 'type' | 'value',
|
|
69
|
-
names: Iterable<string>,
|
|
70
|
-
) => {
|
|
71
|
-
const missing = new Set(Array.from(names).filter(Boolean))
|
|
72
|
-
if (missing.size === 0) return
|
|
73
|
-
|
|
74
|
-
for (const statement of ast.program.body) {
|
|
75
|
-
if (!t.isImportDeclaration(statement) || statement.source.value !== 'bricks-ctor') continue
|
|
76
|
-
const isTypeImport = statement.importKind === 'type'
|
|
77
|
-
if ((importKind === 'type') !== isTypeImport) continue
|
|
78
|
-
|
|
79
|
-
statement.specifiers.forEach((specifier) => {
|
|
80
|
-
if (!t.isImportSpecifier(specifier)) return
|
|
81
|
-
const imported = specifier.imported
|
|
82
|
-
if (t.isIdentifier(imported)) missing.delete(imported.name)
|
|
83
|
-
if (t.isStringLiteral(imported)) missing.delete(imported.value)
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
missing.forEach((name) => {
|
|
87
|
-
statement.specifiers.push(t.importSpecifier(t.identifier(name), t.identifier(name)))
|
|
88
|
-
})
|
|
89
|
-
return
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const declaration = t.importDeclaration(
|
|
93
|
-
Array.from(missing).map((name) => t.importSpecifier(t.identifier(name), t.identifier(name))),
|
|
94
|
-
t.stringLiteral('bricks-ctor'),
|
|
95
|
-
)
|
|
96
|
-
if (importKind === 'type') declaration.importKind = 'type'
|
|
97
|
-
insertImport(ast, declaration)
|
|
98
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { sh } from '../_shell'
|
|
2
|
-
import { computeConfigChange, readBuildConfig, type ConfigChange } from '../../compile/config-diff'
|
|
3
|
-
|
|
4
|
-
// Result of an editing tool's compile verification, carrying the config delta the
|
|
5
|
-
// compile produced. Shared by entry-editing and data-calc-editing.
|
|
6
|
-
export type VerificationResult = {
|
|
7
|
-
status: 'skipped' | 'compile:ok' | 'compile:failed'
|
|
8
|
-
errors: string[]
|
|
9
|
-
configChange?: ConfigChange
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Strip ANSI colors from the spawned compile so the captured output stays plain text.
|
|
13
|
-
const noColorEnv = { FORCE_COLOR: '0', NO_COLOR: '1' }
|
|
14
|
-
|
|
15
|
-
// Recompile the project and diff the result against the prior build artifact.
|
|
16
|
-
export const compileAndDiff = async (projectDir: string): Promise<VerificationResult> => {
|
|
17
|
-
// Snapshot the prior compiled config before recompiling (the new artifact overwrites it).
|
|
18
|
-
const before = await readBuildConfig(projectDir)
|
|
19
|
-
try {
|
|
20
|
-
// Turn off the editing-tools audit for this spawned compile so compile() doesn't write
|
|
21
|
-
// a duplicate generic entry — the calling editing tool records its own richer entry.
|
|
22
|
-
await sh`bun compile`
|
|
23
|
-
.cwd(projectDir)
|
|
24
|
-
.env({ ...noColorEnv, BRICKS_CTOR_ENABLE_EDITING_TOOLS: '0' })
|
|
25
|
-
.text()
|
|
26
|
-
} catch (err: any) {
|
|
27
|
-
const stdout = err.stdout?.toString() ?? ''
|
|
28
|
-
const stderr = err.stderr?.toString() ?? ''
|
|
29
|
-
const output = [stdout, stderr, err.message].filter(Boolean).join('\n').trim()
|
|
30
|
-
return { status: 'compile:failed', errors: output ? [output] : ['bun compile failed'] }
|
|
31
|
-
}
|
|
32
|
-
const after = await readBuildConfig(projectDir)
|
|
33
|
-
return { status: 'compile:ok', errors: [], configChange: computeConfigChange(before, after) }
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const shouldVerify = (inputVerify?: boolean) => {
|
|
37
|
-
if (inputVerify !== undefined) return inputVerify
|
|
38
|
-
const value = process.env.BRICKS_CTOR_MCP_EDIT_VERIFY ?? 'true'
|
|
39
|
-
return !['0', 'false', 'no', 'off'].includes(value.toLowerCase())
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Compile verification shared by the source-editing tools: per-call `verify` wins,
|
|
43
|
-
// then the BRICKS_CTOR_MCP_EDIT_VERIFY env toggle, defaulting to on.
|
|
44
|
-
export const verifyProject = async (
|
|
45
|
-
projectDir: string,
|
|
46
|
-
verify?: boolean,
|
|
47
|
-
): Promise<VerificationResult> => {
|
|
48
|
-
if (!shouldVerify(verify)) return { status: 'skipped', errors: [] }
|
|
49
|
-
return compileAndDiff(projectDir)
|
|
50
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
2
|
-
import { readFile } from 'node:fs/promises'
|
|
3
|
-
import { z } from 'zod'
|
|
4
|
-
import { sh } from '../_shell'
|
|
5
|
-
|
|
6
|
-
// Disable ANSI color codes from spawned tools so MCP text output stays readable
|
|
7
|
-
// (the host renders raw text; escape sequences leak into the result otherwise).
|
|
8
|
-
const noColorEnv = { FORCE_COLOR: '0', NO_COLOR: '1' }
|
|
9
|
-
|
|
10
|
-
export function register(server: McpServer, projectDir: string) {
|
|
11
|
-
const { dirname } = import.meta
|
|
12
|
-
|
|
13
|
-
// `bun compile` records the resulting config delta to `.bricks/edits.jsonl` itself
|
|
14
|
-
// (see compile() in compile/index.ts), so the spawned output below already reflects it.
|
|
15
|
-
server.tool('compile', {}, async () => {
|
|
16
|
-
let log = 'Type checking & Compiling...\n'
|
|
17
|
-
try {
|
|
18
|
-
log += await sh`bun compile`.cwd(projectDir).env(noColorEnv).text()
|
|
19
|
-
} catch (err: any) {
|
|
20
|
-
const stdout = err.stdout?.toString() ?? ''
|
|
21
|
-
const stderr = err.stderr?.toString() ?? ''
|
|
22
|
-
log += [stdout, stderr].filter(Boolean).join('\n')
|
|
23
|
-
}
|
|
24
|
-
return {
|
|
25
|
-
content: [{ type: 'text', text: log }],
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
if (process.env.BRICKS_CTOR_MCP_DISABLE_PREVIEW === '1') return
|
|
30
|
-
|
|
31
|
-
server.tool(
|
|
32
|
-
'simulator',
|
|
33
|
-
{
|
|
34
|
-
delay: z
|
|
35
|
-
.number()
|
|
36
|
-
.describe('Delay in milliseconds before taking screenshot')
|
|
37
|
-
.optional()
|
|
38
|
-
.default(3000),
|
|
39
|
-
width: z.number().describe('Width of the screenshot').optional().default(600),
|
|
40
|
-
height: z.number().optional().default(480),
|
|
41
|
-
responseImage: z
|
|
42
|
-
.boolean()
|
|
43
|
-
.describe(
|
|
44
|
-
'Whether to response image content (base64 encoded jpeg). If false, only saved path will be responded as text.',
|
|
45
|
-
)
|
|
46
|
-
.optional()
|
|
47
|
-
.default(false),
|
|
48
|
-
testId: z.string().describe('Automation test ID to trigger').optional(),
|
|
49
|
-
testTitleLike: z
|
|
50
|
-
.string()
|
|
51
|
-
.describe('Find automation test by partial title match (case-insensitive)')
|
|
52
|
-
.optional(),
|
|
53
|
-
} as any,
|
|
54
|
-
async ({ delay, width, height, responseImage, testId, testTitleLike }: any) => {
|
|
55
|
-
let log = ''
|
|
56
|
-
let error = false
|
|
57
|
-
try {
|
|
58
|
-
const toolsDir = `${dirname}/..`
|
|
59
|
-
const args = [
|
|
60
|
-
'--no-keep-open',
|
|
61
|
-
'--take-screenshot',
|
|
62
|
-
JSON.stringify({
|
|
63
|
-
delay,
|
|
64
|
-
width,
|
|
65
|
-
height,
|
|
66
|
-
path: `${toolsDir}/screenshot.jpg`,
|
|
67
|
-
closeAfter: true,
|
|
68
|
-
headless: true,
|
|
69
|
-
}),
|
|
70
|
-
]
|
|
71
|
-
if (testId) args.push('--test-id', testId)
|
|
72
|
-
if (testTitleLike) args.push('--test-title-like', testTitleLike)
|
|
73
|
-
log = await sh`bunx --bun electron ${toolsDir}/simulator-main.mjs ${args}`
|
|
74
|
-
.cwd(projectDir)
|
|
75
|
-
.env(noColorEnv)
|
|
76
|
-
.text()
|
|
77
|
-
} catch (err: any) {
|
|
78
|
-
const stdout = err.stdout?.toString() ?? ''
|
|
79
|
-
const stderr = err.stderr?.toString() ?? ''
|
|
80
|
-
log = [stdout, stderr].filter(Boolean).join('\n')
|
|
81
|
-
error = true
|
|
82
|
-
}
|
|
83
|
-
let screenshotBase64: string | null = null
|
|
84
|
-
if (!error && responseImage) {
|
|
85
|
-
const toolsDir = `${dirname}/..`
|
|
86
|
-
const screenshot = await readFile(`${toolsDir}/screenshot.jpg`)
|
|
87
|
-
screenshotBase64 = screenshot.toString('base64')
|
|
88
|
-
}
|
|
89
|
-
const content: Array<
|
|
90
|
-
{ type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string }
|
|
91
|
-
> = [{ type: 'text', text: log }]
|
|
92
|
-
if (screenshotBase64) {
|
|
93
|
-
content.push({
|
|
94
|
-
type: 'image',
|
|
95
|
-
data: screenshotBase64,
|
|
96
|
-
mimeType: 'image/jpeg',
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
return {
|
|
100
|
-
content,
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
)
|
|
104
|
-
}
|