@agile-team/wl-skills-kit 2.3.4 → 2.3.6

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 (96) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +16 -10
  3. package/files/.cursor/mcp.json +8 -8
  4. package/files/.github/guides/README.md +13 -13
  5. package/files/.github/guides/architecture.md +555 -555
  6. package/files/.github/guides/mcp-setup.md +109 -109
  7. package/files/.github/guides/usage.md +184 -184
  8. package/files/.github/reports/README.md +65 -65
  9. package/files/.github/reports/SYS_DICT_INFO.md +50 -50
  10. package/files/.github/reports/SYS_MENU_INFO.md +247 -247
  11. package/files/.github/reports/SYS_PERMISSION_INFO.md +20 -20
  12. package/files/.github/reports//347/273/204/344/273/266/346/217/220/345/217/226/345/273/272/350/256/256.md +33 -33
  13. package/files/.github/reports//350/247/204/350/214/203/345/256/241/346/237/245/346/212/245/345/221/212.md +44 -44
  14. package/files/.github/skills/_compat/README.md +108 -108
  15. package/files/.github/skills/_compat/headers/agents.txt +8 -8
  16. package/files/.github/skills/_compat/headers/claude-code.txt +7 -7
  17. package/files/.github/skills/_compat/headers/cline.txt +7 -7
  18. package/files/.github/skills/_compat/headers/cursor-mdc.txt +16 -16
  19. package/files/.github/skills/_compat/headers/cursor-rules.txt +7 -7
  20. package/files/.github/skills/_compat/headers/github-copilot.txt +1 -1
  21. package/files/.github/skills/_compat/headers/kiro.txt +10 -10
  22. package/files/.github/skills/_compat/headers/qoder.txt +8 -8
  23. package/files/.github/skills/_compat/headers/trae.txt +11 -11
  24. package/files/.github/skills/_compat/headers/windsurf.txt +7 -7
  25. package/files/.github/skills/_registry.md +81 -81
  26. package/files/.github/skills/core/api-contract/SKILL.md +344 -344
  27. package/files/.github/skills/core/api-contract/USAGE.md +110 -110
  28. package/files/.github/skills/core/convention-audit/SKILL.md +189 -189
  29. package/files/.github/skills/core/convention-audit/USAGE.md +99 -99
  30. package/files/.github/skills/core/page-codegen/SKILL.md +973 -973
  31. package/files/.github/skills/core/page-codegen/USAGE.md +102 -102
  32. package/files/.github/skills/core/page-codegen/templates/_index.md +46 -46
  33. package/files/.github/skills/core/page-codegen/templates/domains/_CONTRIBUTING.md +107 -107
  34. package/files/.github/skills/core/page-codegen/templates/domains/produce/TPL-OPERATION-STATION.md +442 -442
  35. package/files/.github/skills/core/page-codegen/templates/domains/sale/README.md +26 -26
  36. package/files/.github/skills/core/page-codegen/templates/universal/TPL-CHANGE-HISTORY.md +276 -276
  37. package/files/.github/skills/core/page-codegen/templates/universal/TPL-DETAIL-TABS.md +1145 -1145
  38. package/files/.github/skills/core/page-codegen/templates/universal/TPL-DRIVEN.md +309 -309
  39. package/files/.github/skills/core/page-codegen/templates/universal/TPL-FORM-ROUTE.md +436 -436
  40. package/files/.github/skills/core/page-codegen/templates/universal/TPL-LIST.md +191 -191
  41. package/files/.github/skills/core/page-codegen/templates/universal/TPL-MASTER-DETAIL.md +148 -148
  42. package/files/.github/skills/core/page-codegen/templates/universal/TPL-RECORD-FORM.md +376 -376
  43. package/files/.github/skills/core/page-codegen/templates/universal/TPL-TREE-LIST.md +186 -186
  44. package/files/.github/skills/core/prototype-scan/SKILL.md +498 -498
  45. package/files/.github/skills/core/prototype-scan/USAGE.md +95 -95
  46. package/files/.github/skills/core/template-extract/SKILL.md +139 -139
  47. package/files/.github/skills/core/template-extract/USAGE.md +93 -93
  48. package/files/.github/skills/domain/README.md +51 -51
  49. package/files/.github/skills/sync/env.local.json +0 -5
  50. package/files/.github/skills/sync/menu-sync/SKILL.md +263 -263
  51. package/files/.github/skills/sync/menu-sync/USAGE.md +104 -104
  52. package/files/.github/skills/sync/menu-sync/env/env.local.json +7 -7
  53. package/files/.github/skills/sync/menu-sync/env/guide.md +99 -99
  54. package/files/.github/skills/sync/permission-sync/SKILL.md +239 -0
  55. package/files/.github/skills/sync/permission-sync/USAGE.md +93 -0
  56. package/files/.github/standards/01-toolchain.md +57 -57
  57. package/files/.github/standards/02-code-structure.md +111 -111
  58. package/files/.github/standards/03-comments.md +53 -53
  59. package/files/.github/standards/04-coding-basics.md +33 -33
  60. package/files/.github/standards/05-logging.md +38 -38
  61. package/files/.github/standards/06-security.md +44 -44
  62. package/files/.github/standards/07-config.md +52 -52
  63. package/files/.github/standards/08-git.md +60 -60
  64. package/files/.github/standards/09-typescript.md +71 -71
  65. package/files/.github/standards/10-pinia.md +57 -57
  66. package/files/.github/standards/11-form-validation.md +81 -81
  67. package/files/.github/standards/12-base-table.md +153 -153
  68. package/files/.github/standards/13-platform-components.md +123 -123
  69. package/files/.github/standards/index.md +89 -89
  70. package/files/.kiro/settings/mcp.json +8 -8
  71. package/files/.mcp.json +8 -8
  72. package/files/.vscode/mcp.json +9 -9
  73. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/data.ts +196 -196
  74. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.scss +150 -150
  75. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.vue +79 -79
  76. package/files/docs/jh-date-range.md +257 -257
  77. package/files/docs/jh-date.md +222 -222
  78. package/files/docs/jh-dept-picker.md +190 -190
  79. package/files/docs/jh-drag-row.md +590 -590
  80. package/files/docs/jh-file-upload.md +216 -216
  81. package/files/docs/jh-picker.md +218 -218
  82. package/files/docs/jh-select.md +148 -148
  83. package/files/docs/jh-text.md +248 -248
  84. package/files/docs/jh-user-picker.md +197 -197
  85. package/files/src/components/global/C_RightToolbar/data.ts +228 -228
  86. package/files/src/components/global/C_RightToolbar/index.scss +44 -44
  87. package/files/src/components/global/C_Splitter/index.scss +61 -61
  88. package/files/src/components/global/C_SvgIcon/index.scss +15 -15
  89. package/files/src/components/global/C_TagStatus/index.scss +20 -20
  90. package/files/src/components/global/C_Tree/data.ts +61 -61
  91. package/files/src/components/local/c_listModal/index.scss +4 -4
  92. package/mcp/api/roleApi.js +60 -0
  93. package/mcp/server.js +125 -5
  94. package/mcp/tools/permissionSync.js +321 -0
  95. package/package.json +1 -1
  96. package/files/.github/skills/sync/permission-sync/SKILL.draft.md +0 -91
