@agile-team/wl-skills-kit 2.7.1 → 2.7.3

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.
@@ -69,16 +69,19 @@ SYS_MENU_INFO.md 是 menu-sync Skill 的输入数据源:
69
69
 
70
70
  ---
71
71
 
72
- ## Phase 1:AI 调用 API 创建菜单(当前方案)
72
+ ## Phase 1:MCP 驱动创建菜单(当前方案)
73
73
 
74
- > 此方案参考平台伙伴的 jh4j-cloud skill,适配 cx-ui-produce 项目。
75
- > 本质是 **menu-sync-design.md 的方案 C(只增不删)**,由 AI 自动执行。
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. 用户提供后端系统管理地址(如 `http://localhost:9000` 或实际网关地址)
80
- 2. 用户提供有效的 Bearer Token(从浏览器开发者工具 Network 面板复制)
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
- #### Step 1: 查询当前 domain 菜单树(防重复 + 取父级信息)
104
+ **默认走 `wls_menu_sync_from_report`**——它内部完成「读报告 查菜单树 一级目录 upsert → 二级菜单 upsert」全流程:
102
105
 
103
106
  ```
104
- 工具:wls_menu_query
105
- 读取:env.local.json menu.domainId
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
- > 推荐:具备 MCP 时优先调用 `wls_menu_sync_from_report`,它会自动读取最新 `SYS_MENU_INFO*.md`、查询菜单树、复用/更新目录,再把二级菜单挂到对应目录下。可先传 `dryRun: true` 做预览。
112
+ ### 手动拆分流程(仅当一步式不满足时)
110
113
 
111
- #### Step 2: 先创建一级目录(type=M)
112
-
113
- 对于 `SYS_MENU_INFO` 中的一级目录,按 `menuName/path` 在父级 `parentMenuId` 下去重;不存在则创建,存在则复用 id。
114
+ #### Step 1: 查询当前 domain 菜单树(防重复 + 取父级信息)
114
115
 
115
- #### Step 3: 再创建二级页面菜单(type=C)
116
+ ```
117
+ 工具:wls_menu_query (无参,自动读 env.local.json → menu.domainId)
118
+ 返回:当前应用域完整菜单树
119
+ ```
116
120
 
117
- 对于每条页面菜单,`parentId` 必须使用上一步对应目录的 id,禁止全部挂到根 `parentMenuId`。
121
+ #### Step 2: 先创建一级目录(type=M),再创建二级页面菜单(type=C)
118
122
 
119
- > **响应码说明**:后端成功响应为 `code: 2000`(非标准 HTTP 200),判断成功应检查 `response.body.code === 2000` `message` 包含"成功"。
123
+ - 一级目录按 `menuName/path` 在父级 `parentMenuId` 下去重;不存在则创建,存在则复用 id
124
+ - 二级页面菜单的 `parentId` 必须是上一步对应目录的 id,**禁止**全部挂到根 `parentMenuId`
120
125
 
121
126
  ```
122
- POST {gatewayPath}/system/menu/save
123
- Headers:
124
- authorization: bearer {token}
125
- Sysappno: {sysAppNo}
126
- Content-Type: application/json
127
+ 工具:wls_menu_upsert
128
+ 入参:{ items: [<下面的对象>...] }
129
+ ```
127
130
 
128
- Body:
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": "{parentMenuId}",
139
+ "type": "C", // "M"=目录, "C"=菜单, "A"=动作
140
+ "parentId": "{父级目录的 id}",
136
141
  "sysAppNo": "{sysAppNo}",
137
- "orderNum": {nextOrder},
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/menu-sync/env/env.local.json`(首次使用先填写):
34
+ `.github/skills/sync/env.local.json`(首次使用先填写,已加入 `.gitignore`):
35
35
 
36
36
  ```json
37
37
  {
38
- "gatewayPath": "https://uat-api.example.com",
39
- "token": "Bearer xxx",
40
- "tenantId": "10001",
41
- "rootMenuId": "1234567890"
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**(已加 .gitignore)。每个开发者本地填自己的 token
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:将调用 /sys/menu/save 创建 5 项
61
+ 步骤 4:将调用 wls_menu_sync_from_report 创建 5 项
58
62
  [需你确认]:
59
- - 父菜单:精整作业 → 客户管理(rootMenuId: xxx)
60
- - 排序:sortNo 自动递增
61
- - 权限标识:mmwr:customer:list
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 不对 | rootMenuId 配错 | 从浏览器开发者工具看父菜单的 dom data-id |
88
+ | 父菜单 ID 不对 | menu.parentMenuId 配错 | 从菜单后台编辑页复制菜单 ID,填入 env.local.json |
83
89
 
84
90
  ---
85
91