@hupan56/wlkj 3.1.6 → 3.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,29 +1,29 @@
1
- {
2
- "name": "@hupan56/wlkj",
3
- "version": "3.1.6",
4
- "description": "AI Product R&D Workflow - PRD/Prototype/Search/Task/Report",
5
- "bin": {
6
- "wlkj": "bin/cli.js"
7
- },
8
- "files": [
9
- "bin/",
10
- "templates/",
11
- "MAC-VERIFY.md"
12
- ],
13
- "keywords": [
14
- "workflow",
15
- "ai",
16
- "prd",
17
- "pipeline",
18
- "qoder",
19
- "product",
20
- "team"
21
- ],
22
- "license": "MIT",
23
- "publishConfig": {
24
- "access": "public"
25
- },
26
- "engines": {
27
- "node": ">=16"
28
- }
1
+ {
2
+ "name": "@hupan56/wlkj",
3
+ "version": "3.1.7",
4
+ "description": "AI Product R&D Workflow - PRD/Prototype/Search/Task/Report",
5
+ "bin": {
6
+ "wlkj": "bin/cli.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "templates/",
11
+ "MAC-VERIFY.md"
12
+ ],
13
+ "keywords": [
14
+ "workflow",
15
+ "ai",
16
+ "prd",
17
+ "pipeline",
18
+ "qoder",
19
+ "product",
20
+ "team"
21
+ ],
22
+ "license": "MIT",
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "engines": {
27
+ "node": ">=16"
28
+ }
29
29
  }
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: wl-req
2
3
  description: "需求管理: 看需求/看产出/发布"
3
4
  argument-hint: "[REQ-ID] [发布]"
4
5
  ---
@@ -10,7 +10,7 @@ for _ in range(10):
10
10
  break
11
11
  if _cp not in _s.path: _s.path.insert(0, _cp)
12
12
  from bootstrap import setup; setup()
13
- from foundation.core.paths import get_repo_root
13
+ from foundation.core.paths import get_repo_root
14
14
 
15
15
  """
16
16
  gen_design_doc.py - 自动生成 DESIGN.md (给 AI 的设计系统说明书)
@@ -43,7 +43,7 @@ except (AttributeError, TypeError, OSError, IOError):
43
43
  except Exception:
44
44
  pass
45
45
 
46
- BASE = get_repo_root()
46
+ BASE = get_repo_root()
47
47
  INDEX_DIR = os.path.join(BASE, 'data', 'index')
48
48
  OUTPUT_DIR = os.path.join(BASE, 'data', 'design')
49
49
 
@@ -269,8 +269,14 @@ def gen_design_doc():
269
269
  lines.append(f'- `{field_name}` -> {title} (used {count}x)')
270
270
  lines.append('')
271
271
 
272
- # ========== 4.5 Feature Modules (from prd-features.json) ==========
273
- pf = load_json('prd-features.json')
272
+ # ========== 4.5 Feature Modules (from prd-features.json, DuckDB-backed) ==========
273
+ # prd-features.json 文件不存在, 真实数据在 DuckDB entities(FEATURE 行)
274
+ # 用 search_index.load_index 走 DuckDB (load_json 只读文件, 永远返回 {})。
275
+ try:
276
+ from domain.kg.search.search_index import load_index as _load_idx
277
+ pf = _load_idx('prd-features.json') or {}
278
+ except Exception:
279
+ pf = load_json('prd-features.json')
274
280
  features = pf.get('features', {}) if isinstance(pf, dict) else {}
275
281
  if features:
276
282
  lines.append('## 4.5 Feature Modules (系统有哪些功能模块)')
@@ -288,8 +294,14 @@ def gen_design_doc():
288
294
  lines.append(f' - 标杆页面: {sample_pages}')
289
295
  lines.append('')
290
296
 
291
- # ========== 4.6 Real Buttons (from entity-registry.json) ==========
292
- er = load_json('entity-registry.json')
297
+ # ========== 4.6 Real Buttons (from entity-registry.json, DuckDB-backed) ==========
298
+ # entity-registry.json 文件不存在, 真实数据在 DuckDB entities(BUTTON 行, 2675 个)
299
+ # 用 search_index.load_index 走 DuckDB (load_json 只读文件, 永远返回 {} → 按钮段永远空)。
300
+ try:
301
+ from domain.kg.search.search_index import load_index as _load_idx
302
+ er = _load_idx('entity-registry.json') or {}
303
+ except Exception:
304
+ er = load_json('entity-registry.json')
293
305
  entities = er.get('entities', {}) if isinstance(er, dict) else {}
294
306
  button_samples = []
295
307
  for eid, info in list(entities.items())[:500]:
@@ -1,17 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """learn_aggregate.py - 团队学习聚合 (同构 kg_build.py)
3
3
 
4
- # v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
5
- import os as _o, sys as _s
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
12
- if _cp not in _s.path: _s.path.insert(0, _cp)
13
- from bootstrap import setup; setup()
14
-
15
4
  扫所有人的 workspace/members/{dev}/journal/feedback.jsonl
16
5
  → 增量写入 kg.duckdb 的 learning_events 表 (团队单一真源)
17
6
 
@@ -26,6 +15,19 @@ from bootstrap import setup; setup()
26
15
  python learn_aggregate.py # 增量
27
16
  python learn_aggregate.py --rebuild # 全量重建
28
17
  """
18
+ # v3.0 路径自举: 引导到 foundation/bootstrap, 统一 sys.path 逻辑
19
+ # ⚠ 必须在 module docstring 之外! 旧版把这块包进 docstring → bootstrap 永不执行
20
+ # → from foundation... ModuleNotFoundError → 学习聚合全链路死。
21
+ import os as _o, sys as _s
22
+ _f = _o.path.abspath(__file__)
23
+ for _ in range(10):
24
+ _f = _o.path.dirname(_f)
25
+ _cp = _o.path.join(_f, 'foundation')
26
+ if _o.path.isfile(_o.path.join(_cp, 'bootstrap.py')):
27
+ break
28
+ if _cp not in _s.path: _s.path.insert(0, _cp)
29
+ from bootstrap import setup; setup()
30
+
29
31
  import os
30
32
  import sys
31
33
  import json
@@ -33,9 +35,6 @@ import hashlib
33
35
  import time
34
36
  from datetime import datetime
35
37
 
36
- SCRIPTS = os.path.dirname(os.path.abspath(__file__))
37
- sys.path.insert(0, SCRIPTS)
38
-
39
38
  from foundation.core.paths import MEMBERS_DIR
40
39
  from domain.kg.storage.kg_duckdb import get_db, init_schema # v3.0: kg_duckdb 已迁入 kg/ 子包
41
40
 
@@ -258,6 +258,42 @@ def _duckdb_load(filename):
258
258
  result[proj] = {'files': vf or 0, 'classes': 0, 'apis': 0}
259
259
  return result if result else None
260
260
 
261
+ elif filename == 'entity-registry.json':
262
+ # 实体注册表 (fill_prototype 取真实按钮文案 / gen_design_doc 取按钮样本)。
263
+ # 真实数据在 DuckDB entities 表 (6131 行: BUTTON/ENDPOINT/FEATURE/...),
264
+ # 不再有 entity-registry.json 文件 (kg.py 注释: 通常不存在)。
265
+ # 重建为 {'entities': {id: {'type':..., 'canonical':..., 'cn':..., 'properties': props}}}
266
+ # 消费方 extract_real_buttons 读 entities[eid]['properties']['button_text']。
267
+ def _entity_loader(con):
268
+ rows = con.execute("SELECT id, type, canonical, cn, props FROM entities").fetchall()
269
+ result = {'entities': {}}
270
+ for eid, etype, canon, cn, props in rows:
271
+ try:
272
+ props_d = json.loads(props) if props else {}
273
+ except Exception:
274
+ props_d = {}
275
+ result['entities'][eid] = {
276
+ 'type': etype, 'canonical': canon, 'cn': cn or '',
277
+ 'properties': props_d,
278
+ }
279
+ return result if result['entities'] else None
280
+ return _load_with_pickle_cache(con, 'entity-registry', _entity_loader)
281
+
282
+ elif filename == 'prd-features.json':
283
+ # 从 entities 表 FEATURE 行重建 (prd-features.json 文件不存在)。
284
+ # gen_design_doc 取 feature 模块样本。结构: {'features': {canonical: {'cn':..., 'properties':...}}}
285
+ def _feature_loader(con):
286
+ rows = con.execute("SELECT id, canonical, cn, props FROM entities WHERE type='FEATURE'").fetchall()
287
+ result = {'features': {}}
288
+ for eid, canon, cn, props in rows:
289
+ try:
290
+ props_d = json.loads(props) if props else {}
291
+ except Exception:
292
+ props_d = {}
293
+ result['features'][canon or eid] = {'cn': cn or '', 'id': eid, 'properties': props_d}
294
+ return result if result['features'] else None
295
+ return _load_with_pickle_cache(con, 'prd-features', _feature_loader)
296
+
261
297
  except Exception:
262
298
  return None
263
299
  return None
@@ -24,10 +24,10 @@ import os
24
24
  import sys
25
25
 
26
26
  # ── 路径自举: 让脚本能独立运行 (复用 bootstrap 模式) ──
27
- # task_utils/identity 用相对导入 (.paths), 必须从 common 包上下文导入,
28
- # 因此把 scripts/ 加入 path, common.xxx / task.xxx 访问。
27
+ # 本脚本在 scripts/domain/task/ (scripts 下 2 级), dirname 两次才到 scripts/。
28
+ # 旧版只 dirname 一次 → _SCRIPTS=scripts/domain/ 找不到 foundation 整个 zentao CLI 同步死。
29
29
  _HERE = os.path.dirname(os.path.abspath(__file__))
30
- _SCRIPTS = os.path.dirname(_HERE) # .qoder/scripts
30
+ _SCRIPTS = os.path.dirname(os.path.dirname(_HERE)) # .qoder/scripts (上两级)
31
31
  _COMMON = os.path.join(_SCRIPTS, 'foundation')
32
32
  for _p in (_SCRIPTS, _COMMON):
33
33
  if _p not in sys.path: