@hupan56/wlkj 2.7.11 → 3.0.0

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 (152) hide show
  1. package/bin/cli.js +375 -78
  2. package/package.json +29 -29
  3. package/templates/.qoder/.runtime/ctx-cache-5660152f1d6dd819.md +23 -0
  4. package/templates/.qoder/.runtime/ctx-cache-afdce0dac06b25b0.md +23 -0
  5. package/templates/.qoder/.runtime/search-cache-eae7644e7b122f35.txt +1 -0
  6. package/templates/.qoder/learning/eval-history.jsonl +28 -0
  7. package/templates/data/index/wiki-index.json +8 -0
  8. package/templates/qoder/agents/insight-planning.md +1 -1
  9. package/templates/qoder/agents/insight-research.md +28 -15
  10. package/templates/qoder/commands/optional/wl-insight.md +159 -161
  11. package/templates/qoder/commands/optional/wl-report.md +4 -4
  12. package/templates/qoder/commands/optional/wl-status.md +2 -2
  13. package/templates/qoder/commands/wl-code.md +2 -2
  14. package/templates/qoder/commands/wl-design.md +2 -2
  15. package/templates/qoder/commands/wl-init.md +3 -3
  16. package/templates/qoder/commands/wl-prd.md +2 -2
  17. package/templates/qoder/commands/wl-req.md +43 -0
  18. package/templates/qoder/commands/wl-search.md +8 -8
  19. package/templates/qoder/commands/wl-task.md +17 -17
  20. package/templates/qoder/commands/wl-test.md +41 -15
  21. package/templates/qoder/config.yaml +17 -1
  22. package/templates/qoder/hooks/session-start.py +12 -22
  23. package/templates/qoder/nul +4 -0
  24. package/templates/qoder/rules/wl-pipeline.md +22 -48
  25. package/templates/qoder/scripts/README.md +139 -0
  26. package/templates/qoder/scripts/common/autotest_auth.py +109 -0
  27. package/templates/qoder/scripts/common/bootstrap.py +145 -0
  28. package/templates/qoder/scripts/common/check_publish.py +98 -0
  29. package/templates/qoder/scripts/common/cmd_registry.py +112 -0
  30. package/templates/qoder/scripts/common/config.py +187 -0
  31. package/templates/qoder/scripts/common/contract.py +317 -0
  32. package/templates/qoder/scripts/common/developer.py +2 -1
  33. package/templates/qoder/scripts/common/feishu.py +10 -9
  34. package/templates/qoder/scripts/common/guard.py +159 -0
  35. package/templates/qoder/scripts/common/identity.py +121 -2
  36. package/templates/qoder/scripts/common/kg_capabilities.py +182 -0
  37. package/templates/qoder/scripts/common/mcp_base.py +268 -0
  38. package/templates/qoder/scripts/common/paths.py +187 -1
  39. package/templates/qoder/scripts/common/result.py +223 -0
  40. package/templates/qoder/scripts/common/roles.py +60 -0
  41. package/templates/qoder/scripts/common/task_utils.py +21 -9
  42. package/templates/qoder/scripts/common/test_extract.py +115 -0
  43. package/templates/qoder/scripts/kg/__init__.py +11 -0
  44. package/templates/qoder/scripts/kg/build_entity_registry.py +196 -0
  45. package/templates/qoder/scripts/kg/build_relations.py +127 -0
  46. package/templates/qoder/scripts/{build_style_index.py → kg/build_style_index.py} +39 -10
  47. package/templates/qoder/scripts/kg/build_workflows.py +144 -0
  48. package/templates/qoder/scripts/{context_pack.py → kg/context_pack.py} +18 -11
  49. package/templates/qoder/scripts/{enrich_prompt.py → kg/enrich_prompt.py} +232 -226
  50. package/templates/qoder/scripts/{extract_api_params.py → kg/extract.py} +398 -246
  51. package/templates/qoder/scripts/{kg.py → kg/kg.py} +638 -708
  52. package/templates/qoder/scripts/{kg_build.py → kg/kg_build.py} +618 -612
  53. package/templates/qoder/scripts/{kg_build_db.py → kg/kg_build_db.py} +333 -327
  54. package/templates/qoder/scripts/{kg_duckdb.py → kg/kg_duckdb.py} +38 -37
  55. package/templates/qoder/scripts/{kg_incremental.py → kg/kg_incremental.py} +420 -393
  56. package/templates/qoder/scripts/{kg_link_db.py → kg/kg_link_db.py} +230 -224
  57. package/templates/qoder/scripts/{kg_semantic.py → kg/kg_semantic.py} +156 -150
  58. package/templates/qoder/scripts/kg/prefetch.py +359 -0
  59. package/templates/qoder/scripts/{search_index.py → kg/search_index.py} +70 -14
  60. package/templates/qoder/scripts/mcp/__init__.py +11 -0
  61. package/templates/qoder/scripts/{kg_mcp_server.py → mcp/kg_mcp_server.py} +77 -272
  62. package/templates/qoder/scripts/{lanhu_stdio_wrapper.py → mcp/lanhu_stdio_wrapper.py} +125 -119
  63. package/templates/qoder/scripts/{check_mcp.py → mcp/mcp_doctor.py} +515 -298
  64. package/templates/qoder/scripts/{mcp_launcher.py → mcp/mcp_launcher.py} +442 -414
  65. package/templates/qoder/scripts/{mysql_mcp_server.py → mcp/mysql_mcp_server.py} +347 -396
  66. package/templates/qoder/scripts/{zentao_mcp_server.py → mcp/zentao_mcp_server.py} +384 -424
  67. package/templates/qoder/scripts/report/__init__.py +11 -0
  68. package/templates/qoder/scripts/{add_session.py → report/add_session.py} +250 -244
  69. package/templates/qoder/scripts/{archive_prd.py → report/archive_prd.py} +383 -377
  70. package/templates/qoder/scripts/{eval_prd.py → report/eval_prd.py} +73 -11
  71. package/templates/qoder/scripts/{export.py → report/export.py} +63 -0
  72. package/templates/qoder/scripts/{fill_prototype.py → report/fill_prototype.py} +6 -0
  73. package/templates/qoder/scripts/{gen_design_doc.py → report/gen_design_doc.py} +400 -394
  74. package/templates/qoder/scripts/{learn.py → report/learn.py} +152 -146
  75. package/templates/qoder/scripts/{learn_aggregate.py → report/learn_aggregate.py} +207 -201
  76. package/templates/qoder/scripts/{report.py → report/report.py} +287 -281
  77. package/templates/qoder/scripts/report/req.py +222 -0
  78. package/templates/qoder/scripts/report/role.py +33 -0
  79. package/templates/qoder/scripts/{status.py → report/status.py} +634 -628
  80. package/templates/qoder/scripts/setup/__init__.py +11 -0
  81. package/templates/qoder/scripts/setup/carriers.py +662 -0
  82. package/templates/qoder/scripts/{init_doctor.py → setup/init_doctor.py} +63 -26
  83. package/templates/qoder/scripts/{install_qoderwork.py → setup/install_qoderwork.py} +36 -26
  84. package/templates/qoder/scripts/{platform_doctor.py → setup/platform_doctor.py} +265 -259
  85. package/templates/qoder/scripts/{repo_root.py → setup/repo_root.py} +112 -106
  86. package/templates/qoder/scripts/{setup.py → setup/setup.py} +147 -0
  87. package/templates/qoder/scripts/{setup_lanhu.py → setup/setup_lanhu.py} +973 -963
  88. package/templates/qoder/scripts/task/__init__.py +11 -0
  89. package/templates/qoder/scripts/{git_sync.py → task/git_sync.py} +52 -31
  90. package/templates/qoder/scripts/{syncgate.py → task/syncgate.py} +6 -0
  91. package/templates/qoder/scripts/task/task.py +221 -0
  92. package/templates/qoder/scripts/task/task_lifecycle.py +596 -0
  93. package/templates/qoder/scripts/task/task_query.py +161 -0
  94. package/templates/qoder/scripts/task/task_relations.py +424 -0
  95. package/templates/qoder/scripts/{team_sync.py → task/team_sync.py} +93 -20
  96. package/templates/qoder/scripts/test/__init__.py +11 -0
  97. package/templates/qoder/scripts/{autotest.py → test/autotest.py} +1174 -1751
  98. package/templates/qoder/scripts/{autotest_batch.py → test/autotest_batch.py} +242 -224
  99. package/templates/qoder/scripts/test/autotest_data.py +675 -0
  100. package/templates/qoder/scripts/{autotest_run.py → test/autotest_run.py} +309 -297
  101. package/templates/qoder/scripts/{benchmark.py → test/benchmark.py} +6 -0
  102. package/templates/qoder/scripts/{kg_auto_login.py → test/kg_auto_login.py} +202 -196
  103. package/templates/qoder/scripts/{kg_test_runner.py → test/kg_test_runner.py} +7 -1
  104. package/templates/qoder/scripts/{page_probe.py → test/page_probe.py} +465 -459
  105. package/templates/qoder/scripts/wlkj.py +116 -0
  106. package/templates/qoder/settings.json +1 -10
  107. package/templates/qoder/skills/design-import/SKILL.md +226 -226
  108. package/templates/qoder/skills/design-review/SKILL.md +82 -82
  109. package/templates/qoder/skills/prd-generator/SKILL.md +26 -16
  110. package/templates/qoder/skills/prd-review/SKILL.md +5 -5
  111. package/templates/qoder/skills/prototype-generator/SKILL.md +256 -256
  112. package/templates/qoder/skills/spec-coder/SKILL.md +4 -4
  113. package/templates/qoder/skills/spec-generator/SKILL.md +4 -4
  114. package/templates/qoder/skills/test-generator/SKILL.md +5 -5
  115. package/templates/qoder/skills/wl-code/SKILL.md +4 -4
  116. package/templates/qoder/skills/wl-commit/SKILL.md +4 -4
  117. package/templates/qoder/skills/wl-design/SKILL.md +3 -3
  118. package/templates/qoder/skills/wl-init/SKILL.md +8 -8
  119. package/templates/qoder/skills/wl-insight/SKILL.md +5 -5
  120. package/templates/qoder/skills/wl-prd-full/SKILL.md +6 -6
  121. package/templates/qoder/skills/wl-prd-quick/SKILL.md +6 -6
  122. package/templates/qoder/skills/wl-prd-review/SKILL.md +4 -4
  123. package/templates/qoder/skills/wl-report/SKILL.md +7 -7
  124. package/templates/qoder/skills/wl-search/SKILL.md +13 -13
  125. package/templates/qoder/skills/wl-spec/SKILL.md +5 -5
  126. package/templates/qoder/skills/wl-status/SKILL.md +5 -5
  127. package/templates/qoder/skills/wl-task/SKILL.md +6 -6
  128. package/templates/qoder/skills/wl-test/SKILL.md +102 -39
  129. package/templates/root/AGENTS.md +39 -40
  130. package/templates/qoder/hooks/inject-workflow-state.py +0 -169
  131. package/templates/qoder/scripts/__pycache__/check_mcp_launch.cpython-39.pyc +0 -0
  132. package/templates/qoder/scripts/__pycache__/install_qoderwork.cpython-39.pyc +0 -0
  133. package/templates/qoder/scripts/__pycache__/mcp_launcher.cpython-39.pyc +0 -0
  134. package/templates/qoder/scripts/__pycache__/platform_doctor.cpython-39.pyc +0 -0
  135. package/templates/qoder/scripts/check_carriers.py +0 -238
  136. package/templates/qoder/scripts/check_mcp_launch.py +0 -183
  137. package/templates/qoder/scripts/check_qoderwork_consistency.py +0 -166
  138. package/templates/qoder/scripts/collect_prds.py +0 -31
  139. package/templates/qoder/scripts/common/mentions.py +0 -134
  140. package/templates/qoder/scripts/common/utf8.py +0 -38
  141. package/templates/qoder/scripts/extract_routes.py +0 -54
  142. package/templates/qoder/scripts/extract_routes_tree.py +0 -78
  143. package/templates/qoder/scripts/handoff.py +0 -22
  144. package/templates/qoder/scripts/init_developer.py +0 -76
  145. package/templates/qoder/scripts/parse_prds.py +0 -33
  146. package/templates/qoder/scripts/role.py +0 -51
  147. package/templates/qoder/scripts/sync_carriers.py +0 -259
  148. package/templates/qoder/scripts/task.py +0 -1261
  149. package/templates/qoder/scripts/workspace_init.py +0 -102
  150. package/templates/qoder/skills/prompt-enrich/SKILL.md +0 -90
  151. package/templates/qoder/skills/prototype-generator/SKILL.md.zcode-79180-2af4721f-f9a6-412c-88db-c0af680d211b.tmp +0 -0
  152. /package/templates/qoder/scripts/{secure-ls.js → test/secure-ls.js} +0 -0
