@hupan56/wlkj 2.7.12 → 3.0.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.
- package/bin/cli.js +344 -78
- package/package.json +29 -29
- package/templates/.qoder/.runtime/ctx-cache-5660152f1d6dd819.md +23 -0
- package/templates/.qoder/.runtime/ctx-cache-afdce0dac06b25b0.md +23 -0
- package/templates/.qoder/.runtime/search-cache-eae7644e7b122f35.txt +1 -0
- package/templates/.qoder/learning/eval-history.jsonl +28 -0
- package/templates/data/index/wiki-index.json +8 -0
- package/templates/qoder/agents/insight-planning.md +1 -1
- package/templates/qoder/agents/insight-research.md +28 -15
- package/templates/qoder/commands/optional/wl-insight.md +159 -161
- package/templates/qoder/commands/optional/wl-report.md +4 -4
- package/templates/qoder/commands/optional/wl-status.md +2 -2
- package/templates/qoder/commands/wl-code.md +2 -2
- package/templates/qoder/commands/wl-design.md +2 -2
- package/templates/qoder/commands/wl-init.md +3 -3
- package/templates/qoder/commands/wl-prd.md +2 -2
- package/templates/qoder/commands/wl-req.md +43 -0
- package/templates/qoder/commands/wl-search.md +8 -8
- package/templates/qoder/commands/wl-task.md +17 -17
- package/templates/qoder/commands/wl-test.md +41 -15
- package/templates/qoder/config.yaml +17 -1
- package/templates/qoder/hooks/session-start.py +12 -22
- package/templates/qoder/nul +4 -0
- package/templates/qoder/rules/wl-pipeline.md +22 -48
- package/templates/qoder/scripts/README.md +139 -0
- package/templates/qoder/scripts/common/autotest_auth.py +109 -0
- package/templates/qoder/scripts/common/bootstrap.py +145 -0
- package/templates/qoder/scripts/common/check_publish.py +98 -0
- package/templates/qoder/scripts/common/cmd_registry.py +112 -0
- package/templates/qoder/scripts/common/config.py +187 -0
- package/templates/qoder/scripts/common/contract.py +317 -0
- package/templates/qoder/scripts/common/developer.py +2 -1
- package/templates/qoder/scripts/common/feishu.py +10 -9
- package/templates/qoder/scripts/common/guard.py +159 -0
- package/templates/qoder/scripts/common/identity.py +121 -2
- package/templates/qoder/scripts/common/kg_capabilities.py +182 -0
- package/templates/qoder/scripts/common/mcp_base.py +268 -0
- package/templates/qoder/scripts/common/paths.py +187 -1
- package/templates/qoder/scripts/common/result.py +223 -0
- package/templates/qoder/scripts/common/roles.py +60 -0
- package/templates/qoder/scripts/common/task_utils.py +21 -9
- package/templates/qoder/scripts/common/test_extract.py +115 -0
- package/templates/qoder/scripts/kg/__init__.py +11 -0
- package/templates/qoder/scripts/kg/build_entity_registry.py +196 -0
- package/templates/qoder/scripts/kg/build_relations.py +127 -0
- package/templates/qoder/scripts/{build_style_index.py → kg/build_style_index.py} +39 -10
- package/templates/qoder/scripts/kg/build_workflows.py +144 -0
- package/templates/qoder/scripts/{context_pack.py → kg/context_pack.py} +18 -11
- package/templates/qoder/scripts/{enrich_prompt.py → kg/enrich_prompt.py} +232 -226
- package/templates/qoder/scripts/{extract_api_params.py → kg/extract.py} +398 -246
- package/templates/qoder/scripts/{kg.py → kg/kg.py} +638 -708
- package/templates/qoder/scripts/{kg_build.py → kg/kg_build.py} +618 -612
- package/templates/qoder/scripts/{kg_build_db.py → kg/kg_build_db.py} +333 -327
- package/templates/qoder/scripts/{kg_duckdb.py → kg/kg_duckdb.py} +38 -37
- package/templates/qoder/scripts/{kg_incremental.py → kg/kg_incremental.py} +420 -393
- package/templates/qoder/scripts/{kg_link_db.py → kg/kg_link_db.py} +230 -224
- package/templates/qoder/scripts/{kg_semantic.py → kg/kg_semantic.py} +156 -150
- package/templates/qoder/scripts/kg/prefetch.py +359 -0
- package/templates/qoder/scripts/{search_index.py → kg/search_index.py} +70 -14
- package/templates/qoder/scripts/mcp/__init__.py +11 -0
- package/templates/qoder/scripts/{kg_mcp_server.py → mcp/kg_mcp_server.py} +77 -272
- package/templates/qoder/scripts/{lanhu_stdio_wrapper.py → mcp/lanhu_stdio_wrapper.py} +125 -119
- package/templates/qoder/scripts/{check_mcp.py → mcp/mcp_doctor.py} +515 -298
- package/templates/qoder/scripts/{mcp_launcher.py → mcp/mcp_launcher.py} +442 -414
- package/templates/qoder/scripts/{mysql_mcp_server.py → mcp/mysql_mcp_server.py} +347 -396
- package/templates/qoder/scripts/{zentao_mcp_server.py → mcp/zentao_mcp_server.py} +384 -424
- package/templates/qoder/scripts/report/__init__.py +11 -0
- package/templates/qoder/scripts/{add_session.py → report/add_session.py} +250 -244
- package/templates/qoder/scripts/{archive_prd.py → report/archive_prd.py} +383 -377
- package/templates/qoder/scripts/{eval_prd.py → report/eval_prd.py} +73 -11
- package/templates/qoder/scripts/{export.py → report/export.py} +63 -0
- package/templates/qoder/scripts/{fill_prototype.py → report/fill_prototype.py} +6 -0
- package/templates/qoder/scripts/{gen_design_doc.py → report/gen_design_doc.py} +400 -394
- package/templates/qoder/scripts/{learn.py → report/learn.py} +152 -146
- package/templates/qoder/scripts/{learn_aggregate.py → report/learn_aggregate.py} +207 -201
- package/templates/qoder/scripts/{report.py → report/report.py} +287 -281
- package/templates/qoder/scripts/report/req.py +222 -0
- package/templates/qoder/scripts/report/role.py +33 -0
- package/templates/qoder/scripts/{status.py → report/status.py} +634 -628
- package/templates/qoder/scripts/setup/__init__.py +11 -0
- package/templates/qoder/scripts/setup/carriers.py +662 -0
- package/templates/qoder/scripts/{init_doctor.py → setup/init_doctor.py} +63 -26
- package/templates/qoder/scripts/{install_qoderwork.py → setup/install_qoderwork.py} +36 -26
- package/templates/qoder/scripts/{platform_doctor.py → setup/platform_doctor.py} +265 -259
- package/templates/qoder/scripts/{repo_root.py → setup/repo_root.py} +112 -106
- package/templates/qoder/scripts/{setup.py → setup/setup.py} +113 -4
- package/templates/qoder/scripts/{setup_lanhu.py → setup/setup_lanhu.py} +973 -963
- package/templates/qoder/scripts/task/__init__.py +11 -0
- package/templates/qoder/scripts/{git_sync.py → task/git_sync.py} +52 -31
- package/templates/qoder/scripts/{syncgate.py → task/syncgate.py} +6 -0
- package/templates/qoder/scripts/task/task.py +221 -0
- package/templates/qoder/scripts/task/task_lifecycle.py +596 -0
- package/templates/qoder/scripts/task/task_query.py +161 -0
- package/templates/qoder/scripts/task/task_relations.py +424 -0
- package/templates/qoder/scripts/{team_sync.py → task/team_sync.py} +93 -20
- package/templates/qoder/scripts/test/__init__.py +11 -0
- package/templates/qoder/scripts/{autotest.py → test/autotest.py} +1174 -1751
- package/templates/qoder/scripts/{autotest_batch.py → test/autotest_batch.py} +242 -224
- package/templates/qoder/scripts/test/autotest_data.py +675 -0
- package/templates/qoder/scripts/{autotest_run.py → test/autotest_run.py} +309 -297
- package/templates/qoder/scripts/{benchmark.py → test/benchmark.py} +6 -0
- package/templates/qoder/scripts/{kg_auto_login.py → test/kg_auto_login.py} +202 -196
- package/templates/qoder/scripts/{kg_test_runner.py → test/kg_test_runner.py} +7 -1
- package/templates/qoder/scripts/{page_probe.py → test/page_probe.py} +465 -459
- package/templates/qoder/scripts/wlkj.py +116 -0
- package/templates/qoder/settings.json +1 -10
- package/templates/qoder/skills/design-import/SKILL.md +226 -226
- package/templates/qoder/skills/design-review/SKILL.md +82 -82
- package/templates/qoder/skills/prd-generator/SKILL.md +26 -16
- package/templates/qoder/skills/prd-review/SKILL.md +5 -5
- package/templates/qoder/skills/prototype-generator/SKILL.md +256 -256
- package/templates/qoder/skills/spec-coder/SKILL.md +4 -4
- package/templates/qoder/skills/spec-generator/SKILL.md +4 -4
- package/templates/qoder/skills/test-generator/SKILL.md +5 -5
- package/templates/qoder/skills/wl-code/SKILL.md +4 -4
- package/templates/qoder/skills/wl-commit/SKILL.md +4 -4
- package/templates/qoder/skills/wl-design/SKILL.md +3 -3
- package/templates/qoder/skills/wl-init/SKILL.md +8 -8
- package/templates/qoder/skills/wl-insight/SKILL.md +5 -5
- package/templates/qoder/skills/wl-prd-full/SKILL.md +6 -6
- package/templates/qoder/skills/wl-prd-quick/SKILL.md +6 -6
- package/templates/qoder/skills/wl-prd-review/SKILL.md +4 -4
- package/templates/qoder/skills/wl-report/SKILL.md +7 -7
- package/templates/qoder/skills/wl-search/SKILL.md +13 -13
- package/templates/qoder/skills/wl-spec/SKILL.md +5 -5
- package/templates/qoder/skills/wl-status/SKILL.md +5 -5
- package/templates/qoder/skills/wl-task/SKILL.md +6 -6
- package/templates/qoder/skills/wl-test/SKILL.md +102 -39
- package/templates/root/AGENTS.md +39 -40
- package/templates/qoder/hooks/inject-workflow-state.py +0 -169
- package/templates/qoder/scripts/__pycache__/check_mcp_launch.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/__pycache__/install_qoderwork.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/__pycache__/mcp_launcher.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/__pycache__/platform_doctor.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/check_carriers.py +0 -238
- package/templates/qoder/scripts/check_mcp_launch.py +0 -183
- package/templates/qoder/scripts/check_qoderwork_consistency.py +0 -166
- package/templates/qoder/scripts/collect_prds.py +0 -31
- package/templates/qoder/scripts/common/mentions.py +0 -134
- package/templates/qoder/scripts/common/utf8.py +0 -38
- package/templates/qoder/scripts/extract_routes.py +0 -54
- package/templates/qoder/scripts/extract_routes_tree.py +0 -78
- package/templates/qoder/scripts/handoff.py +0 -22
- package/templates/qoder/scripts/init_developer.py +0 -76
- package/templates/qoder/scripts/parse_prds.py +0 -33
- package/templates/qoder/scripts/role.py +0 -51
- package/templates/qoder/scripts/sync_carriers.py +0 -259
- package/templates/qoder/scripts/task.py +0 -1261
- package/templates/qoder/scripts/workspace_init.py +0 -102
- package/templates/qoder/skills/prompt-enrich/SKILL.md +0 -90
- package/templates/qoder/skills/prototype-generator/SKILL.md.zcode-79180-2af4721f-f9a6-412c-88db-c0af680d211b.tmp +0 -0
- /package/templates/qoder/scripts/{secure-ls.js → test/secure-ls.js} +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
wlkj.py - 工作流顶层调度器 (统一入口, 兼容旧调用)
|
|
5
|
+
|
|
6
|
+
v3.0 引入: 把分散的脚本调用收敛到一个入口, 提供"逻辑分组"体验,
|
|
7
|
+
而不需要物理分子目录 (避免 170+ 处路径改写 + 40 处 sys.path 风险)。
|
|
8
|
+
|
|
9
|
+
用法 (与旧 python .qoder/scripts/xxx.py 等价):
|
|
10
|
+
python .qoder/scripts/wlkj.py kg search 保险 --platform web
|
|
11
|
+
python .qoder/scripts/wlkj.py task list
|
|
12
|
+
python .qoder/scripts/wlkj.py doctor --fix
|
|
13
|
+
python .qoder/scripts/wlkj.py search 考勤
|
|
14
|
+
python .qoder/scripts/wlkj.py status
|
|
15
|
+
|
|
16
|
+
分组 (逻辑导航, 非物理目录):
|
|
17
|
+
kg/* 知识图谱 (kg.py 的子命令直接透传)
|
|
18
|
+
task 任务系统
|
|
19
|
+
search 代码搜索
|
|
20
|
+
doctor 环境体检
|
|
21
|
+
status 项目状态
|
|
22
|
+
sync 团队同步
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
设计:
|
|
26
|
+
- 透明转发: 不改变任何子脚本的行为, 只是把 argv 转过去
|
|
27
|
+
- 兼容: 旧的 `python .qoder/scripts/kg.py` 仍可用 (脚本都还在原位)
|
|
28
|
+
- 零维护: 加新命令只需在 DISPATCH 表加一行
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
import os
|
|
32
|
+
import subprocess
|
|
33
|
+
import sys
|
|
34
|
+
|
|
35
|
+
# 命令 → 脚本 映射 (加新命令只需在此加一行)
|
|
36
|
+
# v3.0: 脚本已分子目录, 路径更新为 子包/脚本
|
|
37
|
+
DISPATCH = {
|
|
38
|
+
'kg': 'kg/kg.py',
|
|
39
|
+
'task': 'task/task.py',
|
|
40
|
+
'sync': 'task/team_sync.py',
|
|
41
|
+
'team-sync': 'task/team_sync.py',
|
|
42
|
+
'git-sync': 'task/git_sync.py',
|
|
43
|
+
'search': 'kg/search_index.py',
|
|
44
|
+
'context': 'kg/context_pack.py',
|
|
45
|
+
'prefetch': 'kg/prefetch.py',
|
|
46
|
+
'status': 'report/status.py',
|
|
47
|
+
'report': 'report/report.py',
|
|
48
|
+
'doctor': 'setup/init_doctor.py',
|
|
49
|
+
'init': 'setup/setup.py',
|
|
50
|
+
'test': 'test/autotest.py',
|
|
51
|
+
'autotest': 'test/autotest.py',
|
|
52
|
+
'eval': 'report/eval_prd.py',
|
|
53
|
+
'eva': 'report/eval_prd.py',
|
|
54
|
+
'export': 'report/export.py',
|
|
55
|
+
'style': 'kg/build_style_index.py',
|
|
56
|
+
'role': 'report/role.py',
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _usage():
|
|
61
|
+
lines = [
|
|
62
|
+
'wlkj.py — 工作流顶层调度器',
|
|
63
|
+
'',
|
|
64
|
+
'用法: python .qoder/scripts/wlkj.py <命令> [参数...]',
|
|
65
|
+
'',
|
|
66
|
+
'命令分组 (转发到对应脚本):',
|
|
67
|
+
' 知识图谱: kg <子命令> (kg.py, 13+ 能力)',
|
|
68
|
+
' 任务: task <子命令> (task.py, create/list/start/finish)',
|
|
69
|
+
' 同步: sync pull|push (team_sync.py)',
|
|
70
|
+
' 搜索: search <词> (search_index.py)',
|
|
71
|
+
' 上下文: context <词> (context_pack.py)',
|
|
72
|
+
' 体检: doctor [--fix] (init_doctor.py)',
|
|
73
|
+
' 状态: status (status.py)',
|
|
74
|
+
' 报告: report daily|weekly (report.py)',
|
|
75
|
+
' 测试: test <子命令> (autotest.py)',
|
|
76
|
+
' 评估: eval <prd.md> (eval_prd.py)',
|
|
77
|
+
' 导出: export <格式> (export.py)',
|
|
78
|
+
'',
|
|
79
|
+
'示例:',
|
|
80
|
+
' wlkj.py kg search 保险 --platform web',
|
|
81
|
+
' wlkj.py task create "登录优化"',
|
|
82
|
+
' wlkj.py doctor --fix',
|
|
83
|
+
'',
|
|
84
|
+
'注: 旧的 python .qoder/scripts/kg.py 形式仍可用 (脚本在原位)。',
|
|
85
|
+
]
|
|
86
|
+
return '\n'.join(lines)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def main():
|
|
90
|
+
argv = sys.argv[1:]
|
|
91
|
+
if not argv or argv[0] in ('-h', '--help', 'help'):
|
|
92
|
+
print(_usage())
|
|
93
|
+
return 0
|
|
94
|
+
|
|
95
|
+
cmd = argv[0]
|
|
96
|
+
rest = argv[1:]
|
|
97
|
+
|
|
98
|
+
script = DISPATCH.get(cmd)
|
|
99
|
+
if not script:
|
|
100
|
+
# 未知命令: 提示 + 退出
|
|
101
|
+
sys.stderr.write('未知命令: %s\n' % cmd)
|
|
102
|
+
sys.stderr.write('可用命令: %s\n' % ', '.join(sorted(DISPATCH.keys())))
|
|
103
|
+
return 1
|
|
104
|
+
|
|
105
|
+
script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), script)
|
|
106
|
+
if not os.path.isfile(script_path):
|
|
107
|
+
sys.stderr.write('脚本不存在: %s\n' % script_path)
|
|
108
|
+
return 1
|
|
109
|
+
|
|
110
|
+
# 透明转发: 用当前 python 跑目标脚本, 透传所有参数和 exit code
|
|
111
|
+
r = subprocess.run([sys.executable, script_path] + rest)
|
|
112
|
+
return r.returncode
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if __name__ == '__main__':
|
|
116
|
+
sys.exit(main())
|
|
@@ -1,226 +1,226 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: design-import
|
|
3
|
-
description: "把设计师的 Figma/Axure 设计稿录入工作流,生成设计规范 spec.json 并存入知识图谱。Import designer's Figma/Axure design into the pipeline as a style spec.
|
|
4
|
-
trigger: "user
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## 🔧 仓库根定位(QoderWork 桌面端 vs Qoder IDE/CLI)
|
|
9
|
-
|
|
10
|
-
**后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
|
|
11
|
-
```bash
|
|
12
|
-
R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
13
|
-
```
|
|
14
|
-
> `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python .qoder/scripts/install_qoderwork.py`。
|
|
15
|
-
|
|
16
|
-
# Design Import Skill(设计师专用)
|
|
17
|
-
|
|
18
|
-
> 🚫 **边界铁律:蓝湖工具(`mcp__lanhu__*`)只能在本 skill(即 `/wl-design
|
|
19
|
-
> 用户直接说"查蓝湖""读一下这个蓝湖链接"而没走录入命令时,**不要裸调蓝湖**——先确认意图,
|
|
20
|
-
> 引导到 `/wl-design
|
|
21
|
-
> 不能脱离流程裸调工具(否则不可控、不可审计)。
|
|
22
|
-
|
|
23
|
-
把设计师在 Figma/Axure 里出的设计稿,转成工作流能消化的**设计规范 spec.json**,
|
|
24
|
-
存到 `data/style/`,进入知识图谱。从此同需求的 AI 原型优先锚定这份 spec,
|
|
25
|
-
不再跟设计师的稿打架。
|
|
26
|
-
|
|
27
|
-
## ⚙️ 自取上下文(QoderWork 无 hook 注入,必须自读)
|
|
28
|
-
|
|
29
|
-
- `.qoder/.developer` — 当前设计师名(产出归属)
|
|
30
|
-
- `.qoder/.current-task` — 若存在,spec 命名带上任务关键词
|
|
31
|
-
- 平台必须明确(Web/APP/Both);如未指定,先问
|
|
32
|
-
|
|
33
|
-
**已录入清单**(设计师问"我录过哪些"时):
|
|
34
|
-
```bash
|
|
35
|
-
ls "$R/data/style/"*-design-spec.json 2>/dev/null # 列所有 spec
|
|
36
|
-
```
|
|
37
|
-
对每个文件读 `requirement`/`platform`/`source` 字段汇总给设计师,让他知道哪些录过、哪端录了。
|
|
38
|
-
|
|
39
|
-
## Step 0: 确认平台
|
|
40
|
-
|
|
41
|
-
跟 /wl-prd-full 一样,先问:Web 管理端 / APP 移动端 / 两端都要?
|
|
42
|
-
**问了就停,等设计师回答。**
|
|
43
|
-
|
|
44
|
-
## Step 1: 收集设计信息
|
|
45
|
-
|
|
46
|
-
设计师用以下任一方式提供设计信息(按精度从高到低排):
|
|
47
|
-
|
|
48
|
-
**方式 A(最推荐):蓝湖链接直读**
|
|
49
|
-
|
|
50
|
-
设计师发蓝湖链接(`https://lanhuapp.com/web/#/item/...`),AI 用蓝湖 MCP 精确提取颜色/尺寸/字体/切图,比截图口述精确 10 倍。**走以下 4 步,每步失败就降级到方式 B(绝不报错、绝不阻塞):**
|
|
51
|
-
|
|
52
|
-
**A-1. 探测蓝湖可用性(失败就静默降级)**
|
|
53
|
-
```
|
|
54
|
-
调 mcp__lanhu__get_designs(url=<链接>)
|
|
55
|
-
```
|
|
56
|
-
- 返回设计图列表 → 继续 A-2
|
|
57
|
-
- 报"连接失败"/工具不存在/418(cookie 失效)→ **立刻降级**:告诉用户"蓝湖没起/cookie 失效,改用截图口述",然后走方式 B,**不许卡住**
|
|
58
|
-
|
|
59
|
-
> 蓝湖是增强不是必需。没有蓝湖,工作流照样完整跑(方式 B/C/D 都不依赖蓝湖)。
|
|
60
|
-
|
|
61
|
-
**A-2. 选设计图(图多时帮用户缩小范围)**
|
|
62
|
-
```
|
|
63
|
-
调 mcp__lanhu__get_designs(url=<链接>) → 返回 {designs:[{name, width, height, ...}], sectors:[...], total_designs}
|
|
64
|
-
```
|
|
65
|
-
- **图少(≤15 张)**:直接列全部图名,问"录入哪张?"(**问了就停**)
|
|
66
|
-
- **图多(>15 张)**:别一次倒几百张,先帮缩小:
|
|
67
|
-
1. 若有 `sectors`(分组):先列分组名+图数,问"哪个分组?",再列该组图
|
|
68
|
-
2. 没分组:问设计师"你要录的功能叫什么?",按图名关键词过滤后列
|
|
69
|
-
3. 过滤掉明显占位名(如重复的"命名"),只列有意义的
|
|
70
|
-
- 选定后记下图名,进 A-3。**可一次选多张**(`design_names` 支持数组)。
|
|
71
|
-
|
|
72
|
-
**A-3. 读标注 + 切图**
|
|
73
|
-
```
|
|
74
|
-
调 mcp__lanhu__get_ai_analyze_design_result(url=<链接>, design_names=[<选中的图名>])
|
|
75
|
-
→ 返回: HTML/CSS 标注 (rgba 值、width、padding、font...) + 还原指引
|
|
76
|
-
调 mcp__lanhu__get_design_slices(url=<链接>, design_name=<图名>, include_metadata=true)
|
|
77
|
-
→ 返回: {slices:[{name, size, download_url, svg_url, scale_urls:{1x,2x,3x}}]}
|
|
78
|
-
```
|
|
79
|
-
- CSS 标注 → 填 `design_tokens`/`layout`/`components`
|
|
80
|
-
- **切图**:每个 slice 的 `svg_url` 是设计师切的**真实图标矢量**。挑出图标类(size 小、name 含"图标/icon/箭头"等),
|
|
81
|
-
填进 spec.json 的 `icons` 字段(见 Step 2)。这是原型图标的最佳真源(优于 ref-icon.json 通用图标)。
|
|
82
|
-
返回的 CSS 标注是**设计稿的权威真值**,优先级高于代码风格、高于 PDF 规范。
|
|
83
|
-
|
|
84
|
-
**A-4. AI 语义映射进 spec.json(关键:落到实处)**
|
|
85
|
-
蓝湖返回的是一堆 CSS 属性,AI 读懂后**语义判断**填进 spec.json 各字段:
|
|
86
|
-
|
|
87
|
-
| 蓝湖返回 | 填进 spec.json 哪里 | 怎么判断 |
|
|
88
|
-
|---------|-------------------|---------|
|
|
89
|
-
| 出现最多的背景色/按钮色 (如 `rgba(255,115,10,1)`) | `design_tokens["--primary-color"]` | 统计频率,按钮/导航反复用的色 = 主色 |
|
|
90
|
-
| 容器 width (如 `200px`) | `design_tokens["--sidebar-width"]` | web 端左侧固定宽容器 = 侧边栏 |
|
|
91
|
-
| 行高 padding font-size | `design_tokens["--table-row-height"]` 等 | 表格行的 height |
|
|
92
|
-
| 布局结构 | `layout.description` / `layout.sidebar` | 看是左+右(web) 还是单列(app) |
|
|
93
|
-
| 卡片/表格/表单/按钮组 | `components[]` | 按视觉块列 |
|
|
94
|
-
|
|
95
|
-
**铁律:CSS 值原样填,禁止改格式。** `rgba(255,115,10,1)` 不要写成 `#FF730A`,`200px` 不要四舍五入。蓝湖给什么就填什么(这是设计稿的真值,AI 改了就不准了)。
|
|
96
|
-
|
|
97
|
-
> 蓝湖 MCP 是 STDIO 模式:开 QoderWork 自动起、关自动停,**无需手动 start**。
|
|
98
|
-
> cookie 按角色隔离在 `workspace/members/{当前用户}/.secrets/lanhu.env`(不进 git)——
|
|
99
|
-
> wrapper(lanhu_stdio_wrapper.py)读当前 `.developer` 角色的 cookie 拉起服务,UI 角色有改稿权限、PM/开发只读。
|
|
100
|
-
> 没配的话跑 `python "$R/.qoder/scripts/setup_lanhu.py"`;换角色改 `.developer` + 配新角色 cookie 后重启 QoderWork。
|
|
101
|
-
|
|
102
|
-
**方式 B:截图 + 口述**
|
|
103
|
-
设计师发一张 Figma/Axure 截图,口述关键设计决策:
|
|
104
|
-
- "主色用 #1677ff,背景用 #f5f5f5"
|
|
105
|
-
- "侧边栏宽 200px,一级菜单点击展开二级"
|
|
106
|
-
- "表格行高 48px,斑马纹"
|
|
107
|
-
|
|
108
|
-
**方式 C:导出标注**
|
|
109
|
-
设计师从 Figma 导出 CSS / 标注 PDF / tokens JSON,AI 直接读。
|
|
110
|
-
|
|
111
|
-
**方式 D:参照现有系统页面改**
|
|
112
|
-
设计师说"类似 XX 页面,但侧边栏改成手风琴式"——AI 读那个页面代码,提取基础 spec,再叠加设计师的改动。
|
|
113
|
-
|
|
114
|
-
## Step 2: 生成 spec.json
|
|
115
|
-
|
|
116
|
-
把设计信息结构化成 spec.json,格式对齐 `data/index/vben-style-reference.json`:
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"source": "Figma (设计师: {designer})",
|
|
121
|
-
"imported_at": "2026-06-16",
|
|
122
|
-
"platform": "web",
|
|
123
|
-
"requirement": "{需求名}",
|
|
124
|
-
"design_tokens": {
|
|
125
|
-
"--primary-color": "#1677ff",
|
|
126
|
-
"--bg-color": "#f5f5f5",
|
|
127
|
-
"--sidebar-width": "200px",
|
|
128
|
-
"--table-row-height": "48px"
|
|
129
|
-
},
|
|
130
|
-
"layout": {
|
|
131
|
-
"description": "左侧侧边栏 + 右侧内容区;一级菜单点击展开二级手风琴",
|
|
132
|
-
"sidebar": "width: 200px, collapsible, accordion mode",
|
|
133
|
-
"content": "padding: 16px, background: #f5f5f5"
|
|
134
|
-
},
|
|
135
|
-
"components": [
|
|
136
|
-
{"name": "侧边栏菜单", "spec": "三级折叠,一级固定,二级手风琴展开"},
|
|
137
|
-
{"name": "数据表格", "spec": "VxeGrid 风格,行高 48px,斑马纹"}
|
|
138
|
-
],
|
|
139
|
-
"notes": "设计师强调:侧边栏必须有图标,不能用纯文字",
|
|
140
|
-
"icons": [
|
|
141
|
-
{"name": "返回箭头", "svg_url": "https://lanhu-oss-.../xxx.svg", "size": "7x14", "usage": "顶部返回按钮"},
|
|
142
|
-
{"name": "提交图标", "svg_url": "https://lanhu-oss-.../yyy.svg", "size": "20x20", "usage": "提交按钮"}
|
|
143
|
-
],
|
|
144
|
-
"lanhu_source": {
|
|
145
|
-
"url": "https://lanhuapp.com/web/#/item/project/stage?pid=...",
|
|
146
|
-
"image_names": ["问题反馈-详情"],
|
|
147
|
-
"slice_count": 12,
|
|
148
|
-
"imported_at": "2026-06-18"
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
> ⚠️ **`requirement` 字段是落地关键**:fill_prototype.py 靠它匹配关键词
|
|
154
|
-
> (`load_design_spec` 扫描 `data/style/*-design-spec.json`,`requirement` 包含查询词就命中)。
|
|
155
|
-
> 所以 `requirement` 必须跟未来 `/wl-design
|
|
156
|
-
> 蓝湖来源时填 `source: "蓝湖直读 (设计师: XX)"`,截图口述填 `source: "Figma (设计师: XX)"`,
|
|
157
|
-
> 下游 fill_prototype 不管来源只认值。
|
|
158
|
-
> **`lanhu_source` 可选**:仅蓝湖来源时填,记录链接/图名/切图数,可追溯设计稿出处。
|
|
159
|
-
|
|
160
|
-
## Step 3: 存储到知识图谱
|
|
161
|
-
|
|
162
|
-
- 存到 `data/style/{需求名}-{平台}-design-spec.json`(平台 = web/app,避免同功能多端冲突)
|
|
163
|
-
- 例:`待办-web-design-spec.json`、`待办-app-design-spec.json`
|
|
164
|
-
- 同需求同平台重新录入 → 覆盖(更新);不同平台 → 各自独立文件
|
|
165
|
-
- **优先级声明**:这份 spec 的优先级 > 代码风格 > PDF 规范
|
|
166
|
-
(因为它是最新、最明确的设计决策)
|
|
167
|
-
- **`requirement` 字段填法**(解决"设计师不知道 PM 搜什么词"):
|
|
168
|
-
用**功能名 + 同义词**,别只填图名。如图名"设置-我的待办",requirement 填 `"待办 我的待办 设置待办"`
|
|
169
|
-
(空格分隔多个可能的关键词),这样 PM 搜"待办"或"我的待办"都能命中。
|
|
170
|
-
|
|
171
|
-
> 🎯 **落地链路(已验证通)**:spec.json 落盘后,下次 `/wl-design
|
|
172
|
-
> `fill_prototype.py` 的 `load_design_spec()` 会自动命中这份 spec(靠 `requirement` 字段匹配),
|
|
173
|
-
> 把 `design_tokens` **原样注入**原型 HTML 的 `:root` CSS(最高优先级,覆盖模板默认色)。
|
|
174
|
-
> 即:蓝湖读到的 `rgba(255,115,10,1)` 会真实出现在原型里,不是 AI 看一眼就忘。
|
|
175
|
-
> 验证方法:看输出原型 `:root` 里有没有 `/* design-import spec tokens (优先级最高) */` 注释及下面的值。
|
|
176
|
-
|
|
177
|
-
## Step 3.5: 录入埋点
|
|
178
|
-
|
|
179
|
-
spec.json 落盘后埋点,供 /wl-status 统计设计录入活跃度:
|
|
180
|
-
```bash
|
|
181
|
-
python "$R/.qoder/scripts/learn.py" record design_import "{\"requirement\": \"<需求名>\", \"platform\": \"<web|app>\", \"source\": \"<蓝湖|截图|导出>\"}"
|
|
182
|
-
```
|
|
183
|
-
> 失败静默忽略。
|
|
184
|
-
|
|
185
|
-
## Step 4: 确认与通知
|
|
186
|
-
输出给设计师:
|
|
187
|
-
```
|
|
188
|
-
✅ 设计规范已录入: data/style/{需求名}-design-spec.json
|
|
189
|
-
- 平台: Web 管理端
|
|
190
|
-
- 来源: 蓝湖直读 (设计师: XX) ← 或 截图口述
|
|
191
|
-
- 主色: rgba(255,115,10,1)
|
|
192
|
-
- 布局: 左侧边栏 200px + 手风琴二级菜单
|
|
193
|
-
- 组件: 侧边栏菜单、数据表格
|
|
194
|
-
|
|
195
|
-
✅ 已自动接入原型链路:下次 PM/任何人用同一关键词出原型时,
|
|
196
|
-
fill_prototype.py 会自动发现并优先用这份 spec(优先级高于代码风格),
|
|
197
|
-
主色/侧边栏宽度/布局全部按你的设计来(design_tokens 注入原型 :root)。
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
设计师可以随时说"录入设计稿"更新它。
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
## 铁律
|
|
204
|
-
|
|
205
|
-
- **有蓝湖 MCP 时优先用它直读**:设计师发蓝湖链接,AI 调 `mcp__lanhu__*` 提取精确参数,
|
|
206
|
-
不要让设计师截图口述(截图口述是蓝湖不可用时的降级方案)
|
|
207
|
-
- **绝不编造 token**:设计师没说的值,留空或标"待确认",不要自己猜
|
|
208
|
-
- **图标必须来自真源**:即使设计师用了 emoji 示意,录入时也要替换成系统真源
|
|
209
|
-
(Web: data/index/ref-icon.json 的 Ant Design SVG)
|
|
210
|
-
- **spec 一旦录入,同需求 prototype 必须锚定它**:AI 出原型前先查 data/style/ 有没有 spec
|
|
211
|
-
|
|
212
|
-
## 🆕 录入前可参考知识图谱新数据
|
|
213
|
-
|
|
214
|
-
设计师录入 spec 前,可以先问 AI 系统现状,让 spec 更贴合系统:
|
|
215
|
-
|
|
216
|
-
- **"这个功能模块现在有哪些页面?"** → AI 调 `mcp__qoder-knowledge-graph__feature_overview(feature='资产管理')`
|
|
217
|
-
返回该模块所有页面 + API + 按钮,设计师知道改哪些、加哪些
|
|
218
|
-
- **"这个模块的业务流程是什么?"** → AI 调 `mcp__qoder-knowledge-graph__get_workflow(module='资产')`
|
|
219
|
-
返回操作链(查询→新增→审批→...),spec 里的交互流程跟系统一致
|
|
220
|
-
- **"系统里这个模块的按钮都叫什么?"** → 看 DESIGN.md 的 "Real Button Texts" 段
|
|
221
|
-
或 entity-registry.json,spec 里的按钮文案跟系统统一
|
|
222
|
-
- **"这个模块用的是什么布局模式?"** → 看 DESIGN.md 的 layout_fingerprint
|
|
223
|
-
spec 里的侧边栏宽度/布局模式跟系统一致(如 160px / mixed-nav)
|
|
224
|
-
|
|
225
|
-
> 这些数据让设计师的 spec 不是"凭空设计",而是"基于系统现状的增量改进"——
|
|
226
|
-
> 录入的 spec 天然就跟系统风格一致,AI 出原型时不会打架。
|
|
1
|
+
---
|
|
2
|
+
name: design-import
|
|
3
|
+
description: "把设计师的 Figma/Axure 设计稿录入工作流,生成设计规范 spec.json 并存入知识图谱。Import designer's Figma/Axure design into the pipeline as a style spec. "
|
|
4
|
+
trigger: "user invokes /wl-* command explicitly"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## 🔧 仓库根定位(QoderWork 桌面端 vs Qoder IDE/CLI)
|
|
9
|
+
|
|
10
|
+
**后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
|
|
11
|
+
```bash
|
|
12
|
+
R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
13
|
+
```
|
|
14
|
+
> `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python .qoder/scripts/setup/install_qoderwork.py`。
|
|
15
|
+
|
|
16
|
+
# Design Import Skill(设计师专用)
|
|
17
|
+
|
|
18
|
+
> 🚫 **边界铁律:蓝湖工具(`mcp__lanhu__*`)只能在本 skill(即 `/wl-design 预览`)内部调用。**
|
|
19
|
+
> 用户直接说"查蓝湖""读一下这个蓝湖链接"而没走录入命令时,**不要裸调蓝湖**——先确认意图,
|
|
20
|
+
> 引导到 `/wl-design 预览 <蓝湖链接>`。工作流是非侵入式的,所有能力必须经命令/工序站触发,
|
|
21
|
+
> 不能脱离流程裸调工具(否则不可控、不可审计)。
|
|
22
|
+
|
|
23
|
+
把设计师在 Figma/Axure 里出的设计稿,转成工作流能消化的**设计规范 spec.json**,
|
|
24
|
+
存到 `data/style/`,进入知识图谱。从此同需求的 AI 原型优先锚定这份 spec,
|
|
25
|
+
不再跟设计师的稿打架。
|
|
26
|
+
|
|
27
|
+
## ⚙️ 自取上下文(QoderWork 无 hook 注入,必须自读)
|
|
28
|
+
|
|
29
|
+
- `.qoder/.developer` — 当前设计师名(产出归属)
|
|
30
|
+
- `.qoder/.current-task` — 若存在,spec 命名带上任务关键词
|
|
31
|
+
- 平台必须明确(Web/APP/Both);如未指定,先问
|
|
32
|
+
|
|
33
|
+
**已录入清单**(设计师问"我录过哪些"时):
|
|
34
|
+
```bash
|
|
35
|
+
ls "$R/data/style/"*-design-spec.json 2>/dev/null # 列所有 spec
|
|
36
|
+
```
|
|
37
|
+
对每个文件读 `requirement`/`platform`/`source` 字段汇总给设计师,让他知道哪些录过、哪端录了。
|
|
38
|
+
|
|
39
|
+
## Step 0: 确认平台
|
|
40
|
+
|
|
41
|
+
跟 /wl-prd-full 一样,先问:Web 管理端 / APP 移动端 / 两端都要?
|
|
42
|
+
**问了就停,等设计师回答。**
|
|
43
|
+
|
|
44
|
+
## Step 1: 收集设计信息
|
|
45
|
+
|
|
46
|
+
设计师用以下任一方式提供设计信息(按精度从高到低排):
|
|
47
|
+
|
|
48
|
+
**方式 A(最推荐):蓝湖链接直读**
|
|
49
|
+
|
|
50
|
+
设计师发蓝湖链接(`https://lanhuapp.com/web/#/item/...`),AI 用蓝湖 MCP 精确提取颜色/尺寸/字体/切图,比截图口述精确 10 倍。**走以下 4 步,每步失败就降级到方式 B(绝不报错、绝不阻塞):**
|
|
51
|
+
|
|
52
|
+
**A-1. 探测蓝湖可用性(失败就静默降级)**
|
|
53
|
+
```
|
|
54
|
+
调 mcp__lanhu__get_designs(url=<链接>)
|
|
55
|
+
```
|
|
56
|
+
- 返回设计图列表 → 继续 A-2
|
|
57
|
+
- 报"连接失败"/工具不存在/418(cookie 失效)→ **立刻降级**:告诉用户"蓝湖没起/cookie 失效,改用截图口述",然后走方式 B,**不许卡住**
|
|
58
|
+
|
|
59
|
+
> 蓝湖是增强不是必需。没有蓝湖,工作流照样完整跑(方式 B/C/D 都不依赖蓝湖)。
|
|
60
|
+
|
|
61
|
+
**A-2. 选设计图(图多时帮用户缩小范围)**
|
|
62
|
+
```
|
|
63
|
+
调 mcp__lanhu__get_designs(url=<链接>) → 返回 {designs:[{name, width, height, ...}], sectors:[...], total_designs}
|
|
64
|
+
```
|
|
65
|
+
- **图少(≤15 张)**:直接列全部图名,问"录入哪张?"(**问了就停**)
|
|
66
|
+
- **图多(>15 张)**:别一次倒几百张,先帮缩小:
|
|
67
|
+
1. 若有 `sectors`(分组):先列分组名+图数,问"哪个分组?",再列该组图
|
|
68
|
+
2. 没分组:问设计师"你要录的功能叫什么?",按图名关键词过滤后列
|
|
69
|
+
3. 过滤掉明显占位名(如重复的"命名"),只列有意义的
|
|
70
|
+
- 选定后记下图名,进 A-3。**可一次选多张**(`design_names` 支持数组)。
|
|
71
|
+
|
|
72
|
+
**A-3. 读标注 + 切图**
|
|
73
|
+
```
|
|
74
|
+
调 mcp__lanhu__get_ai_analyze_design_result(url=<链接>, design_names=[<选中的图名>])
|
|
75
|
+
→ 返回: HTML/CSS 标注 (rgba 值、width、padding、font...) + 还原指引
|
|
76
|
+
调 mcp__lanhu__get_design_slices(url=<链接>, design_name=<图名>, include_metadata=true)
|
|
77
|
+
→ 返回: {slices:[{name, size, download_url, svg_url, scale_urls:{1x,2x,3x}}]}
|
|
78
|
+
```
|
|
79
|
+
- CSS 标注 → 填 `design_tokens`/`layout`/`components`
|
|
80
|
+
- **切图**:每个 slice 的 `svg_url` 是设计师切的**真实图标矢量**。挑出图标类(size 小、name 含"图标/icon/箭头"等),
|
|
81
|
+
填进 spec.json 的 `icons` 字段(见 Step 2)。这是原型图标的最佳真源(优于 ref-icon.json 通用图标)。
|
|
82
|
+
返回的 CSS 标注是**设计稿的权威真值**,优先级高于代码风格、高于 PDF 规范。
|
|
83
|
+
|
|
84
|
+
**A-4. AI 语义映射进 spec.json(关键:落到实处)**
|
|
85
|
+
蓝湖返回的是一堆 CSS 属性,AI 读懂后**语义判断**填进 spec.json 各字段:
|
|
86
|
+
|
|
87
|
+
| 蓝湖返回 | 填进 spec.json 哪里 | 怎么判断 |
|
|
88
|
+
|---------|-------------------|---------|
|
|
89
|
+
| 出现最多的背景色/按钮色 (如 `rgba(255,115,10,1)`) | `design_tokens["--primary-color"]` | 统计频率,按钮/导航反复用的色 = 主色 |
|
|
90
|
+
| 容器 width (如 `200px`) | `design_tokens["--sidebar-width"]` | web 端左侧固定宽容器 = 侧边栏 |
|
|
91
|
+
| 行高 padding font-size | `design_tokens["--table-row-height"]` 等 | 表格行的 height |
|
|
92
|
+
| 布局结构 | `layout.description` / `layout.sidebar` | 看是左+右(web) 还是单列(app) |
|
|
93
|
+
| 卡片/表格/表单/按钮组 | `components[]` | 按视觉块列 |
|
|
94
|
+
|
|
95
|
+
**铁律:CSS 值原样填,禁止改格式。** `rgba(255,115,10,1)` 不要写成 `#FF730A`,`200px` 不要四舍五入。蓝湖给什么就填什么(这是设计稿的真值,AI 改了就不准了)。
|
|
96
|
+
|
|
97
|
+
> 蓝湖 MCP 是 STDIO 模式:开 QoderWork 自动起、关自动停,**无需手动 start**。
|
|
98
|
+
> cookie 按角色隔离在 `workspace/members/{当前用户}/.secrets/lanhu.env`(不进 git)——
|
|
99
|
+
> wrapper(lanhu_stdio_wrapper.py)读当前 `.developer` 角色的 cookie 拉起服务,UI 角色有改稿权限、PM/开发只读。
|
|
100
|
+
> 没配的话跑 `python "$R/.qoder/scripts/setup/setup_lanhu.py"`;换角色改 `.developer` + 配新角色 cookie 后重启 QoderWork。
|
|
101
|
+
|
|
102
|
+
**方式 B:截图 + 口述**
|
|
103
|
+
设计师发一张 Figma/Axure 截图,口述关键设计决策:
|
|
104
|
+
- "主色用 #1677ff,背景用 #f5f5f5"
|
|
105
|
+
- "侧边栏宽 200px,一级菜单点击展开二级"
|
|
106
|
+
- "表格行高 48px,斑马纹"
|
|
107
|
+
|
|
108
|
+
**方式 C:导出标注**
|
|
109
|
+
设计师从 Figma 导出 CSS / 标注 PDF / tokens JSON,AI 直接读。
|
|
110
|
+
|
|
111
|
+
**方式 D:参照现有系统页面改**
|
|
112
|
+
设计师说"类似 XX 页面,但侧边栏改成手风琴式"——AI 读那个页面代码,提取基础 spec,再叠加设计师的改动。
|
|
113
|
+
|
|
114
|
+
## Step 2: 生成 spec.json
|
|
115
|
+
|
|
116
|
+
把设计信息结构化成 spec.json,格式对齐 `data/index/vben-style-reference.json`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"source": "Figma (设计师: {designer})",
|
|
121
|
+
"imported_at": "2026-06-16",
|
|
122
|
+
"platform": "web",
|
|
123
|
+
"requirement": "{需求名}",
|
|
124
|
+
"design_tokens": {
|
|
125
|
+
"--primary-color": "#1677ff",
|
|
126
|
+
"--bg-color": "#f5f5f5",
|
|
127
|
+
"--sidebar-width": "200px",
|
|
128
|
+
"--table-row-height": "48px"
|
|
129
|
+
},
|
|
130
|
+
"layout": {
|
|
131
|
+
"description": "左侧侧边栏 + 右侧内容区;一级菜单点击展开二级手风琴",
|
|
132
|
+
"sidebar": "width: 200px, collapsible, accordion mode",
|
|
133
|
+
"content": "padding: 16px, background: #f5f5f5"
|
|
134
|
+
},
|
|
135
|
+
"components": [
|
|
136
|
+
{"name": "侧边栏菜单", "spec": "三级折叠,一级固定,二级手风琴展开"},
|
|
137
|
+
{"name": "数据表格", "spec": "VxeGrid 风格,行高 48px,斑马纹"}
|
|
138
|
+
],
|
|
139
|
+
"notes": "设计师强调:侧边栏必须有图标,不能用纯文字",
|
|
140
|
+
"icons": [
|
|
141
|
+
{"name": "返回箭头", "svg_url": "https://lanhu-oss-.../xxx.svg", "size": "7x14", "usage": "顶部返回按钮"},
|
|
142
|
+
{"name": "提交图标", "svg_url": "https://lanhu-oss-.../yyy.svg", "size": "20x20", "usage": "提交按钮"}
|
|
143
|
+
],
|
|
144
|
+
"lanhu_source": {
|
|
145
|
+
"url": "https://lanhuapp.com/web/#/item/project/stage?pid=...",
|
|
146
|
+
"image_names": ["问题反馈-详情"],
|
|
147
|
+
"slice_count": 12,
|
|
148
|
+
"imported_at": "2026-06-18"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
> ⚠️ **`requirement` 字段是落地关键**:fill_prototype.py 靠它匹配关键词
|
|
154
|
+
> (`load_design_spec` 扫描 `data/style/*-design-spec.json`,`requirement` 包含查询词就命中)。
|
|
155
|
+
> 所以 `requirement` 必须跟未来 `/wl-design 预览` 的关键词一致(如"问题反馈""营业外合同")。
|
|
156
|
+
> 蓝湖来源时填 `source: "蓝湖直读 (设计师: XX)"`,截图口述填 `source: "Figma (设计师: XX)"`,
|
|
157
|
+
> 下游 fill_prototype 不管来源只认值。
|
|
158
|
+
> **`lanhu_source` 可选**:仅蓝湖来源时填,记录链接/图名/切图数,可追溯设计稿出处。
|
|
159
|
+
|
|
160
|
+
## Step 3: 存储到知识图谱
|
|
161
|
+
|
|
162
|
+
- 存到 `data/style/{需求名}-{平台}-design-spec.json`(平台 = web/app,避免同功能多端冲突)
|
|
163
|
+
- 例:`待办-web-design-spec.json`、`待办-app-design-spec.json`
|
|
164
|
+
- 同需求同平台重新录入 → 覆盖(更新);不同平台 → 各自独立文件
|
|
165
|
+
- **优先级声明**:这份 spec 的优先级 > 代码风格 > PDF 规范
|
|
166
|
+
(因为它是最新、最明确的设计决策)
|
|
167
|
+
- **`requirement` 字段填法**(解决"设计师不知道 PM 搜什么词"):
|
|
168
|
+
用**功能名 + 同义词**,别只填图名。如图名"设置-我的待办",requirement 填 `"待办 我的待办 设置待办"`
|
|
169
|
+
(空格分隔多个可能的关键词),这样 PM 搜"待办"或"我的待办"都能命中。
|
|
170
|
+
|
|
171
|
+
> 🎯 **落地链路(已验证通)**:spec.json 落盘后,下次 `/wl-design 预览 <同关键词>` 时,
|
|
172
|
+
> `fill_prototype.py` 的 `load_design_spec()` 会自动命中这份 spec(靠 `requirement` 字段匹配),
|
|
173
|
+
> 把 `design_tokens` **原样注入**原型 HTML 的 `:root` CSS(最高优先级,覆盖模板默认色)。
|
|
174
|
+
> 即:蓝湖读到的 `rgba(255,115,10,1)` 会真实出现在原型里,不是 AI 看一眼就忘。
|
|
175
|
+
> 验证方法:看输出原型 `:root` 里有没有 `/* design-import spec tokens (优先级最高) */` 注释及下面的值。
|
|
176
|
+
|
|
177
|
+
## Step 3.5: 录入埋点
|
|
178
|
+
|
|
179
|
+
spec.json 落盘后埋点,供 /wl-status 统计设计录入活跃度:
|
|
180
|
+
```bash
|
|
181
|
+
python "$R/.qoder/scripts/report/learn.py" record design_import "{\"requirement\": \"<需求名>\", \"platform\": \"<web|app>\", \"source\": \"<蓝湖|截图|导出>\"}"
|
|
182
|
+
```
|
|
183
|
+
> 失败静默忽略。
|
|
184
|
+
|
|
185
|
+
## Step 4: 确认与通知
|
|
186
|
+
输出给设计师:
|
|
187
|
+
```
|
|
188
|
+
✅ 设计规范已录入: data/style/{需求名}-design-spec.json
|
|
189
|
+
- 平台: Web 管理端
|
|
190
|
+
- 来源: 蓝湖直读 (设计师: XX) ← 或 截图口述
|
|
191
|
+
- 主色: rgba(255,115,10,1)
|
|
192
|
+
- 布局: 左侧边栏 200px + 手风琴二级菜单
|
|
193
|
+
- 组件: 侧边栏菜单、数据表格
|
|
194
|
+
|
|
195
|
+
✅ 已自动接入原型链路:下次 PM/任何人用同一关键词出原型时,
|
|
196
|
+
fill_prototype.py 会自动发现并优先用这份 spec(优先级高于代码风格),
|
|
197
|
+
主色/侧边栏宽度/布局全部按你的设计来(design_tokens 注入原型 :root)。
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
设计师可以随时说"录入设计稿"更新它。
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## 铁律
|
|
204
|
+
|
|
205
|
+
- **有蓝湖 MCP 时优先用它直读**:设计师发蓝湖链接,AI 调 `mcp__lanhu__*` 提取精确参数,
|
|
206
|
+
不要让设计师截图口述(截图口述是蓝湖不可用时的降级方案)
|
|
207
|
+
- **绝不编造 token**:设计师没说的值,留空或标"待确认",不要自己猜
|
|
208
|
+
- **图标必须来自真源**:即使设计师用了 emoji 示意,录入时也要替换成系统真源
|
|
209
|
+
(Web: data/index/ref-icon.json 的 Ant Design SVG)
|
|
210
|
+
- **spec 一旦录入,同需求 prototype 必须锚定它**:AI 出原型前先查 data/style/ 有没有 spec
|
|
211
|
+
|
|
212
|
+
## 🆕 录入前可参考知识图谱新数据
|
|
213
|
+
|
|
214
|
+
设计师录入 spec 前,可以先问 AI 系统现状,让 spec 更贴合系统:
|
|
215
|
+
|
|
216
|
+
- **"这个功能模块现在有哪些页面?"** → AI 调 `mcp__qoder-knowledge-graph__feature_overview(feature='资产管理')`
|
|
217
|
+
返回该模块所有页面 + API + 按钮,设计师知道改哪些、加哪些
|
|
218
|
+
- **"这个模块的业务流程是什么?"** → AI 调 `mcp__qoder-knowledge-graph__get_workflow(module='资产')`
|
|
219
|
+
返回操作链(查询→新增→审批→...),spec 里的交互流程跟系统一致
|
|
220
|
+
- **"系统里这个模块的按钮都叫什么?"** → 看 DESIGN.md 的 "Real Button Texts" 段
|
|
221
|
+
或 entity-registry.json,spec 里的按钮文案跟系统统一
|
|
222
|
+
- **"这个模块用的是什么布局模式?"** → 看 DESIGN.md 的 layout_fingerprint
|
|
223
|
+
spec 里的侧边栏宽度/布局模式跟系统一致(如 160px / mixed-nav)
|
|
224
|
+
|
|
225
|
+
> 这些数据让设计师的 spec 不是"凭空设计",而是"基于系统现状的增量改进"——
|
|
226
|
+
> 录入的 spec 天然就跟系统风格一致,AI 出原型时不会打架。
|