toolnet-memory 0.2.0 → 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 (341) hide show
  1. package/README.md +443 -70
  2. package/bin/toolnet-memory +66 -53
  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 +11 -5
  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/snapshot-cli.js +0 -58
  199. package/dist/src/project-manual/cli.js +0 -77
  200. package/dist/src/project-manual/index.js +0 -2
  201. package/dist/src/project-manual/manager.js +0 -147
  202. package/dist/src/project-manual/types.js +0 -1
  203. package/dist/src/retrieval/bm25/index.js +0 -1
  204. package/dist/src/retrieval/bm25/search.js +0 -1
  205. package/dist/src/retrieval/bm25.js +0 -30
  206. package/dist/src/retrieval/context-budget.js +0 -1
  207. package/dist/src/retrieval/context-builder.js +0 -22
  208. package/dist/src/retrieval/graph/index.js +0 -1
  209. package/dist/src/retrieval/graph/search.js +0 -1
  210. package/dist/src/retrieval/hybrid/hybrid-search.js +0 -1
  211. package/dist/src/retrieval/hybrid/index.js +0 -1
  212. package/dist/src/retrieval/hybrid-search.js +0 -68
  213. package/dist/src/retrieval/importance.js +0 -16
  214. package/dist/src/retrieval/index.js +0 -12
  215. package/dist/src/retrieval/query-analyzer.js +0 -32
  216. package/dist/src/retrieval/query-classifier.js +0 -1
  217. package/dist/src/retrieval/query-expansion.js +0 -1
  218. package/dist/src/retrieval/recency.js +0 -12
  219. package/dist/src/retrieval/reranker/index.js +0 -1
  220. package/dist/src/retrieval/reranker/reranker.js +0 -1
  221. package/dist/src/retrieval/retrieval-engine.js +0 -17
  222. package/dist/src/retrieval/tokenizer.js +0 -9
  223. package/dist/src/retrieval/type-priority.js +0 -10
  224. package/dist/src/retrieval/types.js +0 -1
  225. package/dist/src/retrieval/vector/index.js +0 -4
  226. package/dist/src/retrieval/vector/metadata-filter.js +0 -1
  227. package/dist/src/retrieval/vector/persistence.js +0 -67
  228. package/dist/src/retrieval/vector/search.js +0 -12
  229. package/dist/src/retrieval/vector/test-persistence.js +0 -36
  230. package/dist/src/retrieval/vector/upsert.js +0 -40
  231. package/dist/src/retrieval/vector/vector-store.js +0 -89
  232. package/dist/src/retrieval/vector-hybrid-engine.js +0 -91
  233. package/dist/src/runtime/bootstrap.js +0 -28
  234. package/dist/src/runtime/graceful.js +0 -17
  235. package/dist/src/runtime/index.js +0 -3
  236. package/dist/src/runtime/toolnet-memory-runtime.js +0 -156
  237. package/dist/src/security/encryption.js +0 -1
  238. package/dist/src/security/file-filter.js +0 -30
  239. package/dist/src/security/index.js +0 -3
  240. package/dist/src/security/sanitizer.js +0 -49
  241. package/dist/src/security/secret-scanner.js +0 -56
  242. package/dist/src/session/agy/adapter.js +0 -159
  243. package/dist/src/session/agy/cli.js +0 -87
  244. package/dist/src/session/agy/hook-installer.js +0 -62
  245. package/dist/src/session/agy/hook.js +0 -167
  246. package/dist/src/session/agy/index.js +0 -5
  247. package/dist/src/session/agy/project-resolver.js +0 -27
  248. package/dist/src/session/agy/recovery.js +0 -112
  249. package/dist/src/session/agy/transcript.js +0 -191
  250. package/dist/src/session/codex/adapter.js +0 -138
  251. package/dist/src/session/codex/cli.js +0 -236
  252. package/dist/src/session/codex/context-hook-installer.js +0 -70
  253. package/dist/src/session/codex/context-hook.js +0 -69
  254. package/dist/src/session/codex/discovery.js +0 -138
  255. package/dist/src/session/codex/index.js +0 -6
  256. package/dist/src/session/codex/notify-installer.js +0 -135
  257. package/dist/src/session/codex/project-resolver.js +0 -25
  258. package/dist/src/session/codex/recovery.js +0 -27
  259. package/dist/src/session/codex/rollout.js +0 -186
  260. package/dist/src/session/core.js +0 -239
  261. package/dist/src/session/identity.js +0 -57
  262. package/dist/src/session/index.js +0 -9
  263. package/dist/src/session/learner/cli.js +0 -62
  264. package/dist/src/session/learner/extractor.js +0 -461
  265. package/dist/src/session/learner/index.js +0 -4
  266. package/dist/src/session/learner/journal.js +0 -159
  267. package/dist/src/session/learner/learner.js +0 -124
  268. package/dist/src/session/learner/types.js +0 -1
  269. package/dist/src/session/opencode/adapter.js +0 -553
  270. package/dist/src/session/opencode/cli.js +0 -121
  271. package/dist/src/session/opencode/index.js +0 -2
  272. package/dist/src/session/opencode/plugin-installer.js +0 -230
  273. package/dist/src/session/store.js +0 -242
  274. package/dist/src/session/types.js +0 -1
  275. package/dist/src/session/utils.js +0 -47
  276. package/dist/src/session/wal.js +0 -303
  277. package/dist/src/snapshot/index.js +0 -2
  278. package/dist/src/snapshot/manager.js +0 -130
  279. package/dist/src/snapshot/test-snapshot.js +0 -28
  280. package/dist/src/snapshot/types.js +0 -1
  281. package/dist/src/storage/architecture-store.js +0 -37
  282. package/dist/src/storage/cleanup-health.js +0 -20
  283. package/dist/src/storage/code-analysis-store.js +0 -35
  284. package/dist/src/storage/code-chunk-store.js +0 -25
  285. package/dist/src/storage/code-graph-store.js +0 -24
  286. package/dist/src/storage/code-manifest-store.js +0 -24
  287. package/dist/src/storage/code-vector-store.js +0 -25
  288. package/dist/src/storage/github/client.js +0 -1
  289. package/dist/src/storage/github/index.js +0 -1
  290. package/dist/src/storage/google-drive/client.js +0 -1
  291. package/dist/src/storage/google-drive/index.js +0 -1
  292. package/dist/src/storage/huggingface/client.js +0 -116
  293. package/dist/src/storage/huggingface/index.js +0 -1
  294. package/dist/src/storage/index.js +0 -16
  295. package/dist/src/storage/list-bucket-raw.js +0 -14
  296. package/dist/src/storage/list-bucket-tree.js +0 -38
  297. package/dist/src/storage/local/client.js +0 -99
  298. package/dist/src/storage/local/index.js +0 -1
  299. package/dist/src/storage/memory-store.js +0 -30
  300. package/dist/src/storage/project/cleanup-layout-v1.js +0 -72
  301. package/dist/src/storage/project/folder.js +0 -15
  302. package/dist/src/storage/project/index.js +0 -3
  303. package/dist/src/storage/project/layout.js +0 -74
  304. package/dist/src/storage/project/migrate-layout-v2.js +0 -101
  305. package/dist/src/storage/project/migrate.js +0 -73
  306. package/dist/src/storage/project/scoped-provider.js +0 -165
  307. package/dist/src/storage/provider.js +0 -26
  308. package/dist/src/storage/retrying-provider.js +0 -23
  309. package/dist/src/storage/test-connection.js +0 -32
  310. package/dist/src/storage/type-resolution-store.js +0 -26
  311. package/dist/src/storage/types.js +0 -1
  312. package/dist/src/storage/vector-store.js +0 -30
  313. package/dist/src/storage/visualization-store.js +0 -25
  314. package/dist/src/sync/compressor.js +0 -1
  315. package/dist/src/sync/conflict-resolver.js +0 -1
  316. package/dist/src/sync/downloader.js +0 -1
  317. package/dist/src/sync/index.js +0 -1
  318. package/dist/src/sync/sync-engine.js +0 -1
  319. package/dist/src/sync/upload-queue.js +0 -1
  320. package/dist/src/utils/retry.js +0 -29
  321. package/dist/src/visualization/server.js +0 -270
  322. package/dist/src/work-continuity/brief-cache.js +0 -107
  323. package/dist/src/work-continuity/brief.js +0 -349
  324. package/dist/src/work-continuity/cli.js +0 -96
  325. package/dist/src/work-continuity/context-cli.js +0 -106
  326. package/dist/src/work-continuity/context-runtime-cli.js +0 -88
  327. package/dist/src/work-continuity/extractor.js +0 -339
  328. package/dist/src/work-continuity/handoff.js +0 -185
  329. package/dist/src/work-continuity/index.js +0 -14
  330. package/dist/src/work-continuity/injection.js +0 -84
  331. package/dist/src/work-continuity/journal.js +0 -49
  332. package/dist/src/work-continuity/learner.js +0 -127
  333. package/dist/src/work-continuity/reducer.js +0 -316
  334. package/dist/src/work-continuity/semantic-extractor.js +0 -360
  335. package/dist/src/work-continuity/semantic-journal.js +0 -55
  336. package/dist/src/work-continuity/semantic-learner.js +0 -125
  337. package/dist/src/work-continuity/semantic-reducer.js +0 -268
  338. package/dist/src/work-continuity/semantic-types.js +0 -1
  339. package/dist/src/work-continuity/types.js +0 -1
  340. package/dist/visualization/public/index.html +0 -2896
  341. package/dist/visualization/public/vendor/3d-force-graph.min.js +0 -5
