toolnet-memory 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/README.md +55 -28
  2. package/bin/toolnet-memory +55 -55
  3. package/bundle/agy.js +88 -0
  4. package/bundle/codex.js +92 -0
  5. package/bundle/context-runtime.js +56 -0
  6. package/bundle/context.js +62 -0
  7. package/bundle/doctor.js +3 -0
  8. package/bundle/full-index.js +8 -0
  9. package/bundle/learner.js +8 -0
  10. package/bundle/mcp.js +7 -0
  11. package/bundle/opencode.js +314 -0
  12. package/bundle/project-manual.js +54 -0
  13. package/bundle/setup.js +31 -0
  14. package/bundle/snapshot.js +4 -0
  15. package/bundle/work-continuity.js +12 -0
  16. package/package.json +9 -6
  17. package/dist/packages/cli/commands.js +0 -1
  18. package/dist/packages/cli/index.js +0 -1
  19. package/dist/packages/sdk/client.js +0 -78
  20. package/dist/packages/sdk/index.js +0 -1
  21. package/dist/packages/sdk/types.js +0 -1
  22. package/dist/src/api/index.js +0 -1
  23. package/dist/src/api/routes/health.js +0 -1
  24. package/dist/src/api/routes/index.js +0 -1
  25. package/dist/src/api/routes/memory.js +0 -1
  26. package/dist/src/api/routes/projects.js +0 -1
  27. package/dist/src/api/routes/search.js +0 -1
  28. package/dist/src/api/server.js +0 -1
  29. package/dist/src/capture/activity-capture.js +0 -21
  30. package/dist/src/capture/command-capture.js +0 -12
  31. package/dist/src/capture/error-capture.js +0 -14
  32. package/dist/src/capture/event-deduplicator.js +0 -28
  33. package/dist/src/capture/event-queue.js +0 -20
  34. package/dist/src/capture/file-capture.js +0 -23
  35. package/dist/src/capture/index.js +0 -8
  36. package/dist/src/capture/session-capture.js +0 -18
  37. package/dist/src/capture/tool-capture.js +0 -13
  38. package/dist/src/code-intelligence/analysis/analysis-engine.js +0 -26
  39. package/dist/src/code-intelligence/analysis/dead-code-analyzer.js +0 -127
  40. package/dist/src/code-intelligence/analysis/dependency-analyzer.js +0 -66
  41. package/dist/src/code-intelligence/analysis/index.js +0 -4
  42. package/dist/src/code-intelligence/analysis/types.js +0 -1
  43. package/dist/src/code-intelligence/architecture/architecture-engine.js +0 -48
  44. package/dist/src/code-intelligence/architecture/clusters.js +0 -322
  45. package/dist/src/code-intelligence/architecture/entry-points.js +0 -150
  46. package/dist/src/code-intelligence/architecture/hotspots.js +0 -136
  47. package/dist/src/code-intelligence/architecture/index.js +0 -6
  48. package/dist/src/code-intelligence/architecture/layers.js +0 -197
  49. package/dist/src/code-intelligence/architecture/types.js +0 -1
  50. package/dist/src/code-intelligence/chunks/index.js +0 -2
  51. package/dist/src/code-intelligence/chunks/smart-chunker.js +0 -125
  52. package/dist/src/code-intelligence/chunks/types.js +0 -1
  53. package/dist/src/code-intelligence/git/git-diff.js +0 -109
  54. package/dist/src/code-intelligence/git/index.js +0 -1
  55. package/dist/src/code-intelligence/graph/architecture.js +0 -26
  56. package/dist/src/code-intelligence/graph/graph-builder.js +0 -213
  57. package/dist/src/code-intelligence/graph/graph-store.js +0 -57
  58. package/dist/src/code-intelligence/graph/index.js +0 -1
  59. package/dist/src/code-intelligence/graph/relationships.js +0 -1
  60. package/dist/src/code-intelligence/graph/trace.js +0 -65
  61. package/dist/src/code-intelligence/impact/blast-radius.js +0 -160
  62. package/dist/src/code-intelligence/impact/change-mapper.js +0 -69
  63. package/dist/src/code-intelligence/impact/edit-tool-detector.js +0 -92
  64. package/dist/src/code-intelligence/impact/impact-analyzer.js +0 -60
  65. package/dist/src/code-intelligence/impact/impact-guard.js +0 -33
  66. package/dist/src/code-intelligence/impact/index.js +0 -5
  67. package/dist/src/code-intelligence/incremental/file-hash.js +0 -8
  68. package/dist/src/code-intelligence/incremental/incremental-indexer.js +0 -106
  69. package/dist/src/code-intelligence/incremental/manifest-builder.js +0 -19
  70. package/dist/src/code-intelligence/incremental/manifest.js +0 -31
  71. package/dist/src/code-intelligence/index.js +0 -23
  72. package/dist/src/code-intelligence/indexer/file-watcher.js +0 -1
  73. package/dist/src/code-intelligence/indexer/incremental-indexer.js +0 -1
  74. package/dist/src/code-intelligence/indexer/index.js +0 -1
  75. package/dist/src/code-intelligence/indexer/repository-indexer.js +0 -31
  76. package/dist/src/code-intelligence/indexer/repository-scanner.js +0 -50
  77. package/dist/src/code-intelligence/parsers/index.js +0 -1
  78. package/dist/src/code-intelligence/parsers/tree-sitter/index.js +0 -1
  79. package/dist/src/code-intelligence/parsers/tree-sitter/languages.js +0 -1
  80. package/dist/src/code-intelligence/parsers/tree-sitter/parser.js +0 -1
  81. package/dist/src/code-intelligence/parsers/typescript-parser.js +0 -190
  82. package/dist/src/code-intelligence/query/graph-query-engine.js +0 -275
  83. package/dist/src/code-intelligence/query/index.js +0 -2
  84. package/dist/src/code-intelligence/query/types.js +0 -1
  85. package/dist/src/code-intelligence/resolution/index.js +0 -2
  86. package/dist/src/code-intelligence/resolution/types.js +0 -1
  87. package/dist/src/code-intelligence/resolution/typescript-resolver.js +0 -316
  88. package/dist/src/code-intelligence/rich/index.js +0 -1
  89. package/dist/src/code-intelligence/rich/rich-graph-enricher.js +0 -463
  90. package/dist/src/code-intelligence/semantic/index.js +0 -2
  91. package/dist/src/code-intelligence/semantic/semantic-code-engine.js +0 -213
  92. package/dist/src/code-intelligence/semantic/source-priority.js +0 -22
  93. package/dist/src/code-intelligence/symbols/index.js +0 -1
  94. package/dist/src/code-intelligence/symbols/reference-resolver.js +0 -21
  95. package/dist/src/code-intelligence/symbols/symbol-extractor.js +0 -1
  96. package/dist/src/code-intelligence/test-analysis.js +0 -72
  97. package/dist/src/code-intelligence/test-architecture.js +0 -67
  98. package/dist/src/code-intelligence/test-impact.js +0 -47
  99. package/dist/src/code-intelligence/test-incremental.js +0 -24
  100. package/dist/src/code-intelligence/test-index.js +0 -39
  101. package/dist/src/code-intelligence/test-resolution.js +0 -54
  102. package/dist/src/code-intelligence/test-rich-graph.js +0 -48
  103. package/dist/src/code-intelligence/test-semantic.js +0 -57
  104. package/dist/src/code-intelligence/test-visualization.js +0 -36
  105. package/dist/src/code-intelligence/types.js +0 -1
  106. package/dist/src/code-intelligence/visualization/index.js +0 -2
  107. package/dist/src/code-intelligence/visualization/types.js +0 -1
  108. package/dist/src/code-intelligence/visualization/visualization-builder.js +0 -104
  109. package/dist/src/core/config.js +0 -66
  110. package/dist/src/core/global-env.js +0 -70
  111. package/dist/src/core/importance.js +0 -30
  112. package/dist/src/core/index.js +0 -5
  113. package/dist/src/core/memory-engine.js +0 -183
  114. package/dist/src/core/project-manager.js +0 -243
  115. package/dist/src/core/types.js +0 -1
  116. package/dist/src/embeddings/batch-embedder.js +0 -1
  117. package/dist/src/embeddings/cache.js +0 -1
  118. package/dist/src/embeddings/embedder.js +0 -51
  119. package/dist/src/embeddings/index.js +0 -4
  120. package/dist/src/embeddings/local.js +0 -37
  121. package/dist/src/embeddings/provider.js +0 -1
  122. package/dist/src/embeddings/remote.js +0 -76
  123. package/dist/src/embeddings/test-connection.js +0 -16
  124. package/dist/src/hooks/after-edit.js +0 -3
  125. package/dist/src/hooks/after-tool.js +0 -3
  126. package/dist/src/hooks/auto-context.js +0 -68
  127. package/dist/src/hooks/auto-impact-guard.js +0 -94
  128. package/dist/src/hooks/auto-retrieval.js +0 -27
  129. package/dist/src/hooks/before-agent.js +0 -18
  130. package/dist/src/hooks/before-compact.js +0 -3
  131. package/dist/src/hooks/before-edit.js +0 -20
  132. package/dist/src/hooks/index.js +0 -11
  133. package/dist/src/hooks/runtime.js +0 -110
  134. package/dist/src/hooks/session-end.js +0 -3
  135. package/dist/src/hooks/session-start.js +0 -3
  136. package/dist/src/index.js +0 -22
  137. package/dist/src/mcp/bootstrap.js +0 -68
  138. package/dist/src/mcp/context.js +0 -1
  139. package/dist/src/mcp/index.js +0 -3
  140. package/dist/src/mcp/server.js +0 -45
  141. package/dist/src/mcp/tools/analyze-impact.js +0 -41
  142. package/dist/src/mcp/tools/dead-code.js +0 -55
  143. package/dist/src/mcp/tools/find-callers.js +0 -24
  144. package/dist/src/mcp/tools/find-dependencies.js +0 -57
  145. package/dist/src/mcp/tools/find-symbol.js +0 -7
  146. package/dist/src/mcp/tools/get-architecture.js +0 -11
  147. package/dist/src/mcp/tools/graph-dependents.js +0 -24
  148. package/dist/src/mcp/tools/graph-neighborhood.js +0 -58
  149. package/dist/src/mcp/tools/graph-path.js +0 -43
  150. package/dist/src/mcp/tools/graph-query-utils.js +0 -32
  151. package/dist/src/mcp/tools/impact-guard.js +0 -34
  152. package/dist/src/mcp/tools/index-repository.js +0 -1
  153. package/dist/src/mcp/tools/index.js +0 -20
  154. package/dist/src/mcp/tools/memory-decisions.js +0 -1
  155. package/dist/src/mcp/tools/memory-forget.js +0 -14
  156. package/dist/src/mcp/tools/memory-recent.js +0 -1
  157. package/dist/src/mcp/tools/memory-remember.js +0 -33
  158. package/dist/src/mcp/tools/memory-rules.js +0 -1
  159. package/dist/src/mcp/tools/memory-search.js +0 -18
  160. package/dist/src/mcp/tools/memory-todos.js +0 -1
  161. package/dist/src/mcp/tools/project-context.js +0 -25
  162. package/dist/src/mcp/tools/search-code.js +0 -21
  163. package/dist/src/mcp/tools/semantic-code-search.js +0 -33
  164. package/dist/src/mcp/tools/snapshot-create.js +0 -13
  165. package/dist/src/mcp/tools/snapshot-list.js +0 -7
  166. package/dist/src/mcp/tools/snapshot-restore.js +0 -13
  167. package/dist/src/mcp/tools/trace-calls.js +0 -37
  168. package/dist/src/memory/activity.js +0 -5
  169. package/dist/src/memory/conflict-detector.js +0 -105
  170. package/dist/src/memory/consolidator.js +0 -104
  171. package/dist/src/memory/decay.js +0 -59
  172. package/dist/src/memory/decisions.js +0 -3
  173. package/dist/src/memory/deduplicate.js +0 -25
  174. package/dist/src/memory/index.js +0 -11
  175. package/dist/src/memory/maintenance.js +0 -16
  176. package/dist/src/memory/remember.js +0 -3
  177. package/dist/src/memory/rules.js +0 -3
  178. package/dist/src/memory/search.js +0 -3
  179. package/dist/src/memory/summaries.js +0 -1
  180. package/dist/src/memory/todos.js +0 -3
  181. package/dist/src/processor/decision-extractor.js +0 -13
  182. package/dist/src/processor/importance-scorer.js +0 -22
  183. package/dist/src/processor/index.js +0 -7
  184. package/dist/src/processor/memory-extractor.js +0 -59
  185. package/dist/src/processor/memory-processor.js +0 -105
  186. package/dist/src/processor/rule-extractor.js +0 -13
  187. package/dist/src/processor/summarizer.js +0 -71
  188. package/dist/src/processor/todo-extractor.js +0 -12
  189. package/dist/src/production/config-check.js +0 -34
  190. package/dist/src/production/doctor.js +0 -58
  191. package/dist/src/production/full-index.js +0 -114
  192. package/dist/src/production/health.js +0 -58
  193. package/dist/src/production/index-pipeline.js +0 -151
  194. package/dist/src/production/index.js +0 -4
  195. package/dist/src/production/project-lock.js +0 -95
  196. package/dist/src/production/project-status.js +0 -16
  197. package/dist/src/production/recovery.js +0 -15
  198. package/dist/src/production/setup.js +0 -219
  199. package/dist/src/production/snapshot-cli.js +0 -58
  200. package/dist/src/project-manual/cli.js +0 -77
  201. package/dist/src/project-manual/index.js +0 -2
  202. package/dist/src/project-manual/manager.js +0 -147
  203. package/dist/src/project-manual/types.js +0 -1
  204. package/dist/src/retrieval/bm25/index.js +0 -1
  205. package/dist/src/retrieval/bm25/search.js +0 -1
  206. package/dist/src/retrieval/bm25.js +0 -30
  207. package/dist/src/retrieval/context-budget.js +0 -1
  208. package/dist/src/retrieval/context-builder.js +0 -22
  209. package/dist/src/retrieval/graph/index.js +0 -1
  210. package/dist/src/retrieval/graph/search.js +0 -1
  211. package/dist/src/retrieval/hybrid/hybrid-search.js +0 -1
  212. package/dist/src/retrieval/hybrid/index.js +0 -1
  213. package/dist/src/retrieval/hybrid-search.js +0 -68
  214. package/dist/src/retrieval/importance.js +0 -16
  215. package/dist/src/retrieval/index.js +0 -12
  216. package/dist/src/retrieval/query-analyzer.js +0 -32
  217. package/dist/src/retrieval/query-classifier.js +0 -1
  218. package/dist/src/retrieval/query-expansion.js +0 -1
  219. package/dist/src/retrieval/recency.js +0 -12
  220. package/dist/src/retrieval/reranker/index.js +0 -1
  221. package/dist/src/retrieval/reranker/reranker.js +0 -1
  222. package/dist/src/retrieval/retrieval-engine.js +0 -17
  223. package/dist/src/retrieval/tokenizer.js +0 -9
  224. package/dist/src/retrieval/type-priority.js +0 -10
  225. package/dist/src/retrieval/types.js +0 -1
  226. package/dist/src/retrieval/vector/index.js +0 -4
  227. package/dist/src/retrieval/vector/metadata-filter.js +0 -1
  228. package/dist/src/retrieval/vector/persistence.js +0 -67
  229. package/dist/src/retrieval/vector/search.js +0 -12
  230. package/dist/src/retrieval/vector/test-persistence.js +0 -36
  231. package/dist/src/retrieval/vector/upsert.js +0 -40
  232. package/dist/src/retrieval/vector/vector-store.js +0 -89
  233. package/dist/src/retrieval/vector-hybrid-engine.js +0 -91
  234. package/dist/src/runtime/bootstrap.js +0 -28
  235. package/dist/src/runtime/graceful.js +0 -17
  236. package/dist/src/runtime/index.js +0 -3
  237. package/dist/src/runtime/toolnet-memory-runtime.js +0 -156
  238. package/dist/src/security/encryption.js +0 -1
  239. package/dist/src/security/file-filter.js +0 -30
  240. package/dist/src/security/index.js +0 -3
  241. package/dist/src/security/sanitizer.js +0 -49
  242. package/dist/src/security/secret-scanner.js +0 -56
  243. package/dist/src/session/agy/adapter.js +0 -159
  244. package/dist/src/session/agy/cli.js +0 -87
  245. package/dist/src/session/agy/hook-installer.js +0 -62
  246. package/dist/src/session/agy/hook.js +0 -167
  247. package/dist/src/session/agy/index.js +0 -5
  248. package/dist/src/session/agy/project-resolver.js +0 -27
  249. package/dist/src/session/agy/recovery.js +0 -112
  250. package/dist/src/session/agy/transcript.js +0 -191
  251. package/dist/src/session/codex/adapter.js +0 -138
  252. package/dist/src/session/codex/cli.js +0 -236
  253. package/dist/src/session/codex/context-hook-installer.js +0 -70
  254. package/dist/src/session/codex/context-hook.js +0 -69
  255. package/dist/src/session/codex/discovery.js +0 -138
  256. package/dist/src/session/codex/index.js +0 -6
  257. package/dist/src/session/codex/notify-installer.js +0 -135
  258. package/dist/src/session/codex/project-resolver.js +0 -25
  259. package/dist/src/session/codex/recovery.js +0 -27
  260. package/dist/src/session/codex/rollout.js +0 -186
  261. package/dist/src/session/core.js +0 -239
  262. package/dist/src/session/identity.js +0 -57
  263. package/dist/src/session/index.js +0 -9
  264. package/dist/src/session/learner/cli.js +0 -62
  265. package/dist/src/session/learner/extractor.js +0 -461
  266. package/dist/src/session/learner/index.js +0 -4
  267. package/dist/src/session/learner/journal.js +0 -159
  268. package/dist/src/session/learner/learner.js +0 -124
  269. package/dist/src/session/learner/types.js +0 -1
  270. package/dist/src/session/opencode/adapter.js +0 -553
  271. package/dist/src/session/opencode/cli.js +0 -121
  272. package/dist/src/session/opencode/index.js +0 -2
  273. package/dist/src/session/opencode/plugin-installer.js +0 -230
  274. package/dist/src/session/store.js +0 -242
  275. package/dist/src/session/types.js +0 -1
  276. package/dist/src/session/utils.js +0 -47
  277. package/dist/src/session/wal.js +0 -303
  278. package/dist/src/snapshot/index.js +0 -2
  279. package/dist/src/snapshot/manager.js +0 -130
  280. package/dist/src/snapshot/test-snapshot.js +0 -28
  281. package/dist/src/snapshot/types.js +0 -1
  282. package/dist/src/storage/architecture-store.js +0 -37
  283. package/dist/src/storage/cleanup-health.js +0 -20
  284. package/dist/src/storage/code-analysis-store.js +0 -35
  285. package/dist/src/storage/code-chunk-store.js +0 -25
  286. package/dist/src/storage/code-graph-store.js +0 -24
  287. package/dist/src/storage/code-manifest-store.js +0 -24
  288. package/dist/src/storage/code-vector-store.js +0 -25
  289. package/dist/src/storage/github/client.js +0 -1
  290. package/dist/src/storage/github/index.js +0 -1
  291. package/dist/src/storage/google-drive/client.js +0 -1
  292. package/dist/src/storage/google-drive/index.js +0 -1
  293. package/dist/src/storage/huggingface/client.js +0 -116
  294. package/dist/src/storage/huggingface/index.js +0 -1
  295. package/dist/src/storage/index.js +0 -16
  296. package/dist/src/storage/list-bucket-raw.js +0 -14
  297. package/dist/src/storage/list-bucket-tree.js +0 -38
  298. package/dist/src/storage/local/client.js +0 -99
  299. package/dist/src/storage/local/index.js +0 -1
  300. package/dist/src/storage/memory-store.js +0 -30
  301. package/dist/src/storage/project/cleanup-layout-v1.js +0 -72
  302. package/dist/src/storage/project/folder.js +0 -15
  303. package/dist/src/storage/project/index.js +0 -3
  304. package/dist/src/storage/project/layout.js +0 -74
  305. package/dist/src/storage/project/migrate-layout-v2.js +0 -101
  306. package/dist/src/storage/project/migrate.js +0 -73
  307. package/dist/src/storage/project/scoped-provider.js +0 -165
  308. package/dist/src/storage/provider.js +0 -26
  309. package/dist/src/storage/retrying-provider.js +0 -23
  310. package/dist/src/storage/test-connection.js +0 -32
  311. package/dist/src/storage/type-resolution-store.js +0 -26
  312. package/dist/src/storage/types.js +0 -1
  313. package/dist/src/storage/vector-store.js +0 -30
  314. package/dist/src/storage/visualization-store.js +0 -25
  315. package/dist/src/sync/compressor.js +0 -1
  316. package/dist/src/sync/conflict-resolver.js +0 -1
  317. package/dist/src/sync/downloader.js +0 -1
  318. package/dist/src/sync/index.js +0 -1
  319. package/dist/src/sync/sync-engine.js +0 -1
  320. package/dist/src/sync/upload-queue.js +0 -1
  321. package/dist/src/utils/retry.js +0 -29
  322. package/dist/src/visualization/server.js +0 -270
  323. package/dist/src/work-continuity/brief-cache.js +0 -107
  324. package/dist/src/work-continuity/brief.js +0 -349
  325. package/dist/src/work-continuity/cli.js +0 -96
  326. package/dist/src/work-continuity/context-cli.js +0 -106
  327. package/dist/src/work-continuity/context-runtime-cli.js +0 -88
  328. package/dist/src/work-continuity/extractor.js +0 -339
  329. package/dist/src/work-continuity/handoff.js +0 -185
  330. package/dist/src/work-continuity/index.js +0 -14
  331. package/dist/src/work-continuity/injection.js +0 -84
  332. package/dist/src/work-continuity/journal.js +0 -49
  333. package/dist/src/work-continuity/learner.js +0 -127
  334. package/dist/src/work-continuity/reducer.js +0 -316
  335. package/dist/src/work-continuity/semantic-extractor.js +0 -360
  336. package/dist/src/work-continuity/semantic-journal.js +0 -55
  337. package/dist/src/work-continuity/semantic-learner.js +0 -125
  338. package/dist/src/work-continuity/semantic-reducer.js +0 -268
  339. package/dist/src/work-continuity/semantic-types.js +0 -1
  340. package/dist/src/work-continuity/types.js +0 -1
  341. package/dist/visualization/public/index.html +0 -2896
  342. package/dist/visualization/public/vendor/3d-force-graph.min.js +0 -5
