@fugood/bricks-project 2.22.0-beta.2 → 2.22.0-beta.22
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 +146 -1
- package/compile/index.ts +1 -0
- package/package.json +3 -2
- package/tools/mcp-server.ts +86 -0
- package/tools/postinstall.ts +63 -5
- package/tools/preview-main.mjs +13 -7
- package/tools/preview.ts +31 -25
- package/types/bricks.ts +105 -2
- package/types/canvas.ts +1 -1
- package/types/common.ts +2 -2
- package/types/data.ts +6 -0
- package/types/generators.ts +1933 -231
- package/types/system.ts +42 -0
- package/utils/data.ts +18 -0
- package/utils/event-props.ts +185 -0
|
@@ -100,6 +100,9 @@ export const templateActionNameMap = {
|
|
|
100
100
|
payloadType: 'CHANNEL_PUBLISH_PAYLOAD_TYPE',
|
|
101
101
|
payload: 'CHANNEL_PUBLISH_PAYLOAD',
|
|
102
102
|
},
|
|
103
|
+
DELAY: {
|
|
104
|
+
time: 'DELAY_TIME',
|
|
105
|
+
},
|
|
103
106
|
USE_SHARE_APPLICATION: {
|
|
104
107
|
applicationId: 'APPLICATION_ID',
|
|
105
108
|
releaseVersion: 'RELEASE_VERSION',
|
|
@@ -126,6 +129,12 @@ export const templateActionNameMap = {
|
|
|
126
129
|
behavior: 'BEHAVIOR',
|
|
127
130
|
exceptionMessage: 'EXCEPTION_MESSAGE',
|
|
128
131
|
},
|
|
132
|
+
TRIGGER_APPLICATION_FILTER: {
|
|
133
|
+
name: 'NAME',
|
|
134
|
+
variables: 'VARIABLES',
|
|
135
|
+
result: 'RESULT',
|
|
136
|
+
error: 'ERROR',
|
|
137
|
+
},
|
|
129
138
|
},
|
|
130
139
|
|
|
131
140
|
BRICK_TEXT_INPUT: {
|
|
@@ -142,6 +151,13 @@ export const templateActionNameMap = {
|
|
|
142
151
|
},
|
|
143
152
|
},
|
|
144
153
|
|
|
154
|
+
BRICK_VIDEO: {
|
|
155
|
+
BRICK_VIDEO_SEEK: {
|
|
156
|
+
seekTime: 'BRICK_VIDEO_SEEK_TIME',
|
|
157
|
+
play: 'BRICK_VIDEO_PLAY',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
|
|
145
161
|
BRICK_SLIDESHOW: {
|
|
146
162
|
BRICK_SLIDESHOW_JUMP_TO_INDEX: {
|
|
147
163
|
index: 'BRICK_SLIDESHOW_INDEX',
|
|
@@ -231,7 +247,12 @@ export const templateActionNameMap = {
|
|
|
231
247
|
index: 'BRICK_ITEMS_INDEX',
|
|
232
248
|
},
|
|
233
249
|
},
|
|
234
|
-
|
|
250
|
+
BRICK_LOTTIE: {
|
|
251
|
+
BRICK_LOTTIE_PLAY: {
|
|
252
|
+
startFrame: 'BRICK_LOTTIE_START_FRAME',
|
|
253
|
+
endFrame: 'BRICK_LOTTIE_END_FRAME',
|
|
254
|
+
},
|
|
255
|
+
},
|
|
235
256
|
BRICK_RIVE: {
|
|
236
257
|
BRICK_RIVE_PLAY: {
|
|
237
258
|
animationName: 'BRICK_RIVE_ANIMATION_NAME',
|
|
@@ -257,6 +278,10 @@ export const templateActionNameMap = {
|
|
|
257
278
|
BRICK_WEBVIEW_INJECT_JAVASCRIPT: {
|
|
258
279
|
javascriptCode: 'BRICK_WEBVIEW_JAVASCRIPT_CODE',
|
|
259
280
|
},
|
|
281
|
+
BRICK_WEBVIEW_QUERY_SELECTOR: {
|
|
282
|
+
querySelector: 'BRICK_WEBVIEW_QUERY_SELECTOR',
|
|
283
|
+
expression: 'BRICK_WEBVIEW_EXPRESSION',
|
|
284
|
+
},
|
|
260
285
|
},
|
|
261
286
|
BRICK_CAMERA: {
|
|
262
287
|
BRICK_CAMERA_TAKE_PICTURE: {
|
|
@@ -512,6 +537,36 @@ export const templateActionNameMap = {
|
|
|
512
537
|
paramsString: 'GENERATOR_SQLITE_PARAMS_STRING',
|
|
513
538
|
},
|
|
514
539
|
},
|
|
540
|
+
|
|
541
|
+
GENERATOR_MCP: {
|
|
542
|
+
GENERATOR_MCP_LIST_RESOURCES: {
|
|
543
|
+
requestId: 'GENERATOR_MCP_REQUEST_ID',
|
|
544
|
+
},
|
|
545
|
+
GENERATOR_MCP_LIST_RESOURCE_TEMPLATES: {
|
|
546
|
+
requestId: 'GENERATOR_MCP_REQUEST_ID',
|
|
547
|
+
},
|
|
548
|
+
GENERATOR_MCP_READ_RESOURCE: {
|
|
549
|
+
requestId: 'GENERATOR_MCP_REQUEST_ID',
|
|
550
|
+
uri: 'GENERATOR_MCP_URI',
|
|
551
|
+
variables: 'GENERATOR_MCP_VARIABLES',
|
|
552
|
+
},
|
|
553
|
+
GENERATOR_MCP_LIST_TOOLS: {
|
|
554
|
+
requestId: 'GENERATOR_MCP_REQUEST_ID',
|
|
555
|
+
},
|
|
556
|
+
GENERATOR_MCP_CALL_TOOL: {
|
|
557
|
+
requestId: 'GENERATOR_MCP_REQUEST_ID',
|
|
558
|
+
name: 'GENERATOR_MCP_NAME',
|
|
559
|
+
variables: 'GENERATOR_MCP_VARIABLES',
|
|
560
|
+
},
|
|
561
|
+
GENERATOR_MCP_LIST_PROMPTS: {
|
|
562
|
+
requestId: 'GENERATOR_MCP_REQUEST_ID',
|
|
563
|
+
},
|
|
564
|
+
GENERATOR_MCP_GET_PROMPT: {
|
|
565
|
+
requestId: 'GENERATOR_MCP_REQUEST_ID',
|
|
566
|
+
name: 'GENERATOR_MCP_NAME',
|
|
567
|
+
variables: 'GENERATOR_MCP_VARIABLES',
|
|
568
|
+
},
|
|
569
|
+
},
|
|
515
570
|
GENERATOR_TTS: {
|
|
516
571
|
GENERATOR_TTS_GENERATE: {
|
|
517
572
|
text: 'GENERATOR_TTS_TEXT',
|
|
@@ -521,6 +576,9 @@ export const templateActionNameMap = {
|
|
|
521
576
|
GENERATOR_ONNX_LLM_INFER: {
|
|
522
577
|
prompt: 'GENERATOR_ONNX_LLM_PROMPT',
|
|
523
578
|
chat: 'GENERATOR_ONNX_LLM_CHAT',
|
|
579
|
+
images: 'GENERATOR_ONNX_LLM_IMAGES',
|
|
580
|
+
tools: 'GENERATOR_ONNX_LLM_TOOLS',
|
|
581
|
+
toolChoice: 'GENERATOR_ONNX_LLM_TOOL_CHOICE',
|
|
524
582
|
},
|
|
525
583
|
},
|
|
526
584
|
GENERATOR_ONNX_STT: {
|
|
@@ -558,7 +616,37 @@ export const templateActionNameMap = {
|
|
|
558
616
|
realtimeVadFreqThold: 'GENERATOR_SPEECH_INFERENCE_REALTIME_VAD_FREQ_THOLD',
|
|
559
617
|
},
|
|
560
618
|
},
|
|
619
|
+
GENERATOR_VAD_INFERENCE: {
|
|
620
|
+
GENERATOR_VAD_INFERENCE_DETECT_FILE: {
|
|
621
|
+
fileUrl: 'GENERATOR_VAD_INFERENCE_FILE_URL',
|
|
622
|
+
threshold: 'GENERATOR_VAD_INFERENCE_THRESHOLD',
|
|
623
|
+
minSpeechDurationMs: 'GENERATOR_VAD_INFERENCE_MIN_SPEECH_DURATION_MS',
|
|
624
|
+
minSilenceDurationMs: 'GENERATOR_VAD_INFERENCE_MIN_SILENCE_DURATION_MS',
|
|
625
|
+
maxSpeechDurationS: 'GENERATOR_VAD_INFERENCE_MAX_SPEECH_DURATION_S',
|
|
626
|
+
speechPadMs: 'GENERATOR_VAD_INFERENCE_SPEECH_PAD_MS',
|
|
627
|
+
samplesOverlap: 'GENERATOR_VAD_INFERENCE_SAMPLES_OVERLAP',
|
|
628
|
+
},
|
|
629
|
+
GENERATOR_VAD_INFERENCE_DETECT_DATA: {
|
|
630
|
+
data: 'GENERATOR_VAD_INFERENCE_DATA',
|
|
631
|
+
threshold: 'GENERATOR_VAD_INFERENCE_THRESHOLD',
|
|
632
|
+
minSpeechDurationMs: 'GENERATOR_VAD_INFERENCE_MIN_SPEECH_DURATION_MS',
|
|
633
|
+
minSilenceDurationMs: 'GENERATOR_VAD_INFERENCE_MIN_SILENCE_DURATION_MS',
|
|
634
|
+
maxSpeechDurationS: 'GENERATOR_VAD_INFERENCE_MAX_SPEECH_DURATION_S',
|
|
635
|
+
speechPadMs: 'GENERATOR_VAD_INFERENCE_SPEECH_PAD_MS',
|
|
636
|
+
samplesOverlap: 'GENERATOR_VAD_INFERENCE_SAMPLES_OVERLAP',
|
|
637
|
+
},
|
|
638
|
+
},
|
|
639
|
+
|
|
561
640
|
GENERATOR_LLM: {
|
|
641
|
+
GENERATOR_LLM_TOKENIZE: {
|
|
642
|
+
mode: 'GENERATOR_LLM_MODE',
|
|
643
|
+
prompt: 'GENERATOR_LLM_PROMPT',
|
|
644
|
+
promptMediaPaths: 'GENERATOR_LLM_PROMPT_MEDIA_PATHS',
|
|
645
|
+
messages: 'GENERATOR_LLM_MESSAGES',
|
|
646
|
+
},
|
|
647
|
+
GENERATOR_LLM_DETOKENIZE: {
|
|
648
|
+
tokens: 'GENERATOR_LLM_TOKENS',
|
|
649
|
+
},
|
|
562
650
|
GENERATOR_LLM_PROCESS_PROMPT: {
|
|
563
651
|
sessionKey: 'GENERATOR_LLM_SESSION_KEY',
|
|
564
652
|
mode: 'GENERATOR_LLM_MODE',
|
|
@@ -566,7 +654,9 @@ export const templateActionNameMap = {
|
|
|
566
654
|
tools: 'GENERATOR_LLM_TOOLS',
|
|
567
655
|
parallelToolCalls: 'GENERATOR_LLM_PARALLEL_TOOL_CALLS',
|
|
568
656
|
toolChoice: 'GENERATOR_LLM_TOOL_CHOICE',
|
|
657
|
+
enableThinking: 'GENERATOR_LLM_ENABLE_THINKING',
|
|
569
658
|
prompt: 'GENERATOR_LLM_PROMPT',
|
|
659
|
+
promptMediaPaths: 'GENERATOR_LLM_PROMPT_MEDIA_PATHS',
|
|
570
660
|
promptTemplateData: 'GENERATOR_LLM_PROMPT_TEMPLATE_DATA',
|
|
571
661
|
promptTemplateType: 'GENERATOR_LLM_PROMPT_TEMPLATE_TYPE',
|
|
572
662
|
responseFormat: 'GENERATOR_LLM_RESPONSE_FORMAT',
|
|
@@ -578,7 +668,9 @@ export const templateActionNameMap = {
|
|
|
578
668
|
tools: 'GENERATOR_LLM_TOOLS',
|
|
579
669
|
parallelToolCalls: 'GENERATOR_LLM_PARALLEL_TOOL_CALLS',
|
|
580
670
|
toolChoice: 'GENERATOR_LLM_TOOL_CHOICE',
|
|
671
|
+
enableThinking: 'GENERATOR_LLM_ENABLE_THINKING',
|
|
581
672
|
prompt: 'GENERATOR_LLM_PROMPT',
|
|
673
|
+
promptMediaPaths: 'GENERATOR_LLM_PROMPT_MEDIA_PATHS',
|
|
582
674
|
promptTemplateData: 'GENERATOR_LLM_PROMPT_TEMPLATE_DATA',
|
|
583
675
|
promptTemplateType: 'GENERATOR_LLM_PROMPT_TEMPLATE_TYPE',
|
|
584
676
|
responseFormat: 'GENERATOR_LLM_RESPONSE_FORMAT',
|
|
@@ -615,6 +707,24 @@ export const templateActionNameMap = {
|
|
|
615
707
|
sessionCustomKey: 'GENERATOR_LLM_SESSION_CUSTOM_KEY',
|
|
616
708
|
},
|
|
617
709
|
},
|
|
710
|
+
GENERATOR_GGML_TTS: {
|
|
711
|
+
GENERATOR_GGML_TTS_GENERATE: {
|
|
712
|
+
text: 'GENERATOR_GGML_TTS_TEXT',
|
|
713
|
+
},
|
|
714
|
+
},
|
|
715
|
+
GENERATOR_RERANKER: {
|
|
716
|
+
GENERATOR_RERANKER_RERANK: {
|
|
717
|
+
query: 'GENERATOR_RERANKER_QUERY',
|
|
718
|
+
documents: 'GENERATOR_RERANKER_DOCUMENTS',
|
|
719
|
+
},
|
|
720
|
+
},
|
|
721
|
+
GENERATOR_QNN_LLM: {
|
|
722
|
+
GENERATOR_QNN_LLM_GENERATE: {
|
|
723
|
+
prompt: 'GENERATOR_QNN_LLM_PROMPT',
|
|
724
|
+
messages: 'GENERATOR_QNN_LLM_MESSAGES',
|
|
725
|
+
tools: 'GENERATOR_QNN_LLM_TOOLS',
|
|
726
|
+
},
|
|
727
|
+
},
|
|
618
728
|
GENERATOR_OPENAI_LLM: {
|
|
619
729
|
GENERATOR_OPENAI_LLM_COMPLETION: {
|
|
620
730
|
messages: 'GENERATOR_OPENAI_LLM_MESSAGES',
|
|
@@ -630,10 +740,16 @@ export const templateActionNameMap = {
|
|
|
630
740
|
responseFormat: 'GENERATOR_OPENAI_LLM_RESPONSE_FORMAT',
|
|
631
741
|
},
|
|
632
742
|
},
|
|
743
|
+
GENERATOR_OPENAI_TTS: {
|
|
744
|
+
GENERATOR_OPENAI_TTS_GENERATE: {
|
|
745
|
+
text: 'GENERATOR_OPENAI_TTS_TEXT',
|
|
746
|
+
},
|
|
747
|
+
},
|
|
633
748
|
GENERATOR_ASSISTANT: {
|
|
634
749
|
GENERATOR_ASSISTANT_ADD_MESSAGE: {
|
|
635
750
|
role: 'GENERATOR_ASSISTANT_ROLE',
|
|
636
751
|
content: 'GENERATOR_ASSISTANT_CONTENT',
|
|
752
|
+
image: 'GENERATOR_ASSISTANT_IMAGE',
|
|
637
753
|
payload: 'GENERATOR_ASSISTANT_PAYLOAD',
|
|
638
754
|
useFileSearch: 'GENERATOR_ASSISTANT_USE_FILE_SEARCH',
|
|
639
755
|
filePath: 'GENERATOR_ASSISTANT_FILE_PATH',
|
|
@@ -643,15 +759,28 @@ export const templateActionNameMap = {
|
|
|
643
759
|
fileSearchCitationCount: 'GENERATOR_ASSISTANT_FILE_SEARCH_CITATION_COUNT',
|
|
644
760
|
fileSearchInsertMethod: 'GENERATOR_ASSISTANT_FILE_SEARCH_INSERT_METHOD',
|
|
645
761
|
},
|
|
762
|
+
GENERATOR_ASSISTANT_INIT_MCP_PROMPT: {
|
|
763
|
+
mcpClientName: 'GENERATOR_ASSISTANT_MCP_CLIENT_NAME',
|
|
764
|
+
mcpPromptName: 'GENERATOR_ASSISTANT_MCP_PROMPT_NAME',
|
|
765
|
+
mcpArguments: 'GENERATOR_ASSISTANT_MCP_ARGUMENTS',
|
|
766
|
+
firstMessageAsSystem: 'GENERATOR_ASSISTANT_FIRST_MESSAGE_AS_SYSTEM',
|
|
767
|
+
},
|
|
768
|
+
GENERATOR_ASSISTANT_ADD_MCP_PROMPT_MESSAGE: {
|
|
769
|
+
mcpClientName: 'GENERATOR_ASSISTANT_MCP_CLIENT_NAME',
|
|
770
|
+
mcpPromptName: 'GENERATOR_ASSISTANT_MCP_PROMPT_NAME',
|
|
771
|
+
mcpArguments: 'GENERATOR_ASSISTANT_MCP_ARGUMENTS',
|
|
772
|
+
},
|
|
646
773
|
GENERATOR_ASSISTANT_UPDATE_MESSAGE_AT_INDEX: {
|
|
647
774
|
index: 'GENERATOR_ASSISTANT_INDEX',
|
|
648
775
|
content: 'GENERATOR_ASSISTANT_CONTENT',
|
|
776
|
+
image: 'GENERATOR_ASSISTANT_IMAGE',
|
|
649
777
|
payload: 'GENERATOR_ASSISTANT_PAYLOAD',
|
|
650
778
|
},
|
|
651
779
|
GENERATOR_ASSISTANT_ADD_AUDIO_MESSAGE: {
|
|
652
780
|
role: 'GENERATOR_ASSISTANT_ROLE',
|
|
653
781
|
contentFile: 'GENERATOR_ASSISTANT_CONTENT_FILE',
|
|
654
782
|
contentBase64: 'GENERATOR_ASSISTANT_CONTENT_BASE64',
|
|
783
|
+
image: 'GENERATOR_ASSISTANT_IMAGE',
|
|
655
784
|
useFileSearch: 'GENERATOR_ASSISTANT_USE_FILE_SEARCH',
|
|
656
785
|
payload: 'GENERATOR_ASSISTANT_PAYLOAD',
|
|
657
786
|
filePath: 'GENERATOR_ASSISTANT_FILE_PATH',
|
|
@@ -674,11 +803,27 @@ export const templateActionNameMap = {
|
|
|
674
803
|
index: 'GENERATOR_ASSISTANT_INDEX',
|
|
675
804
|
contentFile: 'GENERATOR_ASSISTANT_CONTENT_FILE',
|
|
676
805
|
contentBase64: 'GENERATOR_ASSISTANT_CONTENT_BASE64',
|
|
806
|
+
image: 'GENERATOR_ASSISTANT_IMAGE',
|
|
677
807
|
payload: 'GENERATOR_ASSISTANT_PAYLOAD',
|
|
678
808
|
},
|
|
679
809
|
GENERATOR_ASSISTANT_REMOVE_MESSAGE_AT_INDEX: {
|
|
680
810
|
index: 'GENERATOR_ASSISTANT_INDEX',
|
|
681
811
|
},
|
|
812
|
+
GENERATOR_ASSISTANT_SUBMIT: {
|
|
813
|
+
continueOnToolCallConfirm: 'GENERATOR_ASSISTANT_CONTINUE_ON_TOOL_CALL_CONFIRM',
|
|
814
|
+
continueOnToolCallStrategy: 'GENERATOR_ASSISTANT_CONTINUE_ON_TOOL_CALL_STRATEGY',
|
|
815
|
+
continueOnToolCallLimit: 'GENERATOR_ASSISTANT_CONTINUE_ON_TOOL_CALL_LIMIT',
|
|
816
|
+
},
|
|
817
|
+
GENERATOR_ASSISTANT_INSERT_MCP_RESOURCE: {
|
|
818
|
+
mcpClientName: 'GENERATOR_ASSISTANT_MCP_CLIENT_NAME',
|
|
819
|
+
mcpResourceUri: 'GENERATOR_ASSISTANT_MCP_RESOURCE_URI',
|
|
820
|
+
mcpVariables: 'GENERATOR_ASSISTANT_MCP_VARIABLES',
|
|
821
|
+
role: 'GENERATOR_ASSISTANT_ROLE',
|
|
822
|
+
},
|
|
823
|
+
GENERATOR_ASSISTANT_SUMMARY_MESSAGES: {
|
|
824
|
+
summaryMessages: 'GENERATOR_ASSISTANT_SUMMARY_MESSAGES',
|
|
825
|
+
summarySessionKey: 'GENERATOR_ASSISTANT_SUMMARY_SESSION_KEY',
|
|
826
|
+
},
|
|
682
827
|
},
|
|
683
828
|
GENERATOR_VECTOR_STORE: {
|
|
684
829
|
GENERATOR_VECTOR_STORE_RESET: {
|
package/compile/index.ts
CHANGED
|
@@ -856,6 +856,7 @@ export const compile = async (app: Application) => {
|
|
|
856
856
|
fonts: app.fonts,
|
|
857
857
|
...compileApplicationSettings(app.settings),
|
|
858
858
|
test_map: app.metadata?.TEMP_test_map || {},
|
|
859
|
+
automation_map: app.metadata?.TEMP_automation_map || {},
|
|
859
860
|
}
|
|
860
861
|
return config
|
|
861
862
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fugood/bricks-project",
|
|
3
|
-
"version": "2.22.0-beta.
|
|
3
|
+
"version": "2.22.0-beta.22",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "node scripts/build.js"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
+
"@modelcontextprotocol/sdk": "^1.15.0",
|
|
9
10
|
"@types/escodegen": "^0.0.10",
|
|
10
11
|
"@types/lodash": "^4.17.12",
|
|
11
12
|
"acorn": "^8.13.0",
|
|
@@ -13,5 +14,5 @@
|
|
|
13
14
|
"lodash": "^4.17.4",
|
|
14
15
|
"uuid": "^8.3.1"
|
|
15
16
|
},
|
|
16
|
-
"gitHead": "
|
|
17
|
+
"gitHead": "f1a67a715ee30aac5067df53b8b640511a81fc83"
|
|
17
18
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import { $ } from 'bun'
|
|
5
|
+
|
|
6
|
+
const server = new McpServer({
|
|
7
|
+
name: 'bricks-project',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const dirname = import.meta.dirname
|
|
12
|
+
const projectDir = String(dirname).split('/node_modules/')[0]
|
|
13
|
+
|
|
14
|
+
server.tool('compile', {}, async () => {
|
|
15
|
+
let log
|
|
16
|
+
try {
|
|
17
|
+
log = await $`bun compile`.cwd(projectDir).text()
|
|
18
|
+
} catch (err) {
|
|
19
|
+
log = err.stdout.toString() + '\n' + err.stderr.toString()
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: 'text', text: log || 'Compiled successfully' }],
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// NOTE: Cursor (Or VSCode) seems set ELECTRON_RUN_AS_NODE to 1, so we need to unset it
|
|
27
|
+
process.env.ELECTRON_RUN_AS_NODE = ''
|
|
28
|
+
|
|
29
|
+
server.tool(
|
|
30
|
+
'take-preview-screenshot',
|
|
31
|
+
{
|
|
32
|
+
delay: z
|
|
33
|
+
.number()
|
|
34
|
+
.describe('Delay in milliseconds before taking screenshot')
|
|
35
|
+
.optional()
|
|
36
|
+
.default(3000),
|
|
37
|
+
width: z.number().describe('Width of the screenshot').optional().default(600),
|
|
38
|
+
height: z.number().optional().default(480),
|
|
39
|
+
responseImage: z
|
|
40
|
+
.boolean()
|
|
41
|
+
.describe(
|
|
42
|
+
'Whether to response image content (base64 encoded jpeg). If false, only saved path will be responded as text.',
|
|
43
|
+
)
|
|
44
|
+
.optional()
|
|
45
|
+
.default(false),
|
|
46
|
+
} as any,
|
|
47
|
+
async ({ delay, width, height, responseImage }: any) => {
|
|
48
|
+
let log = ''
|
|
49
|
+
let error = false
|
|
50
|
+
try {
|
|
51
|
+
const args = [
|
|
52
|
+
'--take-screenshot',
|
|
53
|
+
JSON.stringify({
|
|
54
|
+
delay,
|
|
55
|
+
width,
|
|
56
|
+
height,
|
|
57
|
+
path: `${dirname}/screenshot.jpg`,
|
|
58
|
+
closeAfter: true,
|
|
59
|
+
headless: true,
|
|
60
|
+
}),
|
|
61
|
+
]
|
|
62
|
+
log = await $`bunx --bun electron ${dirname}/preview-main.mjs ${args}`.cwd(projectDir).text()
|
|
63
|
+
} catch (err) {
|
|
64
|
+
log = err.stdout.toString() + '\n' + err.stderr.toString()
|
|
65
|
+
error = true
|
|
66
|
+
}
|
|
67
|
+
let screenshotBase64: any = null
|
|
68
|
+
if (!error && responseImage) {
|
|
69
|
+
const screenshot = await Bun.file(`${dirname}/screenshot.jpg`).arrayBuffer()
|
|
70
|
+
screenshotBase64 = Buffer.from(screenshot).toString('base64')
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{ type: 'text', text: log },
|
|
75
|
+
screenshotBase64 && {
|
|
76
|
+
type: 'image',
|
|
77
|
+
data: screenshotBase64,
|
|
78
|
+
mimeType: 'image/jpeg',
|
|
79
|
+
},
|
|
80
|
+
].filter(Boolean),
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
const transport = new StdioServerTransport()
|
|
86
|
+
await server.connect(transport)
|
package/tools/postinstall.ts
CHANGED
|
@@ -1,12 +1,70 @@
|
|
|
1
1
|
import { $ } from 'bun'
|
|
2
|
+
import { stat, readFile, writeFile } from 'fs/promises'
|
|
2
3
|
|
|
3
4
|
const cwd = process.cwd()
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
async function exists(f: string) {
|
|
7
|
+
try {
|
|
8
|
+
await stat(f)
|
|
9
|
+
return true
|
|
10
|
+
} catch {
|
|
11
|
+
return false
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// handle flag --skip-copy
|
|
16
|
+
const skipCopyProject = process.argv.includes('--skip-copy-project')
|
|
17
|
+
if (skipCopyProject) {
|
|
18
|
+
console.log('Skipping copy of files to project/')
|
|
19
|
+
} else {
|
|
20
|
+
|
|
21
|
+
const libFiles = ['types', 'utils', 'index.ts']
|
|
22
|
+
|
|
23
|
+
await $`mkdir -p ${cwd}/project`
|
|
24
|
+
for (const file of libFiles) {
|
|
25
|
+
await $`cp -r ${__dirname}/../${file} ${cwd}/project`
|
|
26
|
+
}
|
|
27
|
+
console.log('Copied files to project/')
|
|
28
|
+
}
|
|
6
29
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
30
|
+
const projectMcpServer = {
|
|
31
|
+
command: 'bun',
|
|
32
|
+
args: [`${cwd}/node_modules/@fugood/bricks-project/tools/mcp-server.ts`],
|
|
10
33
|
}
|
|
11
34
|
|
|
12
|
-
|
|
35
|
+
const defaultMcpConfig = {
|
|
36
|
+
mcpServers: {
|
|
37
|
+
'bricks-project': projectMcpServer,
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const handleMcpConfigOverride = async (mcpConfigPath: string) => {
|
|
42
|
+
let mcpConfig: { mcpServers: Record<string, typeof projectMcpServer> } | null = null
|
|
43
|
+
if (await exists(mcpConfigPath)) {
|
|
44
|
+
const configStr = await readFile(mcpConfigPath, 'utf-8')
|
|
45
|
+
try {
|
|
46
|
+
mcpConfig = JSON.parse(configStr)
|
|
47
|
+
if (!mcpConfig?.mcpServers) throw new Error('mcpServers is not defined')
|
|
48
|
+
mcpConfig.mcpServers['bricks-project'] = projectMcpServer
|
|
49
|
+
} catch (e) {
|
|
50
|
+
mcpConfig = defaultMcpConfig
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
mcpConfig = defaultMcpConfig
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
await writeFile(mcpConfigPath, `${JSON.stringify(mcpConfig, null, 2)}\n`)
|
|
57
|
+
|
|
58
|
+
console.log(`Updated ${mcpConfigPath}`)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (await exists(`${cwd}/.cursor/rules/instructions.mdc`)) {
|
|
62
|
+
const cursorMcpConfigPath = `${cwd}/.cursor/mcp.json`
|
|
63
|
+
await handleMcpConfigOverride(cursorMcpConfigPath)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (await exists(`${cwd}/CLAUDE.md`)) {
|
|
67
|
+
await $`mkdir -p ${cwd}/.cursor`
|
|
68
|
+
const claudeCodeMcpConfigPath = `${cwd}/.mcp.json`
|
|
69
|
+
await handleMcpConfigOverride(claudeCodeMcpConfigPath)
|
|
70
|
+
}
|
package/tools/preview-main.mjs
CHANGED
|
@@ -20,7 +20,7 @@ let takeScreenshotConfig = null
|
|
|
20
20
|
try {
|
|
21
21
|
if (values['take-screenshot']) {
|
|
22
22
|
takeScreenshotConfig = JSON.parse(values['take-screenshot'])
|
|
23
|
-
if (!takeScreenshotConfig.path) takeScreenshotConfig.path = `${cwd}/screenshot.
|
|
23
|
+
if (!takeScreenshotConfig.path) takeScreenshotConfig.path = `${cwd}/screenshot.jpg`
|
|
24
24
|
if (!takeScreenshotConfig.width) takeScreenshotConfig.width = 1280
|
|
25
25
|
if (!takeScreenshotConfig.height) takeScreenshotConfig.height = 768
|
|
26
26
|
if (!takeScreenshotConfig.delay) takeScreenshotConfig.delay = 1000
|
|
@@ -46,8 +46,13 @@ if (!previewUrl) throw new Error(`Invalid BRICKS_STAGE: ${stage}`)
|
|
|
46
46
|
|
|
47
47
|
app.on('ready', () => {
|
|
48
48
|
let show = true
|
|
49
|
-
if (takeScreenshotConfig
|
|
50
|
-
const mainWindow = new BrowserWindow({
|
|
49
|
+
if (takeScreenshotConfig && !takeScreenshotConfig.noHeadless) show = false
|
|
50
|
+
const mainWindow = new BrowserWindow({
|
|
51
|
+
width: takeScreenshotConfig?.width || 1280,
|
|
52
|
+
height: takeScreenshotConfig?.height || 768,
|
|
53
|
+
frame: !takeScreenshotConfig,
|
|
54
|
+
show,
|
|
55
|
+
})
|
|
51
56
|
mainWindow.setBackgroundColor('#333')
|
|
52
57
|
mainWindow.loadURL(previewUrl)
|
|
53
58
|
|
|
@@ -56,18 +61,19 @@ app.on('ready', () => {
|
|
|
56
61
|
type: 'config',
|
|
57
62
|
configFile: { _originTitle: 'Test', ...config, title: Math.random().toString() },
|
|
58
63
|
workspace: { billing: { lock: {}, plan: 'free' } },
|
|
64
|
+
showMenu: false,
|
|
59
65
|
}
|
|
60
66
|
mainWindow.webContents.executeJavaScript(
|
|
61
67
|
`window.postMessage(JSON.stringify(${JSON.stringify(payload)}))`,
|
|
62
68
|
)
|
|
63
69
|
if (takeScreenshotConfig) {
|
|
64
|
-
const { delay, width, height, path,
|
|
70
|
+
const { delay, width, height, path, keepOpen = false } = takeScreenshotConfig
|
|
65
71
|
setTimeout(() => {
|
|
66
72
|
console.log('Taking screenshot')
|
|
67
|
-
mainWindow.webContents.capturePage(
|
|
73
|
+
mainWindow.webContents.capturePage().then((image) => {
|
|
68
74
|
console.log('Writing screenshot to', path)
|
|
69
|
-
writeFile(path, image.
|
|
70
|
-
if (
|
|
75
|
+
writeFile(path, image.resize({ width, height }).toJPEG(75))
|
|
76
|
+
if (!keepOpen) {
|
|
71
77
|
console.log('Closing app')
|
|
72
78
|
app.quit()
|
|
73
79
|
}
|
package/tools/preview.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { $ } from 'bun'
|
|
2
2
|
import { watch } from 'fs'
|
|
3
|
+
import type { FSWatcher } from 'fs'
|
|
3
4
|
import { parseArgs } from 'util'
|
|
4
5
|
import { debounce } from 'lodash'
|
|
5
6
|
|
|
@@ -8,55 +9,60 @@ const { values } = parseArgs({
|
|
|
8
9
|
options: {
|
|
9
10
|
'skip-typecheck': { type: 'boolean' },
|
|
10
11
|
'clear-cache': { type: 'boolean' },
|
|
11
|
-
|
|
12
|
+
screenshot: { type: 'boolean' },
|
|
12
13
|
'screenshot-delay': { type: 'string' },
|
|
13
14
|
'screenshot-width': { type: 'string' },
|
|
14
15
|
'screenshot-height': { type: 'string' },
|
|
15
16
|
'screenshot-path': { type: 'string' },
|
|
16
|
-
'screenshot-
|
|
17
|
-
'screenshot-headless': { type: 'boolean' },
|
|
17
|
+
'screenshot-keep-open': { type: 'boolean' },
|
|
18
|
+
'screenshot-no-headless': { type: 'boolean' },
|
|
18
19
|
},
|
|
19
20
|
strict: true,
|
|
20
21
|
allowPositionals: true,
|
|
21
22
|
})
|
|
22
23
|
|
|
23
|
-
const useTypecheck = !values['skip-typecheck']
|
|
24
|
-
|
|
25
|
-
const compile = async () => {
|
|
26
|
-
if (useTypecheck) await $`bun typecheck`
|
|
27
|
-
await $`bun compile`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
await compile()
|
|
31
|
-
|
|
32
|
-
const compileDebounced = debounce(compile, 500)
|
|
33
|
-
|
|
34
24
|
const cwd = process.cwd()
|
|
35
25
|
|
|
36
|
-
const watcher = watch(`${cwd}/subspaces`, { recursive: true }, async (event, filename) => {
|
|
37
|
-
console.log(`Detected ${event} in ${filename}`)
|
|
38
|
-
compileDebounced()
|
|
39
|
-
})
|
|
40
|
-
|
|
41
26
|
const app = await Bun.file(`${cwd}/application.json`).json()
|
|
42
27
|
|
|
43
28
|
let args: string[] = []
|
|
44
29
|
if (values['clear-cache']) args.push('--clear-cache')
|
|
45
30
|
|
|
31
|
+
let needWatcher = true
|
|
46
32
|
if (values['screenshot']) {
|
|
47
33
|
args.push(`--take-screenshot`)
|
|
34
|
+
const keepOpen = values['screenshot-keep-open'] ?? false
|
|
48
35
|
args.push(
|
|
49
36
|
JSON.stringify({
|
|
50
37
|
delay: Number(values['screenshot-delay']) || 1000,
|
|
51
|
-
width: Number(values['screenshot-width']) ||
|
|
52
|
-
height: Number(values['screenshot-height']) ||
|
|
53
|
-
path: values['screenshot-path'] || `${cwd}/screenshot.
|
|
54
|
-
|
|
55
|
-
|
|
38
|
+
width: Number(values['screenshot-width']) || 600,
|
|
39
|
+
height: Number(values['screenshot-height']) || 480,
|
|
40
|
+
path: values['screenshot-path'] || `${cwd}/screenshot.jpg`,
|
|
41
|
+
keepOpen,
|
|
42
|
+
noHeadless: values['screenshot-no-headless'] ?? false,
|
|
56
43
|
}),
|
|
57
44
|
)
|
|
45
|
+
needWatcher = keepOpen
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const useTypecheck = !values['skip-typecheck']
|
|
49
|
+
|
|
50
|
+
const compile = async () => {
|
|
51
|
+
if (useTypecheck) await $`bun typecheck`
|
|
52
|
+
await $`bun compile`
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
await compile()
|
|
56
|
+
|
|
57
|
+
let watcher: FSWatcher | null = null
|
|
58
|
+
if (needWatcher) {
|
|
59
|
+
const compileDebounced = debounce(compile, 500)
|
|
60
|
+
watcher = watch(`${cwd}/subspaces`, { recursive: true }, async (event, filename) => {
|
|
61
|
+
console.log(`Detected ${event} in ${filename}`)
|
|
62
|
+
compileDebounced()
|
|
63
|
+
})
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
await $`BRICKS_STAGE=${app.stage || 'production'} bunx --bun electron ${__dirname}/preview-main.mjs ${args}`
|
|
61
67
|
|
|
62
|
-
watcher.close()
|
|
68
|
+
if (watcher) watcher.close()
|