@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.
Files changed (237) hide show
  1. package/bin/cli.js +1435 -1373
  2. package/package.json +1 -1
  3. package/templates/qoder/commands/optional/wl-insight.md +6 -4
  4. package/templates/qoder/commands/optional/wl-report.md +20 -39
  5. package/templates/qoder/commands/optional/wl-status.md +4 -4
  6. package/templates/qoder/commands/wl-code.md +2 -2
  7. package/templates/qoder/commands/wl-design.md +5 -5
  8. package/templates/qoder/commands/wl-init.md +3 -3
  9. package/templates/qoder/commands/wl-prd.md +26 -13
  10. package/templates/qoder/commands/wl-req.md +3 -3
  11. package/templates/qoder/commands/wl-search.md +78 -47
  12. package/templates/qoder/commands/wl-task.md +343 -40
  13. package/templates/qoder/commands/wl-test.md +10 -10
  14. package/templates/qoder/config.yaml +35 -13
  15. package/templates/qoder/hooks/post-tool-use.py +181 -0
  16. package/templates/qoder/hooks/session-start.py +82 -1
  17. package/templates/qoder/hooks/stop-eval.py +207 -0
  18. package/templates/qoder/hooks/user-prompt-submit.py +139 -0
  19. package/templates/qoder/rules/wl-pipeline.md +70 -8
  20. package/templates/qoder/scripts/README.md +78 -115
  21. package/templates/qoder/scripts/capability/__init__.py +26 -0
  22. package/templates/qoder/scripts/capability/__main__.py +72 -0
  23. package/templates/qoder/scripts/capability/adapters/__init__.py +29 -0
  24. package/templates/qoder/scripts/capability/adapters/cli.py +316 -0
  25. package/templates/qoder/scripts/capability/adapters/mcp.py +334 -0
  26. package/templates/qoder/scripts/capability/adapters/qw.py +271 -0
  27. package/templates/qoder/scripts/capability/caps/__init__.py +27 -0
  28. package/templates/qoder/scripts/capability/caps/context.py +36 -0
  29. package/templates/qoder/scripts/capability/caps/cron.py +50 -0
  30. package/templates/qoder/scripts/capability/caps/identity.py +43 -0
  31. package/templates/qoder/scripts/capability/caps/memory.py +71 -0
  32. package/templates/qoder/scripts/capability/caps/notify.py +41 -0
  33. package/templates/qoder/scripts/capability/caps/present.py +48 -0
  34. package/templates/qoder/scripts/capability/caps/repo.py +31 -0
  35. package/templates/qoder/scripts/capability/caps/sandbox.py +43 -0
  36. package/templates/qoder/scripts/capability/chain.py +92 -0
  37. package/templates/qoder/scripts/capability/memory_chain.py +41 -0
  38. package/templates/qoder/scripts/capability/registry.py +246 -0
  39. package/templates/qoder/scripts/capability/registry_mcp.py +250 -0
  40. package/templates/qoder/scripts/capability/smoke_test.py +211 -0
  41. package/templates/qoder/scripts/capability/smoke_test_report.json +94 -0
  42. package/templates/qoder/scripts/{report → deployment/setup}/__init__.py +11 -11
  43. package/templates/qoder/scripts/{setup → deployment/setup}/carriers.py +33 -26
  44. package/templates/qoder/scripts/deployment/setup/carriers_verify.py +148 -0
  45. package/templates/qoder/scripts/{setup → deployment/setup}/init_doctor.py +40 -16
  46. package/templates/qoder/scripts/{setup → deployment/setup}/install_qoderwork.py +20 -12
  47. package/templates/qoder/scripts/{setup → deployment/setup}/platform_doctor.py +8 -2
  48. package/templates/qoder/scripts/{setup → deployment/setup}/repo_root.py +113 -112
  49. package/templates/qoder/scripts/{setup → deployment/setup}/setup.py +31 -11
  50. package/templates/qoder/scripts/{setup → deployment/setup}/setup_lanhu.py +13 -7
  51. package/templates/qoder/scripts/domain/__init__.py +0 -0
  52. package/templates/qoder/scripts/domain/design/__init__.py +0 -0
  53. package/templates/qoder/scripts/{report → domain/design}/fill_prototype.py +12 -6
  54. package/templates/qoder/scripts/{report → domain/design}/gen_design_doc.py +8 -2
  55. package/templates/qoder/scripts/{setup → domain/kg}/__init__.py +11 -11
  56. package/templates/qoder/scripts/domain/kg/build/__init__.py +0 -0
  57. package/templates/qoder/scripts/{kg → domain/kg/build}/build_entity_registry.py +7 -2
  58. package/templates/qoder/scripts/{kg → domain/kg/build}/build_relations.py +7 -2
  59. package/templates/qoder/scripts/{kg → domain/kg/build}/build_style_index.py +13 -7
  60. package/templates/qoder/scripts/{kg → domain/kg/build}/build_workflows.py +7 -2
  61. package/templates/qoder/scripts/{kg → domain/kg/build}/kg_build.py +76 -9
  62. package/templates/qoder/scripts/{kg → domain/kg/build}/kg_build_db.py +7 -2
  63. package/templates/qoder/scripts/{kg → domain/kg/build}/kg_incremental.py +11 -6
  64. package/templates/qoder/scripts/{report → domain/kg/build}/learn_aggregate.py +9 -4
  65. package/templates/qoder/scripts/domain/kg/extract/__init__.py +0 -0
  66. package/templates/qoder/scripts/{common → domain/kg/extract}/extract.py +430 -419
  67. package/templates/qoder/scripts/{common → domain/kg/extract}/test_extract.py +115 -115
  68. package/templates/qoder/scripts/{common → domain/kg/extract}/ts_extract.py +614 -536
  69. package/templates/qoder/scripts/domain/kg/graph/__init__.py +0 -0
  70. package/templates/qoder/scripts/{kg → domain/kg/graph}/kg_link_db.py +7 -2
  71. package/templates/qoder/scripts/domain/kg/graph/kg_semantic.py +683 -0
  72. package/templates/qoder/scripts/{kg → domain/kg}/kg.py +263 -30
  73. package/templates/qoder/scripts/{common → domain/kg}/kg_capabilities.py +182 -182
  74. package/templates/qoder/scripts/domain/kg/search/__init__.py +0 -0
  75. package/templates/qoder/scripts/{kg → domain/kg/search}/context_pack.py +30 -9
  76. package/templates/qoder/scripts/{kg → domain/kg/search}/enrich_prompt.py +10 -4
  77. package/templates/qoder/scripts/{kg → domain/kg/search}/prefetch.py +33 -8
  78. package/templates/qoder/scripts/{common → domain/kg/search}/search_engine.py +207 -205
  79. package/templates/qoder/scripts/{kg → domain/kg/search}/search_index.py +143 -77
  80. package/templates/qoder/scripts/domain/kg/server/__init__.py +0 -0
  81. package/templates/qoder/scripts/domain/kg/server/kgd.py +549 -0
  82. package/templates/qoder/scripts/domain/kg/server/perf_bench.py +197 -0
  83. package/templates/qoder/scripts/domain/kg/storage/__init__.py +0 -0
  84. package/templates/qoder/scripts/{kg → domain/kg/storage}/kg_duckdb.py +38 -14
  85. package/templates/qoder/scripts/domain/learning/__init__.py +0 -0
  86. package/templates/qoder/scripts/{report → domain/learning}/learn.py +8 -3
  87. package/templates/qoder/scripts/{mcp → domain/report}/__init__.py +11 -11
  88. package/templates/qoder/scripts/{report → domain/report}/add_session.py +9 -3
  89. package/templates/qoder/scripts/{report → domain/report}/export.py +10 -5
  90. package/templates/qoder/scripts/{report → domain/report}/report.py +9 -4
  91. package/templates/qoder/scripts/domain/report/report_snapshot.py +261 -0
  92. package/templates/qoder/scripts/{report → domain/report}/role.py +10 -4
  93. package/templates/qoder/scripts/{report → domain/report}/status.py +112 -9
  94. package/templates/qoder/scripts/domain/report/status_snapshot.py +191 -0
  95. package/templates/qoder/scripts/domain/requirement/__init__.py +0 -0
  96. package/templates/qoder/scripts/{report → domain/requirement}/archive_prd.py +8 -2
  97. package/templates/qoder/scripts/{report → domain/requirement}/req.py +228 -222
  98. package/templates/qoder/scripts/{kg → domain/task}/__init__.py +11 -11
  99. package/templates/qoder/scripts/{task → domain/task}/git_sync.py +40 -21
  100. package/templates/qoder/scripts/{task → domain/task}/syncgate.py +13 -8
  101. package/templates/qoder/scripts/{task → domain/task}/task.py +13 -5
  102. package/templates/qoder/scripts/{task → domain/task}/task_lifecycle.py +606 -596
  103. package/templates/qoder/scripts/{task → domain/task}/task_query.py +162 -161
  104. package/templates/qoder/scripts/{task → domain/task}/task_relations.py +425 -424
  105. package/templates/qoder/scripts/{task → domain/task}/team_sync.py +9 -4
  106. package/templates/qoder/scripts/domain/task/zentao_sync.py +370 -0
  107. package/templates/qoder/scripts/foundation/__init__.py +0 -0
  108. package/templates/qoder/scripts/{common → foundation}/bootstrap.py +10 -10
  109. package/templates/qoder/scripts/foundation/core/__init__.py +0 -0
  110. package/templates/qoder/scripts/{common → foundation/core}/cmd_registry.py +1 -1
  111. package/templates/qoder/scripts/{common → foundation/core}/config.py +1 -1
  112. package/templates/qoder/scripts/{common → foundation/core}/paths.py +706 -586
  113. package/templates/qoder/scripts/foundation/data/__init__.py +0 -0
  114. package/templates/qoder/scripts/{common → foundation/data}/contract.py +2 -2
  115. package/templates/qoder/scripts/{common → foundation/data}/events.py +2 -2
  116. package/templates/qoder/scripts/{common → foundation/data}/result.py +1 -1
  117. package/templates/qoder/scripts/{common → foundation/data}/task_utils.py +427 -404
  118. package/templates/qoder/scripts/foundation/identity/__init__.py +0 -0
  119. package/templates/qoder/scripts/{common → foundation/identity}/check_publish.py +103 -98
  120. package/templates/qoder/scripts/{common → foundation/identity}/developer.py +239 -239
  121. package/templates/qoder/scripts/{common → foundation/identity}/guard.py +2 -2
  122. package/templates/qoder/scripts/{common → foundation/identity}/identity.py +14 -10
  123. package/templates/qoder/scripts/{common → foundation/identity}/roles.py +1 -1
  124. package/templates/qoder/scripts/foundation/integrations/__init__.py +0 -0
  125. package/templates/qoder/scripts/{common → foundation/integrations}/active_task.py +30 -15
  126. package/templates/qoder/scripts/{common → foundation/integrations}/feishu.py +2 -2
  127. package/templates/qoder/scripts/{common → foundation/integrations}/terms.py +3 -3
  128. package/templates/qoder/scripts/foundation/integrations/zentao_client.py +220 -0
  129. package/templates/qoder/scripts/foundation/io/__init__.py +0 -0
  130. package/templates/qoder/scripts/{common → foundation/io}/filelock.py +1 -1
  131. package/templates/qoder/scripts/{common → foundation/io}/reqid.py +1 -1
  132. package/templates/qoder/scripts/foundation/protocol/__init__.py +0 -0
  133. package/templates/qoder/scripts/foundation/protocol/duckdb_conn.py +39 -0
  134. package/templates/qoder/scripts/{common → foundation/protocol}/mcp_base.py +1 -1
  135. package/templates/qoder/scripts/foundation/utils/__init__.py +0 -0
  136. package/templates/qoder/scripts/{common → foundation/utils}/eval_api.py +12 -1
  137. package/templates/qoder/scripts/{common → foundation/utils}/pip_install.py +23 -6
  138. package/templates/qoder/scripts/{common → foundation/utils}/platform_guard.py +1 -1
  139. package/templates/qoder/scripts/orchestration/__init__.py +0 -0
  140. package/templates/qoder/scripts/orchestration/wlkj.py +185 -0
  141. package/templates/qoder/scripts/protocol/__init__.py +0 -0
  142. package/templates/qoder/scripts/protocol/browser/README.md +207 -0
  143. package/templates/qoder/scripts/protocol/browser/SKILL.md +265 -0
  144. package/templates/qoder/scripts/protocol/browser/config.env +9 -0
  145. package/templates/qoder/scripts/protocol/browser/references/cdp-api.md +110 -0
  146. package/templates/qoder/scripts/protocol/browser/references/migration-2.5.3.md +72 -0
  147. package/templates/qoder/scripts/protocol/browser/references/site-patterns/.gitkeep +0 -0
  148. package/templates/qoder/scripts/protocol/browser/scripts/browser-discovery.mjs +138 -0
  149. package/templates/qoder/scripts/protocol/browser/scripts/cdp-proxy.mjs +672 -0
  150. package/templates/qoder/scripts/protocol/browser/scripts/check-deps.mjs +206 -0
  151. package/templates/qoder/scripts/protocol/browser/scripts/find-url.mjs +253 -0
  152. package/templates/qoder/scripts/protocol/browser/scripts/match-site.mjs +46 -0
  153. package/templates/qoder/scripts/protocol/browser/templates/config.env.template +9 -0
  154. package/templates/qoder/scripts/protocol/mcp/__init__.py +11 -0
  155. package/templates/qoder/scripts/protocol/mcp/kg_mcp_server.py +478 -0
  156. package/templates/qoder/scripts/{mcp → protocol/mcp}/lanhu_stdio_wrapper.py +11 -5
  157. package/templates/qoder/scripts/{mcp → protocol/mcp}/mcp_doctor.py +47 -14
  158. package/templates/qoder/scripts/protocol/mcp/mcp_launcher.py +600 -0
  159. package/templates/qoder/scripts/{mcp → protocol/mcp}/mysql_mcp_server.py +181 -67
  160. package/templates/qoder/scripts/protocol/mcp/zentao_mcp_server.py +1920 -0
  161. package/templates/qoder/scripts/protocol/transports/__init__.py +56 -0
  162. package/templates/qoder/scripts/protocol/transports/base.py +87 -0
  163. package/templates/qoder/scripts/protocol/transports/cli.py +132 -0
  164. package/templates/qoder/scripts/protocol/transports/http.py +141 -0
  165. package/templates/qoder/scripts/protocol/transports/stdio.py +293 -0
  166. package/templates/qoder/scripts/run_weekly_update.bat +27 -18
  167. package/templates/qoder/scripts/run_weekly_update.sh +22 -13
  168. package/templates/qoder/scripts/validation/__init__.py +0 -0
  169. package/templates/qoder/scripts/validation/eval/__init__.py +0 -0
  170. package/templates/qoder/scripts/validation/eval/perf-report-2026-06-24.md +139 -0
  171. package/templates/qoder/scripts/validation/eval/qwork_harness.py +617 -0
  172. package/templates/qoder/scripts/validation/eval/report-commands.md +220 -0
  173. package/templates/qoder/scripts/validation/eval/transcript_timing.py +386 -0
  174. package/templates/qoder/scripts/validation/metrics/__init__.py +0 -0
  175. package/templates/qoder/scripts/{report → validation/metrics}/eval_prd.py +17 -10
  176. package/templates/qoder/scripts/validation/metrics/usability_score.py +750 -0
  177. package/templates/qoder/scripts/validation/test/__init__.py +11 -0
  178. package/templates/qoder/scripts/validation/test/assertion_gen.py +551 -0
  179. package/templates/qoder/scripts/{test → validation/test}/autotest.py +64 -4
  180. package/templates/qoder/scripts/{common → validation/test}/autotest_auth.py +1 -1
  181. package/templates/qoder/scripts/{test → validation/test}/autotest_batch.py +16 -3
  182. package/templates/qoder/scripts/{test → validation/test}/autotest_data.py +17 -12
  183. package/templates/qoder/scripts/validation/test/autotest_opencli.py +646 -0
  184. package/templates/qoder/scripts/{test → validation/test}/autotest_run.py +17 -3
  185. package/templates/qoder/scripts/validation/test/autotest_webaccess.py +571 -0
  186. package/templates/qoder/scripts/{test → validation/test}/benchmark.py +12 -6
  187. package/templates/qoder/scripts/{test → validation/test}/kg_auto_login.py +8 -2
  188. package/templates/qoder/scripts/{test → validation/test}/kg_test_runner.py +7 -2
  189. package/templates/qoder/scripts/{test → validation/test}/page_probe.py +8 -3
  190. package/templates/qoder/scripts/validation/test/smoke_all_commands.py +170 -0
  191. package/templates/qoder/settings.json +30 -0
  192. package/templates/qoder/skills/design-import/SKILL.md +22 -13
  193. package/templates/qoder/skills/design-review/SKILL.md +19 -10
  194. package/templates/qoder/skills/prd-generator/SKILL.md +22 -18
  195. package/templates/qoder/skills/prd-review/SKILL.md +6 -4
  196. package/templates/qoder/skills/prototype-generator/SKILL.md +63 -14
  197. package/templates/qoder/skills/spec-coder/SKILL.md +22 -13
  198. package/templates/qoder/skills/spec-generator/SKILL.md +22 -10
  199. package/templates/qoder/skills/test-generator/SKILL.md +7 -5
  200. package/templates/qoder/skills/wl-code/SKILL.md +23 -11
  201. package/templates/qoder/skills/wl-commit/SKILL.md +9 -8
  202. package/templates/qoder/skills/wl-design/SKILL.md +5 -3
  203. package/templates/qoder/skills/wl-init/SKILL.md +6 -6
  204. package/templates/qoder/skills/wl-insight/SKILL.md +23 -10
  205. package/templates/qoder/skills/wl-prd-full/SKILL.md +57 -6
  206. package/templates/qoder/skills/wl-prd-quick/SKILL.md +3 -3
  207. package/templates/qoder/skills/wl-prd-review/SKILL.md +16 -4
  208. package/templates/qoder/skills/wl-report/SKILL.md +25 -23
  209. package/templates/qoder/skills/wl-search/SKILL.md +149 -78
  210. package/templates/qoder/skills/wl-spec/SKILL.md +7 -5
  211. package/templates/qoder/skills/wl-status/SKILL.md +48 -16
  212. package/templates/qoder/skills/wl-task/SKILL.md +92 -10
  213. package/templates/qoder/skills/wl-test/SKILL.md +75 -29
  214. package/templates/qoder/templates/prd-full-template.md +7 -0
  215. package/templates/root/AGENTS.md +275 -236
  216. package/templates/root/requirements.txt +3 -0
  217. package/templates/root//344/275/277/347/224/250/350/257/264/346/230/216.md +3 -3
  218. package/templates/root//346/226/260/346/211/213/346/214/207/345/215/227.md +2 -2
  219. package/templates/.qoder/.runtime/ctx-cache-5660152f1d6dd819.md +0 -23
  220. package/templates/.qoder/.runtime/ctx-cache-afdce0dac06b25b0.md +0 -23
  221. package/templates/.qoder/.runtime/search-cache-eae7644e7b122f35.txt +0 -1
  222. package/templates/.qoder/learning/eval-history.jsonl +0 -28
  223. package/templates/data/index/wiki-index.json +0 -8
  224. package/templates/qoder/nul +0 -4
  225. package/templates/qoder/scripts/kg/extract.py +0 -398
  226. package/templates/qoder/scripts/kg/kg_semantic.py +0 -156
  227. package/templates/qoder/scripts/mcp/kg_mcp_server.py +0 -606
  228. package/templates/qoder/scripts/mcp/mcp_launcher.py +0 -442
  229. package/templates/qoder/scripts/mcp/zentao_mcp_server.py +0 -384
  230. package/templates/qoder/scripts/task/__init__.py +0 -11
  231. package/templates/qoder/scripts/test/__init__.py +0 -11
  232. package/templates/qoder/scripts/wlkj.py +0 -116
  233. /package/templates/qoder/scripts/{common → deployment}/__init__.py +0 -0
  234. /package/templates/qoder/scripts/{common → domain/kg/graph}/graph_traverse.py +0 -0
  235. /package/templates/qoder/scripts/{common → domain/kg/server}/repowiki.py +0 -0
  236. /package/templates/qoder/scripts/{common → foundation/io}/atomicio.py +0 -0
  237. /package/templates/qoder/scripts/{test → validation/test}/secure-ls.js +0 -0