@@ -1,197 +0,0 @@
1
- function normalize(value) {
2
- return value
3
- .replaceAll("\\", "/")
4
- .toLowerCase();
5
- }
6
- const EDGE_WEIGHT = {
7
- CALL_REFERENCE: 6,
8
- CALLS: 4,
9
- IMPORTS: 4,
10
- USES_TYPE: 4,
11
- WRITES: 5,
12
- INHERITS: 6,
13
- IMPLEMENTS: 6,
14
- ROUTE: 3,
15
- TESTS: 1,
16
- };
17
- export class LayerDetector {
18
- graph;
19
- constructor(graph) {
20
- this.graph = graph;
21
- }
22
- detect(projectId) {
23
- const symbols = this.graph.allSymbols(projectId);
24
- const edges = this.graph.allEdges(projectId);
25
- const symbolById = new Map(symbols.map((symbol) => [
26
- symbol.id,
27
- symbol,
28
- ]));
29
- const files = [
30
- ...new Set(symbols.map((symbol) => symbol.filePath)),
31
- ].sort();
32
- const result = new Map();
33
- /*
34
- * Phase 1:
35
- * deterministic path classification.
36
- */
37
- for (const filePath of files) {
38
- result.set(filePath, this.classifyPath(filePath));
39
- }
40
- /*
41
- * Phase 2:
42
- * propagate known layers through
43
- * dependency graph.
44
- *
45
- * Multiple passes giúp unknown -> known
46
- * lan truyền nhưng vẫn deterministic.
47
- */
48
- for (let pass = 0; pass < 3; pass++) {
49
- let changed = false;
50
- for (const filePath of files) {
51
- const current = result.get(filePath);
52
- if (!current ||
53
- current.layer !==
54
- "unknown") {
55
- continue;
56
- }
57
- const votes = new Map();
58
- for (const edge of edges) {
59
- const from = symbolById.get(edge.from);
60
- const to = symbolById.get(edge.to);
61
- if (!from ||
62
- !to ||
63
- from.filePath ===
64
- to.filePath) {
65
- continue;
66
- }
67
- let neighbor = null;
68
- if (from.filePath ===
69
- filePath) {
70
- neighbor =
71
- to.filePath;
72
- }
73
- else if (to.filePath ===
74
- filePath) {
75
- neighbor =
76
- from.filePath;
77
- }
78
- if (!neighbor) {
79
- continue;
80
- }
81
- const neighborLayer = result.get(neighbor);
82
- if (!neighborLayer ||
83
- neighborLayer.layer ===
84
- "unknown" ||
85
- neighborLayer.layer ===
86
- "tests") {
87
- continue;
88
- }
89
- const weight = EDGE_WEIGHT[edge.type] ?? 1;
90
- votes.set(neighborLayer.layer, (votes.get(neighborLayer.layer) ?? 0) + weight);
91
- }
92
- const best = [
93
- ...votes.entries(),
94
- ]
95
- .sort((a, b) => b[1] -
96
- a[1] ||
97
- a[0].localeCompare(b[0]))[0];
98
- if (best &&
99
- best[1] >= 4) {
100
- result.set(filePath, {
101
- filePath,
102
- layer: best[0],
103
- confidence: 0.65,
104
- reasons: [
105
- `graph-neighbor vote=${best[1]}`,
106
- ],
107
- });
108
- changed =
109
- true;
110
- }
111
- }
112
- if (!changed) {
113
- break;
114
- }
115
- }
116
- return files.map((filePath) => result.get(filePath));
117
- }
118
- classifyPath(filePath) {
119
- const path = normalize(filePath);
120
- if (path.startsWith("tests/") ||
121
- path.includes("/tests/") ||
122
- path.includes("__tests__") ||
123
- /\.(test|spec)\.[^.]+$/
124
- .test(path)) {
125
- return {
126
- filePath,
127
- layer: "tests",
128
- confidence: 1,
129
- reasons: [
130
- "test path",
131
- ],
132
- };
133
- }
134
- if (path.startsWith("bin/") ||
135
- path.includes("/mcp/") ||
136
- path.includes("/cli/") ||
137
- path.includes("/api/") ||
138
- path.includes("/routes/") ||
139
- path.includes("/hooks/")) {
140
- return {
141
- filePath,
142
- layer: "interface",
143
- confidence: 0.9,
144
- reasons: [
145
- "interface boundary",
146
- ],
147
- };
148
- }
149
- if (path.includes("/runtime/") ||
150
- path.includes("/processor/") ||
151
- path.includes("/retrieval/") ||
152
- path.includes("/snapshot/") ||
153
- path.includes("/code-intelligence/")) {
154
- return {
155
- filePath,
156
- layer: "application",
157
- confidence: 0.85,
158
- reasons: [
159
- "application orchestration",
160
- ],
161
- };
162
- }
163
- if (path.includes("/core/") ||
164
- path.includes("/memory/") ||
165
- /(^|\/)types\.[^.]+$/
166
- .test(path)) {
167
- return {
168
- filePath,
169
- layer: "domain",
170
- confidence: 0.9,
171
- reasons: [
172
- "domain/core logic",
173
- ],
174
- };
175
- }
176
- if (path.includes("/storage/") ||
177
- path.includes("/production/") ||
178
- path.includes("/security/") ||
179
- path.includes("/config/") ||
180
- path.includes("/utils/")) {
181
- return {
182
- filePath,
183
- layer: "infrastructure",
184
- confidence: 0.85,
185
- reasons: [
186
- "infrastructure boundary",
187
- ],
188
- };
189
- }
190
- return {
191
- filePath,
192
- layer: "unknown",
193
- confidence: 0.35,
194
- reasons: [],
195
- };
196
- }
197
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- export * from "./types.js";
2
- export * from "./smart-chunker.js";
@@ -1,125 +0,0 @@
1
- import { createHash, } from "node:crypto";
2
- import { readFile, } from "node:fs/promises";
3
- import { join, } from "node:path";
4
- import { Sanitizer, } from "../../security/sanitizer.js";
5
- function hash(value) {
6
- return createHash("sha256")
7
- .update(value)
8
- .digest("hex");
9
- }
10
- export class SmartCodeChunker {
11
- sanitizer = new Sanitizer();
12
- async build(projectId, rootPath, symbols, options = {}) {
13
- const maxLines = options.maxLines ?? 80;
14
- const overlapLines = options.overlapLines ?? 10;
15
- const byFile = new Map();
16
- for (const symbol of symbols) {
17
- const list = byFile.get(symbol.filePath) ?? [];
18
- list.push(symbol);
19
- byFile.set(symbol.filePath, list);
20
- }
21
- const chunks = [];
22
- for (const [filePath, fileSymbols] of byFile) {
23
- let text;
24
- try {
25
- text =
26
- await readFile(join(rootPath, filePath), "utf8");
27
- }
28
- catch {
29
- continue;
30
- }
31
- const lines = text.split(/\r?\n/);
32
- const semanticSymbols = fileSymbols.filter((symbol) => symbol.type !==
33
- "file" &&
34
- typeof symbol.startLine ===
35
- "number" &&
36
- typeof symbol.endLine ===
37
- "number");
38
- /*
39
- * Có symbol -> chunk theo symbol.
40
- * Không có symbol -> fallback chia file theo cửa sổ.
41
- */
42
- if (semanticSymbols.length >
43
- 0) {
44
- for (const symbol of semanticSymbols) {
45
- chunks.push(...this.chunkRange({
46
- projectId,
47
- filePath,
48
- lines,
49
- symbol,
50
- startLine: symbol.startLine,
51
- endLine: symbol.endLine,
52
- maxLines,
53
- overlapLines,
54
- }));
55
- }
56
- }
57
- else {
58
- chunks.push(...this.chunkRange({
59
- projectId,
60
- filePath,
61
- lines,
62
- startLine: 1,
63
- endLine: Math.max(1, lines.length),
64
- maxLines,
65
- overlapLines,
66
- }));
67
- }
68
- }
69
- return chunks;
70
- }
71
- chunkRange(input) {
72
- const { projectId, filePath, lines, symbol, maxLines, } = input;
73
- const overlapLines = Math.min(input.overlapLines, Math.max(0, maxLines - 1));
74
- const start = Math.max(1, input.startLine);
75
- const end = Math.min(lines.length, Math.max(start, input.endLine));
76
- const output = [];
77
- let cursor = start;
78
- let part = 0;
79
- while (cursor <= end) {
80
- const chunkEnd = Math.min(end, cursor +
81
- maxLines -
82
- 1);
83
- const raw = lines
84
- .slice(cursor - 1, chunkEnd)
85
- .join("\n")
86
- .trim();
87
- if (raw) {
88
- const content = this.sanitizer
89
- .sanitize(raw)
90
- .text;
91
- const contentHash = hash(content);
92
- const identity = [
93
- projectId,
94
- filePath,
95
- symbol?.id ?? "file",
96
- String(part),
97
- contentHash,
98
- ].join(":");
99
- output.push({
100
- id: hash(identity)
101
- .slice(0, 32),
102
- projectId,
103
- filePath,
104
- symbolId: symbol?.id,
105
- symbolName: symbol?.qualifiedName ??
106
- symbol?.name,
107
- symbolType: symbol?.type,
108
- startLine: cursor,
109
- endLine: chunkEnd,
110
- content,
111
- contentHash,
112
- });
113
- }
114
- if (chunkEnd >= end) {
115
- break;
116
- }
117
- cursor =
118
- chunkEnd -
119
- overlapLines +
120
- 1;
121
- part++;
122
- }
123
- return output;
124
- }
125
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,109 +0,0 @@
1
- import { execFile, } from "node:child_process";
2
- import { promisify, } from "node:util";
3
- const execFileAsync = promisify(execFile);
4
- function parseRanges(patch) {
5
- const ranges = [];
6
- const regex = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;
7
- for (const match of patch.matchAll(regex)) {
8
- const start = Number(match[1]);
9
- const count = Number(match[2] ?? 1);
10
- ranges.push({
11
- startLine: start,
12
- endLine: Math.max(start, start + count - 1),
13
- });
14
- }
15
- return ranges;
16
- }
17
- function mapStatus(value) {
18
- if (value.startsWith("A")) {
19
- return "added";
20
- }
21
- if (value.startsWith("D")) {
22
- return "deleted";
23
- }
24
- if (value.startsWith("R")) {
25
- return "renamed";
26
- }
27
- return "modified";
28
- }
29
- export async function readGitChanges(rootPath) {
30
- let names = "";
31
- try {
32
- const result = await execFileAsync("git", [
33
- "diff",
34
- "HEAD",
35
- "--name-status",
36
- "--no-renames",
37
- ], {
38
- cwd: rootPath,
39
- maxBuffer: 10 * 1024 * 1024,
40
- });
41
- names =
42
- result.stdout;
43
- }
44
- catch {
45
- return [];
46
- }
47
- const files = [];
48
- for (const line of names
49
- .split(/\r?\n/)
50
- .filter(Boolean)) {
51
- const [rawStatus, ...parts] = line.split("\t");
52
- const filePath = parts.at(-1);
53
- if (!filePath) {
54
- continue;
55
- }
56
- let patch = "";
57
- try {
58
- const result = await execFileAsync("git", [
59
- "diff",
60
- "HEAD",
61
- "--unified=0",
62
- "--",
63
- filePath,
64
- ], {
65
- cwd: rootPath,
66
- maxBuffer: 20 * 1024 * 1024,
67
- });
68
- patch =
69
- result.stdout;
70
- }
71
- catch {
72
- patch = "";
73
- }
74
- files.push({
75
- filePath,
76
- status: mapStatus(rawStatus),
77
- ranges: parseRanges(patch),
78
- });
79
- }
80
- /*
81
- * Git diff HEAD không bao gồm untracked.
82
- */
83
- try {
84
- const result = await execFileAsync("git", [
85
- "ls-files",
86
- "--others",
87
- "--exclude-standard",
88
- ], {
89
- cwd: rootPath,
90
- });
91
- for (const filePath of result.stdout
92
- .split(/\r?\n/)
93
- .filter(Boolean)) {
94
- if (files.some((item) => item.filePath ===
95
- filePath)) {
96
- continue;
97
- }
98
- files.push({
99
- filePath,
100
- status: "added",
101
- ranges: [],
102
- });
103
- }
104
- }
105
- catch {
106
- // Not fatal.
107
- }
108
- return files;
109
- }
@@ -1 +0,0 @@
1
- export * from "./git-diff.js";
@@ -1,26 +0,0 @@
1
- export function getArchitecture(graph, projectId) {
2
- const symbols = graph.allSymbols(projectId);
3
- const edges = graph.allEdges(projectId);
4
- const symbol = (type) => symbols.filter((item) => item.type === type).length;
5
- const edge = (type) => edges.filter((item) => item.type === type).length;
6
- return {
7
- files: symbol("file"),
8
- classes: symbol("class"),
9
- interfaces: symbol("interface"),
10
- functions: symbol("function"),
11
- methods: symbol("method"),
12
- properties: symbol("property"),
13
- routes: symbol("route"),
14
- symbols: symbols.length,
15
- edges: edges.length,
16
- calls: edge("CALLS"),
17
- callReferences: edge("CALL_REFERENCE"),
18
- imports: edge("IMPORTS"),
19
- inherits: edge("INHERITS"),
20
- implements: edge("IMPLEMENTS"),
21
- usesType: edge("USES_TYPE"),
22
- tests: edge("TESTS"),
23
- routeEdges: edge("ROUTE"),
24
- writes: edge("WRITES"),
25
- };
26
- }
@@ -1,213 +0,0 @@
1
- import { createHash, } from "node:crypto";
2
- import { dirname, extname, normalize, posix, } from "node:path";
3
- import { CodeGraphStore, } from "./graph-store.js";
4
- function edgeId(projectId, from, type, to) {
5
- return createHash("sha256")
6
- .update(`${projectId}:${from}:${type}:${to}`)
7
- .digest("hex")
8
- .slice(0, 24);
9
- }
10
- function cleanPath(value) {
11
- return normalize(value).replaceAll("\\", "/");
12
- }
13
- function resolveImportFile(fromFile, source, availableFiles) {
14
- if (!source.startsWith(".")) {
15
- return undefined;
16
- }
17
- const base = cleanPath(posix.join(dirname(fromFile), source));
18
- const extension = extname(base);
19
- let candidates;
20
- if (extension === ".js") {
21
- const stem = base.slice(0, -3);
22
- candidates = [
23
- `${stem}.ts`,
24
- `${stem}.tsx`,
25
- `${stem}.js`,
26
- `${stem}.jsx`,
27
- ];
28
- }
29
- else if (extension === ".mjs") {
30
- const stem = base.slice(0, -4);
31
- candidates = [
32
- `${stem}.mts`,
33
- `${stem}.ts`,
34
- `${stem}.mjs`,
35
- ];
36
- }
37
- else if (extension === ".cjs") {
38
- const stem = base.slice(0, -4);
39
- candidates = [
40
- `${stem}.cts`,
41
- `${stem}.ts`,
42
- `${stem}.cjs`,
43
- ];
44
- }
45
- else if (extension) {
46
- candidates = [base];
47
- }
48
- else {
49
- candidates = [
50
- `${base}.ts`,
51
- `${base}.tsx`,
52
- `${base}.mts`,
53
- `${base}.cts`,
54
- `${base}.js`,
55
- `${base}.jsx`,
56
- `${base}.mjs`,
57
- `${base}.cjs`,
58
- `${base}/index.ts`,
59
- `${base}/index.tsx`,
60
- `${base}/index.js`,
61
- `${base}/index.jsx`,
62
- ];
63
- }
64
- return candidates.find((candidate) => availableFiles.has(cleanPath(candidate)));
65
- }
66
- export class GraphBuilder {
67
- build(projectId, parsed) {
68
- const graph = new CodeGraphStore();
69
- const files = new Map();
70
- for (const file of parsed) {
71
- for (const symbol of file.symbols) {
72
- graph.addSymbol(symbol);
73
- if (symbol.type ===
74
- "file") {
75
- files.set(cleanPath(file.filePath), symbol);
76
- }
77
- }
78
- }
79
- const availableFiles = new Set(files.keys());
80
- for (const file of parsed) {
81
- const filePath = cleanPath(file.filePath);
82
- const fileNode = files.get(filePath);
83
- if (!fileNode) {
84
- continue;
85
- }
86
- // DEFINES
87
- for (const symbol of file.symbols) {
88
- if (symbol.id ===
89
- fileNode.id) {
90
- continue;
91
- }
92
- graph.addEdge(this.edge(projectId, fileNode.id, "DEFINES", symbol.id));
93
- }
94
- // IMPORTS
95
- for (const item of file.imports) {
96
- const targetPath = resolveImportFile(filePath, item.source, availableFiles);
97
- if (!targetPath) {
98
- continue;
99
- }
100
- const targetFile = files.get(targetPath);
101
- if (!targetFile) {
102
- continue;
103
- }
104
- graph.addEdge(this.edge(projectId, fileNode.id, "IMPORTS", targetFile.id, {
105
- source: item.source,
106
- }));
107
- }
108
- // INHERITS / IMPLEMENTS
109
- for (const relation of file.heritage) {
110
- const targets = graph.findByName(projectId, relation.targetName)
111
- .filter((symbol) => symbol.type ===
112
- "class" ||
113
- symbol.type ===
114
- "interface");
115
- for (const target of targets) {
116
- graph.addEdge(this.edge(projectId, relation.fromId, relation.type, target.id));
117
- }
118
- }
119
- // CALLS
120
- for (const call of file.calls) {
121
- if (!call.callerId) {
122
- continue;
123
- }
124
- const targets = this.resolveCallTargets(projectId, file, call.calleeName, call.qualifier, parsed, graph, availableFiles);
125
- for (const target of targets) {
126
- if (target.id ===
127
- call.callerId) {
128
- continue;
129
- }
130
- graph.addEdge(this.edge(projectId, call.callerId, "CALLS", target.id, {
131
- line: call.line,
132
- qualifier: call.qualifier,
133
- }));
134
- }
135
- }
136
- }
137
- return graph;
138
- }
139
- resolveCallTargets(projectId, file, calleeName, qualifier, parsed, graph, availableFiles) {
140
- const filePath = cleanPath(file.filePath);
141
- // Same-file symbol first.
142
- const sameFile = graph
143
- .findByName(projectId, calleeName)
144
- .filter((symbol) => cleanPath(symbol.filePath) ===
145
- filePath);
146
- if (!qualifier &&
147
- sameFile.length) {
148
- return sameFile;
149
- }
150
- // Namespace import: api.login()
151
- if (qualifier) {
152
- for (const imported of file.imports) {
153
- const namespace = imported.bindings
154
- .find((binding) => binding.kind ===
155
- "namespace" &&
156
- binding.localName ===
157
- qualifier);
158
- if (!namespace) {
159
- continue;
160
- }
161
- const targetPath = resolveImportFile(filePath, imported.source, availableFiles);
162
- if (!targetPath) {
163
- continue;
164
- }
165
- return graph
166
- .findByName(projectId, calleeName)
167
- .filter((symbol) => cleanPath(symbol.filePath) ===
168
- targetPath);
169
- }
170
- }
171
- // Named/default imported function.
172
- for (const imported of file.imports) {
173
- const binding = imported.bindings
174
- .find((item) => item.localName ===
175
- calleeName);
176
- if (!binding) {
177
- continue;
178
- }
179
- const targetPath = resolveImportFile(filePath, imported.source, availableFiles);
180
- if (!targetPath) {
181
- continue;
182
- }
183
- const targetName = binding.importedName ===
184
- "default"
185
- ? calleeName
186
- : binding.importedName;
187
- const target = graph
188
- .findByName(projectId, targetName)
189
- .filter((symbol) => cleanPath(symbol.filePath) ===
190
- targetPath);
191
- if (target.length) {
192
- return target;
193
- }
194
- }
195
- // Last fallback.
196
- return graph
197
- .findByName(projectId, calleeName)
198
- .filter((symbol) => symbol.type ===
199
- "function" ||
200
- symbol.type ===
201
- "method");
202
- }
203
- edge(projectId, from, type, to, metadata) {
204
- return {
205
- id: edgeId(projectId, from, type, to),
206
- projectId,
207
- from,
208
- to,
209
- type,
210
- metadata,
211
- };
212
- }
213
- }