@hupan56/wlkj 3.4.3 → 3.4.5

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 CHANGED
@@ -26,6 +26,10 @@ const PROTECTED_FILES = new Set([
26
26
  "settings.json", // 本地权限/hook 配置
27
27
  ]);
28
28
 
29
+ // commands/ 目录下的文件强制覆盖(不走三路快照保护)
30
+ // 原因:commands 是引擎产物(类似 .py 脚本),用户不该改;三路快照误保护导致新版 commands 到不了用户
31
+ const FORCE_OVERWRITE_DIRS = new Set(["commands"]);
32
+
29
33
  // 本地状态文件(升级时也绝不碰,但不算"受保护配置",不提示合并)
30
34
  const LOCAL_STATE_FILES = new Set([
31
35
  ".developer", ".current-task", ".engine-version",
@@ -497,6 +501,16 @@ function copyDirRecursive(src, dst, mode = "init", snap = {}, newSnap = {}, relB
497
501
  const s = path.join(src, entry.name);
498
502
  const d = path.join(dst, entry.name);
499
503
  const rel = relBase ? `${relBase}/${entry.name}` : entry.name;
504
+
505
+ // commands/ 目录强制覆盖(不走三路快照,引擎产物不该被保护)
506
+ const inForceOverwriteDir = FORCE_OVERWRITE_DIRS.has(relBase);
507
+ if (entry.isDirectory() && inForceOverwriteDir) {
508
+ // 直接全量拷贝目录(不保护,不快照)
509
+ const r = copyDirRecursive(s, d, "init", {}, {}, rel);
510
+ copied += r.copied; protectedN += r.protectedN; skipped += r.skipped;
511
+ protectedFiles.push(...r.protectedFiles);
512
+ continue;
513
+ }
500
514
  if (entry.isDirectory()) {
501
515
  const r = copyDirRecursive(s, d, mode, snap, newSnap, rel);
502
516
  copied += r.copied; protectedN += r.protectedN; skipped += r.skipped;
@@ -508,8 +522,22 @@ function copyDirRecursive(src, dst, mode = "init", snap = {}, newSnap = {}, relB
508
522
  entry.name.endsWith(".html") || entry.name.endsWith(".txt");
509
523
 
510
524
  if (mode === "update") {
511
- // 受保护配置 (config.yaml/settings.json): 永不覆盖, 有差异存 .new
525
+ // 受保护配置 (config.yaml/settings.json): 永不覆盖, 但自动修复已知问题
512
526
  if (PROTECTED_FILES.has(entry.name) && fs.existsSync(d)) {
527
+ // ★ config.yaml url 行内注释修复:自动清理 url 行的 # 注释(防被当 git url)
528
+ if (entry.name === "config.yaml") {
529
+ try {
530
+ let cfgContent = fs.readFileSync(d, "utf-8");
531
+ // 匹配 url: "xxx" # 注释 → 去掉注释
532
+ const fixedContent = cfgContent.replace(
533
+ /^(\s*url:\s*["']?[^"'\n]*["']?)\s+#.*$/gm, "$1"
534
+ );
535
+ if (fixedContent !== cfgContent) {
536
+ fs.writeFileSync(d, fixedContent, "utf-8");
537
+ console.log(` [FIX] config.yaml url 行内注释已自动清理`);
538
+ }
539
+ } catch { /* 修复失败不阻塞 */ }
540
+ }
513
541
  if (!filesEqual(s, d)) {
514
542
  fs.copyFileSync(s, d + ".new");
515
543
  protectedN++; protectedFiles.push(rel);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hupan56/wlkj",
3
- "version": "3.4.3",
3
+ "version": "3.4.5",
4
4
  "description": "AI Product R&D Workflow - PRD/Prototype/Search/Task/Report",
5
5
  "bin": {
6
6
  "wlkj": "bin/cli.js"
@@ -15,17 +15,20 @@ User input: $ARGUMENTS
15
15
  **所有知识查询走 MCP 工具(云平台),绝不跑 wlkj.py kg/context 等本地脚本。**
16
16
  本地 kg.duckdb 是空的(共识:全走平台)。跑本地脚本 = 空结果 = 浪费时间。
17
17
 
18
- **直接用这些 MCP 工具:**
19
-
20
- | 要什么 | 工具名 |
21
- |---|---|
22
- | 全上下文(代码+API+字段+PRD) | context_pack |
23
- | 代码搜索 | search_code |
24
- | 业务流程问答 | semantic_search |
25
- | 影响分析 | get_impact |
26
- | 功能画像 | feature_overview |
27
- | 表字段 | search_field |
28
- | 设计系统 | get_design_system |
18
+ **直接用这些 MCP 工具(工具名必须和下表完全一致):**
19
+
20
+ | 要什么 | 工具名 | 参数 |
21
+ |---|---|---|
22
+ | 全上下文(代码+API+字段+PRD) | context_pack | {keyword, platform} |
23
+ | 代码搜索 | search_code | {keyword, platform} |
24
+ | 语义检索(业务流程/概念) | rag_search | {query, top_k} |
25
+ | 全局业务流程问答 | graphrag_ask | {q, top_k} |
26
+ | 影响分析 | get_impact | {entity, depth} |
27
+ | 功能画像 | feature_profile | {feature} |
28
+ | 表字段搜索 | search_field | {field} |
29
+ | 真表结构 | schema_link | {concept} |
30
+ | 设计系统 | get_design_system | {platform} |
31
+ | 需求串联 | aggregate_requirement | {req_key} |
29
32
 
30
33
  > QoderWork: `mcp__qoder-knowledge-graph__<工具名>` 参数用JSON
31
34
  > Qoder IDE: `cap.mcp.call("<工具名>", {参数})`
@@ -18,9 +18,9 @@ User input: $ARGUMENTS
18
18
  |---|---|---|
19
19
  | 查代码在哪 | search_code | {keyword: "考勤", platform: "web"} |
20
20
  | 全上下文 | context_pack | {keyword: "车辆保养", platform: "app"} |
21
- | 业务流程 | semantic_search | {query: "保险流程"} |
21
+ | 业务流程 | rag_search | {query: "保险流程"} |
22
22
  | 改XX影响谁 | get_impact | {endpoint: "/asset"} |
23
- | 功能画像 | feature_overview | {feature: "资产管理"} |
23
+ | 功能画像 | feature_profile | {feature: "资产管理"} |
24
24
  | 字段在哪用 | search_field | {field: "plateNo"} |
25
25
  | 设计规范 | get_design_system | {platform: "web"} |
26
26
 
@@ -122,20 +122,20 @@ class KnowledgeGraphMCPServer(BaseMCPServer):
122
122
  # 本地工具 → 云平台工具映射(名称不同或参数不同)
123
123
  _TOOL_MAP = {
124
124
  "search_code": "search_code",
125
- "search_api": "search_code",
126
- "search_prd": "rag_search",
125
+ "search_api": "search_api",
126
+ "search_prd": "search_prd_semantic",
127
127
  "get_impact": "get_impact",
128
128
  "context_360": "context_360",
129
129
  "context_pack": "context_pack",
130
130
  "get_workflow": "business_trace",
131
131
  "multi_hop": "business_trace",
132
132
  "search_wiki": "rag_search",
133
- "search_field": "schema_link",
134
- "list_modules": "search_code",
135
- "coverage_matrix": "rag_search",
136
- "feature_overview": "evidence_chain",
137
- "table_impact": "get_impact",
138
- "fill_prototype": None, # 云平台无等价(本地原型模板)
133
+ "search_field": "search_field",
134
+ "list_modules": "get_modules",
135
+ "coverage_matrix": "impact_coverage",
136
+ "feature_overview": "feature_profile",
137
+ "table_impact": "table_impact",
138
+ "fill_prototype": None,
139
139
  "get_design_system": "get_design_system",
140
140
  "semantic_search": "rag_search",
141
141
  }