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,463 +0,0 @@
1
- import { createHash, } from "node:crypto";
2
- import { dirname, relative, resolve, } from "node:path";
3
- import ts from "typescript";
4
- function normalize(value) {
5
- return value
6
- .replaceAll("\\", "/")
7
- .replace(/^\.\//, "");
8
- }
9
- function id(...parts) {
10
- return createHash("sha256")
11
- .update(parts.join(":"))
12
- .digest("hex")
13
- .slice(0, 24);
14
- }
15
- function lineOf(source, node) {
16
- return source
17
- .getLineAndCharacterOfPosition(node.getStart(source)).line + 1;
18
- }
19
- const ROUTE_METHODS = new Set([
20
- "get",
21
- "post",
22
- "put",
23
- "patch",
24
- "delete",
25
- "options",
26
- "head",
27
- ]);
28
- const ASSIGNMENTS = new Set([
29
- ts.SyntaxKind.EqualsToken,
30
- ts.SyntaxKind.PlusEqualsToken,
31
- ts.SyntaxKind.MinusEqualsToken,
32
- ts.SyntaxKind.AsteriskEqualsToken,
33
- ts.SyntaxKind.SlashEqualsToken,
34
- ts.SyntaxKind.PercentEqualsToken,
35
- ts.SyntaxKind.QuestionQuestionEqualsToken,
36
- ts.SyntaxKind.AmpersandAmpersandEqualsToken,
37
- ts.SyntaxKind.BarBarEqualsToken,
38
- ]);
39
- export class RichGraphEnricher {
40
- graph;
41
- constructor(graph) {
42
- this.graph = graph;
43
- }
44
- enrich(projectId, rootPath, resolution) {
45
- const stats = {
46
- routes: 0,
47
- tests: 0,
48
- usesType: 0,
49
- writes: 0,
50
- callReferences: 0,
51
- properties: 0,
52
- };
53
- const config = this.loadConfig(rootPath);
54
- const program = ts.createProgram({
55
- rootNames: config.fileNames,
56
- options: config.options,
57
- });
58
- const checker = program.getTypeChecker();
59
- for (const source of program.getSourceFiles()) {
60
- if (source.isDeclarationFile) {
61
- continue;
62
- }
63
- const filePath = normalize(relative(rootPath, resolve(source.fileName)));
64
- if (filePath.startsWith("../") ||
65
- filePath.includes("node_modules/")) {
66
- continue;
67
- }
68
- const fileNode = this.fileNode(projectId, filePath);
69
- if (!fileNode) {
70
- continue;
71
- }
72
- const visit = (node) => {
73
- if (ts.isCallExpression(node)) {
74
- if (this.addRoute(projectId, rootPath, source, fileNode, node, checker)) {
75
- stats.routes++;
76
- }
77
- }
78
- if (ts.isTypeReferenceNode(node)) {
79
- if (this.addTypeUse(projectId, rootPath, source, node, checker)) {
80
- stats.usesType++;
81
- }
82
- }
83
- if (ts.isBinaryExpression(node) &&
84
- ASSIGNMENTS.has(node.operatorToken.kind)) {
85
- const result = this.addWrite(projectId, rootPath, source, node.left, checker);
86
- if (result.added) {
87
- stats.writes++;
88
- if (result.propertyCreated) {
89
- stats.properties++;
90
- }
91
- }
92
- }
93
- if ((ts.isPrefixUnaryExpression(node) ||
94
- ts.isPostfixUnaryExpression(node)) &&
95
- (node.operator ===
96
- ts.SyntaxKind.PlusPlusToken ||
97
- node.operator ===
98
- ts.SyntaxKind.MinusMinusToken)) {
99
- const result = this.addWrite(projectId, rootPath, source, node.operand, checker);
100
- if (result.added) {
101
- stats.writes++;
102
- if (result.propertyCreated) {
103
- stats.properties++;
104
- }
105
- }
106
- }
107
- ts.forEachChild(node, visit);
108
- };
109
- visit(source);
110
- }
111
- stats.tests +=
112
- this.addTestEdges(projectId);
113
- if (resolution) {
114
- stats.callReferences +=
115
- this.addResolvedCalls(projectId, resolution);
116
- }
117
- return stats;
118
- }
119
- addRoute(projectId, rootPath, source, fileNode, node, checker) {
120
- if (!ts.isPropertyAccessExpression(node.expression)) {
121
- return false;
122
- }
123
- const method = node.expression
124
- .name.text
125
- .toLowerCase();
126
- if (!ROUTE_METHODS.has(method)) {
127
- return false;
128
- }
129
- const first = node.arguments[0];
130
- if (!first ||
131
- !(ts.isStringLiteral(first) ||
132
- ts.isNoSubstitutionTemplateLiteral(first))) {
133
- return false;
134
- }
135
- const path = first.text;
136
- if (!path.startsWith("/")) {
137
- return false;
138
- }
139
- const sourceLine = lineOf(source, node);
140
- const routeId = id(projectId, source.fileName, sourceLine, method, path);
141
- if (!this.graph.getSymbol(routeId)) {
142
- this.graph.addSymbol({
143
- id: routeId,
144
- projectId,
145
- name: `${method.toUpperCase()} ${path}`,
146
- qualifiedName: `${method.toUpperCase()} ${path}`,
147
- type: "route",
148
- filePath: fileNode.filePath,
149
- startLine: sourceLine,
150
- endLine: sourceLine,
151
- });
152
- this.graph.addEdge(this.edge(projectId, fileNode.id, "DEFINES", routeId));
153
- }
154
- const handler = node.arguments.at(-1);
155
- if (handler) {
156
- const target = this.resolveNodeSymbol(projectId, rootPath, handler, checker);
157
- if (target) {
158
- this.graph.addEdge(this.edge(projectId, routeId, "ROUTE", target.id, {
159
- method: method.toUpperCase(),
160
- path,
161
- }));
162
- }
163
- }
164
- return true;
165
- }
166
- addTypeUse(projectId, rootPath, source, node, checker) {
167
- const target = this.resolveNodeSymbol(projectId, rootPath, node.typeName, checker);
168
- if (!target) {
169
- return false;
170
- }
171
- const sourceSymbol = this.containingSymbol(projectId, normalize(relative(rootPath, resolve(source.fileName))), lineOf(source, node));
172
- if (!sourceSymbol ||
173
- sourceSymbol.id ===
174
- target.id) {
175
- return false;
176
- }
177
- this.graph.addEdge(this.edge(projectId, sourceSymbol.id, "USES_TYPE", target.id));
178
- return true;
179
- }
180
- addWrite(projectId, rootPath, source, targetNode, checker) {
181
- const symbol = this.resolveTsSymbol(targetNode, checker);
182
- const declaration = symbol
183
- ?.valueDeclaration ??
184
- symbol
185
- ?.declarations?.[0];
186
- if (!declaration) {
187
- return {
188
- added: false,
189
- propertyCreated: false,
190
- };
191
- }
192
- const declarationSource = declaration
193
- .getSourceFile();
194
- if (declarationSource
195
- .isDeclarationFile) {
196
- return {
197
- added: false,
198
- propertyCreated: false,
199
- };
200
- }
201
- const targetFile = normalize(relative(rootPath, resolve(declarationSource
202
- .fileName)));
203
- if (targetFile.startsWith("../") ||
204
- targetFile.includes("node_modules/")) {
205
- return {
206
- added: false,
207
- propertyCreated: false,
208
- };
209
- }
210
- const targetLine = lineOf(declarationSource, declaration);
211
- let target = this.findSymbolAt(projectId, targetFile, targetLine);
212
- let propertyCreated = false;
213
- if (!target ||
214
- target.type === "file") {
215
- const name = symbol?.getName() ??
216
- targetNode.getText(source);
217
- const propertyId = id(projectId, targetFile, "property", name, targetLine);
218
- target =
219
- this.graph.getSymbol(propertyId);
220
- if (!target) {
221
- target = {
222
- id: propertyId,
223
- projectId,
224
- name,
225
- qualifiedName: name,
226
- type: "property",
227
- filePath: targetFile,
228
- startLine: targetLine,
229
- endLine: targetLine,
230
- };
231
- this.graph.addSymbol(target);
232
- const targetFileNode = this.fileNode(projectId, targetFile);
233
- if (targetFileNode) {
234
- this.graph.addEdge(this.edge(projectId, targetFileNode.id, "DEFINES", target.id));
235
- }
236
- propertyCreated =
237
- true;
238
- }
239
- }
240
- if (!target) {
241
- return {
242
- added: false,
243
- propertyCreated,
244
- };
245
- }
246
- const sourceFile = normalize(relative(rootPath, resolve(source.fileName)));
247
- const writer = this.containingSymbol(projectId, sourceFile, lineOf(source, targetNode));
248
- if (!writer ||
249
- writer.id === target.id) {
250
- return {
251
- added: false,
252
- propertyCreated,
253
- };
254
- }
255
- this.graph.addEdge(this.edge(projectId, writer.id, "WRITES", target.id, {
256
- expression: targetNode.getText(source),
257
- }));
258
- return {
259
- added: true,
260
- propertyCreated,
261
- };
262
- }
263
- addTestEdges(projectId) {
264
- const edges = this.graph.allEdges(projectId);
265
- let added = 0;
266
- for (const edge of edges) {
267
- if (edge.type !==
268
- "IMPORTS") {
269
- continue;
270
- }
271
- const from = this.graph.getSymbol(edge.from);
272
- const to = this.graph.getSymbol(edge.to);
273
- if (!from ||
274
- !to ||
275
- !this.isTestFile(from.filePath) ||
276
- this.isTestFile(to.filePath)) {
277
- continue;
278
- }
279
- this.graph.addEdge(this.edge(projectId, from.id, "TESTS", to.id));
280
- added++;
281
- }
282
- return added;
283
- }
284
- addResolvedCalls(projectId, resolution) {
285
- let added = 0;
286
- for (const item of resolution.resolutions) {
287
- if (item.kind !== "CALL" ||
288
- !item.targetSymbolId) {
289
- continue;
290
- }
291
- const target = this.graph.getSymbol(item.targetSymbolId);
292
- if (!target) {
293
- continue;
294
- }
295
- const source = this.containingSymbol(projectId, item.sourceFile, item.sourceLine);
296
- if (!source ||
297
- source.id === target.id) {
298
- continue;
299
- }
300
- /*
301
- * Nếu CALLS hiện tại đã đúng target
302
- * thì không tạo edge trùng.
303
- */
304
- const exactAlreadyExists = this.graph
305
- .allEdges(projectId)
306
- .some((edge) => edge.type ===
307
- "CALLS" &&
308
- edge.from ===
309
- source.id &&
310
- edge.to ===
311
- target.id);
312
- if (exactAlreadyExists) {
313
- continue;
314
- }
315
- this.graph.addEdge(this.edge(projectId, source.id, "CALL_REFERENCE", target.id, {
316
- expression: item.expression,
317
- confidence: item.confidence,
318
- resolver: item.resolver,
319
- }));
320
- added++;
321
- }
322
- return added;
323
- }
324
- resolveNodeSymbol(projectId, rootPath, node, checker) {
325
- const symbol = this.resolveTsSymbol(node, checker);
326
- const declaration = symbol
327
- ?.valueDeclaration ??
328
- symbol
329
- ?.declarations?.[0];
330
- if (!declaration) {
331
- return undefined;
332
- }
333
- const targetSource = declaration
334
- .getSourceFile();
335
- if (targetSource
336
- .isDeclarationFile) {
337
- return undefined;
338
- }
339
- const filePath = normalize(relative(rootPath, resolve(targetSource
340
- .fileName)));
341
- if (filePath.startsWith("../") ||
342
- filePath.includes("node_modules/")) {
343
- return undefined;
344
- }
345
- return this.findSymbolAt(projectId, filePath, lineOf(targetSource, declaration), symbol?.getName());
346
- }
347
- resolveTsSymbol(node, checker) {
348
- let symbol = checker.getSymbolAtLocation(node);
349
- if (symbol &&
350
- (symbol.flags &
351
- ts.SymbolFlags.Alias)) {
352
- try {
353
- symbol =
354
- checker.getAliasedSymbol(symbol);
355
- }
356
- catch {
357
- // keep original
358
- }
359
- }
360
- return symbol;
361
- }
362
- containingSymbol(projectId, filePath, line) {
363
- return this.graph
364
- .allSymbols(projectId)
365
- .filter((symbol) => normalize(symbol.filePath) ===
366
- normalize(filePath) &&
367
- typeof symbol.startLine ===
368
- "number" &&
369
- typeof symbol.endLine ===
370
- "number" &&
371
- symbol.startLine <= line &&
372
- symbol.endLine >= line)
373
- .sort((a, b) => ((a.endLine ?? 0) -
374
- (a.startLine ?? 0)) -
375
- ((b.endLine ?? 0) -
376
- (b.startLine ?? 0)))[0];
377
- }
378
- findSymbolAt(projectId, filePath, line, name) {
379
- const candidates = this.graph
380
- .allSymbols(projectId)
381
- .filter((symbol) => normalize(symbol.filePath) ===
382
- normalize(filePath) &&
383
- typeof symbol.startLine ===
384
- "number" &&
385
- typeof symbol.endLine ===
386
- "number" &&
387
- symbol.startLine <= line &&
388
- symbol.endLine >= line)
389
- .sort((a, b) => ((a.endLine ?? 0) -
390
- (a.startLine ?? 0)) -
391
- ((b.endLine ?? 0) -
392
- (b.startLine ?? 0)));
393
- if (name) {
394
- const named = candidates.find((symbol) => symbol.name === name ||
395
- (symbol.qualifiedName
396
- ?.endsWith(`.${name}`) ?? false));
397
- if (named) {
398
- return named;
399
- }
400
- }
401
- return candidates[0];
402
- }
403
- fileNode(projectId, filePath) {
404
- return this.graph
405
- .allSymbols(projectId)
406
- .find((symbol) => symbol.type ===
407
- "file" &&
408
- normalize(symbol.filePath) ===
409
- normalize(filePath));
410
- }
411
- isTestFile(filePath) {
412
- const path = normalize(filePath).toLowerCase();
413
- return (path.startsWith("tests/") ||
414
- path.includes("/tests/") ||
415
- path.includes("__tests__") ||
416
- /\.(test|spec)\.[^.]+$/
417
- .test(path));
418
- }
419
- edge(projectId, from, type, to, metadata) {
420
- return {
421
- id: id(projectId, from, type, to, JSON.stringify(metadata ?? {})),
422
- projectId,
423
- from,
424
- to,
425
- type,
426
- metadata,
427
- };
428
- }
429
- loadConfig(rootPath) {
430
- const configPath = ts.findConfigFile(rootPath, ts.sys.fileExists, "tsconfig.json");
431
- if (configPath) {
432
- const raw = ts.readConfigFile(configPath, ts.sys.readFile);
433
- return ts.parseJsonConfigFileContent(raw.config, ts.sys, dirname(configPath));
434
- }
435
- return {
436
- fileNames: ts.sys.readDirectory(rootPath, [
437
- ".ts",
438
- ".tsx",
439
- ".js",
440
- ".jsx",
441
- ".mts",
442
- ".cts",
443
- ".mjs",
444
- ".cjs",
445
- ], [
446
- "node_modules",
447
- ".git",
448
- "dist",
449
- "build",
450
- "coverage",
451
- ]),
452
- options: {
453
- allowJs: true,
454
- noEmit: true,
455
- skipLibCheck: true,
456
- target: ts.ScriptTarget.ES2022,
457
- module: ts.ModuleKind.NodeNext,
458
- moduleResolution: ts.ModuleResolutionKind
459
- .NodeNext,
460
- },
461
- };
462
- }
463
- }
@@ -1,2 +0,0 @@
1
- export * from "./semantic-code-engine.js";
2
- export * from "./source-priority.js";
@@ -1,213 +0,0 @@
1
- import { PersistentCodeChunkStore, } from "../../storage/code-chunk-store.js";
2
- import { PersistentCodeVectorStore, } from "../../storage/code-vector-store.js";
3
- import { SmartCodeChunker, } from "../chunks/smart-chunker.js";
4
- import { VectorStore, } from "../../retrieval/vector/vector-store.js";
5
- import { tokenize, } from "../../retrieval/tokenizer.js";
6
- import { codeSourceWeight, } from "./source-priority.js";
7
- export class SemanticCodeEngine {
8
- options;
9
- vectors = new VectorStore();
10
- chunks = new Map();
11
- constructor(options) {
12
- this.options = options;
13
- }
14
- async initialize() {
15
- const { projectId, rootPath, storage, embeddings, graph, model, } = this.options;
16
- const chunkStore = new PersistentCodeChunkStore(storage);
17
- const vectorStore = new PersistentCodeVectorStore(storage);
18
- const chunks = await new SmartCodeChunker()
19
- .build(projectId, rootPath, graph.allSymbols(projectId));
20
- this.chunks.clear();
21
- for (const chunk of chunks) {
22
- this.chunks.set(chunk.id, chunk);
23
- }
24
- const previousChunks = await chunkStore.load(projectId);
25
- const chunksChanged = !previousChunks ||
26
- previousChunks.chunks.length !==
27
- chunks.length ||
28
- previousChunks.chunks.some((old) => !this.chunks.has(old.id));
29
- if (chunksChanged) {
30
- await chunkStore.save({
31
- version: 1,
32
- projectId,
33
- updatedAt: new Date()
34
- .toISOString(),
35
- chunks,
36
- });
37
- }
38
- const previousVectors = await vectorStore.load(projectId);
39
- let vectorsLoaded = 0;
40
- if (previousVectors &&
41
- previousVectors.model ===
42
- model) {
43
- vectorsLoaded =
44
- this.vectors.importRecords(previousVectors.records);
45
- }
46
- const validIds = new Set(chunks.map((chunk) => chunk.id));
47
- let vectorsRemoved = 0;
48
- for (const record of this.vectors
49
- .exportProject(projectId)) {
50
- if (!validIds.has(record.id)) {
51
- if (this.vectors.remove(record.id)) {
52
- vectorsRemoved++;
53
- }
54
- }
55
- }
56
- const pending = chunks.filter((chunk) => {
57
- const existing = this.vectors.get(chunk.id);
58
- if (!existing) {
59
- return true;
60
- }
61
- return (existing.metadata
62
- ?.contentHash !==
63
- chunk.contentHash);
64
- });
65
- let vectorsIndexed = 0;
66
- /*
67
- * Batch nhỏ để tránh request embedding quá lớn.
68
- */
69
- const batchSize = 8;
70
- let targetDimensions = this.vectors
71
- .exportProject(projectId)[0]
72
- ?.vector.length;
73
- for (let offset = 0; offset < pending.length; offset += batchSize) {
74
- const batch = pending.slice(offset, offset +
75
- batchSize);
76
- const texts = batch.map((chunk) => [
77
- `file: ${chunk.filePath}`,
78
- chunk.symbolName
79
- ? `symbol: ${chunk.symbolName}`
80
- : "",
81
- chunk.symbolType
82
- ? `type: ${chunk.symbolType}`
83
- : "",
84
- chunk.content,
85
- ]
86
- .filter(Boolean)
87
- .join("\n"));
88
- const vectors = await embeddings
89
- .embedMany(texts);
90
- for (let i = 0; i < batch.length; i++) {
91
- const chunk = batch[i];
92
- const vector = vectors[i];
93
- if (!chunk ||
94
- !vector ||
95
- vector.length === 0) {
96
- continue;
97
- }
98
- if (targetDimensions ===
99
- undefined) {
100
- targetDimensions =
101
- vector.length;
102
- }
103
- /*
104
- * Không cho trộn vector 384d/128d
105
- * nếu provider fallback giữa chừng.
106
- */
107
- if (vector.length !==
108
- targetDimensions) {
109
- console.warn(`[code-semantic] skip dimension mismatch: ${vector.length} != ${targetDimensions}`);
110
- continue;
111
- }
112
- this.vectors.upsert({
113
- id: chunk.id,
114
- projectId,
115
- vector,
116
- metadata: {
117
- contentHash: chunk.contentHash,
118
- filePath: chunk.filePath,
119
- symbolName: chunk.symbolName,
120
- symbolType: chunk.symbolType,
121
- startLine: chunk.startLine,
122
- endLine: chunk.endLine,
123
- },
124
- });
125
- vectorsIndexed++;
126
- }
127
- }
128
- const records = this.vectors
129
- .exportProject(projectId);
130
- const shouldSaveVectors = vectorsIndexed > 0 ||
131
- vectorsRemoved > 0 ||
132
- !previousVectors ||
133
- previousVectors.model !==
134
- model;
135
- if (shouldSaveVectors) {
136
- await vectorStore.save({
137
- version: 1,
138
- projectId,
139
- model,
140
- dimensions: records[0]
141
- ?.vector.length ??
142
- targetDimensions ??
143
- 0,
144
- updatedAt: new Date()
145
- .toISOString(),
146
- records,
147
- });
148
- }
149
- return {
150
- chunks: chunks.length,
151
- vectorsLoaded,
152
- vectorsIndexed,
153
- vectorsRemoved,
154
- totalVectors: records.length,
155
- savedChunks: chunksChanged,
156
- savedVectors: shouldSaveVectors,
157
- };
158
- }
159
- async search(query, limit = 8) {
160
- const queryVector = await this.options
161
- .embeddings
162
- .embed(query);
163
- const vectorResults = this.vectors.search(this.options.projectId, queryVector, Math.max(limit * 4, 20));
164
- const queryTokens = new Set(tokenize(query));
165
- const output = [];
166
- for (const result of vectorResults) {
167
- const chunk = this.chunks.get(result.id);
168
- if (!chunk) {
169
- continue;
170
- }
171
- const documentTokens = new Set(tokenize([
172
- chunk.filePath,
173
- chunk.symbolName ??
174
- "",
175
- chunk.symbolType ??
176
- "",
177
- chunk.content,
178
- ].join(" ")));
179
- let matches = 0;
180
- for (const token of queryTokens) {
181
- if (documentTokens.has(token)) {
182
- matches++;
183
- }
184
- }
185
- const lexicalScore = queryTokens.size === 0
186
- ? 0
187
- : matches /
188
- queryTokens.size;
189
- const vectorScore = Math.max(0, result.score);
190
- /*
191
- * Semantic quan trọng hơn lexical.
192
- */
193
- const sourceWeight = codeSourceWeight(chunk.filePath, query);
194
- const score = (vectorScore *
195
- 0.75 +
196
- lexicalScore *
197
- 0.25) *
198
- sourceWeight;
199
- output.push({
200
- chunk,
201
- score,
202
- vectorScore,
203
- lexicalScore,
204
- });
205
- }
206
- return output
207
- .sort((a, b) => b.score - a.score)
208
- .slice(0, limit);
209
- }
210
- size() {
211
- return this.chunks.size;
212
- }
213
- }
@@ -1,22 +0,0 @@
1
- export function codeSourceWeight(filePath, query) {
2
- const path = filePath
3
- .toLowerCase()
4
- .replaceAll("\\", "/");
5
- const q = query.toLowerCase();
6
- const testIntent = /\b(test|tests|spec|fixture|mock)\b/
7
- .test(q);
8
- const isTest = path.startsWith("tests/") ||
9
- path.includes("/tests/") ||
10
- path.includes("__tests__") ||
11
- /\.(test|spec)\.[^.]+$/
12
- .test(path);
13
- if (isTest &&
14
- !testIntent) {
15
- return 0.35;
16
- }
17
- if (path.includes("/generated/") ||
18
- path.includes(".generated.")) {
19
- return 0.25;
20
- }
21
- return 1;
22
- }
@@ -1 +0,0 @@
1
- export {};