toolnet-memory 0.2.1 → 0.2.3

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
@@ -0,0 +1,8 @@
1
+ import{closeSync as Gr,mkdirSync as zr,openSync as Br,rmSync as Hr,writeFileSync as Kr}from"node:fs";import{join as De}from"node:path";import{existsSync as dt,readFileSync as pt}from"node:fs";import{homedir as mt}from"node:os";import{join as ut}from"node:path";function ft(n){let e=n.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
2
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function gt(){let n=process.env.TOOLNET_GLOBAL_ENV??ut(mt(),".config","toolnet-memory",".env");if(!dt(n))return;let e=pt(n,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let i=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=ft(r.slice(s+1)))}}gt();function U(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function O(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function ze(){return{memory:{autoCapture:U(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:U(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:U(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:U(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:O(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:O(process.env.MEMORY_RERANK_TOP,10),finalContext:O(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:O(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:O(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ht}from"node:crypto";import{existsSync as Te,mkdirSync as yt,readFileSync as St,renameSync as bt,writeFileSync as xt}from"node:fs";import{basename as wt,dirname as J,join as Y,parse as Ke,resolve as F}from"node:path";var We=".toolnet",Et="project.json";function Ct(n){return ht("sha256").update(n).digest("hex").slice(0,16)}function ke(n){return Y(n,We,Et)}function vt(n){return Te(ke(n))}function Pt(n,e){let t=F(n),r=Ke(t).root;for(;;){if(vt(t))return t;if(t===r||e&&t===F(e))break;let s=J(t);if(s===t)break;t=s}return null}function Rt(n){let e=F(n),t=Ke(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(i=>Te(Y(e,i))))return e;if(e===t)break;let s=J(e);if(s===e)break;e=s}return F(n)}function Tt(n){let e;try{e=JSON.parse(St(n,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${n}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${n}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${n}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${n}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:J(J(n)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function Be(n,e){let t=Y(n,We);yt(t,{recursive:!0});let r=ke(n),s=`${r}.tmp-${process.pid}`;xt(s,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),bt(s,r)}function He(n,e){return{id:n.id,name:n.name,remote:n.remote,rootPath:e,createdAt:n.createdAt,updatedAt:n.updatedAt,graphVersion:n.graphVersion,memoryVersion:n.memoryVersion,metadata:n.metadata}}var q=class{detect(e=process.cwd()){let t=F(e),r=Rt(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>Te(Y(r,l))),o=Pt(t,i?r:void 0);if(o){let l=ke(o),u=Tt(l);return u.rootPath!==o&&(u.rootPath=o,u.updatedAt=new Date().toISOString(),Be(o,u)),He(u,o)}let a=new Date().toISOString(),m=wt(r),c={version:1,id:Ct(r),name:m,remote:m,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Be(r,c),He(c,r)}};var kt=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],Z=class{scan(e){let t=[];for(let r of kt){let s=new RegExp(r.regex.source,r.regex.flags);for(let i of e.matchAll(s))t.push({type:r.type,value:i[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var _=class{scanner=new Z;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let i of r)s.add(i.type),t=t.split(i.value).join(`[REDACTED:${i.type}]`);return{text:t,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[r,s]of Object.entries(e)){let i=r.toLowerCase();i.includes("password")||i.includes("secret")||i.includes("token")||i.includes("cookie")||i.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var Q=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,r=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:e,options:{wait_for_model:!0}})});if(!r.ok)throw new Error(`HF embedding failed: ${r.status} ${await r.text()}`);let s=await r.json();if(!Array.isArray(s))throw new Error("HF embedding returned invalid response");return s.map(i=>Lt(i))}};function Lt(n){if(!Array.isArray(n))throw new Error("Invalid embedding");if(n.length>0&&typeof n[0]=="number")return n;if(n.length>0&&Array.isArray(n[0])){let e=n;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let i=0;i<t;i++)r[i]+=s[i]??0;for(let s=0;s<t;s++)r[s]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as jt}from"node:crypto";var X=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),r=e.toLowerCase().split(/\s+/).filter(Boolean);for(let s of r){let o=jt("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[o]+=1}return At(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function At(n){let e=Math.sqrt(n.reduce((t,r)=>t+r*r,0));return e===0?n:n.map(t=>t/e)}var Le=class{constructor(e,t=new X){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}};function Ve(){let n=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=n?new Q({token:n,model:e}):null;return new Le(t)}import{readdir as Ot}from"node:fs/promises";import{extname as Ft,join as _t,relative as $t}from"node:path";import{basename as Nt}from"node:path";var Mt=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),It=new Set([".pem",".key",".p12",".pfx"]);function Ue(n){let e=Nt(n).toLowerCase();if(Mt.has(e))return!0;for(let t of It)if(e.endsWith(t))return!0;return!1}var Dt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Gt=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function je(n){let e=[];async function t(r){let s=await Ot(r,{withFileTypes:!0});for(let i of s){if(Gt.has(i.name))continue;let o=_t(r,i.name);if(i.isDirectory()){await t(o);continue}Dt.has(Ft(i.name))&&(Ue(o)||e.push($t(n,o)))}}return await t(n),e.sort()}import{readFile as zt}from"node:fs/promises";import{join as Bt}from"node:path";import{createHash as Ht}from"node:crypto";import v from"typescript";function Je(n,e){return Ht("sha256").update(`${n}:${e}`).digest("hex").slice(0,24)}function Ae(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}async function Ne(n,e,t){let r=Bt(e,t),s=await zt(r,"utf8"),i=v.createSourceFile(t,s,v.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?v.ScriptKind.TSX:v.ScriptKind.TS),o=[],a=[],m=[],c=[],l={id:Je(n,`file:${t}`),projectId:n,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:i.getLineAndCharacterOfPosition(i.end).line+1};o.push(l);let u=[],d=[];function f(g,b,y,x){let C=Je(n,`${t}:${y}:${x??b}:${g.pos}`);return o.push({id:C,projectId:n,name:b,qualifiedName:x??b,type:y,filePath:t,startLine:Ae(i,g),endLine:i.getLineAndCharacterOfPosition(g.end).line+1}),C}function h(g){if(!v.isStringLiteral(g.moduleSpecifier))return;let b=[],y=g.importClause;if(y?.name&&b.push({localName:y.name.text,importedName:"default",kind:"default"}),y?.namedBindings&&v.isNamedImports(y.namedBindings))for(let x of y.namedBindings.elements)b.push({localName:x.name.text,importedName:x.propertyName?.text??x.name.text,kind:"named"});y?.namedBindings&&v.isNamespaceImport(y.namedBindings)&&b.push({localName:y.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:g.moduleSpecifier.text,bindings:b})}function p(g,b){for(let y of g.heritageClauses??[])for(let x of y.types){let C=x.expression.getText(i).split(".").at(-1)??"";C&&c.push({fromId:b,targetName:C,type:y.token===v.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function S(g){let b=!1,y=!1;if(v.isImportDeclaration(g)&&h(g),v.isInterfaceDeclaration(g)&&f(g,g.name.text,"interface",g.name.text),v.isClassDeclaration(g)&&g.name){let x=f(g,g.name.text,"class",g.name.text);p(g,x),d.push({id:x,name:g.name.text}),y=!0}if(v.isFunctionDeclaration(g)&&g.name){let x=f(g,g.name.text,"function",g.name.text);u.push(x),b=!0}if(v.isMethodDeclaration(g)&&g.name){let x=g.name.getText(i),C=d.at(-1)?.name,E=f(g,x,"method",C?`${C}.${x}`:x);u.push(E),b=!0}if(v.isCallExpression(g)&&(v.isIdentifier(g.expression)&&m.push({callerId:u.at(-1),calleeName:g.expression.text,line:Ae(i,g)}),v.isPropertyAccessExpression(g.expression))){let x=g.expression;m.push({callerId:u.at(-1),qualifier:x.expression.getText(i),calleeName:x.name.text,line:Ae(i,g)})}v.forEachChild(g,S),b&&u.pop(),y&&d.pop()}return S(i),{filePath:t,symbols:o,imports:a,calls:m,heritage:c}}import{createHash as Kt}from"node:crypto";import{dirname as Wt,extname as Vt,normalize as Ut,posix as Jt}from"node:path";var $=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(r=>r.projectId===e&&(r.name===t||r.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let r of e)this.addSymbol(r);for(let r of t)this.addEdge(r)}clearProject(e){for(let[t,r]of this.symbols)r.projectId===e&&this.symbols.delete(t);for(let[t,r]of this.edges)r.projectId===e&&this.edges.delete(t)}};function qt(n,e,t,r){return Kt("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function j(n){return Ut(n).replaceAll("\\","/")}function Me(n,e,t){if(!e.startsWith("."))return;let r=j(Jt.join(Wt(n),e)),s=Vt(r),i;if(s===".js"){let o=r.slice(0,-3);i=[`${o}.ts`,`${o}.tsx`,`${o}.js`,`${o}.jsx`]}else if(s===".mjs"){let o=r.slice(0,-4);i=[`${o}.mts`,`${o}.ts`,`${o}.mjs`]}else if(s===".cjs"){let o=r.slice(0,-4);i=[`${o}.cts`,`${o}.ts`,`${o}.cjs`]}else s?i=[r]:i=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.js`,`${r}/index.jsx`];return i.find(o=>t.has(j(o)))}var D=class{build(e,t){let r=new $,s=new Map;for(let o of t)for(let a of o.symbols)r.addSymbol(a),a.type==="file"&&s.set(j(o.filePath),a);let i=new Set(s.keys());for(let o of t){let a=j(o.filePath),m=s.get(a);if(m){for(let c of o.symbols)c.id!==m.id&&r.addEdge(this.edge(e,m.id,"DEFINES",c.id));for(let c of o.imports){let l=Me(a,c.source,i);if(!l)continue;let u=s.get(l);u&&r.addEdge(this.edge(e,m.id,"IMPORTS",u.id,{source:c.source}))}for(let c of o.heritage){let l=r.findByName(e,c.targetName).filter(u=>u.type==="class"||u.type==="interface");for(let u of l)r.addEdge(this.edge(e,c.fromId,c.type,u.id))}for(let c of o.calls){if(!c.callerId)continue;let l=this.resolveCallTargets(e,o,c.calleeName,c.qualifier,t,r,i);for(let u of l)u.id!==c.callerId&&r.addEdge(this.edge(e,c.callerId,"CALLS",u.id,{line:c.line,qualifier:c.qualifier}))}}}return r}resolveCallTargets(e,t,r,s,i,o,a){let m=j(t.filePath),c=o.findByName(e,r).filter(l=>j(l.filePath)===m);if(!s&&c.length)return c;if(s)for(let l of t.imports){if(!l.bindings.find(f=>f.kind==="namespace"&&f.localName===s))continue;let d=Me(m,l.source,a);if(d)return o.findByName(e,r).filter(f=>j(f.filePath)===d)}for(let l of t.imports){let u=l.bindings.find(p=>p.localName===r);if(!u)continue;let d=Me(m,l.source,a);if(!d)continue;let f=u.importedName==="default"?r:u.importedName,h=o.findByName(e,f).filter(p=>j(p.filePath)===d);if(h.length)return h}return o.findByName(e,r).filter(l=>l.type==="function"||l.type==="method")}edge(e,t,r,s,i){return{id:qt(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:i}}};var ee=class{async index(e,t){let r=await je(t),s=[];for(let o of r)try{s.push(await Ne(e,t,o))}catch(a){console.warn(`[indexer] skipped ${o}:`,a instanceof Error?a.message:a)}let i=new D().build(e,s);return{files:s.length,symbols:i.allSymbols(e).length,edges:i.allEdges(e).length,graph:i}}};import{execFile as Yt}from"node:child_process";import{promisify as Zt}from"node:util";var mo=Zt(Yt);var G=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};import{createHash as Qt}from"node:crypto";import{readFile as Xt}from"node:fs/promises";import{join as er}from"node:path";function qe(n){return Qt("sha256").update(n).digest("hex")}var te=class{sanitizer=new _;async build(e,t,r,s={}){let i=s.maxLines??80,o=s.overlapLines??10,a=new Map;for(let c of r){let l=a.get(c.filePath)??[];l.push(c),a.set(c.filePath,l)}let m=[];for(let[c,l]of a){let u;try{u=await Xt(er(t,c),"utf8")}catch{continue}let d=u.split(/\r?\n/),f=l.filter(h=>h.type!=="file"&&typeof h.startLine=="number"&&typeof h.endLine=="number");if(f.length>0)for(let h of f)m.push(...this.chunkRange({projectId:e,filePath:c,lines:d,symbol:h,startLine:h.startLine,endLine:h.endLine,maxLines:i,overlapLines:o}));else m.push(...this.chunkRange({projectId:e,filePath:c,lines:d,startLine:1,endLine:Math.max(1,d.length),maxLines:i,overlapLines:o}))}return m}chunkRange(e){let{projectId:t,filePath:r,lines:s,symbol:i,maxLines:o}=e,a=Math.min(e.overlapLines,Math.max(0,o-1)),m=Math.max(1,e.startLine),c=Math.min(s.length,Math.max(m,e.endLine)),l=[],u=m,d=0;for(;u<=c;){let f=Math.min(c,u+o-1),h=s.slice(u-1,f).join(`
4
+ `).trim();if(h){let p=this.sanitizer.sanitize(h).text,S=qe(p),g=[t,r,i?.id??"file",String(d),S].join(":");l.push({id:qe(g).slice(0,32),projectId:t,filePath:r,symbolId:i?.id,symbolName:i?.qualifiedName??i?.name,symbolType:i?.type,startLine:u,endLine:f,content:p,contentHash:S})}if(f>=c)break;u=f-a+1,d++}return l}};var re=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var se=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var oe=class{records=new Map;upsert(e){this.records.set(e.id,e)}get(e){return this.records.get(e)}has(e){return this.records.has(e)}remove(e){return this.records.delete(e)}clearProject(e){let t=0;for(let[r,s]of this.records)s.projectId===e&&(this.records.delete(r),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let r of e)!r?.id||!r?.projectId||!Array.isArray(r.vector)||(this.records.set(r.id,r),t++);return t}search(e,t,r=10){let s=[];for(let i of this.records.values()){if(i.projectId!==e)continue;let o=tr(t,i.vector);s.push({id:i.id,score:o,metadata:i.metadata})}return s.sort((i,o)=>o.score-i.score).slice(0,r)}size(){return this.records.size}};function tr(n,e){if(n.length===0||e.length===0||n.length!==e.length)return 0;let t=0,r=0,s=0;for(let i=0;i<n.length;i++){let o=n[i]??0,a=e[i]??0;t+=o*a,r+=o*o,s+=a*a}return r===0||s===0?0:t/(Math.sqrt(r)*Math.sqrt(s))}function Ie(n){return n.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}function Ye(n,e){let t=n.toLowerCase().replaceAll("\\","/"),r=e.toLowerCase(),s=/\b(test|tests|spec|fixture|mock)\b/.test(r);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!s?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var ne=class{constructor(e){this.options=e}options;vectors=new oe;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:r,embeddings:s,graph:i,model:o}=this.options,a=new re(r),m=new se(r),c=await new te().build(e,t,i.allSymbols(e));this.chunks.clear();for(let E of c)this.chunks.set(E.id,E);let l=await a.load(e),u=!l||l.chunks.length!==c.length||l.chunks.some(E=>!this.chunks.has(E.id));u&&await a.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:c});let d=await m.load(e),f=0;d&&d.model===o&&(f=this.vectors.importRecords(d.records));let h=new Set(c.map(E=>E.id)),p=0;for(let E of this.vectors.exportProject(e))h.has(E.id)||this.vectors.remove(E.id)&&p++;let S=c.filter(E=>{let k=this.vectors.get(E.id);return k?k.metadata?.contentHash!==E.contentHash:!0}),g=0,b=8,y=this.vectors.exportProject(e)[0]?.vector.length;for(let E=0;E<S.length;E+=b){let k=S.slice(E,E+b),ct=k.map(T=>[`file: ${T.filePath}`,T.symbolName?`symbol: ${T.symbolName}`:"",T.symbolType?`type: ${T.symbolType}`:"",T.content].filter(Boolean).join(`
5
+ `)),lt=await s.embedMany(ct);for(let T=0;T<k.length;T++){let L=k[T],N=lt[T];if(!(!L||!N||N.length===0)){if(y===void 0&&(y=N.length),N.length!==y){console.warn(`[code-semantic] skip dimension mismatch: ${N.length} != ${y}`);continue}this.vectors.upsert({id:L.id,projectId:e,vector:N,metadata:{contentHash:L.contentHash,filePath:L.filePath,symbolName:L.symbolName,symbolType:L.symbolType,startLine:L.startLine,endLine:L.endLine}}),g++}}}let x=this.vectors.exportProject(e),C=g>0||p>0||!d||d.model!==o;return C&&await m.save({version:1,projectId:e,model:o,dimensions:x[0]?.vector.length??y??0,updatedAt:new Date().toISOString(),records:x}),{chunks:c.length,vectorsLoaded:f,vectorsIndexed:g,vectorsRemoved:p,totalVectors:x.length,savedChunks:u,savedVectors:C}}async search(e,t=8){let r=await this.options.embeddings.embed(e),s=this.vectors.search(this.options.projectId,r,Math.max(t*4,20)),i=new Set(Ie(e)),o=[];for(let a of s){let m=this.chunks.get(a.id);if(!m)continue;let c=new Set(Ie([m.filePath,m.symbolName??"",m.symbolType??"",m.content].join(" "))),l=0;for(let p of i)c.has(p)&&l++;let u=i.size===0?0:l/i.size,d=Math.max(0,a.score),f=Ye(m.filePath,e),h=(d*.75+u*.25)*f;o.push({chunk:m,score:h,vectorScore:d,lexicalScore:u})}return o.sort((a,m)=>m.score-a.score).slice(0,t)}size(){return this.chunks.size}};import{createHash as rr}from"node:crypto";import{dirname as sr,relative as ie,resolve as ae}from"node:path";import P from"typescript";function M(n){return n.replaceAll("\\","/").replace(/^\.\//,"")}function Ze(n){return rr("sha256").update(n).digest("hex").slice(0,24)}function z(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}function or(n){let e=n;if(e.name&&P.isIdentifier(e.name))return e.name.text}var ce=class{constructor(e){this.graph=e}graph;async resolveProject(e,t){let r=this.loadConfig(t),s=P.createProgram({rootNames:r.fileNames,options:r.options}),i=s.getTypeChecker(),o=[];for(let a of s.getSourceFiles()){if(a.isDeclarationFile)continue;let m=ae(a.fileName),c=M(ie(t,m));if(c.startsWith("../")||c.includes("node_modules/"))continue;let l=u=>{if(P.isCallExpression(u)){let d=this.resolveCall({projectId:e,rootPath:t,source:a,node:u,checker:i});d&&o.push(d)}P.isClassDeclaration(u)&&o.push(...this.resolveHeritage({projectId:e,rootPath:t,source:a,node:u,checker:i})),P.forEachChild(u,l)};l(a)}return{version:1,projectId:e,updatedAt:new Date().toISOString(),total:o.length,exact:o.filter(a=>a.confidence==="exact").length,high:o.filter(a=>a.confidence==="high").length,fallback:o.filter(a=>a.confidence==="fallback").length,resolutions:o}}resolveCall(e){let{projectId:t,rootPath:r,source:s,node:i,checker:o}=e,a;if(a=o.getResolvedSignature(i)?.declaration,!a){let c=o.getSymbolAtLocation(i.expression);a=c?.valueDeclaration??c?.declarations?.[0]}return a?this.fromDeclaration({projectId:t,rootPath:r,source:s,sourceNode:i,declaration:a,expression:i.expression.getText(s),kind:"CALL"}):this.fallbackCall(t,r,s,i)}resolveHeritage(e){let{projectId:t,rootPath:r,source:s,node:i,checker:o}=e,a=[];for(let m of i.heritageClauses??[])for(let c of m.types){let l=o.getSymbolAtLocation(c.expression),u=l?.valueDeclaration??l?.declarations?.[0];if(!u)continue;let d=this.fromDeclaration({projectId:t,rootPath:r,source:s,sourceNode:c,declaration:u,expression:c.getText(s),kind:m.token===P.SyntaxKind.ExtendsKeyword?"EXTENDS":"IMPLEMENTS"});d&&a.push(d)}return a}fromDeclaration(e){let t=e.declaration.getSourceFile();if(t.isDeclarationFile)return null;let r=M(ie(e.rootPath,ae(t.fileName)));if(r.startsWith("../")||r.includes("node_modules/"))return null;let s=z(t,e.declaration),i=or(e.declaration)??e.expression.split(".").at(-1),o=this.findGraphSymbol(e.projectId,r,s,i),a=M(ie(e.rootPath,ae(e.source.fileName)));return{id:Ze([e.projectId,a,z(e.source,e.sourceNode),e.kind,r,s].join(":")),projectId:e.projectId,kind:e.kind,sourceFile:a,sourceLine:z(e.source,e.sourceNode),expression:e.expression,targetFile:r,targetLine:s,targetName:i,targetQualifiedName:o?.qualifiedName,targetSymbolId:o?.id,confidence:o?"exact":"high",resolver:"typescript-checker"}}fallbackCall(e,t,r,s){let i=s.expression.getText(r).split(".").at(-1);if(!i)return null;let o=this.graph.findByName(e,i).filter(c=>c.type==="function"||c.type==="method");if(o.length!==1)return null;let a=o[0],m=M(ie(t,ae(r.fileName)));return{id:Ze(`${e}:${m}:${z(r,s)}:${a.id}`),projectId:e,kind:"CALL",sourceFile:m,sourceLine:z(r,s),expression:s.expression.getText(r),targetFile:a.filePath,targetLine:a.startLine,targetName:a.name,targetQualifiedName:a.qualifiedName,targetSymbolId:a.id,confidence:"fallback",resolver:"graph-fallback"}}findGraphSymbol(e,t,r,s){let o=this.graph.allSymbols(e).filter(a=>M(a.filePath)===M(t)).filter(a=>typeof a.startLine=="number"&&typeof a.endLine=="number"&&a.startLine<=r&&a.endLine>=r);if(s){let a=o.find(m=>m.name===s||(m.qualifiedName?.endsWith(`.${s}`)??!1));if(a)return a}return o.sort((a,m)=>(a.endLine??0)-(a.startLine??0)-((m.endLine??0)-(m.startLine??0)))[0]}loadConfig(e){let t=P.findConfigFile(e,P.sys.fileExists,"tsconfig.json");if(t){let s=P.readConfigFile(t,P.sys.readFile);if(s.error)throw new Error(P.flattenDiagnosticMessageText(s.error.messageText,`
6
+ `));return P.parseJsonConfigFileContent(s.config,P.sys,sr(t))}return{fileNames:P.sys.readDirectory(e,[".ts",".tsx",".js",".jsx",".mts",".cts",".mjs",".cjs"],["node_modules",".git","dist","build","coverage"]),options:{allowJs:!0,checkJs:!1,target:P.ScriptTarget.ES2022,module:P.ModuleKind.NodeNext,moduleResolution:P.ModuleResolutionKind.NodeNext,skipLibCheck:!0,noEmit:!0}}}};import{createHash as nr}from"node:crypto";import{dirname as ir,relative as B,resolve as H}from"node:path";import w from"typescript";function R(n){return n.replaceAll("\\","/").replace(/^\.\//,"")}function Oe(...n){return nr("sha256").update(n.join(":")).digest("hex").slice(0,24)}function K(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}var ar=new Set(["get","post","put","patch","delete","options","head"]),cr=new Set([w.SyntaxKind.EqualsToken,w.SyntaxKind.PlusEqualsToken,w.SyntaxKind.MinusEqualsToken,w.SyntaxKind.AsteriskEqualsToken,w.SyntaxKind.SlashEqualsToken,w.SyntaxKind.PercentEqualsToken,w.SyntaxKind.QuestionQuestionEqualsToken,w.SyntaxKind.AmpersandAmpersandEqualsToken,w.SyntaxKind.BarBarEqualsToken]),le=class{constructor(e){this.graph=e}graph;enrich(e,t,r){let s={routes:0,tests:0,usesType:0,writes:0,callReferences:0,properties:0},i=this.loadConfig(t),o=w.createProgram({rootNames:i.fileNames,options:i.options}),a=o.getTypeChecker();for(let m of o.getSourceFiles()){if(m.isDeclarationFile)continue;let c=R(B(t,H(m.fileName)));if(c.startsWith("../")||c.includes("node_modules/"))continue;let l=this.fileNode(e,c);if(!l)continue;let u=d=>{if(w.isCallExpression(d)&&this.addRoute(e,t,m,l,d,a)&&s.routes++,w.isTypeReferenceNode(d)&&this.addTypeUse(e,t,m,d,a)&&s.usesType++,w.isBinaryExpression(d)&&cr.has(d.operatorToken.kind)){let f=this.addWrite(e,t,m,d.left,a);f.added&&(s.writes++,f.propertyCreated&&s.properties++)}if((w.isPrefixUnaryExpression(d)||w.isPostfixUnaryExpression(d))&&(d.operator===w.SyntaxKind.PlusPlusToken||d.operator===w.SyntaxKind.MinusMinusToken)){let f=this.addWrite(e,t,m,d.operand,a);f.added&&(s.writes++,f.propertyCreated&&s.properties++)}w.forEachChild(d,u)};u(m)}return s.tests+=this.addTestEdges(e),r&&(s.callReferences+=this.addResolvedCalls(e,r)),s}addRoute(e,t,r,s,i,o){if(!w.isPropertyAccessExpression(i.expression))return!1;let a=i.expression.name.text.toLowerCase();if(!ar.has(a))return!1;let m=i.arguments[0];if(!m||!(w.isStringLiteral(m)||w.isNoSubstitutionTemplateLiteral(m)))return!1;let c=m.text;if(!c.startsWith("/"))return!1;let l=K(r,i),u=Oe(e,r.fileName,l,a,c);this.graph.getSymbol(u)||(this.graph.addSymbol({id:u,projectId:e,name:`${a.toUpperCase()} ${c}`,qualifiedName:`${a.toUpperCase()} ${c}`,type:"route",filePath:s.filePath,startLine:l,endLine:l}),this.graph.addEdge(this.edge(e,s.id,"DEFINES",u)));let d=i.arguments.at(-1);if(d){let f=this.resolveNodeSymbol(e,t,d,o);f&&this.graph.addEdge(this.edge(e,u,"ROUTE",f.id,{method:a.toUpperCase(),path:c}))}return!0}addTypeUse(e,t,r,s,i){let o=this.resolveNodeSymbol(e,t,s.typeName,i);if(!o)return!1;let a=this.containingSymbol(e,R(B(t,H(r.fileName))),K(r,s));return!a||a.id===o.id?!1:(this.graph.addEdge(this.edge(e,a.id,"USES_TYPE",o.id)),!0)}addWrite(e,t,r,s,i){let o=this.resolveTsSymbol(s,i),a=o?.valueDeclaration??o?.declarations?.[0];if(!a)return{added:!1,propertyCreated:!1};let m=a.getSourceFile();if(m.isDeclarationFile)return{added:!1,propertyCreated:!1};let c=R(B(t,H(m.fileName)));if(c.startsWith("../")||c.includes("node_modules/"))return{added:!1,propertyCreated:!1};let l=K(m,a),u=this.findSymbolAt(e,c,l),d=!1;if(!u||u.type==="file"){let p=o?.getName()??s.getText(r),S=Oe(e,c,"property",p,l);if(u=this.graph.getSymbol(S),!u){u={id:S,projectId:e,name:p,qualifiedName:p,type:"property",filePath:c,startLine:l,endLine:l},this.graph.addSymbol(u);let g=this.fileNode(e,c);g&&this.graph.addEdge(this.edge(e,g.id,"DEFINES",u.id)),d=!0}}if(!u)return{added:!1,propertyCreated:d};let f=R(B(t,H(r.fileName))),h=this.containingSymbol(e,f,K(r,s));return!h||h.id===u.id?{added:!1,propertyCreated:d}:(this.graph.addEdge(this.edge(e,h.id,"WRITES",u.id,{expression:s.getText(r)})),{added:!0,propertyCreated:d})}addTestEdges(e){let t=this.graph.allEdges(e),r=0;for(let s of t){if(s.type!=="IMPORTS")continue;let i=this.graph.getSymbol(s.from),o=this.graph.getSymbol(s.to);!i||!o||!this.isTestFile(i.filePath)||this.isTestFile(o.filePath)||(this.graph.addEdge(this.edge(e,i.id,"TESTS",o.id)),r++)}return r}addResolvedCalls(e,t){let r=0;for(let s of t.resolutions){if(s.kind!=="CALL"||!s.targetSymbolId)continue;let i=this.graph.getSymbol(s.targetSymbolId);if(!i)continue;let o=this.containingSymbol(e,s.sourceFile,s.sourceLine);!o||o.id===i.id||this.graph.allEdges(e).some(m=>m.type==="CALLS"&&m.from===o.id&&m.to===i.id)||(this.graph.addEdge(this.edge(e,o.id,"CALL_REFERENCE",i.id,{expression:s.expression,confidence:s.confidence,resolver:s.resolver})),r++)}return r}resolveNodeSymbol(e,t,r,s){let i=this.resolveTsSymbol(r,s),o=i?.valueDeclaration??i?.declarations?.[0];if(!o)return;let a=o.getSourceFile();if(a.isDeclarationFile)return;let m=R(B(t,H(a.fileName)));if(!(m.startsWith("../")||m.includes("node_modules/")))return this.findSymbolAt(e,m,K(a,o),i?.getName())}resolveTsSymbol(e,t){let r=t.getSymbolAtLocation(e);if(r&&r.flags&w.SymbolFlags.Alias)try{r=t.getAliasedSymbol(r)}catch{}return r}containingSymbol(e,t,r){return this.graph.allSymbols(e).filter(s=>R(s.filePath)===R(t)&&typeof s.startLine=="number"&&typeof s.endLine=="number"&&s.startLine<=r&&s.endLine>=r).sort((s,i)=>(s.endLine??0)-(s.startLine??0)-((i.endLine??0)-(i.startLine??0)))[0]}findSymbolAt(e,t,r,s){let i=this.graph.allSymbols(e).filter(o=>R(o.filePath)===R(t)&&typeof o.startLine=="number"&&typeof o.endLine=="number"&&o.startLine<=r&&o.endLine>=r).sort((o,a)=>(o.endLine??0)-(o.startLine??0)-((a.endLine??0)-(a.startLine??0)));if(s){let o=i.find(a=>a.name===s||(a.qualifiedName?.endsWith(`.${s}`)??!1));if(o)return o}return i[0]}fileNode(e,t){return this.graph.allSymbols(e).find(r=>r.type==="file"&&R(r.filePath)===R(t))}isTestFile(e){let t=R(e).toLowerCase();return t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t)}edge(e,t,r,s,i){return{id:Oe(e,t,r,s,JSON.stringify(i??{})),projectId:e,from:t,to:s,type:r,metadata:i}}loadConfig(e){let t=w.findConfigFile(e,w.sys.fileExists,"tsconfig.json");if(t){let r=w.readConfigFile(t,w.sys.readFile);return w.parseJsonConfigFileContent(r.config,w.sys,ir(t))}return{fileNames:w.sys.readDirectory(e,[".ts",".tsx",".js",".jsx",".mts",".cts",".mjs",".cjs"],["node_modules",".git","dist","build","coverage"]),options:{allowJs:!0,noEmit:!0,skipLibCheck:!0,target:w.ScriptTarget.ES2022,module:w.ModuleKind.NodeNext,moduleResolution:w.ModuleResolutionKind.NodeNext}}}};function lr(n){return n.replaceAll("\\","/").toLowerCase()}var I=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=[];for(let o of t){if(o.type!=="route"&&o.type!=="file")continue;let a=this.classify(o,r);a&&s.push({symbolId:o.id,filePath:o.filePath,name:o.name,kind:a.kind,score:a.score,reasons:a.reasons})}let i=new Map;for(let o of s){let a=o.kind==="route"?o.symbolId:o.filePath,m=i.get(a);(!m||o.score>m.score)&&i.set(a,o)}return[...i.values()].sort((o,a)=>a.score-o.score||o.filePath.localeCompare(a.filePath))}classify(e,t){let r=lr(e.filePath),s=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let i=null,o=0;if(r.startsWith("bin/"))i="cli",o=100,s.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(r))i="cli",o=90,s.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(r))i="main",o=90,s.push("main/server file");else if(r.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(r))i="runtime",o=75,s.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(r)){let m=t.filter(l=>l.to===e.id&&l.type!=="DEFINES").length,c=t.filter(l=>l.from===e.id&&l.type!=="DEFINES").length;(r.startsWith("packages/")||m===0||c>0)&&(i="package",o=r.startsWith("packages/")?70:55,s.push("package/public index"))}return i?(t.filter(m=>m.to===e.id&&m.type!=="DEFINES").length===0&&(o+=10,s.push("no incoming dependency")),{kind:i,score:o,reasons:s}):null}};var dr={CALL_REFERENCE:6,CALLS:4,IMPORTS:3,USES_TYPE:4,WRITES:5,ROUTE:4,TESTS:1,INHERITS:5,IMPLEMENTS:5,DEFINES:.25},de=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(c=>[c.id,c])),i=new Map,o=c=>{let l=i.get(c);return l||(l={symbols:0,incoming:0,outgoing:0,weightedIncoming:0,weightedOutgoing:0,writes:0,callReferences:0,crossFile:0},i.set(c,l)),l};for(let c of t)o(c.filePath).symbols++;for(let c of r){let l=s.get(c.from),u=s.get(c.to);if(!l||!u)continue;let d=dr[c.type]??1,f=o(l.filePath),h=o(u.filePath);f.outgoing++,h.incoming++,f.weightedOutgoing+=d,h.weightedIncoming+=d,c.type==="WRITES"&&f.writes++,c.type==="CALL_REFERENCE"&&f.callReferences++,l.filePath!==u.filePath&&(f.crossFile++,h.crossFile++)}let a=[...i.entries()].map(([c,l])=>{let u=Number((l.symbols*.4+l.weightedIncoming*1.75+l.weightedOutgoing*.65+l.crossFile*1.5+l.writes*3+l.callReferences*2).toFixed(2)),d=[];return l.incoming>=10&&d.push("high incoming dependency"),l.crossFile>=10&&d.push("high cross-file coupling"),l.callReferences>=5&&d.push("many exact call references"),l.writes>0&&d.push("contains write relationships"),l.symbols>=10&&d.push("high symbol density"),{filePath:c,score:u,symbols:l.symbols,incoming:l.incoming,outgoing:l.outgoing,reasons:d}}).filter(c=>c.score>0).sort((c,l)=>l.score-c.score||c.filePath.localeCompare(l.filePath));if(a.length===0)return[];let m=Math.max(1,Math.min(30,Math.ceil(a.length*.15)));return a.slice(0,m)}};function pr(n){return n.replaceAll("\\","/").toLowerCase()}var mr={CALL_REFERENCE:6,CALLS:4,IMPORTS:4,USES_TYPE:4,WRITES:5,INHERITS:6,IMPLEMENTS:6,ROUTE:3,TESTS:1},pe=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(a=>[a.id,a])),i=[...new Set(t.map(a=>a.filePath))].sort(),o=new Map;for(let a of i)o.set(a,this.classifyPath(a));for(let a=0;a<3;a++){let m=!1;for(let c of i){let l=o.get(c);if(!l||l.layer!=="unknown")continue;let u=new Map;for(let f of r){let h=s.get(f.from),p=s.get(f.to);if(!h||!p||h.filePath===p.filePath)continue;let S=null;if(h.filePath===c?S=p.filePath:p.filePath===c&&(S=h.filePath),!S)continue;let g=o.get(S);if(!g||g.layer==="unknown"||g.layer==="tests")continue;let b=mr[f.type]??1;u.set(g.layer,(u.get(g.layer)??0)+b)}let d=[...u.entries()].sort((f,h)=>h[1]-f[1]||f[0].localeCompare(h[0]))[0];d&&d[1]>=4&&(o.set(c,{filePath:c,layer:d[0],confidence:.65,reasons:[`graph-neighbor vote=${d[1]}`]}),m=!0)}if(!m)break}return i.map(a=>o.get(a))}classifyPath(e){let t=pr(e);return t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t)?{filePath:e,layer:"tests",confidence:1,reasons:["test path"]}:t.startsWith("bin/")||t.includes("/mcp/")||t.includes("/cli/")||t.includes("/api/")||t.includes("/routes/")||t.includes("/hooks/")?{filePath:e,layer:"interface",confidence:.9,reasons:["interface boundary"]}:t.includes("/runtime/")||t.includes("/processor/")||t.includes("/retrieval/")||t.includes("/snapshot/")||t.includes("/code-intelligence/")?{filePath:e,layer:"application",confidence:.85,reasons:["application orchestration"]}:t.includes("/core/")||t.includes("/memory/")||/(^|\/)types\.[^.]+$/.test(t)?{filePath:e,layer:"domain",confidence:.9,reasons:["domain/core logic"]}:t.includes("/storage/")||t.includes("/production/")||t.includes("/security/")||t.includes("/config/")||t.includes("/utils/")?{filePath:e,layer:"infrastructure",confidence:.85,reasons:["infrastructure boundary"]}:{filePath:e,layer:"unknown",confidence:.35,reasons:[]}}};import{createHash as ur}from"node:crypto";var fr={CALL_REFERENCE:7,CALLS:3,IMPORTS:4,USES_TYPE:4,WRITES:5,INHERITS:7,IMPLEMENTS:7,ROUTE:4,TESTS:1};function gr(n){return ur("sha256").update(n).digest("hex").slice(0,12)}function me(n){return n.replaceAll("\\","/")}function hr(n){let t=me(n).split("/").filter(Boolean);return t[0]==="src"&&t[1]?`src/${t[1]}`:t[0]==="packages"&&t[1]?`packages/${t[1]}`:t[0]==="tests"?"tests":t[0]==="bin"?"bin":t[0]??"root"}function yr(n){let e=n.replace(/^src\//,"").replace(/^packages\//,"");return{"code-intelligence":"Code Intelligence",memory:"Memory",storage:"Storage",retrieval:"Retrieval",runtime:"Runtime",mcp:"MCP",hooks:"Hooks",security:"Security",snapshot:"Snapshots",production:"Production",capture:"Capture",processor:"Processor",core:"Core",tests:"Tests",bin:"CLI",sdk:"SDK",cli:"CLI"}[e]??e}var ue=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(d=>[d.id,d])),i=[...new Set(t.map(d=>me(d.filePath)))].sort(),o=new Map,a=(d,f)=>{let h=[d,f].sort();return`${h[0]}\0${h[1]}`};for(let d of r){let f=s.get(d.from),h=s.get(d.to);if(!f||!h)continue;let p=me(f.filePath),S=me(h.filePath);if(p===S)continue;let g=fr[d.type]??0;if(g<=0)continue;let b=a(p,S),y=o.get(b);y?y.weight+=g:o.set(b,{a:[p,S].sort()[0],b:[p,S].sort()[1],weight:g})}let m=new Map;for(let d of i){let f=hr(d),h=m.get(f)??[];h.push(d),m.set(f,h)}let c=[];for(let[d,f]of m){if(f.sort(),f.length<=30){c.push({subsystem:d,files:f});continue}let h=new Set(f),p=new Map;for(let y of f)p.set(y,new Set);for(let y of o.values())!h.has(y.a)||!h.has(y.b)||y.weight>=8&&(p.get(y.a)?.add(y.b),p.get(y.b)?.add(y.a));let S=new Set,g=[];for(let y of f){if(S.has(y))continue;let x=[y],C=[];for(S.add(y);x.length>0;){let E=x.shift();C.push(E);for(let k of p.get(E)??[])S.has(k)||(S.add(k),x.push(k))}g.push(C.sort())}let b=[];for(let y of g)y.length>=2?c.push({subsystem:d,files:y}):b.push(...y);b.length>0&&c.push({subsystem:`${d}/residual`,files:b.sort()})}let l=c.map(d=>({subsystem:d.subsystem,files:[...d.files]}));for(let d=0;d<3;d++){let f=!1;e:for(let h=0;h<l.length;h++){let p=l[h];if(!(!p||p.files.length>3))for(let S=0;S<l.length;S++){if(h===S)continue;let g=l[S];if(!g)continue;let b=0,y=new Set(p.files),x=new Set(g.files);for(let C of o.values())(y.has(C.a)&&x.has(C.b)||y.has(C.b)&&x.has(C.a))&&(b+=C.weight);if(b>=20){g.files=[...new Set([...g.files,...p.files])].sort(),l.splice(h,1),f=!0;break e}}}if(!f)break}let u=[];for(let d of l){let f=new Set(d.files),h=0,p=0;for(let x of o.values()){let C=f.has(x.a),E=f.has(x.b);C&&E?h+=x.weight:(C||E)&&(p+=x.weight)}let S=h+p,g=d.subsystem.replace(/\/residual$/,""),b=yr(g),y=d.subsystem.endsWith("/residual")?`${b} Misc`:b;u.push({id:`cluster-${gr(`${d.subsystem}:${d.files.join("|")}`)}`,label:y,subsystem:g,files:d.files,size:d.files.length,internalWeight:h,externalWeight:p,cohesion:S>0?Number((h/S).toFixed(4)):0})}return u.sort((d,f)=>f.size-d.size||f.cohesion-d.cohesion||d.label.localeCompare(f.label))}};var fe=class{constructor(e){this.graph=e;this.entryPoints=new I(e),this.hotspots=new de(e),this.layers=new pe(e),this.clusters=new ue(e)}graph;entryPoints;hotspots;layers;clusters;analyze(e){let t=this.entryPoints.detect(e),r=this.hotspots.analyze(e),s=this.layers.detect(e),i=this.clusters.detect(e),o=new Set(this.graph.allSymbols(e).map(a=>a.filePath));return{version:1,projectId:e,updatedAt:new Date().toISOString(),summary:{files:o.size,entryPoints:t.length,hotspots:r.length,layers:s.length,clusters:i.length},entryPoints:t,hotspots:r,layers:s,clusters:i}}};var Qe=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Fe(n){return n.replaceAll("\\","/").toLowerCase()}function Sr(n){let e=Fe(n);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function br(n){let e=Fe(n.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var ge=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Set(new I(this.graph).detect(e).map(o=>o.symbolId)),i=[];for(let o of t){if(!["function","method","class","interface","property"].includes(o.type)||Sr(o.filePath)||s.has(o.id)||br(o)||r.filter(f=>f.to===o.id&&Qe.has(f.type)).length>0)continue;let m=r.filter(f=>f.from===o.id&&Qe.has(f.type)),c=["no incoming usage edge"],l=50;(o.type==="function"||o.type==="method")&&(l+=20,c.push("callable symbol")),o.type==="property"&&(l-=15),m.length===0&&(l+=10,c.push("no outgoing dependency")),Fe(o.filePath).includes("/internal/")&&(l+=10,c.push("internal implementation")),o.name.startsWith("_")&&(l+=5);let d=l>=75?"high":l>=55?"medium":"low";i.push({symbolId:o.id,name:o.name,qualifiedName:o.qualifiedName,type:o.type,filePath:o.filePath,startLine:o.startLine,confidence:d,score:l,reasons:c})}return i.sort((o,a)=>a.score-o.score||o.filePath.localeCompare(a.filePath)||o.name.localeCompare(a.name))}};var xr=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),he=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e).filter(o=>xr.has(o.type)),s=new Map(t.map(o=>[o.id,o]));return[...new Set(t.map(o=>o.filePath))].sort().map(o=>{let a=new Set,m=new Set,c=0,l=0;for(let u of r){let d=s.get(u.from),f=s.get(u.to);!d||!f||d.filePath===f.filePath||(d.filePath===o&&(a.add(f.filePath),c++),f.filePath===o&&(m.add(d.filePath),l++))}return{filePath:o,dependencies:[...a].sort(),dependents:[...m].sort(),outgoingEdges:c,incomingEdges:l}})}};var ye=class{constructor(e){this.graph=e}graph;analyze(e){let t=new ge(this.graph).analyze(e),r=new he(this.graph).analyze(e);return{version:1,projectId:e,updatedAt:new Date().toISOString(),summary:{deadCodeCandidates:t.length,highConfidenceDeadCode:t.filter(s=>s.confidence==="high").length,files:r.length},deadCode:t,dependencies:r}}};var Se=class{constructor(e){this.graph=e}graph;build(e,t,r){let s=this.graph.allSymbols(e),i=this.graph.allEdges(e),o=new Map(t?.layers.map(p=>[p.filePath,p.layer])??[]),a=new Map;for(let p of t?.clusters??[])for(let S of p.files)a.set(S,{id:p.id,label:p.label});let m=new Map(t?.hotspots.map(p=>[p.filePath,p.score])??[]),c=new Map(r?.deadCode.map(p=>[p.symbolId,{confidence:p.confidence,score:p.score}])??[]),l=new Map,u=new Map;for(let p of i)u.set(p.from,(u.get(p.from)??0)+1),l.set(p.to,(l.get(p.to)??0)+1);let d=s.map(p=>{let S=a.get(p.filePath);return{id:p.id,name:p.name,qualifiedName:p.qualifiedName,type:p.type,filePath:p.filePath,layer:o.get(p.filePath),cluster:S?.id,clusterLabel:S?.label,hotspotScore:m.get(p.filePath),deadCode:c.get(p.id),incoming:l.get(p.id)??0,outgoing:u.get(p.id)??0}}),f=new Set(d.map(p=>p.id)),h=i.filter(p=>f.has(p.from)&&f.has(p.to)).map(p=>({source:p.from,target:p.to,type:p.type,confidence:typeof p.metadata?.confidence=="string"?p.metadata.confidence:void 0,resolver:typeof p.metadata?.resolver=="string"?p.metadata.resolver:void 0}));return{version:1,projectId:e,generatedAt:new Date().toISOString(),summary:{nodes:d.length,links:h.length,files:new Set(d.map(p=>p.filePath)).size,clusters:new Set(d.map(p=>p.cluster).filter(Boolean)).size},nodes:d,links:h}}};import{homedir as Fr}from"node:os";import{join as _r}from"node:path";import{DeleteObjectCommand as wr,GetObjectCommand as Er,HeadObjectCommand as Cr,ListObjectsV2Command as vr,PutObjectCommand as Pr,S3Client as Rr}from"@aws-sdk/client-s3";import{getSignedUrl as Tr}from"@aws-sdk/s3-request-presigner";var be=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Rr({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,r="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Pr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Tr(this.client,new Er({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new Cr({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new wr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new vr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let i of s.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as Xe,mkdir as kr,readFile as Lr,readdir as jr,rm as Ar,stat as et,writeFile as Nr}from"node:fs/promises";import{dirname as Mr,join as Ir,relative as tt,resolve as Or}from"node:path";var W=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Or(this.root,t)}async put(e,t){let r=this.path(e);await kr(Mr(r),{recursive:!0}),await Nr(r,t)}async get(e){try{return await Lr(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await Xe(this.path(e)),!0}catch{return!1}}async delete(e){await Ar(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await Xe(t)}catch{return r}let s=async o=>{let a=await jr(o,{withFileTypes:!0});for(let m of a){let c=Ir(o,m.name);if(m.isDirectory()){await s(c);continue}let l=await et(c);r.push({key:tt(this.root,c),size:l.size,updatedAt:l.mtime.toISOString()})}},i=await et(t);return i.isDirectory()?await s(t):r.push({key:tt(this.root,t),size:i.size,updatedAt:i.mtime.toISOString()}),r}};function rt(n){let e=n.localRoot??_r(Fr(),".toolnet-memory","storage");if(n.provider==="huggingface"){let t=n.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new be({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new W(e))}return new W(e)}function $r(n){return new Promise(e=>setTimeout(e,n))}async function st(n,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,i;for(let o=1;o<=t;o++)try{return await n()}catch(a){if(i=a,o>=t)break;let m=Math.min(s,r*2**(o-1)),c=Math.floor(Math.random()*Math.max(1,m*.2));await $r(m+c)}throw i}var Dr=new Set(["put","get","getText","delete","list"]);function ot(n,e={}){return new Proxy(n,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:Dr.has(r)?(...i)=>st(()=>Promise.resolve(s.apply(t,i)),e):s.bind(t)}})}function nt(n){let e=n.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function it(n){let e=n.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var xe=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=nt(s??r),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),r=t,s=await this.provider.getText(e);if(s){let o;try{o=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof o.id=="string"&&o.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${o.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof o.createdAt=="string"&&(r=o.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(i,null,2)+`
7
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=it(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};var we=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","resolution","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var Ee=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","architecture"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),r=s=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:s},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/entry-points.json`,r(e.entryPoints),"application/json"),this.storage.put(`${t}/hotspots.json`,r(e.hotspots),"application/json"),this.storage.put(`${t}/layers.json`,r(e.layers),"application/json"),this.storage.put(`${t}/clusters.json`,r(e.clusters),"application/json")])}};var Ce=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","analysis"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),r=s=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:s},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/dead-code.json`,r(e.deadCode),"application/json"),this.storage.put(`${t}/dependencies.json`,r(e.dependencies),"application/json")])}};var ve=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","visualization","graph.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e,null,2),"application/json")}};async function at(n,e={}){let t=Date.now();async function r(p,S,g){await e.onStage?.({id:p,title:S,state:"start"});let b=Date.now(),y=await g();return await e.onStage?.({id:p,title:S,state:"complete",durationMs:Date.now()-b}),y}let s=ze(),i=ot(rt({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:3}),o=new xe(i,n.id,n.name,n.remote??n.name),a=new G(o),c=(await r("source-index","Source Index",async()=>{let p=await new ee().index(n.id,n.rootPath);return await a.save({version:1,projectId:n.id,updatedAt:new Date().toISOString(),files:p.files,symbols:p.graph.allSymbols(n.id),edges:p.graph.allEdges(n.id)}),p})).graph,l=await r("type-resolution","Type Resolution",async()=>{let p=await new ce(c).resolveProject(n.id,n.rootPath);return await new we(o).save(p),p});await r("rich-graph","Rich Graph",async()=>{let p=new le(c).enrich(n.id,n.rootPath,l),S=c.allSymbols(n.id),g=c.allEdges(n.id);return await a.save({version:1,projectId:n.id,updatedAt:new Date().toISOString(),files:S.filter(b=>b.type==="file").length,symbols:S,edges:g}),p});let u=await r("semantic-index","Semantic Code Index",async()=>new ne({projectId:n.id,rootPath:n.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:o,embeddings:Ve(),graph:c}).initialize()),d=await r("architecture","Architecture Intelligence",async()=>{let p=new fe(c).analyze(n.id);return await new Ee(o).save(p),p}),f=await r("analysis","Graph Analysis",async()=>{let p=new ye(c).analyze(n.id);return await new Ce(o).save(p),p}),h=await r("visualization","3D Visualization Dataset",async()=>{let p=new Se(c).build(n.id,d,f);return await new ve(o).save(p),p});return{project:{id:n.id,name:n.name,remote:n.remote??n.name},storage:o.name,durationMs:Date.now()-t,graph:{symbols:c.allSymbols(n.id).length,edges:c.allEdges(n.id).length},resolution:{total:l.total,exact:l.exact,high:l.high,fallback:l.fallback},semantic:u,architecture:d.summary,analysis:f.summary,visualization:h.summary}}var A=new q().detect(),Ge=De(A.rootPath,".toolnet"),_e=De(Ge,"index.lock"),Wr=De(Ge,"last-index.json");zr(Ge,{recursive:!0});function Pe(n){Kr(Wr,JSON.stringify(n,null,2)+`
8
+ `,{encoding:"utf8",mode:384})}var $e;try{$e=Br(_e,"wx",384)}catch{console.error("\u274C Index already running for this project."),console.error(`Lock: ${_e}`),process.exit(2)}var Re=new Date().toISOString(),V=[];try{console.log(),console.log("=============================================="),console.log(" ToolNet Production Index"),console.log("=============================================="),console.log(`Project : ${A.name}`),console.log(`Remote : projects/${A.remote??A.name}/`),console.log("Runtime : production/dist"),console.log("Snapshot: disabled"),Pe({version:2,state:"running",startedAt:Re,completedStages:V,project:A});let n=await at(A,{onStage:async e=>{e.state==="start"?(console.log(),console.log(`===== ${e.title} =====`)):(V.push(e.id),console.log(`\u2705 ${e.title} (${((e.durationMs??0)/1e3).toFixed(1)}s)`)),Pe({version:2,state:"running",startedAt:Re,currentStage:e.id,completedStages:[...V],project:A})}});Pe({version:2,state:"complete",startedAt:Re,finishedAt:new Date().toISOString(),completedStages:V,result:n}),console.log(),console.log("=============================================="),console.log(" FULL INDEX COMPLETE \u2705"),console.log("=============================================="),console.log(JSON.stringify(n,null,2))}catch(n){Pe({version:2,state:"failed",startedAt:Re,failedAt:new Date().toISOString(),completedStages:V,error:n instanceof Error?n.message:String(n)}),console.error("FULL INDEX FAILED \u274C"),console.error(n),process.exitCode=1}finally{$e!==void 0&&Gr($e),Hr(_e,{force:!0})}
@@ -0,0 +1,8 @@
1
+ import{existsSync as X,readFileSync as ee}from"node:fs";import{homedir as te}from"node:os";import{join as re}from"node:path";function oe(o){let e=o.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
2
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function ne(){let o=process.env.TOOLNET_GLOBAL_ENV??re(te(),".config","toolnet-memory",".env");if(!X(o))return;let e=ee(o,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let n=r.indexOf("=");if(n<=0)continue;let s=r.slice(0,n).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=oe(r.slice(n+1)))}}ne();function f(o,e){return o===void 0?e:["1","true","yes","on"].includes(o.toLowerCase())}function u(o,e){if(!o)return e;let t=Number(o);return Number.isFinite(t)?t:e}function O(){return{memory:{autoCapture:f(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:f(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:f(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:f(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:u(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:u(process.env.MEMORY_RERANK_TOP,10),finalContext:u(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:u(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:u(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var se={critical:100,high:75,normal:50,temporary:20};function C(o){return se[o]}function _(o,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c")||t.includes("must not")||t.includes("critical")?"critical":o==="rule"||o==="decision"?"high":o==="todo"?"normal":o==="activity"||o==="summary"?"temporary":"normal"}import{createHash as ie}from"node:crypto";import{existsSync as A,mkdirSync as ae,readFileSync as ce,renameSync as pe,writeFileSync as de}from"node:fs";import{basename as me,dirname as y,join as S,parse as z,resolve as g}from"node:path";var L=".toolnet",ue="project.json";function ge(o){return ie("sha256").update(o).digest("hex").slice(0,16)}function M(o){return S(o,L,ue)}function le(o){return A(M(o))}function fe(o,e){let t=g(o),r=z(t).root;for(;;){if(le(t))return t;if(t===r||e&&t===g(e))break;let n=y(t);if(n===t)break;t=n}return null}function ye(o){let e=g(o),t=z(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>A(S(e,s))))return e;if(e===t)break;let n=y(e);if(n===e)break;e=n}return g(o)}function he(o){let e;try{e=JSON.parse(ce(o,"utf8"))}catch(n){throw new Error(`Invalid ToolNet project manifest: ${o}: ${n instanceof Error?n.message:String(n)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${o}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${o}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${o}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:y(y(o)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function N(o,e){let t=S(o,L);ae(t,{recursive:!0});let r=M(o),n=`${r}.tmp-${process.pid}`;de(n,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),pe(n,r)}function $(o,e){return{id:o.id,name:o.name,remote:o.remote,rootPath:e,createdAt:o.createdAt,updatedAt:o.updatedAt,graphVersion:o.graphVersion,memoryVersion:o.memoryVersion,metadata:o.metadata}}var h=class{detect(e=process.cwd()){let t=g(e),r=ye(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>A(S(r,m))),i=fe(t,s?r:void 0);if(i){let m=M(i),p=he(m);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),N(i,p)),$(p,i)}let a=new Date().toISOString(),c=me(r),d={version:1,id:ge(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return N(r,d),$(d,r)}};import{randomUUID as ke}from"node:crypto";var Se=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],j=class{scan(e){let t=[];for(let r of Se){let n=new RegExp(r.regex.source,r.regex.flags);for(let s of e.matchAll(n))t.push({type:r.type,value:s[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var v=class{scanner=new j;sanitize(e){let t=e,r=this.scanner.scan(e),n=new Set;for(let s of r)n.add(s.type),t=t.split(s.value).join(`[REDACTED:${s.type}]`);return{text:t,redacted:r.length,secretTypes:[...n]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[r,n]of Object.entries(e)){let s=r.toLowerCase();s.includes("password")||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(n)}return t}return e}};var je=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),ve=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","use","using","the","a","an","cho","v\xE0","l\xE0","c\u1EE7a","to","for","with","quy\u1EBFt","\u0111\u1ECBnh"]);function D(o){return new Set(o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!ve.has(e)))}function we(o,e){let t=D(o),r=D(e);if(t.size===0||r.size===0)return 0;let n=0;for(let i of t)r.has(i)&&n++;let s=new Set([...t,...r]).size;return n/s}function K(o){return new Set(o.tags.filter(e=>!je.has(e.toLowerCase())))}var w=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,n=K(e);return t.filter(s=>{if(s.id===e.id||s.projectId!==e.projectId||s.type!==e.type||s.metadata?.supersededBy)return!1;let i=typeof s.metadata?.topic=="string"?s.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=K(s);for(let c of n)if(a.has(c))return!0;return we(e.content,s.content)>=.6})}};var xe={critical:100,high:75,normal:50,temporary:20},Pe={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function V(o,e,t=new Date){let r;if(e==="temporary"&&(r=30),o==="activity"&&(r=Math.min(r??14,14)),o==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function T(o,e=Date.now()){return o.expiresAt?new Date(o.expiresAt).getTime()<=e:!1}function be(o){return!!o.metadata?.supersededBy}function I(o,e=Date.now()){return!T(o,e)&&!be(o)}function E(o,e=Date.now()){if(!I(o,e))return 0;let t=xe[o.importance];if(o.importance==="critical")return t;let r=Pe[o.type]??180,s=Math.max(0,e-new Date(o.updatedAt).getTime())/864e5,i=Math.pow(.5,s/r);return t*i}var x=class{memories=new Map;sanitizer=new v;conflicts=new w;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,n=e.importance??_(e.type,r),s={id:ke(),projectId:e.projectId,type:e.type,content:r,importance:n,importanceScore:C(n),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??V(e.type,n,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(s,this.list(e.projectId));if(i.length){s.metadata={...s.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:s.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(s.id,s),s}importRecords(e){let t=0;for(let r of e)r?.id&&(this.memories.set(r.id,r),t++);return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,r)=>r.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>I(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(r=>r.type===t)}search(e){let t=e.query.trim().toLowerCase(),r=e.limit??10,n=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(s=>{if(e.types&&!e.types.includes(s.type))return!1;let i=E(s);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>s.tags.includes(c)))}).map(s=>{let i=s.content.toLowerCase(),a=n.filter(m=>i.includes(m)).length,c=n.length===0?0:a/n.length,d=E(s)/500;return{memory:s,score:c+d,source:"memory"}}).filter(s=>t.length===0||s.score>0).sort((s,i)=>i.score-s.score).slice(0,r)}pruneExpired(e,t=Date.now()){let r=0;for(let[n,s]of this.memories)s.projectId===e&&T(s,t)&&(this.memories.delete(n),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let n=0,s=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;r-new Date(c).getTime()>=s&&(this.memories.delete(i),n++)}return n}clearProject(e){let t=0;for(let[r,n]of this.memories)n.projectId===e&&(this.memories.delete(r),t++);return t}};import{homedir as Ve}from"node:os";import{join as Je}from"node:path";import{DeleteObjectCommand as Re,GetObjectCommand as Ae,HeadObjectCommand as Me,ListObjectsV2Command as Te,PutObjectCommand as Ie,S3Client as Ee}from"@aws-sdk/client-s3";import{getSignedUrl as Oe}from"@aws-sdk/s3-request-presigner";var P=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ee({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,r="application/octet-stream"){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ie({Bucket:this.bucket,Key:e,Body:n,ContentType:r}))}async get(e){let t=await Oe(this.client,new Ae({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new Me({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new Re({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let n=await this.client.send(new Te({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let s of n.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=n.IsTruncated?n.NextContinuationToken:void 0}while(r);return t}};import{access as J,mkdir as Ce,readFile as _e,readdir as Ne,rm as $e,stat as B,writeFile as ze}from"node:fs/promises";import{dirname as Le,join as De,relative as F,resolve as Ke}from"node:path";var l=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ke(this.root,t)}async put(e,t){let r=this.path(e);await Ce(Le(r),{recursive:!0}),await ze(r,t)}async get(e){try{return await _e(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await J(this.path(e)),!0}catch{return!1}}async delete(e){await $e(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await J(t)}catch{return r}let n=async i=>{let a=await Ne(i,{withFileTypes:!0});for(let c of a){let d=De(i,c.name);if(c.isDirectory()){await n(d);continue}let m=await B(d);r.push({key:F(this.root,d),size:m.size,updatedAt:m.mtime.toISOString()})}},s=await B(t);return s.isDirectory()?await n(t):r.push({key:F(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),r}};function H(o){let e=o.localRoot??Je(Ve(),".toolnet-memory","storage");if(o.provider==="huggingface"){let t=o.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new P({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new l(e))}return new l(e)}var b=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid memory snapshot");return r}async save(e,t){let r=JSON.stringify(t,null,2);await this.storage.put(this.key(e),r,"application/json")}};function Be(o){return new Promise(e=>setTimeout(e,o))}async function U(o,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,n=e.maxDelayMs??2e3,s;for(let i=1;i<=t;i++)try{return await o()}catch(a){if(s=a,i>=t)break;let c=Math.min(n,r*2**(i-1)),d=Math.floor(Math.random()*Math.max(1,c*.2));await Be(c+d)}throw s}var Fe=new Set(["put","get","getText","delete","list"]);function Y(o,e={}){return new Proxy(o,{get(t,r){let n=Reflect.get(t,r,t);return typeof n!="function"?n:Fe.has(r)?(...s)=>U(()=>Promise.resolve(n.apply(t,s)),e):n.bind(t)}})}function G(o){let e=o.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function W(o){let e=o.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let n=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return n?`${n[1]}memory/records/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),n?`${n[1]}memory/vectors/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),n?`${n[1]}code/graph/${n[2]}`:e))}var k=class{constructor(e,t,r,n){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=G(n??r),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),r=t,n=await this.provider.getText(e);if(n){let i;try{i=JSON.parse(n)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(s,null,2)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=W(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{closeSync as He,mkdirSync as Ue,openSync as Ye,readFileSync as Ge,unlinkSync as Z,writeFileSync as We}from"node:fs";import{tmpdir as Ze}from"node:os";import{join as q}from"node:path";function qe(o){try{return process.kill(o,0),!0}catch(e){return e?.code==="EPERM"}}var R=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=q(Ze(),"toolnet-memory-locks");Ue(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=q(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Ye(this.path,"wx");We(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),He(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let r=!0;try{let n=JSON.parse(Ge(this.path,"utf8"));Number.isInteger(n.pid)&&qe(n.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{Z(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{Z(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};function Qe(o){let e=o.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}async function Xe(o,e){let t=`projects/${o.id}/memory/learned/`,r=await e.list(t),n=[];for(let s of r.filter(i=>i.key.includes("/batches/")&&i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(s.key);if(i)try{let a=JSON.parse(i);if(a.version!==1||!Array.isArray(a.candidates))continue;n.push(a)}catch{}}return n}async function Q(o,e){let t=await Xe(o,e),r=new b(e),n=await r.load(o.id),s=new x;s.importRecords(n);let i=new Set(n.map(m=>Qe(m)).filter(m=>!!m)),a=0,c=0,d=0;for(let m of t)for(let p of m.candidates){if(a+=1,i.has(p.fingerprint)){d+=1;continue}s.remember({projectId:o.id,type:p.type,content:p.content,importance:p.importance,tags:p.tags,source:"session-memory-learner",metadata:{learningFingerprint:p.fingerprint,learningKind:p.kind,confidence:p.confidence,provenance:p.provenance,sourceCreatedAt:p.createdAt,sessionKey:p.sessionKey,agent:p.agent,nativeSessionId:p.nativeSessionId}}),i.add(p.fingerprint),c+=1}return c>0&&await r.save(o.id,s.exportProject(o.id)),{batches:t.length,candidates:a,added:c,duplicates:d,memories:s.exportProject(o.id).length}}function et(o,e){let t=o.indexOf(e);return t>=0?o[t+1]:void 0}async function tt(){let[o="help",...e]=process.argv.slice(2);if(o!=="reconcile"){console.log(`Session Memory Learner
5
+
6
+ Commands:
7
+ reconcile [--project PATH]
8
+ `);return}let t=et(e,"--project")??process.cwd(),r=new h().detect(t),n=O(),s=Y(H({provider:n.storage.provider,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),{attempts:3}),i=new k(s,r.id,r.name,r.remote??r.name),a=new R(r.id);await a.acquire();try{let c=await Q(r,i);console.log(JSON.stringify({project:r.name,...c},null,2))}finally{await a.release()}}tt().catch(o=>{console.error(o instanceof Error?o.message:o),process.exit(1)});
package/bundle/mcp.js ADDED
@@ -0,0 +1,7 @@
1
+ import"dotenv/config";import{existsSync as sr,readFileSync as nr}from"node:fs";import{homedir as ir}from"node:os";import{join as ar}from"node:path";function cr(o){let e=o.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
2
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function lr(){let o=process.env.TOOLNET_GLOBAL_ENV??ar(ir(),".config","toolnet-memory",".env");if(!sr(o))return;let e=nr(o,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let n=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=cr(r.slice(s+1)))}}lr();function q(o,e){return o===void 0?e:["1","true","yes","on"].includes(o.toLowerCase())}function A(o,e){if(!o)return e;let t=Number(o);return Number.isFinite(t)?t:e}function Ie(){return{memory:{autoCapture:q(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:q(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:q(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:q(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:A(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:A(process.env.MEMORY_RERANK_TOP,10),finalContext:A(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:A(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:A(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var pr={critical:100,high:75,normal:50,temporary:20};function Oe(o){return pr[o]}function _e(o,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c")||t.includes("must not")||t.includes("critical")?"critical":o==="rule"||o==="decision"?"high":o==="todo"?"normal":o==="activity"||o==="summary"?"temporary":"normal"}import{createHash as dr}from"node:crypto";import{existsSync as Ce,mkdirSync as mr,readFileSync as fr,renameSync as ur,writeFileSync as gr}from"node:fs";import{basename as hr,dirname as K,join as W,parse as De,resolve as I}from"node:path";var Ge=".toolnet",yr="project.json";function Sr(o){return dr("sha256").update(o).digest("hex").slice(0,16)}function we(o){return W(o,Ge,yr)}function br(o){return Ce(we(o))}function xr(o,e){let t=I(o),r=De(t).root;for(;;){if(br(t))return t;if(t===r||e&&t===I(e))break;let s=K(t);if(s===t)break;t=s}return null}function Cr(o){let e=I(o),t=De(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>Ce(W(e,n))))return e;if(e===t)break;let s=K(e);if(s===e)break;e=s}return I(o)}function wr(o){let e;try{e=JSON.parse(fr(o,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${o}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${o}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${o}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${o}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:K(K(o)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function Fe(o,e){let t=W(o,Ge);mr(t,{recursive:!0});let r=we(o),s=`${r}.tmp-${process.pid}`;gr(s,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),ur(s,r)}function $e(o,e){return{id:o.id,name:o.name,remote:o.remote,rootPath:e,createdAt:o.createdAt,updatedAt:o.updatedAt,graphVersion:o.graphVersion,memoryVersion:o.memoryVersion,metadata:o.metadata}}var H=class{detect(e=process.cwd()){let t=I(e),r=Cr(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>Ce(W(r,p))),i=xr(t,n?r:void 0);if(i){let p=we(i),m=wr(p);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),Fe(i,m)),$e(m,i)}let a=new Date().toISOString(),c=hr(r),l={version:1,id:Sr(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Fe(r,l),$e(l,r)}};import{randomUUID as kr}from"node:crypto";var vr=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],V=class{scan(e){let t=[];for(let r of vr){let s=new RegExp(r.regex.source,r.regex.flags);for(let n of e.matchAll(s))t.push({type:r.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var k=class{scanner=new V;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let n of r)s.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[r,s]of Object.entries(e)){let n=r.toLowerCase();n.includes("password")||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var Er=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Pr=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","use","using","the","a","an","cho","v\xE0","l\xE0","c\u1EE7a","to","for","with","quy\u1EBFt","\u0111\u1ECBnh"]);function ze(o){return new Set(o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Pr.has(e)))}function jr(o,e){let t=ze(o),r=ze(e);if(t.size===0||r.size===0)return 0;let s=0;for(let i of t)r.has(i)&&s++;let n=new Set([...t,...r]).size;return s/n}function Be(o){return new Set(o.tags.filter(e=>!Er.has(e.toLowerCase())))}var U=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,s=Be(e);return t.filter(n=>{if(n.id===e.id||n.projectId!==e.projectId||n.type!==e.type||n.metadata?.supersededBy)return!1;let i=typeof n.metadata?.topic=="string"?n.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=Be(n);for(let c of s)if(a.has(c))return!0;return jr(e.content,n.content)>=.6})}};var Rr={critical:100,high:75,normal:50,temporary:20},Tr={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function qe(o,e,t=new Date){let r;if(e==="temporary"&&(r=30),o==="activity"&&(r=Math.min(r??14,14)),o==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function ve(o,e=Date.now()){return o.expiresAt?new Date(o.expiresAt).getTime()<=e:!1}function Mr(o){return!!o.metadata?.supersededBy}function Ee(o,e=Date.now()){return!ve(o,e)&&!Mr(o)}function O(o,e=Date.now()){if(!Ee(o,e))return 0;let t=Rr[o.importance];if(o.importance==="critical")return t;let r=Tr[o.type]??180,n=Math.max(0,e-new Date(o.updatedAt).getTime())/864e5,i=Math.pow(.5,n/r);return t*i}var J=class{memories=new Map;sanitizer=new k;conflicts=new U;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,s=e.importance??_e(e.type,r),n={id:kr(),projectId:e.projectId,type:e.type,content:r,importance:s,importanceScore:Oe(s),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??qe(e.type,s,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(n,this.list(e.projectId));if(i.length){n.metadata={...n.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:n.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(n.id,n),n}importRecords(e){let t=0;for(let r of e)r?.id&&(this.memories.set(r.id,r),t++);return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,r)=>r.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>Ee(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(r=>r.type===t)}search(e){let t=e.query.trim().toLowerCase(),r=e.limit??10,s=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(n=>{if(e.types&&!e.types.includes(n.type))return!1;let i=O(n);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>n.tags.includes(c)))}).map(n=>{let i=n.content.toLowerCase(),a=s.filter(p=>i.includes(p)).length,c=s.length===0?0:a/s.length,l=O(n)/500;return{memory:n,score:c+l,source:"memory"}}).filter(n=>t.length===0||n.score>0).sort((n,i)=>i.score-n.score).slice(0,r)}pruneExpired(e,t=Date.now()){let r=0;for(let[s,n]of this.memories)n.projectId===e&&ve(n,t)&&(this.memories.delete(s),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let s=0,n=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;r-new Date(c).getTime()>=n&&(this.memories.delete(i),s++)}return s}clearProject(e){let t=0;for(let[r,s]of this.memories)s.projectId===e&&(this.memories.delete(r),t++);return t}};function L(o){return o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var Y=class{score(e,t){let r=L(e),s=L([t.content,...t.tags??[],t.type].join(" "));if(r.length===0||s.length===0)return 0;let n=new Map;for(let a of s)n.set(a,(n.get(a)??0)+1);let i=0;for(let a of r){let c=n.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/r.length}};function Ke(o,e=Date.now()){let t=o.updatedAt??o.createdAt,r=new Date(t).getTime();if(!Number.isFinite(r))return 0;let s=Math.max(0,e-r)/864e5;return Math.exp(-Math.LN2*s/30)}function He(o){return O(o)/100}var Lr={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function We(o){return Lr[o]??.4}var Q=class{analyze(e){let t=e.toLowerCase(),r=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&r.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&r.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&r.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&r.push("summary"),{query:e,preferredTypes:r}}};var Z=class{bm25=new Y;analyzer=new Q;search(e,t,r={}){let s=r.topK??8,n=r.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(r.types?.length&&!r.types.includes(c.type))continue;let l=this.bm25.score(e,c),p=Ke(c),m=He(c),d=We(c.type);i.preferredTypes.includes(c.type)&&(d=Math.min(1,d+.25));let f=l*.55+m*.2+p*.15+d*.1;l<=0||f<n||a.push({memory:c,score:f,scores:{keyword:l,recency:p,importance:m,type:d}})}return a.sort((c,l)=>l.score-c.score).slice(0,s)}};var X=class{build(e,t=6e3){let r=[],s=0;for(let n of e){let i=n.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(s+a.length>t)break;r.push(a),s+=a.length}return r.join(`
4
+ `)}};var ee=class{constructor(e){this.memory=e}memory;searcher=new Z;contextBuilder=new X;search(e,t,r={}){return this.searcher.search(t,this.memory.list(e),r)}context(e,t,r={}){let s=this.search(e,t,r);return this.contextBuilder.build(s)}};var te=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,r=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:e,options:{wait_for_model:!0}})});if(!r.ok)throw new Error(`HF embedding failed: ${r.status} ${await r.text()}`);let s=await r.json();if(!Array.isArray(s))throw new Error("HF embedding returned invalid response");return s.map(n=>Nr(n))}};function Nr(o){if(!Array.isArray(o))throw new Error("Invalid embedding");if(o.length>0&&typeof o[0]=="number")return o;if(o.length>0&&Array.isArray(o[0])){let e=o;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let n=0;n<t;n++)r[n]+=s[n]??0;for(let s=0;s<t;s++)r[s]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as Ar}from"node:crypto";var re=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),r=e.toLowerCase().split(/\s+/).filter(Boolean);for(let s of r){let i=Ar("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return Ir(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function Ir(o){let e=Math.sqrt(o.reduce((t,r)=>t+r*r,0));return e===0?o:o.map(t=>t/e)}var Pe=class{constructor(e,t=new re){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}};function Ve(){let o=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=o?new te({token:o,model:e}):null;return new Pe(t)}import Hs from"typescript";var N=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(r=>r.projectId===e&&(r.name===t||r.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let r of e)this.addSymbol(r);for(let r of t)this.addEdge(r)}clearProject(e){for(let[t,r]of this.symbols)r.projectId===e&&this.symbols.delete(t);for(let[t,r]of this.edges)r.projectId===e&&this.edges.delete(t)}};function oe(o,e){let t=o.allSymbols(e),r=o.allEdges(e),s=i=>t.filter(a=>a.type===i).length,n=i=>r.filter(a=>a.type===i).length;return{files:s("file"),classes:s("class"),interfaces:s("interface"),functions:s("function"),methods:s("method"),properties:s("property"),routes:s("route"),symbols:t.length,edges:r.length,calls:n("CALLS"),callReferences:n("CALL_REFERENCE"),imports:n("IMPORTS"),inherits:n("INHERITS"),implements:n("IMPLEMENTS"),usesType:n("USES_TYPE"),tests:n("TESTS"),routeEdges:n("ROUTE"),writes:n("WRITES")}}var se=class{constructor(e){this.graph=e}graph;callees(e,t,r=3){return this.walk(e,t,"out",r)}callers(e,t,r=3){return this.walk(e,t,"in",r)}walk(e,t,r,s){let n=[],i=new Set([t]),a=[{id:t,depth:0}],c=this.graph.allEdges(e).filter(l=>l.type==="CALLS"||l.type==="CALL_REFERENCE");for(;a.length;){let l=a.shift();if(l.depth>=s)continue;let p=r==="out"?c.filter(m=>m.from===l.id):c.filter(m=>m.to===l.id);for(let m of p){let d=r==="out"?m.to:m.from;if(i.has(d))continue;i.add(d);let f=this.graph.getSymbol(d);if(!f)continue;let g=l.depth+1;n.push({symbol:f,depth:g}),a.push({id:d,depth:g})}}return n}};var ne=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(s=>s.type==="CALLS"&&s.to===t).map(s=>s.from).map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};var ie=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let s=this.graph.allEdges(e),n=new Set([t]),i=[{id:t,depth:0}],a=[];for(;i.length;){let c=i.shift();if(c.depth>=r)continue;let l=s.filter(p=>p.to===c.id&&["CALLS","IMPORTS","INHERITS","IMPLEMENTS"].includes(p.type));for(let p of l){if(n.has(p.from))continue;n.add(p.from);let m=this.graph.getSymbol(p.from);if(!m)continue;let d=c.depth+1;a.push({symbol:m,depth:d,relation:p.type}),i.push({id:p.from,depth:d})}}return a}};function $r(o,e){return e.ranges.length===0?!0:typeof o.startLine!="number"||typeof o.endLine!="number"?!1:e.ranges.some(t=>o.startLine<=t.endLine&&o.endLine>=t.startLine)}var ae=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),s=[];for(let n of t){let i=r.filter(l=>l.filePath===n.filePath),c=i.filter(l=>l.type!=="file").filter(l=>$r(l,n));if(c.length===0){let l=i.find(p=>p.type==="file");l&&s.push({symbol:l,fileStatus:n.status,direct:!0});continue}for(let l of c)s.push({symbol:l,fileStatus:n.status,direct:!0})}return s}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var Dr={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function Gr(o){return o>=30?"CRITICAL":o>=16?"HIGH":o>=6?"MEDIUM":"LOW"}function Ue(o){let e=o.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var ce=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let s=this.graph.allEdges(e),n=new Map,i=0;for(let p of t){p.fileStatus==="deleted"?i+=8:p.fileStatus==="renamed"?i+=5:i+=2,p.symbol.type==="interface"&&(i+=5),p.symbol.type==="class"&&(i+=3);let m=new Set([p.symbol.id]),d=[{id:p.symbol.id,depth:0}];for(;d.length;){let f=d.shift();if(f.depth>=r)continue;let g=s.filter(h=>h.to===f.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(h.type));for(let h of g){if(m.has(h.from))continue;m.add(h.from);let C=this.graph.getSymbol(h.from);if(!C)continue;let w=f.depth+1,B=`${p.symbol.id}:${C.id}`;n.set(B,{symbol:C,relation:h.type,depth:w,sourceSymbolId:p.symbol.id});let R=Dr[h.type]??1;i+=Math.max(1,R-(w-1)),d.push({id:C.id,depth:w})}}}let a=[...n.values()].sort((p,m)=>p.depth-m.depth),c=[...new Set(a.map(p=>p.symbol.filePath))],l=c.filter(Ue);return l.length===0&&l.push(...c.filter(p=>!Ue(p)).slice(0,10)),{risk:Gr(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as zr}from"node:child_process";import{promisify as Br}from"node:util";var je=Br(zr);function qr(o){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of o.matchAll(t)){let s=Number(r[1]),n=Number(r[2]??1);e.push({startLine:s,endLine:Math.max(s,s+n-1)})}return e}function Kr(o){return o.startsWith("A")?"added":o.startsWith("D")?"deleted":o.startsWith("R")?"renamed":"modified"}async function Je(o){let e="";try{e=(await je("git",["diff","HEAD","--name-status","--no-renames"],{cwd:o,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[s,...n]=r.split(" "),i=n.at(-1);if(!i)continue;let a="";try{a=(await je("git",["diff","HEAD","--unified=0","--",i],{cwd:o,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:Kr(s),ranges:qr(a)})}try{let r=await je("git",["ls-files","--others","--exclude-standard"],{cwd:o});for(let s of r.stdout.split(/\r?\n/).filter(Boolean))t.some(n=>n.filePath===s)||t.push({filePath:s,status:"added",ranges:[]})}catch{}return t}var le=class{constructor(e){this.graph=e;this.mapper=new ae(e),this.blast=new ce(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let s=await Je(t),n=this.mapper.map(e,s),i=this.blast.analyze(e,n,r.maxDepth??4);return{mode:"git_diff",changes:s,...i}}analyzeFile(e,t,r={}){let s=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,s,r.maxDepth??4)}}};var _=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};import{createHash as Hr}from"node:crypto";import{readFile as Wr}from"node:fs/promises";import{join as Vr}from"node:path";function Ye(o){return Hr("sha256").update(o).digest("hex")}var pe=class{sanitizer=new k;async build(e,t,r,s={}){let n=s.maxLines??80,i=s.overlapLines??10,a=new Map;for(let l of r){let p=a.get(l.filePath)??[];p.push(l),a.set(l.filePath,p)}let c=[];for(let[l,p]of a){let m;try{m=await Wr(Vr(t,l),"utf8")}catch{continue}let d=m.split(/\r?\n/),f=p.filter(g=>g.type!=="file"&&typeof g.startLine=="number"&&typeof g.endLine=="number");if(f.length>0)for(let g of f)c.push(...this.chunkRange({projectId:e,filePath:l,lines:d,symbol:g,startLine:g.startLine,endLine:g.endLine,maxLines:n,overlapLines:i}));else c.push(...this.chunkRange({projectId:e,filePath:l,lines:d,startLine:1,endLine:Math.max(1,d.length),maxLines:n,overlapLines:i}))}return c}chunkRange(e){let{projectId:t,filePath:r,lines:s,symbol:n,maxLines:i}=e,a=Math.min(e.overlapLines,Math.max(0,i-1)),c=Math.max(1,e.startLine),l=Math.min(s.length,Math.max(c,e.endLine)),p=[],m=c,d=0;for(;m<=l;){let f=Math.min(l,m+i-1),g=s.slice(m-1,f).join(`
5
+ `).trim();if(g){let h=this.sanitizer.sanitize(g).text,C=Ye(h),w=[t,r,n?.id??"file",String(d),C].join(":");p.push({id:Ye(w).slice(0,32),projectId:t,filePath:r,symbolId:n?.id,symbolName:n?.qualifiedName??n?.name,symbolType:n?.type,startLine:m,endLine:f,content:h,contentHash:C})}if(f>=l)break;m=f-a+1,d++}return p}};var de=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var me=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var fe=class{records=new Map;upsert(e){this.records.set(e.id,e)}get(e){return this.records.get(e)}has(e){return this.records.has(e)}remove(e){return this.records.delete(e)}clearProject(e){let t=0;for(let[r,s]of this.records)s.projectId===e&&(this.records.delete(r),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let r of e)!r?.id||!r?.projectId||!Array.isArray(r.vector)||(this.records.set(r.id,r),t++);return t}search(e,t,r=10){let s=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let i=Ur(t,n.vector);s.push({id:n.id,score:i,metadata:n.metadata})}return s.sort((n,i)=>i.score-n.score).slice(0,r)}size(){return this.records.size}};function Ur(o,e){if(o.length===0||e.length===0||o.length!==e.length)return 0;let t=0,r=0,s=0;for(let n=0;n<o.length;n++){let i=o[n]??0,a=e[n]??0;t+=i*a,r+=i*i,s+=a*a}return r===0||s===0?0:t/(Math.sqrt(r)*Math.sqrt(s))}function Qe(o,e){let t=o.toLowerCase().replaceAll("\\","/"),r=e.toLowerCase(),s=/\b(test|tests|spec|fixture|mock)\b/.test(r);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!s?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var ue=class{constructor(e){this.options=e}options;vectors=new fe;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:r,embeddings:s,graph:n,model:i}=this.options,a=new de(r),c=new me(r),l=await new pe().build(e,t,n.allSymbols(e));this.chunks.clear();for(let y of l)this.chunks.set(y.id,y);let p=await a.load(e),m=!p||p.chunks.length!==l.length||p.chunks.some(y=>!this.chunks.has(y.id));m&&await a.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:l});let d=await c.load(e),f=0;d&&d.model===i&&(f=this.vectors.importRecords(d.records));let g=new Set(l.map(y=>y.id)),h=0;for(let y of this.vectors.exportProject(e))g.has(y.id)||this.vectors.remove(y.id)&&h++;let C=l.filter(y=>{let T=this.vectors.get(y.id);return T?T.metadata?.contentHash!==y.contentHash:!0}),w=0,B=8,R=this.vectors.exportProject(e)[0]?.vector.length;for(let y=0;y<C.length;y+=B){let T=C.slice(y,y+B),rr=T.map(x=>[`file: ${x.filePath}`,x.symbolName?`symbol: ${x.symbolName}`:"",x.symbolType?`type: ${x.symbolType}`:"",x.content].filter(Boolean).join(`
6
+ `)),or=await s.embedMany(rr);for(let x=0;x<T.length;x++){let P=T[x],M=or[x];if(!(!P||!M||M.length===0)){if(R===void 0&&(R=M.length),M.length!==R){console.warn(`[code-semantic] skip dimension mismatch: ${M.length} != ${R}`);continue}this.vectors.upsert({id:P.id,projectId:e,vector:M,metadata:{contentHash:P.contentHash,filePath:P.filePath,symbolName:P.symbolName,symbolType:P.symbolType,startLine:P.startLine,endLine:P.endLine}}),w++}}}let xe=this.vectors.exportProject(e),Ae=w>0||h>0||!d||d.model!==i;return Ae&&await c.save({version:1,projectId:e,model:i,dimensions:xe[0]?.vector.length??R??0,updatedAt:new Date().toISOString(),records:xe}),{chunks:l.length,vectorsLoaded:f,vectorsIndexed:w,vectorsRemoved:h,totalVectors:xe.length,savedChunks:m,savedVectors:Ae}}async search(e,t=8){let r=await this.options.embeddings.embed(e),s=this.vectors.search(this.options.projectId,r,Math.max(t*4,20)),n=new Set(L(e)),i=[];for(let a of s){let c=this.chunks.get(a.id);if(!c)continue;let l=new Set(L([c.filePath,c.symbolName??"",c.symbolType??"",c.content].join(" "))),p=0;for(let h of n)l.has(h)&&p++;let m=n.size===0?0:p/n.size,d=Math.max(0,a.score),f=Qe(c.filePath,e),g=(d*.75+m*.25)*f;i.push({chunk:c,score:g,vectorScore:d,lexicalScore:m})}return i.sort((a,c)=>c.score-a.score).slice(0,t)}size(){return this.chunks.size}};import di from"typescript";import v from"typescript";var yi=new Set([v.SyntaxKind.EqualsToken,v.SyntaxKind.PlusEqualsToken,v.SyntaxKind.MinusEqualsToken,v.SyntaxKind.AsteriskEqualsToken,v.SyntaxKind.SlashEqualsToken,v.SyntaxKind.PercentEqualsToken,v.SyntaxKind.QuestionQuestionEqualsToken,v.SyntaxKind.AmpersandAmpersandEqualsToken,v.SyntaxKind.BarBarEqualsToken]);function Jr(o){return o.replaceAll("\\","/").toLowerCase()}var F=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,r);a&&s.push({symbolId:i.id,filePath:i.filePath,name:i.name,kind:a.kind,score:a.score,reasons:a.reasons})}let n=new Map;for(let i of s){let a=i.kind==="route"?i.symbolId:i.filePath,c=n.get(a);(!c||i.score>c.score)&&n.set(a,i)}return[...n.values()].sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath))}classify(e,t){let r=Jr(e.filePath),s=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let n=null,i=0;if(r.startsWith("bin/"))n="cli",i=100,s.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(r))n="cli",i=90,s.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(r))n="main",i=90,s.push("main/server file");else if(r.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(r))n="runtime",i=75,s.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(r)){let c=t.filter(p=>p.to===e.id&&p.type!=="DEFINES").length,l=t.filter(p=>p.from===e.id&&p.type!=="DEFINES").length;(r.startsWith("packages/")||c===0||l>0)&&(n="package",i=r.startsWith("packages/")?70:55,s.push("package/public index"))}return n?(t.filter(c=>c.to===e.id&&c.type!=="DEFINES").length===0&&(i+=10,s.push("no incoming dependency")),{kind:n,score:i,reasons:s}):null}};var ge=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Ze=new Set(["CALLS","CALL_REFERENCE"]),b=class{constructor(e){this.graph=e}graph;findSymbols(e,t){let r=t.trim().toLowerCase();return r?this.graph.allSymbols(e).filter(s=>s.name.toLowerCase().includes(r)||(s.qualifiedName?.toLowerCase().includes(r)??!1)||s.filePath.toLowerCase().includes(r)).sort((s,n)=>{let i=s.name.toLowerCase()===r,a=n.name.toLowerCase()===r;return i!==a?i?-1:1:s.filePath.localeCompare(n.filePath)}):[]}callers(e,t){return this.relatedIncoming(e,t,Ze)}callees(e,t){return this.relatedOutgoing(e,t,Ze)}dependents(e,t){return this.relatedIncoming(e,t,ge)}dependencies(e,t){return this.relatedOutgoing(e,t,ge)}neighborhood(e,t,r=1){let s=this.graph.getSymbol(t);return!s||s.projectId!==e?null:{center:s,incoming:this.walk(e,t,"incoming",r),outgoing:this.walk(e,t,"outgoing",r)}}shortestPath(e,t,r,s=12){let n=this.graph.getSymbol(t),i=this.graph.getSymbol(r);if(!n||!i||n.projectId!==e||i.projectId!==e)return{found:!1,distance:-1,symbols:[],edges:[]};if(t===r)return{found:!0,distance:0,symbols:[n],edges:[]};let a=this.graph.allEdges(e).filter(d=>ge.has(d.type)),c=new Map;for(let d of a){let f=c.get(d.from)??[];f.push(d),c.set(d.from,f)}let l=[{id:t,depth:0}],p=new Set([t]),m=new Map;for(;l.length>0;){let d=l.shift();if(!(d.depth>=s)){for(let f of c.get(d.id)??[])if(!p.has(f.to)){if(p.add(f.to),m.set(f.to,{node:d.id,edge:f}),f.to===r)return this.buildPath(t,r,m);l.push({id:f.to,depth:d.depth+1})}}}return{found:!1,distance:-1,symbols:[],edges:[]}}buildPath(e,t,r){let s=[t],n=[],i=t;for(;i!==e;){let c=r.get(i);if(!c)return{found:!1,distance:-1,symbols:[],edges:[]};n.push(c.edge),i=c.node,s.push(i)}s.reverse(),n.reverse();let a=s.map(c=>this.graph.getSymbol(c)).filter(c=>!!c);return{found:!0,distance:n.length,symbols:a,edges:n}}walk(e,t,r,s){let n=this.graph.allEdges(e).filter(l=>ge.has(l.type)),i=[{id:t,depth:0}],a=new Set([t]),c=[];for(;i.length>0;){let l=i.shift();if(!(l.depth>=s))for(let p of n){if(!(r==="incoming"?p.to===l.id:p.from===l.id))continue;let d=r==="incoming"?p.from:p.to;if(a.has(d))continue;let f=this.graph.getSymbol(d);f&&(a.add(d),c.push({symbol:f,depth:l.depth+1,via:p}),i.push({id:d,depth:l.depth+1}))}}return c}relatedIncoming(e,t,r){return[...new Set(this.graph.allEdges(e).filter(n=>n.to===t&&r.has(n.type)).map(n=>n.from))].map(n=>this.graph.getSymbol(n)).filter(n=>!!n)}relatedOutgoing(e,t,r){return[...new Set(this.graph.allEdges(e).filter(n=>n.from===t&&r.has(n.type)).map(n=>n.to))].map(n=>this.graph.getSymbol(n)).filter(n=>!!n)}};var Xe=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Re(o){return o.replaceAll("\\","/").toLowerCase()}function Yr(o){let e=Re(o);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function Qr(o){let e=Re(o.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var $=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Set(new F(this.graph).detect(e).map(i=>i.symbolId)),n=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||Yr(i.filePath)||s.has(i.id)||Qr(i)||r.filter(f=>f.to===i.id&&Xe.has(f.type)).length>0)continue;let c=r.filter(f=>f.from===i.id&&Xe.has(f.type)),l=["no incoming usage edge"],p=50;(i.type==="function"||i.type==="method")&&(p+=20,l.push("callable symbol")),i.type==="property"&&(p-=15),c.length===0&&(p+=10,l.push("no outgoing dependency")),Re(i.filePath).includes("/internal/")&&(p+=10,l.push("internal implementation")),i.name.startsWith("_")&&(p+=5);let d=p>=75?"high":p>=55?"medium":"low";n.push({symbolId:i.id,name:i.name,qualifiedName:i.qualifiedName,type:i.type,filePath:i.filePath,startLine:i.startLine,confidence:d,score:p,reasons:l})}return n.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var Zr=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),D=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e).filter(i=>Zr.has(i.type)),s=new Map(t.map(i=>[i.id,i]));return[...new Set(t.map(i=>i.filePath))].sort().map(i=>{let a=new Set,c=new Set,l=0,p=0;for(let m of r){let d=s.get(m.from),f=s.get(m.to);!d||!f||d.filePath===f.filePath||(d.filePath===i&&(a.add(f.filePath),l++),f.filePath===i&&(c.add(d.filePath),p++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:l,incomingEdges:p}})}};import{homedir as go}from"node:os";import{join as ho}from"node:path";import{DeleteObjectCommand as Xr,GetObjectCommand as eo,HeadObjectCommand as to,ListObjectsV2Command as ro,PutObjectCommand as oo,S3Client as so}from"@aws-sdk/client-s3";import{getSignedUrl as no}from"@aws-sdk/s3-request-presigner";var he=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new so({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,r="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new oo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await no(this.client,new eo({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new to({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new Xr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new ro({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as et,mkdir as io,readFile as ao,readdir as co,rm as lo,stat as tt,writeFile as po}from"node:fs/promises";import{dirname as mo,join as fo,relative as rt,resolve as uo}from"node:path";var G=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return uo(this.root,t)}async put(e,t){let r=this.path(e);await io(mo(r),{recursive:!0}),await po(r,t)}async get(e){try{return await ao(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await et(this.path(e)),!0}catch{return!1}}async delete(e){await lo(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await et(t)}catch{return r}let s=async i=>{let a=await co(i,{withFileTypes:!0});for(let c of a){let l=fo(i,c.name);if(c.isDirectory()){await s(l);continue}let p=await tt(l);r.push({key:rt(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await tt(t);return n.isDirectory()?await s(t):r.push({key:rt(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};function ot(o){let e=o.localRoot??ho(go(),".toolnet-memory","storage");if(o.provider==="huggingface"){let t=o.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new he({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new G(e))}return new G(e)}var ye=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid memory snapshot");return r}async save(e,t){let r=JSON.stringify(t,null,2);await this.storage.put(this.key(e),r,"application/json")}};function yo(o){return new Promise(e=>setTimeout(e,o))}async function st(o,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await o()}catch(a){if(n=a,i>=t)break;let c=Math.min(s,r*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await yo(c+l)}throw n}var So=new Set(["put","get","getText","delete","list"]);function nt(o,e={}){return new Proxy(o,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:So.has(r)?(...n)=>st(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function it(o){let e=o.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function at(o){let e=o.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var Se=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=it(s??r),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),r=t,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
7
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=at(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{McpServer as jo}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as Ro}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as ct}from"zod";var lt={query:ct.string(),limit:ct.number().int().min(1).max(20).optional()};async function pt(o,e){return o.retrieval.search(o.project.id,e.query,{topK:e.limit??8}).map(r=>({id:r.memory.id,type:r.memory.type,content:r.memory.content,importance:r.memory.importance,score:r.score,tags:r.memory.tags}))}import{z}from"zod";var dt={type:z.enum(["activity","decision","rule","todo","summary"]),content:z.string().min(1),tags:z.array(z.string()).optional(),importance:z.enum(["critical","high","normal","temporary"]).optional()};async function mt(o,e){let t=o.memory.remember({projectId:o.project.id,type:e.type,content:e.content,tags:e.tags,importance:e.importance,source:"mcp"});return o.memoryStore&&await o.memoryStore.save(o.project.id,o.memory.exportProject(o.project.id)),t}import{z as bo}from"zod";var ft={id:bo.string().min(1)};async function ut(o,e){let t=o.memory.delete(e.id);return t&&o.memoryStore&&await o.memoryStore.save(o.project.id,o.memory.exportProject(o.project.id)),{deleted:t}}import{z as xo}from"zod";var gt={name:xo.string().min(1)};async function ht(o,e){return o.graph.findByName(o.project.id,e.name)}import{z as Co}from"zod";function E(o,e){let t=o.graph.getSymbol(e);if(t&&t.projectId===o.project.id)return t;let r=new b(o.graph),s=r.findSymbols(o.project.id,e).find(n=>n.name===e||n.qualifiedName===e);return s||(r.findSymbols(o.project.id,e)[0]??null)}function S(o){return{id:o.id,name:o.name,qualifiedName:o.qualifiedName,type:o.type,filePath:o.filePath,startLine:o.startLine,endLine:o.endLine}}var yt={symbolId:Co.string().min(1)};async function St(o,e){let t=E(o,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let s=new b(o.graph).callers(o.project.id,t.id);return{found:!0,symbol:S(t),count:s.length,callers:s.map(S)}}import{z as bt}from"zod";var xt={query:bt.string().min(1),limit:bt.number().int().min(1).max(50).optional()};async function Ct(o,e){let t=e.query.toLowerCase(),r=e.limit??20;return o.graph.allSymbols(o.project.id).filter(s=>s.name.toLowerCase().includes(t)||s.qualifiedName?.toLowerCase().includes(t)||s.filePath.toLowerCase().includes(t)).slice(0,r)}import{z as wt}from"zod";var vt={query:wt.string().optional(),memoryLimit:wt.number().int().min(1).max(20).optional()};async function Et(o,e){let t=oe(o.graph,o.project.id),r=o.memory.recent(o.project.id,5),s=e.query?o.retrieval.search(o.project.id,e.query,{topK:e.memoryLimit??5}):[];return{project:{id:o.project.id,name:o.project.name,rootPath:o.project.rootPath},architecture:t,recent:r,relevant:s.map(n=>n.memory)}}import{z as vo}from"zod";var wo=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],j=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",r){let s=new Date().toISOString(),n=s.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,n),c=[];for(let p of wo){let m=`${i}/${p}`,d=await this.storage.get(m);d&&(await this.storage.put(`${a}/${p}`,d,"application/json"),c.push(p))}if(c.length===0)return null;let l={version:1,id:n,projectId:e,createdAt:s,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(l,null,2),"application/json"),l}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),s=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),n=[];for(let i of s){let a=await this.storage.getText(i.key);if(a)try{n.push(JSON.parse(a))}catch{}}return n.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.getText(`${r}/snapshot.json`);if(!s)throw new Error(`Snapshot not found: ${t}`);let n=JSON.parse(s);if(n.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of n.objects){let l=await this.storage.get(`${r}/${c}`);l&&(await this.storage.put(`${i}/${c}`,l,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.list(r);for(let n of s)await this.storage.delete(n.key);return s.length}async prune(e,t=10){let s=(await this.list(e)).slice(t),n=0;for(let i of s)await this.remove(e,i.id),n++;return n}};var Pt={reason:vo.string().optional()};async function jt(o,e){if(!o.storage)throw new Error("Storage unavailable");return new j(o.storage).create(o.project.id,e.reason??"manual-mcp")}async function Rt(o){if(!o.storage)throw new Error("Storage unavailable");return new j(o.storage).list(o.project.id)}import{z as Eo}from"zod";var Tt={snapshotId:Eo.string().min(1)};async function Mt(o,e){if(!o.storage)throw new Error("Storage unavailable");let t=new j(o.storage);return await t.create(o.project.id,"before-rollback"),t.restore(o.project.id,e.snapshotId)}import{z as Te}from"zod";var kt={symbolId:Te.string().min(1),direction:Te.enum(["callers","callees"]).optional(),depth:Te.number().int().min(1).max(10).optional()};async function Lt(o,e){let t=new se(o.graph),r=e.direction??"callees",s=e.depth??3,n=r==="callers"?t.callers(o.project.id,e.symbolId,s):t.callees(o.project.id,e.symbolId,s);return{direction:r,depth:s,results:n.map(i=>({id:i.symbol.id,name:i.symbol.name,qualifiedName:i.symbol.qualifiedName,type:i.symbol.type,filePath:i.symbol.filePath,depth:i.depth}))}}import{z as Nt}from"zod";var At={symbolId:Nt.string().min(1),depth:Nt.number().int().min(1).max(10).optional()};async function It(o,e){let t=o.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let s=new ie(o.graph).analyze(o.project.id,t.id,e.depth??4);return{found:!0,target:{id:t.id,name:t.name,qualifiedName:t.qualifiedName,filePath:t.filePath,type:t.type},impacts:s.map(n=>({id:n.symbol.id,name:n.symbol.name,qualifiedName:n.symbol.qualifiedName,filePath:n.symbol.filePath,type:n.symbol.type,relation:n.relation,depth:n.depth}))}}async function Ot(o){return{project:{id:o.project.id,name:o.project.name,rootPath:o.project.rootPath},architecture:oe(o.graph,o.project.id)}}import{z as _t}from"zod";var Ft={filePath:_t.string().min(1),direction:_t.enum(["dependencies","dependents","both"]).optional()};async function $t(o,e){let r=new D(o.graph).analyze(o.project.id).find(c=>c.filePath===e.filePath);if(!r)return{found:!1,filePath:e.filePath,dependencies:[],dependents:[]};let s=o.graph.allSymbols(o.project.id).filter(c=>c.type==="file"),n=new Map(s.map(c=>[c.filePath,c])),i=c=>({id:n.get(c)?.id??c,filePath:c}),a=e.direction??"both";return{found:!0,filePath:r.filePath,outgoingEdges:r.outgoingEdges,incomingEdges:r.incomingEdges,dependencies:a==="dependents"?[]:r.dependencies.map(i),dependents:a==="dependencies"?[]:r.dependents.map(i)}}import{z as Dt}from"zod";var Gt={query:Dt.string().min(1),limit:Dt.number().int().min(1).max(20).optional()};async function zt(o,e){return o.codeSemantic?{available:!0,results:(await o.codeSemantic.search(e.query,e.limit??8)).map(r=>({id:r.chunk.id,filePath:r.chunk.filePath,symbol:r.chunk.symbolName,symbolType:r.chunk.symbolType,startLine:r.chunk.startLine,endLine:r.chunk.endLine,score:r.score,vectorScore:r.vectorScore,lexicalScore:r.lexicalScore,content:r.chunk.content}))}:{available:!1,results:[]}}import{z as Me}from"zod";var Bt={mode:Me.enum(["git_diff","file"]).optional(),filePath:Me.string().optional(),depth:Me.number().int().min(1).max(10).optional()};async function qt(o,e){let t=new le(o.graph);if((e.mode??(e.filePath?"file":"git_diff"))==="file"){if(!e.filePath)throw new Error("filePath is required when mode=file");return t.analyzeFile(o.project.id,e.filePath,{maxDepth:e.depth})}return t.analyzeGitDiff(o.project.id,o.project.rootPath,{maxDepth:e.depth})}import{z as Po}from"zod";var Kt={symbol:Po.string().min(1)};async function Ht(o,e){let t=E(o,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let s=new b(o.graph).dependents(o.project.id,t.id);return{found:!0,symbol:S(t),count:s.length,dependents:s.map(S)}}import{z as ke}from"zod";var Wt={from:ke.string().min(1),to:ke.string().min(1),maxDepth:ke.number().int().min(1).max(30).optional()};async function Vt(o,e){let t=E(o,e.from),r=E(o,e.to);if(!t||!r)return{found:!1,fromFound:!!t,toFound:!!r,path:[],edges:[]};let n=new b(o.graph).shortestPath(o.project.id,t.id,r.id,e.maxDepth??12);return{found:n.found,distance:n.distance,from:S(t),to:S(r),path:n.symbols.map(S),edges:n.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as Le}from"zod";var Ut={symbol:Le.string().min(1),depth:Le.number().int().min(1).max(5).optional(),limit:Le.number().int().min(1).max(200).optional()};async function Jt(o,e){let t=E(o,e.symbol);if(!t)return{found:!1,query:e.symbol};let s=new b(o.graph).neighborhood(o.project.id,t.id,e.depth??1);if(!s)return{found:!1,query:e.symbol};let n=e.limit??50;return{found:!0,center:S(s.center),incomingCount:s.incoming.length,outgoingCount:s.outgoing.length,incoming:s.incoming.slice(0,n).map(i=>({depth:i.depth,via:i.via?.type,symbol:S(i.symbol)})),outgoing:s.outgoing.slice(0,n).map(i=>({depth:i.depth,via:i.via?.type,symbol:S(i.symbol)}))}}import{z as Ne}from"zod";var Qt={confidence:Ne.enum(["high","medium","low","all"]).optional(),filePath:Ne.string().min(1).optional(),limit:Ne.number().int().min(1).max(500).optional()},Yt={high:3,medium:2,low:1};async function Zt(o,e){let r=new $(o.graph).analyze(o.project.id);if(e.confidence&&e.confidence!=="all"){let i=Yt[e.confidence];r=r.filter(a=>Yt[a.confidence]>=i)}e.filePath&&(r=r.filter(i=>i.filePath===e.filePath));let s=r.length,n=e.limit??100;return{total:s,high:r.filter(i=>i.confidence==="high").length,medium:r.filter(i=>i.confidence==="medium").length,low:r.filter(i=>i.confidence==="low").length,warning:"Dead-code results are candidates only. Verify before deleting code.",candidates:r.slice(0,n)}}function u(o){return{content:[{type:"text",text:JSON.stringify(o,null,2)}]}}function To(o){let e=new jo({name:"toolnet-memory",version:"0.1.0"});return e.tool("memory_search","Search relevant long-term memory for the current project.",lt,async t=>u(await pt(o,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",dt,async t=>u(await mt(o,t))),e.tool("memory_forget","Delete a memory by id.",ft,async t=>u(await ut(o,t))),e.tool("find_symbol","Find code symbols by exact name.",gt,async t=>u(await ht(o,t))),e.tool("find_callers","Find functions or methods calling a symbol.",yt,async t=>u(await St(o,t))),e.tool("code_search","Search indexed code symbols and files.",xt,async t=>u(await Ct(o,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",vt,async t=>u(await Et(o,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",kt,async t=>u(await Lt(o,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",At,async t=>u(await It(o,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>u(await Ot(o))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Ft,async t=>u(await $t(o,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",Gt,async t=>u(await zt(o,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",Pt,async t=>u(await jt(o,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>u(await Rt(o))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",Tt,async t=>u(await Mt(o,t))),e.tool("impact_guard","Analyze blast radius before or after code changes. Maps changed files/lines to symbols, follows reverse dependencies, assigns risk and suggests verification targets.",Bt,async t=>u(await qt(o,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",Kt,async t=>u(await Ht(o,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",Wt,async t=>u(await Vt(o,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",Ut,async t=>u(await Jt(o,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",Qt,async t=>u(await Zt(o,t))),e}async function Xt(o){let e=To(o),t=new Ro;await e.connect(t)}import{closeSync as Mo,mkdirSync as ko,openSync as Lo,readFileSync as No,unlinkSync as er,writeFileSync as Ao}from"node:fs";import{tmpdir as Io}from"node:os";import{join as tr}from"node:path";function Oo(o){try{return process.kill(o,0),!0}catch(e){return e?.code==="EPERM"}}var be=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=tr(Io(),"toolnet-memory-locks");ko(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=tr(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Lo(this.path,"wx");Ao(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Mo(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let r=!0;try{let s=JSON.parse(No(this.path,"utf8"));Number.isInteger(s.pid)&&Oo(s.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{er(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{er(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};async function _o(){let o=Ie(),e=new H().detect(),t=ot({provider:o.storage.provider,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),r=nt(t,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),s=new Se(r,e.id,e.name,e.remote??e.name),n=new be(e.id);await n.acquire();let i=()=>{n.release().finally(()=>process.exit(0))};process.once("SIGINT",i),process.once("SIGTERM",i);let a=new J,c=new ye(s);a.importRecords(await c.load(e.id));let l=new ee(a),p=new N,m=await new _(s).load(e.id);m&&p.import(m.symbols,m.edges);let d=new ne(p),f=new ue({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:s,embeddings:Ve(),graph:p});await f.initialize(),await Xt({project:e,memory:a,retrieval:l,graph:p,references:d,codeSemantic:f,memoryStore:c,storage:s})}_o().catch(o=>{console.error(o),process.exit(1)});