@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,119 +1,131 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- lanhu_stdio_wrapper.py - 蓝湖 MCP STDIO 启动包装(角色隔离 + QoderWork 自动开关)
5
-
6
- 被谁调用:
7
- QoderWork ~/.qoderwork/mcp.json 的 lanhu.command 拉起本脚本。
8
- QoderWork 管本进程的生死 ( QoderWork 自动拉起, 关 QoderWork 自动杀)
9
-
10
- 做什么:
11
- 1. 定位仓库根
12
- 2. .qoder/.developer 当前角色 (UI设计师/PM/开发...)
13
- 3. 读 workspace/members/{角色}/.secrets/lanhu.env 该角色的蓝湖 cookie
14
- 4. 注入环境变量 (LANHU_COOKIE + MCP_TRANSPORT=stdio + LANHU_USER_NAME)
15
- 5. os.execv() 拉起 lanhu_mcp_server.py (用 venv 的 3.10+ python)
16
-
17
- 为什么用 wrapper 而不是直接在 mcp.json 写 cookie:
18
- 蓝湖权限按角色分 (UI 能改稿, PM/开发只读)。
19
- cookie 必须按角色隔离, .developer 时跟着换。
20
- wrapper 每次启动读当前角色 用对应 cookie 权限正确。
21
- cookie 不进 mcp.json (那是机器级全局, 不按人), 仍按角色存 .secrets/。
22
-
23
- 为什么用 os.execv 而非 subprocess:
24
- execv lanhu server 直接替换 wrapper 进程。
25
- QoderWork 杀的就是 lanhu server 本身, 不留孤儿 wrapper 进程。
26
-
27
- 跨平台:
28
- 纯 Python, os.execv + venv python 路径跨平台 (win Scripts/python.exe, mac bin/python)。
29
- """
30
-
31
- import os
32
- import sys
33
- from pathlib import Path
34
-
35
- try:
36
- sys.stderr.reconfigure(encoding='utf-8', errors='replace')
37
- except (AttributeError, TypeError, OSError):
38
- pass
39
-
40
- # 定位仓库根: 本文件在 <repo>/.qoder/scripts/ 上三级
41
- SCRIPT_DIR = Path(__file__).resolve().parent
42
- BASE = SCRIPT_DIR.parent.parent # repo root
43
-
44
-
45
- def _find_repo_root():
46
- """定位仓库根。本文件在 .qoder/scripts/, 上三级即根。
47
- 兜底: 上溯找 .qoder/ 目录。"""
48
- if (BASE / '.qoder').is_dir():
49
- return BASE
50
- # 兜底: 上溯 10 级找 .qoder/
51
- cur = SCRIPT_DIR
52
- for _ in range(10):
53
- if (cur / '.qoder').is_dir():
54
- return cur
55
- parent = cur.parent
56
- if parent == cur:
57
- break
58
- cur = parent
59
- return BASE # 找不到回退默认
60
-
61
-
62
- def main():
63
- repo = _find_repo_root()
64
-
65
- # 复用 setup_lanhu.py 的角色探测 + cookie 读取 (单一事实源)
66
- sys.path.insert(0, str(repo / '.qoder' / 'scripts'))
67
- try:
68
- from setup_lanhu import (_current_developer, lanhu_env_file,
69
- _read_env_cookie, _venv_python,
70
- LANHU_VENV, LANHU_SERVER_SCRIPT, COOKIE_PLACEHOLDER)
71
- except ImportError as e:
72
- sys.stderr.write(f'[lanhu-wrapper] 无法导入 setup_lanhu: {e}\n')
73
- sys.stderr.write(f'[lanhu-wrapper] 检查 {repo}/.qoder/scripts/setup_lanhu.py 是否存在\n')
74
- sys.exit(1)
75
-
76
- # 1. 当前角色
77
- dev = _current_developer()
78
- if not dev:
79
- sys.stderr.write('[lanhu-wrapper] 未初始化开发者 (.qoder/.developer 不存在)。\n')
80
- sys.stderr.write(' 跑 /wl-init python .qoder/scripts/setup.py 初始化。\n')
81
- sys.exit(1)
82
-
83
- # 2. 该角色的 cookie
84
- cookie = _read_env_cookie(dev)
85
- if not cookie or cookie == COOKIE_PLACEHOLDER:
86
- env_file = lanhu_env_file(dev)
87
- sys.stderr.write(f'[lanhu-wrapper] 角色 {dev} 的蓝湖 cookie 未配置 (占位/缺失)。\n')
88
- sys.stderr.write(f' 编辑 {env_file}, 把 {COOKIE_PLACEHOLDER} 换成真 cookie。\n')
89
- sys.stderr.write(' 获取: lanhuapp.com 登录 → F12 → Network → Cookie 头整行复制\n')
90
- sys.stderr.write(' (蓝湖工具将不可用, 但工作流其他功能不受影响)\n')
91
- sys.exit(1)
92
-
93
- # 3. venv python (lanhu 依赖要求 3.10+)
94
- venv_py = _venv_python(LANHU_VENV)
95
- if not venv_py.is_file():
96
- sys.stderr.write(f'[lanhu-wrapper] 蓝湖 venv 不存在: {venv_py}\n')
97
- sys.stderr.write(' 跑 python .qoder/scripts/setup_lanhu.py 安装蓝湖依赖\n')
98
- sys.exit(1)
99
-
100
- if not LANHU_SERVER_SCRIPT.is_file():
101
- sys.stderr.write(f'[lanhu-wrapper] 蓝湖服务脚本不存在: {LANHU_SERVER_SCRIPT}\n')
102
- sys.stderr.write(' python .qoder/scripts/setup_lanhu.py clone 蓝湖源码\n')
103
- sys.exit(1)
104
-
105
- # 4. 注入环境变量 (角色隔离的核心: cookie + 用户名都是当前角色的)
106
- os.environ['LANHU_COOKIE'] = cookie
107
- os.environ['MCP_TRANSPORT'] = 'stdio'
108
- os.environ['LANHU_USER_NAME'] = dev
109
- os.environ['LANHU_USER_ROLE'] = 'Developer'
110
-
111
- # 调试日志打到 stderr (MCP stdio 协议用 stdout, 不能污染)
112
- sys.stderr.write(f'[lanhu-wrapper] 启动蓝湖 MCP (STDIO, 角色: {dev})\n')
113
-
114
- # 5. execv 拉起 lanhu server (接管进程, QoderWork 直接管它生死)
115
- os.execv(str(venv_py), [str(venv_py), str(LANHU_SERVER_SCRIPT)])
116
-
117
-
118
- if __name__ == '__main__':
119
- main()
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
+ lanhu_stdio_wrapper.py - 蓝湖 MCP STDIO 启动包装(角色隔离 + QoderWork 自动开关)
17
+
18
+ 被谁调用:
19
+ QoderWork ~/.qoderwork/mcp.json 的 lanhu.command 拉起本脚本。
20
+ QoderWork 管本进程的生死 (开 QoderWork 自动拉起, QoderWork 自动杀)。
21
+
22
+ 做什么:
23
+ 1. 定位仓库根
24
+ 2. .qoder/.developer 当前角色 (UI设计师/PM/开发...)
25
+ 3. workspace/members/{角色}/.private/secrets/lanhu.env 该角色的蓝湖 cookie
26
+ 4. 注入环境变量 (LANHU_COOKIE + MCP_TRANSPORT=stdio + LANHU_USER_NAME)
27
+ 5. os.execv() 拉起 lanhu_mcp_server.py (用 venv 的 3.10+ python)
28
+
29
+ 为什么用 wrapper 而不是直接在 mcp.json 写 cookie:
30
+ 蓝湖权限按角色分 (UI 能改稿, PM/开发只读)。
31
+ cookie 必须按角色隔离, 换 .developer 时跟着换。
32
+ wrapper 每次启动读当前角色 → 用对应 cookie → 权限正确。
33
+ cookie 不进 mcp.json (那是机器级全局, 不按人), 仍按角色存 .private/secrets/。
34
+
35
+ 为什么用 os.execv 而非 subprocess:
36
+ execv 让 lanhu server 直接替换 wrapper 进程。
37
+ QoderWork 杀的就是 lanhu server 本身, 不留孤儿 wrapper 进程。
38
+
39
+ 跨平台:
40
+ Python, os.execv + venv python 路径跨平台 (win Scripts/python.exe, mac bin/python)。
41
+ """
42
+
43
+ import os
44
+ import sys
45
+ from pathlib import Path
46
+
47
+ try:
48
+ sys.stderr.reconfigure(encoding='utf-8', errors='replace')
49
+ except (AttributeError, TypeError, OSError):
50
+ pass
51
+
52
+ # 定位仓库根: 本文件在 <repo>/.qoder/scripts/ → 上三级
53
+ SCRIPT_DIR = Path(__file__).resolve().parent
54
+ BASE = get_repo_root()
55
+
56
+
57
+ def _find_repo_root():
58
+ """定位仓库根。本文件在 .qoder/scripts/, 上三级即根。
59
+ 兜底: 上溯找 .qoder/ 目录。"""
60
+ if (BASE / '.qoder').is_dir():
61
+ return BASE
62
+ # 兜底: 上溯 10 级找 .qoder/
63
+ cur = SCRIPT_DIR
64
+ for _ in range(10):
65
+ if (cur / '.qoder').is_dir():
66
+ return cur
67
+ parent = cur.parent
68
+ if parent == cur:
69
+ break
70
+ cur = parent
71
+ return BASE # 找不到回退默认
72
+
73
+
74
+ def main():
75
+ repo = _find_repo_root()
76
+
77
+ # 复用 setup_lanhu.py 的角色探测 + cookie 读取 (单一事实源)
78
+ sys.path.insert(0, str(repo / '.qoder' / 'scripts'))
79
+ try:
80
+ from setup_lanhu import (_current_developer, lanhu_env_file,
81
+ _read_env_cookie, _venv_python,
82
+ LANHU_VENV, LANHU_SERVER_SCRIPT, COOKIE_PLACEHOLDER)
83
+ except ImportError as e:
84
+ sys.stderr.write(f'[lanhu-wrapper] 无法导入 setup_lanhu: {e}\n')
85
+ sys.stderr.write(f'[lanhu-wrapper] 检查 {repo}/.qoder/scripts/setup_lanhu.py 是否存在\n')
86
+ sys.exit(1)
87
+
88
+ # 1. 当前角色
89
+ dev = _current_developer()
90
+ if not dev:
91
+ sys.stderr.write('[lanhu-wrapper] 未初始化开发者 (.qoder/.developer 不存在)。\n')
92
+ sys.stderr.write(' 跑 /wl-init 或 npx @hupan56/wlkj init <你的名字> 初始化。\n')
93
+ sys.exit(1)
94
+
95
+ # 2. 该角色的 cookie
96
+ cookie = _read_env_cookie(dev)
97
+ if not cookie or cookie == COOKIE_PLACEHOLDER:
98
+ env_file = lanhu_env_file(dev)
99
+ sys.stderr.write(f'[lanhu-wrapper] 角色 {dev} 的蓝湖 cookie 未配置 (占位/缺失)。\n')
100
+ sys.stderr.write(f' 编辑 {env_file}, 把 {COOKIE_PLACEHOLDER} 换成真 cookie。\n')
101
+ sys.stderr.write(' 获取: lanhuapp.com 登录 → F12 → Network → Cookie 头整行复制\n')
102
+ sys.stderr.write(' (蓝湖工具将不可用, 但工作流其他功能不受影响)\n')
103
+ sys.exit(1)
104
+
105
+ # 3. venv python (lanhu 依赖要求 3.10+)
106
+ venv_py = _venv_python(LANHU_VENV)
107
+ if not venv_py.is_file():
108
+ sys.stderr.write(f'[lanhu-wrapper] 蓝湖 venv 不存在: {venv_py}\n')
109
+ sys.stderr.write(' python .qoder/scripts/setup_lanhu.py 安装蓝湖依赖\n')
110
+ sys.exit(1)
111
+
112
+ if not LANHU_SERVER_SCRIPT.is_file():
113
+ sys.stderr.write(f'[lanhu-wrapper] 蓝湖服务脚本不存在: {LANHU_SERVER_SCRIPT}\n')
114
+ sys.stderr.write(' 跑 python .qoder/scripts/setup_lanhu.py clone 蓝湖源码\n')
115
+ sys.exit(1)
116
+
117
+ # 4. 注入环境变量 (角色隔离的核心: cookie + 用户名都是当前角色的)
118
+ os.environ['LANHU_COOKIE'] = cookie
119
+ os.environ['MCP_TRANSPORT'] = 'stdio'
120
+ os.environ['LANHU_USER_NAME'] = dev
121
+ os.environ['LANHU_USER_ROLE'] = 'Developer'
122
+
123
+ # 调试日志打到 stderr (MCP stdio 协议用 stdout, 不能污染)
124
+ sys.stderr.write(f'[lanhu-wrapper] 启动蓝湖 MCP (STDIO, 角色: {dev})\n')
125
+
126
+ # 5. execv 拉起 lanhu server (接管进程, QoderWork 直接管它生死)
127
+ os.execv(str(venv_py), [str(venv_py), str(LANHU_SERVER_SCRIPT)])
128
+
129
+
130
+ if __name__ == '__main__':
131
+ main()