@@ -1,15 +1,15 @@
1
- .sub-el-icon,
2
- .nav-icon {
3
- display: inline-block;
4
- font-size: 15px;
5
- margin-right: 12px;
6
- position: relative;
7
- }
8
-
9
- .svg-icon {
10
- width: 1em;
11
- height: 1em;
12
- position: relative;
13
- fill: currentColor;
14
- vertical-align: -2px;
15
- }
1
+ .sub-el-icon,
2
+ .nav-icon {
3
+ display: inline-block;
4
+ font-size: 15px;
5
+ margin-right: 12px;
6
+ position: relative;
7
+ }
8
+
9
+ .svg-icon {
10
+ width: 1em;
11
+ height: 1em;
12
+ position: relative;
13
+ fill: currentColor;
14
+ vertical-align: -2px;
15
+ }
@@ -1,20 +1,20 @@
1
- .status-fallback {
2
- display: inline-block;
3
- padding: 0 8px;
4
- font-size: 12px;
5
- color: #909399;
6
- line-height: 22px;
7
- white-space: nowrap;
8
- }
9
-
10
- // 增强 el-tag 的视觉效果
11
- :deep(.el-tag) {
12
- font-weight: 500;
13
- border: none;
14
-
15
- // 为淡色效果添加边框
16
- &.el-tag--light {
17
- border: 1px solid currentColor;
18
- border-color: var(--el-tag-border-color);
19
- }
20
- }
1
+ .status-fallback {
2
+ display: inline-block;
3
+ padding: 0 8px;
4
+ font-size: 12px;
5
+ color: #909399;
6
+ line-height: 22px;
7
+ white-space: nowrap;
8
+ }
9
+
10
+ // 增强 el-tag 的视觉效果
11
+ :deep(.el-tag) {
12
+ font-weight: 500;
13
+ border: none;
14
+
15
+ // 为淡色效果添加边框
16
+ &.el-tag--light {
17
+ border: 1px solid currentColor;
18
+ border-color: var(--el-tag-border-color);
19
+ }
20
+ }
@@ -1,61 +1,61 @@
1
- import { ref, watch } from "vue";
2
- import { Search } from "@element-plus/icons-vue";
3
-
4
- // ===== 类型定义 =====
5
- export interface Props {
6
- tabs?: Array<{ label: string; name: string }>;
7
- treeData: any[];
8
- treeProps?: Record<string, string>;
9
- defaultActiveTab?: string;
10
- showSearch?: boolean;
11
- searchPlaceholder?: string;
12
- defaultExpandAll?: boolean;
13
- highlightCurrent?: boolean;
14
- }
15
-
16
- // ===== 组件逻辑 =====
17
- export function createTree(
18
- props: Props,
19
- emit: (e: "node-click" | "tab-change", ...args: any[]) => void,
20
- ) {
21
- const activeTab = ref(props.defaultActiveTab ?? "tab1");
22
- const searchKeyword = ref("");
23
- const treeRef = ref<any>(null);
24
-
25
- const filterNode = (value: string, data: any) => {
26
- if (!value) return true;
27
- const label = data[props.treeProps?.label || "label"];
28
- return label && label.includes(value);
29
- };
30
-
31
- const handleNodeClick = (data: any) => {
32
- emit("node-click", data);
33
- };
34
-
35
- watch(searchKeyword, (val) => {
36
- treeRef.value?.filter(val);
37
- });
38
-
39
- watch(activeTab, (val) => {
40
- emit("tab-change", val);
41
- });
42
-
43
- const clearSearch = () => {
44
- searchKeyword.value = "";
45
- };
46
-
47
- const switchTab = (tabName: string) => {
48
- activeTab.value = tabName;
49
- };
50
-
51
- return {
52
- Search,
53
- activeTab,
54
- searchKeyword,
55
- treeRef,
56
- filterNode,
57
- handleNodeClick,
58
- clearSearch,
59
- switchTab,
60
- };
61
- }
1
+ import { ref, watch } from "vue";
2
+ import { Search } from "@element-plus/icons-vue";
3
+
4
+ // ===== 类型定义 =====
5
+ export interface Props {
6
+ tabs?: Array<{ label: string; name: string }>;
7
+ treeData: any[];
8
+ treeProps?: Record<string, string>;
9
+ defaultActiveTab?: string;
10
+ showSearch?: boolean;
11
+ searchPlaceholder?: string;
12
+ defaultExpandAll?: boolean;
13
+ highlightCurrent?: boolean;
14
+ }
15
+
16
+ // ===== 组件逻辑 =====
17
+ export function createTree(
18
+ props: Props,
19
+ emit: (e: "node-click" | "tab-change", ...args: any[]) => void,
20
+ ) {
21
+ const activeTab = ref(props.defaultActiveTab ?? "tab1");
22
+ const searchKeyword = ref("");
23
+ const treeRef = ref<any>(null);
24
+
25
+ const filterNode = (value: string, data: any) => {
26
+ if (!value) return true;
27
+ const label = data[props.treeProps?.label || "label"];
28
+ return label && label.includes(value);
29
+ };
30
+
31
+ const handleNodeClick = (data: any) => {
32
+ emit("node-click", data);
33
+ };
34
+
35
+ watch(searchKeyword, (val) => {
36
+ treeRef.value?.filter(val);
37
+ });
38
+
39
+ watch(activeTab, (val) => {
40
+ emit("tab-change", val);
41
+ });
42
+
43
+ const clearSearch = () => {
44
+ searchKeyword.value = "";
45
+ };
46
+
47
+ const switchTab = (tabName: string) => {
48
+ activeTab.value = tabName;
49
+ };
50
+
51
+ return {
52
+ Search,
53
+ activeTab,
54
+ searchKeyword,
55
+ treeRef,
56
+ filterNode,
57
+ handleNodeClick,
58
+ clearSearch,
59
+ switchTab,
60
+ };
61
+ }
@@ -1,4 +1,4 @@
1
- .dialog-footer {
2
- display: flex;
3
- justify-content: flex-end;
4
- }
1
+ .dialog-footer {
2
+ display: flex;
3
+ justify-content: flex-end;
4
+ }
@@ -0,0 +1,60 @@
1
+ 'use strict'
2
+
3
+ const { wlsFetch } = require('./client')
4
+
5
+ /**
6
+ * 查询角色列表(分页)
7
+ * GET /system/role/list?current=1&size=10
8
+ */
9
+ function queryRoleList(params, config) {
10
+ const current = (params && params.current) || 1
11
+ const size = (params && params.size) || 100
12
+ return wlsFetch(
13
+ `/system/role/list?current=${current}&size=${size}`,
14
+ {},
15
+ config
16
+ )
17
+ }
18
+
19
+ /**
20
+ * 新增角色
21
+ * POST /system/role/save
22
+ * body: { roleName, code, configDesc }
23
+ */
24
+ function saveRole(body, config) {
25
+ return wlsFetch('/system/role/save', { method: 'POST', body }, config)
26
+ }
27
+
28
+ /**
29
+ * 查询全量可授权菜单(用于角色分配菜单)
30
+ * GET /system/menu/get/subMenu?size=999
31
+ */
32
+ function queryAssignableMenus(config) {
33
+ return wlsFetch('/system/menu/get/subMenu?size=999', {}, config)
34
+ }
35
+
36
+ /**
37
+ * 给角色批量分配菜单权限
38
+ * POST /system/role/saveRoleMenus
39
+ * body: { roleId, menuIds: "id1,id2,id3" } // 注意 menuIds 是逗号分隔字符串
40
+ */
41
+ function saveRoleMenus(body, config) {
42
+ return wlsFetch('/system/role/saveRoleMenus', { method: 'POST', body }, config)
43
+ }
44
+
45
+ /**
46
+ * 查询父菜单下的子菜单/动作列表
47
+ * GET /system/menu/children?current=1&size=10&menuId=xxx
48
+ */
49
+ function queryMenuChildren(menuId, config) {
50
+ const params = `current=1&size=999&menuId=${encodeURIComponent(menuId)}`
51
+ return wlsFetch(`/system/menu/children?${params}`, {}, config)
52
+ }
53
+
54
+ module.exports = {
55
+ queryRoleList,
56
+ saveRole,
57
+ queryAssignableMenus,
58
+ saveRoleMenus,
59
+ queryMenuChildren,
60
+ }
package/mcp/server.js CHANGED
@@ -5,11 +5,17 @@
5
5
  * wl-skills MCP Server
