@hupan56/wlkj 2.7.12 → 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.
Files changed (253) hide show
  1. package/bin/cli.js +1435 -1107
  2. package/package.json +29 -29
  3. package/templates/qoder/agents/insight-planning.md +1 -1
  4. package/templates/qoder/agents/insight-research.md +28 -15
  5. package/templates/qoder/commands/optional/wl-insight.md +161 -161
  6. package/templates/qoder/commands/optional/wl-report.md +20 -39
  7. package/templates/qoder/commands/optional/wl-status.md +4 -4
  8. package/templates/qoder/commands/wl-code.md +2 -2
  9. package/templates/qoder/commands/wl-design.md +6 -6
  10. package/templates/qoder/commands/wl-init.md +3 -3
  11. package/templates/qoder/commands/wl-prd.md +26 -13
  12. package/templates/qoder/commands/wl-req.md +43 -0
  13. package/templates/qoder/commands/wl-search.md +78 -47
  14. package/templates/qoder/commands/wl-task.md +343 -40
  15. package/templates/qoder/commands/wl-test.md +43 -17
  16. package/templates/qoder/config.yaml +52 -14
  17. package/templates/qoder/hooks/post-tool-use.py +181 -0
  18. package/templates/qoder/hooks/session-start.py +94 -23
  19. package/templates/qoder/hooks/stop-eval.py +207 -0
  20. package/templates/qoder/hooks/user-prompt-submit.py +139 -0
  21. package/templates/qoder/rules/wl-pipeline.md +85 -49
  22. package/templates/qoder/scripts/README.md +102 -0
  23. package/templates/qoder/scripts/capability/__init__.py +26 -0
  24. package/templates/qoder/scripts/capability/__main__.py +72 -0
  25. package/templates/qoder/scripts/capability/adapters/__init__.py +29 -0
  26. package/templates/qoder/scripts/capability/adapters/cli.py +316 -0
  27. package/templates/qoder/scripts/capability/adapters/mcp.py +334 -0
  28. package/templates/qoder/scripts/capability/adapters/qw.py +271 -0
  29. package/templates/qoder/scripts/capability/caps/__init__.py +27 -0
  30. package/templates/qoder/scripts/capability/caps/context.py +36 -0
  31. package/templates/qoder/scripts/capability/caps/cron.py +50 -0
  32. package/templates/qoder/scripts/capability/caps/identity.py +43 -0
  33. package/templates/qoder/scripts/capability/caps/memory.py +71 -0
  34. package/templates/qoder/scripts/capability/caps/notify.py +41 -0
  35. package/templates/qoder/scripts/capability/caps/present.py +48 -0
  36. package/templates/qoder/scripts/capability/caps/repo.py +31 -0
  37. package/templates/qoder/scripts/capability/caps/sandbox.py +43 -0
  38. package/templates/qoder/scripts/capability/chain.py +92 -0
  39. package/templates/qoder/scripts/capability/memory_chain.py +41 -0
  40. package/templates/qoder/scripts/capability/registry.py +246 -0
  41. package/templates/qoder/scripts/capability/registry_mcp.py +250 -0
  42. package/templates/qoder/scripts/capability/smoke_test.py +211 -0
  43. package/templates/qoder/scripts/capability/smoke_test_report.json +94 -0
  44. package/templates/qoder/scripts/deployment/setup/__init__.py +11 -0
  45. package/templates/qoder/scripts/deployment/setup/carriers.py +669 -0
  46. package/templates/qoder/scripts/deployment/setup/carriers_verify.py +148 -0
  47. package/templates/qoder/scripts/{init_doctor.py → deployment/setup/init_doctor.py} +100 -39
  48. package/templates/qoder/scripts/{install_qoderwork.py → deployment/setup/install_qoderwork.py} +48 -30
  49. package/templates/qoder/scripts/{platform_doctor.py → deployment/setup/platform_doctor.py} +271 -259
  50. package/templates/qoder/scripts/{repo_root.py → deployment/setup/repo_root.py} +9 -2
  51. package/templates/qoder/scripts/{setup.py → deployment/setup/setup.py} +143 -14
  52. package/templates/qoder/scripts/{setup_lanhu.py → deployment/setup/setup_lanhu.py} +979 -963
  53. package/templates/qoder/scripts/domain/design/__init__.py +0 -0
  54. package/templates/qoder/scripts/{fill_prototype.py → domain/design/fill_prototype.py} +17 -5
  55. package/templates/qoder/scripts/{gen_design_doc.py → domain/design/gen_design_doc.py} +406 -394
  56. package/templates/qoder/scripts/domain/kg/__init__.py +11 -0
  57. package/templates/qoder/scripts/domain/kg/build/__init__.py +0 -0
  58. package/templates/qoder/scripts/domain/kg/build/build_entity_registry.py +201 -0
  59. package/templates/qoder/scripts/domain/kg/build/build_relations.py +132 -0
  60. package/templates/qoder/scripts/{build_style_index.py → domain/kg/build/build_style_index.py} +50 -15
  61. package/templates/qoder/scripts/domain/kg/build/build_workflows.py +149 -0
  62. package/templates/qoder/scripts/{kg_build.py → domain/kg/build/kg_build.py} +685 -612
  63. package/templates/qoder/scripts/{kg_build_db.py → domain/kg/build/kg_build_db.py} +338 -327
  64. package/templates/qoder/scripts/{kg_incremental.py → domain/kg/build/kg_incremental.py} +425 -393
  65. package/templates/qoder/scripts/{learn_aggregate.py → domain/kg/build/learn_aggregate.py} +212 -201
  66. package/templates/qoder/scripts/domain/kg/extract/__init__.py +0 -0
  67. package/templates/qoder/scripts/{common → domain/kg/extract}/extract.py +430 -419
  68. package/templates/qoder/scripts/domain/kg/extract/test_extract.py +115 -0
  69. package/templates/qoder/scripts/{common → domain/kg/extract}/ts_extract.py +614 -536
  70. package/templates/qoder/scripts/domain/kg/graph/__init__.py +0 -0
  71. package/templates/qoder/scripts/{kg_link_db.py → domain/kg/graph/kg_link_db.py} +235 -224
  72. package/templates/qoder/scripts/domain/kg/graph/kg_semantic.py +683 -0
  73. package/templates/qoder/scripts/{kg.py → domain/kg/kg.py} +871 -708
  74. package/templates/qoder/scripts/domain/kg/kg_capabilities.py +182 -0
  75. package/templates/qoder/scripts/domain/kg/search/__init__.py +0 -0
  76. package/templates/qoder/scripts/{context_pack.py → domain/kg/search/context_pack.py} +45 -17
  77. package/templates/qoder/scripts/{enrich_prompt.py → domain/kg/search/enrich_prompt.py} +238 -226
  78. package/templates/qoder/scripts/domain/kg/search/prefetch.py +384 -0
  79. package/templates/qoder/scripts/{common → domain/kg/search}/search_engine.py +207 -205
  80. package/templates/qoder/scripts/{search_index.py → domain/kg/search/search_index.py} +210 -88
  81. package/templates/qoder/scripts/domain/kg/server/__init__.py +0 -0
  82. package/templates/qoder/scripts/domain/kg/server/kgd.py +549 -0
  83. package/templates/qoder/scripts/domain/kg/server/perf_bench.py +197 -0
  84. package/templates/qoder/scripts/domain/kg/storage/__init__.py +0 -0
  85. package/templates/qoder/scripts/{kg_duckdb.py → domain/kg/storage/kg_duckdb.py} +70 -45
  86. package/templates/qoder/scripts/domain/learning/__init__.py +0 -0
  87. package/templates/qoder/scripts/{learn.py → domain/learning/learn.py} +157 -146
  88. package/templates/qoder/scripts/domain/report/__init__.py +11 -0
  89. package/templates/qoder/scripts/{add_session.py → domain/report/add_session.py} +256 -244
  90. package/templates/qoder/scripts/{export.py → domain/report/export.py} +72 -4
  91. package/templates/qoder/scripts/{report.py → domain/report/report.py} +292 -281
  92. package/templates/qoder/scripts/domain/report/report_snapshot.py +261 -0
  93. package/templates/qoder/scripts/domain/report/role.py +39 -0
  94. package/templates/qoder/scripts/{status.py → domain/report/status.py} +737 -628
  95. package/templates/qoder/scripts/domain/report/status_snapshot.py +191 -0
  96. package/templates/qoder/scripts/domain/requirement/__init__.py +0 -0
  97. package/templates/qoder/scripts/{archive_prd.py → domain/requirement/archive_prd.py} +389 -377
  98. package/templates/qoder/scripts/domain/requirement/req.py +228 -0
  99. package/templates/qoder/scripts/domain/task/__init__.py +11 -0
  100. package/templates/qoder/scripts/{git_sync.py → domain/task/git_sync.py} +90 -50
  101. package/templates/qoder/scripts/{syncgate.py → domain/task/syncgate.py} +18 -7
  102. package/templates/qoder/scripts/domain/task/task.py +229 -0
  103. package/templates/qoder/scripts/domain/task/task_lifecycle.py +606 -0
  104. package/templates/qoder/scripts/domain/task/task_query.py +162 -0
  105. package/templates/qoder/scripts/domain/task/task_relations.py +425 -0
  106. package/templates/qoder/scripts/{team_sync.py → domain/task/team_sync.py} +101 -23
  107. package/templates/qoder/scripts/domain/task/zentao_sync.py +370 -0
  108. package/templates/qoder/scripts/foundation/__init__.py +0 -0
  109. package/templates/qoder/scripts/foundation/bootstrap.py +145 -0
  110. package/templates/qoder/scripts/foundation/core/__init__.py +0 -0
  111. package/templates/qoder/scripts/foundation/core/cmd_registry.py +112 -0
  112. package/templates/qoder/scripts/foundation/core/config.py +187 -0
  113. package/templates/qoder/scripts/{common → foundation/core}/paths.py +706 -400
  114. package/templates/qoder/scripts/foundation/data/__init__.py +0 -0
  115. package/templates/qoder/scripts/foundation/data/contract.py +317 -0
  116. package/templates/qoder/scripts/{common → foundation/data}/events.py +2 -2
  117. package/templates/qoder/scripts/foundation/data/result.py +223 -0
  118. package/templates/qoder/scripts/{common → foundation/data}/task_utils.py +427 -392
  119. package/templates/qoder/scripts/foundation/identity/__init__.py +0 -0
  120. package/templates/qoder/scripts/foundation/identity/check_publish.py +103 -0
  121. package/templates/qoder/scripts/{common → foundation/identity}/developer.py +239 -238
  122. package/templates/qoder/scripts/foundation/identity/guard.py +159 -0
  123. package/templates/qoder/scripts/{common → foundation/identity}/identity.py +132 -9
  124. package/templates/qoder/scripts/foundation/identity/roles.py +60 -0
  125. package/templates/qoder/scripts/foundation/integrations/__init__.py +0 -0
  126. package/templates/qoder/scripts/{common → foundation/integrations}/active_task.py +30 -15
  127. package/templates/qoder/scripts/{common → foundation/integrations}/feishu.py +11 -10
  128. package/templates/qoder/scripts/{common → foundation/integrations}/terms.py +3 -3
  129. package/templates/qoder/scripts/foundation/integrations/zentao_client.py +220 -0
  130. package/templates/qoder/scripts/foundation/io/__init__.py +0 -0
  131. package/templates/qoder/scripts/{common → foundation/io}/filelock.py +1 -1
  132. package/templates/qoder/scripts/{common → foundation/io}/reqid.py +1 -1
  133. package/templates/qoder/scripts/foundation/protocol/__init__.py +0 -0
  134. package/templates/qoder/scripts/foundation/protocol/duckdb_conn.py +39 -0
  135. package/templates/qoder/scripts/foundation/protocol/mcp_base.py +268 -0
  136. package/templates/qoder/scripts/foundation/utils/__init__.py +0 -0
  137. package/templates/qoder/scripts/{common → foundation/utils}/eval_api.py +12 -1
  138. package/templates/qoder/scripts/{common → foundation/utils}/pip_install.py +23 -6
  139. package/templates/qoder/scripts/{common → foundation/utils}/platform_guard.py +1 -1
  140. package/templates/qoder/scripts/orchestration/__init__.py +0 -0
  141. package/templates/qoder/scripts/orchestration/wlkj.py +185 -0
  142. package/templates/qoder/scripts/protocol/__init__.py +0 -0
  143. package/templates/qoder/scripts/protocol/browser/README.md +207 -0
  144. package/templates/qoder/scripts/protocol/browser/SKILL.md +265 -0
  145. package/templates/qoder/scripts/protocol/browser/config.env +9 -0
  146. package/templates/qoder/scripts/protocol/browser/references/cdp-api.md +110 -0
  147. package/templates/qoder/scripts/protocol/browser/references/migration-2.5.3.md +72 -0
  148. package/templates/qoder/scripts/protocol/browser/references/site-patterns/.gitkeep +0 -0
  149. package/templates/qoder/scripts/protocol/browser/scripts/browser-discovery.mjs +138 -0
  150. package/templates/qoder/scripts/protocol/browser/scripts/cdp-proxy.mjs +672 -0
  151. package/templates/qoder/scripts/protocol/browser/scripts/check-deps.mjs +206 -0
  152. package/templates/qoder/scripts/protocol/browser/scripts/find-url.mjs +253 -0
  153. package/templates/qoder/scripts/protocol/browser/scripts/match-site.mjs +46 -0
  154. package/templates/qoder/scripts/protocol/browser/templates/config.env.template +9 -0
  155. package/templates/qoder/scripts/protocol/mcp/__init__.py +11 -0
  156. package/templates/qoder/scripts/protocol/mcp/kg_mcp_server.py +478 -0
  157. package/templates/qoder/scripts/{lanhu_stdio_wrapper.py → protocol/mcp/lanhu_stdio_wrapper.py} +131 -119
  158. package/templates/qoder/scripts/protocol/mcp/mcp_doctor.py +548 -0
  159. package/templates/qoder/scripts/protocol/mcp/mcp_launcher.py +600 -0
  160. package/templates/qoder/scripts/protocol/mcp/mysql_mcp_server.py +461 -0
  161. package/templates/qoder/scripts/protocol/mcp/zentao_mcp_server.py +1920 -0
  162. package/templates/qoder/scripts/protocol/transports/__init__.py +56 -0
  163. package/templates/qoder/scripts/protocol/transports/base.py +87 -0
  164. package/templates/qoder/scripts/protocol/transports/cli.py +132 -0
  165. package/templates/qoder/scripts/protocol/transports/http.py +141 -0
  166. package/templates/qoder/scripts/protocol/transports/stdio.py +293 -0
  167. package/templates/qoder/scripts/run_weekly_update.bat +27 -18
  168. package/templates/qoder/scripts/run_weekly_update.sh +22 -13
  169. package/templates/qoder/scripts/validation/__init__.py +0 -0
  170. package/templates/qoder/scripts/validation/eval/__init__.py +0 -0
  171. package/templates/qoder/scripts/validation/eval/perf-report-2026-06-24.md +139 -0
  172. package/templates/qoder/scripts/validation/eval/qwork_harness.py +617 -0
  173. package/templates/qoder/scripts/validation/eval/report-commands.md +220 -0
  174. package/templates/qoder/scripts/validation/eval/transcript_timing.py +386 -0
  175. package/templates/qoder/scripts/validation/metrics/__init__.py +0 -0
  176. package/templates/qoder/scripts/{eval_prd.py → validation/metrics/eval_prd.py} +84 -15
  177. package/templates/qoder/scripts/validation/metrics/usability_score.py +750 -0
  178. package/templates/qoder/scripts/validation/test/__init__.py +11 -0
  179. package/templates/qoder/scripts/validation/test/assertion_gen.py +551 -0
  180. package/templates/qoder/scripts/{autotest.py → validation/test/autotest.py} +1234 -1751
  181. package/templates/qoder/scripts/validation/test/autotest_auth.py +109 -0
  182. package/templates/qoder/scripts/{autotest_batch.py → validation/test/autotest_batch.py} +255 -224
  183. package/templates/qoder/scripts/validation/test/autotest_data.py +680 -0
  184. package/templates/qoder/scripts/validation/test/autotest_opencli.py +646 -0
  185. package/templates/qoder/scripts/{autotest_run.py → validation/test/autotest_run.py} +323 -297
  186. package/templates/qoder/scripts/validation/test/autotest_webaccess.py +571 -0
  187. package/templates/qoder/scripts/{benchmark.py → validation/test/benchmark.py} +17 -5
  188. package/templates/qoder/scripts/{kg_auto_login.py → validation/test/kg_auto_login.py} +208 -196
  189. package/templates/qoder/scripts/{kg_test_runner.py → validation/test/kg_test_runner.py} +13 -2
  190. package/templates/qoder/scripts/{page_probe.py → validation/test/page_probe.py} +470 -459
  191. package/templates/qoder/scripts/validation/test/smoke_all_commands.py +170 -0
  192. package/templates/qoder/settings.json +23 -2
  193. package/templates/qoder/skills/design-import/SKILL.md +235 -226
  194. package/templates/qoder/skills/design-review/SKILL.md +91 -82
  195. package/templates/qoder/skills/prd-generator/SKILL.md +38 -24
  196. package/templates/qoder/skills/prd-review/SKILL.md +8 -6
  197. package/templates/qoder/skills/prototype-generator/SKILL.md +296 -247
  198. package/templates/qoder/skills/spec-coder/SKILL.md +24 -15
  199. package/templates/qoder/skills/spec-generator/SKILL.md +24 -12
  200. package/templates/qoder/skills/test-generator/SKILL.md +9 -7
  201. package/templates/qoder/skills/wl-code/SKILL.md +25 -13
  202. package/templates/qoder/skills/wl-commit/SKILL.md +10 -9
  203. package/templates/qoder/skills/wl-design/SKILL.md +7 -5
  204. package/templates/qoder/skills/wl-init/SKILL.md +8 -8
  205. package/templates/qoder/skills/wl-insight/SKILL.md +25 -12
  206. package/templates/qoder/skills/wl-prd-full/SKILL.md +59 -8
  207. package/templates/qoder/skills/wl-prd-quick/SKILL.md +7 -7
  208. package/templates/qoder/skills/wl-prd-review/SKILL.md +18 -6
  209. package/templates/qoder/skills/wl-report/SKILL.md +27 -25
  210. package/templates/qoder/skills/wl-search/SKILL.md +151 -80
  211. package/templates/qoder/skills/wl-spec/SKILL.md +9 -7
  212. package/templates/qoder/skills/wl-status/SKILL.md +50 -18
  213. package/templates/qoder/skills/wl-task/SKILL.md +94 -12
  214. package/templates/qoder/skills/wl-test/SKILL.md +154 -45
  215. package/templates/qoder/templates/prd-full-template.md +7 -0
  216. package/templates/root/AGENTS.md +275 -237
  217. package/templates/root/requirements.txt +3 -0
  218. package/templates/root//344/275/277/347/224/250/350/257/264/346/230/216.md +3 -3
  219. package/templates/root//346/226/260/346/211/213/346/214/207/345/215/227.md +2 -2
  220. package/templates/qoder/hooks/inject-workflow-state.py +0 -169
  221. package/templates/qoder/scripts/__pycache__/check_mcp_launch.cpython-39.pyc +0 -0
  222. package/templates/qoder/scripts/__pycache__/install_qoderwork.cpython-39.pyc +0 -0
  223. package/templates/qoder/scripts/__pycache__/mcp_launcher.cpython-39.pyc +0 -0
  224. package/templates/qoder/scripts/__pycache__/platform_doctor.cpython-39.pyc +0 -0
  225. package/templates/qoder/scripts/check_carriers.py +0 -238
  226. package/templates/qoder/scripts/check_mcp.py +0 -298
  227. package/templates/qoder/scripts/check_mcp_launch.py +0 -183
  228. package/templates/qoder/scripts/check_qoderwork_consistency.py +0 -166
  229. package/templates/qoder/scripts/collect_prds.py +0 -31
  230. package/templates/qoder/scripts/common/mentions.py +0 -134
  231. package/templates/qoder/scripts/common/utf8.py +0 -38
  232. package/templates/qoder/scripts/extract_api_params.py +0 -246
  233. package/templates/qoder/scripts/extract_routes.py +0 -54
  234. package/templates/qoder/scripts/extract_routes_tree.py +0 -78
  235. package/templates/qoder/scripts/handoff.py +0 -22
  236. package/templates/qoder/scripts/init_developer.py +0 -76
  237. package/templates/qoder/scripts/kg_mcp_server.py +0 -801
  238. package/templates/qoder/scripts/kg_semantic.py +0 -150
  239. package/templates/qoder/scripts/mcp_launcher.py +0 -414
  240. package/templates/qoder/scripts/mysql_mcp_server.py +0 -396
  241. package/templates/qoder/scripts/parse_prds.py +0 -33
  242. package/templates/qoder/scripts/role.py +0 -51
  243. package/templates/qoder/scripts/sync_carriers.py +0 -259
  244. package/templates/qoder/scripts/task.py +0 -1261
  245. package/templates/qoder/scripts/workspace_init.py +0 -102
  246. package/templates/qoder/scripts/zentao_mcp_server.py +0 -424
  247. package/templates/qoder/skills/prompt-enrich/SKILL.md +0 -90
  248. /package/templates/qoder/scripts/{common → deployment}/__init__.py +0 -0
  249. /package/templates/qoder/{skills/prototype-generator/SKILL.md.zcode-79180-2af4721f-f9a6-412c-88db-c0af680d211b.tmp → scripts/domain/__init__.py} +0 -0
  250. /package/templates/qoder/scripts/{common → domain/kg/graph}/graph_traverse.py +0 -0
  251. /package/templates/qoder/scripts/{common → domain/kg/server}/repowiki.py +0 -0
  252. /package/templates/qoder/scripts/{common → foundation/io}/atomicio.py +0 -0
  253. /package/templates/qoder/scripts/{secure-ls.js → validation/test/secure-ls.js} +0 -0