@@ -2,9 +2,15 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
4
4
  import os as _o, sys as _s
5
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
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
6
11
  if _cp not in _s.path: _s.path.insert(0, _cp)
7
12
  from bootstrap import setup; setup()
13
+ from foundation.core.paths import get_repo_root
8
14
 
9
15
  """
10
16
  QODER Fill Prototype - 用真实数据自动预填原型模板 (80%完成)
@@ -38,9 +44,9 @@ except (AttributeError, TypeError, OSError, IOError):
38
44
  pass
39
45
 
40
46
  sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
41
- from common.terms import expand_chinese_query, get_platform_map
47
+ from foundation.integrations.terms import expand_chinese_query, get_platform_map
42
48
 
43
- BASE = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
49
+ BASE = get_repo_root()
44
50
  INDEX_DIR = os.path.join(BASE, 'data', 'index')
45
51
  TEMPLATE_DIR = os.path.join(BASE, '.qoder', 'templates')
46
52
 
@@ -48,7 +54,7 @@ TEMPLATE_DIR = os.path.join(BASE, '.qoder', 'templates')
48
54
  def load_index(filename):
49
55
  """Load index from DuckDB (preferred) or JSON fallback."""
50
56
  try:
51
- from search_index import _duckdb_load
57
+ from domain.kg.search.search_index import _duckdb_load
52
58
  result = _duckdb_load(filename)
53
59
  if result is not None:
54
60
  return result
@@ -458,8 +464,8 @@ def main():
458
464
 
459
465
  # 平台守卫: 注意 --platform 有 default='web', 不能查 args.platform (永远非 None),
460
466
  # 必须查 sys.argv 是否【显式】传了 --platform。否则违规调用会被默认值绕过。
461
- from common.platform_guard import assert_platform_selected
462
- assert_platform_selected(skill='wl-prd-full')
467
+ from foundation.utils.platform_guard import assert_platform_selected
468
+ assert_platform_selected(skill='wl-prd')
463
469
 
464
470
  query = args.query.strip()
465
471
  if not query:
@@ -2,9 +2,15 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
4
4
  import os as _o, sys as _s
5
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
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
6
11
  if _cp not in _s.path: _s.path.insert(0, _cp)
7
12
  from bootstrap import setup; setup()
13
+ from foundation.core.paths import get_repo_root
8
14
 
9
15
  """
