@trench-craft/sds 1.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 (276) hide show
  1. package/README.en.md +522 -0
  2. package/README.md +566 -0
  3. package/dist/bin/sds.d.ts +3 -0
  4. package/dist/bin/sds.d.ts.map +1 -0
  5. package/dist/bin/sds.js +50 -0
  6. package/dist/bin/sds.js.map +1 -0
  7. package/dist/src/__tests__/cli.test.d.ts +2 -0
  8. package/dist/src/__tests__/cli.test.d.ts.map +1 -0
  9. package/dist/src/__tests__/cli.test.js +37 -0
  10. package/dist/src/__tests__/cli.test.js.map +1 -0
  11. package/dist/src/__tests__/e2e.test.d.ts +5 -0
  12. package/dist/src/__tests__/e2e.test.d.ts.map +1 -0
  13. package/dist/src/__tests__/e2e.test.js +143 -0
  14. package/dist/src/__tests__/e2e.test.js.map +1 -0
  15. package/dist/src/__tests__/graph.test.d.ts +5 -0
  16. package/dist/src/__tests__/graph.test.d.ts.map +1 -0
  17. package/dist/src/__tests__/graph.test.js +423 -0
  18. package/dist/src/__tests__/graph.test.js.map +1 -0
  19. package/dist/src/__tests__/openspec.test.d.ts +5 -0
  20. package/dist/src/__tests__/openspec.test.d.ts.map +1 -0
  21. package/dist/src/__tests__/openspec.test.js +172 -0
  22. package/dist/src/__tests__/openspec.test.js.map +1 -0
  23. package/dist/src/commands/apply.d.ts +4 -0
  24. package/dist/src/commands/apply.d.ts.map +1 -0
  25. package/dist/src/commands/apply.js +14 -0
  26. package/dist/src/commands/apply.js.map +1 -0
  27. package/dist/src/commands/archive.d.ts +4 -0
  28. package/dist/src/commands/archive.d.ts.map +1 -0
  29. package/dist/src/commands/archive.js +20 -0
  30. package/dist/src/commands/archive.js.map +1 -0
  31. package/dist/src/commands/cache.d.ts +4 -0
  32. package/dist/src/commands/cache.d.ts.map +1 -0
  33. package/dist/src/commands/cache.js +31 -0
  34. package/dist/src/commands/cache.js.map +1 -0
  35. package/dist/src/commands/config.d.ts +4 -0
  36. package/dist/src/commands/config.d.ts.map +1 -0
  37. package/dist/src/commands/config.js +29 -0
  38. package/dist/src/commands/config.js.map +1 -0
  39. package/dist/src/commands/e2e.d.ts +4 -0
  40. package/dist/src/commands/e2e.d.ts.map +1 -0
  41. package/dist/src/commands/e2e.js +65 -0
  42. package/dist/src/commands/e2e.js.map +1 -0
  43. package/dist/src/commands/graph.d.ts +4 -0
  44. package/dist/src/commands/graph.d.ts.map +1 -0
  45. package/dist/src/commands/graph.js +783 -0
  46. package/dist/src/commands/graph.js.map +1 -0
  47. package/dist/src/commands/init.d.ts +4 -0
  48. package/dist/src/commands/init.d.ts.map +1 -0
  49. package/dist/src/commands/init.js +15 -0
  50. package/dist/src/commands/init.js.map +1 -0
  51. package/dist/src/commands/project.d.ts +4 -0
  52. package/dist/src/commands/project.d.ts.map +1 -0
  53. package/dist/src/commands/project.js +6 -0
  54. package/dist/src/commands/project.js.map +1 -0
  55. package/dist/src/commands/propose.d.ts +4 -0
  56. package/dist/src/commands/propose.d.ts.map +1 -0
  57. package/dist/src/commands/propose.js +26 -0
  58. package/dist/src/commands/propose.js.map +1 -0
  59. package/dist/src/commands/registry.d.ts +4 -0
  60. package/dist/src/commands/registry.d.ts.map +1 -0
  61. package/dist/src/commands/registry.js +6 -0
  62. package/dist/src/commands/registry.js.map +1 -0
  63. package/dist/src/commands/skills-install.d.ts +4 -0
  64. package/dist/src/commands/skills-install.d.ts.map +1 -0
  65. package/dist/src/commands/skills-install.js +158 -0
  66. package/dist/src/commands/skills-install.js.map +1 -0
  67. package/dist/src/commands/skills.d.ts +4 -0
  68. package/dist/src/commands/skills.d.ts.map +1 -0
  69. package/dist/src/commands/skills.js +19 -0
  70. package/dist/src/commands/skills.js.map +1 -0
  71. package/dist/src/commands/verify.d.ts +4 -0
  72. package/dist/src/commands/verify.d.ts.map +1 -0
  73. package/dist/src/commands/verify.js +31 -0
  74. package/dist/src/commands/verify.js.map +1 -0
  75. package/dist/src/core/engine.d.ts +33 -0
  76. package/dist/src/core/engine.d.ts.map +1 -0
  77. package/dist/src/core/engine.js +87 -0
  78. package/dist/src/core/engine.js.map +1 -0
  79. package/dist/src/core/engine.test.d.ts +2 -0
  80. package/dist/src/core/engine.test.d.ts.map +1 -0
  81. package/dist/src/core/engine.test.js +13 -0
  82. package/dist/src/core/engine.test.js.map +1 -0
  83. package/dist/src/core/session-state.d.ts +18 -0
  84. package/dist/src/core/session-state.d.ts.map +1 -0
  85. package/dist/src/core/session-state.js +55 -0
  86. package/dist/src/core/session-state.js.map +1 -0
  87. package/dist/src/core/session-state.test.d.ts +2 -0
  88. package/dist/src/core/session-state.test.d.ts.map +1 -0
  89. package/dist/src/core/session-state.test.js +90 -0
  90. package/dist/src/core/session-state.test.js.map +1 -0
  91. package/dist/src/core/subagent-timeout.d.ts +18 -0
  92. package/dist/src/core/subagent-timeout.d.ts.map +1 -0
  93. package/dist/src/core/subagent-timeout.js +61 -0
  94. package/dist/src/core/subagent-timeout.js.map +1 -0
  95. package/dist/src/core/subagent-timeout.test.d.ts +2 -0
  96. package/dist/src/core/subagent-timeout.test.d.ts.map +1 -0
  97. package/dist/src/core/subagent-timeout.test.js +57 -0
  98. package/dist/src/core/subagent-timeout.test.js.map +1 -0
  99. package/dist/src/core/task-sync.d.ts +19 -0
  100. package/dist/src/core/task-sync.d.ts.map +1 -0
  101. package/dist/src/core/task-sync.js +62 -0
  102. package/dist/src/core/task-sync.js.map +1 -0
  103. package/dist/src/core/task-sync.test.d.ts +2 -0
  104. package/dist/src/core/task-sync.test.d.ts.map +1 -0
  105. package/dist/src/core/task-sync.test.js +84 -0
  106. package/dist/src/core/task-sync.test.js.map +1 -0
  107. package/dist/src/graph/advanced-performance.d.ts +137 -0
  108. package/dist/src/graph/advanced-performance.d.ts.map +1 -0
  109. package/dist/src/graph/advanced-performance.js +375 -0
  110. package/dist/src/graph/advanced-performance.js.map +1 -0
  111. package/dist/src/graph/database.d.ts +79 -0
  112. package/dist/src/graph/database.d.ts.map +1 -0
  113. package/dist/src/graph/database.js +305 -0
  114. package/dist/src/graph/database.js.map +1 -0
  115. package/dist/src/graph/engine.d.ts +43 -0
  116. package/dist/src/graph/engine.d.ts.map +1 -0
  117. package/dist/src/graph/engine.js +334 -0
  118. package/dist/src/graph/engine.js.map +1 -0
  119. package/dist/src/graph/exporter.d.ts +56 -0
  120. package/dist/src/graph/exporter.d.ts.map +1 -0
  121. package/dist/src/graph/exporter.js +273 -0
  122. package/dist/src/graph/exporter.js.map +1 -0
  123. package/dist/src/graph/index.d.ts +21 -0
  124. package/dist/src/graph/index.d.ts.map +1 -0
  125. package/dist/src/graph/index.js +14 -0
  126. package/dist/src/graph/index.js.map +1 -0
  127. package/dist/src/graph/layouts.d.ts +77 -0
  128. package/dist/src/graph/layouts.d.ts.map +1 -0
  129. package/dist/src/graph/layouts.js +368 -0
  130. package/dist/src/graph/layouts.js.map +1 -0
  131. package/dist/src/graph/parser.d.ts +47 -0
  132. package/dist/src/graph/parser.d.ts.map +1 -0
  133. package/dist/src/graph/parser.js +228 -0
  134. package/dist/src/graph/parser.js.map +1 -0
  135. package/dist/src/graph/performance.d.ts +90 -0
  136. package/dist/src/graph/performance.d.ts.map +1 -0
  137. package/dist/src/graph/performance.js +275 -0
  138. package/dist/src/graph/performance.js.map +1 -0
  139. package/dist/src/graph/semantic.d.ts +151 -0
  140. package/dist/src/graph/semantic.d.ts.map +1 -0
  141. package/dist/src/graph/semantic.js +402 -0
  142. package/dist/src/graph/semantic.js.map +1 -0
  143. package/dist/src/graph/types.d.ts +114 -0
  144. package/dist/src/graph/types.d.ts.map +1 -0
  145. package/dist/src/graph/types.js +5 -0
  146. package/dist/src/graph/types.js.map +1 -0
  147. package/dist/src/graph/visualizer.d.ts +50 -0
  148. package/dist/src/graph/visualizer.d.ts.map +1 -0
  149. package/dist/src/graph/visualizer.js +869 -0
  150. package/dist/src/graph/visualizer.js.map +1 -0
  151. package/dist/src/openspec/apply.d.ts +16 -0
  152. package/dist/src/openspec/apply.d.ts.map +1 -0
  153. package/dist/src/openspec/apply.js +140 -0
  154. package/dist/src/openspec/apply.js.map +1 -0
  155. package/dist/src/openspec/archive.d.ts +3 -0
  156. package/dist/src/openspec/archive.d.ts.map +1 -0
  157. package/dist/src/openspec/archive.js +17 -0
  158. package/dist/src/openspec/archive.js.map +1 -0
  159. package/dist/src/openspec/e2e-generate.d.ts +39 -0
  160. package/dist/src/openspec/e2e-generate.d.ts.map +1 -0
  161. package/dist/src/openspec/e2e-generate.js +315 -0
  162. package/dist/src/openspec/e2e-generate.js.map +1 -0
  163. package/dist/src/openspec/e2e-runner.d.ts +32 -0
  164. package/dist/src/openspec/e2e-runner.d.ts.map +1 -0
  165. package/dist/src/openspec/e2e-runner.js +208 -0
  166. package/dist/src/openspec/e2e-runner.js.map +1 -0
  167. package/dist/src/openspec/explore.d.ts +3 -0
  168. package/dist/src/openspec/explore.d.ts.map +1 -0
  169. package/dist/src/openspec/explore.js +20 -0
  170. package/dist/src/openspec/explore.js.map +1 -0
  171. package/dist/src/openspec/propose.d.ts +8 -0
  172. package/dist/src/openspec/propose.d.ts.map +1 -0
  173. package/dist/src/openspec/propose.js +124 -0
  174. package/dist/src/openspec/propose.js.map +1 -0
  175. package/dist/src/openspec/verify.d.ts +13 -0
  176. package/dist/src/openspec/verify.d.ts.map +1 -0
  177. package/dist/src/openspec/verify.js +156 -0
  178. package/dist/src/openspec/verify.js.map +1 -0
  179. package/dist/src/platform/claudecode.d.ts +2 -0
  180. package/dist/src/platform/claudecode.d.ts.map +1 -0
  181. package/dist/src/platform/claudecode.js +7 -0
  182. package/dist/src/platform/claudecode.js.map +1 -0
  183. package/dist/src/platform/codex.d.ts +2 -0
  184. package/dist/src/platform/codex.d.ts.map +1 -0
  185. package/dist/src/platform/codex.js +7 -0
  186. package/dist/src/platform/codex.js.map +1 -0
  187. package/dist/src/platform/opencode.d.ts +2 -0
  188. package/dist/src/platform/opencode.d.ts.map +1 -0
  189. package/dist/src/platform/opencode.js +7 -0
  190. package/dist/src/platform/opencode.js.map +1 -0
  191. package/dist/src/platform/router.d.ts +13 -0
  192. package/dist/src/platform/router.d.ts.map +1 -0
  193. package/dist/src/platform/router.js +57 -0
  194. package/dist/src/platform/router.js.map +1 -0
  195. package/dist/src/skills/cache.d.ts +16 -0
  196. package/dist/src/skills/cache.d.ts.map +1 -0
  197. package/dist/src/skills/cache.js +53 -0
  198. package/dist/src/skills/cache.js.map +1 -0
  199. package/dist/src/skills/discovery.d.ts +12 -0
  200. package/dist/src/skills/discovery.d.ts.map +1 -0
  201. package/dist/src/skills/discovery.js +61 -0
  202. package/dist/src/skills/discovery.js.map +1 -0
  203. package/dist/src/skills/loader.d.ts +12 -0
  204. package/dist/src/skills/loader.d.ts.map +1 -0
  205. package/dist/src/skills/loader.js +69 -0
  206. package/dist/src/skills/loader.js.map +1 -0
  207. package/dist/src/skills/registry.d.ts +23 -0
  208. package/dist/src/skills/registry.d.ts.map +1 -0
  209. package/dist/src/skills/registry.js +68 -0
  210. package/dist/src/skills/registry.js.map +1 -0
  211. package/dist/src/utils/fs.d.ts +5 -0
  212. package/dist/src/utils/fs.d.ts.map +1 -0
  213. package/dist/src/utils/fs.js +23 -0
  214. package/dist/src/utils/fs.js.map +1 -0
  215. package/dist/src/utils/logger.d.ts +7 -0
  216. package/dist/src/utils/logger.d.ts.map +1 -0
  217. package/dist/src/utils/logger.js +8 -0
  218. package/dist/src/utils/logger.js.map +1 -0
  219. package/dist/src/utils/yaml.d.ts +3 -0
  220. package/dist/src/utils/yaml.d.ts.map +1 -0
  221. package/dist/src/utils/yaml.js +8 -0
  222. package/dist/src/utils/yaml.js.map +1 -0
  223. package/package.json +62 -0
  224. package/registry/skills-registry.yaml +218 -0
  225. package/skills/core/brainstorming/SKILL.md +259 -0
  226. package/skills/core/brainstorming/scripts/frame-template.html +214 -0
  227. package/skills/core/brainstorming/scripts/helper.js +88 -0
  228. package/skills/core/brainstorming/scripts/server.cjs +338 -0
  229. package/skills/core/brainstorming/scripts/start-server.sh +153 -0
  230. package/skills/core/brainstorming/scripts/stop-server.sh +55 -0
  231. package/skills/core/brainstorming/skill.yaml +12 -0
  232. package/skills/core/brainstorming/spec-document-reviewer-prompt.md +48 -0
  233. package/skills/core/brainstorming/visual-companion.md +286 -0
  234. package/skills/core/claude-code-core/SKILL.md +164 -0
  235. package/skills/core/claude-code-core/skill.yaml +14 -0
  236. package/skills/core/claude-code-prompt/SKILL.md +283 -0
  237. package/skills/core/claude-code-prompt/skill.yaml +14 -0
  238. package/skills/core/claude-code-subagent/SKILL.md +168 -0
  239. package/skills/core/claude-code-subagent/skill.yaml +14 -0
  240. package/skills/core/e2e-generate/SKILL.md +147 -0
  241. package/skills/core/e2e-generate/skill.yaml +12 -0
  242. package/skills/core/ecc-agents-md-router/SKILL.md +90 -0
  243. package/skills/core/ecc-agents-md-router/skill.yaml +12 -0
  244. package/skills/core/ecc-context-injector/SKILL.md +69 -0
  245. package/skills/core/ecc-context-injector/skill.yaml +12 -0
  246. package/skills/core/existing-code-caveman/SKILL.md +340 -0
  247. package/skills/core/existing-code-caveman/skill.yaml +12 -0
  248. package/skills/core/opsx-apply/SKILL.md +121 -0
  249. package/skills/core/opsx-apply/skill.yaml +12 -0
  250. package/skills/core/opsx-archive/SKILL.md +83 -0
  251. package/skills/core/opsx-archive/skill.yaml +12 -0
  252. package/skills/core/opsx-explore/SKILL.md +101 -0
  253. package/skills/core/opsx-explore/skill.yaml +12 -0
  254. package/skills/core/opsx-propose/SKILL.md +131 -0
  255. package/skills/core/opsx-propose/skill.yaml +16 -0
  256. package/skills/core/opsx-verify/SKILL.md +109 -0
  257. package/skills/core/opsx-verify/skill.yaml +12 -0
  258. package/skills/core/subagent-driven-development/SKILL.md +157 -0
  259. package/skills/core/subagent-driven-development/code-quality-reviewer-prompt.md +64 -0
  260. package/skills/core/subagent-driven-development/implementer-prompt.md +122 -0
  261. package/skills/core/subagent-driven-development/skill.yaml +12 -0
  262. package/skills/core/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  263. package/skills/core/writing-plans/SKILL.md +268 -0
  264. package/skills/core/writing-plans/plan-document-reviewer-prompt.md +63 -0
  265. package/skills/core/writing-plans/skill.yaml +12 -0
  266. package/skills/locale/chinese-code-review/SKILL.md +17 -0
  267. package/skills/locale/chinese-code-review/skill.yaml +16 -0
  268. package/skills/locale/chinese-commit-conventions/SKILL.md +17 -0
  269. package/skills/locale/chinese-commit-conventions/skill.yaml +16 -0
  270. package/skills/locale/chinese-documentation/SKILL.md +17 -0
  271. package/skills/locale/chinese-documentation/skill.yaml +16 -0
  272. package/skills/locale/chinese-git-workflow/SKILL.md +17 -0
  273. package/skills/locale/chinese-git-workflow/skill.yaml +16 -0
  274. package/templates/agents-md.md +42 -0
  275. package/templates/claude-md.md +44 -0
  276. package/templates/codex-md.md +49 -0