@@ -1,4 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
+ # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
3
+ import os as _o, sys as _s
4
+ _cp = _o.path.join(_o.path.dirname(_o.path.dirname(_o.path.abspath(__file__))), 'common')
5
+ if _cp not in _s.path: _s.path.insert(0, _cp)
6
+ from bootstrap import setup; setup()
7
+
2
8
  """
3
9
  DuckDB knowledge graph store — replaces the JSON flat files with a single
4
10
  embedded database for fast incremental updates.
@@ -21,13 +27,32 @@ import sys
21
27
 
22
28
  import duckdb
23
29
 
24
- SCRIPTS = os.path.join(os.path.dirname(os.path.abspath(__file__)), '.qoder', 'scripts')
25
- sys.path.insert(0, SCRIPTS)
30
+ # __file__ 本身就在 .qoder/scripts/ 下, dirname 即 scripts 目录。
31
+ # 早期版本误拼了一层 '.qoder/scripts', 导致路径变成
32
+ # '.qoder/scripts/.qoder/scripts'(不存在), 只靠调用方提前 insert sys.path
33
+ # 才能侥幸 import common.paths —— 50 人团队不同安装路径/独立 import 时必崩。
34
+ SCRIPTS = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 子包→scripts/根
35
+ if SCRIPTS not in sys.path:
36
+ sys.path.insert(0, SCRIPTS)
26
37
  from common.paths import DATA_INDEX_DIR
27
38
 
28
39
  DB_PATH = str(DATA_INDEX_DIR / 'kg.duckdb')
29
40
 
30
41
 
42
+ def _load_index_json(name):
43
+ """统一加载索引 JSON。build_style_index 把产物写到 _build_cache/,
44
+ 旧布局/手动放的可能在 INDEX 直接目录。两个位置都查, 优先 _build_cache。
45
+ 所有 import_*_layer 共用这个, 避免各写各的 load() 导致路径不一致。"""
46
+ for d in (str(DATA_INDEX_DIR / '_build_cache'), str(DATA_INDEX_DIR)):
47
+ p = os.path.join(d, name)
48
+ if os.path.isfile(p):
49
+ try:
50
+ return json.load(open(p, encoding='utf-8'))
51
+ except (json.JSONDecodeError, OSError):
52
+ pass
53
+ return {}
54
+
55
+
31
56
  def get_db():
32
57
  """Open DuckDB connection (creates file if not exists)."""
33
58
  os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)
@@ -245,20 +270,12 @@ def multi_hop(con, start_id, edge_types=None, max_depth=5):
245
270
 
246
271
  def bulk_import_from_json(con):
247
272
  """One-time full import from existing JSON indexes into DuckDB."""
248
- INDEX = str(DATA_INDEX_DIR / '_build_cache')
249
-
250
- def load(name):
251
- p = os.path.join(INDEX, name)
252
- if os.path.isfile(p):
253
- return json.load(open(p, encoding='utf-8'))
254
- return {}
255
-
256
273
  con.execute("DELETE FROM entities")
257
274
  con.execute("DELETE FROM aliases")
258
275
  con.execute("DELETE FROM edges")
259
276
 
260
- er = load('entity-registry.json')
261
- rel = load('relations.json')
277
+ er = _load_index_json('entity-registry.json')
278
+ rel = _load_index_json('relations.json')
262
279
  edges_data = rel.get('edges', {})
263
280
 
264
281
  entity_rows = []
@@ -330,27 +347,22 @@ def bulk_import_from_json(con):
330
347
 
331
348
  def import_search_layer(con):
332
349
  """导入搜索层: keywords/endpoints/prds/wiki → DuckDB 表。"""
333
- INDEX = str(DATA_INDEX_DIR)
334
- def load(name):
335
- p = os.path.join(INDEX, name)
336
- return json.load(open(p, encoding='utf-8')) if os.path.isfile(p) else {}
337
-
338
350
  # keywords (code-keyword.json: {keyword: [files]})
339
- kw = load('code-keyword.json')
351
+ kw = _load_index_json('code-keyword.json')
340
352
  kw_rows = [(k, f) for k, files in kw.items() for f in files]
341
353
  con.execute("DELETE FROM keywords")
342
354
  if kw_rows:
343
355
  _batch_insert(con, 'keywords', kw_rows)
344
356
 
345
357
  # endpoints (code-api.json: {endpoint: controller_file})
346
- api = load('code-api.json')
358
+ api = _load_index_json('code-api.json')
347
359
  con.execute("DELETE FROM endpoints")
348
360
  ep_rows = [(ep, f) for ep, f in api.items()]
349
361
  if ep_rows:
350
362
  _batch_insert(con, 'endpoints', ep_rows, ignore=True)
351
363
 
352
364
  # prds (prd-index.json)
353
- prds = load('prd-index.json')
365
+ prds = _load_index_json('prd-index.json')
354
366
  con.execute("DELETE FROM prds")
355
367
  prd_rows = [(f, info.get('title', ''),
356
368
  json.dumps(info.get('keywords', []), ensure_ascii=False),
@@ -361,7 +373,7 @@ def import_search_layer(con):
361
373
  _batch_insert(con, 'prds', prd_rows, ignore=True)
362
374
 
363
375
  # wiki (wiki-index.json)
364
- wiki = load('wiki-index.json')
376
+ wiki = _load_index_json('wiki-index.json')
365
377
  con.execute("DELETE FROM wiki")
366
378
  wiki_rows = []
367
379
  for kw, entries in (wiki.get('index', {}) if isinstance(wiki, dict) else {}).items():
@@ -376,12 +388,7 @@ def import_search_layer(con):
376
388
 
377
389
  def import_ui_layer(con):
378
390
  """导入UI层: pages/fields/modules → DuckDB 表。"""
379
- INDEX = str(DATA_INDEX_DIR)
380
- def load(name):
381
- p = os.path.join(INDEX, name)
382
- return json.load(open(p, encoding='utf-8')) if os.path.isfile(p) else {}
383
-
384
- si = load('ui-style.json')
391
+ si = _load_index_json('ui-style.json')
385
392
 
386
393
  # pages (from ui-style projects.page_examples + page_types)
387
394
  con.execute("DELETE FROM pages")
@@ -408,7 +415,7 @@ def import_ui_layer(con):
408
415
  _batch_insert(con, 'fields', field_rows)
409
416
 
410
417
  # modules (from ui-modules.json)
411
- mi = load('ui-modules.json')
418
+ mi = _load_index_json('ui-modules.json')
412
419
  con.execute("DELETE FROM modules")
413
420
  mod_rows = [(m['dir'], m['cn'], proj, m['path'])
414
421
  for proj, mods in mi.get('projects', {}).items() for m in mods]
@@ -434,9 +441,7 @@ def import_ui_layer(con):
434
441
 
435
442
  def import_trace_layer(con):
436
443
  """导入trace层: traces/api_functions → DuckDB 表。"""
437
- INDEX = str(DATA_INDEX_DIR)
438
- tc = json.load(open(os.path.join(INDEX, 'trace-chain.json'), encoding='utf-8')) \
439
- if os.path.isfile(os.path.join(INDEX, 'trace-chain.json')) else {}
444
+ tc = _load_index_json('trace-chain.json')
440
445
 
441
446
  con.execute("DELETE FROM traces")
442
447
  trace_rows = [(
@@ -458,9 +463,7 @@ def import_trace_layer(con):
458
463
 
459
464
  def import_test_layer(con):
460
465
  """导入test层: tests → DuckDB 表。"""
461
- INDEX = str(DATA_INDEX_DIR)
462
- ta = json.load(open(os.path.join(INDEX, 'test-assertions.json'), encoding='utf-8')) \
463
- if os.path.isfile(os.path.join(INDEX, 'test-assertions.json')) else {}
466
+ ta = _load_index_json('test-assertions.json')
464
467
 
465
468
  con.execute("DELETE FROM tests")
466
469
  test_rows = [(
@@ -478,9 +481,7 @@ def import_test_layer(con):
478
481
 
479
482
  def import_workflow_layer(con):
480
483
  """导入workflow层 → DuckDB 表。"""
481
- INDEX = str(DATA_INDEX_DIR)
482
- wf = json.load(open(os.path.join(INDEX, 'workflow-index.json'), encoding='utf-8')) \
483
- if os.path.isfile(os.path.join(INDEX, 'workflow-index.json')) else {}
484
+ wf = _load_index_json('workflow-index.json')
484
485
 
485
486
  con.execute("DELETE FROM workflows")
486
487
  wf_rows = []