@agile-team/wl-skills-kit 2.5.2 → 2.7.0

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.
Files changed (28) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +32 -4
  3. package/bin/wl-skills.js +48 -2
  4. package/docs/agent-pipeline-runbook.md +2 -1
  5. package/docs/ai/345/205/250/346/231/257/345/210/206/346/236/220.md +13 -4
  6. package/docs/mcp-tool-risk-matrix.md +2 -1
  7. package/docs//345/205/250/347/233/230/345/210/206/346/236/220/344/270/216/346/231/272/350/203/275/344/275/223/346/220/255/345/273/272/346/214/207/345/215/227.md +3 -2
  8. package/files/.github/copilot-instructions.md +2 -11
  9. package/files/.github/guides/architecture.md +1 -1
  10. package/files/.github/guides/usage.md +4 -3
  11. package/files/.github/skills/_compat/headers/cursor-mdc.txt +1 -1
  12. package/files/.github/skills/_compat/headers/kiro.txt +1 -1
  13. package/files/.github/skills/_compat/headers/trae.txt +1 -1
  14. package/files/.github/skills/_pipeline.md +10 -4
  15. package/files/.github/skills/_registry.md +3 -0
  16. package/files/.github/skills/core/business-doc-extract/SKILL.md +234 -0
  17. package/files/.github/skills/core/business-doc-extract/USAGE.md +176 -0
  18. package/files/.github/skills/core/business-doc-extract/templates/business-index.md +66 -0
  19. package/files/.github/skills/core/business-doc-extract/templates/business-open-questions.md +40 -0
  20. package/files/.github/skills/core/business-doc-extract/templates/module-dictionary.md +54 -0
  21. package/files/.github/skills/core/business-doc-extract/templates/module-field.md +63 -0
  22. package/files/.github/skills/core/business-doc-extract/templates/module-index.md +67 -0
  23. package/files/.github/skills/core/business-doc-extract/templates/module-requirement.md +101 -0
  24. package/files/.github/skills/ops/code-fix/USAGE.md +131 -0
  25. package/files/.github/skills/sync/dict-sync/USAGE.md +122 -0
  26. package/mcp/registry.js +368 -0
  27. package/mcp/server.js +65 -432
  28. package/package.json +9 -5
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * MCP Tool 描述符集中注册(v2.7.0+ auto-discovery)
5
+ *
6
+ * 每个描述符字段:
7
+ * - name 工具唯一标识(wls_*)
8
+ * - description 工具说明(出现在 tools/list 响应中)
9
+ * - inputSchema JSON Schema
10
+ * - handle(args, cfg) 处理函数,返回字符串文本
11
+ * - needsBackendConfig 是否需要 loadConfig()(false: 纯本地工具)
12
+ *
13
+ * server.js 仅做协议层 + 自动调度;新增 Tool 只改本文件,不动 server.js。
14
+ *
15
+ * 导出:
16
+ * - DESCRIPTORS 完整描述符数组(含 handle)
17
+ * - TOOLS 对外公开的 tools/list 数据(仅 name/description/inputSchema)
18
+ * - HANDLERS 工具名 → 描述符的映射,供 dispatchTool 查表
19
+ */
20
+
21
+ const {
22
+ handleMenuQuery,
23
+ handleMenuUpsert,
24
+ handleMenuSyncFromReport,
25
+ } = require("./tools/menuSync");
26
+ const { handleDictQuery, handleDictUpsert } = require("./tools/dictSync");
27
+ const {
28
+ handleRoleQuery,
29
+ handleRoleUpsert,
30
+ handleRoleAssignMenus,
31
+ handleAssignableMenusQuery,
32
+ handleActionQuery,
33
+ handleActionUpsert,
34
+ } = require("./tools/permissionSync");
35
+ const {
36
+ handleCodeScan,
37
+ handleValidatePage,
38
+ handleDoctorUi,
39
+ handleRouteCheck,
40
+ handleGitLogExtract,
41
+ handleAuditReportPush,
42
+ } = require("./tools/projectTools");
43
+
44
+ const DESCRIPTORS = [
45
+ // ── menu ───────────────────────────────────────────────────────────
46
+ {
47
+ name: "wls_menu_query",
48
+ description:
49
+ "查询当前应用的完整菜单树。自动从 .github/skills/sync/env.local.json 读取 domainId," +
50
+ "无需传参。在 wls_menu_upsert 前调用,用于判断哪些菜单需要新增、哪些需要更新。",
51
+ inputSchema: { type: "object", properties: {}, required: [] },
52
+ needsBackendConfig: true,
53
+ handle: (_args, config) => handleMenuQuery(config),
54
+ },
55
+ {
56
+ name: "wls_menu_upsert",
57
+ description:
58
+ "批量新增或更新菜单项。有 id 字段 → 更新;无 id 字段 → 新增。" +
59
+ "新增时响应自动包含服务端生成的 id,可链式用于创建子菜单。",
60
+ inputSchema: {
61
+ type: "object",
62
+ properties: {
63
+ items: {
64
+ type: "array",
65
+ description:
66
+ "MenuSaveBody 数组。每项字段:" +
67
+ "id(更新时传), sysAppNo, menuName, menuNameCode, parentId, " +
68
+ 'type("M"=目录/"C"=菜单), path, icon, orderNum, ' +
69
+ "useCache(1), common(2), hidden(false), editMode(false), " +
70
+ "component(type=C时传), permission(type=C时传)",
71
+ items: { type: "object" },
72
+ },
73
+ },
74
+ required: ["items"],
75
+ },
76
+ needsBackendConfig: true,
77
+ handle: (args, config) => handleMenuUpsert(args, config),
78
+ },
79
+ {
80
+ name: "wls_menu_sync_from_report",
81
+ description:
82
+ "读取 .github/reports/SYS_MENU_INFO*.md,按一级目录(type=M)优先、二级菜单(type=C)随后同步到后端菜单。" +
83
+ "自动查询 domain 菜单树去重,复用或更新已存在菜单,避免把二级页面全部挂到根 parentMenuId。",
84
+ inputSchema: {
85
+ type: "object",
86
+ properties: {
87
+ reportPath: {
88
+ type: "string",
89
+ description:
90
+ "可选。SYS_MENU_INFO*.md 路径;不传则使用 .github/reports 下最新报告。",
91
+ },
92
+ dryRun: {
93
+ type: "boolean",
94
+ description: "可选。true 时只解析和预览,不调用保存接口。",
95
+ },
96
+ },
97
+ required: [],
98
+ },
99
+ needsBackendConfig: true,
100
+ handle: (args, config) => handleMenuSyncFromReport(args, config),
101
+ },
102
+ // ── dict ───────────────────────────────────────────────────────────
103
+ {
104
+ name: "wls_dict_query",
105
+ description:
106
+ "查询当前应用的所有字典模块及字典项。在 wls_dict_upsert 前调用," +
107
+ "用于判断哪些模块/字典项已存在。",
108
+ inputSchema: { type: "object", properties: {}, required: [] },
109
+ needsBackendConfig: true,
110
+ handle: (_args, config) => handleDictQuery(config),
111
+ },
112
+ {
113
+ name: "wls_dict_upsert",
114
+ description:
115
+ "新增或更新字典模块及其字典项。内部自动处理:" +
116
+ "若模块不存在则创建(data=null 后自动 re-query 获取 id)," +
117
+ "若已存在则直接取 id;字典项自动跳过已存在的 strSn。",
118
+ inputSchema: {
119
+ type: "object",
120
+ properties: {
121
+ module: {
122
+ type: "object",
123
+ description:
124
+ 'DictModuleSaveBody: strSn(必填), strName(必填), sortPriority("1"), strLevel(2)',
125
+ properties: {
126
+ strSn: { type: "string", description: '模块标识符,如 "gender"' },
127
+ strName: { type: "string", description: '模块显示名,如 "性别"' },
128
+ sortPriority: {
129
+ type: "string",
130
+ description: '排序,字符串类型,如 "1"',
131
+ },
132
+ strLevel: { type: "number", description: "固定传 2" },
133
+ },
134
+ required: ["strSn", "strName"],
135
+ },
136
+ items: {
137
+ type: "array",
138
+ description:
139
+ "DictItemSaveBody 数组(可选)。每项字段:" +
140
+ "strSn(必填), strName(必填), strLevel(2), " +
141
+ 'dtlValue(""), dtlValueRequired(false), dtlValue2Required(false), ' +
142
+ "dtlValue3Required(false), dtlValue4Required(false)",
143
+ items: { type: "object" },
144
+ },
145
+ },
146
+ required: ["module"],
147
+ },
148
+ needsBackendConfig: true,
149
+ handle: (args, config) => handleDictUpsert(args, config),
150
+ },
151
+ // ── role / permission ──────────────────────────────────────────────
152
+ {
153
+ name: "wls_role_query",
154
+ description:
155
+ "查询角色列表。可选参数 current/size 翻页,默认 size=100。返回精简字段:id, roleName, code, sysAppNo, roleDesc。",
156
+ inputSchema: {
157
+ type: "object",
158
+ properties: {
159
+ current: { type: "number", description: "页码,默认 1" },
160
+ size: { type: "number", description: "每页数量,默认 100" },
161
+ },
162
+ required: [],
163
+ },
164
+ needsBackendConfig: true,
165
+ handle: (args, config) => handleRoleQuery(args, config),
166
+ },
167
+ {
168
+ name: "wls_role_upsert",
169
+ description:
170
+ "批量新增角色(按 code 字段自动去重;已存在则跳过)。每项必填 roleName 和 code,可选 configDesc。" +
171
+ "注意:角色仅新增不更新,因角色变更通常需要业务确认。",
172
+ inputSchema: {
173
+ type: "object",
174
+ properties: {
175
+ items: {
176
+ type: "array",
177
+ description:
178
+ "角色数组。字段:roleName(必填,显示名), code(必填,唯一标识), configDesc(可选,描述)",
179
+ items: { type: "object" },
180
+ },
181
+ },
182
+ required: ["items"],
183
+ },
184
+ needsBackendConfig: true,
185
+ handle: (args, config) => handleRoleUpsert(args, config),
186
+ },
187
+ {
188
+ name: "wls_assignable_menus_query",
189
+ description:
190
+ "查询全量可授权菜单列表(扁平结构,含菜单 id/menuName/permission)。" +
191
+ "在 wls_role_assign_menus 前调用,AI 据此选出要分配给角色的 menuIds。",
192
+ inputSchema: { type: "object", properties: {}, required: [] },
193
+ needsBackendConfig: true,
194
+ handle: (args, config) => handleAssignableMenusQuery(args, config),
195
+ },
196
+ {
197
+ name: "wls_role_assign_menus",
198
+ description:
199
+ "给指定角色批量分配菜单权限。menuIds 传字符串数组,内部自动拼成逗号分隔字符串提交后端。" +
200
+ "该接口为全量覆盖式,应包含该角色所有菜单(含已有的,否则会被移除)。",
201
+ inputSchema: {
202
+ type: "object",
203
+ properties: {
204
+ roleId: {
205
+ type: "string",
206
+ description: "角色 id(来自 wls_role_query)",
207
+ },
208
+ menuIds: {
209
+ type: "array",
210
+ description: "该角色应拥有的全部菜单 id 数组",
211
+ items: { type: "string" },
212
+ },
213
+ },
214
+ required: ["roleId", "menuIds"],
215
+ },
216
+ needsBackendConfig: true,
217
+ handle: (args, config) => handleRoleAssignMenus(args, config),
218
+ },
219
+ {
220
+ name: "wls_action_query",
221
+ description:
222
+ "查询指定页面菜单(type=C)下的动作按钮列表(type=A)。返回 id/menuName/permission/orderNum/icon。",
223
+ inputSchema: {
224
+ type: "object",
225
+ properties: {
226
+ menuId: { type: "string", description: "父菜单 id(页面菜单)" },
227
+ },
228
+ required: ["menuId"],
229
+ },
230
+ needsBackendConfig: true,
231
+ handle: (args, config) => handleActionQuery(args, config),
232
+ },
233
+ {
234
+ name: "wls_action_upsert",
235
+ description:
236
+ "在指定页面菜单下批量新增动作按钮(type=A),按 permission 字段自动去重。" +
237
+ "权限码命名规范:{资源camelCase}_{动作} 或 {模块}:{资源}:{动作}(与项目既有约定保持一致)。" +
238
+ "常见动作:add/edit/remove/export/import/approve。",
239
+ inputSchema: {
240
+ type: "object",
241
+ properties: {
242
+ parentId: {
243
+ type: "string",
244
+ description: "页面菜单 id(动作挂在它下面)",
245
+ },
246
+ items: {
247
+ type: "array",
248
+ description:
249
+ "动作数组。字段:menuName(必填,显示名), permission(必填,权限码), icon(可选,默认list), orderNum(可选,默认1), useCache(可选,默认1)",
250
+ items: { type: "object" },
251
+ },
252
+ },
253
+ required: ["parentId", "items"],
254
+ },
255
+ needsBackendConfig: true,
256
+ handle: (args, config) => handleActionUpsert(args, config),
257
+ },
258
+ // ── project / local(无需后端配置)─────────────────────────────────
259
+ {
260
+ name: "wls_code_scan",
261
+ description:
262
+ "扫描项目页面目录,返回 index.vue/data.ts/index.scss/api.md 完整性与 API_CONFIG 概览。" +
263
+ "默认扫描 src/views,可传 path 指定目录。适用于 convention-audit / Agent Pipeline 前置感知项目结构。",
264
+ inputSchema: {
265
+ type: "object",
266
+ properties: {
267
+ path: {
268
+ type: "string",
269
+ description: "相对项目根目录的扫描路径,默认 src/views",
270
+ },
271
+ },
272
+ required: [],
273
+ },
274
+ needsBackendConfig: false,
275
+ handle: (args) => handleCodeScan(args),
276
+ },
277
+ {
278
+ name: "wls_route_check",
279
+ description:
280
+ "检查 src/views 页面目录是否能在路由文件中被发现。默认查找 vite/plugins/shared/pages.ts 等常见路由文件," +
281
+ "可传 path 和 routeFile 定制。用于 page-codegen/menu-sync 后闭环验证。",
282
+ inputSchema: {
283
+ type: "object",
284
+ properties: {
285
+ path: { type: "string", description: "页面扫描路径,默认 src/views" },
286
+ routeFile: {
287
+ type: "string",
288
+ description: "路由文件路径,默认自动探测",
289
+ },
290
+ },
291
+ required: [],
292
+ },
293
+ needsBackendConfig: false,
294
+ handle: (args) => handleRouteCheck(args),
295
+ },
296
+ {
297
+ name: "wls_validate_page",
298
+ description:
299
+ "校验页面是否符合 wl-skills-kit 最新页面规范:BaseTable+AGGrid+cid、defineColumns、renderOps、mock-first、api.md 等。",
300
+ inputSchema: {
301
+ type: "object",
302
+ properties: {
303
+ path: { type: "string", description: "页面或目录路径,默认 src/views" },
304
+ },
305
+ required: [],
306
+ },
307
+ needsBackendConfig: false,
308
+ handle: (args) => handleValidatePage(args),
309
+ },
310
+ {
311
+ name: "wls_doctor_ui",
312
+ description:
313
+ "检查 @agile-team/wk-skills-ui 是否真正接入:依赖、tokens、styles preset、installCommonPreset、defineColumns、renderOps。",
314
+ inputSchema: { type: "object", properties: {}, required: [] },
315
+ needsBackendConfig: false,
316
+ handle: (args) => handleDoctorUi(args),
317
+ },
318
+ {
319
+ name: "wls_git_log_extract",
320
+ description:
321
+ "提取最近 N 次 git commit 摘要,用于 convention-audit 的 Git 规范检查或 changelog-gen 的数据源。",
322
+ inputSchema: {
323
+ type: "object",
324
+ properties: {
325
+ n: { type: "number", description: "提取数量,默认 20,最大 100" },
326
+ },
327
+ required: [],
328
+ },
329
+ needsBackendConfig: false,
330
+ handle: (args) => handleGitLogExtract(args),
331
+ },
332
+ {
333
+ name: "wls_audit_report_push",
334
+ description:
335
+ "将最新审计报告推送到飞书机器人 webhook。未配置 env.local.json 的 feishu_webhook 时静默跳过,不影响其他流程。",
336
+ inputSchema: {
337
+ type: "object",
338
+ properties: {
339
+ reportPath: {
340
+ type: "string",
341
+ description:
342
+ "审计报告路径,不传则自动选择 .github/reports 下最新 AUDIT_*.md 或规范审查报告.md",
343
+ },
344
+ },
345
+ required: [],
346
+ },
347
+ needsBackendConfig: false,
348
+ handle: (args) => handleAuditReportPush(args),
349
+ },
350
+ ];
351
+
352
+ const TOOLS = DESCRIPTORS.map((d) => ({
353
+ name: d.name,
354
+ description: d.description,
355
+ inputSchema: d.inputSchema,
356
+ }));
357
+
358
+ const HANDLERS = Object.create(null);
359
+ for (const d of DESCRIPTORS) {
360
+ if (HANDLERS[d.name]) {
361
+ throw new Error(
362
+ "[mcp/registry] 工具名重复: " + d.name + "(请检查 DESCRIPTORS 数组)",
363
+ );
364
+ }
365
+ HANDLERS[d.name] = d;
366
+ }
367
+
368
+ module.exports = { DESCRIPTORS, TOOLS, HANDLERS };