@@ -0,0 +1,783 @@
1
+ import { Command } from 'commander';
2
+ import os from 'os';
3
+ import { resolve } from 'path';
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
5
+ import { GraphEngine } from '../graph/index.js';
6
+ import yaml from 'yaml';
7
+ const graph = new Command('graph')
8
+ .description('代码图谱管理(结构索引 + 语义增强)');
9
+ // sds graph init
10
+ graph
11
+ .command('init')
12
+ .description('初始化图谱数据库,检测项目语言')
13
+ .option('--lang <lang>', '强制指定语言(ts / python / go / rust / java)', 'auto')
14
+ .option('--db-path <path>', '图谱数据库路径', '.sds/codegraph.db')
15
+ .option('--include <dirs>', '额外包含目录(逗号分隔)')
16
+ .option('--exclude <dirs>', '排除目录(逗号分隔)', 'node_modules,dist,.git')
17
+ .option('--platform <platform>', '目标平台(claude-code / opencode / codex)', 'auto')
18
+ .action(async (options) => {
19
+ const projectDir = process.cwd();
20
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
21
+ console.log('\n sds graph init — 初始化图谱数据库\n');
22
+ console.log(` 项目目录: ${projectDir}\n`);
23
+ // 检测项目语言
24
+ let lang = options.lang;
25
+ if (lang === 'auto') {
26
+ lang = detectProjectLanguage(projectDir);
27
+ console.log(` 检测到语言: ${lang}`);
28
+ }
29
+ else {
30
+ console.log(` 指定语言: ${lang}`);
31
+ }
32
+ // 检测平台
33
+ let platform = options.platform;
34
+ if (platform === 'auto') {
35
+ if (existsSync(resolve(projectDir, '.codex'))) {
36
+ platform = 'codex';
37
+ }
38
+ else if (existsSync(resolve(projectDir, '.opencode'))) {
39
+ platform = 'opencode';
40
+ }
41
+ else if (existsSync(resolve(projectDir, '.claude'))) {
42
+ platform = 'claude-code';
43
+ }
44
+ else {
45
+ platform = 'claude-code'; // 默认
46
+ }
47
+ console.log(` 检测到平台: ${platform}`);
48
+ }
49
+ else {
50
+ console.log(` 指定平台: ${platform}`);
51
+ }
52
+ // 解析 include/exclude
53
+ const include = options.include
54
+ ? options.include.split(',').map((s) => s.trim())
55
+ : ['src', 'lib'];
56
+ const exclude = options.exclude
57
+ ? options.exclude.split(',').map((s) => s.trim())
58
+ : ['node_modules', 'dist', '.git', 'build', 'coverage'];
59
+ // 生成配置
60
+ const config = {
61
+ project: {
62
+ name: getProjectName(projectDir),
63
+ lang,
64
+ root: '.'
65
+ },
66
+ graph: {
67
+ db_path: options.dbPath,
68
+ semantic_path: '.sds/semantic-graph.json',
69
+ include,
70
+ exclude
71
+ },
72
+ enhance: {
73
+ enabled: 'auto',
74
+ provider: 'openai',
75
+ model: 'gpt-4o',
76
+ depth: 'standard',
77
+ max_files: 50,
78
+ budget_tokens: 100000
79
+ },
80
+ cache: {
81
+ l1_ttl: 3600,
82
+ l2_path: '~/.sds/graph-cache/'
83
+ },
84
+ platform: {
85
+ target: platform
86
+ }
87
+ };
88
+ // 确保 .sds 目录存在
89
+ const sdsDir = resolve(projectDir, '.sds');
90
+ if (!existsSync(sdsDir)) {
91
+ mkdirSync(sdsDir, { recursive: true });
92
+ }
93
+ // 写入配置文件
94
+ writeFileSync(configPath, yaml.stringify(config), 'utf-8');
95
+ console.log(`\n ✅ 配置文件已生成: .sds/graph.config.yaml`);
96
+ // 初始化数据库
97
+ const dbPath = resolve(projectDir, options.dbPath);
98
+ const engine = new GraphEngine(projectDir, {
99
+ graph: {
100
+ dbPath: options.dbPath,
101
+ semanticPath: '.sds/semantic-graph.json',
102
+ include,
103
+ exclude
104
+ }
105
+ });
106
+ await engine.init();
107
+ engine.close();
108
+ console.log(` ✅ 数据库已初始化: ${options.dbPath}`);
109
+ console.log(`\n 下一步: 运行 'sds graph index' 进行全量索引\n`);
110
+ });
111
+ /**
112
+ * 检测项目语言
113
+ */
114
+ function detectProjectLanguage(projectDir) {
115
+ // 检查常见配置文件
116
+ const langIndicators = {
117
+ 'typescript': ['tsconfig.json', 'package.json'],
118
+ 'python': ['pyproject.toml', 'setup.py', 'requirements.txt', 'Pipfile'],
119
+ 'go': ['go.mod', 'go.sum'],
120
+ 'rust': ['Cargo.toml', 'Cargo.lock'],
121
+ 'java': ['pom.xml', 'build.gradle', 'build.gradle.kts'],
122
+ 'ruby': ['Gemfile', 'Rakefile'],
123
+ 'php': ['composer.json'],
124
+ 'c': ['Makefile', 'CMakeLists.txt'],
125
+ 'cpp': ['Makefile', 'CMakeLists.txt'],
126
+ };
127
+ for (const [lang, files] of Object.entries(langIndicators)) {
128
+ for (const file of files) {
129
+ if (existsSync(resolve(projectDir, file))) {
130
+ // 对于 package.json,进一步检查是否是 TypeScript
131
+ if (file === 'package.json') {
132
+ if (existsSync(resolve(projectDir, 'tsconfig.json'))) {
133
+ return 'typescript';
134
+ }
135
+ return 'javascript';
136
+ }
137
+ return lang;
138
+ }
139
+ }
140
+ }
141
+ return 'unknown';
142
+ }
143
+ /**
144
+ * 获取项目名称
145
+ */
146
+ function getProjectName(projectDir) {
147
+ const packageJsonPath = resolve(projectDir, 'package.json');
148
+ if (existsSync(packageJsonPath)) {
149
+ try {
150
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
151
+ return packageJson.name || 'unknown';
152
+ }
153
+ catch {
154
+ // ignore
155
+ }
156
+ }
157
+ const pyprojectPath = resolve(projectDir, 'pyproject.toml');
158
+ if (existsSync(pyprojectPath)) {
159
+ try {
160
+ const content = readFileSync(pyprojectPath, 'utf-8');
161
+ const nameMatch = content.match(/name\s*=\s*"([^"]+)"/);
162
+ if (nameMatch)
163
+ return nameMatch[1];
164
+ }
165
+ catch {
166
+ // ignore
167
+ }
168
+ }
169
+ const cargoPath = resolve(projectDir, 'Cargo.toml');
170
+ if (existsSync(cargoPath)) {
171
+ try {
172
+ const content = readFileSync(cargoPath, 'utf-8');
173
+ const nameMatch = content.match(/name\s*=\s*"([^"]+)"/);
174
+ if (nameMatch)
175
+ return nameMatch[1];
176
+ }
177
+ catch {
178
+ // ignore
179
+ }
180
+ }
181
+ // 使用目录名
182
+ return projectDir.split(/[/\\]/).pop() || 'unknown';
183
+ }
184
+ // sds graph index
185
+ graph
186
+ .command('index')
187
+ .description('全量索引(CodeGraph Tree-sitter)')
188
+ .option('--incremental', '增量模式(对比上次索引的 hash)', false)
189
+ .option('--tiered', '分层索引(大型项目优化)', false)
190
+ .option('--workers <number>', '并行 Worker 数', String(os.cpus().length))
191
+ .option('--output-format <format>', '输出格式(sqlite / json / mcp)', 'sqlite')
192
+ .option('--verbose', '显示详细进度', false)
193
+ .action(async (options) => {
194
+ const projectDir = process.cwd();
195
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
196
+ // 检查配置文件
197
+ if (!existsSync(configPath)) {
198
+ console.error('\n ❌ 未找到配置文件,请先运行: sds graph init\n');
199
+ process.exit(1);
200
+ }
201
+ // 读取配置
202
+ const configContent = readFileSync(configPath, 'utf-8');
203
+ const config = yaml.parse(configContent);
204
+ console.log('\n sds graph index — 全量索引\n');
205
+ console.log(` 项目目录: ${projectDir}`);
206
+ console.log(` 增量模式: ${options.incremental ? '是' : '否'}`);
207
+ console.log(` 分层索引: ${options.tiered ? '是' : '否'}\n`);
208
+ // 创建引擎
209
+ const engine = new GraphEngine(projectDir, {
210
+ graph: {
211
+ dbPath: config.graph.db_path,
212
+ semanticPath: config.graph.semantic_path,
213
+ include: config.graph.include,
214
+ exclude: config.graph.exclude
215
+ }
216
+ });
217
+ await engine.init();
218
+ // 执行索引
219
+ const startTime = Date.now();
220
+ let stats;
221
+ if (options.tiered) {
222
+ // 分层索引
223
+ console.log(' 使用分层索引策略...\n');
224
+ const progressCallback = (progress) => {
225
+ if (options.verbose) {
226
+ const bar = '█'.repeat(Math.floor(progress.percentage / 5)) + '░'.repeat(20 - Math.floor(progress.percentage / 5));
227
+ process.stdout.write(`\r ${bar} ${progress.percentage}% | ${progress.phase} | ${progress.current}/${progress.total} | ${progress.speed.toFixed(1)} 文件/秒`);
228
+ }
229
+ };
230
+ stats = await engine.tieredIndex(progressCallback);
231
+ if (options.verbose) {
232
+ process.stdout.write('\n');
233
+ }
234
+ }
235
+ else {
236
+ // 普通索引
237
+ stats = await engine.index({
238
+ incremental: options.incremental,
239
+ verbose: options.verbose
240
+ });
241
+ }
242
+ const durationMs = Date.now() - startTime;
243
+ // 输出统计
244
+ console.log('\n 索引完成!\n');
245
+ console.log(` 文件数: ${stats.filesIndexed}`);
246
+ console.log(` 函数: ${stats.functions}`);
247
+ console.log(` 类: ${stats.classes}`);
248
+ console.log(` 接口: ${stats.interfaces}`);
249
+ console.log(` 类型: ${stats.types}`);
250
+ console.log(` 变量: ${stats.variables}`);
251
+ console.log(` 调用关系: ${stats.callEdges}`);
252
+ console.log(` 导入关系: ${stats.importEdges}`);
253
+ console.log(` 耗时: ${durationMs}ms`);
254
+ console.log(` 缓存命中: ${stats.cacheHit ? '是' : '否'}\n`);
255
+ engine.close();
256
+ });
257
+ // sds graph enhance
258
+ graph
259
+ .command('enhance')
260
+ .description('语义增强(Understand Anything LLM)')
261
+ .option('--files <files>', '指定文件路径(逗号分隔),不传则自动采样')
262
+ .option('--depth <depth>', 'lite / standard / deep', 'standard')
263
+ .option('--model <model>', '覆盖模型')
264
+ .option('--output <path>', '语义图谱输出路径', '.sds/semantic-graph.json')
265
+ .option('--dry-run', '预览将分析哪些文件,不实际调用 LLM', false)
266
+ .action(async (options) => {
267
+ const projectDir = process.cwd();
268
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
269
+ // 检查配置文件
270
+ if (!existsSync(configPath)) {
271
+ console.error('\n ❌ 未找到配置文件,请先运行: sds graph init\n');
272
+ process.exit(1);
273
+ }
274
+ // 读取配置
275
+ const configContent = readFileSync(configPath, 'utf-8');
276
+ const config = yaml.parse(configContent);
277
+ console.log('\n sds graph enhance — 语义增强\n');
278
+ // 创建引擎
279
+ const engine = new GraphEngine(projectDir, {
280
+ graph: {
281
+ dbPath: config.graph.db_path,
282
+ semanticPath: config.graph.semantic_path,
283
+ include: config.graph.include,
284
+ exclude: config.graph.exclude
285
+ },
286
+ enhance: {
287
+ enabled: config.enhance.enabled,
288
+ provider: config.enhance.provider,
289
+ model: config.enhance.model,
290
+ depth: options.depth,
291
+ maxFiles: config.enhance.max_files,
292
+ budgetTokens: config.enhance.budget_tokens
293
+ }
294
+ });
295
+ await engine.init();
296
+ // 检查是否可用
297
+ if (!engine.isSemanticAvailable()) {
298
+ console.log(' ⚠️ 语义增强不可用\n');
299
+ console.log(' 请设置环境变量:');
300
+ console.log(' - OPENAI_API_KEY (for OpenAI)');
301
+ console.log(' - ANTHROPIC_API_KEY (for Anthropic)\n');
302
+ engine.close();
303
+ process.exit(1);
304
+ }
305
+ // 解析文件列表
306
+ const files = options.files ? options.files.split(',').map((s) => s.trim()) : undefined;
307
+ // 构建选项
308
+ const enhanceOptions = {
309
+ files,
310
+ depth: options.depth,
311
+ model: options.model,
312
+ budgetTokens: config.enhance.budget_tokens,
313
+ dryRun: options.dryRun
314
+ };
315
+ // 预览采样
316
+ const preview = engine.previewEnhance(enhanceOptions);
317
+ console.log(` 采样文件数: ${preview.files.length}`);
318
+ console.log(` 预估 Token: ${preview.estimatedTokens}`);
319
+ console.log(` 预估成本: $${preview.estimatedCost.toFixed(4)}`);
320
+ console.log('');
321
+ if (options.dryRun) {
322
+ console.log(' 预览模式,不执行实际分析\n');
323
+ console.log(' 采样文件:');
324
+ for (const file of preview.files) {
325
+ console.log(` - ${file.path} (${file.lines} 行)`);
326
+ }
327
+ console.log('');
328
+ engine.close();
329
+ return;
330
+ }
331
+ // 执行增强
332
+ console.log(' 开始语义分析...\n');
333
+ const result = await engine.enhance(enhanceOptions);
334
+ if (result.status === 'completed') {
335
+ console.log(' ✅ 语义增强完成!\n');
336
+ console.log(` 分析文件数: ${result.filesAnalyzed}`);
337
+ console.log(` Token 消耗: ${result.tokensUsed}`);
338
+ console.log(` 耗时: ${result.durationMs}ms`);
339
+ console.log(` 输出路径: ${result.outputPath}\n`);
340
+ }
341
+ else {
342
+ console.error(' ❌ 语义增强失败\n');
343
+ for (const error of result.errors) {
344
+ console.error(` - ${error}`);
345
+ }
346
+ console.log('');
347
+ }
348
+ engine.close();
349
+ });
350
+ // sds graph query
351
+ graph
352
+ .command('query')
353
+ .description('查询图谱(SQL / 自然语言)')
354
+ .option('--sql <query>', 'SQL 查询语句')
355
+ .option('--nl <query>', '自然语言查询')
356
+ .option('--template <template>', '预定义查询模板(dead-code / circular-deps / entry-points)')
357
+ .action(async (options) => {
358
+ const projectDir = process.cwd();
359
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
360
+ // 检查配置文件
361
+ if (!existsSync(configPath)) {
362
+ console.error('\n ❌ 未找到配置文件,请先运行: sds graph init\n');
363
+ process.exit(1);
364
+ }
365
+ // 读取配置
366
+ const configContent = readFileSync(configPath, 'utf-8');
367
+ const config = yaml.parse(configContent);
368
+ // 创建引擎
369
+ const engine = new GraphEngine(projectDir, {
370
+ graph: {
371
+ dbPath: config.graph.db_path,
372
+ semanticPath: config.graph.semantic_path,
373
+ include: config.graph.include,
374
+ exclude: config.graph.exclude
375
+ }
376
+ });
377
+ await engine.init();
378
+ let sql = options.sql;
379
+ // 处理模板查询
380
+ if (options.template) {
381
+ sql = getTemplateQuery(options.template);
382
+ if (!sql) {
383
+ console.error(`\n ❌ 未知模板: ${options.template}`);
384
+ console.error(' 可用模板: dead-code, circular-deps, entry-points\n');
385
+ engine.close();
386
+ process.exit(1);
387
+ }
388
+ }
389
+ // 处理自然语言查询(简化实现,后续可集成 LLM)
390
+ if (options.nl) {
391
+ console.log('\n ⚠️ 自然语言查询暂未实现,请使用 --sql 或 --template\n');
392
+ engine.close();
393
+ process.exit(1);
394
+ }
395
+ if (!sql) {
396
+ console.error('\n ❌ 请指定查询: --sql, --nl, 或 --template\n');
397
+ engine.close();
398
+ process.exit(1);
399
+ }
400
+ console.log('\n sds graph query\n');
401
+ console.log(` SQL: ${sql}\n`);
402
+ try {
403
+ const result = engine.query(sql);
404
+ // 输出结果
405
+ if (result.rows.length === 0) {
406
+ console.log(' 没有结果\n');
407
+ }
408
+ else {
409
+ // 格式化输出
410
+ const maxColWidths = {};
411
+ // 计算列宽
412
+ for (const col of result.columns) {
413
+ maxColWidths[col] = col.length;
414
+ }
415
+ for (const row of result.rows) {
416
+ for (const col of result.columns) {
417
+ const val = String(row[col] ?? '');
418
+ maxColWidths[col] = Math.max(maxColWidths[col], val.length);
419
+ }
420
+ }
421
+ // 输出表头
422
+ const header = result.columns.map(col => col.padEnd(maxColWidths[col])).join(' | ');
423
+ const separator = result.columns.map(col => '-'.repeat(maxColWidths[col])).join('-+-');
424
+ console.log(` ${header}`);
425
+ console.log(` ${separator}`);
426
+ // 输出行
427
+ for (const row of result.rows) {
428
+ const line = result.columns.map(col => {
429
+ const val = String(row[col] ?? '');
430
+ return val.padEnd(maxColWidths[col]);
431
+ }).join(' | ');
432
+ console.log(` ${line}`);
433
+ }
434
+ console.log(`\n ${result.rowCount} 行结果,耗时 ${result.durationMs}ms\n`);
435
+ }
436
+ }
437
+ catch (error) {
438
+ console.error(`\n ❌ 查询失败: ${error.message}\n`);
439
+ }
440
+ engine.close();
441
+ });
442
+ /**
443
+ * 获取预定义查询模板
444
+ */
445
+ function getTemplateQuery(template) {
446
+ const templates = {
447
+ 'dead-code': `
448
+ SELECT f.path, s.name, s.type
449
+ FROM symbols s
450
+ JOIN files f ON s.file_id = f.id
451
+ WHERE s.id NOT IN (
452
+ SELECT DISTINCT callee_symbol_id FROM call_graph WHERE callee_symbol_id > 0
453
+ )
454
+ AND s.type IN ('function', 'class')
455
+ ORDER BY f.path, s.name
456
+ `,
457
+ 'circular-deps': `
458
+ SELECT
459
+ f1.path as file1,
460
+ f2.path as file2,
461
+ COUNT(*) as dep_count
462
+ FROM call_graph cg
463
+ JOIN files f1 ON cg.caller_file_id = f1.id
464
+ JOIN files f2 ON cg.callee_file_id = f2.id
465
+ WHERE cg.relation_type = 'import'
466
+ AND EXISTS (
467
+ SELECT 1 FROM call_graph cg2
468
+ WHERE cg2.caller_file_id = f2.id
469
+ AND cg2.callee_file_id = f1.id
470
+ AND cg2.relation_type = 'import'
471
+ )
472
+ GROUP BY f1.path, f2.path
473
+ ORDER BY dep_count DESC
474
+ `,
475
+ 'entry-points': `
476
+ SELECT f.path, f.lang, f.lines
477
+ FROM files f
478
+ WHERE f.id NOT IN (
479
+ SELECT DISTINCT callee_file_id FROM call_graph WHERE callee_file_id > 0
480
+ )
481
+ OR f.path LIKE '%main%'
482
+ OR f.path LIKE '%index%'
483
+ OR f.path LIKE '%app%'
484
+ ORDER BY f.path
485
+ `
486
+ };
487
+ return templates[template] || null;
488
+ }
489
+ // sds graph diff
490
+ graph
491
+ .command('diff')
492
+ .description('增量更新(基于 Git Diff)')
493
+ .action(async () => {
494
+ const projectDir = process.cwd();
495
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
496
+ // 检查配置文件
497
+ if (!existsSync(configPath)) {
498
+ console.error('\n ❌ 未找到配置文件,请先运行: sds graph init\n');
499
+ process.exit(1);
500
+ }
501
+ // 读取配置
502
+ const configContent = readFileSync(configPath, 'utf-8');
503
+ const config = yaml.parse(configContent);
504
+ console.log('\n sds graph diff — 增量更新\n');
505
+ // 创建引擎
506
+ const engine = new GraphEngine(projectDir, {
507
+ graph: {
508
+ dbPath: config.graph.db_path,
509
+ semanticPath: config.graph.semantic_path,
510
+ include: config.graph.include,
511
+ exclude: config.graph.exclude
512
+ }
513
+ });
514
+ await engine.init();
515
+ // 执行增量更新
516
+ const result = await engine.diff();
517
+ if (result.status === 'no_changes') {
518
+ console.log(' 没有检测到变更文件\n');
519
+ }
520
+ else {
521
+ console.log(` 变更文件数: ${result.changedFiles}`);
522
+ console.log(` 重新索引节点: ${result.reindexedNodes}`);
523
+ console.log(` 重新索引关系: ${result.reindexedEdges}`);
524
+ if (result.semanticInvalidated.length > 0) {
525
+ console.log(`\n 语义失效文件:`);
526
+ for (const file of result.semanticInvalidated) {
527
+ console.log(` - ${file}`);
528
+ }
529
+ }
530
+ if (result.suggestion) {
531
+ console.log(`\n 建议: ${result.suggestion}`);
532
+ }
533
+ }
534
+ console.log('');
535
+ engine.close();
536
+ });
537
+ // sds graph export
538
+ graph
539
+ .command('export')
540
+ .description('导出为 AI 助手引导文件片段')
541
+ .option('--format <format>', '导出格式(claude-md / agents-md / json)', 'claude-md')
542
+ .option('--output <path>', '输出路径')
543
+ .action(async (options) => {
544
+ const projectDir = process.cwd();
545
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
546
+ // 检查配置文件
547
+ if (!existsSync(configPath)) {
548
+ console.error('\n ❌ 未找到配置文件,请先运行: sds graph init\n');
549
+ process.exit(1);
550
+ }
551
+ // 读取配置
552
+ const configContent = readFileSync(configPath, 'utf-8');
553
+ const config = yaml.parse(configContent);
554
+ console.log('\n sds graph export — 导出图谱\n');
555
+ // 创建引擎
556
+ const engine = new GraphEngine(projectDir, {
557
+ graph: {
558
+ dbPath: config.graph.db_path,
559
+ semanticPath: config.graph.semantic_path,
560
+ include: config.graph.include,
561
+ exclude: config.graph.exclude
562
+ }
563
+ });
564
+ await engine.init();
565
+ // 导出图谱
566
+ const result = await engine.exportGraph({
567
+ format: options.format,
568
+ outputPath: options.output
569
+ });
570
+ if (result.status === 'completed') {
571
+ console.log(' ✅ 导出完成!\n');
572
+ console.log(` 格式: ${result.format}`);
573
+ console.log(` 输出路径: ${result.outputPath}`);
574
+ console.log(` 耗时: ${result.durationMs}ms\n`);
575
+ }
576
+ else {
577
+ console.error(' ❌ 导出失败\n');
578
+ for (const error of result.errors) {
579
+ console.error(` - ${error}`);
580
+ }
581
+ console.log('');
582
+ }
583
+ engine.close();
584
+ });
585
+ // sds graph status
586
+ graph
587
+ .command('status')
588
+ .description('查看索引状态、覆盖率、最后更新')
589
+ .action(async () => {
590
+ const projectDir = process.cwd();
591
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
592
+ console.log('\n sds graph status\n');
593
+ // 检查配置文件
594
+ if (!existsSync(configPath)) {
595
+ console.log(' 状态: 未初始化\n');
596
+ console.log(' 运行 \'sds graph init\' 初始化图谱数据库\n');
597
+ return;
598
+ }
599
+ // 读取配置
600
+ const configContent = readFileSync(configPath, 'utf-8');
601
+ const config = yaml.parse(configContent);
602
+ // 创建引擎
603
+ const engine = new GraphEngine(projectDir, {
604
+ graph: {
605
+ dbPath: config.graph.db_path,
606
+ semanticPath: config.graph.semantic_path,
607
+ include: config.graph.include,
608
+ exclude: config.graph.exclude
609
+ }
610
+ });
611
+ await engine.init();
612
+ // 获取状态
613
+ const status = await engine.getStatus();
614
+ if (!status.exists) {
615
+ console.log(' 状态: 数据库不存在\n');
616
+ console.log(' 运行 \'sds graph index\' 进行索引\n');
617
+ }
618
+ else {
619
+ console.log(' 状态: 已初始化\n');
620
+ console.log(` 数据库路径: ${status.dbPath}`);
621
+ console.log(` 文件数: ${status.filesCount}`);
622
+ console.log(` 符号数: ${status.symbolsCount}`);
623
+ console.log(` 关系数: ${status.edgesCount}`);
624
+ console.log(` 覆盖率: ${status.coveragePercent}%`);
625
+ if (status.lastUpdated) {
626
+ console.log(` 最后更新: ${status.lastUpdated}`);
627
+ }
628
+ if (status.semanticEnabled) {
629
+ console.log(` 语义增强: 已启用`);
630
+ if (status.semanticLastUpdated) {
631
+ console.log(` 语义更新: ${status.semanticLastUpdated}`);
632
+ }
633
+ }
634
+ else {
635
+ console.log(` 语义增强: 未启用`);
636
+ }
637
+ }
638
+ console.log('');
639
+ engine.close();
640
+ });
641
+ // sds graph cache
642
+ graph
643
+ .command('cache')
644
+ .description('管理 L1/L2 缓存')
645
+ .option('--clear', '清除所有缓存', false)
646
+ .option('--info', '显示缓存信息', false)
647
+ .action(async (options) => {
648
+ const projectDir = process.cwd();
649
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
650
+ console.log('\n sds graph cache — 缓存管理\n');
651
+ // 检查配置文件
652
+ if (!existsSync(configPath)) {
653
+ console.log(' 状态: 未初始化\n');
654
+ console.log(' 运行 \'sds graph init\' 初始化图谱数据库\n');
655
+ return;
656
+ }
657
+ // 读取配置
658
+ const configContent = readFileSync(configPath, 'utf-8');
659
+ const config = yaml.parse(configContent);
660
+ const dbPath = resolve(projectDir, config.graph.db_path);
661
+ const semanticPath = resolve(projectDir, config.graph.semantic_path);
662
+ const l2Path = resolve(projectDir, config.cache.l2_path);
663
+ if (options.clear) {
664
+ // 清除缓存
665
+ console.log(' 清除缓存...\n');
666
+ // 清除 L1 内存缓存(重新加载即可)
667
+ console.log(' ✅ L1 内存缓存已清除');
668
+ // 清除 L2 磁盘缓存
669
+ if (existsSync(l2Path)) {
670
+ const { rmSync } = await import('fs');
671
+ rmSync(l2Path, { recursive: true, force: true });
672
+ console.log(' ✅ L2 磁盘缓存已清除');
673
+ }
674
+ else {
675
+ console.log(' ℹ️ L2 磁盘缓存不存在');
676
+ }
677
+ console.log('');
678
+ }
679
+ else if (options.info) {
680
+ // 显示缓存信息
681
+ console.log(' 缓存信息:\n');
682
+ // L1 内存缓存
683
+ console.log(' L1 内存缓存:');
684
+ console.log(' - 状态: 活跃(进程级)');
685
+ console.log(' - TTL: 配置值');
686
+ // L2 磁盘缓存
687
+ console.log('\n L2 磁盘缓存:');
688
+ console.log(` - 路径: ${l2Path}`);
689
+ if (existsSync(l2Path)) {
690
+ const { statSync } = await import('fs');
691
+ const stat = statSync(l2Path);
692
+ console.log(` - 状态: 存在`);
693
+ console.log(` - 最后修改: ${stat.mtime.toISOString()}`);
694
+ }
695
+ else {
696
+ console.log(' - 状态: 不存在');
697
+ }
698
+ // L3 项目本地
699
+ console.log('\n L3 项目本地:');
700
+ console.log(` - 数据库: ${dbPath}`);
701
+ console.log(` - 语义图谱: ${semanticPath}`);
702
+ if (existsSync(dbPath)) {
703
+ const { statSync } = await import('fs');
704
+ const stat = statSync(dbPath);
705
+ console.log(` - 数据库大小: ${(stat.size / 1024).toFixed(2)} KB`);
706
+ }
707
+ if (existsSync(semanticPath)) {
708
+ const { statSync } = await import('fs');
709
+ const stat = statSync(semanticPath);
710
+ console.log(` - 语义图谱大小: ${(stat.size / 1024).toFixed(2)} KB`);
711
+ }
712
+ console.log('');
713
+ }
714
+ else {
715
+ console.log(' 请指定操作:\n');
716
+ console.log(' --clear 清除所有缓存');
717
+ console.log(' --info 显示缓存信息\n');
718
+ }
719
+ });
720
+ // sds graph viz
721
+ graph
722
+ .command('viz')
723
+ .description('生成 HTML 交互图谱')
724
+ .option('--format <format>', '输出格式(html / svg)', 'html')
725
+ .option('--output <path>', '输出路径')
726
+ .option('--max-nodes <number>', '最大节点数', '100')
727
+ .option('--max-edges <number>', '最大边数', '500')
728
+ .option('--theme <theme>', '主题(light / dark)', 'light')
729
+ .option('--layout <layout>', '布局算法(hierarchical / circular / force-directed / grid / tree)', 'force-directed')
730
+ .action(async (options) => {
731
+ const projectDir = process.cwd();
732
+ const configPath = resolve(projectDir, '.sds/graph.config.yaml');
733
+ // 检查配置文件
734
+ if (!existsSync(configPath)) {
735
+ console.error('\n ❌ 未找到配置文件,请先运行: sds graph init\n');
736
+ process.exit(1);
737
+ }
738
+ // 读取配置
739
+ const configContent = readFileSync(configPath, 'utf-8');
740
+ const config = yaml.parse(configContent);
741
+ console.log('\n sds graph viz — 生成交互图谱\n');
742
+ // 创建引擎
743
+ const engine = new GraphEngine(projectDir, {
744
+ graph: {
745
+ dbPath: config.graph.db_path,
746
+ semanticPath: config.graph.semantic_path,
747
+ include: config.graph.include,
748
+ exclude: config.graph.exclude
749
+ }
750
+ });
751
+ await engine.init();
752
+ // 生成可视化
753
+ const result = await engine.visualize({
754
+ format: options.format,
755
+ outputPath: options.output,
756
+ includeCode: false,
757
+ maxNodes: parseInt(options.maxNodes),
758
+ maxEdges: parseInt(options.maxEdges),
759
+ theme: options.theme,
760
+ layout: options.layout,
761
+ });
762
+ if (result.status === 'completed') {
763
+ console.log(' ✅ 图谱生成完成!\n');
764
+ console.log(` 格式: ${result.format}`);
765
+ console.log(` 节点数: ${result.nodesCount}`);
766
+ console.log(` 边数: ${result.edgesCount}`);
767
+ console.log(` 输出路径: ${result.outputPath}`);
768
+ console.log(` 耗时: ${result.durationMs}ms\n`);
769
+ if (result.format === 'html') {
770
+ console.log(' 在浏览器中打开 HTML 文件查看交互图谱\n');
771
+ }
772
+ }
773
+ else {
774
+ console.error(' ❌ 图谱生成失败\n');
775
+ for (const error of result.errors) {
776
+ console.error(` - ${error}`);
777
+ }
778
+ console.log('');
779
+ }
780
+ engine.close();
781
+ });
782
+ export default graph;
783
+ //# sourceMappingURL=graph.js.map