10
16
  gen_design_doc.py - 自动生成 DESIGN.md (给 AI 的设计系统说明书)
@@ -37,7 +43,7 @@ except (AttributeError, TypeError, OSError, IOError):
37
43
  except Exception:
38
44
  pass
39
45
 
40
- BASE = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
46
+ BASE = get_repo_root()
41
47
  INDEX_DIR = os.path.join(BASE, 'data', 'index')
42
48
  OUTPUT_DIR = os.path.join(BASE, 'data', 'design')
43
49
 
@@ -1,11 +1,11 @@
1
- # 子包初始化: 注入 scripts/根 + 所有子包到 sys.path
2
- # 让跨包 import (旧式不带前缀) 仍可用, 兼容现有代码
3
- import os as _os, sys as _sys
4
- _root = _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__)))
5
- if _root not in _sys.path:
6
- _sys.path.insert(0, _root)
7
- # 注入所有子包目录 (兼容旧式 import xxx)
8
- for _sub in ('kg', 'build', 'test', 'setup', 'io'):
9
- _subdir = _os.path.join(_root, _sub)
10
- if _os.path.isdir(_subdir) and _subdir not in _sys.path:
11
- _sys.path.insert(0, _subdir)
1
+ # 子包初始化: 注入 scripts/根 + 所有子包到 sys.path
2
+ # 让跨包 import (旧式不带前缀) 仍可用, 兼容现有代码
3
+ import os as _os, sys as _sys
4
+ _root = _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__)))
5
+ if _root not in _sys.path:
6
+ _sys.path.insert(0, _root)
7
+ # 注入所有子包目录 (兼容旧式 import xxx)
8
+ for _sub in ('kg', 'build', 'test', 'setup', 'io'):
9
+ _subdir = _os.path.join(_root, _sub)
10
+ if _os.path.isdir(_subdir) and _subdir not in _sys.path:
11
+ _sys.path.insert(0, _subdir)
@@ -3,7 +3,12 @@
3
3
 
