worsoft-frontend-codegen-local-mcp 0.1.0 → 0.1.2
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/README.md
CHANGED
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
# Worsoft Frontend Codegen Local MCP
|
|
2
2
|
|
|
3
|
-
This
|
|
4
|
-
It does not call `/admin/generator/mcp/execute`.
|
|
3
|
+
This MCP generates Worsoft frontend files from a local Markdown design document.
|
|
5
4
|
|
|
6
|
-
##
|
|
5
|
+
## Scope
|
|
7
6
|
|
|
8
7
|
- local Markdown design file input
|
|
9
8
|
- style-based template selection
|
|
10
9
|
- local template rendering
|
|
11
10
|
- single-table runtime generation
|
|
12
|
-
- master-child runtime generation with relation
|
|
13
|
-
- render plan preview
|
|
11
|
+
- master-child runtime generation with caller-provided relation input
|
|
14
12
|
- optional write-to-disk
|
|
15
13
|
|
|
16
14
|
## Current Inputs
|
|
17
15
|
|
|
18
|
-
- `designFile
|
|
16
|
+
- `designFile`: optional, defaults to `../sql/SQL 设计说明.md`
|
|
19
17
|
- `tableName`
|
|
20
18
|
- `style`
|
|
21
19
|
- `frontendPath`
|
|
22
20
|
- `moduleName`
|
|
23
21
|
- `writeToDisk`
|
|
24
|
-
- `
|
|
22
|
+
- `overwrite`
|
|
23
|
+
- `childTableName` when `style=master_child_jump`: required
|
|
24
|
+
- `mainField` when `style=master_child_jump`: required
|
|
25
|
+
- `childField` when `style=master_child_jump`: required
|
|
26
|
+
- `relationType` when `style=master_child_jump`: optional
|
|
25
27
|
|
|
26
28
|
## Recommended MCP Arguments
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
Single table:
|
|
29
31
|
|
|
30
32
|
```json
|
|
31
33
|
{
|
|
32
34
|
"tableName": "iwm_sys_trade",
|
|
33
|
-
"style": "
|
|
35
|
+
"style": "single_table_dialog",
|
|
34
36
|
"designFile": "plugins/sql/SQL 设计说明.md",
|
|
35
37
|
"frontendPath": "E:/own-worker-platform/trunk/worsoft-ui",
|
|
36
38
|
"moduleName": "admin/test",
|
|
@@ -38,22 +40,41 @@ Use `designFile` as the source argument.
|
|
|
38
40
|
}
|
|
39
41
|
```
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
Master-child:
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"tableName": "iwm_sys_trade",
|
|
48
|
+
"style": "master_child_jump",
|
|
49
|
+
"childTableName": "iwm_sys_trade_level",
|
|
50
|
+
"mainField": "id",
|
|
51
|
+
"childField": "trade_id",
|
|
52
|
+
"relationType": "1:N",
|
|
53
|
+
"designFile": "plugins/sql/SQL 设计说明.md",
|
|
54
|
+
"frontendPath": "E:/own-worker-platform/trunk/worsoft-ui",
|
|
55
|
+
"moduleName": "admin/test",
|
|
56
|
+
"writeToDisk": false
|
|
57
|
+
}
|
|
58
|
+
```
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
## Smoke Test
|
|
46
61
|
|
|
47
|
-
|
|
48
|
-
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario single
|
|
49
|
-
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario master
|
|
50
|
-
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario child
|
|
51
|
-
```
|
|
62
|
+
PowerShell:
|
|
52
63
|
|
|
53
64
|
```powershell
|
|
54
65
|
powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario single
|
|
55
66
|
powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario master
|
|
56
67
|
powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario child
|
|
68
|
+
powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario missing_relation
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Node:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario single
|
|
75
|
+
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario master
|
|
76
|
+
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario child
|
|
77
|
+
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario missing_relation
|
|
57
78
|
```
|
|
58
79
|
|
|
59
80
|
Optional overrides:
|
|
@@ -62,21 +83,30 @@ Optional overrides:
|
|
|
62
83
|
- `--table-name`
|
|
63
84
|
- `--style`
|
|
64
85
|
- `--child-table-name`
|
|
86
|
+
- `--main-field`
|
|
87
|
+
- `--child-field`
|
|
88
|
+
- `--relation-type`
|
|
65
89
|
- `--frontend-path`
|
|
66
90
|
- `--write-to-disk`
|
|
67
91
|
|
|
68
|
-
|
|
92
|
+
## Master-Child Contract
|
|
93
|
+
|
|
94
|
+
For `master_child_jump`, MCP does not infer relations from the design file anymore.
|
|
69
95
|
|
|
70
|
-
|
|
96
|
+
The caller must provide:
|
|
97
|
+
|
|
98
|
+
- `childTableName`
|
|
99
|
+
- `mainField`
|
|
100
|
+
- `childField`
|
|
101
|
+
|
|
102
|
+
If these fields are missing, MCP returns `relation_input_required`.
|
|
103
|
+
|
|
104
|
+
Example:
|
|
71
105
|
|
|
72
106
|
```json
|
|
73
107
|
{
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"designFile": "plugins/sql/SQL 设计说明.md",
|
|
77
|
-
"childTableName": "iwm_sys_trade_level_standard",
|
|
78
|
-
"frontendPath": "E:/own-worker-platform/trunk/worsoft-ui",
|
|
79
|
-
"writeToDisk": false
|
|
108
|
+
"type": "relation_input_required",
|
|
109
|
+
"requiredFields": ["childTableName", "mainField", "childField"]
|
|
80
110
|
}
|
|
81
111
|
```
|
|
82
112
|
|
|
@@ -94,28 +124,20 @@ When one main table has multiple child relations in the design file, add `childT
|
|
|
94
124
|
- Machine source: `assets/style-catalog.json`
|
|
95
125
|
|
|
96
126
|
Declared styles:
|
|
127
|
+
|
|
97
128
|
- `single_table_jump`
|
|
98
129
|
- `single_table_dialog`
|
|
99
130
|
- `master_child_jump`
|
|
100
131
|
|
|
101
|
-
Runtime generation support:
|
|
102
|
-
- `single_table_jump`: supported
|
|
103
|
-
- `single_table_dialog`: supported
|
|
104
|
-
- `master_child_jump`: supported
|
|
105
|
-
|
|
106
|
-
## Non-goals for v0.1
|
|
107
|
-
|
|
108
|
-
- backend API forwarding
|
|
109
|
-
- generic Velocity rendering
|
|
110
|
-
- dict lookup from backend
|
|
111
|
-
- full compatibility with the old generator contract
|
|
112
|
-
|
|
113
132
|
## Notes
|
|
114
133
|
|
|
115
134
|
- Shared Worsoft template references live under `../template`.
|
|
116
135
|
- Plugin-local runtime assets live under `assets/templates`.
|
|
117
136
|
- The preferred source is `plugins/sql/SQL 设计说明.md`.
|
|
118
|
-
- Markdown
|
|
119
|
-
-
|
|
120
|
-
- Menu SQL is
|
|
121
|
-
|
|
137
|
+
- Markdown parsing is used for field-definition tables.
|
|
138
|
+
- Master-child relation parsing is handled outside MCP and passed in through tool arguments.
|
|
139
|
+
- Menu SQL is emitted to `frontendPath/menu/`.
|
|
140
|
+
|
|
141
|
+
## IDE Guide
|
|
142
|
+
|
|
143
|
+
- `IDE_MCP_SETUP.md`
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="layout-padding-auto layout-padding-view">
|
|
3
3
|
<el-card shadow="never">
|
|
4
4
|
<template #header>
|
|
5
|
-
<span>{{ form.{{PK_ATTR}} ? (detail ? '
|
|
5
|
+
<span>{{ form.{{PK_ATTR}} ? (detail ? '查看' : '编辑') : '新增' }}</span>
|
|
6
6
|
</template>
|
|
7
7
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading">
|
|
8
8
|
<el-row :gutter="24">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-dialog v-model="visible" :title="form.{{PK_ATTR}} ? '
|
|
2
|
+
<el-dialog v-model="visible" :title="form.{{PK_ATTR}} ? '编辑' : '新增'" :close-on-click-modal="false" draggable>
|
|
3
3
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="100px" v-loading="loading">
|
|
4
4
|
<el-row :gutter="24">
|
|
5
5
|
{{FORM_FIELDS}}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
</el-form>
|
|
8
8
|
<template #footer>
|
|
9
9
|
<span class="dialog-footer">
|
|
10
|
-
<el-button @click="visible = false"
|
|
11
|
-
<el-button type="primary" @click="onSubmit" :disabled="loading"
|
|
10
|
+
<el-button @click="visible = false">取消</el-button>
|
|
11
|
+
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
|
|
12
12
|
</span>
|
|
13
13
|
</template>
|
|
14
14
|
</el-dialog>
|
|
@@ -39,7 +39,7 @@ const get{{CLASS_NAME}}Data = async (id: string) => {
|
|
|
39
39
|
const { data } = await getObj({ {{PK_ATTR}}: id });
|
|
40
40
|
Object.assign(form, data[0] || {});
|
|
41
41
|
} catch (error) {
|
|
42
|
-
useMessage().error('
|
|
42
|
+
useMessage().error('获取数据失败');
|
|
43
43
|
} finally {
|
|
44
44
|
loading.value = false;
|
|
45
45
|
}
|
|
@@ -75,11 +75,11 @@ const onSubmit = async () => {
|
|
|
75
75
|
|
|
76
76
|
try {
|
|
77
77
|
form.{{PK_ATTR}} ? await putObj(form) : await addObj(form);
|
|
78
|
-
useMessage().success(form.{{PK_ATTR}} ? '
|
|
78
|
+
useMessage().success(form.{{PK_ATTR}} ? '修改成功' : '添加成功');
|
|
79
79
|
visible.value = false;
|
|
80
80
|
emit('refresh');
|
|
81
81
|
} catch (err: any) {
|
|
82
|
-
useMessage().error(err.msg || '
|
|
82
|
+
useMessage().error(err.msg || '提交失败');
|
|
83
83
|
} finally {
|
|
84
84
|
loading.value = false;
|
|
85
85
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="layout-padding-auto layout-padding-view">
|
|
3
3
|
<el-card shadow="never">
|
|
4
4
|
<template #header>
|
|
5
|
-
<span>{{ form.{{PK_ATTR}} ? (detail ? '
|
|
5
|
+
<span>{{ form.{{PK_ATTR}} ? (detail ? '查看' : '编辑') : '新增' }}</span>
|
|
6
6
|
</template>
|
|
7
7
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading">
|
|
8
8
|
<el-row :gutter="24">
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
</el-row>
|
|
11
11
|
</el-form>
|
|
12
12
|
<div class="dialog-footer" style="text-align: right; margin-top: 18px;">
|
|
13
|
-
<el-button @click="handleBack"
|
|
14
|
-
<el-button type="primary" @click="onSubmit" :disabled="loading"
|
|
13
|
+
<el-button @click="handleBack">取消</el-button>
|
|
14
|
+
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
|
|
15
15
|
</div>
|
|
16
16
|
</el-card>
|
|
17
17
|
</div>
|
|
@@ -43,7 +43,7 @@ const get{{CLASS_NAME}}Data = async (id: string) => {
|
|
|
43
43
|
const { data } = await getObj({ {{PK_ATTR}}: id });
|
|
44
44
|
Object.assign(form, data[0] || {});
|
|
45
45
|
} catch (error) {
|
|
46
|
-
useMessage().error('
|
|
46
|
+
useMessage().error('获取数据失败');
|
|
47
47
|
} finally {
|
|
48
48
|
loading.value = false;
|
|
49
49
|
}
|
|
@@ -90,10 +90,10 @@ const onSubmit = async () => {
|
|
|
90
90
|
|
|
91
91
|
try {
|
|
92
92
|
form.{{PK_ATTR}} ? await putObj(form) : await addObj(form);
|
|
93
|
-
useMessage().success(form.{{PK_ATTR}} ? '
|
|
93
|
+
useMessage().success(form.{{PK_ATTR}} ? '修改成功' : '添加成功');
|
|
94
94
|
closeCurrentPage();
|
|
95
95
|
} catch (err: any) {
|
|
96
|
-
useMessage().error(err.msg || '
|
|
96
|
+
useMessage().error(err.msg || '提交失败');
|
|
97
97
|
} finally {
|
|
98
98
|
loading.value = false;
|
|
99
99
|
}
|
package/mcp_server.js
CHANGED
|
@@ -5,7 +5,7 @@ const fs = require('fs');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
|
|
7
7
|
const SERVER_NAME = 'worsoft-codegen-local';
|
|
8
|
-
const SERVER_VERSION = '0.1.
|
|
8
|
+
const SERVER_VERSION = '0.1.2';
|
|
9
9
|
const PROTOCOL_VERSION = '2024-11-05';
|
|
10
10
|
const TOOL_NAME = 'worsoft_codegen_local_generate_frontend';
|
|
11
11
|
const TEMPLATE_LIBRARY_ROOT = path.resolve(__dirname, '..', 'template');
|
|
@@ -19,7 +19,10 @@ const TOOL_SCHEMA = {
|
|
|
19
19
|
designFile: { type: 'string', description: 'Absolute or relative Markdown design file path. Defaults to ../sql/SQL 设计说明.md when omitted.' },
|
|
20
20
|
tableName: { type: 'string', description: 'Target main table name from the design file.' },
|
|
21
21
|
style: { type: 'string', enum: Object.keys(STYLE_CATALOG), description: 'Style id from assets/style-catalog.json.' },
|
|
22
|
-
childTableName: { type: 'string', description: '
|
|
22
|
+
childTableName: { type: 'string', description: 'Child table name. Required when style=master_child_jump.' },
|
|
23
|
+
mainField: { type: 'string', description: 'Main table relation field. Required when style=master_child_jump.' },
|
|
24
|
+
childField: { type: 'string', description: 'Child table relation field. Required when style=master_child_jump.' },
|
|
25
|
+
relationType: { type: 'string', description: 'Optional relation type label, for example 1:N.' },
|
|
23
26
|
frontendPath: { type: 'string', description: 'Absolute frontend output root path.' },
|
|
24
27
|
moduleName: { type: 'string', description: 'Relative frontend module path, for example admin/test.' },
|
|
25
28
|
writeToDisk: { type: 'boolean', default: true, description: 'Whether to write generated files.' },
|
|
@@ -375,7 +378,7 @@ function parseMarkdownRelations(markdownText) {
|
|
|
375
378
|
function parseMarkdownDesignFile(markdownText) {
|
|
376
379
|
return {
|
|
377
380
|
tables: parseMarkdownDesignTables(markdownText),
|
|
378
|
-
relations:
|
|
381
|
+
relations: [],
|
|
379
382
|
};
|
|
380
383
|
}
|
|
381
384
|
|
|
@@ -475,6 +478,18 @@ function buildRetryArguments(safeArgs, sourceFile, childTableName) {
|
|
|
475
478
|
retryArguments.childTableName = childTableName;
|
|
476
479
|
}
|
|
477
480
|
|
|
481
|
+
if (safeArgs.mainField) {
|
|
482
|
+
retryArguments.mainField = safeArgs.mainField;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (safeArgs.childField) {
|
|
486
|
+
retryArguments.childField = safeArgs.childField;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (safeArgs.relationType) {
|
|
490
|
+
retryArguments.relationType = safeArgs.relationType;
|
|
491
|
+
}
|
|
492
|
+
|
|
478
493
|
return retryArguments;
|
|
479
494
|
}
|
|
480
495
|
|
|
@@ -522,26 +537,39 @@ function loadSourceDocument(safeArgs) {
|
|
|
522
537
|
}
|
|
523
538
|
|
|
524
539
|
function resolveMarkdownChildRelation(sourceDocument, safeArgs) {
|
|
525
|
-
|
|
526
|
-
if (
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
: '
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
540
|
+
const missingFields = ['childTableName', 'mainField', 'childField'].filter((field) => !safeArgs[field]);
|
|
541
|
+
if (missingFields.length) {
|
|
542
|
+
const message =
|
|
543
|
+
'master_child_jump requires externally provided relation fields. Missing: ' +
|
|
544
|
+
missingFields.join(', ') +
|
|
545
|
+
'.';
|
|
546
|
+
const error = new Error(message);
|
|
547
|
+
error.details = {
|
|
548
|
+
type: 'relation_input_required',
|
|
549
|
+
status: 'missing_required_relation_input',
|
|
550
|
+
tableName: safeArgs.tableName,
|
|
551
|
+
designFile: sourceDocument.path,
|
|
552
|
+
message,
|
|
553
|
+
requiredFields: ['childTableName', 'mainField', 'childField'],
|
|
554
|
+
correctionEntry: {
|
|
555
|
+
fields: ['childTableName', 'mainField', 'childField'],
|
|
556
|
+
example: {
|
|
557
|
+
...buildRetryArguments(safeArgs, sourceDocument.path, safeArgs.childTableName || '<child_table_name>'),
|
|
558
|
+
mainField: safeArgs.mainField || '<main_field>',
|
|
559
|
+
childField: safeArgs.childField || '<child_field>',
|
|
560
|
+
},
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
throw error;
|
|
542
564
|
}
|
|
543
565
|
|
|
544
|
-
return
|
|
566
|
+
return {
|
|
567
|
+
mainTableName: safeArgs.tableName,
|
|
568
|
+
childTableName: safeArgs.childTableName,
|
|
569
|
+
mainField: safeArgs.mainField,
|
|
570
|
+
childField: safeArgs.childField,
|
|
571
|
+
relationType: safeArgs.relationType || '',
|
|
572
|
+
};
|
|
545
573
|
}
|
|
546
574
|
|
|
547
575
|
function getStylePreset(styleId) {
|
|
@@ -644,7 +672,7 @@ function renderFormField(field) {
|
|
|
644
672
|
return [
|
|
645
673
|
' <el-col :span="12" class="mb20">',
|
|
646
674
|
` <el-form-item label="${label}" prop="${prop}">`,
|
|
647
|
-
` <el-select v-model="form.${prop}" placeholder="
|
|
675
|
+
` <el-select v-model="form.${prop}" placeholder="请选择${label}" style="width: 100%">`,
|
|
648
676
|
` <el-option v-for="item in ${field.dictType}" :key="item.value" :label="item.label" :value="Number(item.value)" />`,
|
|
649
677
|
' </el-select>',
|
|
650
678
|
' </el-form-item>',
|
|
@@ -658,7 +686,7 @@ function renderFormField(field) {
|
|
|
658
686
|
return [
|
|
659
687
|
' <el-col :span="12" class="mb20">',
|
|
660
688
|
` <el-form-item label="${label}" prop="${prop}">`,
|
|
661
|
-
` <el-input-number v-model="form.${prop}" :min="0"${max}${precision} placeholder="
|
|
689
|
+
` <el-input-number v-model="form.${prop}" :min="0"${max}${precision} placeholder="请输入${label}" style="width: 100%" />`,
|
|
662
690
|
' </el-form-item>',
|
|
663
691
|
' </el-col>',
|
|
664
692
|
].join('\n');
|
|
@@ -670,7 +698,7 @@ function renderFormField(field) {
|
|
|
670
698
|
return [
|
|
671
699
|
' <el-col :span="12" class="mb20">',
|
|
672
700
|
` <el-form-item label="${label}" prop="${prop}">`,
|
|
673
|
-
` <el-date-picker type="${pickerType}" placeholder="
|
|
701
|
+
` <el-date-picker type="${pickerType}" placeholder="请选择${label}" v-model="form.${prop}" :value-format="${formatName}" style="width: 100%"></el-date-picker>`,
|
|
674
702
|
' </el-form-item>',
|
|
675
703
|
' </el-col>',
|
|
676
704
|
].join('\n');
|
|
@@ -680,7 +708,7 @@ function renderFormField(field) {
|
|
|
680
708
|
return [
|
|
681
709
|
' <el-col :span="24" class="mb20">',
|
|
682
710
|
` <el-form-item label="${label}" prop="${prop}">`,
|
|
683
|
-
` <el-input type="textarea" v-model="form.${prop}" placeholder="
|
|
711
|
+
` <el-input type="textarea" v-model="form.${prop}" placeholder="请输入${label}" />`,
|
|
684
712
|
' </el-form-item>',
|
|
685
713
|
' </el-col>',
|
|
686
714
|
].join('\n');
|
|
@@ -689,7 +717,7 @@ function renderFormField(field) {
|
|
|
689
717
|
return [
|
|
690
718
|
' <el-col :span="12" class="mb20">',
|
|
691
719
|
` <el-form-item label="${label}" prop="${prop}">`,
|
|
692
|
-
` <el-input v-model="form.${prop}" placeholder="
|
|
720
|
+
` <el-input v-model="form.${prop}" placeholder="请输入${label}" />`,
|
|
693
721
|
' </el-form-item>',
|
|
694
722
|
' </el-col>',
|
|
695
723
|
].join('\n');
|
|
@@ -854,6 +882,9 @@ function ensureArguments(input) {
|
|
|
854
882
|
tableName: String(input.tableName),
|
|
855
883
|
style,
|
|
856
884
|
childTableName: input.childTableName ? String(input.childTableName) : null,
|
|
885
|
+
mainField: input.mainField ? String(input.mainField) : null,
|
|
886
|
+
childField: input.childField ? String(input.childField) : null,
|
|
887
|
+
relationType: input.relationType ? String(input.relationType) : '',
|
|
857
888
|
frontendPath: String(input.frontendPath),
|
|
858
889
|
moduleName: input.moduleName ? String(input.moduleName) : 'admin/test',
|
|
859
890
|
writeToDisk: input.writeToDisk === undefined ? true : Boolean(input.writeToDisk),
|
|
@@ -875,7 +906,6 @@ function maybeWriteFiles(files, writeToDisk, overwrite) {
|
|
|
875
906
|
}
|
|
876
907
|
|
|
877
908
|
function buildManifest(model, safeArgs, stylePreset, sharedTemplates, files, note) {
|
|
878
|
-
const relationCandidates = getRelationCandidates(loadSourceDocument(safeArgs).designDoc, safeArgs.tableName);
|
|
879
909
|
return {
|
|
880
910
|
mode: 'local-template',
|
|
881
911
|
style: safeArgs.style,
|
|
@@ -901,17 +931,21 @@ function buildManifest(model, safeArgs, stylePreset, sharedTemplates, files, not
|
|
|
901
931
|
: null,
|
|
902
932
|
relationResolution: model.child
|
|
903
933
|
? {
|
|
904
|
-
status: '
|
|
934
|
+
status: 'provided',
|
|
905
935
|
tableName: safeArgs.tableName,
|
|
906
936
|
designFile: model.designFile,
|
|
907
|
-
|
|
937
|
+
source: 'arguments',
|
|
938
|
+
message: 'The relation was provided by the caller. MCP skipped design-doc relation inference and generated files directly.',
|
|
908
939
|
selected: formatRelationCandidate({
|
|
909
940
|
childTableName: model.child.tableName,
|
|
910
941
|
mainField: model.child.mainField.fieldName,
|
|
911
942
|
childField: model.child.childField.fieldName,
|
|
912
943
|
relationType: model.child.relationType || '',
|
|
913
944
|
}),
|
|
914
|
-
correctionEntry:
|
|
945
|
+
correctionEntry: {
|
|
946
|
+
fields: ['childTableName', 'mainField', 'childField'],
|
|
947
|
+
example: buildRetryArguments(safeArgs, model.designFile, model.child.tableName),
|
|
948
|
+
},
|
|
915
949
|
}
|
|
916
950
|
: null,
|
|
917
951
|
summary: {
|
|
@@ -962,7 +996,7 @@ async function onMessage(message) {
|
|
|
962
996
|
}
|
|
963
997
|
|
|
964
998
|
if (method === 'tools/list') {
|
|
965
|
-
writeMessage(successResponse(id, { tools: [{ name: TOOL_NAME, description: 'Generate Worsoft frontend files and menu SQL from a local Markdown design file with style-based local templates. In master_child_jump mode,
|
|
999
|
+
writeMessage(successResponse(id, { tools: [{ name: TOOL_NAME, description: 'Generate Worsoft frontend files and menu SQL from a local Markdown design file with style-based local templates. In master_child_jump mode, the caller must provide childTableName, mainField, and childField.', inputSchema: TOOL_SCHEMA }] }));
|
|
966
1000
|
return;
|
|
967
1001
|
}
|
|
968
1002
|
|
package/package.json
CHANGED