@hupan56/wlkj 3.1.20 → 3.1.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hupan56/wlkj",
3
- "version": "3.1.20",
3
+ "version": "3.1.22",
4
4
  "description": "AI Product R&D Workflow - PRD/Prototype/Search/Task/Report",
5
5
  "bin": {
6
6
  "wlkj": "bin/cli.js"
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # Design Import Skill(设计师专用)
17
18
 
@@ -29,14 +30,14 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
29
30
  本 skill 用到的知识图谱 MCP 工具(`MCP 工具 (` / `MCP 工具 (`)**自动路由(有 MCP 走 MCP,无 MCP 走 CLI)**。
30
31
 
31
32
  - **QoderWork**:直接调 MCP 工具(更快更准);Step 3 存储到知识图谱也走 MCP。
32
- - **Qoder IDE/Quest/CLI(无 MCP)**:用 `python "$R/.qoder/scripts/orchestration/wlkj.py" search` 降级查样式;存储到知识图谱步骤跳过(spec.json 照常生成,本地可用)。
33
+ - **Qoder IDE/Quest/CLI(无 MCP)**:用 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" search` 降级查样式;存储到知识图谱步骤跳过(spec.json 照常生成,本地可用)。
33
34
 
34
35
  ## ⚙️ 自取上下文(QoderWork 无 hook 注入,必须自读)
35
36
 
36
- - **当前身份**:当前设计师名(产出归属)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
37
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
37
+ - **当前身份**:当前设计师名(产出归属)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
38
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
38
39
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
39
- - **活动任务**:若存在,spec 命名带上任务关键词。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
40
+ - **活动任务**:若存在,spec 命名带上任务关键词。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
40
41
  - 平台必须明确(Web/APP/Both);如未指定,先问
41
42
 
42
43
  **已录入清单**(设计师问"我录过哪些"时):
@@ -106,7 +107,7 @@ ls "$R/data/style/"*-design-spec.json 2>/dev/null # 列所有 spec
106
107
  > 蓝湖 MCP 是 STDIO 模式:开 QoderWork 自动起、关自动停,**无需手动 start**。
107
108
  > cookie 按角色隔离在 `workspace/members/{当前用户}/.secrets/lanhu.env`(不进 git)——
108
109
  > wrapper(lanhu_stdio_wrapper.py)读当前 `.developer` 角色的 cookie 拉起服务,UI 角色有改稿权限、PM/开发只读。
109
- > 没配的话跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" setup-lanhu`;换角色改 `.developer` + 配新角色 cookie 后重启 QoderWork。
110
+ > 没配的话跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" setup-lanhu`;换角色改 `.developer` + 配新角色 cookie 后重启 QoderWork。
110
111
 
111
112
  **方式 B:截图 + 口述**
112
113
  设计师发一张 Figma/Axure 截图,口述关键设计决策:
@@ -187,7 +188,7 @@ ls "$R/data/style/"*-design-spec.json 2>/dev/null # 列所有 spec
187
188
 
188
189
  spec.json 落盘后埋点,供 /wl-status 统计设计录入活跃度:
189
190
  ```bash
190
- python "$R/.qoder/scripts/orchestration/wlkj.py" learn record design_import "{\"requirement\": \"<需求名>\", \"platform\": \"<web|app>\", \"source\": \"<蓝湖|截图|导出>\"}"
191
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" learn record design_import "{\"requirement\": \"<需求名>\", \"platform\": \"<web|app>\", \"source\": \"<蓝湖|截图|导出>\"}"
191
192
  ```
192
193
  > 失败静默忽略。
193
194
 
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # Design Review Skill(设计师 + PM 都可用)
17
18
 
@@ -23,12 +24,12 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
23
24
  本 skill 用到的知识图谱 MCP 工具(`MCP 工具 (` / `MCP 工具 (`)**自动路由(有 MCP 走 MCP,无 MCP 走 CLI)**。
24
25
 
25
26
  - **QoderWork**:直接调 MCP 工具(更快更准)。
26
- - **Qoder IDE/Quest/CLI(无 MCP)**:用 `python "$R/.qoder/scripts/orchestration/wlkj.py" search` 降级(`--style table|form|modal` / `--field <名>` / `--components`);仅 MCP 有的能力(如 feature_overview/get_workflow)跳过或人工评估。
27
+ - **Qoder IDE/Quest/CLI(无 MCP)**:用 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" search` 降级(`--style table|form|modal` / `--field <名>` / `--components`);仅 MCP 有的能力(如 feature_overview/get_workflow)跳过或人工评估。
27
28
 
28
29
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
29
30
 
30
- - **当前身份**:当前评审人。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
31
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
31
+ - **当前身份**:当前评审人。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
32
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
32
33
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
33
34
  - 设计文件路径由用户指定,或扫 `workspace/members/{dev}/drafts/prototype-*.html`
34
35
  - 若 `data/style/{需求名}-design-spec.json` 存在,作为评审基准(优先级最高)
@@ -84,7 +85,7 @@ PM 说"评审设计稿",AI 检查设计师的 spec.json 或原型:
84
85
  评审输出报告后,**立即调用 learning 引擎记录本次评审**(让团队学习哪些设计问题最常见):
85
86
 
86
87
  ```bash
87
- python "$R/.qoder/scripts/orchestration/wlkj.py" learn record review_done "{\"target\":\"{被评审的原型或spec}\",\"result\":\"PASS或问题数\",\"issues\":[\"严重问题1\",\"建议1\"]}"
88
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" learn record review_done "{\"target\":\"{被评审的原型或spec}\",\"result\":\"PASS或问题数\",\"issues\":[\"严重问题1\",\"建议1\"]}"
88
89
  ```
89
90
 
90
91
  > 埋点失败不阻塞评审。数据进个人 journal,管理员聚合到 kg.duckdb 后,可统计"最常出现的设计问题",反哺 design-import 防再犯。
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # PRD Generator Skill
17
18
 
@@ -39,20 +40,20 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
39
40
 
40
41
  ## 自取上下文(Quest / QoderWork 无 hook,必须自读)
41
42
 
42
- - **当前身份**:当前开发者名。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
43
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
43
+ - **当前身份**:当前开发者名。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
44
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
44
45
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
45
- - **活动任务**:当前活动任务。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
46
+ - **活动任务**:当前活动任务。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
46
47
  - `data/index/.index-meta.json` — 知识图谱新鲜度
47
48
 
48
49
  ### 写 PRD 前:一次取全(prefetch 预测 + 批量预取)
49
50
 
50
51
  **写 PRD 第一件事:调 1 次 `prefetch`**(它会预测业务词 + 批量取多词上下文,合并去重):
51
52
  ```bash
52
- ROLE=$(python "$R/.qoder/scripts/orchestration/wlkj.py" role 2>/dev/null || echo pm)
53
- python "$R/.qoder/scripts/orchestration/wlkj.py" kg prefetch "<需求描述>" --platform <p>
53
+ ROLE=$($PY "$R/.qoder/scripts/orchestration/wlkj.py" role 2>/dev/null || echo pm)
54
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" kg prefetch "<需求描述>" --platform <p>
54
55
  ```
55
- 或直接:`python "$R/.qoder/scripts/orchestration/wlkj.py" prefetch "<需求描述>" --platform <p>`
56
+ 或直接:`$PY "$R/.qoder/scripts/orchestration/wlkj.py" prefetch "<需求描述>" --platform <p>`
56
57
 
57
58
  prefetch 一次返回 8 段(含历史PRD/数据库表/真实字段/API/Wiki),等于把多个业务词的查询合并。**prefetch 之后严禁再串行 search/find/grep**(这是轮次爆炸的根因——查一个词不命中就换词再查 6+ 次)。
58
59
 
@@ -142,10 +143,10 @@ prefetch 一次返回 8 段(含历史PRD/数据库表/真实字段/API/Wiki)
142
143
  ```bash
143
144
  # 门 1+2: 角色边界(当前角色能否产 prd?) + 契约校验(@contract 头是否合规?)
144
145
  # 软提示不阻塞, 越权/无契约头会提示但仍可发布
145
- python "$R/.qoder/scripts/foundation/identity/check_publish.py" prd <draft-prd.md>
146
+ $PY "$R/.qoder/scripts/foundation/identity/check_publish.py" prd <draft-prd.md>
146
147
 
147
148
  # 门 3: 质量分 (eval_prd 内部也会跑契约校验, 这里是质量评分)
148
- python "$R/.qoder/scripts/orchestration/wlkj.py" eval <draft-prd.md> <prototype.html>
149
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" eval <draft-prd.md> <prototype.html>
149
150
  ```
150
151
  - check_publish 越权提示 → 软提示(如 dev 产 prd 会提示"建议产品经理"),不阻塞
151
152
  - eval_prd < 80% 不准发布,按报告修到 PASS
@@ -187,7 +188,7 @@ context_pack 字段段返回"无直接相关字段"时,**字段锁不报错,
187
188
  ## 取上下文 — 一次取全(不要逐个搜)
188
189
 
189
190
  ```bash
190
- python "$R/.qoder/scripts/orchestration/wlkj.py" context <关键词> --platform <web|app>
191
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" context <关键词> --platform <web|app>
191
192
  ```
192
193
  返回 7 章节(代码+页面+字段+PRD+API+样式+Wiki)。**只读最相关 1-2 个 Vue 文件**。
193
194
 
@@ -210,7 +211,7 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" context <关键词> --platform
210
211
  ## 原型规则
211
212
 
212
213
  - 从模板开始(`.qoder/templates/prototype-{web|app}.html`),模板已有正确颜色与 mixed-nav 多级菜单骨架
213
- - 先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" fill-prototype <关键词> --platform <web|app>` 拿 80% 草稿;
214
+ - 先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" fill-prototype <关键词> --platform <web|app>` 拿 80% 草稿;
214
215
  它会按目标项目的 `layout_fingerprint` 自动填示例菜单骨架和真实字段,你只微调 20%
215
216
  - 颜色/布局指纹见 fill_prototype 输出的"设计 Token"段(布局模式/主色/侧边栏宽度)
216
217
  - **菜单层级**: 若需求描述了侧边栏/菜单结构(如"一级→二级,右侧三四级"),
@@ -225,7 +226,7 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" context <关键词> --platform
225
226
  PRD 写入 drafts 后,**顺手归档一份**到当前成员的按时间文件夹,方便人翻查"我那天做了啥":
226
227
 
227
228
  ```bash
228
- python "$R/.qoder/scripts/orchestration/wlkj.py" archive-prd <刚生成的PRD文件路径>
229
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" archive-prd <刚生成的PRD文件路径>
229
230
  ```
230
231
 
231
232
  > 归档产物:`workspace/members/{你的名字}/archive/{YYYY-MM-DD}/REQ-{编号}-{中文标题}.md`
@@ -9,16 +9,17 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # PRD Review Skill
17
18
 
18
19
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
19
20
 
20
- - **当前身份**:当前评审人。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
21
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
21
+ - **当前身份**:当前评审人。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
22
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
22
23
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
23
24
  - `data/index/.index-meta.json` — 图谱新鲜度(影响"现实锚定"能否校验)
24
25
  - 评审的 PRD 文件路径由用户指定;若用户没给路径,扫 `data/docs/prd/` 和
@@ -42,7 +43,7 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
42
43
 
43
44
  跑一次 EVA 门禁给出客观分数:
44
45
  ```bash
45
- python "$R/.qoder/scripts/orchestration/wlkj.py" eval <PRD路径> [原型HTML路径]
46
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" eval <PRD路径> [原型HTML路径]
46
47
  ```
47
48
  分数 ≥80% 才能发布。低于 80% 把 EVA 报告的问题合并进上面的清单。
48
49
 
@@ -50,6 +51,6 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" eval <PRD路径> [原型HTML路
50
51
 
51
52
  评审出结论(无论 PASS/打回)后埋点,供 /wl-status 统计评审活跃度:
52
53
  ```bash
53
- python "$R/.qoder/scripts/orchestration/wlkj.py" learn record review_done "{\"prd\": \"<PRD文件名>\", \"verdict\": \"<PASS|打回>\", \"score\": <EVA分数或空>}"
54
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" learn record review_done "{\"prd\": \"<PRD文件名>\", \"verdict\": \"<PASS|打回>\", \"score\": <EVA分数或空>}"
54
55
  ```
55
56
  > 失败静默忽略。
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # Prototype Generator
17
18
 
@@ -22,12 +23,12 @@ Generate production-ready HTML prototypes that match the project's actual UI sty
22
23
  本 skill 用到的知识图谱 MCP 工具(`MCP 工具 (` / `MCP 工具 (`)**自动路由(有 MCP 走 MCP,无 MCP 走 CLI)**。
23
24
 
24
25
  - **QoderWork**:直接调 MCP 工具(更快更准)。
25
- - **Qoder IDE/Quest/CLI(无 MCP)**:用 `python "$R/.qoder/scripts/orchestration/wlkj.py" search` 降级(`--style` / `--field <名>` / `--vben` / `--components`);仅 MCP 有的能力(如 fill_prototype/context_pack)跳过或人工补。
26
+ - **Qoder IDE/Quest/CLI(无 MCP)**:用 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" search` 降级(`--style` / `--field <名>` / `--vben` / `--components`);仅 MCP 有的能力(如 fill_prototype/context_pack)跳过或人工补。
26
27
 
27
28
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
28
29
 
29
- - **当前身份**:决定产出存到 `workspace/members/{dev}/drafts/`。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
30
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
30
+ - **当前身份**:决定产出存到 `workspace/members/{dev}/drafts/`。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
31
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
31
32
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
32
33
  - 若 `.qoder/.current-task` 存在,原型命名带上任务关键词
33
34
  - 平台(Web/APP/Both)必须明确;如未指定,先问用户(见 prd-generator Step 0)
@@ -94,7 +95,7 @@ cap.mcp.call("get_design_system", {"platform": "web"})
94
95
  ```
95
96
 
96
97
  **FALLBACK: Read file directly:**
97
- Read `data/design/DESIGN.md`. If missing, run `python "$R/.qoder/scripts/orchestration/wlkj.py" design-doc`.
98
+ Read `data/design/DESIGN.md`. If missing, run `$PY "$R/.qoder/scripts/orchestration/wlkj.py" design-doc`.
98
99
 
99
100
  Returns: layout fingerprint (sidebar 160px, mixed-nav), token set (primary HSL),
100
101
  page type patterns, form behavior modes, icon rules, component stats.
@@ -119,7 +120,7 @@ cap.mcp.call("fill_prototype", {"keyword": "营业外合同", "platform": "web"}
119
120
 
120
121
  **FALLBACK: Run script:**
121
122
  ```bash
122
- python "$R/.qoder/scripts/orchestration/wlkj.py" fill-prototype <关键词> --platform <web|app>
123
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" fill-prototype <关键词> --platform <web|app>
123
124
  ```
124
125
 
125
126
  Returns: 80% complete HTML draft (real columns/fields/layout injected) + data manifest.
@@ -173,9 +174,9 @@ cap.mcp.call("search_wiki", {"keyword": "资产"})
173
174
 
174
175
  **FALLBACK: Python scripts:**
175
176
  ```bash
176
- python "$R/.qoder/scripts/orchestration/wlkj.py" search --style <table|form|detail|modal|dashboard> --platform <web|app>
177
- python "$R/.qoder/scripts/orchestration/wlkj.py" search <keyword> --platform <web|app>
178
- python "$R/.qoder/scripts/orchestration/wlkj.py" search --field <field_name>
177
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" search --style <table|form|detail|modal|dashboard> --platform <web|app>
178
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" search <keyword> --platform <web|app>
179
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" search --field <field_name>
179
180
  ```
180
181
 
181
182
  Then read the TOP 2-3 most similar existing Vue files to extract:
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # Spec Coder
17
18
 
@@ -25,10 +26,10 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
25
26
 
26
27
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
27
28
 
28
- - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
29
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
29
+ - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
30
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
30
31
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
31
- - **活动任务**:当前任务(含任务相关的 Spec 路径)。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
32
+ - **活动任务**:当前任务(含任务相关的 Spec 路径)。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
32
33
  - Spec 文件位置:`workspace/specs/REQ-{ID}-*.spec.md` 或 `workspace/tasks/{task-id}/spec.md`
33
34
  - 目标代码库:`data/code/`(fywl-ics 后端 / fywl-ui 前端 / Carmg-H5 移动端)
34
35
 
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # Spec Generator
17
18
 
@@ -23,13 +24,13 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
23
24
 
24
25
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
25
26
 
26
- - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
27
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
27
+ - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
28
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
28
29
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
29
- - **活动任务**:当前任务(决定 spec 存到哪个 task 目录)。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
30
+ - **活动任务**:当前任务(决定 spec 存到哪个 task 目录)。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
30
31
  - 扫描 PRD 来源目录:`data/docs/prd/`(已发布)+ `workspace/members/{dev}/drafts/REQ-*.md`(草稿)
31
32
  找出还没有对应 Spec 的 PRD
32
- - 风格/字段参考:`python "$R/.qoder/scripts/orchestration/wlkj.py" search --field <字段名>` 查现有字段命名约定
33
+ - 风格/字段参考:`$PY "$R/.qoder/scripts/orchestration/wlkj.py" search --field <字段名>` 查现有字段命名约定
33
34
  - 团队 Java 约定(MyBatis Plus + RESTful + BigDecimal 金额)写在本 skill 的 Step 3
34
35
 
35
36
  ## Step 1: 定位 PRD
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # Test Generator
17
18
 
@@ -25,14 +26,14 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
25
26
 
26
27
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
27
28
 
28
- - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
29
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
29
+ - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
30
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
30
31
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
31
- - **活动任务**:当前任务。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
32
+ - **活动任务**:当前任务。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
32
33
  - Spec 文件:`workspace/specs/REQ-{ID}-*.spec.md` 或 `workspace/tasks/{task-id}/spec.md`
33
34
  - 已实现代码:用 search_index.py 定位
34
35
  ```bash
35
- python "$R/.qoder/scripts/orchestration/wlkj.py" search <类名或模块关键词>
36
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" search <类名或模块关键词>
36
37
  ```
37
38
 
38
39
  ## Step 1: 定位待测代码
@@ -50,7 +51,7 @@ ls data/code/ # 已实现代码库
50
51
  2. **Spec 文件**(推荐):测试用例映射来源
51
52
  3. **现有测试代码**(推荐):用 search_index.py 找同类 Test 类,照着写
52
53
  ```bash
53
- python "$R/.qoder/scripts/orchestration/wlkj.py" search Test
54
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" search Test
54
55
  ```
55
56
 
56
57
  ## Step 3: 生成测试
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-code — 按 Spec 实现代码(/wl-code 命令入口)
17
18
 
@@ -22,10 +23,10 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
22
23
 
23
24
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
24
25
 
25
- - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
26
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
26
+ - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
27
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
27
28
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
28
- - **活动任务**:当前活动任务(找对应的 spec)。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
29
+ - **活动任务**:当前活动任务(找对应的 spec)。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
29
30
  - 活动任务的 spec:`workspace/specs/` 或 `workspace/tasks/{id}/spec.md`
30
31
 
31
32
  ### ⚡ 取全一次到位(spec 里的模块名 → 1 次 context_pack 拿全)
@@ -41,7 +42,7 @@ cap.mcp.call("context_pack", {"keyword": "..."}) <模块关键词> --platform <w
41
42
  ### 改表/改 Entity 前必查(用知识图谱 MCP,防改崩)
42
43
 
43
44
  > ⚠️ 本段依赖知识图谱 MCP(`cap.mcp.call("search_code", ...)` / `cap.mcp.call("query_schema", ...)`),自动路由。
44
- > Qoder IDE/Quest/CLI 无 MCP 时:table_impact 无脚本等价,需人工评估改动波及面;真实字段可用 `python "$R/.qoder/scripts/orchestration/wlkj.py" search --field <表名>` 查代码侧字段(不含 DB 真实列类型)。
45
+ > Qoder IDE/Quest/CLI 无 MCP 时:table_impact 无脚本等价,需人工评估改动波及面;真实字段可用 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" search --field <表名>` 查代码侧字段(不含 DB 真实列类型)。
45
46
 
46
47
  1. **改表影响分析**:涉及改数据库表/Entity 时,先 `cap.mcp.call("table_impact", {"table": "表名"})`
47
48
  - 查这张表关联哪些 Entity + 影响哪些 Controller/接口。
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-commit — 代码提交 + 质量门禁 + 同步
17
18
 
@@ -21,11 +22,11 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
21
22
 
22
23
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
23
24
 
24
- - **当前身份**:当前开发者(提交作者)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
25
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
25
+ - **当前身份**:当前开发者(提交作者)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
26
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
26
27
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
27
28
  - 当前工作目录的 `git status` 和 `git diff --stat` 看改了什么
28
- - **活动任务**:若有活动任务,提交信息关联任务 ID。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
29
+ - **活动任务**:若有活动任务,提交信息关联任务 ID。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
29
30
 
30
31
  ## 执行流程
31
32
 
@@ -83,7 +84,7 @@ git push
83
84
 
84
85
  提交成功后埋点(写当前开发者的 journal,供 /wl-status 健康度统计):
85
86
  ```bash
86
- python "$R/.qoder/scripts/orchestration/wlkj.py" learn record commit_done "{\"files\": <改动文件数>, \"task\": \"<关联任务ID或空>\"}"
87
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" learn record commit_done "{\"files\": <改动文件数>, \"task\": \"<关联任务ID或空>\"}"
87
88
  ```
88
89
  > 失败静默忽略,绝不阻塞提交流程。
89
90
 
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-design — 设计工序入口(/wl-design 命令入口)
17
18
 
@@ -36,10 +37,10 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
36
37
 
37
38
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
38
39
 
39
- - **当前身份**:当前设计师名(产出归属)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
40
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
40
+ - **当前身份**:当前设计师名(产出归属)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
41
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
41
42
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
42
- - **活动任务**:若存在,spec/原型命名带上任务关键词。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
43
+ - **活动任务**:若存在,spec/原型命名带上任务关键词。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
43
44
  - 平台必须明确(Web/APP/Both);如未指定,先问
44
45
  - 风格真源:`data/style/*-design-spec.json`(优先)→ `data/code/` 源码 → `data/index/vben-style-reference.json`(Web)/ Vant(APP)
45
46
 
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-init — 开发者身份 + 环境体检
17
18
 
@@ -28,14 +29,14 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
28
29
 
29
30
  ### 无参数(仅体检)
30
31
  ```bash
31
- python "$R/.qoder/scripts/orchestration/wlkj.py" doctor
32
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" doctor
32
33
  ```
33
34
  输出 8 段体检报告,每行 `[OK]/[WARN]/[FIX]/[MISS]` 标注。
34
35
 
35
36
  ### 带名字(注册 + 自愈)
36
37
  ```bash
37
- python "$R/.qoder/scripts/orchestration/wlkj.py" doctor --fix <名字> [角色]
38
- # 例:python "$R/.qoder/scripts/orchestration/wlkj.py" doctor --fix 小王 pm
38
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" doctor --fix <名字> [角色]
39
+ # 例:$PY "$R/.qoder/scripts/orchestration/wlkj.py" doctor --fix 小王 pm
39
40
  ```
40
41
  做 3 件事:
41
42
  1. 写 `.qoder/.developer`(key=value 格式)
@@ -44,7 +45,7 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" doctor --fix <名字> [角色]
44
45
 
45
46
  ### 仅自愈(不换人)
46
47
  ```bash
47
- python "$R/.qoder/scripts/orchestration/wlkj.py" doctor --fix
48
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" doctor --fix
48
49
  ```
49
50
 
50
51
  ## 体检覆盖的 8 段
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-insight — 需求探索(7 站之前的「探索站」· 产品工位)
17
18
 
@@ -54,12 +55,12 @@ insight(探索/调研/规划)→ [用户确认转PRD] → prd(落地)→
54
55
 
55
56
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
56
57
 
57
- - **当前身份**:当前探索者(报告归属)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
58
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
58
+ - **当前身份**:当前探索者(报告归属)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
59
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
59
60
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
60
61
  - **现状锚点(必跑,只跑这一次)**:用 prefetch 一次取全,不要串行换词搜:
61
62
  ```bash
62
- python "$R/.qoder/scripts/orchestration/wlkj.py" kg prefetch "<需求描述原句>"
63
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" kg prefetch "<需求描述原句>"
63
64
  ```
64
65
  > **不传 `--platform` = 默认双平台一次返回**(platform: all)。探索阶段需求常未定平台,
65
66
  > 直接默认双平台拿全,**绝不 web 跑一次、app 再跑一次**(这是 insight 慢的 #2 元凶)。
@@ -76,7 +77,7 @@ insight(探索/调研/规划)→ [用户确认转PRD] → prd(落地)→
76
77
 
77
78
  ## 🔒 三道前置检查(任何动作前先做)
78
79
 
79
- 1. **身份检查**:跑 `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`,无输出/退出码1 = 未初始化 → 停下,提示先 `/wl-init`
80
+ 1. **身份检查**:跑 `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`,无输出/退出码1 = 未初始化 → 停下,提示先 `/wl-init`
80
81
  2. **现状锚点**:任何探索前先跑 **1 次** `kg.py prefetch "<需求句>"`(见上方自取上下文段)。**不锚定现状的探索 = 凭空臆想,禁止。禁止串行换词搜。**
81
82
  3. **报告归属**:报告必须写到 `workspace/members/{dev}/drafts/`,用 `.developer` 归属。
82
83
 
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-prd-full — 完整档 PRD + 原型(/wl-prd-full 命令入口)
17
18
 
@@ -89,10 +90,10 @@ Read 指定 insight 报告 → 把现状锚定 + 选中的机会/Gap 作为 PRD
89
90
 
90
91
  ## 完整流程(详细见 command 文件)
91
92
 
92
- 1. **并行取全上下文**:先读当前角色(`python "$R/.qoder/scripts/orchestration/wlkj.py" role` 输出 pm/design/dev/test/admin 之一),用 prefetch 一次取全(完整档需求含多业务实体,prefetch 多词预测比单词 context 更准):
93
+ 1. **并行取全上下文**:先读当前角色(`$PY "$R/.qoder/scripts/orchestration/wlkj.py" role` 输出 pm/design/dev/test/admin 之一),用 prefetch 一次取全(完整档需求含多业务实体,prefetch 多词预测比单词 context 更准):
93
94
  ```bash
94
- ROLE=$(python "$R/.qoder/scripts/orchestration/wlkj.py" role 2>/dev/null || echo pm)
95
- python "$R/.qoder/scripts/orchestration/wlkj.py" kg prefetch "<需求描述原句>" --platform <p>
95
+ ROLE=$($PY "$R/.qoder/scripts/orchestration/wlkj.py" role 2>/dev/null || echo pm)
96
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" kg prefetch "<需求描述原句>" --platform <p>
96
97
  ```
97
98
  > prefetch 把需求句拆成多个业务词批量搜、一次合并(例"考勤导入校验"→考勤/导入两词全搜)。
98
99
  > 拿到后**按 $ROLE 视角看重点**:dev 看代码段、design 看页面+风格段、pm 看字段+历史PRD段。prefetch 之后不要再串行 search。
@@ -103,7 +104,7 @@ Read 指定 insight 报告 → 把现状锚定 + 选中的机会/Gap 作为 PRD
103
104
  - **原型按 Step 0.5 决策**:用户选"画"→ 走 prototype-generator(必须先 fill_prototype);
104
105
  用户选"不画"→ 跳过,PRD 第 11 章写 `无` + contract 头标 `prototype: none`
105
106
  - 3 道质量锁:背景锁/字段锁/闭环锁 → eval_prd(**不要加 `2>/dev/null`,stderr 阻断原因要看**)→ 不过自动修
106
- - eval 命令:`python "$R/.qoder/scripts/orchestration/wlkj.py" eval <prd.md> [原型.html]`
107
+ - eval 命令:`$PY "$R/.qoder/scripts/orchestration/wlkj.py" eval <prd.md> [原型.html]`
107
108
  (wlkj.py eval 内部映射 validation/metrics/eval_prd.py,路径不会漂移)
108
109
  4. **发布 + 归档 + 同步**(3 合 1):collect_prds → team_sync push → archive_prd
109
110
 
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-prd-quick — 小改动极速出 Mini-PRD(/wl-prd-quick 命令入口)
17
18
 
@@ -40,7 +41,7 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
40
41
 
41
42
  1. **先 prefetch(预测 + 批量预取,禁止串行 search)**:
42
43
  ```bash
43
- python "$R/.qoder/scripts/orchestration/wlkj.py" prefetch "<需求描述>" --platform <p>
44
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" prefetch "<需求描述>" --platform <p>
44
45
  ```
45
46
  prefetch 一次返回代码/字段/API/Wiki/历史PRD 的合并结果。**之后不要再用 search/find/grep 逐个查词**——那会变成 6+ 次串行往返,是轮次爆炸的根因。prefetch 不够时才补调一次。
46
47
  2. 一次 Write:Mini-PRD(prd-quick-template.md,6 章)+ 微型原型(只画 diff)
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-prd-review — 评审 PRD 质量(/wl-prd-review 命令入口)
17
18
 
@@ -24,7 +25,7 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
24
25
 
25
26
  拿到一份 PRD,检查它够不够格发布/交付下游:
26
27
  1. **7 项 checklist**:用户故事清晰 / 验收可测 / 优先级已标 / 模块已识别 / 非功能已列 / 边界已考虑 / 依赖已识别
27
- 2. **EVA 客观评分**:`python "$R/.qoder/scripts/orchestration/wlkj.py" eval <PRD> [原型]`,≥80% 才 PASS
28
+ 2. **EVA 客观评分**:`$PY "$R/.qoder/scripts/orchestration/wlkj.py" eval <PRD> [原型]`,≥80% 才 PASS
28
29
  3. **合并报告**:PASS → 可发布;不 PASS → 修复清单
29
30
 
30
31
  ## 定位要评审的 PRD
@@ -39,7 +40,7 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
39
40
  这是「可用性指标 F2 转化漏斗」评审级数据的唯一来源,不埋则该级永远为 0:
40
41
 
41
42
  ```bash
42
- python "$R/.qoder/scripts/orchestration/wlkj.py" learn record review_done "{\"prd\": \"<被评审PRD文件名>\", \"verdict\": \"PASS\"}"
43
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" learn record review_done "{\"prd\": \"<被评审PRD文件名>\", \"verdict\": \"PASS\"}"
43
44
  ```
44
45
  - `verdict`:评审结论,`PASS` 或 `FAIL`
45
46
  - 埋点失败不阻塞评审(包在 try 里无所谓),但能埋一定要埋。
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-report — 日报 / 周报(按开发者隔离)
17
18
 
@@ -22,9 +23,9 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
22
23
  ### ⚡ Fast Path:一次拿全(必须先跑,禁止逐个 cat/ls/git log)
23
24
 
24
25
  ```bash
25
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
26
- python "$R/.qoder/scripts/orchestration/wlkj.py" report-snapshot "$R" # 日报
27
- python "$R/.qoder/scripts/orchestration/wlkj.py" report-snapshot "$R" --days 7 # 周报
26
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
27
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" report-snapshot "$R" # 日报
28
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" report-snapshot "$R" --days 7 # 周报
28
29
  ```
29
30
 
30
31
  这一个命令**一次返回全部所需数据**(JSON,全部已按当前开发者过滤):
@@ -120,8 +121,8 @@ cap.mcp.call("sync", {"direction": "push"})
120
121
  ### 方式 B: webhook(任何环境,脚本化)
121
122
  如果没有连接器,用引擎自带的 webhook 推送:
122
123
  ```bash
123
- python "$R/.qoder/scripts/orchestration/wlkj.py" report daily --push-feishu
124
- python "$R/.qoder/scripts/orchestration/wlkj.py" report weekly --push-feishu
124
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" report daily --push-feishu
125
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" report weekly --push-feishu
125
126
  ```
126
127
  这会通过 config.yaml 里配的飞书 bot webhook 发卡片通知。
127
128
  两种方式不冲突,连接器更富交互,webhook 更可靠无依赖。
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-spec — 生成开发 Spec(/wl-spec 命令入口)
17
18
 
@@ -22,13 +23,13 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
22
23
 
23
24
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
24
25
 
25
- - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
26
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
26
+ - **当前身份**:当前开发者。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
27
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
27
28
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
28
- - **活动任务**:当前任务(决定 spec 存哪个 task 目录)。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
29
+ - **活动任务**:当前任务(决定 spec 存哪个 task 目录)。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
29
30
  - 扫描 PRD 来源:`data/docs/prd/`(已发布)+
30
31
  `workspace/members/{dev}/drafts/REQ-*.md`(草稿),找出还没 Spec 的 PRD
31
- - 字段命名约定:`python "$R/.qoder/scripts/orchestration/wlkj.py" search --field <字段名>`
32
+ - 字段命名约定:`$PY "$R/.qoder/scripts/orchestration/wlkj.py" search --field <字段名>`
32
33
  - 团队 Java 约定(MyBatis Plus + RESTful + BigDecimal 金额)见
33
34
  `.qoder/skills/spec-generator/SKILL.md` 的 Step 3
34
35
 
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-status — 项目状态总览
17
18
 
@@ -22,8 +23,8 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
22
23
  ### ⚡ Fast Path:一次拿全(必须先跑,禁止逐个 cat/ls)
23
24
 
24
25
  ```bash
25
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
26
- python "$R/.qoder/scripts/orchestration/wlkj.py" status-snapshot "$R"
26
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
27
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" status-snapshot "$R"
27
28
  ```
28
29
 
29
30
  这一个命令**一次返回全部所需数据**(JSON):开发者、图谱新鲜度、EVA 历史、
@@ -103,7 +104,7 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" status-snapshot "$R"
103
104
  健康度展示后,**追加一个可用性看板**(让"工作流用没用起来"可视化):
104
105
 
105
106
  ```bash
106
- python "$R/.qoder/scripts/orchestration/wlkj.py" usability --html
107
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" usability --html
107
108
  ```
108
109
 
109
110
  - **QoderWork**:脚本自动调 `qoder_show_widget` 把交互看板(仪表盘 + 绿黄红指标条)**嵌入对话流**。
@@ -9,9 +9,10 @@ trigger: "user invokes /wl-* command explicitly"
9
9
 
10
10
  **后续脚本里的 `$R` 代表仓库根**,先确定它(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
11
11
  ```bash
12
- R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
12
+ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
13
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
13
14
  ```
14
- > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
+ > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
15
16
 
16
17
  # wl-task — 任务管理(7 站之「任务」站 · 产品工位)
17
18
 
@@ -118,16 +119,16 @@ AI: ✅ 需求#761 已关联 build#22(本周) + #16(未来)
118
119
 
119
120
  ## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
120
121
 
121
- - **当前身份**:当前开发者(assignee 默认值)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
122
- `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
122
+ - **当前身份**:当前开发者(assignee 默认值)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
123
+ `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
123
124
  ⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
124
- - **活动任务**:当前活动任务("开始做""完成了"默认对它操作)。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
125
+ - **活动任务**:当前活动任务("开始做""完成了"默认对它操作)。读法 `$PY "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
125
126
  - 列出已有任务:`cap.mcp.call("list_tasks", {})`
126
127
  - 衔接 PRD:扫 `workspace/members/{dev}/drafts/REQ-*.md` + `data/docs/prd/REQ-*.md`
127
128
 
128
129
  ## 🔒 三道前置检查(任何动作前先做,保证健壮)
129
130
 
130
- 1. **身份检查**:跑 `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`,无输出/退出码1 = 未初始化 → 停下,提示先 `/wl-init`(否则 create 会把 assignee 写空)。
131
+ 1. **身份检查**:跑 `$PY "$R/.qoder/scripts/foundation/core/paths.py" whoami`,无输出/退出码1 = 未初始化 → 停下,提示先 `/wl-init`(否则 create 会把 assignee 写空)。
131
132
  2. **空数据兜底**:tasks 目录不存在/空 → 读操作友好提示"还没有任务",不报错;create 直接建。
132
133
  3. **脚本退出码**:`task.py` 返回非 0 → 原样读 stderr 告诉用户。`4`=权限不足(零信任 ACL),`1`=任务不存在/JSON 缺失。**绝不绕过 ACL。**
133
134
 
@@ -46,9 +46,9 @@ trigger: "user invokes /wl-* command explicitly"
46
46
  **③ 用例 JSON 必须用 `--cases-file` 传文件,禁止内联 `--cases`。**
47
47
  ```bash
48
48
  # ✅ 对: 写文件再传路径(不截断)
49
- python "$R/.qoder/scripts/orchestration/wlkj.py" test quick --cases-file <文件路径> --env test --platform web
49
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test quick --cases-file <文件路径> --env test --platform web
50
50
  # ❌ 错: 内联(长JSON截断, 多条用例必丢)
51
- python "$R/.qoder/scripts/orchestration/wlkj.py" test quick --cases '[{"case_id"...(超长)...}]'
51
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test quick --cases '[{"case_id"...(超长)...}]'
52
52
  ```
53
53
 
54
54
  **④ 无锚点时必须先 snapshot 拿真实 anchor 再填,禁止预猜 CSS selector。**
@@ -67,9 +67,9 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" test quick --cases '[{"case_id"
67
67
  **⑥ recall 的 `--url` 必须用相对路径(无前导斜杠),避开 Git-bash/MSYS 路径转换坑。**
68
68
  ```bash
69
69
  # ✅ 对: 相对路径 (MSYS 不转换)
70
- python "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url auth/login
70
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url auth/login
71
71
  # ❌ 错: 前导斜杠会被 Windows Git-bash 转成 /D:/.../Git/auth/login
72
- python "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url /auth/login
72
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url /auth/login
73
73
  ```
74
74
  (脚本已加 normalize 兜底能修这个,但别依赖兜底——直接写相对路径最干净。)
75
75
 
@@ -95,11 +95,12 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url /auth/login
95
95
  >
96
96
  > **先确定仓库根 R**(QoderWork 桌面端工作目录不是仓库根,相对路径会失效):
97
97
  > ```bash
98
- > R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
98
+ > R=$(python ~/.qoderwork/repo_root.py 2>/dev/null || python3 ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
99
+ PY=$(python --version >/dev/null 2>&1 && echo python || echo python3)
99
100
  > ```
100
101
  > `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。
101
- > **后续脚本统一用 `python "$R/.qoder/scripts/orchestration/wlkj.py" <命令>`,不要再搜!**
102
- > 如果 `repo_root.py` 报错找不到,先在仓库里跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
102
+ > **后续脚本统一用 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" <命令>`,不要再搜!**
103
+ > 如果 `repo_root.py` 报错找不到,先在仓库里跑 `$PY "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
103
104
 
104
105
  - `<R>/.qoder/.developer` — 当前开发者
105
106
  - `<R>/.qoder/config.yaml` 的 `autotest:` 段 — 环境/域名
@@ -112,7 +113,7 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url /auth/login
112
113
 
113
114
  **唯一正确做法**——1 条命令查 MySQL sys_menu 真实路由:
114
115
  ```bash
115
- python "$R/.qoder/scripts/orchestration/wlkj.py" search --routes 保险
116
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" search --routes 保险
116
117
  # → 保险管理 -> /veh/vehicle/vehAffair/insurance
117
118
  ```
118
119
  - 数据来自 MySQL `sys_menu` 表(后台动态菜单,**唯一事实源**)
@@ -165,7 +166,7 @@ coverage_matrix()
165
166
 
166
167
  **Step 0:recall 查锚点**(用相对 URL,避开 MSYS 坑)
167
168
  ```bash
168
- python "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url auth/login
169
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url auth/login
169
170
  ```
170
171
  - **有锚点** → 生成用例时直接把 anchor 填进 step(确定性命中,快、零 LLM)
171
172
  - **无锚点(首次)** → **先 navigate + snapshot 拿真实锚点,再生成用例**(见 Step 0.6)
@@ -212,8 +213,8 @@ snapshot 返回形如:
212
213
 
213
214
  **🎯 知道页面名/URL 时,AI 先查按钮+接口画像(最精准,1 条命令拿到所有交互点):**
214
215
  ```bash
215
- python "$R/.qoder/scripts/orchestration/wlkj.py" test page --kw 保险 # 按业务名查
216
- python "$R/.qoder/scripts/orchestration/wlkj.py" test page --url /veh/insurance # 按URL查
216
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test page --kw 保险 # 按业务名查
217
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test page --url /veh/insurance # 按URL查
217
218
  ```
218
219
  (这是 AI 在 `/wl-test` 流程内部自动调用的工具,**用户只用 `/wl-test`,不碰此命令**。)
219
220
  输出每个按钮的 handler + 调用接口 + HTTP 方法 + 置信度,**直接对应到用例的 click→assert 断言点**。开发 `finish` 任务时也会自动生成 `test-handoff.md`,内容同此画像——交接场景直接读那份即可,不必重查。
@@ -245,7 +246,7 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" test page --url /veh/insurance
245
246
  # AI 先写文件:
246
247
  # 写 workspace/members/{dev}/drafts/_autotest-cases.json
247
248
  # 再调:
248
- python "$R/.qoder/scripts/orchestration/wlkj.py" test quick \
249
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test quick \
249
250
  --cases-file workspace/members/{dev}/drafts/_autotest-cases.json \
250
251
  --desc "<用户描述>" --platform <web|app>
251
252
  ```
@@ -326,7 +327,7 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" test quick \
326
327
 
327
328
  **执行方式**:把测试结果 + 测试中 `browser_snapshot` 看到的页面元素一起回传:
328
329
  ```bash
329
- python "$R/.qoder/scripts/orchestration/wlkj.py" test quick \
330
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test quick \
330
331
  --cases-file <之前的cases文件> \
331
332
  --record '{"Q-1":"pass","Q-2":"pass","Q-3":"pass"}' \
332
333
  --page-json '{"url":"/veh/vehicle/vehAffair/insurance","elements":[{"role":"textbox","name":"车牌号"},{"role":"button","name":"搜索"},{"role":"button","name":"新增"}]}'
@@ -348,10 +349,10 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" test quick \
348
349
 
349
350
  ```bash
350
351
  cap.mcp.call("list_tasks", {}) # 确认任务存在
351
- python "$R/.qoder/scripts/orchestration/wlkj.py" test generate <task> # 生成骨架到 autotest-cases.jsonl
352
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test generate <task> # 生成骨架到 autotest-cases.jsonl
352
353
  # AI 读任务 PRD「验收标准」补全 steps/expected (真实数据用 {{ask:}}, 不搜源码)
353
- python "$R/.qoder/scripts/orchestration/wlkj.py" test run <task> # 注入+出执行计划
354
- python "$R/.qoder/scripts/orchestration/wlkj.py" test run <task> --record '{"..":"pass"}' # 回收结果
354
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test run <task> # 注入+出执行计划
355
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test run <task> --record '{"..":"pass"}' # 回收结果
355
356
  ```
356
357
 
357
358
  **回归测试增强(图谱 MCP)**:测接口改动时,用 `get_impact` 查影响范围,自动覆盖受影响页面:
@@ -388,10 +389,10 @@ JUnit 测试(Mock + MockMvc,Given-When-Then,`@DisplayName`,AssertJ)→
388
389
 
389
390
  ```bash
390
391
  # 从任务 PRD 的验收标准章节抿断言
391
- python "$R/.qoder/scripts/orchestration/wlkj.py" test assertion-gen --task <任务名> --page 保险
392
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test assertion-gen --task <任务名> --page 保险
392
393
 
393
394
  # 临时用 GWT 文本兜底(PRD 没写验收标准时)
394
- python "$R/.qoder/scripts/orchestration/wlkj.py" test assertion-gen \
395
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test assertion-gen \
395
396
  --gwt "Given 已登录保险页 When 点击延期提交 Then 接口 /api/insurance/delay 返回 code=200 且 状态列显示审批中" \
396
397
  --page 保险
397
398
  ```
@@ -416,9 +417,9 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" test assertion-gen \
416
417
  域名才放 config(全团队一致)。账号密码每人不同 → 个人文档。
417
418
  - **个人文档**:`workspace/members/{你的名字}/autotest-data.yaml`(gitignored,永不 push)
418
419
  ```bash
419
- python "$R/.qoder/scripts/orchestration/wlkj.py" test init-data # 生成模板
420
- python "$R/.qoder/scripts/orchestration/wlkj.py" test set-data 登录账号 test --env test # 填(按环境/平台分块)
421
- python "$R/.qoder/scripts/orchestration/wlkj.py" test list-data --env test # 查看(密码脱敏)
420
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test init-data # 生成模板
421
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test set-data 登录账号 test --env test # 填(按环境/平台分块)
422
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test list-data --env test # 查看(密码脱敏)
422
423
  ```
423
424
  run/quick 时按 env/platform 自动取最精确的值;`--data` 可临时覆盖。
424
425
 
@@ -428,7 +429,7 @@ run/quick 时按 env/platform 自动取最精确的值;`--data` 可临时覆
428
429
 
429
430
  **Step A:查登录态**
430
431
  ```bash
431
- python "$R/.qoder/scripts/orchestration/wlkj.py" test login-state show
432
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test login-state show
432
433
  ```
433
434
 
434
435
  **Step B:按登录态决定行为**
@@ -449,8 +450,8 @@ python "$R/.qoder/scripts/orchestration/wlkj.py" test login-state show
449
450
 
450
451
  ```bash
451
452
  # 手动操作(一般不用,AI 会自动):
452
- python "$R/.qoder/scripts/orchestration/wlkj.py" test login-state mark --env pre --platform web # 标记已登录
453
- python "$R/.qoder/scripts/orchestration/wlkj.py" test login-state clear --env pre # 清除(强制重登录)
453
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test login-state mark --env pre --platform web # 标记已登录
454
+ $PY "$R/.qoder/scripts/orchestration/wlkj.py" test login-state clear --env pre # 清除(强制重登录)
454
455
  ```
455
456
 
456
457
  ## 🧩 QoderWork 增强:浏览器自动执行(可选 · 无连接器则自动回退)