@@ -1,57 +0,0 @@
1
- export class CodeGraphStore {
2
- symbols = new Map();
3
- edges = new Map();
4
- addSymbol(symbol) {
5
- this.symbols.set(symbol.id, symbol);
6
- }
7
- addEdge(edge) {
8
- this.edges.set(edge.id, edge);
9
- }
10
- getSymbol(id) {
11
- return this.symbols.get(id);
12
- }
13
- findByName(projectId, name) {
14
- return [
15
- ...this.symbols.values(),
16
- ].filter((symbol) => symbol.projectId ===
17
- projectId &&
18
- (symbol.name ===
19
- name ||
20
- symbol.qualifiedName ===
21
- name));
22
- }
23
- allSymbols(projectId) {
24
- return [
25
- ...this.symbols.values(),
26
- ].filter((symbol) => symbol.projectId ===
27
- projectId);
28
- }
29
- allEdges(projectId) {
30
- return [
31
- ...this.edges.values(),
32
- ].filter((edge) => edge.projectId ===
33
- projectId);
34
- }
35
- import(symbols, edges) {
36
- for (const symbol of symbols) {
37
- this.addSymbol(symbol);
38
- }
39
- for (const edge of edges) {
40
- this.addEdge(edge);
41
- }
42
- }
43
- clearProject(projectId) {
44
- for (const [id, symbol] of this.symbols) {
45
- if (symbol.projectId ===
46
- projectId) {
47
- this.symbols.delete(id);
48
- }
49
- }
50
- for (const [id, edge] of this.edges) {
51
- if (edge.projectId ===
52
- projectId) {
53
- this.edges.delete(id);
54
- }
55
- }
56
- }
57
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,65 +0,0 @@
1
- export class CallGraphTracer {
2
- graph;
3
- constructor(graph) {
4
- this.graph = graph;
5
- }
6
- callees(projectId, symbolId, maxDepth = 3) {
7
- return this.walk(projectId, symbolId, "out", maxDepth);
8
- }
9
- callers(projectId, symbolId, maxDepth = 3) {
10
- return this.walk(projectId, symbolId, "in", maxDepth);
11
- }
12
- walk(projectId, startId, direction, maxDepth) {
13
- const result = [];
14
- const visited = new Set([
15
- startId,
16
- ]);
17
- const queue = [
18
- {
19
- id: startId,
20
- depth: 0,
21
- },
22
- ];
23
- const edges = this.graph
24
- .allEdges(projectId)
25
- .filter((edge) => edge.type === "CALLS" ||
26
- edge.type === "CALL_REFERENCE");
27
- while (queue.length) {
28
- const current = queue.shift();
29
- if (current.depth >=
30
- maxDepth) {
31
- continue;
32
- }
33
- const related = direction ===
34
- "out"
35
- ? edges.filter((edge) => edge.from ===
36
- current.id)
37
- : edges.filter((edge) => edge.to ===
38
- current.id);
39
- for (const edge of related) {
40
- const nextId = direction ===
41
- "out"
42
- ? edge.to
43
- : edge.from;
44
- if (visited.has(nextId)) {
45
- continue;
46
- }
47
- visited.add(nextId);
48
- const symbol = this.graph.getSymbol(nextId);
49
- if (!symbol) {
50
- continue;
51
- }
52
- const depth = current.depth + 1;
53
- result.push({
54
- symbol,
55
- depth,
56
- });
57
- queue.push({
58
- id: nextId,
59
- depth,
60
- });
61
- }
62
- }
63
- return result;
64
- }
65
- }
@@ -1,160 +0,0 @@
1
- const RELATION_WEIGHT = {
2
- CALLS: 4,
3
- CALL_REFERENCE: 6,
4
- USES_TYPE: 4,
5
- TESTS: 2,
6
- ROUTE: 4,
7
- WRITES: 3,
8
- IMPORTS: 3,
9
- INHERITS: 5,
10
- IMPLEMENTS: 5,
11
- DEFINES: 1,
12
- };
13
- function riskLevel(score) {
14
- if (score >= 30) {
15
- return "CRITICAL";
16
- }
17
- if (score >= 16) {
18
- return "HIGH";
19
- }
20
- if (score >= 6) {
21
- return "MEDIUM";
22
- }
23
- return "LOW";
24
- }
25
- function isTestFile(path) {
26
- const value = path
27
- .toLowerCase()
28
- .replaceAll("\\", "/");
29
- return (value.startsWith("tests/") ||
30
- value.includes("/tests/") ||
31
- value.includes("__tests__") ||
32
- /\.(test|spec)\.[^.]+$/
33
- .test(value));
34
- }
35
- export class BlastRadiusAnalyzer {
36
- graph;
37
- constructor(graph) {
38
- this.graph = graph;
39
- }
40
- analyze(projectId, changedSymbols, maxDepth = 4) {
41
- const edges = this.graph
42
- .allEdges(projectId);
43
- const impacted = new Map();
44
- let score = 0;
45
- for (const changed of changedSymbols) {
46
- if (changed.fileStatus ===
47
- "deleted") {
48
- score += 8;
49
- }
50
- else if (changed.fileStatus ===
51
- "renamed") {
52
- score += 5;
53
- }
54
- else {
55
- score += 2;
56
- }
57
- if (changed.symbol.type ===
58
- "interface") {
59
- score += 5;
60
- }
61
- if (changed.symbol.type ===
62
- "class") {
63
- score += 3;
64
- }
65
- const visited = new Set([
66
- changed.symbol.id,
67
- ]);
68
- const queue = [
69
- {
70
- id: changed.symbol.id,
71
- depth: 0,
72
- },
73
- ];
74
- while (queue.length) {
75
- const current = queue.shift();
76
- if (current.depth >=
77
- maxDepth) {
78
- continue;
79
- }
80
- /*
81
- * Blast radius đi NGƯỢC dependency:
82
- *
83
- * B thay đổi
84
- * A CALLS B
85
- * => A có nguy cơ ảnh hưởng.
86
- */
87
- const incoming = edges.filter((edge) => edge.to ===
88
- current.id &&
89
- [
90
- "CALLS",
91
- "CALL_REFERENCE",
92
- "USES_TYPE",
93
- "TESTS",
94
- "ROUTE",
95
- "WRITES",
96
- "IMPORTS",
97
- "INHERITS",
98
- "IMPLEMENTS",
99
- "DEFINES",
100
- ].includes(edge.type));
101
- for (const edge of incoming) {
102
- if (visited.has(edge.from)) {
103
- continue;
104
- }
105
- visited.add(edge.from);
106
- const symbol = this.graph.getSymbol(edge.from);
107
- if (!symbol) {
108
- continue;
109
- }
110
- const depth = current.depth + 1;
111
- const key = `${changed.symbol.id}:${symbol.id}`;
112
- impacted.set(key, {
113
- symbol,
114
- relation: edge.type,
115
- depth,
116
- sourceSymbolId: changed.symbol.id,
117
- });
118
- const relationWeight = RELATION_WEIGHT[edge.type] ?? 1;
119
- score +=
120
- Math.max(1, relationWeight -
121
- (depth - 1));
122
- queue.push({
123
- id: symbol.id,
124
- depth,
125
- });
126
- }
127
- }
128
- }
129
- const impactedList = [...impacted.values()]
130
- .sort((a, b) => a.depth -
131
- b.depth);
132
- const impactedFiles = [
133
- ...new Set(impactedList.map((item) => item.symbol
134
- .filePath)),
135
- ];
136
- /*
137
- * Nếu graph đã index tests,
138
- * ưu tiên đề nghị đúng test liên quan.
139
- */
140
- const suggestedTests = impactedFiles.filter(isTestFile);
141
- /*
142
- * Nếu không tìm thấy test trực tiếp,
143
- * trả file production cần verify.
144
- */
145
- if (suggestedTests.length ===
146
- 0) {
147
- suggestedTests.push(...impactedFiles
148
- .filter((file) => !isTestFile(file))
149
- .slice(0, 10));
150
- }
151
- return {
152
- risk: riskLevel(score),
153
- riskScore: score,
154
- changedSymbols,
155
- impacted: impactedList,
156
- impactedFiles,
157
- suggestedTests,
158
- };
159
- }
160
- }
@@ -1,69 +0,0 @@
1
- function intersects(symbol, file) {
2
- /*
3
- * Nếu không lấy được line diff:
4
- * coi toàn file bị thay đổi.
5
- */
6
- if (file.ranges.length === 0) {
7
- return true;
8
- }
9
- if (typeof symbol.startLine !==
10
- "number" ||
11
- typeof symbol.endLine !==
12
- "number") {
13
- return false;
14
- }
15
- return file.ranges.some((range) => symbol.startLine <=
16
- range.endLine &&
17
- symbol.endLine >=
18
- range.startLine);
19
- }
20
- export class ChangeMapper {
21
- graph;
22
- constructor(graph) {
23
- this.graph = graph;
24
- }
25
- map(projectId, changes) {
26
- const symbols = this.graph.allSymbols(projectId);
27
- const output = [];
28
- for (const file of changes) {
29
- const fileSymbols = symbols.filter((symbol) => symbol.filePath ===
30
- file.filePath);
31
- const semanticSymbols = fileSymbols.filter((symbol) => symbol.type !==
32
- "file");
33
- const direct = semanticSymbols.filter((symbol) => intersects(symbol, file));
34
- /*
35
- * Nếu diff nằm ngoài function/class,
36
- * vẫn đưa file node vào blast radius.
37
- */
38
- if (direct.length === 0) {
39
- const fileNode = fileSymbols.find((symbol) => symbol.type ===
40
- "file");
41
- if (fileNode) {
42
- output.push({
43
- symbol: fileNode,
44
- fileStatus: file.status,
45
- direct: true,
46
- });
47
- }
48
- continue;
49
- }
50
- for (const symbol of direct) {
51
- output.push({
52
- symbol,
53
- fileStatus: file.status,
54
- direct: true,
55
- });
56
- }
57
- }
58
- return output;
59
- }
60
- mapFile(projectId, filePath) {
61
- return this.map(projectId, [
62
- {
63
- filePath,
64
- status: "modified",
65
- ranges: [],
66
- },
67
- ]);
68
- }
69
- }
@@ -1,92 +0,0 @@
1
- const EDIT_TOOL = /(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i;
2
- const PATH_KEYS = new Set([
3
- "path",
4
- "filepath",
5
- "file_path",
6
- "filename",
7
- "file",
8
- "target",
9
- "targetpath",
10
- "target_path",
11
- "sourcepath",
12
- "source_path",
13
- ]);
14
- function normalizePath(value) {
15
- return value
16
- .trim()
17
- .replace(/^["']|["']$/g, "")
18
- .replace(/^a\//, "")
19
- .replace(/^b\//, "")
20
- .replaceAll("\\", "/");
21
- }
22
- function looksLikeFile(value) {
23
- return (value.length > 0 &&
24
- value.length < 500 &&
25
- !value.includes("\n") &&
26
- /(^|\/)[^/]+\.[A-Za-z0-9]+$/
27
- .test(value));
28
- }
29
- function extractPatchPaths(patch) {
30
- const output = [];
31
- const patterns = [
32
- /^\*\*\* (?:Update|Add|Delete) File:\s*(.+)$/gm,
33
- /^\+\+\+\s+b\/(.+)$/gm,
34
- /^---\s+a\/(.+)$/gm,
35
- ];
36
- for (const regex of patterns) {
37
- for (const match of patch.matchAll(regex)) {
38
- if (match[1]) {
39
- output.push(normalizePath(match[1]));
40
- }
41
- }
42
- }
43
- return output;
44
- }
45
- function walk(value, output, key) {
46
- if (typeof value === "string") {
47
- const normalizedKey = key?.toLowerCase();
48
- if (normalizedKey &&
49
- PATH_KEYS.has(normalizedKey) &&
50
- looksLikeFile(value)) {
51
- output.add(normalizePath(value));
52
- }
53
- /*
54
- * apply_patch thường nhét đường dẫn
55
- * bên trong một chuỗi patch lớn.
56
- */
57
- if (value.includes("*** Update File:") ||
58
- value.includes("*** Add File:") ||
59
- value.includes("*** Delete File:") ||
60
- value.includes("+++ b/")) {
61
- for (const path of extractPatchPaths(value)) {
62
- output.add(path);
63
- }
64
- }
65
- return;
66
- }
67
- if (Array.isArray(value)) {
68
- for (const item of value) {
69
- walk(item, output, key);
70
- }
71
- return;
72
- }
73
- if (value &&
74
- typeof value === "object") {
75
- for (const [childKey, child] of Object.entries(value)) {
76
- walk(child, output, childKey);
77
- }
78
- }
79
- }
80
- export function isCodeMutationTool(tool) {
81
- return EDIT_TOOL.test(tool.toLowerCase());
82
- }
83
- export function extractEditedFiles(tool, input) {
84
- if (!isCodeMutationTool(tool)) {
85
- return [];
86
- }
87
- const output = new Set();
88
- walk(input, output);
89
- return [
90
- ...output,
91
- ];
92
- }
@@ -1,60 +0,0 @@
1
- export class ImpactAnalyzer {
2
- graph;
3
- constructor(graph) {
4
- this.graph = graph;
5
- }
6
- analyze(projectId, symbolId, maxDepth = 4) {
7
- const edges = this.graph
8
- .allEdges(projectId);
9
- const visited = new Set([
10
- symbolId,
11
- ]);
12
- const queue = [
13
- {
14
- id: symbolId,
15
- depth: 0,
16
- },
17
- ];
18
- const result = [];
19
- while (queue.length) {
20
- const current = queue.shift();
21
- if (current.depth >=
22
- maxDepth) {
23
- continue;
24
- }
25
- /*
26
- * Reverse relationships:
27
- * "Ai phụ thuộc vào symbol này?"
28
- */
29
- const incoming = edges.filter((edge) => edge.to ===
30
- current.id &&
31
- [
32
- "CALLS",
33
- "IMPORTS",
34
- "INHERITS",
35
- "IMPLEMENTS",
36
- ].includes(edge.type));
37
- for (const edge of incoming) {
38
- if (visited.has(edge.from)) {
39
- continue;
40
- }
41
- visited.add(edge.from);
42
- const symbol = this.graph.getSymbol(edge.from);
43
- if (!symbol) {
44
- continue;
45
- }
46
- const depth = current.depth + 1;
47
- result.push({
48
- symbol,
49
- depth,
50
- relation: edge.type,
51
- });
52
- queue.push({
53
- id: edge.from,
54
- depth,
55
- });
56
- }
57
- }
58
- return result;
59
- }
60
- }
@@ -1,33 +0,0 @@
1
- import { readGitChanges, } from "../git/git-diff.js";
2
- import { ChangeMapper, } from "./change-mapper.js";
3
- import { BlastRadiusAnalyzer, } from "./blast-radius.js";
4
- export class ImpactGuard {
5
- graph;
6
- mapper;
7
- blast;
8
- constructor(graph) {
9
- this.graph = graph;
10
- this.mapper =
11
- new ChangeMapper(graph);
12
- this.blast =
13
- new BlastRadiusAnalyzer(graph);
14
- }
15
- async analyzeGitDiff(projectId, rootPath, options = {}) {
16
- const changes = await readGitChanges(rootPath);
17
- const changedSymbols = this.mapper.map(projectId, changes);
18
- const result = this.blast.analyze(projectId, changedSymbols, options.maxDepth ?? 4);
19
- return {
20
- mode: "git_diff",
21
- changes,
22
- ...result,
23
- };
24
- }
25
- analyzeFile(projectId, filePath, options = {}) {
26
- const changedSymbols = this.mapper.mapFile(projectId, filePath);
27
- return {
28
- mode: "planned_file",
29
- filePath,
30
- ...this.blast.analyze(projectId, changedSymbols, options.maxDepth ?? 4),
31
- };
32
- }
33
- }
@@ -1,5 +0,0 @@
1
- export * from "./impact-analyzer.js";
2
- export * from "./change-mapper.js";
3
- export * from "./blast-radius.js";
4
- export * from "./impact-guard.js";
5
- export * from "./edit-tool-detector.js";
@@ -1,8 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { readFile } from "node:fs/promises";
3
- export async function hashFile(path) {
4
- const content = await readFile(path);
5
- return createHash("sha256")
6
- .update(content)
7
- .digest("hex");
8
- }
@@ -1,106 +0,0 @@
1
- import { PersistentCodeGraphStore, } from "../../storage/code-graph-store.js";
2
- import { PersistentCodeManifestStore, } from "../../storage/code-manifest-store.js";
3
- import { buildManifest } from "./manifest-builder.js";
4
- import { diffManifest } from "./manifest.js";
5
- import { parseTypeScriptFile } from "../parsers/typescript-parser.js";
6
- import { GraphBuilder } from "../graph/graph-builder.js";
7
- import { CodeGraphStore } from "../graph/graph-store.js";
8
- export class IncrementalRepositoryIndexer {
9
- storage;
10
- constructor(storage) {
11
- this.storage = storage;
12
- }
13
- async index(projectId, rootPath) {
14
- const manifestStore = new PersistentCodeManifestStore(this.storage);
15
- const graphStore = new PersistentCodeGraphStore(this.storage);
16
- const previousManifest = await manifestStore.load(projectId);
17
- const previousGraph = await graphStore.load(projectId);
18
- const currentManifest = await buildManifest(projectId, rootPath);
19
- const diff = diffManifest(previousManifest, currentManifest);
20
- const changed = [
21
- ...diff.added,
22
- ...diff.modified,
23
- ];
24
- // Nothing changed.
25
- if (previousManifest &&
26
- previousGraph &&
27
- changed.length === 0 &&
28
- diff.deleted.length === 0) {
29
- return {
30
- firstRun: false,
31
- scanned: Object.keys(currentManifest.files).length,
32
- parsed: 0,
33
- added: 0,
34
- modified: 0,
35
- deleted: 0,
36
- unchanged: diff.unchanged.length,
37
- symbols: previousGraph.symbols.length,
38
- edges: previousGraph.edges.length,
39
- saved: false,
40
- };
41
- }
42
- /*
43
- * Preserve parsed symbol data from unchanged files.
44
- * Reparse only ADDED / MODIFIED files.
45
- */
46
- const preservedSymbols = previousGraph?.symbols.filter((symbol) => diff.unchanged.includes(symbol.filePath)) ?? [];
47
- const parsed = [];
48
- for (const filePath of changed) {
49
- parsed.push(await parseTypeScriptFile(projectId, rootPath, filePath));
50
- }
51
- /*
52
- * Build graph for changed files.
53
- */
54
- const changedGraph = new GraphBuilder().build(projectId, parsed);
55
- /*
56
- * Rebuild final graph from preserved + changed symbols.
57
- *
58
- * CALL relationships can cross file boundaries, so after collecting
59
- * current symbols we reconstruct CALL edges from parsed data where
60
- * available and preserve valid unchanged edges.
61
- */
62
- const finalGraph = new CodeGraphStore();
63
- for (const symbol of preservedSymbols) {
64
- finalGraph.addSymbol(symbol);
65
- }
66
- for (const symbol of changedGraph.allSymbols(projectId)) {
67
- finalGraph.addSymbol(symbol);
68
- }
69
- const validIds = new Set(finalGraph
70
- .allSymbols(projectId)
71
- .map((symbol) => symbol.id));
72
- for (const edge of previousGraph?.edges ?? []) {
73
- if (validIds.has(edge.from) &&
74
- validIds.has(edge.to) &&
75
- !changed.includes(previousGraph.symbols.find((symbol) => symbol.id === edge.from)?.filePath ?? "") &&
76
- !changed.includes(previousGraph.symbols.find((symbol) => symbol.id === edge.to)?.filePath ?? "")) {
77
- finalGraph.addEdge(edge);
78
- }
79
- }
80
- for (const edge of changedGraph.allEdges(projectId)) {
81
- finalGraph.addEdge(edge);
82
- }
83
- const snapshot = {
84
- version: 1,
85
- projectId,
86
- updatedAt: new Date().toISOString(),
87
- files: Object.keys(currentManifest.files).length,
88
- symbols: finalGraph.allSymbols(projectId),
89
- edges: finalGraph.allEdges(projectId),
90
- };
91
- await graphStore.save(snapshot);
92
- await manifestStore.save(currentManifest);
93
- return {
94
- firstRun: previousManifest === null,
95
- scanned: Object.keys(currentManifest.files).length,
96
- parsed: changed.length,
97
- added: diff.added.length,
98
- modified: diff.modified.length,
99
- deleted: diff.deleted.length,
100
- unchanged: diff.unchanged.length,
101
- symbols: snapshot.symbols.length,
102
- edges: snapshot.edges.length,
103
- saved: true,
104
- };
105
- }
106
- }
@@ -1,19 +0,0 @@
1
- import { join } from "node:path";
2
- import { scanRepository } from "../indexer/repository-scanner.js";
3
- import { hashFile } from "./file-hash.js";
4
- export async function buildManifest(projectId, rootPath) {
5
- const paths = await scanRepository(rootPath);
6
- const files = {};
7
- for (const path of paths) {
8
- files[path] = {
9
- path,
10
- hash: await hashFile(join(rootPath, path)),
11
- };
12
- }
13
- return {
14
- version: 1,
15
- projectId,
16
- updatedAt: new Date().toISOString(),
17
- files,
18
- };
19
- }