@agile-team/wl-skills-kit 2.7.1 → 2.7.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/CHANGELOG.md +27 -0
- package/README.md +9 -1
- package/bin/wl-skills.js +1 -1
- package/files/.github/copilot-instructions.md +12 -0
- package/files/.github/guides/architecture.md +1 -1
- package/files/.github/skills/_best-practices.md +220 -0
- package/files/.github/skills/_registry.md +23 -19
- package/files/.github/skills/sync/_mcp-guardrail.md +109 -0
- package/files/.github/skills/sync/dict-sync/SKILL.md +86 -329
- package/files/.github/skills/sync/menu-sync/SKILL.md +34 -27
- package/files/.github/skills/sync/menu-sync/USAGE.md +17 -11
- package/files/.github/skills/sync/permission-sync/SKILL.md +19 -2
- package/mcp/api/client.js +8 -1
- package/mcp/server.js +21 -0
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.7.2] - 2026-05-13
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`skills/_best-practices.md`**(新文档):场景级最佳实践索引。AI 每轮对话默认读取,按场景(新建模块 / 补菜单 / 补字典 / 角色授权 / 项目体检等)路由 Skill,弱化"靠关键词猜触发"。人也可当 Runbook 查阅。
|
|
8
|
+
- **`skills/sync/_mcp-guardrail.md`**(新文档):sync 类 Skill 通用护栏。明确 MCP 调用纪律 + 错误分层(L0~L4)+ **自愈闭环剧本**:MCP 调用失败时引导用户完善 `env.local.json`(token/domainId/gatewayPath 等)后重试,**禁止** AI 用 curl/PowerShell/fetch 绕开 MCP 自拼 HTTP。
|
|
9
|
+
- **`scripts/lint-skills.js`**(新脚本)+ **`tests/lint-skills.test.js`**:静态校验 sync SKILL.md 引用 guardrail、列出"严禁 curl"纪律、无残留 `TODO_CONFIRM`,`_registry.md` 引用的 Skill 路径必须存在。`prepublishOnly` 已串联。
|
|
10
|
+
- **`mcp/server.js` 启动 banner**:写入 stderr(不污染 stdio JSON-RPC),列出版本、`WL_PROJECT_ROOT`、已注册的 17 个工具,方便快速判断"MCP 是否真连上"。
|
|
11
|
+
- **`mcp/api/client.js` 友好错误提示**:401 / 4004 自动附排查指引("token 仅填纯 JWT 不含 bearer 前缀" / "gatewayPath 可能缺前缀,不要让 AI 绕开 MCP 拼 HTTP")。
|
|
12
|
+
- **`_registry.md` 增加「MCP 工具依赖」列**:明确每个 Skill 用到的 `wls_*` 工具,AI 加载 Skill 时一并核验工具可用性。
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **`dict-sync/SKILL.md`** 完全重写(451 → 215 行):删除文件被错误拼接的旧版残留段、`TODO_CONFIRM` 错路径(`/system/dict/list` 等)、错字段名;改为 MCP 优先,明确 `wls_dict_query` / `wls_dict_upsert` 入参模板。
|
|
17
|
+
- **`menu-sync/SKILL.md`**:执行流程改为 `wls_menu_sync_from_report` 一步到位优先;HTTP body 显式标注「仅为 MCP 入参参考」,杜绝 AI 据此自行 fetch。
|
|
18
|
+
- **`menu-sync/USAGE.md`**:修正旧字段(`tenantId` / `rootMenuId` / 旧路径示例)→ 统一为 `sysAppNo` / `menu.parentMenuId` / `sync/env.local.json`。
|
|
19
|
+
- **`permission-sync/SKILL.md` §6**:标题从"无 MCP 时的兜底"改为"MCP 内部实现,AI 不得调用",杜绝 AI 把它当 fallback 路径自己跑 HTTP。
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`copilot-instructions.md`** AI Skills 自动调度段:新增"首选场景索引(best-practices)"流程,三件套(best-practices + registry + pipeline)联合路由替代单纯关键词命中。
|
|
24
|
+
- **三个 sync SKILL.md 顶部纪律段统一**:均改为引用 `_mcp-guardrail.md`,错误处理走自愈闭环(不再"立即停止")。
|
|
25
|
+
|
|
26
|
+
### Notes
|
|
27
|
+
|
|
28
|
+
- 纯文档 + MCP 运行时增强,无 SDK 行为破坏性变更,业务项目 `npx @agile-team/wl-skills-kit update` 即可同步。
|
|
29
|
+
|
|
3
30
|
## [2.7.1] - 2026-05-13
|
|
4
31
|
|
|
5
32
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @agile-team/wl-skills-kit
|
|
2
2
|
|
|
3
|
-
**AI Skill 模板包 v2.7.
|
|
3
|
+
**AI Skill 模板包 v2.7.2** — 一键将 13 条规范、10 个 AI Skill、17 个 MCP Tool、编辑器 MCP 配置、文档导入 Vue 3 项目。
|
|
4
4
|
|
|
5
5
|
让 AI 编辑器(Copilot / Cursor / Windsurf / Claude Code / Cline / Kiro / Trae / Qoder / 通用 Agents)**真正理解项目规范**,从原型/详设到完整页面代码全流程自动化。
|
|
6
6
|
|
|
@@ -23,6 +23,14 @@ npm run standards:init # 本包维护/业务项目均可复用
|
|
|
23
23
|
|
|
24
24
|
## 版本亮点
|
|
25
25
|
|
|
26
|
+
**v2.7.2**:sync 类 Skill 自愈闭环 + 场景索引路由。
|
|
27
|
+
|
|
28
|
+
- 新增 `skills/_best-practices.md` 场景索引(AI 每轮默认加载,弱化关键词命中)
|
|
29
|
+
- 新增 `skills/sync/_mcp-guardrail.md` 公共护栏(含 L0~L4 错误自愈剧本,MCP 失败时引导用户完善 `env.local.json` 而不是绕开自拼 HTTP)
|
|
30
|
+
- 修复 `dict-sync/SKILL.md` 旧版残留与错路径;统一 `menu-sync/USAGE.md` 字段命名
|
|
31
|
+
- MCP server 启动 banner(stderr,不污染 JSON-RPC);client.js 401/4004 友好提示
|
|
32
|
+
- 新增 `npm run lint:skills` 静态护栏,已串入 `prepublishOnly`
|
|
33
|
+
|
|
26
34
|
**v2.7.1**:JH 组件文档全面修正,基于 `@jhlc/common-core` 源码校准 Props/API/映射规则。
|
|
27
35
|
|
|
28
36
|
- 修正 `jh-drag-row` 6 个缺失 Props、`jh-date`/`jh-date-range` format 命名
|
package/bin/wl-skills.js
CHANGED
|
@@ -234,6 +234,18 @@ onMounted(() => select());
|
|
|
234
234
|
|
|
235
235
|
完整触发词与 Skill 路径见 `skills/_registry.md`(**单一数据源**,不在此处重复)。
|
|
236
236
|
|
|
237
|
+
> 🔖 **首选「场景索引」**:`skills/_best-practices.md`
|
|
238
|
+
>
|
|
239
|
+
> 进入项目对话或开启新任务时,AI 必须先 `read_file` 加载:
|
|
240
|
+
>
|
|
241
|
+
> 1. `skills/_best-practices.md`(按场景的最佳实践索引,**首选路由依据**)
|
|
242
|
+
> 2. `skills/_registry.md`(触发词 → Skill 路径映射)
|
|
243
|
+
> 3. `skills/_pipeline.md`(Skill I/O 契约 + 推荐链式顺序)
|
|
244
|
+
>
|
|
245
|
+
> 三者联合判定后再决定调用哪个 Skill / MCP 工具。**禁止仅凭关键词命中就跳过 best-practices 的语义判断**。
|
|
246
|
+
>
|
|
247
|
+
> sync 类(菜单/字典/权限)任务必须额外加载 `skills/sync/_mcp-guardrail.md`,调用失败按 §2 自愈剧本引导用户完善配置后重试,不绕开 MCP。
|
|
248
|
+
|
|
237
249
|
### Intent Router(自然语言智能识别)
|
|
238
250
|
|
|
239
251
|
用户不需要记住 Skill 名。只要消息包含以下任一语义,AI 必须自动路由到对应 Skill:
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# 最佳实践索引(Best Practices Playbook)
|
|
2
|
+
|
|
3
|
+
> **本文件是 AI 与团队成员共享的"按场景查手册"**。
|
|
4
|
+
>
|
|
5
|
+
> - 对 AI:**每次进入项目对话时默认读取一次**,用于把用户的自然表达精准映射到推荐流程,减少"靠关键词猜触发"
|
|
6
|
+
> - 对人:当成 Runbook 用,按场景找最佳实践、触发话术、避坑要点
|
|
7
|
+
>
|
|
8
|
+
> 维护策略:场景由实战沉淀,每次踩坑都回写到对应条目;新增 Skill / MCP 工具必须在此登记典型用法。
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 0. 通用前置规则(任一场景共用)
|
|
13
|
+
|
|
14
|
+
| # | 规则 |
|
|
15
|
+
|---|---|
|
|
16
|
+
| 1 | 用户的"自然表达"优先于"关键词命中"。先理解意图再决定是否触发 Skill |
|
|
17
|
+
| 2 | 涉及 **sync 类**(菜单/字典/权限)操作时,**必读** `skills/sync/_mcp-guardrail.md`,调用失败不绕开 MCP,按 guardrail §2 自愈剧本引导用户 |
|
|
18
|
+
| 3 | 每个场景都允许「单步执行」或「流水线执行」两种方式,由用户决定 |
|
|
19
|
+
| 4 | 写文件 / 调写接口 / 修改代码前,输出 Pre-flight 声明并等待用户确认 |
|
|
20
|
+
| 5 | 报告类产物统一写入 `.github/reports/`,**追加不覆盖** |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 1. 场景:新建模块完整闭环(最常用)
|
|
25
|
+
|
|
26
|
+
> 从原型/详设 → 页面 → 菜单注册 → 字典/权限补齐 → 审计通过
|
|
27
|
+
|
|
28
|
+
**用户典型话术**:
|
|
29
|
+
- "帮我做一个新模块"
|
|
30
|
+
- "根据原型/详设生成 XX 模块"
|
|
31
|
+
- "我要新建客户管理模块"
|
|
32
|
+
|
|
33
|
+
**推荐流程**:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
prototype-scan
|
|
37
|
+
→ business-doc-extract(资料完整时)
|
|
38
|
+
→ api-contract
|
|
39
|
+
→ page-codegen ← 产物:src/views/.../{index.vue,data.ts,api.md,SYS_MENU_INFO.md}
|
|
40
|
+
→ menu-sync ← 推荐工具:wls_menu_sync_from_report
|
|
41
|
+
→ dict-sync(页面用到字典时)
|
|
42
|
+
→ permission-sync(需角色授权 / 动作按钮时)
|
|
43
|
+
→ convention-audit
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**关键检查点**:
|
|
47
|
+
- pages.ts 是否注册了新页面(否则路由不存在)
|
|
48
|
+
- `.github/reports/SYS_MENU_INFO.md` 是否包含本次新增页面
|
|
49
|
+
- 同步菜单后端 4004 / 401 → 走 guardrail 引导用户改 env.local.json
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 2. 场景:补菜单 / 注册菜单
|
|
54
|
+
|
|
55
|
+
**用户典型话术**:
|
|
56
|
+
- "帮我创建菜单"
|
|
57
|
+
- "同步菜单"
|
|
58
|
+
- "页面写完了点不进去"
|
|
59
|
+
- "补菜单"
|
|
60
|
+
|
|
61
|
+
**推荐流程**(默认一步到位):
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
wls_menu_sync_from_report ← MCP 工具,自动读报告 + 查菜单树 + 一二级有序创建
|
|
65
|
+
└─ 首次先传 dryRun: true 预览,确认无误再正式执行
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**前置**:
|
|
69
|
+
- `.github/reports/SYS_MENU_INFO.md` 已生成(由 page-codegen 产出,或手工维护)
|
|
70
|
+
- `env.local.json` 配齐:gatewayPath / token(纯 JWT)/ sysAppNo / menu.parentMenuId / menu.domainId
|
|
71
|
+
|
|
72
|
+
**典型故障 → 处理**:
|
|
73
|
+
- 工具列表里没有 `wls_menu_sync_from_report` → guardrail §2.2
|
|
74
|
+
- 报错"请填写真实的 domainId" → guardrail §2.3
|
|
75
|
+
- 返回 401 → guardrail §2.4
|
|
76
|
+
- 返回 4004(路径不存在)→ guardrail §2.5
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 3. 场景:补字典 / 同步字典
|
|
81
|
+
|
|
82
|
+
**用户典型话术**:
|
|
83
|
+
- "同步字典"
|
|
84
|
+
- "data.ts 里 logicValue 缺字典"
|
|
85
|
+
- "字典对比 / 字典审计"
|
|
86
|
+
|
|
87
|
+
**推荐流程**:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
1. 用 wls_dict_query 查线上已有
|
|
91
|
+
2. 扫 data.ts 收集所有 logicValue(DICT_CODE)
|
|
92
|
+
3. 差集 = 待新建 → 用户确认
|
|
93
|
+
4. 逐个调 wls_dict_upsert(含 module + items)
|
|
94
|
+
5. 更新 .github/reports/SYS_DICT_INFO.md
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**配置依赖**:env.local.json → `dict.moduleId`
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 4. 场景:角色授权 / 加动作按钮
|
|
102
|
+
|
|
103
|
+
**用户典型话术**:
|
|
104
|
+
- "给 XX 角色分配菜单"
|
|
105
|
+
- "给页面挂动作按钮"
|
|
106
|
+
- "注册权限码"
|
|
107
|
+
|
|
108
|
+
**推荐流程**:
|
|
109
|
+
|
|
110
|
+
| 子场景 | MCP 工具序列 |
|
|
111
|
+
|---|---|
|
|
112
|
+
| 创建角色 | `wls_role_query`(查重)→ `wls_role_upsert` |
|
|
113
|
+
| 角色授权 | `wls_role_query` → `wls_assignable_menus_query` → `wls_role_assign_menus`(⚠️ **全量覆盖**,AI 需自动合并旧 menuIds + 新增)|
|
|
114
|
+
| 挂动作 | `wls_menu_query` 找页面 id → `wls_action_query` 查重 → `wls_action_upsert` 批量新增 → 修改 `data.ts` 给按钮加 `permission: [xxx]` 字段 |
|
|
115
|
+
|
|
116
|
+
**避坑**:
|
|
117
|
+
- 角色分配是**全量覆盖**,传 `[A,B]` 会把原有 C 移除,必须先查再合并
|
|
118
|
+
- 权限码命名遵循项目既有风格(`资源_动作` 或 `模块:资源:动作`)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 5. 场景:存量项目体检 / 接手新项目
|
|
123
|
+
|
|
124
|
+
**用户典型话术**:
|
|
125
|
+
- "接手新项目"
|
|
126
|
+
- "项目体检"
|
|
127
|
+
- "规范审计"
|
|
128
|
+
|
|
129
|
+
**推荐流程**:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
wls_code_scan ← 概览:页面目录、API_CONFIG、文件完整性
|
|
133
|
+
→ convention-audit ← 13 条规范全量扫描,产出 AUDIT_*.md
|
|
134
|
+
→ code-fix(可选) ← 自动修复可整改项
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 6. 场景:仅 mock 跑通 / 后端没好先能跑
|
|
140
|
+
|
|
141
|
+
**用户典型话术**:"先 mock 一下"、"假数据"、"后端没好先能跑"
|
|
142
|
+
|
|
143
|
+
**推荐**:`page-codegen` 的 mock-first 规则,生成假数据 + 注释好真实接口对接位置。
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 7. 场景:模板沉淀
|
|
148
|
+
|
|
149
|
+
**用户典型话术**:"这页面成熟了,沉淀成模板"
|
|
150
|
+
|
|
151
|
+
**推荐**:`template-extract` Skill → 产出 `templates/domains/**/TPL-*.md` → 下次 `page-codegen` 复用。
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 8. 场景:业务文档/字段字典维护
|
|
156
|
+
|
|
157
|
+
**用户典型话术**:用户提供完整原型/详设/字段或字典资料,意图为业务沉淀
|
|
158
|
+
|
|
159
|
+
**推荐**:`business-doc-extract`(**语义级触发**,碎片需求默认跳过)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 9. 场景:Git 提交 / 分支管理
|
|
164
|
+
|
|
165
|
+
**用户典型话术**:"提交"、"发布"、"打 tag"
|
|
166
|
+
|
|
167
|
+
**推荐**:遵循 `standards/08-*.md` Git 规范,使用 `pnpm cz` / `pnpm release:*` 命令。
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 10. 索引:Skill / MCP 工具速查
|
|
172
|
+
|
|
173
|
+
### Skills(详见 `_registry.md`)
|
|
174
|
+
|
|
175
|
+
| Skill | 一句话 |
|
|
176
|
+
|---|---|
|
|
177
|
+
| prototype-scan | 原型/详设 → 页面清单 |
|
|
178
|
+
| business-doc-extract | 模块级资料 → 业务文档沉淀 |
|
|
179
|
+
| api-contract | 生成 `api.md` 接口约定 |
|
|
180
|
+
| page-codegen | 生成 Vue 页面三件套 + api.md + SYS_MENU_INFO.md |
|
|
181
|
+
| convention-audit | 13 条规范审计 |
|
|
182
|
+
| code-fix | 按审计报告自动修复 |
|
|
183
|
+
| menu-sync | 后端菜单同步(MCP)|
|
|
184
|
+
| dict-sync | 后端字典同步(MCP)|
|
|
185
|
+
| permission-sync | 角色 / 授权 / 动作(MCP)|
|
|
186
|
+
| template-extract | 成熟页面沉淀为模板 |
|
|
187
|
+
|
|
188
|
+
### MCP 工具(详见 `mcp/registry.js`)
|
|
189
|
+
|
|
190
|
+
| 工具 | 用途 |
|
|
191
|
+
|---|---|
|
|
192
|
+
| `wls_menu_query` / `wls_menu_upsert` / `wls_menu_sync_from_report` | 菜单 |
|
|
193
|
+
| `wls_dict_query` / `wls_dict_upsert` | 字典 |
|
|
194
|
+
| `wls_role_query` / `wls_role_upsert` / `wls_assignable_menus_query` / `wls_role_assign_menus` / `wls_action_query` / `wls_action_upsert` | 角色 / 授权 / 动作 |
|
|
195
|
+
| `wls_code_scan` / `wls_validate_page` / `wls_doctor_ui` / `wls_route_check` / `wls_git_log_extract` / `wls_audit_report_push` | 辅助 |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 11. 如何扩展本文件
|
|
200
|
+
|
|
201
|
+
新增场景请按此模板:
|
|
202
|
+
|
|
203
|
+
```markdown
|
|
204
|
+
## N. 场景:{一句话描述}
|
|
205
|
+
|
|
206
|
+
**用户典型话术**:
|
|
207
|
+
- "..."
|
|
208
|
+
|
|
209
|
+
**推荐流程**:
|
|
210
|
+
- 用什么 Skill / MCP 工具
|
|
211
|
+
- 关键顺序
|
|
212
|
+
- 配置依赖
|
|
213
|
+
|
|
214
|
+
**避坑**:
|
|
215
|
+
- ...
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
> ✅ AI 在每轮对话开始时(首次进入项目或长时间未刷新上下文时),优先 `read_file` 加载本文件 + `_registry.md` + `_pipeline.md`,三者联合作为路由依据。
|
|
@@ -39,30 +39,34 @@ skills/
|
|
|
39
39
|
|
|
40
40
|
## 启用 Skill 路由表
|
|
41
41
|
|
|
42
|
-
| Skill 名 | 状态 | 路径 | 触发关键词 |
|
|
43
|
-
| ---------------- | ------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
44
|
-
| prototype-scan | ✅ 启用 | `skills/core/prototype-scan/SKILL.md` | 扫描原型 / 解析原型 / 页面清单 / 详设文档 / 口述需求 / 建个页面 / 写个页面 / 根据截图 / 根据原型 |
|
|
45
|
-
| api-contract | ✅ 启用 | `skills/core/api-contract/SKILL.md` | 接口约定 / api.md / 字段定义 / 前后端对齐 / 接口设计 |
|
|
46
|
-
| page-codegen | ✅ 启用 | `skills/core/page-codegen/SKILL.md` | 生成页面 / 创建页面 / 代码生成 / vue页面 / 按原型生成 / 帮我生成 / 列表页 / 管理页 / 台账 / mock / 假数据 / 先能跑 / AGGrid / skills-ui |
|
|
47
|
-
| convention-audit | ✅ 启用 | `skills/core/convention-audit/SKILL.md` | 规范审计 / 代码审计 / 规范检查 / 对齐规范 / 规范偏差 / 接手新项目 / 存量代码分析 / 项目体检 |
|
|
48
|
-
| business-doc-extract | ✅ 启用 | `skills/core/business-doc-extract/SKILL.md` | **语义级触发,不依赖固定关键词**:用户提供原型 / 详设 / 字段或字典资料 / 现有页面 + api.md,且意图为业务梳理 / 模块沉淀 / 字段字典维护 / 待确认事项整理时触发;碎片化问答、单截图、小修小改默认不触发 |
|
|
49
|
-
| template-extract | ✅ 启用 | `skills/core/template-extract/SKILL.md` | 提取模板 / 抽取模板 / 沉淀模板 / 模板贡献 |
|
|
50
|
-
| menu-sync | ✅ 启用 | `skills/sync/menu-sync/SKILL.md` | 创建菜单 / 注册菜单 / 同步菜单 / 补菜单 / 页面点击进不来 / 菜单打不开 |
|
|
51
|
-
| dict-sync | ✅ 启用 | `skills/sync/dict-sync/SKILL.md` | 同步字典 / 创建字典 / 刷新字典基线 / 字典对比 / 字典审计 |
|
|
52
|
-
| permission-sync | ✅ 启用 | `skills/sync/permission-sync/SKILL.md` | 创建角色 / 角色管理 / 角色授权 / 给角色分配菜单 / 挂动作 / 添加动作按钮 / 同步权限 / 权限码注册 |
|
|
53
|
-
| code-fix | ✅ 启用 | `skills/ops/code-fix/SKILL.md` | 自动修复 / 整改偏差 / 修复报告 / 规范整改 / 修复偏差 / code fix |
|
|
42
|
+
| Skill 名 | 状态 | 路径 | MCP 工具依赖 | 触发关键词 |
|
|
43
|
+
| ---------------- | ------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
44
|
+
| prototype-scan | ✅ 启用 | `skills/core/prototype-scan/SKILL.md` | — | 扫描原型 / 解析原型 / 页面清单 / 详设文档 / 口述需求 / 建个页面 / 写个页面 / 根据截图 / 根据原型 |
|
|
45
|
+
| api-contract | ✅ 启用 | `skills/core/api-contract/SKILL.md` | — | 接口约定 / api.md / 字段定义 / 前后端对齐 / 接口设计 |
|
|
46
|
+
| page-codegen | ✅ 启用 | `skills/core/page-codegen/SKILL.md` | `wls_validate_page` / `wls_doctor_ui` | 生成页面 / 创建页面 / 代码生成 / vue页面 / 按原型生成 / 帮我生成 / 列表页 / 管理页 / 台账 / mock / 假数据 / 先能跑 / AGGrid / skills-ui |
|
|
47
|
+
| convention-audit | ✅ 启用 | `skills/core/convention-audit/SKILL.md` | `wls_code_scan` / `wls_audit_report_push` | 规范审计 / 代码审计 / 规范检查 / 对齐规范 / 规范偏差 / 接手新项目 / 存量代码分析 / 项目体检 |
|
|
48
|
+
| business-doc-extract | ✅ 启用 | `skills/core/business-doc-extract/SKILL.md` | — | **语义级触发,不依赖固定关键词**:用户提供原型 / 详设 / 字段或字典资料 / 现有页面 + api.md,且意图为业务梳理 / 模块沉淀 / 字段字典维护 / 待确认事项整理时触发;碎片化问答、单截图、小修小改默认不触发 |
|
|
49
|
+
| template-extract | ✅ 启用 | `skills/core/template-extract/SKILL.md` | — | 提取模板 / 抽取模板 / 沉淀模板 / 模板贡献 |
|
|
50
|
+
| menu-sync | ✅ 启用 | `skills/sync/menu-sync/SKILL.md` | `wls_menu_sync_from_report` / `wls_menu_query` / `wls_menu_upsert` | 创建菜单 / 注册菜单 / 同步菜单 / 补菜单 / 页面点击进不来 / 菜单打不开 |
|
|
51
|
+
| dict-sync | ✅ 启用 | `skills/sync/dict-sync/SKILL.md` | `wls_dict_query` / `wls_dict_upsert` | 同步字典 / 创建字典 / 刷新字典基线 / 字典对比 / 字典审计 |
|
|
52
|
+
| permission-sync | ✅ 启用 | `skills/sync/permission-sync/SKILL.md` | `wls_role_query` / `wls_role_upsert` / `wls_assignable_menus_query` / `wls_role_assign_menus` / `wls_action_query` / `wls_action_upsert` | 创建角色 / 角色管理 / 角色授权 / 给角色分配菜单 / 挂动作 / 添加动作按钮 / 同步权限 / 权限码注册 |
|
|
53
|
+
| code-fix | ✅ 启用 | `skills/ops/code-fix/SKILL.md` | — | 自动修复 / 整改偏差 / 修复报告 / 规范整改 / 修复偏差 / code fix |
|
|
54
|
+
|
|
55
|
+
> **MCP 工具依赖说明**:sync 类 Skill 必须通过列出的 MCP 工具执行。工具不可用或返回错误时,遵循 `skills/sync/_mcp-guardrail.md` §2 自愈剧本(引导用户完善 `env.local.json` 后重试),**不允许** AI 用 curl/PowerShell/fetch 等绕开 MCP。
|
|
54
56
|
|
|
55
57
|
---
|
|
56
58
|
|
|
57
59
|
## 调度规则
|
|
58
60
|
|
|
59
|
-
1.
|
|
60
|
-
2.
|
|
61
|
-
3.
|
|
62
|
-
4.
|
|
63
|
-
5.
|
|
64
|
-
6.
|
|
65
|
-
7. `
|
|
61
|
+
1. **首先加载** `_best-practices.md`(场景索引,语义级路由依据),结合用户意图判断属于哪个场景
|
|
62
|
+
2. 按场景指向的 Skill,`read_file` 加载对应 SKILL.md
|
|
63
|
+
3. SKILL.md 中标注的 `必读 standards` 按 `standards/index.md` 任务类型映射加载
|
|
64
|
+
4. sync 类(菜单/字典/权限)任务必须额外加载 `skills/sync/_mcp-guardrail.md`
|
|
65
|
+
5. 如用户表达连续交付/智能体/全流程意图,同时读取 `_pipeline.md` 获取 Skill I/O 与 `next_suggest`
|
|
66
|
+
6. 在 SKILL.md 指示下输出 **Pre-flight 声明**(强制约定式输出)
|
|
67
|
+
7. 页面生成任务必须额外读取 `standards/12-base-table.md`,并执行 `BaseTable + render-type="agGrid" + cid + defineColumns + renderOps` 硬约束
|
|
68
|
+
8. 若消息包含"风格 / skills-ui / 状态标签 / 操作列 / AGGrid",同时建议运行 `wl-skills doctor-ui`
|
|
69
|
+
9. `business-doc-extract` 不依赖关键词匹配,AI 必须按 `资料源 + 意图 + 范围` 三因素自行判断;缺资料时先询问用户提供原型/详设/字段资料路径,不要凭推断写入 `docs/business`
|
|
66
70
|
|
|
67
71
|
---
|
|
68
72
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Sync Skill 通用护栏(MCP 调用纪律 + 自愈闭环)
|
|
2
|
+
|
|
3
|
+
> 所有 sync 类 Skill(menu-sync / dict-sync / permission-sync)共用本规则。
|
|
4
|
+
> SKILL.md 顶部需引用本文件,确保 AI 行为一致。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. 调用纪律(AI 必读)
|
|
9
|
+
|
|
10
|
+
- ✅ **首选**:通过本 Skill 在「MCP 工具调用规范」中列出的工具调用(`wls_*`)
|
|
11
|
+
- ❌ **严禁**:使用 `curl` / `Invoke-RestMethod` / `Invoke-WebRequest` / `fetch` / `axios` / `Send-WebRequest` 等任何 shell 命令或代码直接发起 HTTP 请求
|
|
12
|
+
- ❌ **严禁**:自行推测、拼接、或从历史对话沿用接口路径
|
|
13
|
+
- ❌ **严禁**:在 SKILL.md 中看到 `POST /system/xxx/save` 字样后据此手动调用——HTTP 路径仅为 MCP **内部实现说明**
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 2. 自愈闭环(MCP 异常时 AI 该怎么做)
|
|
18
|
+
|
|
19
|
+
> 不是"立即停止",而是"按层级引导用户完善配置,让它能跑通"。原则:**优先帮用户闭环,最后才放弃**。
|
|
20
|
+
|
|
21
|
+
### 2.1 错误分层判定
|
|
22
|
+
|
|
23
|
+
AI 调用 MCP 工具后,按返回内容判定属于哪一类,并按对应剧本处理:
|
|
24
|
+
|
|
25
|
+
| 错误特征 | 归类 | 处理剧本 |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| 工具不在 `tools/list` 中(编辑器根本没识别到 wls_*)| L0 MCP 未连接 | 走 §2.2 |
|
|
28
|
+
| 工具返回"❌ 配置加载失败"/"配置文件不存在"/"请填写真实的 xxx" | L1 配置缺失 | 走 §2.3 |
|
|
29
|
+
| 工具返回 `code === 401` 或包含 "token"/"鉴权"/"未登录" 字样 | L2 Token 失效 | 走 §2.4 |
|
|
30
|
+
| 工具返回 `code === 4004` / "url:GET; ..." / 接口不存在 | L3 接口路径不匹配 | 走 §2.5 |
|
|
31
|
+
| 工具返回业务错误(参数错误、唯一键冲突等) | L4 业务层 | 按工具返回的提示给用户看,不需要 fallback |
|
|
32
|
+
|
|
33
|
+
### 2.2 L0 — MCP 未连接
|
|
34
|
+
|
|
35
|
+
引导(不要默认放弃):
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
🔧 当前编辑器似乎未识别到 wls_* 工具,请按顺序检查:
|
|
39
|
+
1. 编辑器的 MCP 配置文件存在吗?(Cursor/Kiro/Trae: 见各自 mcp.json)
|
|
40
|
+
2. 配置里 WL_PROJECT_ROOT 指向当前项目根了吗?
|
|
41
|
+
3. 重启编辑器后再看 MCP 面板的工具列表
|
|
42
|
+
|
|
43
|
+
请告诉我以上哪一步通不过,我帮你定位。
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
仅在用户明确表示**无法启用 MCP** 时,才退化为「手工去后台维护」的人肉方案,且**不再尝试**让 AI 拼 HTTP。
|
|
47
|
+
|
|
48
|
+
### 2.3 L1 — 配置缺失 / 占位值未替换
|
|
49
|
+
|
|
50
|
+
如果工具返回类似:
|
|
51
|
+
- `请在 env.local.json 中填写真实的 gatewayPath(当前为占位值)`
|
|
52
|
+
- `请在 .github/skills/sync/env.local.json 填写 menu.domainId`
|
|
53
|
+
- `配置文件不存在: .../env.local.json`
|
|
54
|
+
|
|
55
|
+
AI **立即转入引导模式**:
|
|
56
|
+
|
|
57
|
+
1. `read_file` 加载 `.github/skills/sync/menu-sync/env/guide.md`(统一配置说明)
|
|
58
|
+
2. 告诉用户具体哪个字段缺失、获取方式(如 token 抓包、domainId Network 查询)
|
|
59
|
+
3. 等待用户填好 `env.local.json` 后**自动重试同一个 MCP 工具调用**
|
|
60
|
+
4. 直到配置完整、调用成功为止 → 完成闭环
|
|
61
|
+
|
|
62
|
+
### 2.4 L2 — Token 失效
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
🔑 Token 似乎已过期。请:
|
|
66
|
+
1. 浏览器登录系统
|
|
67
|
+
2. F12 → Network → 任意接口 → 复制 authorization 头的值
|
|
68
|
+
3. 去掉开头的 `bearer ` 前缀,把纯 JWT 部分粘到 env.local.json 的 token 字段
|
|
69
|
+
4. 告诉我"token 已更新",我会重新尝试同步
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
更新后**自动重跑**之前失败的 MCP 调用。
|
|
73
|
+
|
|
74
|
+
### 2.5 L3 — 接口路径不匹配(如 4004)
|
|
75
|
+
|
|
76
|
+
后端环境差异可能导致内置接口路径与实际不符。AI 应:
|
|
77
|
+
|
|
78
|
+
1. 提示用户:"当前 MCP 内置的接口路径在你的后端未注册(返回 4004)。可能是该环境网关前缀不同。"
|
|
79
|
+
2. 引导用户:
|
|
80
|
+
- 检查 `env.local.json.gatewayPath` 是否需要补一段前缀(如 `/uac`)
|
|
81
|
+
- 或者联系后端确认该 sync 工具对应的真实路径
|
|
82
|
+
3. **不要**让 AI 自行去猜路径再 curl,否则就是绕开 MCP 的回旋
|
|
83
|
+
4. 路径前缀这类配置类问题可以由用户更新后**重试 MCP 工具**完成闭环
|
|
84
|
+
|
|
85
|
+
> 长期方案:将变化的接口前缀做成 `env.local.json` 中的可配置项,由 kit 维护者在 mcp/api/*.js 中支持读取覆盖。该改动属于 MCP 内部实现,AI 不需要也不应该自行 patch。
|
|
86
|
+
|
|
87
|
+
### 2.6 L4 — 业务错误
|
|
88
|
+
|
|
89
|
+
工具返回的业务层提示(如 "menuName 已存在"、"参数缺失")属正常反馈,AI 直接展示给用户即可,不需要 fallback。
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 3. Pre-flight 自检模板(执行前必须输出)
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
🚀 已触发技能 {skill-name}/SKILL.md → {一句话用途}
|
|
97
|
+
✅ MCP 工具检查:{要用到的 wls_* 全部列出,✓/✗}
|
|
98
|
+
✅ 已读取 .github/skills/sync/env.local.json → gatewayPath/token/sysAppNo/{其他必填}
|
|
99
|
+
✅ 已读取 {本 Skill 的 SYS_*_INFO.md 基线}
|
|
100
|
+
✅ 操作模式:{pull / push / audit / ...}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
任一项 ✗ → 进入 §2 自愈剧本,**不要直接放弃**。
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 4. 一句话总则
|
|
108
|
+
|
|
109
|
+
> **MCP 是默认通路,配置是参数化的;调不通时帮用户改配置,而不是绕开 MCP 自己拼 HTTP。**
|
|
@@ -7,14 +7,21 @@ description: "Use when: syncing data dictionary entries to the backend, pulling
|
|
|
7
7
|
|
|
8
8
|
将 `data.ts` 中引用的数据字典(`logicType: BusLogicDataType.dict, logicValue: "DICT_CODE"`)同步到后端字典表,保持本地基线与线上一致。
|
|
9
9
|
|
|
10
|
-
> **与 menu-sync
|
|
11
|
-
> 配置直接复用 `skills/sync/env.local.json` 统一配置文件,无需重复填写。
|
|
10
|
+
> **与 menu-sync / permission-sync 对称**:同样读取本地基线 → 与线上对比 → 补齐差异。配置共用 `skills/sync/env.local.json`。
|
|
12
11
|
|
|
13
12
|
---
|
|
14
13
|
|
|
15
|
-
##
|
|
14
|
+
## 📖 必读公共护栏
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
本 Skill 遵守 `../_mcp-guardrail.md`(MCP 调用纪律与自愈闭环)。AI 首次执行 sync 类任务时先 `read_file` 加载它。
|
|
17
|
+
|
|
18
|
+
本 Skill 使用的 MCP 工具:`wls_dict_query` / `wls_dict_upsert`。调用失败时按 guardrail §2 剧本引导用户完善 `env.local.json` 后重试,**不得用 curl/手拼 HTTP 绕开 MCP**。
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 配置(统一配置文件)
|
|
23
|
+
|
|
24
|
+
读取 `.github/skills/sync/env.local.json`(已在 `.gitignore`,不入 git):
|
|
18
25
|
|
|
19
26
|
```json
|
|
20
27
|
{
|
|
@@ -27,9 +34,14 @@ description: "Use when: syncing data dictionary entries to the backend, pulling
|
|
|
27
34
|
}
|
|
28
35
|
```
|
|
29
36
|
|
|
30
|
-
|
|
37
|
+
| 字段 | 说明 |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `gatewayPath` | 后端网关,末尾不加斜杠 |
|
|
40
|
+
| `sysAppNo` | 应用编码(非明文) |
|
|
41
|
+
| `token` | 纯 JWT,**不含 `bearer ` 前缀**(MCP 内部自动拼接) |
|
|
42
|
+
| `dict.moduleId` | 字典所属模块 ID(字典管理后台 Network 抓取) |
|
|
31
43
|
|
|
32
|
-
|
|
44
|
+
> 字段获取方式见同目录 `../menu-sync/env/guide.md`。
|
|
33
45
|
|
|
34
46
|
---
|
|
35
47
|
|
|
@@ -37,26 +49,14 @@ description: "Use when: syncing data dictionary entries to the backend, pulling
|
|
|
37
49
|
|
|
38
50
|
```
|
|
39
51
|
🚀 已触发技能 dict-sync/SKILL.md → 字典同步
|
|
40
|
-
✅
|
|
41
|
-
✅ 已读取
|
|
52
|
+
✅ MCP 工具检查:wls_dict_query / wls_dict_upsert 均可用
|
|
53
|
+
✅ 已读取 .github/skills/sync/env.local.json → 网关 + token + sysAppNo + dict.moduleId
|
|
54
|
+
✅ 已读取 .github/reports/SYS_DICT_INFO.md → 本地字典基线
|
|
42
55
|
✅ 操作模式:{pull / push / audit}
|
|
43
|
-
✅ 目标字典码:{用户指定 /
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## API 调用规范
|
|
49
|
-
|
|
50
|
-
所有接口使用以下 Headers:
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
Authorization: Bearer {token}
|
|
54
|
-
Sysappno: {sysAppNo}
|
|
55
|
-
Content-Type: application/json
|
|
56
|
+
✅ 目标字典码:{用户指定 / data.ts 扫描结果}
|
|
56
57
|
```
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
**Token 失效**:`code === 401` 或 `code` 不在 `[200, 2000]` 且 message 含 "token" → 停止执行,提示用户更新 token。
|
|
59
|
+
> Pre-flight 任一项失败(特别是 MCP 工具检查),立即停止并向用户报告,**不得**降级为手动调接口。
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
@@ -66,40 +66,13 @@ Content-Type: application/json
|
|
|
66
66
|
|
|
67
67
|
**触发词**:`刷新字典基线` / `拉字典`
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
调用
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**接口**:
|
|
77
|
-
```
|
|
78
|
-
GET {gatewayPath}/system/business/dict/getDictionaryTreeData
|
|
79
|
-
Headers:
|
|
80
|
-
Authorization: Bearer {token}
|
|
81
|
-
Sysappno: {sysAppNo}
|
|
82
|
-
```
|
|
69
|
+
**执行**:
|
|
70
|
+
1. 调用 MCP 工具 `wls_dict_query`(无参)
|
|
71
|
+
2. 工具返回当前应用域全部字典模块 + 字典项树
|
|
72
|
+
3. AI 解析返回结果,整理为 SYS_DICT_INFO.md 格式覆盖写入
|
|
73
|
+
4. 输出:"共拉取 N 个字典码,M 个字典项"
|
|
83
74
|
|
|
84
|
-
|
|
85
|
-
```json
|
|
86
|
-
{
|
|
87
|
-
"code": 2000,
|
|
88
|
-
"data": {
|
|
89
|
-
"dictionary": {
|
|
90
|
-
"children": [
|
|
91
|
-
{
|
|
92
|
-
"id": "节点ID",
|
|
93
|
-
"strSn": "字典编码或模块编码",
|
|
94
|
-
"strName": "字典名称",
|
|
95
|
-
"children": [...]
|
|
96
|
-
}
|
|
97
|
-
]
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
叶节点(无 `children`)= 实际字典,取其 `id`(用于后续创建字典项)和 `strSn`。
|
|
75
|
+
> MCP 内部对应 `GET /system/business/dict/getDictionaryTreeData`,AI **无需关心**。
|
|
103
76
|
|
|
104
77
|
---
|
|
105
78
|
|
|
@@ -110,93 +83,82 @@ Headers:
|
|
|
110
83
|
#### Step 1:扫描 data.ts 中的字典引用
|
|
111
84
|
|
|
112
85
|
从用户指定范围扫描所有:
|
|
86
|
+
|
|
113
87
|
```typescript
|
|
114
88
|
logicType: BusLogicDataType.dict, logicValue: "DICT_CODE"
|
|
115
89
|
```
|
|
116
|
-
|
|
90
|
+
|
|
91
|
+
去重得到「当前用到的字典码集合」。
|
|
117
92
|
|
|
118
93
|
#### Step 2:与本地基线 + 线上对比(去重双保险)
|
|
119
94
|
|
|
120
95
|
```
|
|
121
|
-
① 读取 reports/SYS_DICT_INFO.md →
|
|
122
|
-
② 调用
|
|
96
|
+
① 读取 reports/SYS_DICT_INFO.md → 本地已知字典码
|
|
97
|
+
② 调用 wls_dict_query → 线上当前字典码(strSn 列表)
|
|
123
98
|
③ 待创建 = 用到的字典码 - 线上已有字典码
|
|
124
99
|
```
|
|
125
100
|
|
|
126
|
-
>
|
|
127
|
-
> 去重通过 Step ② 线上实时查询保证:A 创建了,B 运行时线上已有,自动跳过,**不会重复创建**。
|
|
128
|
-
> 即使极端并发(两人同一秒执行),后端 `strSn` 字段有唯一约束,第二次创建会返回"已存在",Skill 将其视为成功跳过。
|
|
101
|
+
> **多人协同**:每人 env.local.json 不入 git。去重通过 ② 线上实时查询保证;后端 `strSn` 字段有唯一约束,并发场景下第二次创建会被服务端跳过,Skill 视为成功。
|
|
129
102
|
|
|
130
|
-
#### Step 3:Pre-flight
|
|
103
|
+
#### Step 3:Pre-flight 输出待新建清单,等待确认
|
|
131
104
|
|
|
132
105
|
```
|
|
133
106
|
📋 待同步字典清单:
|
|
134
107
|
新建:ORDER_STATUS(订单状态)— 含 4 项
|
|
135
108
|
新建:SALES_COMPANY(销售公司)— 含 3 项
|
|
136
109
|
跳过(线上已有):PRODUCT_SEGMENT
|
|
137
|
-
|
|
138
110
|
确认执行?(yes/no)
|
|
139
111
|
```
|
|
140
112
|
|
|
141
|
-
#### Step 4
|
|
113
|
+
#### Step 4:批量创建字典码 + 字典项
|
|
142
114
|
|
|
143
|
-
|
|
144
|
-
POST {gatewayPath}/system/business/dict/save
|
|
145
|
-
Headers: Authorization / Sysappno / Content-Type
|
|
115
|
+
调用 MCP 工具 `wls_dict_upsert`(**逐个字典模块**调一次):
|
|
146
116
|
|
|
147
|
-
|
|
117
|
+
```jsonc
|
|
118
|
+
// MCP 工具入参
|
|
148
119
|
{
|
|
149
|
-
"
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
120
|
+
"module": {
|
|
121
|
+
"strSn": "ORDER_STATUS",
|
|
122
|
+
"strName": "订单状态",
|
|
123
|
+
"sortPriority": "1",
|
|
124
|
+
"strLevel": 2
|
|
125
|
+
},
|
|
126
|
+
"items": [
|
|
127
|
+
{ "strSn": "0", "strName": "草稿", "strLevel": 2 },
|
|
128
|
+
{ "strSn": "1", "strName": "待审核", "strLevel": 2 },
|
|
129
|
+
{ "strSn": "2", "strName": "已通过", "strLevel": 2 },
|
|
130
|
+
{ "strSn": "3", "strName": "已驳回", "strLevel": 2 }
|
|
131
|
+
]
|
|
154
132
|
}
|
|
155
133
|
```
|
|
156
134
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
#### Step 5:创建字典项
|
|
160
|
-
|
|
161
|
-
**逐条**调用(服务端会跳过重复的 strKey):
|
|
162
|
-
|
|
163
|
-
```
|
|
164
|
-
POST {gatewayPath}/system/dictDtl/save
|
|
165
|
-
Headers: Authorization / Sysappno / Content-Type
|
|
166
|
-
|
|
167
|
-
Body:
|
|
168
|
-
{
|
|
169
|
-
"strKey": "1",
|
|
170
|
-
"strValue": "待审核",
|
|
171
|
-
"strSn": "ORDER_STATUS",
|
|
172
|
-
"dictId": "{上一步获取的字典 id}"
|
|
173
|
-
}
|
|
174
|
-
```
|
|
135
|
+
> 工具内部:模块不存在则创建并自动 re-query 取 id;字典项按 strSn 自动跳过已存在项。AI 无需手动管理 id。
|
|
175
136
|
|
|
176
|
-
#### Step
|
|
137
|
+
#### Step 5:输出结果表 + 更新基线
|
|
177
138
|
|
|
178
139
|
| 字典码 | 字典名称 | 字典项数 | 状态 |
|
|
179
|
-
|
|
140
|
+
|---|---|---|---|
|
|
180
141
|
| ORDER_STATUS | 订单状态 | 4 | ✅ created |
|
|
181
142
|
| SALES_COMPANY | 销售公司 | 3 | ✅ created |
|
|
182
143
|
| PRODUCT_SEGMENT | 产品板块 | - | ⏭️ skipped(线上已有) |
|
|
183
144
|
|
|
184
|
-
执行完成后,将新建字典追加写入
|
|
145
|
+
执行完成后,将新建字典追加写入 `.github/reports/SYS_DICT_INFO.md`。
|
|
185
146
|
|
|
186
147
|
---
|
|
187
148
|
|
|
188
|
-
### audit —
|
|
149
|
+
### audit — 仅检查,不调写接口
|
|
189
150
|
|
|
190
151
|
**触发词**:`字典审计` / `检查字典`
|
|
191
152
|
|
|
192
153
|
```
|
|
193
154
|
1. 扫描指定范围的 data.ts,收集所有 logicValue 字典码
|
|
194
|
-
2.
|
|
195
|
-
3.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
155
|
+
2. 调用 wls_dict_query 获取线上现状
|
|
156
|
+
3. 对比 SYS_DICT_INFO.md 本地基线
|
|
157
|
+
4. 输出三类清单:
|
|
158
|
+
✅ 已在基线 + 线上(健康)
|
|
159
|
+
⚠️ data.ts 用到但缺失(建议执行 push)
|
|
160
|
+
💤 在基线但未被任何 data.ts 引用(可能已废弃)
|
|
161
|
+
5. 不调用任何写接口
|
|
200
162
|
```
|
|
201
163
|
|
|
202
164
|
---
|
|
@@ -208,244 +170,39 @@ Body:
|
|
|
208
170
|
```markdown
|
|
209
171
|
## ORDER_STATUS(订单状态)
|
|
210
172
|
|
|
211
|
-
| 值(
|
|
212
|
-
|
|
|
213
|
-
| 0
|
|
214
|
-
| 1
|
|
215
|
-
| 2
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
**字典码命名规范**:全大写 + 下划线,如 `ORDER_STATUS` / `SALES_COMPANY`(来自项目实际 data.ts 用法)。
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
|
-
## 与其他 Skill 联动
|
|
223
|
-
|
|
224
|
-
| Skill | 联动方式 |
|
|
225
|
-
|-------|---------|
|
|
226
|
-
| **page-codegen** | 生成 data.ts 时,如 `logicValue` 不在基线中,报告末尾提示"建议运行 dict-sync 补齐" |
|
|
227
|
-
| **convention-audit** | 可调用 audit 模式,"字典码未在基线"列为 🟡 偏差 |
|
|
228
|
-
| **menu-sync** | 共享 `skills/sync/env.local.json`,gatewayPath / token / sysAppNo 同一份配置 |
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
# Skill: 字典同步(dict-sync)
|
|
232
|
-
|
|
233
|
-
将 `data.ts` 中引用的数据字典(`logicType: BusLogicDataType.dict`)同步到后端字典表,保持本地基线与线上一致。
|
|
234
|
-
|
|
235
|
-
> **与 menu-sync 的关系**:机制完全对称——同样读取本地基线报告 → 与线上对比 → 补齐差异。
|
|
236
|
-
> 配置直接复用 `menu-sync/env/env.local.json`,无需重复填写。
|
|
237
|
-
|
|
238
|
-
---
|
|
239
|
-
|
|
240
|
-
## ⚠️ 激活前请确认 3 个 API 端点
|
|
241
|
-
|
|
242
|
-
在开始使用本 Skill 前,请与后端团队核实以下 3 个接口路径,并将正确路径填入本文件对应位置(搜索 `TODO_CONFIRM`):
|
|
243
|
-
|
|
244
|
-
| # | 用途 | 草稿路径(待确认) | 确认方式 |
|
|
245
|
-
|---|------|--------------------|---------|
|
|
246
|
-
| 1 | 查询全量字典列表(去重用) | `GET /system/dict/list` | DevTools → 进入"数据字典"列表页 → 查看 Network |
|
|
247
|
-
| 2 | 创建/更新单个字典码 | `POST /system/dict/save` | DevTools → 新增一条字典 → 查看 Request URL + Body |
|
|
248
|
-
| 3 | 批量保存字典项(value/label) | `POST /system/dictItem/save` | DevTools → 为字典添加项 → 查看 Request URL + Body |
|
|
249
|
-
|
|
250
|
-
确认完成后,删除此区块即可正式使用。
|
|
251
|
-
|
|
252
|
-
---
|
|
253
|
-
|
|
254
|
-
## 配置(复用 menu-sync,无需重复填写)
|
|
255
|
-
|
|
256
|
-
本 Skill 读取顺序:
|
|
257
|
-
|
|
258
|
-
1. 优先读取 `skills/sync/dict-sync/env/env.local.json`(如存在)
|
|
259
|
-
2. 回落到 `skills/sync/menu-sync/env/env.local.json`(_inherit 机制)
|
|
260
|
-
|
|
261
|
-
**绝大多数情况下无需单独创建字典配置**——menu-sync 配置的 `gatewayPath`、`token`、`sysAppNo` 完全共用。
|
|
262
|
-
|
|
263
|
-
仅当字典接口需要独立 token 或不同网关时,才在 `dict-sync/env/env.local.json` 单独配置:
|
|
264
|
-
|
|
265
|
-
```json
|
|
266
|
-
{
|
|
267
|
-
"gatewayPath": "http://网关地址:端口",
|
|
268
|
-
"sysAppNo": "应用编码",
|
|
269
|
-
"token": "Bearer Token(不含 bearer 前缀)"
|
|
270
|
-
}
|
|
173
|
+
| 值(strSn) | 显示名称(strName) | 备注 |
|
|
174
|
+
| ---------- | ------------------ | ---- |
|
|
175
|
+
| 0 | 草稿 | |
|
|
176
|
+
| 1 | 待审核 | |
|
|
177
|
+
| 2 | 已通过 | |
|
|
178
|
+
| 3 | 已驳回 | |
|
|
271
179
|
```
|
|
272
180
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
## Pre-flight 声明(执行前必须输出)
|
|
276
|
-
|
|
277
|
-
```
|
|
278
|
-
🚀 已触发技能 dict-sync/SKILL.md → 字典同步
|
|
279
|
-
✅ 已读取 menu-sync/env/env.local.json → 网关地址、token、sysAppNo
|
|
280
|
-
✅ 已读取 reports/SYS_DICT_INFO.md → 本地字典基线
|
|
281
|
-
✅ 操作模式:{pull / push / audit}
|
|
282
|
-
✅ 目标字典码:{用户指定 / 从 data.ts 扫描到的字典码列表}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
---
|
|
286
|
-
|
|
287
|
-
## SYS_DICT_INFO.md — 本地基线格式
|
|
288
|
-
|
|
289
|
-
路径:`.github/reports/SYS_DICT_INFO.md`
|
|
290
|
-
|
|
291
|
-
写入规范(每次 pull 后覆盖更新,push 后追加):
|
|
292
|
-
|
|
293
|
-
```markdown
|
|
294
|
-
## {DICT_CODE}({字典中文名})
|
|
295
|
-
|
|
296
|
-
| 值(value) | 显示名称(label) | 排序 | 备注 |
|
|
297
|
-
| ---------- | ---------------- | ---- | ---- |
|
|
298
|
-
| 0 | 草稿 | 1 | |
|
|
299
|
-
| 1 | 待审核 | 2 | |
|
|
300
|
-
| 2 | 审核通过 | 3 | |
|
|
301
|
-
| 3 | 已驳回 | 4 | |
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
**字典码命名规范**(来自项目 data.ts 分析):
|
|
305
|
-
|
|
306
|
-
| 风格 | 正确 ✅ | 错误 ❌ |
|
|
307
|
-
|------|---------|---------|
|
|
308
|
-
| 全大写+下划线 | `ORDER_STATUS` / `SALES_COMPANY` | `orderStatus` / `salesCompany` |
|
|
309
|
-
|
|
310
|
-
---
|
|
311
|
-
|
|
312
|
-
## 三种工作模式
|
|
313
|
-
|
|
314
|
-
### pull — 刷新本地基线
|
|
315
|
-
|
|
316
|
-
**触发词**:`刷新字典基线` / `拉字典`
|
|
317
|
-
|
|
318
|
-
```
|
|
319
|
-
1. 调用 GET {TODO_CONFIRM: /system/dict/list?size=500} → 获取全量字典
|
|
320
|
-
2. 整理为 SYS_DICT_INFO.md 格式
|
|
321
|
-
3. 覆盖写入 reports/SYS_DICT_INFO.md
|
|
322
|
-
4. 输出:共拉取 N 个字典码,M 个字典项
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**接口调用**:
|
|
326
|
-
```
|
|
327
|
-
GET {gatewayPath}/system/dict/list?current=1&size=500 ← TODO_CONFIRM 路径
|
|
328
|
-
Headers:
|
|
329
|
-
authorization: bearer {token}
|
|
330
|
-
Sysappno: {sysAppNo}
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
**响应处理**:取 `data.records`(或 `data.list`,以实际为准),`code === 2000` 为成功。
|
|
334
|
-
|
|
335
|
-
---
|
|
336
|
-
|
|
337
|
-
### push — 推送新增字典(核心模式)
|
|
338
|
-
|
|
339
|
-
**触发词**:`同步字典` / `创建字典` / `补字典`
|
|
340
|
-
|
|
341
|
-
#### Step 1:扫描当前 data.ts 中的字典引用
|
|
342
|
-
|
|
343
|
-
从用户指定范围(单文件 / 整个 src/views/)扫描所有:
|
|
344
|
-
```typescript
|
|
345
|
-
logicType: BusLogicDataType.dict, logicValue: "DICT_CODE"
|
|
346
|
-
```
|
|
347
|
-
收集所有 `logicValue` 值,去重后得到「当前用到的字典码集合」。
|
|
348
|
-
|
|
349
|
-
#### Step 2:与本地基线对比
|
|
350
|
-
|
|
351
|
-
读取 `reports/SYS_DICT_INFO.md`,找出「未在基线中的字典码」(即需要新建的字典)。
|
|
352
|
-
|
|
353
|
-
> 若本地基线为空或过期,提示用户先执行 `pull` 模式拉取基线。
|
|
354
|
-
|
|
355
|
-
#### Step 3:Pre-flight 输出待新建清单
|
|
356
|
-
|
|
357
|
-
在执行任何 API 调用前,输出:
|
|
358
|
-
|
|
359
|
-
```
|
|
360
|
-
📋 待同步字典清单:
|
|
361
|
-
新建字典码:ORDER_STATUS(订单状态)— 含 4 个字典项
|
|
362
|
-
新建字典码:SALES_COMPANY(销售公司)— 含 3 个字典项
|
|
363
|
-
跳过(已在基线中):PRODUCT_SEGMENT
|
|
364
|
-
|
|
365
|
-
确认执行?(yes/no)
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
等待用户确认后再执行。
|
|
369
|
-
|
|
370
|
-
#### Step 4:逐条创建字典码
|
|
371
|
-
|
|
372
|
-
```
|
|
373
|
-
POST {gatewayPath}/system/dict/save ← TODO_CONFIRM 路径
|
|
374
|
-
Headers:
|
|
375
|
-
authorization: bearer {token}
|
|
376
|
-
Sysappno: {sysAppNo}
|
|
377
|
-
Content-Type: application/json
|
|
378
|
-
|
|
379
|
-
Body(待确认字段名):
|
|
380
|
-
{
|
|
381
|
-
"dictCode": "ORDER_STATUS",
|
|
382
|
-
"dictName": "订单状态",
|
|
383
|
-
"remark": ""
|
|
384
|
-
}
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
#### Step 5:批量写入字典项
|
|
388
|
-
|
|
389
|
-
```
|
|
390
|
-
POST {gatewayPath}/system/dictItem/save ← TODO_CONFIRM 路径
|
|
391
|
-
Headers:
|
|
392
|
-
authorization: bearer {token}
|
|
393
|
-
Sysappno: {sysAppNo}
|
|
394
|
-
Content-Type: application/json
|
|
395
|
-
|
|
396
|
-
Body(待确认字段名,按实际接口响应调整):
|
|
397
|
-
{
|
|
398
|
-
"dictCode": "ORDER_STATUS",
|
|
399
|
-
"items": [
|
|
400
|
-
{ "dictItemValue": "0", "dictItemLabel": "草稿", "sortNo": 1 },
|
|
401
|
-
{ "dictItemValue": "1", "dictItemLabel": "待审核", "sortNo": 2 }
|
|
402
|
-
]
|
|
403
|
-
}
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
#### Step 6:输出结果表
|
|
407
|
-
|
|
408
|
-
| 字典码 | 字典名称 | 字典项数 | 状态 |
|
|
409
|
-
|--------|---------|---------|------|
|
|
410
|
-
| ORDER_STATUS | 订单状态 | 4 | ✅ created |
|
|
411
|
-
| SALES_COMPANY | 销售公司 | 3 | ✅ created |
|
|
412
|
-
| PRODUCT_SEGMENT | 产品板块 | 5 | ⏭️ skipped(已存在) |
|
|
413
|
-
|
|
414
|
-
执行完成后,将新建字典追加写入 `reports/SYS_DICT_INFO.md`。
|
|
415
|
-
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
### audit — 仅检查,不调接口
|
|
419
|
-
|
|
420
|
-
**触发词**:`字典审计` / `检查字典`
|
|
421
|
-
|
|
422
|
-
```
|
|
423
|
-
1. 扫描指定范围的 data.ts,收集所有 logicValue 字典码
|
|
424
|
-
2. 与 SYS_DICT_INFO.md 基线对比
|
|
425
|
-
3. 输出三个清单:
|
|
426
|
-
✅ 已在基线中(无需操作)
|
|
427
|
-
⚠️ 在 data.ts 中使用但不在基线中(建议执行 push)
|
|
428
|
-
💤 在基线中但未被任何 data.ts 使用(可能已废弃)
|
|
429
|
-
4. 不调用任何接口
|
|
430
|
-
```
|
|
181
|
+
**字典码命名规范**:全大写 + 下划线,如 `ORDER_STATUS` / `SALES_COMPANY`。
|
|
431
182
|
|
|
432
183
|
---
|
|
433
184
|
|
|
434
185
|
## 冲突处理原则
|
|
435
186
|
|
|
436
187
|
| 场景 | 策略 |
|
|
437
|
-
|
|
438
|
-
|
|
|
439
|
-
|
|
|
440
|
-
| 字典项
|
|
441
|
-
|
|
|
188
|
+
|---|---|
|
|
189
|
+
| 本地新增、线上不存在 | 调 `wls_dict_upsert` 创建 |
|
|
190
|
+
| 字典码已存在、字典名不同 | 询问用户:以本地为准 / 保留线上 / 跳过 |
|
|
191
|
+
| 字典项 strSn 相同、strName 不同 | 询问用户决定(Skill 默认跳过,不覆盖) |
|
|
192
|
+
| 线上存在、本地无记录 | 仅在 audit 中报告,**绝不主动删除** |
|
|
442
193
|
|
|
443
194
|
---
|
|
444
195
|
|
|
445
196
|
## 与其他 Skill 联动
|
|
446
197
|
|
|
447
198
|
| Skill | 联动方式 |
|
|
448
|
-
|
|
449
|
-
| **page-codegen** | 生成 data.ts
|
|
450
|
-
| **convention-audit** |
|
|
451
|
-
| **menu-sync** | 共享 env.local.json
|
|
199
|
+
|---|---|
|
|
200
|
+
| **page-codegen** | 生成 data.ts 时如 `logicValue` 不在基线中,报告末尾提示"建议运行 dict-sync 补齐" |
|
|
201
|
+
| **convention-audit** | 调用 audit 模式,"字典码未在基线"列为 🟡 偏差 |
|
|
202
|
+
| **menu-sync / permission-sync** | 共享 `skills/sync/env.local.json`,gatewayPath / token / sysAppNo 同一份 |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## MCP 不可用或调用失败时怎么办
|
|
207
|
+
|
|
208
|
+
见 `../_mcp-guardrail.md` §2 自愈闭环剧本。**原则**:先帮用户完善 `env.local.json` 里的 token / dict.moduleId,重试 MCP 工具。**绝不允许** AI 用 curl/PowerShell/fetch 绕开 MCP 手拼 HTTP。
|
|
@@ -69,16 +69,19 @@ SYS_MENU_INFO.md 是 menu-sync Skill 的输入数据源:
|
|
|
69
69
|
|
|
70
70
|
---
|
|
71
71
|
|
|
72
|
-
## Phase 1:
|
|
72
|
+
## Phase 1:MCP 驱动创建菜单(当前方案)
|
|
73
73
|
|
|
74
|
-
>
|
|
75
|
-
|
|
74
|
+
> 本质是 **menu-sync-design.md 的方案 C(只增不删)**,由 AI 调 MCP 工具自动执行。
|
|
75
|
+
|
|
76
|
+
> 📖 **必读公共护栏**:`../_mcp-guardrail.md`
|
|
77
|
+
> 该文件定义了 MCP 调用纪律、错误分层判定、自愈闭环剧本。AI 首次执行 sync 类任务时必须先 `read_file` 加载它。
|
|
78
|
+
>
|
|
79
|
+
> 本 Skill 使用的 MCP 工具:`wls_menu_sync_from_report` / `wls_menu_query` / `wls_menu_upsert`。工具不可用或调用失败时,按 guardrail §2 剧本引导用户完善 `env.local.json` 后重试,**不得用 curl/手拼 HTTP 绕开 MCP**。
|
|
76
80
|
|
|
77
81
|
### 前置条件
|
|
78
82
|
|
|
79
|
-
1.
|
|
80
|
-
2.
|
|
81
|
-
3. 用户提供父级菜单 ID(`menuId`),可通过查询接口获取
|
|
83
|
+
1. MCP 已连接(工具列表中可见 `wls_menu_sync_from_report`)
|
|
84
|
+
2. `.github/skills/sync/env.local.json` 已填写 `token`(纯 JWT,不含 `bearer ` 前缀)、`gatewayPath`、`sysAppNo`、`menu.parentMenuId`、`menu.domainId`
|
|
82
85
|
|
|
83
86
|
### 输入
|
|
84
87
|
|
|
@@ -96,45 +99,47 @@ SYS_MENU_INFO.md 是 menu-sync Skill 的输入数据源:
|
|
|
96
99
|
| `C` | 菜单(页面) | `menuName`, `path`, `permission`, `component` |
|
|
97
100
|
| `A` | 动作按钮 | `menuName`, `path` |
|
|
98
101
|
|
|
99
|
-
###
|
|
102
|
+
### 执行流程(首选:一步到位)
|
|
100
103
|
|
|
101
|
-
|
|
104
|
+
**默认走 `wls_menu_sync_from_report`**——它内部完成「读报告 → 查菜单树 → 一级目录 upsert → 二级菜单 upsert」全流程:
|
|
102
105
|
|
|
103
106
|
```
|
|
104
|
-
工具:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
工具:wls_menu_sync_from_report
|
|
108
|
+
入参:{ dryRun?: boolean, reportPath?: string } // 不传 reportPath 自动用最新 SYS_MENU_INFO*.md
|
|
109
|
+
第一次执行:先传 dryRun: true 预览,确认无误后再正式执行(去掉 dryRun)
|
|
107
110
|
```
|
|
108
111
|
|
|
109
|
-
|
|
112
|
+
### 手动拆分流程(仅当一步式不满足时)
|
|
110
113
|
|
|
111
|
-
#### Step
|
|
112
|
-
|
|
113
|
-
对于 `SYS_MENU_INFO` 中的一级目录,按 `menuName/path` 在父级 `parentMenuId` 下去重;不存在则创建,存在则复用 id。
|
|
114
|
+
#### Step 1: 查询当前 domain 菜单树(防重复 + 取父级信息)
|
|
114
115
|
|
|
115
|
-
|
|
116
|
+
```
|
|
117
|
+
工具:wls_menu_query (无参,自动读 env.local.json → menu.domainId)
|
|
118
|
+
返回:当前应用域完整菜单树
|
|
119
|
+
```
|
|
116
120
|
|
|
117
|
-
|
|
121
|
+
#### Step 2: 先创建一级目录(type=M),再创建二级页面菜单(type=C)
|
|
118
122
|
|
|
119
|
-
|
|
123
|
+
- 一级目录按 `menuName/path` 在父级 `parentMenuId` 下去重;不存在则创建,存在则复用 id
|
|
124
|
+
- 二级页面菜单的 `parentId` 必须是上一步对应目录的 id,**禁止**全部挂到根 `parentMenuId`
|
|
120
125
|
|
|
121
126
|
```
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
Sysappno: {sysAppNo}
|
|
126
|
-
Content-Type: application/json
|
|
127
|
+
工具:wls_menu_upsert
|
|
128
|
+
入参:{ items: [<下面的对象>...] }
|
|
129
|
+
```
|
|
127
130
|
|
|
128
|
-
|
|
131
|
+
**`items[]` 单条对象模板(仅作为 MCP 入参参考,禁止 AI 自行 fetch)**:
|
|
132
|
+
|
|
133
|
+
```jsonc
|
|
129
134
|
{
|
|
130
135
|
"useCache": 1,
|
|
131
136
|
"icon": "list",
|
|
132
137
|
"common": 2,
|
|
133
138
|
"hidden": false,
|
|
134
|
-
"type": "C",
|
|
135
|
-
"parentId": "{
|
|
139
|
+
"type": "C", // "M"=目录, "C"=菜单, "A"=动作
|
|
140
|
+
"parentId": "{父级目录的 id}",
|
|
136
141
|
"sysAppNo": "{sysAppNo}",
|
|
137
|
-
"orderNum":
|
|
142
|
+
"orderNum": 1,
|
|
138
143
|
"menuName": "客户档案",
|
|
139
144
|
"menuNameCode": "{parentMenuNameCode}:{pinyinName}",
|
|
140
145
|
"path": "mmwrCustomerArchive",
|
|
@@ -143,6 +148,8 @@ Body:
|
|
|
143
148
|
}
|
|
144
149
|
```
|
|
145
150
|
|
|
151
|
+
> **MCP 内部说明**(AI 不可据此自行调接口):底层走 `POST /system/menu/save`,成功码 `code: 2000`。
|
|
152
|
+
|
|
146
153
|
#### Step 3: 记录结果
|
|
147
154
|
|
|
148
155
|
创建完成后输出结果表格:
|
|
@@ -31,18 +31,22 @@
|
|
|
31
31
|
|
|
32
32
|
## 前置条件
|
|
33
33
|
|
|
34
|
-
`.github/skills/sync/
|
|
34
|
+
`.github/skills/sync/env.local.json`(首次使用先填写,已加入 `.gitignore`):
|
|
35
35
|
|
|
36
36
|
```json
|
|
37
37
|
{
|
|
38
|
-
"gatewayPath": "
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
38
|
+
"gatewayPath": "http://192.168.10.50:9000",
|
|
39
|
+
"sysAppNo": "应用编码(非明文,从已有菜单接口响应获取)",
|
|
40
|
+
"token": "eyJhbGci...(纯 JWT,不含 bearer 前缀)",
|
|
41
|
+
"menu": {
|
|
42
|
+
"parentMenuId": "父级菜单 ID(菜单管理后台获取)",
|
|
43
|
+
"domainId": "应用域 ID(Network 面板 getMenuTreeByDomainId?domainId=xxx 获取)"
|
|
44
|
+
}
|
|
42
45
|
}
|
|
43
46
|
```
|
|
44
47
|
|
|
45
|
-
> **`env.local.json` 不入 git
|
|
48
|
+
> **`env.local.json` 不入 git**。每个开发者本地填自己的 token(更新 token 时只换 token 字段,其他不动)。
|
|
49
|
+
> 字段获取详见 `env/guide.md`。
|
|
46
50
|
|
|
47
51
|
---
|
|
48
52
|
|
|
@@ -54,11 +58,11 @@ AI:[Pre-flight]
|
|
|
54
58
|
步骤 1:读取线上菜单基线 reports/SYS_MENU_INFO.md(最新更新:2025-04-20)
|
|
55
59
|
步骤 2:扫描 src/views/produce/aiflow/ 共 7 个页面
|
|
56
60
|
步骤 3:对比缺失:5 项缺失,2 项已存在
|
|
57
|
-
步骤 4:将调用
|
|
61
|
+
步骤 4:将调用 wls_menu_sync_from_report 创建 5 项
|
|
58
62
|
[需你确认]:
|
|
59
|
-
- 父菜单:精整作业 → 客户管理(
|
|
60
|
-
- 排序:
|
|
61
|
-
- 权限标识:
|
|
63
|
+
- 父菜单:精整作业 → 客户管理(menu.parentMenuId: xxx)
|
|
64
|
+
- 排序:orderNum 自动递增
|
|
65
|
+
- 权限标识:mmwrCustomerArchive 等
|
|
62
66
|
确认 yes/no?
|
|
63
67
|
```
|
|
64
68
|
|
|
@@ -78,8 +82,10 @@ AI:[Pre-flight]
|
|
|
78
82
|
| -------------------- | ---------------------------- | ---------------------------------------------- |
|
|
79
83
|
| 同步成功但 UI 看不到 | 用户角色没分配新菜单 | 跑 permission-sync(PLANNED)或后台手工分配 |
|
|
80
84
|
| 401/403 报错 | env.local.json 的 token 过期 | 重新登录系统,从 Network 抓 Authorization 替换 |
|
|
85
|
+
| AI 用 curl/Invoke-RestMethod 调接口,返回 4004 | AI 没走 MCP,自行拼接了错误的接口路径 | 确认 MCP 已连接(Cursor/Kiro 设置里可见 wls_menu_sync_from_report),然后重新说「帮我同步菜单」|
|
|
86
|
+
| token 填了 `Bearer eyJ...` 整串,接口 401 | Authorization Header 变成 `Bearer Bearer eyJ...` | token 字段只填 `eyJ...` 纯 JWT 部分,去掉 `bearer ` 前缀 |
|
|
81
87
|
| 同名菜单重复创建 | 没读 SYS_MENU_INFO.md 基线 | 先跑一遍"刷新基线"再 sync |
|
|
82
|
-
| 父菜单 ID 不对 |
|
|
88
|
+
| 父菜单 ID 不对 | menu.parentMenuId 配错 | 从菜单后台编辑页复制菜单 ID,填入 env.local.json |
|
|
83
89
|
|
|
84
90
|
---
|
|
85
91
|
|
|
@@ -49,6 +49,14 @@ description: "Use when: managing roles, authorizing menus to roles, attaching ac
|
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
52
|
+
## ⚠️ 必读公共护栏
|
|
53
|
+
|
|
54
|
+
本 Skill 遵守 `../_mcp-guardrail.md`(MCP 调用纪律与自愈闭环)。AI 首次执行 sync 类任务时先 `read_file` 加载它。
|
|
55
|
+
|
|
56
|
+
本 Skill 使用的 MCP 工具:`wls_role_query` / `wls_role_upsert` / `wls_assignable_menus_query` / `wls_role_assign_menus` / `wls_action_query` / `wls_action_upsert`。调用失败时按 guardrail §2 剧本引导用户完善 `env.local.json` 后重试,**不得用 curl/手拼 HTTP 绕开 MCP**。
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
52
60
|
## MCP 工具调用规范
|
|
53
61
|
|
|
54
62
|
permission-sync 通过 6 个 MCP 工具完成所有操作(无需手动 fetch):
|
|
@@ -62,7 +70,7 @@ permission-sync 通过 6 个 MCP 工具完成所有操作(无需手动 fetch
|
|
|
62
70
|
| `wls_action_query` | 查询页面菜单下的动作(type=A) |
|
|
63
71
|
| `wls_action_upsert` | 批量新增动作(按 permission 去重) |
|
|
64
72
|
|
|
65
|
-
>
|
|
73
|
+
> 上表 6 个工具覆盖所有场景,**不得以任何理由跳过**。§6 仅为记录 MCP 内部调用的底层接口,供后端/运维联调参考,AI 禁止据此自行发起 HTTP 调用。
|
|
66
74
|
|
|
67
75
|
---
|
|
68
76
|
|
|
@@ -207,7 +215,10 @@ permission-sync 通过 6 个 MCP 工具完成所有操作(无需手动 fetch
|
|
|
207
215
|
|
|
208
216
|
---
|
|
209
217
|
|
|
210
|
-
## 6.
|
|
218
|
+
## 6. 后端接口参考(MCP 内部实现,AI 不得调用)
|
|
219
|
+
|
|
220
|
+
> 本节仅记录 MCP 内部调用的后端路径,用于后端联调 / 运维排查 / kit 维护者参考。
|
|
221
|
+
> **AI 绝不以任何方式直接发起这些请求**。MCP 不可用时的处理方式见末尾「MCP 不可用时怎么办」。
|
|
211
222
|
|
|
212
223
|
所有接口共用 Headers:
|
|
213
224
|
|
|
@@ -256,3 +267,9 @@ Authorization: Bearer <token>
|
|
|
256
267
|
- 角色分配可通过重新调用 saveRoleMenus 传旧 menuIds 恢复
|
|
257
268
|
- 新增的角色/动作建议通过后端管理界面手动删除(防止误删生产数据)
|
|
258
269
|
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## 9. MCP 不可用或调用失败时怎么办
|
|
274
|
+
|
|
275
|
+
见 `../_mcp-guardrail.md` §2 自愈闭环剧本。**原则**:先帮用户完善 `env.local.json` 里的 token / gatewayPath,重试 MCP 工具。**绝不允许** AI 用 curl/PowerShell/fetch 绕开 MCP 手拼 HTTP。
|
package/mcp/api/client.js
CHANGED
|
@@ -49,10 +49,17 @@ function wlsFetch(urlPath, options, config) {
|
|
|
49
49
|
if (json.code === 2000) {
|
|
50
50
|
resolve({ ok: true, data: json.data, code: json.code })
|
|
51
51
|
} else {
|
|
52
|
+
// 友好提示:401/4004 等典型错误附带排查指引
|
|
53
|
+
let hint = ''
|
|
54
|
+
if (json.code === 401 || /token|未登录|鉴权/i.test(json.message || '')) {
|
|
55
|
+
hint = '(Token 可能已过期,请重新登录后更新 env.local.json 的 token 字段,仅填纯 JWT 不含 bearer 前缀)'
|
|
56
|
+
} else if (json.code === 4004 || /url:|not\s*found/i.test(json.message || '')) {
|
|
57
|
+
hint = '(接口未找到。可能是 gatewayPath 配置缺失前缀或后端环境差异;请检查 env.local.json 的 gatewayPath。不要让 AI 绕开 MCP 自己拼 HTTP)'
|
|
58
|
+
}
|
|
52
59
|
resolve({
|
|
53
60
|
ok: false,
|
|
54
61
|
data: null,
|
|
55
|
-
error: json.message || `服务端返回 code=${json.code}
|
|
62
|
+
error: (json.message || `服务端返回 code=${json.code}`) + hint,
|
|
56
63
|
code: json.code,
|
|
57
64
|
})
|
|
58
65
|
}
|
package/mcp/server.js
CHANGED
|
@@ -122,7 +122,28 @@ function startServer() {
|
|
|
122
122
|
|
|
123
123
|
// 仅在直接执行时启动监听;被 require(如测试)时不启动
|
|
124
124
|
if (require.main === module) {
|
|
125
|
+
printBanner();
|
|
125
126
|
startServer();
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
/**
|
|
130
|
+
* 启动 banner — 写入 stderr,不污染 stdout 的 JSON-RPC 通道
|
|
131
|
+
* 让用户在编辑器 MCP 输出面板能直观看到:版本、工具数量、项目根
|
|
132
|
+
*/
|
|
133
|
+
function printBanner() {
|
|
134
|
+
const projectRoot = process.env.WL_PROJECT_ROOT || process.cwd();
|
|
135
|
+
const lines = [
|
|
136
|
+
"",
|
|
137
|
+
"═══════════════════════════════════════════════════",
|
|
138
|
+
` wl-skills MCP Server v${PKG.version}`,
|
|
139
|
+
"═══════════════════════════════════════════════════",
|
|
140
|
+
` 项目根 (WL_PROJECT_ROOT): ${projectRoot}`,
|
|
141
|
+
` 已注册工具 (${TOOLS.length}):`,
|
|
142
|
+
...TOOLS.map((t) => ` • ${t.name}`),
|
|
143
|
+
"═══════════════════════════════════════════════════",
|
|
144
|
+
"",
|
|
145
|
+
];
|
|
146
|
+
process.stderr.write(lines.join("\n") + "\n");
|
|
147
|
+
}
|
|
148
|
+
|
|
128
149
|
module.exports = { TOOLS, HANDLERS, dispatchTool, startServer };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agile-team/wl-skills-kit",
|
|
3
|
-
"version": "2.7.
|
|
4
|
-
"description": "AI Skill 模板包 v2.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
|
+
"description": "AI Skill 模板包 v2.7.2 — 13 条编码规范 + 10 个 AI Skill + 17 个 MCP Tool,一条命令导入 Vue 3 项目",
|
|
5
5
|
"main": "./bin/wl-skills.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"wl-skills": "bin/wl-skills.js"
|
|
@@ -43,9 +43,10 @@
|
|
|
43
43
|
"prepare": "husky",
|
|
44
44
|
"cz": "git-cz",
|
|
45
45
|
"lint": "eslint .",
|
|
46
|
+
"lint:skills": "node scripts/lint-skills.js",
|
|
46
47
|
"test": "vitest run",
|
|
47
48
|
"version:verify": "node scripts/verify-version.js",
|
|
48
|
-
"prepublishOnly": "node scripts/verify-version.js && vitest run"
|
|
49
|
+
"prepublishOnly": "node scripts/verify-version.js && node scripts/lint-skills.js && vitest run"
|
|
49
50
|
},
|
|
50
51
|
"dependencies": {
|
|
51
52
|
"xlsx": "^0.18.5"
|