6
6
  *
7
7
  * 实现 MCP 协议(stdio transport,JSON-RPC 2.0)
8
- * 暴露 4 个工具:
9
- * wls_menu_query 查询菜单树
10
- * wls_menu_upsert 批量新增/更新菜单
11
- * wls_dict_query 查询字典模块
12
- * wls_dict_upsert 新增/更新字典模块及字典项
8
+ * 暴露工具:
9
+ * wls_menu_query 查询菜单树
10
+ * wls_menu_upsert 批量新增/更新菜单
11
+ * wls_dict_query 查询字典模块
12
+ * wls_dict_upsert 新增/更新字典模块及字典项
13
+ * wls_role_query 查询角色列表
14
+ * wls_role_upsert 批量新增角色(按 code 去重)
15
+ * wls_assignable_menus_query 查询全量可授权菜单(用于角色授权)
16
+ * wls_role_assign_menus 给角色批量分配菜单权限
17
+ * wls_action_query 查询页面菜单下的动作(type=A)
18
+ * wls_action_upsert 批量新增动作(按 permission 去重)
13
19
  *
14
20
  * 启动方式(由 .cursor/mcp.json 自动注入):
15
21
  * node node_modules/@agile-team/wl-skills-kit/mcp/server.js
@@ -19,6 +25,14 @@ const readline = require('readline')
19
25
  const { loadConfig } = require('./config')