@@ -1,259 +1,271 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- platform_doctor.py - 跨平台环境自诊断 (任何 OS 跑, 输出环境真相)
5
-
6
- 为什么需要它:
7
- MAC-VERIFY.md 是人工清单, mac 同事跑完如果失败, 反馈信息往往不够定位。
8
- 本脚本自动收集所有跨平台关键信息, 一次跑完输出结构化报告,
9
- 同事直接把输出贴回来即可 —— 无需懂代码。
10
-
11
- 它在任何 OS (Windows/macOS/Linux) 上行为一致, 显式报告:
12
- - 平台 + 架构
13
- - python/python3/node/git 是否可用 + 真实路径
14
- - 工作流引擎是否完整 (关键脚本在不在)
15
- - MCP 各组件就绪状态
16
- - 角色配置
17
- - 发现的问题 + 修复建议
18
-
19
- Usage:
20
- python3 .qoder/scripts/platform_doctor.py
21
- # mac 上: python3 platform_doctor.py (从包目录跑也行)
22
- Exit: 0 = 健康, 1 = 有问题
23
- """
24
- import json
25
- import os
26
- import platform
27
- import shutil
28
- import subprocess
29
- import sys
30
- from pathlib import Path
31
-
32
- if sys.platform == 'win32':
33
- try:
34
- sys.stdout.reconfigure(encoding='utf-8')
35
- except (AttributeError, IOError):
36
- pass
37
-
38
- # 定位仓库根 (和 mcp_launcher 同样的多级回退)
39
- HERE = Path(__file__).resolve().parent
40
- BASE = None
41
- for candidate in [HERE.parent.parent, HERE.parent, HERE]:
42
- if (candidate / '.qoder' / 'scripts').is_dir():
43
- BASE = candidate
44
- break
45
- if BASE is None:
46
- BASE = HERE.parent.parent # 最佳猜测
47
-
48
- report = {'platform': {}, 'tools': {}, 'engine': {}, 'mcp': {},
49
- 'role': {}, 'issues': [], 'verdict': 'UNKNOWN'}
50
-
51
-
52
- def add_issue(level, msg, fix=None):
53
- report['issues'].append({'level': level, 'msg': msg, 'fix': fix or ''})
54
-
55
-
56
- def which(cmd):
57
- """找命令路径, 返回字符串或 None。"""
58
- return shutil.which(cmd)
59
-
60
-
61
- def run(cmd, timeout=8):
62
- """跑命令, 返回 (rc, output)。"""
63
- try:
64
- r = subprocess.run(cmd, capture_output=True, text=True,
65
- encoding='utf-8', errors='replace', timeout=timeout)
66
- return r.returncode, (r.stdout or '').strip()
67
- except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
68
- return 1, ''
69
-
70
-
71
- # ============================================================
72
- # 1. 平台信息
73
- # ============================================================
74
- report['platform'] = {
75
- 'sys_platform': sys.platform,
76
- 'platform_system': platform.system(),
77
- 'machine': platform.machine(),
78
- 'python_version': sys.version.split()[0],
79
- 'python_executable': sys.executable,
80
- }
81
- plat_name = platform.system()
82
- is_mac = sys.platform == 'darwin'
83
- is_win = sys.platform == 'win32'
84
- print('【平台】 %s %s (sys.platform=%s)' % (
85
- plat_name, platform.machine(), sys.platform))
86
- print(' Python: %s @ %s' % (sys.version.split()[0], sys.executable))
87
-
88
- # ============================================================
89
- # 2. 工具探测 (python/python3/node/git/brew)
90
- # ============================================================
91
- print('\n【工具探测】')
92
- for tool in ['python', 'python3', 'node', 'npm', 'npx', 'git']:
93
- if is_mac and tool == 'python':
94
- # mac python 通常不存在, 这是正常的
95
- pass
96
- p = which(tool)
97
- ver = ''
98
- if p:
99
- if tool in ('python', 'python3'):
100
- rc, v = run([tool, '--version'])
101
- ver = v or '(版本未知)'
102
- elif tool in ('node',):
103
- rc, v = run([tool, '--version'])
104
- ver = v
105
- elif tool == 'git':
106
- rc, v = run([tool, '--version'])
107
- ver = v
108
- report['tools'][tool] = {'path': p, 'version': ver}
109
- status = '✓ %s' % ver if p else '✗ 未找到'
110
- print(' %-8s %s' % (tool, status))
111
-
112
- # 关键: python/python3 关系 (mac 验证核心)
113
- py = which('python')
114
- py3 = which('python3')
115
- if is_mac and not py and py3:
116
- print(' [mac 正常] python 不存在, python3 可用 (cli.js detectPyCmd 会选 python3)')
117
- elif not py and not py3:
118
- add_issue('CRITICAL', 'python python3 都没找到',
119
- 'mac: brew install python@3.12; win: 装 Python 勾 Add to PATH')
120
- elif not py3 and py:
121
- add_issue('WARN', '只有 python 没有 python3 (罕见, 一般不影响)')
122
-
123
- if is_mac:
124
- brew = which('brew')
125
- print(' brew: %s' % (brew or '✗ (装包用: https://brew.sh)'))
126
-
127
- # ============================================================
128
- # 3. 引擎完整性
129
- # ============================================================
130
- print('\n【工作流引擎】')
131
- scripts_dir = BASE / '.qoder' / 'scripts'
132
- key_scripts = [
133
- 'setup.py', 'kg.py', 'context_pack.py', 'search_index.py',
134
- 'mcp_launcher.py', 'install_qoderwork.py', 'role.py',
135
- 'common/pip_install.py', 'common/events.py', 'common/platform_guard.py',
136
- 'check_mcp.py', 'check_carriers.py',
137
- ]
138
- missing_scripts = []
139
- for s in key_scripts:
140
- exists = (scripts_dir / s).is_file()
141
- if not exists:
142
- missing_scripts.append(s)
143
- report['engine'][s] = exists
144
-
145
- if missing_scripts:
146
- add_issue('CRITICAL', '引擎脚本缺失: %s' % ', '.join(missing_scripts),
147
- '跑: npx @hupan56/wlkj update')
148
- print(' ✗ 缺失: %s' % ', '.join(missing_scripts))
149
- else:
150
- print(' ✓ %d 个关键脚本齐全' % len(key_scripts))
151
-
152
- # 引擎版本
153
- ver_file = BASE / '.qoder' / '.engine-version'
154
- if ver_file.is_file():
155
- ver = ver_file.read_text(encoding='utf-8').strip()
156
- report['engine']['version'] = ver
157
- print(' 引擎版本: %s' % ver)
158
-
159
- # ============================================================
160
- # 4. MCP 组件
161
- # ============================================================
162
- print('\n【MCP 组件】')
163
- # 4.1 mcp.json
164
- HOME = Path(os.environ.get('USERPROFILE') or os.path.expanduser('~'))
165
- mcp_file = HOME / '.qoderwork' / 'mcp.json'
166
- if mcp_file.is_file():
167
- try:
168
- cfg = json.loads(mcp_file.read_text(encoding='utf-8'))
169
- servers = list(cfg.get('mcpServers', {}).keys())
170
- report['mcp']['servers'] = servers
171
- print(' mcp.json: %d 个 server (%s)' % (len(servers), ', '.join(servers)))
172
- except (ValueError, OSError):
173
- add_issue('WARN', 'mcp.json 解析失败', '重跑 install_qoderwork.py --mcp-only')
174
- print(' mcp.json: 解析失败')
175
- else:
176
- add_issue('WARN', 'mcp.json 不存在 (QoderWork 未配 MCP)',
177
- '跑: python .qoder/scripts/install_qoderwork.py --mcp-only')
178
- print(' mcp.json: 不存在')
179
-
180
- # 4.2 .repo-root 锚点
181
- anchor = HOME / '.qoderwork' / '.repo-root'
182
- if anchor.is_file():
183
- root_val = anchor.read_text(encoding='utf-8').strip()
184
- is_correct = (Path(root_val) / '.qoder' / 'scripts').is_dir()
185
- report['mcp']['repo_root'] = root_val
186
- if is_correct:
187
- print(' .repo-root: ✓ 指向 %s' % root_val)
188
- else:
189
- add_issue('CRITICAL', '.repo-root 指向错误目录: %s' % root_val,
190
- '跑: python install_qoderwork.py --mcp-only (会用 PROJECT_ROOT 修复)')
191
- print(' .repo-root: ✗ 指向错误 %s' % root_val)
192
- else:
193
- add_issue('WARN', '.repo-root 锚点不存在',
194
- '跑: install_qoderwork.py --mcp-only')
195
- print(' .repo-root: 不存在')
196
-
197
- # 4.3 duckdb (kg MCP 依赖)
198
- try:
199
- import duckdb
200
- print(' duckdb: ✓ 已装 (kg MCP 可用)')
201
- report['mcp']['duckdb'] = True
202
- except ImportError:
203
- add_issue('CRITICAL', 'duckdb 未装 (kg MCP 会崩)',
204
- 'pip install duckdb 或 npx wlkj install-env')
205
- print(' duckdb: 未装')
206
-
207
- # ============================================================
208
- # 5. 角色配置
209
- # ============================================================
210
- print('\n【角色配置】')
211
- dev_file = BASE / '.qoder' / '.developer'
212
- if dev_file.is_file():
213
- lines = dev_file.read_text(encoding='utf-8').split('\n')
214
- name_l = next((l for l in lines if l.startswith('name=')), '')
215
- role_l = next((l for l in lines if l.startswith('role=')), '')
216
- name = name_l.split('=', 1)[1].strip() if name_l else '?'
217
- role = role_l.split('=', 1)[1].strip() if role_l else 'pm(默认)'
218
- report['role'] = {'name': name, 'role': role}
219
- print(' 开发者: %s' % name)
220
- print(' 角色: %s' % role)
221
- if not role_l:
222
- add_issue('INFO', '角色未显式设置 (默认 pm)',
223
- '重跑 init 选角色: npx wlkj init %s <pm|design|dev|test|admin>' % name)
224
- else:
225
- add_issue('CRITICAL', '.developer 不存在 (未初始化)',
226
- '跑: npx @hupan56/wlkj init <名字> <角色>')
227
- print(' 未初始化!')
228
-
229
- # ============================================================
230
- # 6. 总结
231
- # ============================================================
232
- criticals = [i for i in report['issues'] if i['level'] == 'CRITICAL']
233
- warns = [i for i in report['issues'] if i['level'] == 'WARN']
234
-
235
- print('\n' + '=' * 56)
236
- if criticals:
237
- print('发现 %d 个严重问题:' % len(criticals))
238
- for i in criticals:
239
- print(' 🔴 %s' % i['msg'])
240
- if i['fix']:
241
- print(' 修复: %s' % i['fix'])
242
- report['verdict'] = 'BROKEN'
243
- elif warns:
244
- print('发现 %d 个警告 (非阻塞, 但建议处理):' % len(warns))
245
- for i in warns:
246
- print(' 🟡 %s' % i['msg'])
247
- if i['fix']:
248
- print(' 建议: %s' % i['fix'])
249
- report['verdict'] = 'OK_WITH_WARNINGS'
250
- else:
251
- print(' 环境健康, 工作流可用。')
252
- report['verdict'] = 'HEALTHY'
253
- print('=' * 56)
254
-
255
- # 机器可读报告 (便于同事贴回来)
256
- print('\n--- 可粘贴报告 (JSON) ---')
257
- print(json.dumps(report, ensure_ascii=False, indent=2))
258
-
259
- sys.exit(1 if criticals else 0)
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
4
+ import os as _o, sys as _s
5
+ _f = _o.path.abspath(__file__)
6
+ for _ in range(10):
7
+ _f = _o.path.dirname(_f)
8
+ _cp = _o.path.join(_f, 'foundation')
9
+ if _o.path.isfile(_o.path.join(_cp, 'bootstrap.py')):
10
+ break
11
+ if _cp not in _s.path: _s.path.insert(0, _cp)
12
+ from bootstrap import setup; setup()
13
+ from foundation.core.paths import get_repo_root
14
+
15
+ """
16
+ platform_doctor.py - 跨平台环境自诊断 (任何 OS 跑, 输出环境真相)
17
+
18
+ 为什么需要它:
19
+ MAC-VERIFY.md 是人工清单, mac 同事跑完如果失败, 反馈信息往往不够定位。
20
+ 本脚本自动收集所有跨平台关键信息, 一次跑完输出结构化报告,
21
+ 同事直接把输出贴回来即可 —— 无需懂代码。
22
+
23
+ 它在任何 OS (Windows/macOS/Linux) 上行为一致, 显式报告:
24
+ - 平台 + 架构
25
+ - python/python3/node/git 是否可用 + 真实路径
26
+ - 工作流引擎是否完整 (关键脚本在不在)
27
+ - MCP 各组件就绪状态
28
+ - 角色配置
29
+ - 发现的问题 + 修复建议
30
+
31
+ Usage:
32
+ python3 .qoder/scripts/platform_doctor.py
33
+ # 或 mac 上: python3 platform_doctor.py (从包目录跑也行)
34
+ Exit: 0 = 健康, 1 = 有问题
35
+ """
36
+ import json
37
+ import os
38
+ import platform
39
+ import shutil
40
+ import subprocess
41
+ import sys
42
+ from pathlib import Path
43
+
44
+ if sys.platform == 'win32':
45
+ try:
46
+ sys.stdout.reconfigure(encoding='utf-8')
47
+ except (AttributeError, IOError):
48
+ pass
49
+
50
+ # 定位仓库根 (和 mcp_launcher 同样的多级回退)
51
+ HERE = Path(__file__).resolve().parent
52
+ BASE = None
53
+ for candidate in [HERE.parent.parent, HERE.parent, HERE]:
54
+ if (candidate / '.qoder' / 'scripts').is_dir():
55
+ BASE = candidate
56
+ break
57
+ if BASE is None:
58
+ BASE = get_repo_root()
59
+
60
+ report = {'platform': {}, 'tools': {}, 'engine': {}, 'mcp': {},
61
+ 'role': {}, 'issues': [], 'verdict': 'UNKNOWN'}
62
+
63
+
64
+ def add_issue(level, msg, fix=None):
65
+ report['issues'].append({'level': level, 'msg': msg, 'fix': fix or ''})
66
+
67
+
68
+ def which(cmd):
69
+ """找命令路径, 返回字符串或 None。"""
70
+ return shutil.which(cmd)
71
+
72
+
73
+ def run(cmd, timeout=8):
74
+ """跑命令, 返回 (rc, output)。"""
75
+ try:
76
+ r = subprocess.run(cmd, capture_output=True, text=True,
77
+ encoding='utf-8', errors='replace', timeout=timeout)
78
+ return r.returncode, (r.stdout or '').strip()
79
+ except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
80
+ return 1, ''
81
+
82
+
83
+ # ============================================================
84
+ # 1. 平台信息
85
+ # ============================================================
86
+ report['platform'] = {
87
+ 'sys_platform': sys.platform,
88
+ 'platform_system': platform.system(),
89
+ 'machine': platform.machine(),
90
+ 'python_version': sys.version.split()[0],
91
+ 'python_executable': sys.executable,
92
+ }
93
+ plat_name = platform.system()
94
+ is_mac = sys.platform == 'darwin'
95
+ is_win = sys.platform == 'win32'
96
+ print('【平台】 %s %s (sys.platform=%s)' % (
97
+ plat_name, platform.machine(), sys.platform))
98
+ print(' Python: %s @ %s' % (sys.version.split()[0], sys.executable))
99
+
100
+ # ============================================================
101
+ # 2. 工具探测 (python/python3/node/git/brew)
102
+ # ============================================================
103
+ print('\n【工具探测】')
104
+ for tool in ['python', 'python3', 'node', 'npm', 'npx', 'git']:
105
+ if is_mac and tool == 'python':
106
+ # mac python 通常不存在, 这是正常的
107
+ pass
108
+ p = which(tool)
109
+ ver = ''
110
+ if p:
111
+ if tool in ('python', 'python3'):
112
+ rc, v = run([tool, '--version'])
113
+ ver = v or '(版本未知)'
114
+ elif tool in ('node',):
115
+ rc, v = run([tool, '--version'])
116
+ ver = v
117
+ elif tool == 'git':
118
+ rc, v = run([tool, '--version'])
119
+ ver = v
120
+ report['tools'][tool] = {'path': p, 'version': ver}
121
+ status = ' %s' % ver if p else '✗ 未找到'
122
+ print(' %-8s %s' % (tool, status))
123
+
124
+ # 关键: python/python3 关系 (mac 验证核心)
125
+ py = which('python')
126
+ py3 = which('python3')
127
+ if is_mac and not py and py3:
128
+ print(' [mac 正常] python 不存在, python3 可用 (cli.js detectPyCmd 会选 python3)')
129
+ elif not py and not py3:
130
+ add_issue('CRITICAL', 'python 和 python3 都没找到',
131
+ 'mac: brew install python@3.12; win: 装 Python 勾 Add to PATH')
132
+ elif not py3 and py:
133
+ add_issue('WARN', '只有 python 没有 python3 (罕见, 一般不影响)')
134
+
135
+ if is_mac:
136
+ brew = which('brew')
137
+ print(' brew: %s' % (brew or '✗ (装包用: https://brew.sh)'))
138
+
139
+ # ============================================================
140
+ # 3. 引擎完整性
141
+ # ============================================================
142
+ print('\n【工作流引擎】')
143
+ scripts_dir = BASE / '.qoder' / 'scripts'
144
+ key_scripts = [
145
+ 'setup.py', 'kg.py', 'context_pack.py', 'search_index.py',
146
+ 'mcp_launcher.py', 'install_qoderwork.py', 'role.py',
147
+ 'common/pip_install.py', 'common/events.py', 'common/platform_guard.py',
148
+ 'check_mcp.py', 'check_carriers.py',
149
+ ]
150
+ missing_scripts = []
151
+ for s in key_scripts:
152
+ exists = (scripts_dir / s).is_file()
153
+ if not exists:
154
+ missing_scripts.append(s)
155
+ report['engine'][s] = exists
156
+
157
+ if missing_scripts:
158
+ add_issue('CRITICAL', '引擎脚本缺失: %s' % ', '.join(missing_scripts),
159
+ '跑: npx @hupan56/wlkj update')
160
+ print(' ✗ 缺失: %s' % ', '.join(missing_scripts))
161
+ else:
162
+ print(' %d 个关键脚本齐全' % len(key_scripts))
163
+
164
+ # 引擎版本
165
+ ver_file = BASE / '.qoder' / '.engine-version'
166
+ if ver_file.is_file():
167
+ ver = ver_file.read_text(encoding='utf-8').strip()
168
+ report['engine']['version'] = ver
169
+ print(' 引擎版本: %s' % ver)
170
+
171
+ # ============================================================
172
+ # 4. MCP 组件
173
+ # ============================================================
174
+ print('\n【MCP 组件】')
175
+ # 4.1 mcp.json
176
+ HOME = Path(os.environ.get('USERPROFILE') or os.path.expanduser('~'))
177
+ mcp_file = HOME / '.qoderwork' / 'mcp.json'
178
+ if mcp_file.is_file():
179
+ try:
180
+ cfg = json.loads(mcp_file.read_text(encoding='utf-8'))
181
+ servers = list(cfg.get('mcpServers', {}).keys())
182
+ report['mcp']['servers'] = servers
183
+ print(' mcp.json: %d 个 server (%s)' % (len(servers), ', '.join(servers)))
184
+ except (ValueError, OSError):
185
+ add_issue('WARN', 'mcp.json 解析失败', '重跑 install_qoderwork.py --mcp-only')
186
+ print(' mcp.json: 解析失败')
187
+ else:
188
+ add_issue('WARN', 'mcp.json 不存在 (QoderWork 未配 MCP)',
189
+ '跑: python .qoder/scripts/install_qoderwork.py --mcp-only')
190
+ print(' mcp.json: 不存在')
191
+
192
+ # 4.2 .repo-root 锚点
193
+ anchor = HOME / '.qoderwork' / '.repo-root'
194
+ if anchor.is_file():
195
+ root_val = anchor.read_text(encoding='utf-8').strip()
196
+ is_correct = (Path(root_val) / '.qoder' / 'scripts').is_dir()
197
+ report['mcp']['repo_root'] = root_val
198
+ if is_correct:
199
+ print(' .repo-root: ✓ 指向 %s' % root_val)
200
+ else:
201
+ add_issue('CRITICAL', '.repo-root 指向错误目录: %s' % root_val,
202
+ '跑: python install_qoderwork.py --mcp-only (会用 PROJECT_ROOT 修复)')
203
+ print(' .repo-root: 指向错误 %s' % root_val)
204
+ else:
205
+ add_issue('WARN', '.repo-root 锚点不存在',
206
+ '跑: install_qoderwork.py --mcp-only')
207
+ print(' .repo-root: 不存在')
208
+
209
+ # 4.3 duckdb (kg MCP 依赖)
210
+ try:
211
+ import duckdb
212
+ print(' duckdb: ✓ 已装 (kg MCP 可用)')
213
+ report['mcp']['duckdb'] = True
214
+ except ImportError:
215
+ add_issue('CRITICAL', 'duckdb 未装 (kg MCP 会崩)',
216
+ 'pip install duckdb npx wlkj install-env')
217
+ print(' duckdb: 未装')
218
+
219
+ # ============================================================
220
+ # 5. 角色配置
221
+ # ============================================================
222
+ print('\n【角色配置】')
223
+ dev_file = BASE / '.qoder' / '.developer'
224
+ if dev_file.is_file():
225
+ lines = dev_file.read_text(encoding='utf-8').split('\n')
226
+ name_l = next((l for l in lines if l.startswith('name=')), '')
227
+ role_l = next((l for l in lines if l.startswith('role=')), '')
228
+ name = name_l.split('=', 1)[1].strip() if name_l else '?'
229
+ role = role_l.split('=', 1)[1].strip() if role_l else 'pm(默认)'
230
+ report['role'] = {'name': name, 'role': role}
231
+ print(' 开发者: %s' % name)
232
+ print(' 角色: %s' % role)
233
+ if not role_l:
234
+ add_issue('INFO', '角色未显式设置 (默认 pm)',
235
+ '重跑 init 选角色: npx wlkj init %s <pm|design|dev|test|admin>' % name)
236
+ else:
237
+ add_issue('CRITICAL', '.developer 不存在 (未初始化)',
238
+ '跑: npx @hupan56/wlkj init <名字> <角色>')
239
+ print(' 未初始化!')
240
+
241
+ # ============================================================
242
+ # 6. 总结
243
+ # ============================================================
244
+ criticals = [i for i in report['issues'] if i['level'] == 'CRITICAL']
245
+ warns = [i for i in report['issues'] if i['level'] == 'WARN']
246
+
247
+ print('\n' + '=' * 56)
248
+ if criticals:
249
+ print('发现 %d 个严重问题:' % len(criticals))
250
+ for i in criticals:
251
+ print(' 🔴 %s' % i['msg'])
252
+ if i['fix']:
253
+ print(' 修复: %s' % i['fix'])
254
+ report['verdict'] = 'BROKEN'
255
+ elif warns:
256
+ print('发现 %d 个警告 (非阻塞, 但建议处理):' % len(warns))
257
+ for i in warns:
258
+ print(' 🟡 %s' % i['msg'])
259
+ if i['fix']:
260
+ print(' 建议: %s' % i['fix'])
261
+ report['verdict'] = 'OK_WITH_WARNINGS'
262
+ else:
263
+ print('✓ 环境健康, 工作流可用。')
264
+ report['verdict'] = 'HEALTHY'
265
+ print('=' * 56)
266
+
267
+ # 机器可读报告 (便于同事贴回来)
268
+ print('\n--- 可粘贴报告 (JSON) ---')
269
+ print(json.dumps(report, ensure_ascii=False, indent=2))
270
+
271
+ sys.exit(1 if criticals else 0)
@@ -1,4 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
+ # repo_root.py — 自适应定位 QODER 流水线仓库根(QoderWork 桌面端专用)。
3
+ #
4
+ # ⚠️ 本文件被 install_qoderwork.py 复制到 ~/.qoderwork/repo_root.py, 在那里它
5
+ # 独立运行 (不依赖仓库内的任何模块)。所以这里**零 import 依赖**——
6
+ # 不能 from bootstrap import (那是仓库内的模块, 定位器不能依赖被定位的东西)。
7
+ # bootstrap 的 sys.path 自举作用对其他被复制脚本有效, 对本定位器是死循环。
8
+
2
9
  """
3
10
  repo_root.py — 自适应定位 QODER 流水线仓库根(QoderWork 桌面端专用)。
4
11
 
@@ -86,8 +93,8 @@ def main():
86
93
  elif args and args[0] == '--test':
87
94
  # 自检: 验证关键文件存在
88
95
  checks = [
89
- ('kg.py', '.qoder/scripts/kg.py'),
90
- ('eval_prd.py', '.qoder/scripts/eval_prd.py'),
96
+ ('kg.py', '.qoder/scripts/domain/kg/kg.py'),
97
+ ('eval_prd.py', '.qoder/scripts/validation/metrics/eval_prd.py'),
91
98
  ('quick模板', '.qoder/templates/prd-quick-template.md'),
92
99
  ('full模板', '.qoder/templates/prd-full-template.md'),
93
100
  ('kg.duckdb', 'data/index/kg.duckdb'),