@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,334 @@
1
+ /**
2
+ * GraphEngine 核心类
3
+ * 协调 Tree-sitter 解析和 SQLite 存储
4
+ */
5
+ import { resolve, relative } from 'path';
6
+ import { readFile, stat, access } from 'fs/promises';
7
+ import { exec } from 'child_process';
8
+ import { promisify } from 'util';
9
+ import { glob } from 'glob';
10
+ import { GraphDatabase } from './database.js';
11
+ import { CodeParser } from './parser.js';
12
+ import { SemanticAnalyzer } from './semantic.js';
13
+ import { GraphExporter } from './exporter.js';
14
+ import { PerformanceOptimizer } from './performance.js';
15
+ import { GraphVisualizer } from './visualizer.js';
16
+ const execAsync = promisify(exec);
17
+ async function exists(path) {
18
+ try {
19
+ await access(path);
20
+ return true;
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ // 默认配置
27
+ const DEFAULT_CONFIG = {
28
+ project: {
29
+ name: 'unknown',
30
+ lang: 'auto',
31
+ root: '.'
32
+ },
33
+ graph: {
34
+ dbPath: '.sds/codegraph.db',
35
+ semanticPath: '.sds/semantic-graph.json',
36
+ include: ['src', 'lib'],
37
+ exclude: ['node_modules', 'dist', '.git', 'build', 'coverage']
38
+ },
39
+ enhance: {
40
+ enabled: 'auto',
41
+ provider: 'openai',
42
+ model: 'gpt-4o',
43
+ depth: 'standard',
44
+ maxFiles: 50,
45
+ budgetTokens: 100000
46
+ },
47
+ cache: {
48
+ l1Ttl: 3600,
49
+ l2Path: '~/.sds/graph-cache/'
50
+ },
51
+ platform: {
52
+ target: 'claude-code'
53
+ }
54
+ };
55
+ export class GraphEngine {
56
+ db;
57
+ parser;
58
+ semanticAnalyzer;
59
+ exporter;
60
+ optimizer;
61
+ visualizer;
62
+ config;
63
+ projectDir;
64
+ constructor(projectDir, config) {
65
+ this.projectDir = projectDir;
66
+ this.config = { ...DEFAULT_CONFIG, ...config };
67
+ const dbPath = resolve(projectDir, this.config.graph.dbPath);
68
+ this.db = new GraphDatabase(dbPath);
69
+ this.parser = new CodeParser();
70
+ this.semanticAnalyzer = new SemanticAnalyzer(projectDir, this.db, {
71
+ provider: this.config.enhance.provider
72
+ });
73
+ this.exporter = new GraphExporter(projectDir, this.db, this.config.graph.semanticPath);
74
+ this.optimizer = new PerformanceOptimizer(projectDir, this.db, this.parser);
75
+ this.visualizer = new GraphVisualizer(projectDir, this.db);
76
+ }
77
+ async init() {
78
+ this.db.initialize();
79
+ await this.parser.initialize();
80
+ }
81
+ async enhance(options) {
82
+ return this.semanticAnalyzer.enhance(options);
83
+ }
84
+ previewEnhance(options) {
85
+ return this.semanticAnalyzer.previewSampling(options);
86
+ }
87
+ isSemanticAvailable() {
88
+ return this.semanticAnalyzer.isAvailable();
89
+ }
90
+ async exportGraph(options) {
91
+ return this.exporter.export(options);
92
+ }
93
+ async tieredIndex(progressCallback) {
94
+ if (progressCallback) {
95
+ this.optimizer = new PerformanceOptimizer(this.projectDir, this.db, this.parser, {
96
+ progressCallback,
97
+ });
98
+ }
99
+ return this.optimizer.tieredIndex();
100
+ }
101
+ async visualize(options) {
102
+ return this.visualizer.visualize(options);
103
+ }
104
+ async index(options = {}) {
105
+ const startTime = Date.now();
106
+ const { incremental = false, verbose = false } = options;
107
+ if (verbose)
108
+ console.log('开始索引...');
109
+ let existingHashes = new Map();
110
+ if (incremental) {
111
+ const existingFiles = this.db.getAllFiles();
112
+ for (const file of existingFiles) {
113
+ existingHashes.set(file.path, file.hash);
114
+ }
115
+ }
116
+ const files = await this.scanFiles();
117
+ if (verbose)
118
+ console.log(`找到 ${files.length} 个文件`);
119
+ const allSymbols = [];
120
+ const allEdges = [];
121
+ let filesIndexed = 0;
122
+ for (const filePath of files) {
123
+ const relativePath = relative(this.projectDir, filePath);
124
+ if (incremental) {
125
+ const fileStat = await stat(filePath);
126
+ const content = await readFile(filePath, 'utf-8');
127
+ const hash = this.parser.computeHash(content);
128
+ if (existingHashes.get(relativePath) === hash) {
129
+ continue;
130
+ }
131
+ }
132
+ try {
133
+ const content = await readFile(filePath, 'utf-8');
134
+ const fileStat = await stat(filePath);
135
+ const hash = this.parser.computeHash(content);
136
+ const lang = this.parser.detectLanguage(filePath);
137
+ const lines = this.parser.countLines(content);
138
+ const fileInfo = {
139
+ path: relativePath,
140
+ lang,
141
+ lines,
142
+ hash,
143
+ lastModified: Math.floor(fileStat.mtimeMs / 1000),
144
+ inDegree: 0,
145
+ outDegree: 0
146
+ };
147
+ const fileId = this.db.upsertFile(fileInfo);
148
+ const { symbols, imports } = this.parser.parseFile(filePath, content);
149
+ for (const symbol of symbols) {
150
+ allSymbols.push({ ...symbol, fileId });
151
+ }
152
+ for (const importPath of imports) {
153
+ const resolvedPath = await this.resolveImportPath(filePath, importPath);
154
+ if (resolvedPath) {
155
+ const importRelativePath = relative(this.projectDir, resolvedPath);
156
+ const importFile = this.db.getFile(importRelativePath);
157
+ if (importFile) {
158
+ allEdges.push({
159
+ callerFileId: fileId,
160
+ callerSymbolId: 0,
161
+ calleeFileId: importFile.id,
162
+ calleeSymbolId: 0,
163
+ relationType: 'import',
164
+ lineNumber: 0
165
+ });
166
+ }
167
+ }
168
+ }
169
+ filesIndexed++;
170
+ if (verbose)
171
+ console.log(` 索引: ${relativePath} (${symbols.length} 符号)`);
172
+ }
173
+ catch (error) {
174
+ if (verbose)
175
+ console.warn(` 跳过文件 ${relativePath}: ${error}`);
176
+ }
177
+ }
178
+ if (allSymbols.length > 0)
179
+ this.db.insertSymbols(allSymbols);
180
+ if (allEdges.length > 0)
181
+ this.db.insertCallEdges(allEdges);
182
+ const durationMs = Date.now() - startTime;
183
+ const stats = this.db.getStats();
184
+ stats.durationMs = durationMs;
185
+ stats.cacheHit = incremental && filesIndexed === 0;
186
+ if (verbose) {
187
+ console.log(`索引完成: ${filesIndexed} 文件, ${stats.functions} 函数, ${stats.classes} 类, ${durationMs}ms`);
188
+ }
189
+ return stats;
190
+ }
191
+ async diff() {
192
+ try {
193
+ const { stdout } = await execAsync('git diff --name-only HEAD~1 HEAD', {
194
+ cwd: this.projectDir
195
+ });
196
+ const changedFiles = stdout.trim().split('\n').filter(Boolean);
197
+ if (changedFiles.length === 0) {
198
+ return { status: 'no_changes', changedFiles: 0, reindexedNodes: 0, reindexedEdges: 0, semanticInvalidated: [] };
199
+ }
200
+ let reindexedNodes = 0;
201
+ let reindexedEdges = 0;
202
+ const semanticInvalidated = [];
203
+ for (const filePath of changedFiles) {
204
+ const fullPath = resolve(this.projectDir, filePath);
205
+ if (!(await exists(fullPath))) {
206
+ this.db.deleteFile(filePath);
207
+ semanticInvalidated.push(filePath);
208
+ continue;
209
+ }
210
+ try {
211
+ const content = await readFile(fullPath, 'utf-8');
212
+ const fileStat = await stat(fullPath);
213
+ const hash = this.parser.computeHash(content);
214
+ const lang = this.parser.detectLanguage(fullPath);
215
+ const lines = this.parser.countLines(content);
216
+ const fileInfo = {
217
+ path: filePath,
218
+ lang,
219
+ lines,
220
+ hash,
221
+ lastModified: Math.floor(fileStat.mtimeMs / 1000),
222
+ inDegree: 0,
223
+ outDegree: 0
224
+ };
225
+ this.db.upsertFile(fileInfo);
226
+ reindexedNodes++;
227
+ const { symbols } = this.parser.parseFile(fullPath, content);
228
+ reindexedNodes += symbols.length;
229
+ semanticInvalidated.push(filePath);
230
+ }
231
+ catch (error) {
232
+ console.warn(`跳过文件 ${filePath}: ${error}`);
233
+ }
234
+ }
235
+ return {
236
+ status: 'incremental_updated',
237
+ changedFiles: changedFiles.length,
238
+ reindexedNodes,
239
+ reindexedEdges,
240
+ semanticInvalidated,
241
+ suggestion: `Run 'sds graph enhance --files ${semanticInvalidated.join(',')}' to refresh semantics.`
242
+ };
243
+ }
244
+ catch (error) {
245
+ return { status: 'no_changes', changedFiles: 0, reindexedNodes: 0, reindexedEdges: 0, semanticInvalidated: [] };
246
+ }
247
+ }
248
+ query(sql, params = []) {
249
+ const startTime = Date.now();
250
+ try {
251
+ const rows = this.db.query(sql, params);
252
+ return {
253
+ columns: rows.length > 0 ? Object.keys(rows[0]) : [],
254
+ rows,
255
+ rowCount: rows.length,
256
+ durationMs: Date.now() - startTime
257
+ };
258
+ }
259
+ catch (error) {
260
+ throw new Error(`查询失败: ${error.message}`);
261
+ }
262
+ }
263
+ async getStatus() {
264
+ const dbPath = resolve(this.projectDir, this.config.graph.dbPath);
265
+ if (!(await exists(dbPath))) {
266
+ return { exists: false };
267
+ }
268
+ const stats = this.db.getStats();
269
+ const files = this.db.getAllFiles();
270
+ const coveragePercent = files.length > 0 ? 100 : 0;
271
+ let lastUpdated;
272
+ if (files.length > 0) {
273
+ const validTimestamps = files
274
+ .map(f => f.lastModified)
275
+ .filter(t => t && t > 0);
276
+ if (validTimestamps.length > 0) {
277
+ const maxTimestamp = Math.max(...validTimestamps);
278
+ const date = new Date(maxTimestamp * 1000);
279
+ if (!isNaN(date.getTime())) {
280
+ lastUpdated = date.toISOString();
281
+ }
282
+ }
283
+ }
284
+ return {
285
+ exists: true,
286
+ dbPath,
287
+ lastUpdated,
288
+ filesCount: stats.filesIndexed,
289
+ symbolsCount: stats.functions + stats.classes + stats.interfaces + stats.types + stats.variables,
290
+ edgesCount: stats.callEdges + stats.importEdges + stats.extendEdges + stats.implementEdges,
291
+ coveragePercent,
292
+ semanticEnabled: this.config.enhance.enabled === 'true',
293
+ semanticLastUpdated: undefined
294
+ };
295
+ }
296
+ clear() {
297
+ this.db.clear();
298
+ }
299
+ close() {
300
+ this.db.close();
301
+ }
302
+ async scanFiles() {
303
+ const includePatterns = this.config.graph.include.map(dir => `${dir}/**/*`);
304
+ const excludePatterns = this.config.graph.exclude.map(dir => `**/${dir}/**`);
305
+ const files = [];
306
+ for (const pattern of includePatterns) {
307
+ const matched = await glob(pattern, { cwd: this.projectDir, ignore: excludePatterns, absolute: true });
308
+ files.push(...matched);
309
+ }
310
+ return files.filter(file => {
311
+ const lang = this.parser.detectLanguage(file);
312
+ return lang !== 'unknown';
313
+ });
314
+ }
315
+ async resolveImportPath(fromFile, importPath) {
316
+ if (importPath.startsWith('.')) {
317
+ const fromDir = fromFile.substring(0, fromFile.lastIndexOf('/'));
318
+ const resolvedPath = resolve(fromDir, importPath);
319
+ const extensions = ['.ts', '.tsx', '.js', '.jsx', '.py', '.go'];
320
+ for (const ext of extensions) {
321
+ const withExt = resolvedPath + ext;
322
+ if (await exists(withExt))
323
+ return withExt;
324
+ }
325
+ for (const ext of extensions) {
326
+ const indexPath = resolve(resolvedPath, `index${ext}`);
327
+ if (await exists(indexPath))
328
+ return indexPath;
329
+ }
330
+ }
331
+ return null;
332
+ }
333
+ }
334
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/graph/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * GraphExporter - 图谱导出器
3
+ * 将图谱数据导出为平台特定的引导文件
4
+ */
5
+ import type { GraphDatabase } from './database.js';
6
+ import type { ExportFormat, ExportOptions } from './types.js';
7
+ export interface ExportResult {
8
+ status: 'completed' | 'failed';
9
+ outputPath: string;
10
+ format: ExportFormat;
11
+ durationMs: number;
12
+ errors: string[];
13
+ }
14
+ export declare class GraphExporter {
15
+ private db;
16
+ private projectDir;
17
+ private semanticPath;
18
+ constructor(projectDir: string, db: GraphDatabase, semanticPath?: string);
19
+ /**
20
+ * 导出图谱
21
+ */
22
+ export(options: ExportOptions): Promise<ExportResult>;
23
+ /**
24
+ * 生成 CLAUDE.md 内容
25
+ */
26
+ private generateClaudeMd;
27
+ /**
28
+ * 生成 AGENTS.md 内容
29
+ */
30
+ private generateAgentsMd;
31
+ /**
32
+ * 生成 JSON 内容
33
+ */
34
+ private generateJson;
35
+ /**
36
+ * 生成技术栈信息
37
+ */
38
+ private generateTechStack;
39
+ /**
40
+ * 生成目录结构
41
+ */
42
+ private generateDirectoryStructure;
43
+ /**
44
+ * 获取模块信息
45
+ */
46
+ private getModules;
47
+ /**
48
+ * 生成模块映射
49
+ */
50
+ private generateModuleMap;
51
+ /**
52
+ * 生成调用链信息
53
+ */
54
+ private generateCallChains;
55
+ }
56
+ //# sourceMappingURL=exporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../../../src/graph/exporter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAG3E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAS;gBAEjB,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,YAAY,GAAE,MAAmC;IAMpG;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAgE3D;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoCxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiCxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAgCpB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAqBlC;;OAEG;IACH,OAAO,CAAC,UAAU;IAgBlB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CA2B3B"}
@@ -0,0 +1,273 @@
1
+ /**
2
+ * GraphExporter - 图谱导出器
3
+ * 将图谱数据导出为平台特定的引导文件
4
+ */
5
+ import { resolve, dirname } from 'path';
6
+ import { writeFile, readFile, access, mkdir } from 'fs/promises';
7
+ export class GraphExporter {
8
+ db;
9
+ projectDir;
10
+ semanticPath;
11
+ constructor(projectDir, db, semanticPath = '.sds/semantic-graph.json') {
12
+ this.projectDir = projectDir;
13
+ this.db = db;
14
+ this.semanticPath = resolve(projectDir, semanticPath);
15
+ }
16
+ /**
17
+ * 导出图谱
18
+ */
19
+ async export(options) {
20
+ const startTime = Date.now();
21
+ const errors = [];
22
+ try {
23
+ // 读取语义图谱(如果存在)
24
+ let semanticGraph = null;
25
+ if (await fileExists(this.semanticPath)) {
26
+ try {
27
+ const content = await readFile(this.semanticPath, 'utf-8');
28
+ semanticGraph = JSON.parse(content);
29
+ }
30
+ catch (error) {
31
+ errors.push(`Failed to read semantic graph: ${error.message}`);
32
+ }
33
+ }
34
+ // 根据格式生成内容
35
+ let content;
36
+ let outputPath;
37
+ switch (options.format) {
38
+ case 'claude-md':
39
+ content = this.generateClaudeMd(semanticGraph);
40
+ outputPath = options.outputPath || resolve(this.projectDir, '.claude', 'CLAUDE.md');
41
+ break;
42
+ case 'agents-md':
43
+ content = this.generateAgentsMd(semanticGraph);
44
+ outputPath = options.outputPath || resolve(this.projectDir, '.opencode', 'AGENTS.md');
45
+ break;
46
+ case 'json':
47
+ content = this.generateJson(semanticGraph);
48
+ outputPath = options.outputPath || resolve(this.projectDir, '.sds', 'project-context.json');
49
+ break;
50
+ default:
51
+ throw new Error(`Unsupported format: ${options.format}`);
52
+ }
53
+ // 确保目录存在
54
+ await mkdir(dirname(outputPath), { recursive: true });
55
+ // 写入文件
56
+ await writeFile(outputPath, content, 'utf-8');
57
+ return {
58
+ status: 'completed',
59
+ outputPath,
60
+ format: options.format,
61
+ durationMs: Date.now() - startTime,
62
+ errors
63
+ };
64
+ }
65
+ catch (error) {
66
+ errors.push(error.message);
67
+ return {
68
+ status: 'failed',
69
+ outputPath: '',
70
+ format: options.format,
71
+ durationMs: Date.now() - startTime,
72
+ errors
73
+ };
74
+ }
75
+ }
76
+ /**
77
+ * 生成 CLAUDE.md 内容
78
+ */
79
+ generateClaudeMd(semanticGraph) {
80
+ const stats = this.db.getStats();
81
+ const files = this.db.getAllFiles();
82
+ const modules = this.getModules(files);
83
+ let content = `# Project Code Map
84
+
85
+ > Generated by TrenchCraft sds graph | Last updated: ${new Date().toISOString()}
86
+
87
+ ## Tech Stack
88
+ ${this.generateTechStack(files)}
89
+
90
+ ## Directory Structure
91
+ ${this.generateDirectoryStructure(files)}
92
+
93
+ ## Module Map
94
+ ${this.generateModuleMap(modules, semanticGraph)}
95
+
96
+ ## Key Call Chains
97
+ ${this.generateCallChains()}
98
+
99
+ ## Graph Query Interface
100
+ When you need to explore the codebase further, use these tools:
101
+ - **Structure query**: \`sds graph query --sql "..."\`
102
+ - **Semantic query**: \`sds graph query --nl "..."\`
103
+ - **Template queries**:
104
+ - \`sds graph query --template entry-points\`
105
+ - \`sds graph query --template circular-deps\`
106
+ - \`sds graph query --template dead-code\`
107
+ - **Incremental update**: \`sds graph diff\`
108
+ - **Graph status**: \`sds graph status\`
109
+ `;
110
+ return content;
111
+ }
112
+ /**
113
+ * 生成 AGENTS.md 内容
114
+ */
115
+ generateAgentsMd(semanticGraph) {
116
+ const stats = this.db.getStats();
117
+ const files = this.db.getAllFiles();
118
+ const modules = this.getModules(files);
119
+ let content = `# AGENTS.md
120
+ <!-- trench-craft:begin -->
121
+ ## Project Code Map
122
+
123
+ > Generated by TrenchCraft sds graph | Last updated: ${new Date().toISOString()}
124
+
125
+ ### Tech Stack
126
+ ${this.generateTechStack(files)}
127
+
128
+ ### Module Map
129
+ ${this.generateModuleMap(modules, semanticGraph)}
130
+
131
+ ### Graph Query Interface
132
+ When you need to explore the codebase further, use these tools:
133
+ - **Structure query**: \`sds graph query --sql "..."\`
134
+ - **Semantic query**: \`sds graph query --nl "..."\`
135
+ - **Template queries**:
136
+ - \`sds graph query --template entry-points\`
137
+ - \`sds graph query --template circular-deps\`
138
+ - \`sds graph query --template dead-code\`
139
+ - **Incremental update**: \`sds graph diff\`
140
+ - **Graph status**: \`sds graph status\`
141
+ <!-- trench-craft:end -->
142
+ `;
143
+ return content;
144
+ }
145
+ /**
146
+ * 生成 JSON 内容
147
+ */
148
+ generateJson(semanticGraph) {
149
+ const stats = this.db.getStats();
150
+ const files = this.db.getAllFiles();
151
+ const modules = this.getModules(files);
152
+ const context = {
153
+ generatedAt: new Date().toISOString(),
154
+ stats: {
155
+ files: stats.filesIndexed,
156
+ functions: stats.functions,
157
+ classes: stats.classes,
158
+ interfaces: stats.interfaces,
159
+ callEdges: stats.callEdges,
160
+ importEdges: stats.importEdges
161
+ },
162
+ modules,
163
+ semantic: semanticGraph ? {
164
+ description: semanticGraph.projectSummary.description,
165
+ techStack: semanticGraph.projectSummary.techStack,
166
+ architecturePattern: semanticGraph.projectSummary.architecturePattern,
167
+ tours: semanticGraph.tours
168
+ } : null,
169
+ queryInterface: {
170
+ structure: 'sds graph query --sql "..."',
171
+ semantic: 'sds graph query --nl "..."',
172
+ templates: ['entry-points', 'circular-deps', 'dead-code']
173
+ }
174
+ };
175
+ return JSON.stringify(context, null, 2);
176
+ }
177
+ /**
178
+ * 生成技术栈信息
179
+ */
180
+ generateTechStack(files) {
181
+ const languages = new Set(files.map(f => f.lang));
182
+ const langList = Array.from(languages).map(l => `- **${l}**`).join('\n');
183
+ return `- **Languages**: ${Array.from(languages).join(', ')}
184
+ - **Total files**: ${files.length}
185
+ - **Indexed at**: ${new Date().toISOString()}`;
186
+ }
187
+ /**
188
+ * 生成目录结构
189
+ */
190
+ generateDirectoryStructure(files) {
191
+ const dirs = new Set();
192
+ for (const file of files) {
193
+ const parts = file.path.split('/');
194
+ let current = '';
195
+ for (let i = 0; i < parts.length - 1; i++) {
196
+ current += (current ? '/' : '') + parts[i];
197
+ dirs.add(current);
198
+ }
199
+ }
200
+ const sortedDirs = Array.from(dirs).sort();
201
+ const maxDepth = 3;
202
+ return sortedDirs
203
+ .filter(d => d.split('/').length <= maxDepth)
204
+ .map(d => `${' '.repeat(d.split('/').length - 1)}${d.split('/').pop()}/`)
205
+ .join('\n');
206
+ }
207
+ /**
208
+ * 获取模块信息
209
+ */
210
+ getModules(files) {
211
+ const modules = {};
212
+ for (const file of files) {
213
+ const parts = file.path.split('/');
214
+ const moduleName = parts.length > 1 ? parts[0] : 'root';
215
+ if (!modules[moduleName]) {
216
+ modules[moduleName] = [];
217
+ }
218
+ modules[moduleName].push(file.path);
219
+ }
220
+ return modules;
221
+ }
222
+ /**
223
+ * 生成模块映射
224
+ */
225
+ generateModuleMap(modules, semanticGraph) {
226
+ const lines = [];
227
+ for (const [name, files] of Object.entries(modules)) {
228
+ const semantic = semanticGraph?.modules[name];
229
+ lines.push(`### ${name}`);
230
+ lines.push(`- **Files**: ${files.length}`);
231
+ if (semantic) {
232
+ lines.push(`- **Description**: ${semantic.description}`);
233
+ }
234
+ lines.push('');
235
+ }
236
+ return lines.join('\n');
237
+ }
238
+ /**
239
+ * 生成调用链信息
240
+ */
241
+ generateCallChains() {
242
+ // 查询主要调用链
243
+ const chains = this.db.query(`
244
+ SELECT
245
+ f1.path as caller_file,
246
+ s1.name as caller_name,
247
+ f2.path as callee_file,
248
+ s2.name as callee_name
249
+ FROM call_graph cg
250
+ JOIN files f1 ON cg.caller_file_id = f1.id
251
+ JOIN symbols s1 ON cg.caller_symbol_id = s1.id
252
+ JOIN files f2 ON cg.callee_file_id = f2.id
253
+ JOIN symbols s2 ON cg.callee_symbol_id = s2.id
254
+ WHERE cg.relation_type = 'call'
255
+ LIMIT 10
256
+ `);
257
+ if (chains.length === 0) {
258
+ return 'No call chains detected.';
259
+ }
260
+ const lines = chains.map((c) => `- \`${c.caller_file}:${c.caller_name}\` → \`${c.callee_file}:${c.callee_name}\``);
261
+ return lines.join('\n');
262
+ }
263
+ }
264
+ async function fileExists(path) {
265
+ try {
266
+ await access(path);
267
+ return true;
268
+ }
269
+ catch {
270
+ return false;
271
+ }
272
+ }
273
+ //# sourceMappingURL=exporter.js.map