4
4
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
5
5
  import os as _o, sys as _s
6
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
6
+ _f = _o.path.abspath(__file__)
7
+ for _ in range(10):
8
+ _f = _o.path.dirname(_f)
9
+ _cp = _o.path.join(_f, 'foundation')
10
+ if _o.path.isfile(_o.path.join(_cp, 'bootstrap.py')):
11
+ break
7
12
  if _cp not in _s.path: _s.path.insert(0, _cp)
8
13
  from bootstrap import setup; setup()
9
14
 
@@ -37,7 +42,7 @@ from datetime import datetime
37
42
  # 路径自适应 (和兄弟脚本一致)
38
43
  THIS_DIR = os.path.dirname(os.path.abspath(__file__))
39
44
  sys.path.insert(0, os.path.join(THIS_DIR, '..'))
40
- from common.paths import DATA_INDEX_DIR, BUILD_CACHE_DIR
45
+ from foundation.core.paths import DATA_INDEX_DIR, BUILD_CACHE_DIR
41
46
 
42
47
 
43
48
  def load(name):
@@ -3,7 +3,12 @@
3
3
 
4
4
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
5
5
  import os as _o, sys as _s
6
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
6
+ _f = _o.path.abspath(__file__)
7
+ for _ in range(10):
8
+ _f = _o.path.dirname(_f)
9
+ _cp = _o.path.join(_f, 'foundation')
10
+ if _o.path.isfile(_o.path.join(_cp, 'bootstrap.py')):
11
+ break
7
12
  if _cp not in _s.path: _s.path.insert(0, _cp)
