@hupan56/wlkj 3.2.0 → 3.3.1

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 (130) hide show
  1. package/bin/cli.js +117 -0
  2. package/package.json +2 -2
  3. package/templates/.qoder/.runtime/hook-errors.log +4 -0
  4. package/templates/qoder/commands/optional/wl-insight.md +276 -276
  5. package/templates/qoder/commands/optional/wl-report.md +1 -1
  6. package/templates/qoder/commands/optional/wl-spec.md +13 -1
  7. package/templates/qoder/commands/optional/wl-status.md +14 -1
  8. package/templates/qoder/commands/wl-code.md +111 -4
  9. package/templates/qoder/commands/wl-commit.md +12 -1
  10. package/templates/qoder/commands/wl-design.md +69 -5
  11. package/templates/qoder/commands/wl-init.md +129 -102
  12. package/templates/qoder/commands/wl-prd.md +162 -6
  13. package/templates/qoder/commands/wl-search.md +106 -20
  14. package/templates/qoder/commands/wl-task.md +617 -613
  15. package/templates/qoder/commands/wl-test.md +20 -1
  16. package/templates/qoder/contracts/spec.md +4 -0
  17. package/templates/qoder/hooks/post-tool-use.py +71 -0
  18. package/templates/qoder/hooks/pre-tool-use.py +136 -0
  19. package/templates/qoder/hooks/session-start.py +365 -397
  20. package/templates/qoder/scripts/capability/__pycache__/__init__.cpython-39.pyc +0 -0
  21. package/templates/qoder/scripts/capability/__pycache__/present_html.cpython-39.pyc +0 -0
  22. package/templates/qoder/scripts/capability/__pycache__/registry.cpython-39.pyc +0 -0
  23. package/templates/qoder/scripts/capability/__pycache__/registry_mcp.cpython-39.pyc +0 -0
  24. package/templates/qoder/scripts/capability/adapters/__init__.py +1 -1
  25. package/templates/qoder/scripts/capability/adapters/__pycache__/__init__.cpython-39.pyc +0 -0
  26. package/templates/qoder/scripts/capability/adapters/__pycache__/cli.cpython-39.pyc +0 -0
  27. package/templates/qoder/scripts/capability/adapters/__pycache__/mcp.cpython-39.pyc +0 -0
  28. package/templates/qoder/scripts/capability/adapters/__pycache__/qw.cpython-39.pyc +0 -0
  29. package/templates/qoder/scripts/capability/adapters/mcp.py +76 -100
  30. package/templates/qoder/scripts/capability/adapters/qw.py +295 -295
  31. package/templates/qoder/scripts/capability/caps/__init__.py +5 -5
  32. package/templates/qoder/scripts/capability/caps/__pycache__/__init__.cpython-39.pyc +0 -0
  33. package/templates/qoder/scripts/capability/caps/__pycache__/context.cpython-39.pyc +0 -0
  34. package/templates/qoder/scripts/capability/caps/__pycache__/cron.cpython-39.pyc +0 -0
  35. package/templates/qoder/scripts/capability/caps/__pycache__/identity.cpython-39.pyc +0 -0
  36. package/templates/qoder/scripts/capability/caps/__pycache__/memory.cpython-39.pyc +0 -0
  37. package/templates/qoder/scripts/capability/caps/__pycache__/notify.cpython-39.pyc +0 -0
  38. package/templates/qoder/scripts/capability/caps/__pycache__/present.cpython-39.pyc +0 -0
  39. package/templates/qoder/scripts/capability/caps/__pycache__/repo.cpython-39.pyc +0 -0
  40. package/templates/qoder/scripts/capability/caps/__pycache__/sandbox.cpython-39.pyc +0 -0
  41. package/templates/qoder/scripts/capability/caps/memory.py +1 -1
  42. package/templates/qoder/scripts/capability/caps/notify.py +64 -0
  43. package/templates/qoder/scripts/capability/caps/sandbox.py +38 -0
  44. package/templates/qoder/scripts/capability/present_html.py +68 -0
  45. package/templates/qoder/scripts/capability/registry.py +27 -25
  46. package/templates/qoder/scripts/capability/registry_mcp.py +67 -5
  47. package/templates/qoder/scripts/capability/smoke_test_report.json +34 -20
  48. package/templates/qoder/scripts/deployment/setup/carriers.py +3 -1
  49. package/templates/qoder/scripts/deployment/setup/init_doctor.py +10 -3
  50. package/templates/qoder/scripts/domain/__pycache__/__init__.cpython-39.pyc +0 -0
  51. package/templates/qoder/scripts/domain/integration/__init__.py +0 -0
  52. package/templates/qoder/scripts/domain/integration/__pycache__/__init__.cpython-39.pyc +0 -0
  53. package/templates/qoder/scripts/domain/integration/__pycache__/return_to_platform.cpython-39.pyc +0 -0
  54. package/templates/qoder/scripts/domain/integration/return_to_platform.py +395 -0
  55. package/templates/qoder/scripts/domain/integration/spec_upload.py +208 -0
  56. package/templates/qoder/scripts/domain/kg/build/kg_build.py +27 -3
  57. package/templates/qoder/scripts/domain/kg/extract/asset/__init__.py +10 -0
  58. package/templates/qoder/scripts/domain/kg/extract/asset/asset_tree.py +57 -0
  59. package/templates/qoder/scripts/domain/kg/extract/asset/discussion_importer.py +62 -0
  60. package/templates/qoder/scripts/domain/kg/extract/asset/prd_importer.py +146 -0
  61. package/templates/qoder/scripts/domain/kg/extract/asset/prototype_importer.py +64 -0
  62. package/templates/qoder/scripts/domain/kg/extract/asset/returns_importer.py +52 -0
  63. package/templates/qoder/scripts/domain/kg/extract/build_goal3.py +104 -0
  64. package/templates/qoder/scripts/domain/kg/extract/build_goal4.py +55 -0
  65. package/templates/qoder/scripts/domain/kg/extract/build_goal5.py +95 -0
  66. package/templates/qoder/scripts/domain/kg/extract/db/__init__.py +8 -0
  67. package/templates/qoder/scripts/domain/kg/extract/db/data_profile.py +22 -0
  68. package/templates/qoder/scripts/domain/kg/extract/db/fk_extractor.py +55 -0
  69. package/templates/qoder/scripts/domain/kg/extract/db/schema_extractor.py +90 -0
  70. package/templates/qoder/scripts/domain/kg/extract/extract.py +84 -0
  71. package/templates/qoder/scripts/domain/kg/extract/inference/__init__.py +9 -0
  72. package/templates/qoder/scripts/domain/kg/extract/inference/community_summarizer.py +206 -0
  73. package/templates/qoder/scripts/domain/kg/extract/inference/embed_builder.py +132 -0
  74. package/templates/qoder/scripts/domain/kg/extract/inference/naming_matcher.py +80 -0
  75. package/templates/qoder/scripts/domain/kg/extract/inference/promote.py +59 -0
  76. package/templates/qoder/scripts/domain/kg/extract/inference/recompute.py +93 -0
  77. package/templates/qoder/scripts/domain/kg/extract/inference/weak_link.py +421 -0
  78. package/templates/qoder/scripts/domain/kg/extract/java/__init__.py +15 -0
  79. package/templates/qoder/scripts/domain/kg/extract/java/_parser.py +271 -0
  80. package/templates/qoder/scripts/domain/kg/extract/java/all.py +145 -0
  81. package/templates/qoder/scripts/domain/kg/extract/java/build_java_to_pg.py +102 -0
  82. package/templates/qoder/scripts/domain/kg/extract/java/call_chain.py +49 -0
  83. package/templates/qoder/scripts/domain/kg/extract/java/class_extractor.py +141 -0
  84. package/templates/qoder/scripts/domain/kg/extract/java/domain_extractor.py +148 -0
  85. package/templates/qoder/scripts/domain/kg/extract/java/dubbo_extractor.py +33 -0
  86. package/templates/qoder/scripts/domain/kg/extract/java/endpoint_extractor.py +36 -0
  87. package/templates/qoder/scripts/domain/kg/extract/java/javadoc_extractor.py +110 -0
  88. package/templates/qoder/scripts/domain/kg/extract/java/llm_cn_filler.py +150 -0
  89. package/templates/qoder/scripts/domain/kg/extract/java/member_extractor.py +157 -0
  90. package/templates/qoder/scripts/domain/kg/extract/java/mybatisplus_extractor.py +34 -0
  91. package/templates/qoder/scripts/domain/kg/extract/java/pg_upsert.py +165 -0
  92. package/templates/qoder/scripts/domain/kg/extract/java/satoken_extractor.py +30 -0
  93. package/templates/qoder/scripts/domain/kg/extract/java/spring_extractor.py +39 -0
  94. package/templates/qoder/scripts/domain/kg/extract/java/validation_extractor.py +33 -0
  95. package/templates/qoder/scripts/domain/kg/extract/mybatis/__init__.py +9 -0
  96. package/templates/qoder/scripts/domain/kg/extract/mybatis/all.py +79 -0
  97. package/templates/qoder/scripts/domain/kg/extract/mybatis/mapper_parser.py +99 -0
  98. package/templates/qoder/scripts/domain/kg/extract/mybatis/relation_builder.py +69 -0
  99. package/templates/qoder/scripts/domain/kg/extract/mybatis/sql_extractor.py +78 -0
  100. package/templates/qoder/scripts/domain/kg/extract/prd/__init__.py +8 -0
  101. package/templates/qoder/scripts/domain/kg/extract/prd/prd_chunk_embed.py +105 -0
  102. package/templates/qoder/scripts/domain/kg/extract/prd/prd_llm_extract.py +153 -0
  103. package/templates/qoder/scripts/domain/kg/extract/prd/req_anchor.py +120 -0
  104. package/templates/qoder/scripts/domain/kg/graph/kg_semantic.py +4 -2
  105. package/templates/qoder/scripts/domain/kg/kg.py +42 -5
  106. package/templates/qoder/scripts/domain/kg/search/_remote.py +187 -0
  107. package/templates/qoder/scripts/domain/kg/search/context_pack.py +32 -2
  108. package/templates/qoder/scripts/domain/kg/search/search_index.py +74 -20
  109. package/templates/qoder/scripts/domain/kg/switch_project.py +158 -0
  110. package/templates/qoder/scripts/domain/kg/sync_repowiki.py +109 -0
  111. package/templates/qoder/scripts/domain/task/__pycache__/wlkj_panel.cpython-39.pyc +0 -0
  112. package/templates/qoder/scripts/domain/task/{zentao_panel.py → wlkj_panel.py} +315 -53
  113. package/templates/qoder/scripts/engine/poller.py +219 -0
  114. package/templates/qoder/scripts/foundation/__pycache__/__init__.cpython-39.pyc +0 -0
  115. package/templates/qoder/scripts/foundation/core/__pycache__/__init__.cpython-39.pyc +0 -0
  116. package/templates/qoder/scripts/foundation/core/__pycache__/paths.cpython-39.pyc +0 -0
  117. package/templates/qoder/scripts/foundation/integrations/active_task.py +2 -1
  118. package/templates/qoder/scripts/orchestration/wlkj.py +4 -0
  119. package/templates/qoder/scripts/protocol/__pycache__/__init__.cpython-39.pyc +0 -0
  120. package/templates/qoder/scripts/protocol/mcp/zentao_mcp_server.py +1 -1
  121. package/templates/qoder/scripts/protocol/transports/__pycache__/__init__.cpython-39.pyc +0 -0
  122. package/templates/qoder/scripts/protocol/transports/__pycache__/base.cpython-39.pyc +0 -0
  123. package/templates/qoder/scripts/protocol/transports/__pycache__/cli.cpython-39.pyc +0 -0
  124. package/templates/qoder/scripts/protocol/transports/__pycache__/http.cpython-39.pyc +0 -0
  125. package/templates/qoder/scripts/protocol/transports/__pycache__/stdio.cpython-39.pyc +0 -0
  126. package/templates/qoder/scripts/protocol/transports/http.py +7 -1
  127. package/templates/qoder/scripts/validation/metrics/__pycache__/present_board.cpython-39.pyc +0 -0
  128. package/templates/qoder/scripts/validation/metrics/present_board.py +180 -0
  129. package/templates/qoder/settings.json +10 -0
  130. package/templates/root/AGENTS.md +9 -10
