@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.
- package/bin/cli.js +1435 -1373
- package/package.json +1 -1
- package/templates/qoder/commands/optional/wl-insight.md +6 -4
- package/templates/qoder/commands/optional/wl-report.md +20 -39
- package/templates/qoder/commands/optional/wl-status.md +4 -4
- package/templates/qoder/commands/wl-code.md +2 -2
- package/templates/qoder/commands/wl-design.md +5 -5
- package/templates/qoder/commands/wl-init.md +3 -3
- package/templates/qoder/commands/wl-prd.md +26 -13
- package/templates/qoder/commands/wl-req.md +3 -3
- package/templates/qoder/commands/wl-search.md +78 -47
- package/templates/qoder/commands/wl-task.md +343 -40
- package/templates/qoder/commands/wl-test.md +10 -10
- package/templates/qoder/config.yaml +35 -13
- package/templates/qoder/hooks/post-tool-use.py +181 -0
- package/templates/qoder/hooks/session-start.py +82 -1
- package/templates/qoder/hooks/stop-eval.py +207 -0
- package/templates/qoder/hooks/user-prompt-submit.py +139 -0
- package/templates/qoder/rules/wl-pipeline.md +70 -8
- package/templates/qoder/scripts/README.md +78 -115
- package/templates/qoder/scripts/capability/__init__.py +26 -0
- package/templates/qoder/scripts/capability/__main__.py +72 -0
- package/templates/qoder/scripts/capability/adapters/__init__.py +29 -0
- package/templates/qoder/scripts/capability/adapters/cli.py +316 -0
- package/templates/qoder/scripts/capability/adapters/mcp.py +334 -0
- package/templates/qoder/scripts/capability/adapters/qw.py +271 -0
- package/templates/qoder/scripts/capability/caps/__init__.py +27 -0
- package/templates/qoder/scripts/capability/caps/context.py +36 -0
- package/templates/qoder/scripts/capability/caps/cron.py +50 -0
- package/templates/qoder/scripts/capability/caps/identity.py +43 -0
- package/templates/qoder/scripts/capability/caps/memory.py +71 -0
- package/templates/qoder/scripts/capability/caps/notify.py +41 -0
- package/templates/qoder/scripts/capability/caps/present.py +48 -0
- package/templates/qoder/scripts/capability/caps/repo.py +31 -0
- package/templates/qoder/scripts/capability/caps/sandbox.py +43 -0
- package/templates/qoder/scripts/capability/chain.py +92 -0
- package/templates/qoder/scripts/capability/memory_chain.py +41 -0
- package/templates/qoder/scripts/capability/registry.py +246 -0
- package/templates/qoder/scripts/capability/registry_mcp.py +250 -0
- package/templates/qoder/scripts/capability/smoke_test.py +211 -0
- package/templates/qoder/scripts/capability/smoke_test_report.json +94 -0
- package/templates/qoder/scripts/{report → deployment/setup}/__init__.py +11 -11
- package/templates/qoder/scripts/{setup → deployment/setup}/carriers.py +33 -26
- package/templates/qoder/scripts/deployment/setup/carriers_verify.py +148 -0
- package/templates/qoder/scripts/{setup → deployment/setup}/init_doctor.py +40 -16
- package/templates/qoder/scripts/{setup → deployment/setup}/install_qoderwork.py +20 -12
- package/templates/qoder/scripts/{setup → deployment/setup}/platform_doctor.py +8 -2
- package/templates/qoder/scripts/{setup → deployment/setup}/repo_root.py +113 -112
- package/templates/qoder/scripts/{setup → deployment/setup}/setup.py +31 -11
- package/templates/qoder/scripts/{setup → deployment/setup}/setup_lanhu.py +13 -7
- package/templates/qoder/scripts/domain/__init__.py +0 -0
- package/templates/qoder/scripts/domain/design/__init__.py +0 -0
- package/templates/qoder/scripts/{report → domain/design}/fill_prototype.py +12 -6
- package/templates/qoder/scripts/{report → domain/design}/gen_design_doc.py +8 -2
- package/templates/qoder/scripts/{setup → domain/kg}/__init__.py +11 -11
- package/templates/qoder/scripts/domain/kg/build/__init__.py +0 -0
- package/templates/qoder/scripts/{kg → domain/kg/build}/build_entity_registry.py +7 -2
- package/templates/qoder/scripts/{kg → domain/kg/build}/build_relations.py +7 -2
- package/templates/qoder/scripts/{kg → domain/kg/build}/build_style_index.py +13 -7
- package/templates/qoder/scripts/{kg → domain/kg/build}/build_workflows.py +7 -2
- package/templates/qoder/scripts/{kg → domain/kg/build}/kg_build.py +76 -9
- package/templates/qoder/scripts/{kg → domain/kg/build}/kg_build_db.py +7 -2
- package/templates/qoder/scripts/{kg → domain/kg/build}/kg_incremental.py +11 -6
- package/templates/qoder/scripts/{report → domain/kg/build}/learn_aggregate.py +9 -4
- package/templates/qoder/scripts/domain/kg/extract/__init__.py +0 -0
- package/templates/qoder/scripts/{common → domain/kg/extract}/extract.py +430 -419
- package/templates/qoder/scripts/{common → domain/kg/extract}/test_extract.py +115 -115
- package/templates/qoder/scripts/{common → domain/kg/extract}/ts_extract.py +614 -536
- package/templates/qoder/scripts/domain/kg/graph/__init__.py +0 -0
- package/templates/qoder/scripts/{kg → domain/kg/graph}/kg_link_db.py +7 -2
- package/templates/qoder/scripts/domain/kg/graph/kg_semantic.py +683 -0
- package/templates/qoder/scripts/{kg → domain/kg}/kg.py +263 -30
- package/templates/qoder/scripts/{common → domain/kg}/kg_capabilities.py +182 -182
- package/templates/qoder/scripts/domain/kg/search/__init__.py +0 -0
- package/templates/qoder/scripts/{kg → domain/kg/search}/context_pack.py +30 -9
- package/templates/qoder/scripts/{kg → domain/kg/search}/enrich_prompt.py +10 -4
- package/templates/qoder/scripts/{kg → domain/kg/search}/prefetch.py +33 -8
- package/templates/qoder/scripts/{common → domain/kg/search}/search_engine.py +207 -205
- package/templates/qoder/scripts/{kg → domain/kg/search}/search_index.py +143 -77
- package/templates/qoder/scripts/domain/kg/server/__init__.py +0 -0
- package/templates/qoder/scripts/domain/kg/server/kgd.py +549 -0
- package/templates/qoder/scripts/domain/kg/server/perf_bench.py +197 -0
- package/templates/qoder/scripts/domain/kg/storage/__init__.py +0 -0
- package/templates/qoder/scripts/{kg → domain/kg/storage}/kg_duckdb.py +38 -14
- package/templates/qoder/scripts/domain/learning/__init__.py +0 -0
- package/templates/qoder/scripts/{report → domain/learning}/learn.py +8 -3
- package/templates/qoder/scripts/{mcp → domain/report}/__init__.py +11 -11
- package/templates/qoder/scripts/{report → domain/report}/add_session.py +9 -3
- package/templates/qoder/scripts/{report → domain/report}/export.py +10 -5
- package/templates/qoder/scripts/{report → domain/report}/report.py +9 -4
- package/templates/qoder/scripts/domain/report/report_snapshot.py +261 -0
- package/templates/qoder/scripts/{report → domain/report}/role.py +10 -4
- package/templates/qoder/scripts/{report → domain/report}/status.py +112 -9
- package/templates/qoder/scripts/domain/report/status_snapshot.py +191 -0
- package/templates/qoder/scripts/domain/requirement/__init__.py +0 -0
- package/templates/qoder/scripts/{report → domain/requirement}/archive_prd.py +8 -2
- package/templates/qoder/scripts/{report → domain/requirement}/req.py +228 -222
- package/templates/qoder/scripts/{kg → domain/task}/__init__.py +11 -11
- package/templates/qoder/scripts/{task → domain/task}/git_sync.py +40 -21
- package/templates/qoder/scripts/{task → domain/task}/syncgate.py +13 -8
- package/templates/qoder/scripts/{task → domain/task}/task.py +13 -5
- package/templates/qoder/scripts/{task → domain/task}/task_lifecycle.py +606 -596
- package/templates/qoder/scripts/{task → domain/task}/task_query.py +162 -161
- package/templates/qoder/scripts/{task → domain/task}/task_relations.py +425 -424
- package/templates/qoder/scripts/{task → domain/task}/team_sync.py +9 -4
- package/templates/qoder/scripts/domain/task/zentao_sync.py +370 -0
- package/templates/qoder/scripts/foundation/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation}/bootstrap.py +10 -10
- package/templates/qoder/scripts/foundation/core/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/core}/cmd_registry.py +1 -1
- package/templates/qoder/scripts/{common → foundation/core}/config.py +1 -1
- package/templates/qoder/scripts/{common → foundation/core}/paths.py +706 -586
- package/templates/qoder/scripts/foundation/data/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/data}/contract.py +2 -2
- package/templates/qoder/scripts/{common → foundation/data}/events.py +2 -2
- package/templates/qoder/scripts/{common → foundation/data}/result.py +1 -1
- package/templates/qoder/scripts/{common → foundation/data}/task_utils.py +427 -404
- package/templates/qoder/scripts/foundation/identity/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/identity}/check_publish.py +103 -98
- package/templates/qoder/scripts/{common → foundation/identity}/developer.py +239 -239
- package/templates/qoder/scripts/{common → foundation/identity}/guard.py +2 -2
- package/templates/qoder/scripts/{common → foundation/identity}/identity.py +14 -10
- package/templates/qoder/scripts/{common → foundation/identity}/roles.py +1 -1
- package/templates/qoder/scripts/foundation/integrations/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/integrations}/active_task.py +30 -15
- package/templates/qoder/scripts/{common → foundation/integrations}/feishu.py +2 -2
- package/templates/qoder/scripts/{common → foundation/integrations}/terms.py +3 -3
- package/templates/qoder/scripts/foundation/integrations/zentao_client.py +220 -0
- package/templates/qoder/scripts/foundation/io/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/io}/filelock.py +1 -1
- package/templates/qoder/scripts/{common → foundation/io}/reqid.py +1 -1
- package/templates/qoder/scripts/foundation/protocol/__init__.py +0 -0
- package/templates/qoder/scripts/foundation/protocol/duckdb_conn.py +39 -0
- package/templates/qoder/scripts/{common → foundation/protocol}/mcp_base.py +1 -1
- package/templates/qoder/scripts/foundation/utils/__init__.py +0 -0
- package/templates/qoder/scripts/{common → foundation/utils}/eval_api.py +12 -1
- package/templates/qoder/scripts/{common → foundation/utils}/pip_install.py +23 -6
- package/templates/qoder/scripts/{common → foundation/utils}/platform_guard.py +1 -1
- package/templates/qoder/scripts/orchestration/__init__.py +0 -0
- package/templates/qoder/scripts/orchestration/wlkj.py +185 -0
- package/templates/qoder/scripts/protocol/__init__.py +0 -0
- package/templates/qoder/scripts/protocol/browser/README.md +207 -0
- package/templates/qoder/scripts/protocol/browser/SKILL.md +265 -0
- package/templates/qoder/scripts/protocol/browser/config.env +9 -0
- package/templates/qoder/scripts/protocol/browser/references/cdp-api.md +110 -0
- package/templates/qoder/scripts/protocol/browser/references/migration-2.5.3.md +72 -0
- package/templates/qoder/scripts/protocol/browser/references/site-patterns/.gitkeep +0 -0
- package/templates/qoder/scripts/protocol/browser/scripts/browser-discovery.mjs +138 -0
- package/templates/qoder/scripts/protocol/browser/scripts/cdp-proxy.mjs +672 -0
- package/templates/qoder/scripts/protocol/browser/scripts/check-deps.mjs +206 -0
- package/templates/qoder/scripts/protocol/browser/scripts/find-url.mjs +253 -0
- package/templates/qoder/scripts/protocol/browser/scripts/match-site.mjs +46 -0
- package/templates/qoder/scripts/protocol/browser/templates/config.env.template +9 -0
- package/templates/qoder/scripts/protocol/mcp/__init__.py +11 -0
- package/templates/qoder/scripts/protocol/mcp/kg_mcp_server.py +478 -0
- package/templates/qoder/scripts/{mcp → protocol/mcp}/lanhu_stdio_wrapper.py +11 -5
- package/templates/qoder/scripts/{mcp → protocol/mcp}/mcp_doctor.py +47 -14
- package/templates/qoder/scripts/protocol/mcp/mcp_launcher.py +600 -0
- package/templates/qoder/scripts/{mcp → protocol/mcp}/mysql_mcp_server.py +181 -67
- package/templates/qoder/scripts/protocol/mcp/zentao_mcp_server.py +1920 -0
- package/templates/qoder/scripts/protocol/transports/__init__.py +56 -0
- package/templates/qoder/scripts/protocol/transports/base.py +87 -0
- package/templates/qoder/scripts/protocol/transports/cli.py +132 -0
- package/templates/qoder/scripts/protocol/transports/http.py +141 -0
- package/templates/qoder/scripts/protocol/transports/stdio.py +293 -0
- package/templates/qoder/scripts/run_weekly_update.bat +27 -18
- package/templates/qoder/scripts/run_weekly_update.sh +22 -13
- package/templates/qoder/scripts/validation/__init__.py +0 -0
- package/templates/qoder/scripts/validation/eval/__init__.py +0 -0
- package/templates/qoder/scripts/validation/eval/perf-report-2026-06-24.md +139 -0
- package/templates/qoder/scripts/validation/eval/qwork_harness.py +617 -0
- package/templates/qoder/scripts/validation/eval/report-commands.md +220 -0
- package/templates/qoder/scripts/validation/eval/transcript_timing.py +386 -0
- package/templates/qoder/scripts/validation/metrics/__init__.py +0 -0
- package/templates/qoder/scripts/{report → validation/metrics}/eval_prd.py +17 -10
- package/templates/qoder/scripts/validation/metrics/usability_score.py +750 -0
- package/templates/qoder/scripts/validation/test/__init__.py +11 -0
- package/templates/qoder/scripts/validation/test/assertion_gen.py +551 -0
- package/templates/qoder/scripts/{test → validation/test}/autotest.py +64 -4
- package/templates/qoder/scripts/{common → validation/test}/autotest_auth.py +1 -1
- package/templates/qoder/scripts/{test → validation/test}/autotest_batch.py +16 -3
- package/templates/qoder/scripts/{test → validation/test}/autotest_data.py +17 -12
- package/templates/qoder/scripts/validation/test/autotest_opencli.py +646 -0
- package/templates/qoder/scripts/{test → validation/test}/autotest_run.py +17 -3
- package/templates/qoder/scripts/validation/test/autotest_webaccess.py +571 -0
- package/templates/qoder/scripts/{test → validation/test}/benchmark.py +12 -6
- package/templates/qoder/scripts/{test → validation/test}/kg_auto_login.py +8 -2
- package/templates/qoder/scripts/{test → validation/test}/kg_test_runner.py +7 -2
- package/templates/qoder/scripts/{test → validation/test}/page_probe.py +8 -3
- package/templates/qoder/scripts/validation/test/smoke_all_commands.py +170 -0
- package/templates/qoder/settings.json +30 -0
- package/templates/qoder/skills/design-import/SKILL.md +22 -13
- package/templates/qoder/skills/design-review/SKILL.md +19 -10
- package/templates/qoder/skills/prd-generator/SKILL.md +22 -18
- package/templates/qoder/skills/prd-review/SKILL.md +6 -4
- package/templates/qoder/skills/prototype-generator/SKILL.md +63 -14
- package/templates/qoder/skills/spec-coder/SKILL.md +22 -13
- package/templates/qoder/skills/spec-generator/SKILL.md +22 -10
- package/templates/qoder/skills/test-generator/SKILL.md +7 -5
- package/templates/qoder/skills/wl-code/SKILL.md +23 -11
- package/templates/qoder/skills/wl-commit/SKILL.md +9 -8
- package/templates/qoder/skills/wl-design/SKILL.md +5 -3
- package/templates/qoder/skills/wl-init/SKILL.md +6 -6
- package/templates/qoder/skills/wl-insight/SKILL.md +23 -10
- package/templates/qoder/skills/wl-prd-full/SKILL.md +57 -6
- package/templates/qoder/skills/wl-prd-quick/SKILL.md +3 -3
- package/templates/qoder/skills/wl-prd-review/SKILL.md +16 -4
- package/templates/qoder/skills/wl-report/SKILL.md +25 -23
- package/templates/qoder/skills/wl-search/SKILL.md +149 -78
- package/templates/qoder/skills/wl-spec/SKILL.md +7 -5
- package/templates/qoder/skills/wl-status/SKILL.md +48 -16
- package/templates/qoder/skills/wl-task/SKILL.md +92 -10
- package/templates/qoder/skills/wl-test/SKILL.md +75 -29
- package/templates/qoder/templates/prd-full-template.md +7 -0
- package/templates/root/AGENTS.md +275 -236
- package/templates/root/requirements.txt +3 -0
- package/templates/root//344/275/277/347/224/250/350/257/264/346/230/216.md +3 -3
- package/templates/root//346/226/260/346/211/213/346/214/207/345/215/227.md +2 -2
- package/templates/.qoder/.runtime/ctx-cache-5660152f1d6dd819.md +0 -23
- package/templates/.qoder/.runtime/ctx-cache-afdce0dac06b25b0.md +0 -23
- package/templates/.qoder/.runtime/search-cache-eae7644e7b122f35.txt +0 -1
- package/templates/.qoder/learning/eval-history.jsonl +0 -28
- package/templates/data/index/wiki-index.json +0 -8
- package/templates/qoder/nul +0 -4
- package/templates/qoder/scripts/kg/extract.py +0 -398
- package/templates/qoder/scripts/kg/kg_semantic.py +0 -156
- package/templates/qoder/scripts/mcp/kg_mcp_server.py +0 -606
- package/templates/qoder/scripts/mcp/mcp_launcher.py +0 -442
- package/templates/qoder/scripts/mcp/zentao_mcp_server.py +0 -384
- package/templates/qoder/scripts/task/__init__.py +0 -11
- package/templates/qoder/scripts/test/__init__.py +0 -11
- package/templates/qoder/scripts/wlkj.py +0 -116
- /package/templates/qoder/scripts/{common → deployment}/__init__.py +0 -0
- /package/templates/qoder/scripts/{common → domain/kg/graph}/graph_traverse.py +0 -0
- /package/templates/qoder/scripts/{common → domain/kg/server}/repowiki.py +0 -0
- /package/templates/qoder/scripts/{common → foundation/io}/atomicio.py +0 -0
- /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
|
-
|
|
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
|
|
47
|
+
from foundation.integrations.terms import expand_chinese_query, get_platform_map
|
|
42
48
|
|
|
43
|
-
BASE =
|
|
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
|
|
462
|
-
assert_platform_selected(skill='wl-prd
|
|
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
|
-
|
|
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 =
|
|
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)
|
|
File without changes
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
# v3.0 路径自举: 引导到 common/bootstrap, 统一 sys.path 逻辑
|
|
5
5
|
import os as _o, sys as _s
|
|
6
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
43
|
-
from
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
31
|
-
from kg_duckdb import get_db, init_schema, upsert_entity, upsert_alias, upsert_edge, delete_edges_from
|
|
32
|
-
from
|
|
33
|
-
from
|
|
34
|
-
from
|
|
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
|
-
|
|
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
|
|
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
|
|
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}
|
|
File without changes
|