8
13
  from bootstrap import setup; setup()
9
14
 
@@ -34,7 +39,7 @@ from datetime import datetime
34
39
 
35
40
  THIS_DIR = os.path.dirname(os.path.abspath(__file__))
36
41
  sys.path.insert(0, os.path.join(THIS_DIR, '..'))
37
- from common.paths import DATA_INDEX_DIR, BUILD_CACHE_DIR
42
+ from foundation.core.paths import DATA_INDEX_DIR, BUILD_CACHE_DIR
38
43
 
39
44
 
40
45
  def load(name):
@@ -2,9 +2,15 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
4
4
  import os as _o, sys as _s
5
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
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
6
11
  if _cp not in _s.path: _s.path.insert(0, _cp)
7
12
  from bootstrap import setup; setup()
13
+ from foundation.core.paths import get_repo_root
8
14
 
9
15
  """
10
16
  Build style index from Vue/HTML files.
@@ -14,7 +20,7 @@ Usage:
14
20
  python build_style_index.py
15
21
  """
16
22
  import os, json, re, sys
17
- from common.paths import BUILD_CACHE_DIR
23
+ from foundation.core.paths import BUILD_CACHE_DIR
18
24
  from datetime import datetime
19
25
 
20
26
  # UTF-8 stdio (防御性: stdout 被捕获时不崩溃)
@@ -26,7 +32,7 @@ except (AttributeError, TypeError, OSError, IOError):
26
32
  except Exception:
27
33
  pass
28
34
 
29
- BASE = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
35
+ BASE = get_repo_root()
30
36
  DATA_CODE = os.path.join(BASE, 'data', 'code')
31
37
  INDEX_DIR = os.path.join(BASE, 'data', 'index')
32
38
  STYLE_INDEX_PATH = os.path.join(BUILD_CACHE_DIR, 'ui-style.json')
@@ -39,16 +45,16 @@ TEST_ASSERTIONS_PATH = os.path.join(BUILD_CACHE_DIR, 'test-assertions.json')
39
45
  # E2: prefer tree-sitter extraction (31%->70%+ coverage); fallback to regex
40
46
  sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
41
47
  try:
42
- from common.ts_extract import ts_build_api_fn_table as build_api_fn_table
43
- from common.ts_extract import ts_trace_clicks as trace_clicks
48
+ from domain.kg.extract.ts_extract import ts_build_api_fn_table as build_api_fn_table
49
+ from domain.kg.extract.ts_extract import ts_trace_clicks as trace_clicks
44
50
  _EXTRACT_ENGINE = 'tree-sitter'
45
51
  except Exception:
46
- from common.extract import build_api_fn_table, trace_clicks
52
+ from domain.kg.extract.extract import build_api_fn_table, trace_clicks
47
53
  _EXTRACT_ENGINE = 'regex (tree-sitter not installed)'
48
54
  # test_extract 是可选增强层 (test-assertions 索引), 模块可能未提供。
49
55
  # 用 lazy import + 降级: 没有就跳过 test-assertions, 不阻断 ui-style 主线构建。
50
56
  try:
51
- from common.test_extract import extract_test_assertions # noqa: E402
57
+ from domain.kg.extract.test_extract import extract_test_assertions # noqa: E402
52
58
  _HAS_TEST_EXTRACT = True
53
59
  except ImportError:
54
60
  extract_test_assertions = None
@@ -3,7 +3,12 @@
3
3
 
4
4
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
5
5
  import os as _o, sys as _s
6
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
6
+ _f = _o.path.abspath(__file__)
7
+ for _ in range(10):
8
+ _f = _o.path.dirname(_f)
9
+ _cp = _o.path.join(_f, 'foundation')
10
+ if _o.path.isfile(_o.path.join(_cp, 'bootstrap.py')):
11
+ break
7
12
  if _cp not in _s.path: _s.path.insert(0, _cp)
8
13
  from bootstrap import setup; setup()
9
14
 
@@ -28,7 +33,7 @@ from datetime import datetime
28
33
 
29
34
  THIS_DIR = os.path.dirname(os.path.abspath(__file__))
30
35
  sys.path.insert(0, os.path.join(THIS_DIR, '..'))
31
- from common.paths import DATA_INDEX_DIR, BUILD_CACHE_DIR
36
+ from foundation.core.paths import DATA_INDEX_DIR, BUILD_CACHE_DIR
32
37
 
33
38
 
34
39
  def load(name):
@@ -1,7 +1,12 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
3
3
  import os as _o, sys as _s
4
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
4
+ _f = _o.path.abspath(__file__)
5
+ for _ in range(10):
6
+ _f = _o.path.dirname(_f)
7
+ _cp = _o.path.join(_f, 'foundation')
8
+ if _o.path.isfile(_o.path.join(_cp, 'bootstrap.py')):
9
+ break
5
10
  if _cp not in _s.path: _s.path.insert(0, _cp)
6
11
  from bootstrap import setup; setup()
7
12
 
@@ -25,8 +30,8 @@ import time
25
30
  SCRIPTS = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 子包→scripts/根
26
31
  sys.path.insert(0, SCRIPTS)
27
32
 
28
- from common.paths import DATA_INDEX_DIR, PROJECT_ROOT
29
- from kg_duckdb import get_db, init_schema, _batch_insert
33
+ from foundation.core.paths import DATA_INDEX_DIR, PROJECT_ROOT
34
+ from domain.kg.storage.kg_duckdb import get_db, init_schema, _batch_insert
30
35
 
31
36
  CODE_DIR = str(PROJECT_ROOT / 'data' / 'code')
32
37
  DB_PATH = str(DATA_INDEX_DIR / 'kg.duckdb')
@@ -316,7 +321,7 @@ def extract_traces(cfg, api_table):
316
321
  if not cfg.get('has_vue') or not api_table:
317
322
  return traces
