@hupan56/wlkj 3.0.0 → 3.1.2
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 +1435 -1373
- package/package.json +1 -1
- package/templates/qoder/commands/optional/wl-insight.md +6 -4
- package/templates/qoder/commands/optional/wl-report.md +20 -39
- package/templates/qoder/commands/optional/wl-status.md +4 -4
- package/templates/qoder/commands/wl-code.md +2 -2
- package/templates/qoder/commands/wl-design.md +5 -5
- package/templates/qoder/commands/wl-init.md +3 -3
- package/templates/qoder/commands/wl-prd.md +26 -13
- package/templates/qoder/commands/wl-req.md +3 -3
- package/templates/qoder/commands/wl-search.md +78 -47
- package/templates/qoder/commands/wl-task.md +343 -40
- package/templates/qoder/commands/wl-test.md +10 -10
- package/templates/qoder/config.yaml +35 -13
- package/templates/qoder/hooks/post-tool-use.py +181 -0
- package/templates/qoder/hooks/session-start.py +82 -1
- package/templates/qoder/hooks/stop-eval.py +207 -0
- package/templates/qoder/hooks/user-prompt-submit.py +139 -0
- package/templates/qoder/rules/wl-pipeline.md +70 -8
- package/templates/qoder/scripts/README.md +78 -115
- package/templates/qoder/scripts/capability/__init__.py +26 -0
- package/templates/qoder/scripts/capability/__main__.py +72 -0
- package/templates/qoder/scripts/capability/adapters/__init__.py +29 -0
- package/templates/qoder/scripts/capability/adapters/cli.py +316 -0
- package/templates/qoder/scripts/capability/adapters/mcp.py +334 -0
- package/templates/qoder/scripts/capability/adapters/qw.py +271 -0
- package/templates/qoder/scripts/capability/caps/__init__.py +27 -0
- package/templates/qoder/scripts/capability/caps/context.py +36 -0
- package/templates/qoder/scripts/capability/caps/cron.py +50 -0
- package/templates/qoder/scripts/capability/caps/identity.py +43 -0
- package/templates/qoder/scripts/capability/caps/memory.py +71 -0
- package/templates/qoder/scripts/capability/caps/notify.py +41 -0
- package/templates/qoder/scripts/capability/caps/present.py +48 -0
- package/templates/qoder/scripts/capability/caps/repo.py +31 -0
- package/templates/qoder/scripts/capability/caps/sandbox.py +43 -0
- package/templates/qoder/scripts/capability/chain.py +92 -0
- package/templates/qoder/scripts/capability/memory_chain.py +41 -0
- package/templates/qoder/scripts/capability/registry.py +246 -0
- package/templates/qoder/scripts/capability/registry_mcp.py +250 -0
- package/templates/qoder/scripts/capability/smoke_test.py +211 -0
- package/templates/qoder/scripts/capability/smoke_test_report.json +94 -0
- package/templates/qoder/scripts/{report → deployment/setup}/__init__.py +11 -11
- package/templates/qoder/scripts/{setup → deployment/setup}/carriers.py +33 -26
- package/templates/qoder/scripts/deployment/setup/carriers_verify.py +148 -0
- package/templates/qoder/scripts/{setup → deployment/setup}/init_doctor.py +40 -16
- package/templates/qoder/scripts/{setup → deployment/setup}/install_qoderwork.py +20 -12
- package/templates/qoder/scripts/{setup → deployment/setup}/platform_doctor.py +8 -2
- package/templates/qoder/scripts/{setup → deployment/setup}/repo_root.py +113 -112
- package/templates/qoder/scripts/{setup → deployment/setup}/setup.py +31 -11
- package/templates/qoder/scripts/{setup → deployment/setup}/setup_lanhu.py +13 -7
- package/templates/qoder/scripts/domain/__init__.py +0 -0
- package/templates/qoder/scripts/domain/design/__init__.py +0 -0
- package/templates/qoder/scripts/{report → domain/design}/fill_prototype.py +12 -6
- package/templates/qoder/scripts/{report → domain/design}/gen_design_doc.py +8 -2
- package/templates/qoder/scripts/{setup → domain/kg}/__init__.py +11 -11
- package/templates/qoder/scripts/domain/kg/build/__init__.py +0 -0
- package/templates/qoder/scripts/{kg → domain/kg/build}/build_entity_registry.py +7 -2
- package/templates/qoder/scripts/{kg → domain/kg/build}/build_relations.py +7 -2
- package/templates/qoder/scripts/{kg → domain/kg/build}/build_style_index.py +13 -7
- package/templates/qoder/scripts/{kg → domain/kg/build}/build_workflows.py +7 -2
- package/templates/qoder/scripts/{kg → domain/kg/build}/kg_build.py +76 -9
- package/templates/qoder/scripts/{kg → domain/kg/build}/kg_build_db.py +7 -2
- package/templates/qoder/scripts/{kg → domain/kg/build}/kg_incremental.py +11 -6
- package/templates/qoder/scripts/{report → domain/kg/build}/learn_aggregate.py +9 -4
- package/templates/qoder/scripts/domain/kg/extract/__init__.py +0 -0
- package/templates/qoder/scripts/{common → domain/kg/extract}/extract.py +430 -419
- package/templates/qoder/scripts/{common → domain/kg/extract}/test_extract.py +115 -115
- package/templates/qoder/scripts/{common → domain/kg/extract}/ts_extract.py +614 -536
- package/templates/qoder/scripts/domain/kg/graph/__init__.py +0 -0
- package/templates/qoder/scripts/{kg → domain/kg/graph}/kg_link_db.py +7 -2
- package/templates/qoder/scripts/domain/kg/graph/kg_semantic.py +683 -0
- package/templates/qoder/scripts/{kg → domain/kg}/kg.py +263 -30
- package/templates/qoder/scripts/{common → domain/kg}/kg_capabilities.py +182 -182
- package/templates/qoder/scripts/domain/kg/search/__init__.py +0 -0
- package/templates/qoder/scripts/{kg → domain/kg/search}/context_pack.py +30 -9
- package/templates/qoder/scripts/{kg → domain/kg/search}/enrich_prompt.py +10 -4
- package/templates/qoder/scripts/{kg → domain/kg/search}/prefetch.py +33 -8
- package/templates/qoder/scripts/{common → domain/kg/search}/search_engine.py +207 -205
- package/templates/qoder/scripts/{kg → domain/kg/search}/search_index.py +143 -77
- package/templates/qoder/scripts/domain/kg/server/__init__.py +0 -0
- package/templates/qoder/scripts/domain/kg/server/kgd.py +549 -0
- package/templates/qoder/scripts/domain/kg/server/perf_bench.py +197 -0
- package/templates/qoder/scripts/domain/kg/storage/__init__.py +0 -0
- package/templates/qoder/scripts/{kg → domain/kg/storage}/kg_duckdb.py +38 -14
- package/templates/qoder/scripts/domain/learning/__init__.py +0 -0
- package/templates/qoder/scripts/{report → domain/learning}/learn.py +8 -3
- package/templates/qoder/scripts/{mcp → domain/report}/__init__.py +11 -11
- package/templates/qoder/scripts/{report → domain/report}/add_session.py +9 -3
- package/templates/qoder/scripts/{report → domain/report}/export.py +10 -5
- package/templates/qoder/scripts/{report → domain/report}/report.py +9 -4
- package/templates/qoder/scripts/domain/report/report_snapshot.py +261 -0
- package/templates/qoder/scripts/{report → domain/report}/role.py +10 -4
- package/templates/qoder/scripts/{report → domain/report}/status.py +112 -9
- package/templates/qoder/scripts/domain/report/status_snapshot.py +191 -0
- package/templates/qoder/scripts/domain/requirement/__init__.py +0 -0
- package/templates/qoder/scripts/{report → domain/requirement}/archive_prd.py +8 -2
- package/templates/qoder/scripts/{report → domain/requirement}/req.py +228 -222
- package/templates/qoder/scripts/{kg → domain/task}/__init__.py +11 -11
- package/templates/qoder/scripts/{task → domain/task}/git_sync.py +40 -21
- package/templates/qoder/scripts/{task → domain/task}/syncgate.py +13 -8
- package/templates/qoder/scripts/{task → domain/task}/task.py +13 -5
- package/templates/qoder/scripts/{task → domain/task}/task_lifecycle.py +606 -596
- package/templates/qoder/scripts/{task → domain/task}/task_query.py +162 -161
- package/templates/qoder/scripts/{task → domain/task}/task_relations.py +425 -424
- package/templates/qoder/scripts/{task → domain/task}/team_sync.py +9 -4
- package/templates/qoder/scripts/domain/task/zentao_sync.py +370 -0
- package/templates/qoder/scripts/foundation/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation}/bootstrap.py +10 -10
- package/templates/qoder/scripts/foundation/core/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/core}/cmd_registry.py +1 -1
- package/templates/qoder/scripts/{common → foundation/core}/config.py +1 -1
- package/templates/qoder/scripts/{common → foundation/core}/paths.py +706 -586
- package/templates/qoder/scripts/foundation/data/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/data}/contract.py +2 -2
- package/templates/qoder/scripts/{common → foundation/data}/events.py +2 -2
- package/templates/qoder/scripts/{common → foundation/data}/result.py +1 -1
- package/templates/qoder/scripts/{common → foundation/data}/task_utils.py +427 -404
- package/templates/qoder/scripts/foundation/identity/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/identity}/check_publish.py +103 -98
- package/templates/qoder/scripts/{common → foundation/identity}/developer.py +239 -239
- package/templates/qoder/scripts/{common → foundation/identity}/guard.py +2 -2
- package/templates/qoder/scripts/{common → foundation/identity}/identity.py +14 -10
- package/templates/qoder/scripts/{common → foundation/identity}/roles.py +1 -1
- package/templates/qoder/scripts/foundation/integrations/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/integrations}/active_task.py +30 -15
- package/templates/qoder/scripts/{common → foundation/integrations}/feishu.py +2 -2
- package/templates/qoder/scripts/{common → foundation/integrations}/terms.py +3 -3
- package/templates/qoder/scripts/foundation/integrations/zentao_client.py +220 -0
- package/templates/qoder/scripts/foundation/io/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/io}/filelock.py +1 -1
- package/templates/qoder/scripts/{common → foundation/io}/reqid.py +1 -1
- package/templates/qoder/scripts/foundation/protocol/__init__.py +0 -0
- package/templates/qoder/scripts/foundation/protocol/duckdb_conn.py +39 -0
- package/templates/qoder/scripts/{common → foundation/protocol}/mcp_base.py +1 -1
- package/templates/qoder/scripts/foundation/utils/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/utils}/eval_api.py +12 -1
- package/templates/qoder/scripts/{common → foundation/utils}/pip_install.py +23 -6
- package/templates/qoder/scripts/{common → foundation/utils}/platform_guard.py +1 -1
- package/templates/qoder/scripts/orchestration/__init__.py +0 -0
- package/templates/qoder/scripts/orchestration/wlkj.py +185 -0
- package/templates/qoder/scripts/protocol/__init__.py +0 -0
- package/templates/qoder/scripts/protocol/browser/README.md +207 -0
- package/templates/qoder/scripts/protocol/browser/SKILL.md +265 -0
- package/templates/qoder/scripts/protocol/browser/config.env +9 -0
- package/templates/qoder/scripts/protocol/browser/references/cdp-api.md +110 -0
- package/templates/qoder/scripts/protocol/browser/references/migration-2.5.3.md +72 -0
- package/templates/qoder/scripts/protocol/browser/references/site-patterns/.gitkeep +0 -0
- package/templates/qoder/scripts/protocol/browser/scripts/browser-discovery.mjs +138 -0
- package/templates/qoder/scripts/protocol/browser/scripts/cdp-proxy.mjs +672 -0
- package/templates/qoder/scripts/protocol/browser/scripts/check-deps.mjs +206 -0
- package/templates/qoder/scripts/protocol/browser/scripts/find-url.mjs +253 -0
- package/templates/qoder/scripts/protocol/browser/scripts/match-site.mjs +46 -0
- package/templates/qoder/scripts/protocol/browser/templates/config.env.template +9 -0
- package/templates/qoder/scripts/protocol/mcp/__init__.py +11 -0
- package/templates/qoder/scripts/protocol/mcp/kg_mcp_server.py +478 -0
- package/templates/qoder/scripts/{mcp → protocol/mcp}/lanhu_stdio_wrapper.py +11 -5
- package/templates/qoder/scripts/{mcp → protocol/mcp}/mcp_doctor.py +47 -14
- package/templates/qoder/scripts/protocol/mcp/mcp_launcher.py +600 -0
- package/templates/qoder/scripts/{mcp → protocol/mcp}/mysql_mcp_server.py +181 -67
- package/templates/qoder/scripts/protocol/mcp/zentao_mcp_server.py +1920 -0
- package/templates/qoder/scripts/protocol/transports/__init__.py +56 -0
- package/templates/qoder/scripts/protocol/transports/base.py +87 -0
- package/templates/qoder/scripts/protocol/transports/cli.py +132 -0
- package/templates/qoder/scripts/protocol/transports/http.py +141 -0
- package/templates/qoder/scripts/protocol/transports/stdio.py +293 -0
- package/templates/qoder/scripts/run_weekly_update.bat +27 -18
- package/templates/qoder/scripts/run_weekly_update.sh +22 -13
- package/templates/qoder/scripts/validation/__init__.py +0 -0
- package/templates/qoder/scripts/validation/eval/__init__.py +0 -0
- package/templates/qoder/scripts/validation/eval/perf-report-2026-06-24.md +139 -0
- package/templates/qoder/scripts/validation/eval/qwork_harness.py +617 -0
- package/templates/qoder/scripts/validation/eval/report-commands.md +220 -0
- package/templates/qoder/scripts/validation/eval/transcript_timing.py +386 -0
- package/templates/qoder/scripts/validation/metrics/__init__.py +0 -0
- package/templates/qoder/scripts/{report → validation/metrics}/eval_prd.py +17 -10
- package/templates/qoder/scripts/validation/metrics/usability_score.py +750 -0
- package/templates/qoder/scripts/validation/test/__init__.py +11 -0
- package/templates/qoder/scripts/validation/test/assertion_gen.py +551 -0
- package/templates/qoder/scripts/{test → validation/test}/autotest.py +64 -4
- package/templates/qoder/scripts/{common → validation/test}/autotest_auth.py +1 -1
- package/templates/qoder/scripts/{test → validation/test}/autotest_batch.py +16 -3
- package/templates/qoder/scripts/{test → validation/test}/autotest_data.py +17 -12
- package/templates/qoder/scripts/validation/test/autotest_opencli.py +646 -0
- package/templates/qoder/scripts/{test → validation/test}/autotest_run.py +17 -3
- package/templates/qoder/scripts/validation/test/autotest_webaccess.py +571 -0
- package/templates/qoder/scripts/{test → validation/test}/benchmark.py +12 -6
- package/templates/qoder/scripts/{test → validation/test}/kg_auto_login.py +8 -2
- package/templates/qoder/scripts/{test → validation/test}/kg_test_runner.py +7 -2
- package/templates/qoder/scripts/{test → validation/test}/page_probe.py +8 -3
- package/templates/qoder/scripts/validation/test/smoke_all_commands.py +170 -0
- package/templates/qoder/settings.json +30 -0
- package/templates/qoder/skills/design-import/SKILL.md +22 -13
- package/templates/qoder/skills/design-review/SKILL.md +19 -10
- package/templates/qoder/skills/prd-generator/SKILL.md +22 -18
- package/templates/qoder/skills/prd-review/SKILL.md +6 -4
- package/templates/qoder/skills/prototype-generator/SKILL.md +63 -14
- package/templates/qoder/skills/spec-coder/SKILL.md +22 -13
- package/templates/qoder/skills/spec-generator/SKILL.md +22 -10
- package/templates/qoder/skills/test-generator/SKILL.md +7 -5
- package/templates/qoder/skills/wl-code/SKILL.md +23 -11
- package/templates/qoder/skills/wl-commit/SKILL.md +9 -8
- package/templates/qoder/skills/wl-design/SKILL.md +5 -3
- package/templates/qoder/skills/wl-init/SKILL.md +6 -6
- package/templates/qoder/skills/wl-insight/SKILL.md +23 -10
- package/templates/qoder/skills/wl-prd-full/SKILL.md +57 -6
- package/templates/qoder/skills/wl-prd-quick/SKILL.md +3 -3
- package/templates/qoder/skills/wl-prd-review/SKILL.md +16 -4
- package/templates/qoder/skills/wl-report/SKILL.md +25 -23
- package/templates/qoder/skills/wl-search/SKILL.md +149 -78
- package/templates/qoder/skills/wl-spec/SKILL.md +7 -5
- package/templates/qoder/skills/wl-status/SKILL.md +48 -16
- package/templates/qoder/skills/wl-task/SKILL.md +92 -10
- package/templates/qoder/skills/wl-test/SKILL.md +75 -29
- package/templates/qoder/templates/prd-full-template.md +7 -0
- package/templates/root/AGENTS.md +275 -236
- package/templates/root/requirements.txt +3 -0
- package/templates/root//344/275/277/347/224/250/350/257/264/346/230/216.md +3 -3
- package/templates/root//346/226/260/346/211/213/346/214/207/345/215/227.md +2 -2
- package/templates/.qoder/.runtime/ctx-cache-5660152f1d6dd819.md +0 -23
- package/templates/.qoder/.runtime/ctx-cache-afdce0dac06b25b0.md +0 -23
- package/templates/.qoder/.runtime/search-cache-eae7644e7b122f35.txt +0 -1
- package/templates/.qoder/learning/eval-history.jsonl +0 -28
- package/templates/data/index/wiki-index.json +0 -8
- package/templates/qoder/nul +0 -4
- package/templates/qoder/scripts/kg/extract.py +0 -398
- package/templates/qoder/scripts/kg/kg_semantic.py +0 -156
- package/templates/qoder/scripts/mcp/kg_mcp_server.py +0 -606
- package/templates/qoder/scripts/mcp/mcp_launcher.py +0 -442
- package/templates/qoder/scripts/mcp/zentao_mcp_server.py +0 -384
- package/templates/qoder/scripts/task/__init__.py +0 -11
- package/templates/qoder/scripts/test/__init__.py +0 -11
- package/templates/qoder/scripts/wlkj.py +0 -116
- /package/templates/qoder/scripts/{common → deployment}/__init__.py +0 -0
- /package/templates/qoder/scripts/{common → domain/kg/graph}/graph_traverse.py +0 -0
- /package/templates/qoder/scripts/{common → domain/kg/server}/repowiki.py +0 -0
- /package/templates/qoder/scripts/{common → foundation/io}/atomicio.py +0 -0
- /package/templates/qoder/scripts/{test → validation/test}/secure-ls.js +0 -0
|
@@ -11,7 +11,7 @@ trigger: "user invokes /wl-* command explicitly"
|
|
|
11
11
|
```bash
|
|
12
12
|
R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
13
13
|
```
|
|
14
|
-
> `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python
|
|
14
|
+
> `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
|
|
15
15
|
|
|
16
16
|
# wl-status — 项目状态总览
|
|
17
17
|
|
|
@@ -19,17 +19,33 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
|
19
19
|
|
|
20
20
|
## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
- `data/index/.index-meta.json` — 图谱新鲜度(健康度计算用)
|
|
24
|
-
- `.qoder/learning/eval-history.jsonl` — EVA 评估历史(健康度趋势用,可能不存在)
|
|
25
|
-
- `workspace/tasks/*/task.json` — 全部任务(current 维度用)
|
|
26
|
-
|
|
27
|
-
## 维度 1:current(当前迭代)
|
|
22
|
+
### ⚡ Fast Path:一次拿全(必须先跑,禁止逐个 cat/ls)
|
|
28
23
|
|
|
29
24
|
```bash
|
|
30
|
-
python
|
|
25
|
+
R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
26
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" status-snapshot "$R"
|
|
31
27
|
```
|
|
32
|
-
|
|
28
|
+
|
|
29
|
+
这一个命令**一次返回全部所需数据**(JSON):开发者、图谱新鲜度、EVA 历史、
|
|
30
|
+
任务列表、团队同步、配置、成员、学习记录。**拿到后直接算健康度,不要再 cat/ls 探查。**
|
|
31
|
+
|
|
32
|
+
> 性能:旧方式 5 轮迭代 + 10 次调用;聚合后 1 轮 + 1 次调用。
|
|
33
|
+
> 缺失字段为 null = 该数据源不存在(如 eval_history 没跑过 EVA),正常处理即可。
|
|
34
|
+
|
|
35
|
+
### 字段说明(聚合脚本返回的 JSON)
|
|
36
|
+
|
|
37
|
+
- `developer` — 当前开发者(.developer 内容)
|
|
38
|
+
- `index_meta` + `index_age_days` — 图谱元数据 + 距今天数(健康度·索引新鲜度)
|
|
39
|
+
- `eval_history` — EVA 最近 10 次评估(健康度·EVA 合格率;null=未跑过)
|
|
40
|
+
- `feedback_count` — 学习反馈条数(健康度·学习成长;null=无)
|
|
41
|
+
- `task_list` — 全部任务(current 维度)
|
|
42
|
+
- `team_sync` — ahead/behind/未同步数(健康度·团队同步)
|
|
43
|
+
- `tasks_dir` / `patterns` / `members` — 目录清单(null=不存在)
|
|
44
|
+
- `config_summary` — 项目配置摘要
|
|
45
|
+
|
|
46
|
+
## 维度 1:current(当前迭代)
|
|
47
|
+
|
|
48
|
+
直接用聚合脚本返回的 `task_list` 字段(**不要再调 task.py**):
|
|
33
49
|
- 当前活动任务(标 `*` 的那条)
|
|
34
50
|
- 进行中任务清单 + 各自进度
|
|
35
51
|
- 最近 5 个动作(建任务/finish/PRD 发布等,从 task.json 的 status 历史推)
|
|
@@ -52,21 +68,21 @@ python "$R/.qoder/scripts/task/task.py" list
|
|
|
52
68
|
| 索引新鲜度 | 20% | .index-meta.json 的 last_sync 距今天数 |
|
|
53
69
|
| 按时交付 | 20% | 近期 task finish 是否在计划期内 |
|
|
54
70
|
| 团队同步 | 15% | `team_sync.py status` 的 ahead/behind |
|
|
55
|
-
|
|
|
56
|
-
|
|
|
71
|
+
| **工作流采纳** | **10%** | **usability_score.py 的采纳分(U2/U3/U4/U6 达标率)** |
|
|
72
|
+
| 流水线流转 | 5% | task 在各阶段的停留时长 |
|
|
73
|
+
| 学习成长 | 5% | learning 记录条数 |
|
|
57
74
|
|
|
58
75
|
判定:≥4 健康 / 3–4 有风险 / <3 需关注。
|
|
76
|
+
> 7 维权重合计 = 1.00。**工作流采纳**是吸收宿主能力后新增的维度,回答"工作流用不用得起来"。
|
|
59
77
|
|
|
60
|
-
##
|
|
78
|
+
## 团队同步健康(用聚合数据)
|
|
61
79
|
|
|
62
|
-
|
|
63
|
-
python "$R/.qoder/scripts/task/team_sync.py" status
|
|
64
|
-
```
|
|
80
|
+
直接用聚合脚本返回的 `team_sync` 字段(**不要再调 team_sync.py**):
|
|
65
81
|
看 ahead/behind 是否对齐,未同步产出有几个。
|
|
66
82
|
|
|
67
83
|
## 🧩 QoderWork 增强:日历校准健康度(可选 · 无连接器则自动回退)
|
|
68
84
|
|
|
69
|
-
>
|
|
85
|
+
> 通过 capability 层自动路由(Settings → Connectors,授权 Microsoft 365 / macOS 日历,邮件可选)。
|
|
70
86
|
> **纯 Qoder IDE / CLI 没有连接器 → 本段不生效,健康度照常按上表纯本地数据计算,不受影响。**
|
|
71
87
|
> 探测方式:仅当运行环境提供了「日历」工具可直接读取时才用。
|
|
72
88
|
|
|
@@ -81,3 +97,19 @@ python "$R/.qoder/scripts/task/team_sync.py" status
|
|
|
81
97
|
|
|
82
98
|
一段总览 + 三个分维度小节。健康度分数醒目显示。发现问题(如索引过期、
|
|
83
99
|
未同步堆积、EVA 合格率低)在结尾列"建议动作"清单。
|
|
100
|
+
|
|
101
|
+
## 📊 可用性看板(吸收宿主动态 UI 能力 · 双轨)
|
|
102
|
+
|
|
103
|
+
健康度展示后,**追加一个可用性看板**(让"工作流用没用起来"可视化):
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" usability --html
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
- **QoderWork**:脚本自动调 `qoder_show_widget` 把交互看板(仪表盘 + 绿黄红指标条)**嵌入对话流**。
|
|
110
|
+
- **纯 IDE / CLI**:自动降级——看板落盘到 `workspace/members/{dev}/journal/dashboard-*.html`,
|
|
111
|
+
你把路径告诉用户让他点开看;同时口述核心数字(采纳分 + 红灯项)。
|
|
112
|
+
- 看板数据源:eval-history + feedback + learning.yaml(同 `usability` 命令)。
|
|
113
|
+
|
|
114
|
+
> 这是吸收宿主 Skills 动态 UI 能力的落点:富宿主嵌入对话,纯 CLI 落盘兜底,能力层自动切。
|
|
115
|
+
|
|
@@ -11,7 +11,7 @@ trigger: "user invokes /wl-* command explicitly"
|
|
|
11
11
|
```bash
|
|
12
12
|
R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
13
13
|
```
|
|
14
|
-
> `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python
|
|
14
|
+
> `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。找不到时先跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
|
|
15
15
|
|
|
16
16
|
# wl-task — 任务管理(7 站之「任务」站 · 产品工位)
|
|
17
17
|
|
|
@@ -25,8 +25,10 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
|
25
25
|
| 用户说什么 | 动作 | 跑什么 |
|
|
26
26
|
|-----------|------|--------|
|
|
27
27
|
| "建个任务 XXX" / "把刚才需求建成任务" / "create" | **create** | `task.py create`(带 PRD 衔接) |
|
|
28
|
-
| "
|
|
29
|
-
| "
|
|
28
|
+
| "列一下**本地**任务" / "有哪些任务" / "list" | **list** | `task.py list`(本地离线缓存,非禅道) |
|
|
29
|
+
| **"我的任务" / "我的禅道" / "这周干啥" / "我的Bug"** | **自然查询** | ★直接 `my_workbench()`(见下方禅道查询总表),不走本命令工序 |
|
|
30
|
+
| **"看下#301" / "需求#761怎么样了" / "Bug状态"** | **自然查询** | 直接 `get_task` / `get_story_detail` / `get_bug`,自然回答 |
|
|
31
|
+
| "接下来做啥" / "能做的有哪些" | **list --ready** | 只看能立刻开始的(本地依赖视角) |
|
|
30
32
|
| "卡住的有哪些" / "哪些被阻塞" | **list --blocked** | 只看有未完成依赖的 |
|
|
31
33
|
| "看下 XXX 任务" / "XXX 怎么样了" / "show" | **show** | `task.py show <名>` |
|
|
32
34
|
| "开始做 XXX" / "启动 XXX" / "start" | **start** | `task.py start <名>` |
|
|
@@ -36,16 +38,96 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
|
36
38
|
| "排期" / "甘特图" / "排个日期" / "plan" | **plan** | `task.py gantt` + set-due |
|
|
37
39
|
| 模糊 / 拿不准 | 先 list 给全貌 | 再问要操作哪个 |
|
|
38
40
|
|
|
41
|
+
> **边界**:上面"自然查询"行的(我的任务/看进度/Bug状态)—— AI 直接用禅道 MCP 工具回答,**不拉入工序流程**。
|
|
42
|
+
> "PRD发禅道/记工时/改状态"这类**显式操作**才走工序(见 wl-task.md 的 zentao 剧本)。
|
|
43
|
+
|
|
44
|
+
### 🔌 宿主路由:禅道怎么调(看你在哪个宿主)
|
|
45
|
+
|
|
46
|
+
> ★ 丝滑关键。禅道工具有两条入口,用错就慢/重复 spawn/报错。
|
|
47
|
+
|
|
48
|
+
| 宿主 | 调用入口 | 何时用 |
|
|
49
|
+
|------|---------|--------|
|
|
50
|
+
| **QoderWork** | `qw_mcp_call("工具名", {参数})` | 第一宿主。QoderWork 已起 zentao 进程,直接复用,**省 list/get 两步元调用**。下表工具名确定时直接 call。 |
|
|
51
|
+
| **Qoder IDE / Quest** | `mcp__qoder-zentao__工具名(参数)` | IDE 把 MCP 工具暴露成 `mcp__<server>__<tool>`。 |
|
|
52
|
+
| **CLI / 其他** | `cap.mcp.call("工具名", {参数})` | 无原生 MCP,capability 层 spawn 本地 server。 |
|
|
53
|
+
|
|
54
|
+
**判定宿主**:`QODER_SESSION_ID` 存在 = QoderWork;否则 `detect_host()`。下表统一用 `qw_mcp_call(...)` 示意(CLI 换 `cap.mcp.call`,参数一致)。
|
|
55
|
+
|
|
56
|
+
### ★★★ 禅道查询总表 + 三铁律(处理任何禅道意图,先查这张表,禁止瞎试)
|
|
57
|
+
|
|
58
|
+
> 这三轮实测的病根:AI 看到"看我的禅道X"找不到路就**瞎试→枚举→调用爆炸/token浪费**。
|
|
59
|
+
> 下面这张表是"宪法"——任何禅道意图,**先匹配表里的行,照着走**。匹配不上再问用户,**绝不逐个枚举**。
|
|
60
|
+
|
|
61
|
+
#### 🔒 三条铁律(违反 = 失败,AI 必读)
|
|
62
|
+
|
|
63
|
+
1. **禁止枚举扇出**:拿到 list 结果后,**绝不**逐个调 `get_*_detail`。list 返回的 `id+name+status` 已够用;只有用户明确点了某条("看#761详情"),才单独 `get_story_detail(story_id=761)` 一次。
|
|
64
|
+
2. **🚫 跨域不冒充(v3.1.5 新增,最重要)**:用户问「任务」就查 task 域,问「需求」查 story 域,问「Bug」查 bug 域。**查不到如实说"没有指派给你的任务"+贴查询证据,绝不拿需求/Bug 顶替任务来回答**。用户问"我的任务"却收到需求列表 = 严重失败。
|
|
65
|
+
3. **写操作要确认**:改/删需求、执行、版本这类**无归属校验**的工具,调之前先把要操作的项列出来让用户确认(防改错队友/全局资源)。任务/Bug 的 start/finish/resolve 等有 `_assert_owner` 兜底,但仍建议先 get 一次确认是我的。
|
|
66
|
+
|
|
67
|
+
#### 意图路由总表(用户说什么 → 调什么 → 调几次)
|
|
68
|
+
|
|
69
|
+
| 用户说的意图 | 直达工具 | 调用次数 | 关键约束 |
|
|
70
|
+
|------------|---------|:---:|---------|
|
|
71
|
+
| **看我的禅道任务/这周干啥/我手头有啥** | ★`my_workbench()` | **1** | 跨执行/产品全量聚合,一行拿全!不再逐执行查 |
|
|
72
|
+
| 看我未开始/进行中的任务 | `list_my_tasks(status='wait')` / `list_my_tasks(status='doing')` | 1 | 跨执行全量 |
|
|
73
|
+
| **看我的禅道需求** / "我的需求" | `my_workbench()` 看需求段(或逐产品 `list_stories`) | 1 | 🚫**禁逐个 get_story_detail** |
|
|
74
|
+
| **看我的Bug** | ★`list_my_bugs()` | **1** | 跨产品全量,不再逐产品查 |
|
|
75
|
+
| 看某执行任务(已知eid) | `list_execution_tasks(eid)` | 1 | 默认只看我的 |
|
|
76
|
+
| 看全队任务/需求/Bug | 对应工具 + `all=true` | 1 | ★**必须用户明说"全队"才加** |
|
|
77
|
+
| 看某条详情("#761怎么样") | `get_story_detail` / `get_task` / `get_bug` (该 id) | 1 | 用户**点了具体 ID** 才调 |
|
|
78
|
+
| 看有哪些产品/执行/版本 | `list_products` / `list_executions` / `list_builds(project_id=9)` | 1 | 导航类,可自由调(公开结构) |
|
|
79
|
+
| 建需求 / PRD发禅道 | `create_story` → 然后**主动问关联版本**(见下) | 1+ | 不知产品先 `list_products` 勾选 |
|
|
80
|
+
| 关联版本 | `list_builds(project_id=9)` → `link_story_to_build` | 2 | 多选 = 一个需求进当前+未来版本 |
|
|
81
|
+
| 拆需求为任务 | `list_executions` 选 → `create_task` | 2 | 不填 assignedTo 默认指派给我 |
|
|
82
|
+
| 开始/完成/记工时任务 | `start_task` / `finish_task` / `log_effort` (task_id) | 1 | 有归属校验;finish 要问消耗工时 |
|
|
83
|
+
|
|
84
|
+
#### 「看我的工作」统一范式(v3.1.5 升级)
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
★ 首选: my_workbench() —— 一次返回任务+需求+Bug 三域全量聚合, 跨所有执行/产品不漏。
|
|
88
|
+
这是回答"我手头有什么活/我的任务/我的禅道"的默认工具, 调用次数从原来的 N(逐执行) 降到 1。
|
|
89
|
+
|
|
90
|
+
单域查询: list_my_tasks(status=...) / list_my_bugs() —— 跨执行/产品全量, 只看我的。
|
|
91
|
+
|
|
92
|
+
旧的逐执行/逐产品查法 (list_execution_tasks 逐个执行、list_stories 逐个产品) 仍可用,
|
|
93
|
+
但只用于"已知具体执行/产品ID"的场景。查"我的全部"会被漏数据(实测 61 执行逐个查会漏)。
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### 归属账号未识别(v3.1.5 起工具层直接拒绝)
|
|
97
|
+
|
|
98
|
+
若 `my_workbench` / `list_my_tasks` / `list_my_bugs` / `list_execution_tasks`(默认) 返回:
|
|
99
|
+
`🚫 未识别禅道身份: member.json 缺 zentao_account...`
|
|
100
|
+
→ 这是**工具层主动拒绝**(不再静默降级)。原样把提示转述给用户,引导跑 `/wl-init` 配置。
|
|
101
|
+
**绝不绕过**(不传 all=true 去看全队当我的,不拿别的域顶替)。配好后重启 MCP 生效。
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
#### 建需求后主动问版本(★ 你们的版本=项目级 build)
|
|
105
|
+
|
|
106
|
+
> 你们的「版本」是**项目级 build**(项目#9 下按周 `V+日期`,如 `V20260625`),不是产品级 plan/release。一个需求可能**同时进当前+未来版本**,所以**显式让 PM 多选**,不自动关联。
|
|
107
|
+
|
|
108
|
+
建需求/评审通过后,AI **主动**列最近 build 让 PM 勾选:
|
|
109
|
+
```
|
|
110
|
+
AI: 要关联到哪个版本?(最近 6 个 build):
|
|
111
|
+
[1] #22 V20260625 (本周) [2] #21 V20260618 (上周) [3] #16 V20260604 ...
|
|
112
|
+
PM> 1,3 ← 多选 = 一个需求进当前版本(本周发)+未来版本
|
|
113
|
+
AI: ✅ 需求#761 已关联 build#22(本周) + #16(未来)
|
|
114
|
+
```
|
|
115
|
+
- 候选:`list_builds(project_id=9)` 取最近 6 个,按时间倒序编号。
|
|
116
|
+
- 关联:`link_story_to_build(build_id=<选中>, stories=[<需求ID>])`,**逐个 build 调一次**。
|
|
117
|
+
- PM 也可主动触发:"把#761 关联到本周版本" → AI 查本周 build 再关联。
|
|
118
|
+
|
|
39
119
|
## ⚙️ 自取上下文(Quest / QoderWork 无 hook 注入,必须自读)
|
|
40
120
|
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
121
|
+
- **当前身份**:当前开发者(assignee 默认值)。读法:先 `R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.` 定位仓库根,
|
|
122
|
+
再 `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`(输出开发者名;空=未初始化)。
|
|
123
|
+
⚠️ 勿用裸相对路径 `.qoder/.developer`(QoderWork 桌面端 cwd 不在仓库根,会读不到而误报未初始化)。
|
|
124
|
+
- **活动任务**:当前活动任务("开始做""完成了"默认对它操作)。读法 `python "$R/.qoder/scripts/foundation/core/paths.py" current-task`(输出任务路径;空=无活动任务)。
|
|
125
|
+
- 列出已有任务:`cap.mcp.call("list_tasks", {})`
|
|
44
126
|
- 衔接 PRD:扫 `workspace/members/{dev}/drafts/REQ-*.md` + `data/docs/prd/REQ-*.md`
|
|
45
127
|
|
|
46
128
|
## 🔒 三道前置检查(任何动作前先做,保证健壮)
|
|
47
129
|
|
|
48
|
-
1.
|
|
130
|
+
1. **身份检查**:跑 `python "$R/.qoder/scripts/foundation/core/paths.py" whoami`,无输出/退出码1 = 未初始化 → 停下,提示先 `/wl-init`(否则 create 会把 assignee 写空)。
|
|
49
131
|
2. **空数据兜底**:tasks 目录不存在/空 → 读操作友好提示"还没有任务",不报错;create 直接建。
|
|
50
132
|
3. **脚本退出码**:`task.py` 返回非 0 → 原样读 stderr 告诉用户。`4`=权限不足(零信任 ACL),`1`=任务不存在/JSON 缺失。**绝不绕过 ACL。**
|
|
51
133
|
|
|
@@ -56,7 +138,7 @@ R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
|
56
138
|
**create(最高频)—— PRD 衔接不丢字段:**
|
|
57
139
|
- 有 PRD → 从 PRD 提取标题/模块/验收点,**别让用户重述**;把 REQ-ID 记进 task.json 的 `tags`。
|
|
58
140
|
- 无 PRD → 用用户给的一句话当标题。
|
|
59
|
-
- 建完 push:`
|
|
141
|
+
- 建完 push:`cap.mcp.call("sync", {"direction": "push"})`
|
|
60
142
|
|
|
61
143
|
**rank(RICE)—— 一次取全,别逐个问:**
|
|
62
144
|
1. `task.py list --status planning` 拿全待排任务
|
|
@@ -105,7 +187,7 @@ RICE = Reach × Impact × Confidence ÷ Effort
|
|
|
105
187
|
|
|
106
188
|
`create` / `finish` / `archive` 改了任务状态,都要推给团队(用户永不碰 git):
|
|
107
189
|
```bash
|
|
108
|
-
|
|
190
|
+
cap.mcp.call("sync", {"direction": "push"})
|
|
109
191
|
```
|
|
110
192
|
|
|
111
193
|
## finish 后:自动生成测试交接画像(可选增强)
|
|
@@ -124,7 +206,7 @@ python "$R/.qoder/scripts/task/team_sync.py" push
|
|
|
124
206
|
|
|
125
207
|
## 🧩 QoderWork 增强:待办双向同步(可选 · 无连接器则自动回退)
|
|
126
208
|
|
|
127
|
-
>
|
|
209
|
+
> 通过 capability 层自动路由(Settings → Connectors,授权 Microsoft 365 待办 / OneNote,或 macOS 提醒事项)。
|
|
128
210
|
> **纯 Qoder IDE / CLI 没有连接器 → 本段不生效,任务只在本地 task.json 管理,完全够用。**
|
|
129
211
|
> 探测方式:仅当运行环境提供了「待办 / To-Do」工具可直接读写时才用。
|
|
130
212
|
|
|
@@ -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/
|
|
49
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test quick --cases-file <文件路径> --env test --platform web
|
|
50
50
|
# ❌ 错: 内联(长JSON截断, 多条用例必丢)
|
|
51
|
-
python "$R/.qoder/scripts/
|
|
51
|
+
python "$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/test/autotest.py" quick --cases '[{"case_id"...(超长
|
|
|
67
67
|
**⑥ recall 的 `--url` 必须用相对路径(无前导斜杠),避开 Git-bash/MSYS 路径转换坑。**
|
|
68
68
|
```bash
|
|
69
69
|
# ✅ 对: 相对路径 (MSYS 不转换)
|
|
70
|
-
python "$R/.qoder/scripts/
|
|
70
|
+
python "$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/
|
|
72
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url /auth/login
|
|
73
73
|
```
|
|
74
74
|
(脚本已加 normalize 兜底能修这个,但别依赖兜底——直接写相对路径最干净。)
|
|
75
75
|
|
|
@@ -98,8 +98,8 @@ python "$R/.qoder/scripts/test/autotest.py" recall --url /auth/login
|
|
|
98
98
|
> R=$(python ~/.qoderwork/repo_root.py 2>/dev/null) || R=.
|
|
99
99
|
> ```
|
|
100
100
|
> `repo_root.py` 从 `~/.qoderwork/mcp.json` 反推仓库根;失败回退 `.`(IDE/CLI 工作目录即仓库根)。
|
|
101
|
-
>
|
|
102
|
-
> 如果 `repo_root.py` 报错找不到,先在仓库里跑 `python "$R/.qoder/scripts/
|
|
101
|
+
> **后续脚本统一用 `python "$R/.qoder/scripts/orchestration/wlkj.py" <命令>`,不要再搜!**
|
|
102
|
+
> 如果 `repo_root.py` 报错找不到,先在仓库里跑 `python "$R/.qoder/scripts/orchestration/wlkj.py" install-qw`。
|
|
103
103
|
|
|
104
104
|
- `<R>/.qoder/.developer` — 当前开发者
|
|
105
105
|
- `<R>/.qoder/config.yaml` 的 `autotest:` 段 — 环境/域名
|
|
@@ -112,7 +112,7 @@ python "$R/.qoder/scripts/test/autotest.py" recall --url /auth/login
|
|
|
112
112
|
|
|
113
113
|
**唯一正确做法**——1 条命令查 MySQL sys_menu 真实路由:
|
|
114
114
|
```bash
|
|
115
|
-
python "$R/.qoder/scripts/
|
|
115
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" search --routes 保险
|
|
116
116
|
# → 保险管理 -> /veh/vehicle/vehAffair/insurance
|
|
117
117
|
```
|
|
118
118
|
- 数据来自 MySQL `sys_menu` 表(后台动态菜单,**唯一事实源**)
|
|
@@ -121,10 +121,10 @@ python "$R/.qoder/scripts/kg/search_index.py" --routes 保险
|
|
|
121
121
|
|
|
122
122
|
### 生成用例时用 MySQL MCP 补真实数据(少手填、覆盖边界)
|
|
123
123
|
|
|
124
|
-
1. **取真实测试数据**:需要业务单号/账号时 `
|
|
124
|
+
1. **取真实测试数据**:需要业务单号/账号时 `cap.mcp.call("query_data", {"table": "表名", "columns": "id", "单号列", "where": "条件", "limit": "5"})`
|
|
125
125
|
- 拿测试库真实可用的数据,别编造。填进用例的 data 里。
|
|
126
126
|
- [QAS环境] 数据行仅参考格式,不代表线上。
|
|
127
|
-
2. **枚举边界覆盖**:涉及状态/类型字段时 `
|
|
127
|
+
2. **枚举边界覆盖**:涉及状态/类型字段时 `cap.mcp.call("query_distinct", {"table": "表名", "column": "状态列"})`
|
|
128
128
|
- 查真实取值范围(如 case_status = 1/2/3/4),按每个值造边界用例。
|
|
129
129
|
- 取值范围可信 → 用例枚举全覆盖,不漏分支。
|
|
130
130
|
|
|
@@ -159,18 +159,27 @@ coverage_matrix()
|
|
|
159
159
|
|
|
160
160
|
**不要任务/PRD。零搜索。** 用意图+锚点格式(A方案),observe-act-extract 执行。
|
|
161
161
|
|
|
162
|
-
### Step 0:recall
|
|
162
|
+
### Step 0 + 0.5:recall 查锚点 + context_pack 取全(两者无依赖,同回合并发)
|
|
163
|
+
|
|
164
|
+
> Step0(recall 锚点)和 Step0.5(context_pack 上下文)互不依赖 → **同一条消息并发发**,别先跑0再跑0.5。
|
|
165
|
+
|
|
166
|
+
**Step 0:recall 查锚点**(用相对 URL,避开 MSYS 坑)
|
|
163
167
|
```bash
|
|
164
|
-
python "$R/.qoder/scripts/
|
|
168
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test recall --url auth/login
|
|
165
169
|
```
|
|
166
170
|
- **有锚点** → 生成用例时直接把 anchor 填进 step(确定性命中,快、零 LLM)
|
|
167
171
|
- **无锚点(首次)** → **先 navigate + snapshot 拿真实锚点,再生成用例**(见 Step 0.6)
|
|
168
172
|
|
|
169
|
-
|
|
173
|
+
**Step 0.5:用知识图谱 MCP 增强用例**(1 次调用取全,与 recall 并发)
|
|
174
|
+
```python
|
|
175
|
+
context_pack(keyword='功能名', platform='web', role='test')
|
|
176
|
+
```
|
|
177
|
+
- 返回(role=test 裁剪): 代码落点 + 相关历史 PRD 标题 + API + 字段
|
|
178
|
+
- 拿到后用于: API→断言点, 字段→fill 步骤更准
|
|
170
179
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
180
|
+
> ⚠️ **注意:context_pack 不抓 PRD 验收标准正文**(它只取 PRD 的 title+keywords,
|
|
181
|
+
> 不解析「## 验收标准」章节)。**业务规则断言不要指望 context_pack**,它给不了 expected。
|
|
182
|
+
> 要把 PRD 验收标准翻译成可执行断言,用 `assertion-gen` 子命令(见下方专节)。
|
|
174
183
|
|
|
175
184
|
> 图谱无数据 → 跳过,按通用模式生成。**不要再单独调 feature_overview**(信息重叠,浪费一轮)。
|
|
176
185
|
|
|
@@ -203,8 +212,8 @@ snapshot 返回形如:
|
|
|
203
212
|
|
|
204
213
|
**🎯 知道页面名/URL 时,AI 先查按钮+接口画像(最精准,1 条命令拿到所有交互点):**
|
|
205
214
|
```bash
|
|
206
|
-
python "$R/.qoder/scripts/
|
|
207
|
-
python "$R/.qoder/scripts/
|
|
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查
|
|
208
217
|
```
|
|
209
218
|
(这是 AI 在 `/wl-test` 流程内部自动调用的工具,**用户只用 `/wl-test`,不碰此命令**。)
|
|
210
219
|
输出每个按钮的 handler + 调用接口 + HTTP 方法 + 置信度,**直接对应到用例的 click→assert 断言点**。开发 `finish` 任务时也会自动生成 `test-handoff.md`,内容同此画像——交接场景直接读那份即可,不必重查。
|
|
@@ -236,7 +245,7 @@ python "$R/.qoder/scripts/test/autotest.py" page --url /veh/insurance # 按URL
|
|
|
236
245
|
# AI 先写文件:
|
|
237
246
|
# 写 workspace/members/{dev}/drafts/_autotest-cases.json
|
|
238
247
|
# 再调:
|
|
239
|
-
python "$R/.qoder/scripts/
|
|
248
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test quick \
|
|
240
249
|
--cases-file workspace/members/{dev}/drafts/_autotest-cases.json \
|
|
241
250
|
--desc "<用户描述>" --platform <web|app>
|
|
242
251
|
```
|
|
@@ -317,7 +326,7 @@ python "$R/.qoder/scripts/test/autotest.py" quick \
|
|
|
317
326
|
|
|
318
327
|
**执行方式**:把测试结果 + 测试中 `browser_snapshot` 看到的页面元素一起回传:
|
|
319
328
|
```bash
|
|
320
|
-
python "$R/.qoder/scripts/
|
|
329
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test quick \
|
|
321
330
|
--cases-file <之前的cases文件> \
|
|
322
331
|
--record '{"Q-1":"pass","Q-2":"pass","Q-3":"pass"}' \
|
|
323
332
|
--page-json '{"url":"/veh/vehicle/vehAffair/insurance","elements":[{"role":"textbox","name":"车牌号"},{"role":"button","name":"搜索"},{"role":"button","name":"新增"}]}'
|
|
@@ -338,11 +347,11 @@ python "$R/.qoder/scripts/test/autotest.py" quick \
|
|
|
338
347
|
## browser 基于任务的浏览器测试(用户明确给了任务名时)
|
|
339
348
|
|
|
340
349
|
```bash
|
|
341
|
-
|
|
342
|
-
python "$R/.qoder/scripts/
|
|
350
|
+
cap.mcp.call("list_tasks", {}) # 确认任务存在
|
|
351
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test generate <task> # 生成骨架到 autotest-cases.jsonl
|
|
343
352
|
# AI 读任务 PRD「验收标准」补全 steps/expected (真实数据用 {{ask:}}, 不搜源码)
|
|
344
|
-
python "$R/.qoder/scripts/
|
|
345
|
-
python "$R/.qoder/scripts/
|
|
353
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test run <task> # 注入+出执行计划
|
|
354
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test run <task> --record '{"..":"pass"}' # 回收结果
|
|
346
355
|
```
|
|
347
356
|
|
|
348
357
|
**回归测试增强(图谱 MCP)**:测接口改动时,用 `get_impact` 查影响范围,自动覆盖受影响页面:
|
|
@@ -363,6 +372,43 @@ JUnit 测试(Mock + MockMvc,Given-When-Then,`@DisplayName`,AssertJ)→
|
|
|
363
372
|
|
|
364
373
|
---
|
|
365
374
|
|
|
375
|
+
## 📋 断言生成 assertion-gen(业务规则断言 · 第三档专用)
|
|
376
|
+
|
|
377
|
+
> 解决痛点:quick 模式的 `_check_expect` 能执行 `{fetch, jsonpath, equals}` 断言,
|
|
378
|
+
> 但那个 **equals 期望值从哪来** 没人管——靠 LLM 瞎编不可信。
|
|
379
|
+
> `assertion-gen` 把"PRD 验收标准 → 可执行断言"这条断链接上。
|
|
380
|
+
|
|
381
|
+
**分工(呼应图谱边界三条红线):**
|
|
382
|
+
- **人补语义**:PRD 里写结构化验收(Given-When-Then,或"条件-操作-预期"带接口名/状态码/字段值)
|
|
383
|
+
- **图谱补字段**:`page_probe` 查按钮→接口,`field_map` 查中文标题→字段名
|
|
384
|
+
- **真跑定对错**:assertion-gen 只产断言 JSON,跑不跑交给 quick/webaccess
|
|
385
|
+
|
|
386
|
+
**什么时候用**:业务规则断言(保险延期要审批、退保校验、状态流转)——这是 quick 通用模式
|
|
387
|
+
搞不定的第三档。冒烟(页面没崩)、CRUD 流(新增→列表出现)用 quick 就够,不需要这个。
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
# 从任务 PRD 的验收标准章节抿断言
|
|
391
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test assertion-gen --task <任务名> --page 保险
|
|
392
|
+
|
|
393
|
+
# 临时用 GWT 文本兜底(PRD 没写验收标准时)
|
|
394
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test assertion-gen \
|
|
395
|
+
--gwt "Given 已登录保险页 When 点击延期提交 Then 接口 /api/insurance/delay 返回 code=200 且 状态列显示审批中" \
|
|
396
|
+
--page 保险
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**输出**:`workspace/tasks/<task>/assertions.json`,每条断言带 `source` 置信度标记:
|
|
400
|
+
- `规则·句中含接口` / `图谱·按钮画像` = 可信(接口路径已确定)
|
|
401
|
+
- `需确认·字段未命中` = 待补(字段表查不到,留 `{{ask:}}` 占位)
|
|
402
|
+
|
|
403
|
+
**两条铁律(assertion-gen 内置):**
|
|
404
|
+
1. **抽不到就老实说**:PRD 验收标准为空/纯描述 → 输出"无可抽取的结构化断言",**绝不编造**断言。
|
|
405
|
+
2. **语义不背书**:字段补全命中标 `[图谱]`,查不到留占位标 `[需确认]`,不让图谱假装懂业务。
|
|
406
|
+
|
|
407
|
+
**下一步**:把 `assertions.json` 的 assertions 数组并进 quick 用例的 steps(`intent:"assert"`),
|
|
408
|
+
用 webaccess 或 quick 执行真跑验证。**assertion-gen 自己不执行、不真跑。**
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
366
412
|
## 🔐 测试数据处理原则(个人 vs 团队隔离)
|
|
367
413
|
|
|
368
414
|
- **绝不编造**:账号/密码/手机号用 `{{ask:描述}}` 占位,问用户要。
|
|
@@ -370,9 +416,9 @@ JUnit 测试(Mock + MockMvc,Given-When-Then,`@DisplayName`,AssertJ)→
|
|
|
370
416
|
域名才放 config(全团队一致)。账号密码每人不同 → 个人文档。
|
|
371
417
|
- **个人文档**:`workspace/members/{你的名字}/autotest-data.yaml`(gitignored,永不 push)
|
|
372
418
|
```bash
|
|
373
|
-
python "$R/.qoder/scripts/
|
|
374
|
-
python "$R/.qoder/scripts/
|
|
375
|
-
python "$R/.qoder/scripts/
|
|
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 # 查看(密码脱敏)
|
|
376
422
|
```
|
|
377
423
|
run/quick 时按 env/platform 自动取最精确的值;`--data` 可临时覆盖。
|
|
378
424
|
|
|
@@ -382,7 +428,7 @@ run/quick 时按 env/platform 自动取最精确的值;`--data` 可临时覆
|
|
|
382
428
|
|
|
383
429
|
**Step A:查登录态**
|
|
384
430
|
```bash
|
|
385
|
-
python "$R/.qoder/scripts/
|
|
431
|
+
python "$R/.qoder/scripts/orchestration/wlkj.py" test login-state show
|
|
386
432
|
```
|
|
387
433
|
|
|
388
434
|
**Step B:按登录态决定行为**
|
|
@@ -403,8 +449,8 @@ python "$R/.qoder/scripts/test/autotest.py" login-state show
|
|
|
403
449
|
|
|
404
450
|
```bash
|
|
405
451
|
# 手动操作(一般不用,AI 会自动):
|
|
406
|
-
python "$R/.qoder/scripts/
|
|
407
|
-
python "$R/.qoder/scripts/
|
|
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 # 清除(强制重登录)
|
|
408
454
|
```
|
|
409
455
|
|
|
410
456
|
## 🧩 QoderWork 增强:浏览器自动执行(可选 · 无连接器则自动回退)
|
|
@@ -76,6 +76,13 @@
|
|
|
76
76
|
#### 原型地址
|
|
77
77
|
{prototype-{feature}.html 的路径;两端需求分别给 -web/-app 两个文件}
|
|
78
78
|
|
|
79
|
+
> **原型可选(v3.1)**:若本需求为纯规则/接口/定时/参数下发/计算类(无 UI 变化),
|
|
80
|
+
> 经用户在「轻反思+批量确认」环节明确同意不画原型后,本节写:
|
|
81
|
+
> `无({原因},经用户确认豁免)`
|
|
82
|
+
> 并在 PRD 第 1 行 `@contract` 头标记 `prototype: none`。
|
|
83
|
+
> 下游 `/wl-design` 读到 `prototype: none` 跳过原型环节;`/wl-code` 直接以 PRD 字段表为准。
|
|
84
|
+
> eval_prd 检测到 `prototype: none` 时 A2 自动跳过(满分从 100 降到 70,照样能 PASS)。
|
|
85
|
+
|
|
79
86
|
## 非功能性需求
|
|
80
87
|
{性能(响应时间/并发)、安全(权限)、兼容性(浏览器/系统版本)、可用性}
|
|
81
88
|
|