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,322 +0,0 @@
1
- import { createHash, } from "node:crypto";
2
- const EDGE_WEIGHT = {
3
- CALL_REFERENCE: 7,
4
- CALLS: 3,
5
- IMPORTS: 4,
6
- USES_TYPE: 4,
7
- WRITES: 5,
8
- INHERITS: 7,
9
- IMPLEMENTS: 7,
10
- ROUTE: 4,
11
- TESTS: 1,
12
- };
13
- function hash(value) {
14
- return createHash("sha256")
15
- .update(value)
16
- .digest("hex")
17
- .slice(0, 12);
18
- }
19
- function normalize(value) {
20
- return value.replaceAll("\\", "/");
21
- }
22
- function subsystemOf(filePath) {
23
- const path = normalize(filePath);
24
- const parts = path.split("/")
25
- .filter(Boolean);
26
- if (parts[0] === "src" &&
27
- parts[1]) {
28
- return `src/${parts[1]}`;
29
- }
30
- if (parts[0] === "packages" &&
31
- parts[1]) {
32
- return `packages/${parts[1]}`;
33
- }
34
- if (parts[0] === "tests") {
35
- return "tests";
36
- }
37
- if (parts[0] === "bin") {
38
- return "bin";
39
- }
40
- return parts[0] ?? "root";
41
- }
42
- function clusterLabel(subsystem) {
43
- const value = subsystem
44
- .replace(/^src\//, "")
45
- .replace(/^packages\//, "");
46
- const map = {
47
- "code-intelligence": "Code Intelligence",
48
- memory: "Memory",
49
- storage: "Storage",
50
- retrieval: "Retrieval",
51
- runtime: "Runtime",
52
- mcp: "MCP",
53
- hooks: "Hooks",
54
- security: "Security",
55
- snapshot: "Snapshots",
56
- production: "Production",
57
- capture: "Capture",
58
- processor: "Processor",
59
- core: "Core",
60
- tests: "Tests",
61
- bin: "CLI",
62
- sdk: "SDK",
63
- cli: "CLI",
64
- };
65
- return (map[value] ??
66
- value);
67
- }
68
- export class ClusterDetector {
69
- graph;
70
- constructor(graph) {
71
- this.graph = graph;
72
- }
73
- detect(projectId) {
74
- const symbols = this.graph.allSymbols(projectId);
75
- const edges = this.graph.allEdges(projectId);
76
- const symbolById = new Map(symbols.map((symbol) => [
77
- symbol.id,
78
- symbol,
79
- ]));
80
- const files = [
81
- ...new Set(symbols.map((symbol) => normalize(symbol.filePath))),
82
- ].sort();
83
- const pairMap = new Map();
84
- const makeKey = (a, b) => {
85
- const sorted = [a, b].sort();
86
- return `${sorted[0]}\u0000${sorted[1]}`;
87
- };
88
- for (const edge of edges) {
89
- const from = symbolById.get(edge.from);
90
- const to = symbolById.get(edge.to);
91
- if (!from ||
92
- !to) {
93
- continue;
94
- }
95
- const a = normalize(from.filePath);
96
- const b = normalize(to.filePath);
97
- if (a === b) {
98
- continue;
99
- }
100
- const weight = EDGE_WEIGHT[edge.type] ?? 0;
101
- if (weight <= 0) {
102
- continue;
103
- }
104
- const key = makeKey(a, b);
105
- const existing = pairMap.get(key);
106
- if (existing) {
107
- existing.weight +=
108
- weight;
109
- }
110
- else {
111
- pairMap.set(key, {
112
- a: [a, b].sort()[0],
113
- b: [a, b].sort()[1],
114
- weight,
115
- });
116
- }
117
- }
118
- /*
119
- * 1. Base grouping = architectural subsystem.
120
- */
121
- const subsystemFiles = new Map();
122
- for (const file of files) {
123
- const subsystem = subsystemOf(file);
124
- const group = subsystemFiles.get(subsystem) ?? [];
125
- group.push(file);
126
- subsystemFiles.set(subsystem, group);
127
- }
128
- /*
129
- * 2. Split very large subsystems by strong internal connectivity.
130
- *
131
- * Không để code-intelligence 70+ files trở thành một khối mù.
132
- */
133
- const groups = [];
134
- for (const [subsystem, subsystemGroup,] of subsystemFiles) {
135
- subsystemGroup.sort();
136
- if (subsystemGroup.length <=
137
- 30) {
138
- groups.push({
139
- subsystem,
140
- files: subsystemGroup,
141
- });
142
- continue;
143
- }
144
- const fileSet = new Set(subsystemGroup);
145
- const adjacency = new Map();
146
- for (const file of subsystemGroup) {
147
- adjacency.set(file, new Set());
148
- }
149
- for (const pair of pairMap.values()) {
150
- if (!fileSet.has(pair.a) ||
151
- !fileSet.has(pair.b)) {
152
- continue;
153
- }
154
- /*
155
- * Strong internal relationship only.
156
- */
157
- if (pair.weight >=
158
- 8) {
159
- adjacency.get(pair.a)?.add(pair.b);
160
- adjacency.get(pair.b)?.add(pair.a);
161
- }
162
- }
163
- const visited = new Set();
164
- const components = [];
165
- for (const start of subsystemGroup) {
166
- if (visited.has(start)) {
167
- continue;
168
- }
169
- const queue = [start];
170
- const component = [];
171
- visited.add(start);
172
- while (queue.length >
173
- 0) {
174
- const current = queue.shift();
175
- component.push(current);
176
- for (const neighbor of adjacency.get(current) ?? []) {
177
- if (visited.has(neighbor)) {
178
- continue;
179
- }
180
- visited.add(neighbor);
181
- queue.push(neighbor);
182
- }
183
- }
184
- components.push(component.sort());
185
- }
186
- /*
187
- * Strong components >=2 become own clusters.
188
- * Singleton files remain one residual subsystem cluster.
189
- */
190
- const residual = [];
191
- for (const component of components) {
192
- if (component.length >=
193
- 2) {
194
- groups.push({
195
- subsystem,
196
- files: component,
197
- });
198
- }
199
- else {
200
- residual.push(...component);
201
- }
202
- }
203
- if (residual.length >
204
- 0) {
205
- groups.push({
206
- subsystem: `${subsystem}/residual`,
207
- files: residual.sort(),
208
- });
209
- }
210
- }
211
- /*
212
- * 3. Merge tiny cross-subsystem groups only
213
- * when coupling is extremely strong.
214
- */
215
- let working = groups.map((group) => ({
216
- subsystem: group.subsystem,
217
- files: [...group.files],
218
- }));
219
- for (let pass = 0; pass < 3; pass++) {
220
- let merged = false;
221
- outer: for (let i = 0; i <
222
- working.length; i++) {
223
- const a = working[i];
224
- if (!a ||
225
- a.files.length >
226
- 3) {
227
- continue;
228
- }
229
- for (let j = 0; j <
230
- working.length; j++) {
231
- if (i === j) {
232
- continue;
233
- }
234
- const b = working[j];
235
- if (!b) {
236
- continue;
237
- }
238
- let connection = 0;
239
- const setA = new Set(a.files);
240
- const setB = new Set(b.files);
241
- for (const pair of pairMap.values()) {
242
- const crosses = (setA.has(pair.a) &&
243
- setB.has(pair.b)) ||
244
- (setA.has(pair.b) &&
245
- setB.has(pair.a));
246
- if (crosses) {
247
- connection +=
248
- pair.weight;
249
- }
250
- }
251
- if (connection >=
252
- 20) {
253
- b.files =
254
- [
255
- ...new Set([
256
- ...b.files,
257
- ...a.files,
258
- ]),
259
- ].sort();
260
- working.splice(i, 1);
261
- merged =
262
- true;
263
- break outer;
264
- }
265
- }
266
- }
267
- if (!merged) {
268
- break;
269
- }
270
- }
271
- /*
272
- * 4. Compute metrics.
273
- */
274
- const result = [];
275
- for (const group of working) {
276
- const set = new Set(group.files);
277
- let internalWeight = 0;
278
- let externalWeight = 0;
279
- for (const pair of pairMap.values()) {
280
- const inA = set.has(pair.a);
281
- const inB = set.has(pair.b);
282
- if (inA &&
283
- inB) {
284
- internalWeight +=
285
- pair.weight;
286
- }
287
- else if (inA ||
288
- inB) {
289
- externalWeight +=
290
- pair.weight;
291
- }
292
- }
293
- const total = internalWeight +
294
- externalWeight;
295
- const baseSubsystem = group.subsystem
296
- .replace(/\/residual$/, "");
297
- const labelBase = clusterLabel(baseSubsystem);
298
- const label = group.subsystem.endsWith("/residual")
299
- ? `${labelBase} Misc`
300
- : labelBase;
301
- result.push({
302
- id: `cluster-${hash(`${group.subsystem}:${group.files.join("|")}`)}`,
303
- label,
304
- subsystem: baseSubsystem,
305
- files: group.files,
306
- size: group.files.length,
307
- internalWeight,
308
- externalWeight,
309
- cohesion: total > 0
310
- ? Number((internalWeight /
311
- total).toFixed(4))
312
- : 0,
313
- });
314
- }
315
- return result
316
- .sort((a, b) => b.size -
317
- a.size ||
318
- b.cohesion -
319
- a.cohesion ||
320
- a.label.localeCompare(b.label));
321
- }
322
- }
@@ -1,150 +0,0 @@
1
- function normalize(value) {
2
- return value
3
- .replaceAll("\\", "/")
4
- .toLowerCase();
5
- }
6
- export class EntryPointDetector {
7
- graph;
8
- constructor(graph) {
9
- this.graph = graph;
10
- }
11
- detect(projectId) {
12
- const symbols = this.graph.allSymbols(projectId);
13
- const edges = this.graph.allEdges(projectId);
14
- const results = [];
15
- for (const symbol of symbols) {
16
- /*
17
- * Route là entry semantic.
18
- * Các loại còn lại chỉ xét FILE node.
19
- */
20
- if (symbol.type !== "route" &&
21
- symbol.type !== "file") {
22
- continue;
23
- }
24
- const result = this.classify(symbol, edges);
25
- if (result) {
26
- results.push({
27
- symbolId: symbol.id,
28
- filePath: symbol.filePath,
29
- name: symbol.name,
30
- kind: result.kind,
31
- score: result.score,
32
- reasons: result.reasons,
33
- });
34
- }
35
- }
36
- /*
37
- * Một file chỉ giữ entry tốt nhất.
38
- * Route vẫn giữ riêng theo symbol.
39
- */
40
- const bestByKey = new Map();
41
- for (const item of results) {
42
- const key = item.kind === "route"
43
- ? item.symbolId
44
- : item.filePath;
45
- const existing = bestByKey.get(key);
46
- if (!existing ||
47
- item.score >
48
- existing.score) {
49
- bestByKey.set(key, item);
50
- }
51
- }
52
- return [
53
- ...bestByKey.values(),
54
- ]
55
- .sort((a, b) => b.score -
56
- a.score ||
57
- a.filePath.localeCompare(b.filePath));
58
- }
59
- classify(symbol, edges) {
60
- const path = normalize(symbol.filePath);
61
- const reasons = [];
62
- if (symbol.type ===
63
- "route") {
64
- return {
65
- kind: "route",
66
- score: 100,
67
- reasons: [
68
- "HTTP route",
69
- ],
70
- };
71
- }
72
- let kind = null;
73
- let score = 0;
74
- if (path.startsWith("bin/")) {
75
- kind =
76
- "cli";
77
- score =
78
- 100;
79
- reasons.push("bin executable");
80
- }
81
- else if (/(^|\/)(cli)\.[^.]+$/
82
- .test(path)) {
83
- kind =
84
- "cli";
85
- score =
86
- 90;
87
- reasons.push("CLI entry file");
88
- }
89
- else if (/(^|\/)(main|server)\.[^.]+$/
90
- .test(path)) {
91
- kind =
92
- "main";
93
- score =
94
- 90;
95
- reasons.push("main/server file");
96
- }
97
- else if (path.includes("/runtime/") &&
98
- /(^|\/)(bootstrap|index)\.[^.]+$/
99
- .test(path)) {
100
- kind =
101
- "runtime";
102
- score =
103
- 75;
104
- reasons.push("runtime bootstrap");
105
- }
106
- else if (/(^|\/)index\.[^.]+$/
107
- .test(path)) {
108
- /*
109
- * Chỉ package/public index có tín hiệu
110
- * dependency thực sự.
111
- */
112
- const incoming = edges.filter((edge) => edge.to ===
113
- symbol.id &&
114
- edge.type !==
115
- "DEFINES").length;
116
- const outgoing = edges.filter((edge) => edge.from ===
117
- symbol.id &&
118
- edge.type !==
119
- "DEFINES").length;
120
- if (path.startsWith("packages/") ||
121
- incoming === 0 ||
122
- outgoing > 0) {
123
- kind =
124
- "package";
125
- score =
126
- path.startsWith("packages/")
127
- ? 70
128
- : 55;
129
- reasons.push("package/public index");
130
- }
131
- }
132
- if (!kind) {
133
- return null;
134
- }
135
- const incoming = edges.filter((edge) => edge.to ===
136
- symbol.id &&
137
- edge.type !==
138
- "DEFINES").length;
139
- if (incoming === 0) {
140
- score +=
141
- 10;
142
- reasons.push("no incoming dependency");
143
- }
144
- return {
145
- kind,
146
- score,
147
- reasons,
148
- };
149
- }
150
- }
@@ -1,136 +0,0 @@
1
- const EDGE_WEIGHT = {
2
- CALL_REFERENCE: 6,
3
- CALLS: 4,
4
- IMPORTS: 3,
5
- USES_TYPE: 4,
6
- WRITES: 5,
7
- ROUTE: 4,
8
- TESTS: 1,
9
- INHERITS: 5,
10
- IMPLEMENTS: 5,
11
- DEFINES: 0.25,
12
- };
13
- export class HotspotAnalyzer {
14
- graph;
15
- constructor(graph) {
16
- this.graph = graph;
17
- }
18
- analyze(projectId) {
19
- const symbols = this.graph.allSymbols(projectId);
20
- const edges = this.graph.allEdges(projectId);
21
- const symbolById = new Map(symbols.map((symbol) => [
22
- symbol.id,
23
- symbol,
24
- ]));
25
- const files = new Map();
26
- const get = (filePath) => {
27
- let value = files.get(filePath);
28
- if (!value) {
29
- value = {
30
- symbols: 0,
31
- incoming: 0,
32
- outgoing: 0,
33
- weightedIncoming: 0,
34
- weightedOutgoing: 0,
35
- writes: 0,
36
- callReferences: 0,
37
- crossFile: 0,
38
- };
39
- files.set(filePath, value);
40
- }
41
- return value;
42
- };
43
- for (const symbol of symbols) {
44
- get(symbol.filePath).symbols++;
45
- }
46
- for (const edge of edges) {
47
- const from = symbolById.get(edge.from);
48
- const to = symbolById.get(edge.to);
49
- if (!from ||
50
- !to) {
51
- continue;
52
- }
53
- const weight = EDGE_WEIGHT[edge.type] ?? 1;
54
- const source = get(from.filePath);
55
- const target = get(to.filePath);
56
- source.outgoing++;
57
- target.incoming++;
58
- source.weightedOutgoing +=
59
- weight;
60
- target.weightedIncoming +=
61
- weight;
62
- if (edge.type ===
63
- "WRITES") {
64
- source.writes++;
65
- }
66
- if (edge.type ===
67
- "CALL_REFERENCE") {
68
- source.callReferences++;
69
- }
70
- if (from.filePath !==
71
- to.filePath) {
72
- source.crossFile++;
73
- target.crossFile++;
74
- }
75
- }
76
- const scored = [
77
- ...files.entries(),
78
- ]
79
- .map(([filePath, value,]) => {
80
- const score = Number((value.symbols *
81
- 0.4 +
82
- value.weightedIncoming *
83
- 1.75 +
84
- value.weightedOutgoing *
85
- 0.65 +
86
- value.crossFile *
87
- 1.5 +
88
- value.writes *
89
- 3 +
90
- value.callReferences *
91
- 2).toFixed(2));
92
- const reasons = [];
93
- if (value.incoming >=
94
- 10) {
95
- reasons.push("high incoming dependency");
96
- }
97
- if (value.crossFile >=
98
- 10) {
99
- reasons.push("high cross-file coupling");
100
- }
101
- if (value.callReferences >=
102
- 5) {
103
- reasons.push("many exact call references");
104
- }
105
- if (value.writes > 0) {
106
- reasons.push("contains write relationships");
107
- }
108
- if (value.symbols >=
109
- 10) {
110
- reasons.push("high symbol density");
111
- }
112
- return {
113
- filePath,
114
- score,
115
- symbols: value.symbols,
116
- incoming: value.incoming,
117
- outgoing: value.outgoing,
118
- reasons,
119
- };
120
- })
121
- .filter((item) => item.score > 0)
122
- .sort((a, b) => b.score -
123
- a.score ||
124
- a.filePath.localeCompare(b.filePath));
125
- if (scored.length === 0) {
126
- return [];
127
- }
128
- /*
129
- * Top 15%, tối đa 30.
130
- * Repo nhỏ vẫn giữ tối thiểu 1 hotspot.
131
- */
132
- const limit = Math.max(1, Math.min(30, Math.ceil(scored.length *
133
- 0.15)));
134
- return scored.slice(0, limit);
135
- }
136
- }
@@ -1,6 +0,0 @@
1
- export * from "./types.js";
2
- export * from "./entry-points.js";
3
- export * from "./hotspots.js";
4
- export * from "./layers.js";
5
- export * from "./clusters.js";
6
- export * from "./architecture-engine.js";