20
26
  const { handleMenuQuery, handleMenuUpsert } = require('./tools/menuSync')
21
27
  const { handleDictQuery, handleDictUpsert } = require('./tools/dictSync')
28
+ const {
29
+ handleRoleQuery,
30
+ handleRoleUpsert,
31
+ handleRoleAssignMenus,
32
+ handleAssignableMenusQuery,
33
+ handleActionQuery,
34
+ handleActionUpsert,
35
+ } = require('./tools/permissionSync')
22
36
 
23
37
  const PKG = require('../package.json')
24
38
 
@@ -102,6 +116,94 @@ const TOOLS = [
102
116
  required: ['module'],
103
117
  },
104
118
  },
119
+ {
120
+ name: 'wls_role_query',
121
+ description:
122
+ '查询角色列表。可选参数 current/size 翻页,默认 size=100。返回精简字段:id, roleName, code, sysAppNo, roleDesc。',
123
+ inputSchema: {
124
+ type: 'object',
125
+ properties: {
126
+ current: { type: 'number', description: '页码,默认 1' },
127
+ size: { type: 'number', description: '每页数量,默认 100' },
128
+ },
129
+ required: [],
130
+ },
131
+ },
132
+ {
133
+ name: 'wls_role_upsert',
134
+ description:
135
+ '批量新增角色(按 code 字段自动去重;已存在则跳过)。每项必填 roleName 和 code,可选 configDesc。' +
136
+ '注意:角色仅新增不更新,因角色变更通常需要业务确认。',
137
+ inputSchema: {
138
+ type: 'object',
139
+ properties: {
140
+ items: {
141
+ type: 'array',
142
+ description:
143
+ '角色数组。字段:roleName(必填,显示名), code(必填,唯一标识), configDesc(可选,描述)',
144
+ items: { type: 'object' },
145
+ },
146
+ },
147
+ required: ['items'],
148
+ },
149
+ },
150
+ {
151
+ name: 'wls_assignable_menus_query',
152
+ description:
153
+ '查询全量可授权菜单列表(扁平结构,含菜单 id/menuName/permission)。' +
154
+ '在 wls_role_assign_menus 前调用,AI 据此选出要分配给角色的 menuIds。',
155
+ inputSchema: { type: 'object', properties: {}, required: [] },
156
+ },
157
+ {
158
+ name: 'wls_role_assign_menus',
159
+ description:
160
+ '给指定角色批量分配菜单权限。menuIds 传字符串数组,内部自动拼成逗号分隔字符串提交后端。' +
161
+ '该接口为全量覆盖式,应包含该角色所有菜单(含已有的,否则会被移除)。',
162
+ inputSchema: {
163
+ type: 'object',
164
+ properties: {
165
+ roleId: { type: 'string', description: '角色 id(来自 wls_role_query)' },
166
+ menuIds: {
167
+ type: 'array',
168
+ description: '该角色应拥有的全部菜单 id 数组',
169
+ items: { type: 'string' },
170
+ },
171
+ },
172
+ required: ['roleId', 'menuIds'],
173
+ },
174
+ },
175
+ {
176
+ name: 'wls_action_query',
177
+ description:
178
+ '查询指定页面菜单(type=C)下的动作按钮列表(type=A)。返回 id/menuName/permission/orderNum/icon。',
179
+ inputSchema: {
180
+ type: 'object',
181
+ properties: {
182
+ menuId: { type: 'string', description: '父菜单 id(页面菜单)' },
183
+ },
184
+ required: ['menuId'],
185
+ },
186
+ },
187
+ {
188
+ name: 'wls_action_upsert',
189
+ description:
190
+ '在指定页面菜单下批量新增动作按钮(type=A),按 permission 字段自动去重。' +
191
+ '权限码命名规范:{资源camelCase}_{动作} 或 {模块}:{资源}:{动作}(与项目既有约定保持一致)。' +
192
+ '常见动作:add/edit/remove/export/import/approve。',
193
+ inputSchema: {
194
+ type: 'object',
195
+ properties: {
196
+ parentId: { type: 'string', description: '页面菜单 id(动作挂在它下面)' },
197
+ items: {
198
+ type: 'array',
199
+ description:
200
+ '动作数组。字段:menuName(必填,显示名), permission(必填,权限码), icon(可选,默认list), orderNum(可选,默认1), useCache(可选,默认1)',
201
+ items: { type: 'object' },
202
+ },
203
+ },
204
+ required: ['parentId', 'items'],
205
+ },
206
+ },
105
207
  ]
106
208
 
107
209
  // ─── JSON-RPC 协议层 ────────────────────────────────────────────────────
@@ -145,6 +247,24 @@ async function dispatchTool(id, toolName, toolArgs) {
145
247
  case 'wls_dict_upsert':
146
248
  text = await handleDictUpsert(toolArgs, config)
147
249
  break
250
+ case 'wls_role_query':
251
+ text = await handleRoleQuery(toolArgs, config)
252
+ break
253
+ case 'wls_role_upsert':
254
+ text = await handleRoleUpsert(toolArgs, config)
255
+ break
256
+ case 'wls_assignable_menus_query':
257
+ text = await handleAssignableMenusQuery(toolArgs, config)
258
+ break
259
+ case 'wls_role_assign_menus':
260
+ text = await handleRoleAssignMenus(toolArgs, config)
261
+ break
262
+ case 'wls_action_query':
263
+ text = await handleActionQuery(toolArgs, config)
264
+ break
265
+ case 'wls_action_upsert':
266
+ text = await handleActionUpsert(toolArgs, config)
267
+ break
148
268
  default:
149
269
  sendError(id, -32601, `未知工具: ${toolName}`)
150
270
  return