318
323
  try:
319
- from common.ts_extract import ts_trace_clicks
324
+ from domain.kg.extract.ts_extract import ts_trace_clicks
320
325
  except Exception:
321
326
  return traces
322
327
 
@@ -341,7 +346,7 @@ def extract_tests(cfg):
341
346
  """Extract test assertions for one project."""
342
347
  results = []
343
348
  try:
344
- from common.test_extract import extract_test_assertions
349
+ from domain.kg.extract.test_extract import extract_test_assertions
345
350
  results = extract_test_assertions(cfg['path'])
346
351
  except Exception:
347
352
  pass
@@ -354,7 +359,7 @@ def extract_layout_fingerprint(cfg):
354
359
  layout_file = cfg.get('layout_file')
355
360
  if layout_file and layout_file.endswith('preferences.ts'):
356
361
  try:
357
- from build_style_index import extract_layout_fingerprint as _elf
362
+ from domain.kg.build.build_style_index import extract_layout_fingerprint as _elf
358
363
  fp = _elf(cfg['path'])
359
364
  except Exception:
360
365
  pass
@@ -443,7 +448,7 @@ def build_all():
443
448
  for cfg in projects:
444
449
  for api_dir in cfg.get('api_dirs', []):
445
450
  try:
446
- from common.ts_extract import ts_build_api_fn_table
451
+ from domain.kg.extract.ts_extract import ts_build_api_fn_table
447
452
  t = ts_build_api_fn_table(api_dir)
448
453
  api_table.update(t)
449
454
  except Exception:
@@ -486,10 +491,21 @@ def build_all():
486
491
  stats['edges'] = con.execute("SELECT COUNT(*) FROM edges").fetchone()[0]
487
492
 
488
493
  # 7. Workflows
489
- print(' [7/7] workflows...')
494
+ print(' [7/8] workflows...')
490
495
  wf_count = _build_workflows(con, all_traces)
491
496
  stats['workflows'] = wf_count
492
497
 
498
+ # 8. Import PRD + Wiki (from git_sync's JSON output)
499
+ print(' [8/8] PRD + Wiki...')
500
+ try:
501
+ prd_count, wiki_count = _import_prds_and_wiki(con)
502
+ stats['prds'] = prd_count
503
+ stats['wiki'] = wiki_count
504
+ except Exception as e:
505
+ print(' PRD/Wiki SKIP: %s' % str(e)[:60])
506
+ stats['prds'] = 0
507
+ stats['wiki'] = 0
508
+
493
509
  con.execute("INSERT OR REPLACE INTO build_meta VALUES ('version', '2.0')")
494
510
  con.execute("INSERT OR REPLACE INTO build_meta VALUES ('built_at', ?)", [str(int(time.time()))])
495
511
  con.close()
@@ -532,9 +548,14 @@ def _build_entities_and_edges(con, modules, api_idx, traces, tests):
532
548
  handler = t.get('handler', '')
533
549
  vue_short = vue.split('/views/')[-1] if '/views/' in vue else vue.split('/pages/')[-1] if '/pages/' in vue else vue
534
550
  eid = 'B:%s:%s' % (vue_short, handler)