package/bin/cli.js CHANGED
@@ -1249,6 +1249,10 @@ function doHelp() {
1249
1249
  console.log(" 或斜杠: /wl-prd /wl-design /wl-task /wl-code /wl-test /wl-commit");
1250
1250
  console.log(" (提交/同步 /wl-task 和 /wl-commit 会自动做, 不用单独 npx sync)");
1251
1251
  console.log("");
1252
+ console.log("=== 能力市场 ===");
1253
+ console.log(" npx @hupan56/wlkj install skill <token> --host <url> 从市场装 Skill 到本地 IDE");
1254
+ console.log(" npx @hupan56/wlkj install agent <token> --host <url> 从市场装 Agent (含依赖 Skill)");
1255
+ console.log("");
1252
1256
  console.log("=== 进阶 (管理员/特殊情况才用, 不常用) ===");
1253
1257
  console.log(" npx @hupan56/wlkj selftest 全套件自检 (跨环境+QoderWork工具协议+smoke+体检+MCP)");
1254
1258
  console.log(" npx @hupan56/wlkj doctor 体检 (或在 Qoder 里 /wl-init 无参数)");
@@ -1521,5 +1525,118 @@ switch (cmd) {
1521
1525
  break;
1522
1526
  }
1523
1527
 
1528
+ // ── 能力市场安装: npx @hupan56/wlkj install <skill|agent> <token> --host <url> ──
1529
+ case "install": {
1530
+ const kind = rest[0]; // skill / agent
1531
+ const token = rest[1]; // share_token
1532
+ const hostIdx = rest.indexOf("--host");
1533
+ const host = hostIdx !== -1 && rest[hostIdx + 1] ? rest[hostIdx + 1] : "http://127.0.0.1:10010";
1534
+
1535
+ if (!kind || !token || !["skill", "agent"].includes(kind)) {
1536
+ console.log("用法: npx @hupan56/wlkj install <skill|agent> <token> [--host <url>]");
1537
+ console.log("例: npx @hupan56/wlkj install skill abc123 --host http://127.0.0.1:10010");
1538
+ process.exit(1);
1539
+ }
1540
+
1541
+ (async () => {
1542
+ try {
1543
+ // 探测本地 IDE
1544
+ const cwd = process.cwd();
1545
+ let ide = "claude";
1546
+ if (fs.existsSync(path.join(cwd, ".cursor"))) ide = "cursor";
1547
+ else if (fs.existsSync(path.join(cwd, ".qoder"))) ide = "qoder";
1548
+ else if (fs.existsSync(path.join(cwd, ".claude"))) ide = "claude";
1549
+ else if (fs.existsSync(path.join(cwd, "CLAUDE.md"))) ide = "claude";
1550
+ else if (fs.existsSync(path.join(cwd, "AGENTS.md"))) ide = "codex";
1551
+
1552
+ if (kind === "agent") {
1553
+ console.log(`→ 从 ${host} 拉取 Agent ${token}...`);
1554
+ const res = await fetch(`${host}/api/market/agent/${token}`);
1555
+ if (!res.ok) throw new Error(`API 返回 ${res.status}`);
1556
+ const agent = await res.json();
1557
+ console.log(`✓ ${agent.icon || "🤖"} ${agent.title}`);
1558
+
1559
+ // 写入 IDE
1560
+ if (ide === "claude" || ide === "codex") {
1561
+ const dir = path.join(cwd, ".claude", "commands");
1562
+ fs.mkdirSync(dir, { recursive: true });
1563
+ const fname = (agent.name || agent.title || "agent") + ".md";
1564
+ let content = `---\ndescription: ${agent.title || ""}\n---\n\n`;
1565
+ content += agent.rolePrompt || agent.role_prompt || `你是${agent.title || "AI助手"}。\n`;
1566
+ if ((agent.toolIds || []).length) {
1567
+ content += `\n## 可用工具\n${(agent.toolIds || []).join(", ")}\n`;
1568
+ }
1569
+ if ((agent.skillIds || []).length) {
1570
+ content += `\n## 可用技能\n${(agent.skillIds || []).join(", ")}\n`;
1571
+ }
1572
+ fs.writeFileSync(path.join(dir, fname), content, "utf-8");
1573
+ console.log(`✓ 已写入: ${path.join(dir, fname)}`);
1574
+ } else if (ide === "qoder") {
1575
+ const dir = path.join(cwd, ".qoder", "agents");
1576
+ fs.mkdirSync(dir, { recursive: true });
1577
+ const fname = (agent.name || agent.title || "agent") + ".json";
1578
+ fs.writeFileSync(path.join(dir, fname), JSON.stringify({
1579
+ name: agent.name, title: agent.title,
1580
+ systemPrompt: agent.rolePrompt || agent.role_prompt || "",
1581
+ tools: agent.toolIds || [], skills: agent.skillIds || [],
1582
+ model: agent.model || null,
1583
+ }, null, 2), "utf-8");
1584
+ console.log(`✓ 已写入: ${path.join(dir, fname)}`);
1585
+ } else if (ide === "cursor") {
1586
+ const dir = path.join(cwd, ".cursor", "rules");
1587
+ fs.mkdirSync(dir, { recursive: true });
1588
+ const fname = (agent.name || agent.title || "agent") + ".mdc";
1589
+ let content = `---\ndescription: ${agent.title || ""}\n---\n`;
1590
+ content += agent.rolePrompt || agent.role_prompt || "";
1591
+ fs.writeFileSync(path.join(dir, fname), content, "utf-8");
1592
+ console.log(`✓ 已写入: ${path.join(dir, fname)}`);
1593
+ }
1594
+
1595
+ // 递归装依赖 Skill
1596
+ const skillIds = agent.skillIds || [];
1597
+ for (const sid of skillIds) {
1598
+ if (typeof sid === "string" && sid.length > 5) {
1599
+ console.log(`→ 递归安装 Skill: ${sid}`);
1600
+ try {
1601
+ const sres = await fetch(`${host}/api/market/skill/${sid}`);
1602
+ if (sres.ok) {
1603
+ const skill = await sres.json();
1604
+ const sdir = path.join(cwd, ".claude", "skills", skill.name || sid);
1605
+ fs.mkdirSync(sdir, { recursive: true });
1606
+ let smd = `---\nname: ${skill.name || sid}\ndescription: ${skill.description || ""}\n---\n`;
1607
+ smd += skill.promptTemplate || skill.prompt_template || "";
1608
+ fs.writeFileSync(path.join(sdir, "SKILL.md"), smd, "utf-8");
1609
+ console.log(` ✓ ${skill.title || sid}`);
1610
+ } else { console.warn(` ⚠ Skill ${sid} 不存在或未发布`); }
1611
+ } catch (e) { console.warn(` ⚠ Skill ${sid} 安装失败: ${e.message}`); }
1612
+ }
1613
+ }
1614
+ console.log(`\n✅ Agent "${agent.title}" 已安装(${ide} 格式)`);
1615
+ }
1616
+
1617
+ else if (kind === "skill") {
1618
+ console.log(`→ 从 ${host} 拉取 Skill ${token}...`);
1619
+ const res = await fetch(`${host}/api/market/skill/${token}`);
1620
+ if (!res.ok) throw new Error(`API 返回 ${res.status}`);
1621
+ const skill = await res.json();
1622
+ console.log(`✓ ${skill.icon || "🛠"} ${skill.title}`);
1623
+
1624
+ const sname = skill.name || token;
1625
+ const sdir = path.join(cwd, ".claude", "skills", sname);
1626
+ fs.mkdirSync(sdir, { recursive: true });
1627
+ let smd = `---\nname: ${sname}\ntitle: ${skill.title || ""}\ndescription: ${skill.description || ""}\nicon: ${skill.icon || ""}\nversion: ${skill.version || "1.0.0"}\n---\n`;
1628
+ smd += skill.promptTemplate || skill.prompt_template || "";
1629
+ fs.writeFileSync(path.join(sdir, "SKILL.md"), smd, "utf-8");
1630
+ console.log(`✓ 已写入: ${path.join(sdir, "SKILL.md")}`);
1631
+ console.log(`\n✅ Skill "${skill.title}" 已安装`);
1632
+ }
1633
+ } catch (e) {
1634
+ console.error(`✗ 安装失败: ${e.message}`);
1635
+ process.exit(1);
1636
+ }
1637
+ })();
1638
+ break;
1639
+ }
1640
+
1524
1641
  default: doHelp();
1525
1642
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hupan56/wlkj",
3
- "version": "3.2.0",
3
+ "version": "3.3.1",
4
4
  "description": "AI Product R&D Workflow - PRD/Prototype/Search/Task/Report",
5
5
  "bin": {
6
6
  "wlkj": "bin/cli.js"
@@ -26,4 +26,4 @@
26
26
  "engines": {
27
27
  "node": ">=16"
28
28
  }
29
- }
29
+ }
@@ -0,0 +1,4 @@
1
+ [2026-07-15 11:55:41] pre-tool-use: stdin parse: Invalid \escape: line 1 column 50 (char 49)
2
+ [2026-07-15 11:55:42] pre-tool-use: stdin parse: Invalid \escape: line 1 column 51 (char 50)
3
+ [2026-07-15 11:55:42] pre-tool-use: stdin parse: Invalid \escape: line 1 column 50 (char 49)
4
+ [2026-07-15 11:55:42] pre-tool-use: stdin parse: Expecting value: line 1 column 1 (char 0)