535
- entity_rows.append((eid, 'BUTTON', handler, '',
551
+ # cn: 用按钮中文文本 (清洗 icon 字体 &#x...; 和噪音), 提升语义检索召回
552
+ btn_cn = re.sub(r'&#x[0-9a-fA-F]+;', '', t.get('button', '')).strip(' >\t\r\n')
553
+ entity_rows.append((eid, 'BUTTON', handler, btn_cn,
536
554
  json.dumps({'button_text': t.get('button', ''),
537
555
  'confidence': t.get('confidence', '')}, ensure_ascii=False)))
556
+ # 别名: 按钮中文名 → entity (让 multi_hop 传中文名能找到按钮)
557
+ if btn_cn:
558
+ alias_rows.append((btn_cn.lower(), eid))
538
559
  ep = t.get('endpoint')
539
560
  if ep and ep != 'None':
540
561
  edge_rows.append((eid, 'E:%s' % ep, 'clicks', 0,
@@ -608,6 +629,52 @@ def _build_workflows(con, traces):
608
629
  return len(wf_rows)
609
630
 
610
631
 
632
+ def _import_prds_and_wiki(con):
633
+ """Import PRD index + Wiki from git_sync's JSON output into DuckDB.
634
+
635
+ Reads _build_cache/prd-index.json and data/index/wiki-index.json.
636
+ Returns (prd_count, wiki_count).
637
+ """
638
+ INDEX = str(DATA_INDEX_DIR)
639
+ prd_count = 0
640
+ wiki_count = 0
641
+
642
+ def _load_json(name):
643
+ for d in [os.path.join(INDEX, '_build_cache'), INDEX]:
644
+ p = os.path.join(d, name)
645
+ if os.path.isfile(p):
646
+ return json.load(open(p, encoding='utf-8'))
647
+ return None
648
+
649
+ # PRD
650
+ prds = _load_json('prd-index.json')
651
+ if prds:
652
+ con.execute("DELETE FROM prds")
653
+ rows = [(f, info.get('title', ''),
654
+ json.dumps(info.get('keywords', []), ensure_ascii=False),
655
+ json.dumps(info.get('features', []), ensure_ascii=False),
656
+ json.dumps(info.get('cn_terms', []), ensure_ascii=False))
657
+ for f, info in prds.items()]
658
+ if rows:
659
+ _batch_insert(con, 'prds', rows, ignore=True)
660
+ prd_count = len(rows)
661
+
662
+ # Wiki
663
+ wiki = _load_json('wiki-index.json')
664
+ if wiki and isinstance(wiki, dict):
665
+ con.execute("DELETE FROM wiki")
666
+ rows = []
667
+ for kw, entries in (wiki.get('index', {}) or {}).items():
668
+ for e in (entries if isinstance(entries, list) else []):
669
+ rows.append((kw, e.get('project', ''), e.get('title', ''),
670
+ e.get('md_path', ''), e.get('description', '')))
671
+ if rows:
672
+ _batch_insert(con, 'wiki', rows)
673
+ wiki_count = len(rows)
674
+
675
+ return prd_count, wiki_count
676
+
677
+
611
678
  if __name__ == '__main__':
612
679
  print('=== kg_build.py: auto-discover → DuckDB (no JSON, no hardcode) ===')
613
680
  stats = build_all()
@@ -2,7 +2,12 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
4
4
  import os as _o, sys as _s
5
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
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
6
11
  if _cp not in _s.path: _s.path.insert(0, _cp)
7
12
  from bootstrap import setup; setup()
8
13
 
@@ -49,7 +54,7 @@ import pymysql
49
54
  SCRIPTS = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 子包→scripts/根
50
55
  sys.path.insert(0, SCRIPTS)
51
56
 
52
- from common.paths import DATA_INDEX_DIR
57
+ from foundation.core.paths import DATA_INDEX_DIR
53
58
 
54
59
  # MySQL 配置 (复用 mysql_mcp_server 的环境变量)
55
60
  MYSQL_HOST = os.environ.get('MYSQL_HOST', '10.54.6.9')
@@ -1,7 +1,12 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
3
3
  import os as _o, sys as _s
4
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
4
+ _f = _o.path.abspath(__file__)
5
+ for _ in range(10):
6
+ _f = _o.path.dirname(_f)
7
+ _cp = _o.path.join(_f, 'foundation')
8
+ if _o.path.isfile(_o.path.join(_cp, 'bootstrap.py')):
9
+ break
5
10
  if _cp not in _s.path: _s.path.insert(0, _cp)
6
11
  from bootstrap import setup; setup()
7
12
 
@@ -27,11 +32,11 @@ import sys
27
32
  SCRIPTS = os.path.join(os.path.dirname(os.path.abspath(__file__)))
28
33
  sys.path.insert(0, SCRIPTS)
29
34
 
30
- from common.paths import DATA_INDEX_DIR, PROJECT_ROOT
31
- from kg_duckdb import get_db, init_schema, upsert_entity, upsert_alias, upsert_edge, delete_edges_from
32
- from common.ts_extract import ts_build_api_fn_table, ts_trace_clicks
33
- from common.extract import build_api_fn_table
34
- from common.test_extract import extract_test_assertions
35
+ from foundation.core.paths import DATA_INDEX_DIR, PROJECT_ROOT
36
+ from domain.kg.storage.kg_duckdb import get_db, init_schema, upsert_entity, upsert_alias, upsert_edge, delete_edges_from
37
+ from domain.kg.extract.ts_extract import ts_build_api_fn_table, ts_trace_clicks
38
+ from domain.kg.extract.extract import build_api_fn_table
39
+ from domain.kg.extract.test_extract import extract_test_assertions
35
40
 
36
41
  CODE_DIR = str(PROJECT_ROOT / 'data' / 'code')
37
42
  INDEX_DIR = str(DATA_INDEX_DIR)
@@ -3,7 +3,12 @@
3
3
 
4
4
  # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
5
5
  import os as _o, sys as _s
6
- _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
6
+ _f = _o.path.abspath(__file__)
7
+ for _ in range(10):
8
+ _f = _o.path.dirname(_f)
9
+ _cp = _o.path.join(_f, 'foundation')
10
+ if _o.path.isfile(_o.path.join(_cp, 'bootstrap.py')):
11
+ break
7
12
  if _cp not in _s.path: _s.path.insert(0, _cp)
8
13
  from bootstrap import setup; setup()
9
14
 
@@ -31,8 +36,8 @@ from datetime import datetime
31
36
  SCRIPTS = os.path.dirname(os.path.abspath(__file__))
32
37
  sys.path.insert(0, SCRIPTS)
33
38
 
34
- from common.paths import MEMBERS_DIR
35
- from kg.kg_duckdb import get_db, init_schema # v3.0: kg_duckdb 已迁入 kg/ 子包
39
+ from foundation.core.paths import MEMBERS_DIR
40
+ from domain.kg.storage.kg_duckdb import get_db, init_schema # v3.0: kg_duckdb 已迁入 kg/ 子包
36
41
 
37
42
  BUILD_META_KEY = 'learning_last_aggregate'
38
43
 
@@ -155,7 +160,7 @@ def _refresh_stats(con):
155
160
  事件→列映射来自 common/events.py (SSOT)。新增埋点只要在 events.py 注册,
156
161
  这里自动生效, 不用改 SQL (修旧版硬编码漂移 bug)。
157
162
  """
158
- from common.events import event_to_sql_filter
163
+ from foundation.data.events import event_to_sql_filter
159
164
  con.execute("DELETE FROM learning_stats")
160
165
  # 列名 = events.py 的 stat 值; 动态拼 FILTER 子句
161
166
  cols = event_to_sql_filter() # {stat_column: event}