toolnet-memory 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/README.md +443 -70
  2. package/bin/toolnet-memory +66 -53
  3. package/bundle/agy.js +88 -0
  4. package/bundle/codex.js +92 -0
  5. package/bundle/context-runtime.js +56 -0
  6. package/bundle/context.js +62 -0
  7. package/bundle/doctor.js +3 -0
  8. package/bundle/full-index.js +8 -0
  9. package/bundle/learner.js +8 -0
  10. package/bundle/mcp.js +7 -0
  11. package/bundle/opencode.js +314 -0
  12. package/bundle/project-manual.js +54 -0
  13. package/bundle/setup.js +31 -0
  14. package/bundle/snapshot.js +4 -0
  15. package/bundle/work-continuity.js +12 -0
  16. package/package.json +11 -5
  17. package/dist/packages/cli/commands.js +0 -1
  18. package/dist/packages/cli/index.js +0 -1
  19. package/dist/packages/sdk/client.js +0 -78
  20. package/dist/packages/sdk/index.js +0 -1
  21. package/dist/packages/sdk/types.js +0 -1
  22. package/dist/src/api/index.js +0 -1
  23. package/dist/src/api/routes/health.js +0 -1
  24. package/dist/src/api/routes/index.js +0 -1
  25. package/dist/src/api/routes/memory.js +0 -1
  26. package/dist/src/api/routes/projects.js +0 -1
  27. package/dist/src/api/routes/search.js +0 -1
  28. package/dist/src/api/server.js +0 -1
  29. package/dist/src/capture/activity-capture.js +0 -21
  30. package/dist/src/capture/command-capture.js +0 -12
  31. package/dist/src/capture/error-capture.js +0 -14
  32. package/dist/src/capture/event-deduplicator.js +0 -28
  33. package/dist/src/capture/event-queue.js +0 -20
  34. package/dist/src/capture/file-capture.js +0 -23
  35. package/dist/src/capture/index.js +0 -8
  36. package/dist/src/capture/session-capture.js +0 -18
  37. package/dist/src/capture/tool-capture.js +0 -13
  38. package/dist/src/code-intelligence/analysis/analysis-engine.js +0 -26
  39. package/dist/src/code-intelligence/analysis/dead-code-analyzer.js +0 -127
  40. package/dist/src/code-intelligence/analysis/dependency-analyzer.js +0 -66
  41. package/dist/src/code-intelligence/analysis/index.js +0 -4
  42. package/dist/src/code-intelligence/analysis/types.js +0 -1
  43. package/dist/src/code-intelligence/architecture/architecture-engine.js +0 -48
  44. package/dist/src/code-intelligence/architecture/clusters.js +0 -322
  45. package/dist/src/code-intelligence/architecture/entry-points.js +0 -150
  46. package/dist/src/code-intelligence/architecture/hotspots.js +0 -136
  47. package/dist/src/code-intelligence/architecture/index.js +0 -6
  48. package/dist/src/code-intelligence/architecture/layers.js +0 -197
  49. package/dist/src/code-intelligence/architecture/types.js +0 -1
  50. package/dist/src/code-intelligence/chunks/index.js +0 -2
  51. package/dist/src/code-intelligence/chunks/smart-chunker.js +0 -125
  52. package/dist/src/code-intelligence/chunks/types.js +0 -1
  53. package/dist/src/code-intelligence/git/git-diff.js +0 -109
  54. package/dist/src/code-intelligence/git/index.js +0 -1
  55. package/dist/src/code-intelligence/graph/architecture.js +0 -26
  56. package/dist/src/code-intelligence/graph/graph-builder.js +0 -213
  57. package/dist/src/code-intelligence/graph/graph-store.js +0 -57
  58. package/dist/src/code-intelligence/graph/index.js +0 -1
  59. package/dist/src/code-intelligence/graph/relationships.js +0 -1
  60. package/dist/src/code-intelligence/graph/trace.js +0 -65
  61. package/dist/src/code-intelligence/impact/blast-radius.js +0 -160
  62. package/dist/src/code-intelligence/impact/change-mapper.js +0 -69
  63. package/dist/src/code-intelligence/impact/edit-tool-detector.js +0 -92
  64. package/dist/src/code-intelligence/impact/impact-analyzer.js +0 -60
  65. package/dist/src/code-intelligence/impact/impact-guard.js +0 -33
  66. package/dist/src/code-intelligence/impact/index.js +0 -5
  67. package/dist/src/code-intelligence/incremental/file-hash.js +0 -8
  68. package/dist/src/code-intelligence/incremental/incremental-indexer.js +0 -106
  69. package/dist/src/code-intelligence/incremental/manifest-builder.js +0 -19
  70. package/dist/src/code-intelligence/incremental/manifest.js +0 -31
  71. package/dist/src/code-intelligence/index.js +0 -23
  72. package/dist/src/code-intelligence/indexer/file-watcher.js +0 -1
  73. package/dist/src/code-intelligence/indexer/incremental-indexer.js +0 -1
  74. package/dist/src/code-intelligence/indexer/index.js +0 -1
  75. package/dist/src/code-intelligence/indexer/repository-indexer.js +0 -31
  76. package/dist/src/code-intelligence/indexer/repository-scanner.js +0 -50
  77. package/dist/src/code-intelligence/parsers/index.js +0 -1
  78. package/dist/src/code-intelligence/parsers/tree-sitter/index.js +0 -1
  79. package/dist/src/code-intelligence/parsers/tree-sitter/languages.js +0 -1
  80. package/dist/src/code-intelligence/parsers/tree-sitter/parser.js +0 -1
  81. package/dist/src/code-intelligence/parsers/typescript-parser.js +0 -190
  82. package/dist/src/code-intelligence/query/graph-query-engine.js +0 -275
  83. package/dist/src/code-intelligence/query/index.js +0 -2
  84. package/dist/src/code-intelligence/query/types.js +0 -1
  85. package/dist/src/code-intelligence/resolution/index.js +0 -2
  86. package/dist/src/code-intelligence/resolution/types.js +0 -1
  87. package/dist/src/code-intelligence/resolution/typescript-resolver.js +0 -316
  88. package/dist/src/code-intelligence/rich/index.js +0 -1
  89. package/dist/src/code-intelligence/rich/rich-graph-enricher.js +0 -463
  90. package/dist/src/code-intelligence/semantic/index.js +0 -2
  91. package/dist/src/code-intelligence/semantic/semantic-code-engine.js +0 -213
  92. package/dist/src/code-intelligence/semantic/source-priority.js +0 -22
  93. package/dist/src/code-intelligence/symbols/index.js +0 -1
  94. package/dist/src/code-intelligence/symbols/reference-resolver.js +0 -21
  95. package/dist/src/code-intelligence/symbols/symbol-extractor.js +0 -1
  96. package/dist/src/code-intelligence/test-analysis.js +0 -72
  97. package/dist/src/code-intelligence/test-architecture.js +0 -67
  98. package/dist/src/code-intelligence/test-impact.js +0 -47
  99. package/dist/src/code-intelligence/test-incremental.js +0 -24
  100. package/dist/src/code-intelligence/test-index.js +0 -39
  101. package/dist/src/code-intelligence/test-resolution.js +0 -54
  102. package/dist/src/code-intelligence/test-rich-graph.js +0 -48
  103. package/dist/src/code-intelligence/test-semantic.js +0 -57
  104. package/dist/src/code-intelligence/test-visualization.js +0 -36
  105. package/dist/src/code-intelligence/types.js +0 -1
  106. package/dist/src/code-intelligence/visualization/index.js +0 -2
  107. package/dist/src/code-intelligence/visualization/types.js +0 -1
  108. package/dist/src/code-intelligence/visualization/visualization-builder.js +0 -104
  109. package/dist/src/core/config.js +0 -66
  110. package/dist/src/core/global-env.js +0 -70
  111. package/dist/src/core/importance.js +0 -30
  112. package/dist/src/core/index.js +0 -5
  113. package/dist/src/core/memory-engine.js +0 -183
  114. package/dist/src/core/project-manager.js +0 -243
  115. package/dist/src/core/types.js +0 -1
  116. package/dist/src/embeddings/batch-embedder.js +0 -1
  117. package/dist/src/embeddings/cache.js +0 -1
  118. package/dist/src/embeddings/embedder.js +0 -51
  119. package/dist/src/embeddings/index.js +0 -4
  120. package/dist/src/embeddings/local.js +0 -37
  121. package/dist/src/embeddings/provider.js +0 -1
  122. package/dist/src/embeddings/remote.js +0 -76
  123. package/dist/src/embeddings/test-connection.js +0 -16
  124. package/dist/src/hooks/after-edit.js +0 -3
  125. package/dist/src/hooks/after-tool.js +0 -3
  126. package/dist/src/hooks/auto-context.js +0 -68
  127. package/dist/src/hooks/auto-impact-guard.js +0 -94
  128. package/dist/src/hooks/auto-retrieval.js +0 -27
  129. package/dist/src/hooks/before-agent.js +0 -18
  130. package/dist/src/hooks/before-compact.js +0 -3
  131. package/dist/src/hooks/before-edit.js +0 -20
  132. package/dist/src/hooks/index.js +0 -11
  133. package/dist/src/hooks/runtime.js +0 -110
  134. package/dist/src/hooks/session-end.js +0 -3
  135. package/dist/src/hooks/session-start.js +0 -3
  136. package/dist/src/index.js +0 -22
  137. package/dist/src/mcp/bootstrap.js +0 -68
  138. package/dist/src/mcp/context.js +0 -1
  139. package/dist/src/mcp/index.js +0 -3
  140. package/dist/src/mcp/server.js +0 -45
  141. package/dist/src/mcp/tools/analyze-impact.js +0 -41
  142. package/dist/src/mcp/tools/dead-code.js +0 -55
  143. package/dist/src/mcp/tools/find-callers.js +0 -24
  144. package/dist/src/mcp/tools/find-dependencies.js +0 -57
  145. package/dist/src/mcp/tools/find-symbol.js +0 -7
  146. package/dist/src/mcp/tools/get-architecture.js +0 -11
  147. package/dist/src/mcp/tools/graph-dependents.js +0 -24
  148. package/dist/src/mcp/tools/graph-neighborhood.js +0 -58
  149. package/dist/src/mcp/tools/graph-path.js +0 -43
  150. package/dist/src/mcp/tools/graph-query-utils.js +0 -32
  151. package/dist/src/mcp/tools/impact-guard.js +0 -34
  152. package/dist/src/mcp/tools/index-repository.js +0 -1
  153. package/dist/src/mcp/tools/index.js +0 -20
  154. package/dist/src/mcp/tools/memory-decisions.js +0 -1
  155. package/dist/src/mcp/tools/memory-forget.js +0 -14
  156. package/dist/src/mcp/tools/memory-recent.js +0 -1
  157. package/dist/src/mcp/tools/memory-remember.js +0 -33
  158. package/dist/src/mcp/tools/memory-rules.js +0 -1
  159. package/dist/src/mcp/tools/memory-search.js +0 -18
  160. package/dist/src/mcp/tools/memory-todos.js +0 -1
  161. package/dist/src/mcp/tools/project-context.js +0 -25
  162. package/dist/src/mcp/tools/search-code.js +0 -21
  163. package/dist/src/mcp/tools/semantic-code-search.js +0 -33
  164. package/dist/src/mcp/tools/snapshot-create.js +0 -13
  165. package/dist/src/mcp/tools/snapshot-list.js +0 -7
  166. package/dist/src/mcp/tools/snapshot-restore.js +0 -13
  167. package/dist/src/mcp/tools/trace-calls.js +0 -37
  168. package/dist/src/memory/activity.js +0 -5
  169. package/dist/src/memory/conflict-detector.js +0 -105
  170. package/dist/src/memory/consolidator.js +0 -104
  171. package/dist/src/memory/decay.js +0 -59
  172. package/dist/src/memory/decisions.js +0 -3
  173. package/dist/src/memory/deduplicate.js +0 -25
  174. package/dist/src/memory/index.js +0 -11
  175. package/dist/src/memory/maintenance.js +0 -16
  176. package/dist/src/memory/remember.js +0 -3
  177. package/dist/src/memory/rules.js +0 -3
  178. package/dist/src/memory/search.js +0 -3
  179. package/dist/src/memory/summaries.js +0 -1
  180. package/dist/src/memory/todos.js +0 -3
  181. package/dist/src/processor/decision-extractor.js +0 -13
  182. package/dist/src/processor/importance-scorer.js +0 -22
  183. package/dist/src/processor/index.js +0 -7
  184. package/dist/src/processor/memory-extractor.js +0 -59
  185. package/dist/src/processor/memory-processor.js +0 -105
  186. package/dist/src/processor/rule-extractor.js +0 -13
  187. package/dist/src/processor/summarizer.js +0 -71
  188. package/dist/src/processor/todo-extractor.js +0 -12
  189. package/dist/src/production/config-check.js +0 -34
  190. package/dist/src/production/doctor.js +0 -58
  191. package/dist/src/production/full-index.js +0 -114
  192. package/dist/src/production/health.js +0 -58
  193. package/dist/src/production/index-pipeline.js +0 -151
  194. package/dist/src/production/index.js +0 -4
  195. package/dist/src/production/project-lock.js +0 -95
  196. package/dist/src/production/project-status.js +0 -16
  197. package/dist/src/production/recovery.js +0 -15
  198. package/dist/src/production/snapshot-cli.js +0 -58
  199. package/dist/src/project-manual/cli.js +0 -77
  200. package/dist/src/project-manual/index.js +0 -2
  201. package/dist/src/project-manual/manager.js +0 -147
  202. package/dist/src/project-manual/types.js +0 -1
  203. package/dist/src/retrieval/bm25/index.js +0 -1
  204. package/dist/src/retrieval/bm25/search.js +0 -1
  205. package/dist/src/retrieval/bm25.js +0 -30
  206. package/dist/src/retrieval/context-budget.js +0 -1
  207. package/dist/src/retrieval/context-builder.js +0 -22
  208. package/dist/src/retrieval/graph/index.js +0 -1
  209. package/dist/src/retrieval/graph/search.js +0 -1
  210. package/dist/src/retrieval/hybrid/hybrid-search.js +0 -1
  211. package/dist/src/retrieval/hybrid/index.js +0 -1
  212. package/dist/src/retrieval/hybrid-search.js +0 -68
  213. package/dist/src/retrieval/importance.js +0 -16
  214. package/dist/src/retrieval/index.js +0 -12
  215. package/dist/src/retrieval/query-analyzer.js +0 -32
  216. package/dist/src/retrieval/query-classifier.js +0 -1
  217. package/dist/src/retrieval/query-expansion.js +0 -1
  218. package/dist/src/retrieval/recency.js +0 -12
  219. package/dist/src/retrieval/reranker/index.js +0 -1
  220. package/dist/src/retrieval/reranker/reranker.js +0 -1
  221. package/dist/src/retrieval/retrieval-engine.js +0 -17
  222. package/dist/src/retrieval/tokenizer.js +0 -9
  223. package/dist/src/retrieval/type-priority.js +0 -10
  224. package/dist/src/retrieval/types.js +0 -1
  225. package/dist/src/retrieval/vector/index.js +0 -4
  226. package/dist/src/retrieval/vector/metadata-filter.js +0 -1
  227. package/dist/src/retrieval/vector/persistence.js +0 -67
  228. package/dist/src/retrieval/vector/search.js +0 -12
  229. package/dist/src/retrieval/vector/test-persistence.js +0 -36
  230. package/dist/src/retrieval/vector/upsert.js +0 -40
  231. package/dist/src/retrieval/vector/vector-store.js +0 -89
  232. package/dist/src/retrieval/vector-hybrid-engine.js +0 -91
  233. package/dist/src/runtime/bootstrap.js +0 -28
  234. package/dist/src/runtime/graceful.js +0 -17
  235. package/dist/src/runtime/index.js +0 -3
  236. package/dist/src/runtime/toolnet-memory-runtime.js +0 -156
  237. package/dist/src/security/encryption.js +0 -1
  238. package/dist/src/security/file-filter.js +0 -30
  239. package/dist/src/security/index.js +0 -3
  240. package/dist/src/security/sanitizer.js +0 -49
  241. package/dist/src/security/secret-scanner.js +0 -56
  242. package/dist/src/session/agy/adapter.js +0 -159
  243. package/dist/src/session/agy/cli.js +0 -87
  244. package/dist/src/session/agy/hook-installer.js +0 -62
  245. package/dist/src/session/agy/hook.js +0 -167
  246. package/dist/src/session/agy/index.js +0 -5
  247. package/dist/src/session/agy/project-resolver.js +0 -27
  248. package/dist/src/session/agy/recovery.js +0 -112
  249. package/dist/src/session/agy/transcript.js +0 -191
  250. package/dist/src/session/codex/adapter.js +0 -138
  251. package/dist/src/session/codex/cli.js +0 -236
  252. package/dist/src/session/codex/context-hook-installer.js +0 -70
  253. package/dist/src/session/codex/context-hook.js +0 -69
  254. package/dist/src/session/codex/discovery.js +0 -138
  255. package/dist/src/session/codex/index.js +0 -6
  256. package/dist/src/session/codex/notify-installer.js +0 -135
  257. package/dist/src/session/codex/project-resolver.js +0 -25
  258. package/dist/src/session/codex/recovery.js +0 -27
  259. package/dist/src/session/codex/rollout.js +0 -186
  260. package/dist/src/session/core.js +0 -239
  261. package/dist/src/session/identity.js +0 -57
  262. package/dist/src/session/index.js +0 -9
  263. package/dist/src/session/learner/cli.js +0 -62
  264. package/dist/src/session/learner/extractor.js +0 -461
  265. package/dist/src/session/learner/index.js +0 -4
  266. package/dist/src/session/learner/journal.js +0 -159
  267. package/dist/src/session/learner/learner.js +0 -124
  268. package/dist/src/session/learner/types.js +0 -1
  269. package/dist/src/session/opencode/adapter.js +0 -553
  270. package/dist/src/session/opencode/cli.js +0 -121
  271. package/dist/src/session/opencode/index.js +0 -2
  272. package/dist/src/session/opencode/plugin-installer.js +0 -230
  273. package/dist/src/session/store.js +0 -242
  274. package/dist/src/session/types.js +0 -1
  275. package/dist/src/session/utils.js +0 -47
  276. package/dist/src/session/wal.js +0 -303
  277. package/dist/src/snapshot/index.js +0 -2
  278. package/dist/src/snapshot/manager.js +0 -130
  279. package/dist/src/snapshot/test-snapshot.js +0 -28
  280. package/dist/src/snapshot/types.js +0 -1
  281. package/dist/src/storage/architecture-store.js +0 -37
  282. package/dist/src/storage/cleanup-health.js +0 -20
  283. package/dist/src/storage/code-analysis-store.js +0 -35
  284. package/dist/src/storage/code-chunk-store.js +0 -25
  285. package/dist/src/storage/code-graph-store.js +0 -24
  286. package/dist/src/storage/code-manifest-store.js +0 -24
  287. package/dist/src/storage/code-vector-store.js +0 -25
  288. package/dist/src/storage/github/client.js +0 -1
  289. package/dist/src/storage/github/index.js +0 -1
  290. package/dist/src/storage/google-drive/client.js +0 -1
  291. package/dist/src/storage/google-drive/index.js +0 -1
  292. package/dist/src/storage/huggingface/client.js +0 -116
  293. package/dist/src/storage/huggingface/index.js +0 -1
  294. package/dist/src/storage/index.js +0 -16
  295. package/dist/src/storage/list-bucket-raw.js +0 -14
  296. package/dist/src/storage/list-bucket-tree.js +0 -38
  297. package/dist/src/storage/local/client.js +0 -99
  298. package/dist/src/storage/local/index.js +0 -1
  299. package/dist/src/storage/memory-store.js +0 -30
  300. package/dist/src/storage/project/cleanup-layout-v1.js +0 -72
  301. package/dist/src/storage/project/folder.js +0 -15
  302. package/dist/src/storage/project/index.js +0 -3
  303. package/dist/src/storage/project/layout.js +0 -74
  304. package/dist/src/storage/project/migrate-layout-v2.js +0 -101
  305. package/dist/src/storage/project/migrate.js +0 -73
  306. package/dist/src/storage/project/scoped-provider.js +0 -165
  307. package/dist/src/storage/provider.js +0 -26
  308. package/dist/src/storage/retrying-provider.js +0 -23
  309. package/dist/src/storage/test-connection.js +0 -32
  310. package/dist/src/storage/type-resolution-store.js +0 -26
  311. package/dist/src/storage/types.js +0 -1
  312. package/dist/src/storage/vector-store.js +0 -30
  313. package/dist/src/storage/visualization-store.js +0 -25
  314. package/dist/src/sync/compressor.js +0 -1
  315. package/dist/src/sync/conflict-resolver.js +0 -1
  316. package/dist/src/sync/downloader.js +0 -1
  317. package/dist/src/sync/index.js +0 -1
  318. package/dist/src/sync/sync-engine.js +0 -1
  319. package/dist/src/sync/upload-queue.js +0 -1
  320. package/dist/src/utils/retry.js +0 -29
  321. package/dist/src/visualization/server.js +0 -270
  322. package/dist/src/work-continuity/brief-cache.js +0 -107
  323. package/dist/src/work-continuity/brief.js +0 -349
  324. package/dist/src/work-continuity/cli.js +0 -96
  325. package/dist/src/work-continuity/context-cli.js +0 -106
  326. package/dist/src/work-continuity/context-runtime-cli.js +0 -88
  327. package/dist/src/work-continuity/extractor.js +0 -339
  328. package/dist/src/work-continuity/handoff.js +0 -185
  329. package/dist/src/work-continuity/index.js +0 -14
  330. package/dist/src/work-continuity/injection.js +0 -84
  331. package/dist/src/work-continuity/journal.js +0 -49
  332. package/dist/src/work-continuity/learner.js +0 -127
  333. package/dist/src/work-continuity/reducer.js +0 -316
  334. package/dist/src/work-continuity/semantic-extractor.js +0 -360
  335. package/dist/src/work-continuity/semantic-journal.js +0 -55
  336. package/dist/src/work-continuity/semantic-learner.js +0 -125
  337. package/dist/src/work-continuity/semantic-reducer.js +0 -268
  338. package/dist/src/work-continuity/semantic-types.js +0 -1
  339. package/dist/src/work-continuity/types.js +0 -1
  340. package/dist/visualization/public/index.html +0 -2896
  341. package/dist/visualization/public/vendor/3d-force-graph.min.js +0 -5
@@ -1,121 +0,0 @@
1
- import { loadConfig, ProjectManager, } from "../../core/index.js";
2
- import { createStorageProvider, ProjectScopedStorageProvider, withStorageRetry, } from "../../storage/index.js";
3
- import { recoverOpenCodeProject, syncOpenCodeSession, } from "./adapter.js";
4
- import { installOpenCodePlugin, } from "./plugin-installer.js";
5
- import { refreshStartupBriefCache, } from "../../work-continuity/brief-cache.js";
6
- function valueAfter(args, flag) {
7
- const index = args.indexOf(flag);
8
- if (index < 0) {
9
- return undefined;
10
- }
11
- return args[index + 1];
12
- }
13
- function has(args, flag) {
14
- return args.includes(flag);
15
- }
16
- function storageFor(project) {
17
- const config = loadConfig();
18
- const raw = withStorageRetry(createStorageProvider({
19
- provider: config.storage.provider,
20
- huggingface: config.storage
21
- .huggingface,
22
- localRoot: config.storage
23
- .localRoot,
24
- }), {
25
- attempts: 3,
26
- });
27
- return new ProjectScopedStorageProvider(raw, project.id, project.name, project.remote ??
28
- project.name);
29
- }
30
- async function main() {
31
- const [command = "help", ...args] = process.argv.slice(2);
32
- if (command ===
33
- "install-plugin") {
34
- const target = installOpenCodePlugin({
35
- binary: valueAfter(args, "--bin"),
36
- });
37
- console.log(`✅ OpenCode plugin installed: ${target}`);
38
- console.log("OpenCode will load it automatically on next start.");
39
- return;
40
- }
41
- const projectPath = valueAfter(args, "--project") ??
42
- process.cwd();
43
- const project = new ProjectManager()
44
- .detect(projectPath);
45
- const storage = storageFor(project);
46
- const dbPath = valueAfter(args, "--db");
47
- if (command ===
48
- "sync") {
49
- const nativeSessionId = args.find(value => !value.startsWith("--") &&
50
- value !==
51
- projectPath &&
52
- value !==
53
- dbPath);
54
- if (!nativeSessionId) {
55
- throw new Error("Usage: session:opencode-sync <session-id>");
56
- }
57
- const idle = has(args, "--idle");
58
- const error = has(args, "--error");
59
- const compacted = has(args, "--compacted");
60
- const result = await syncOpenCodeSession({
61
- project,
62
- storage,
63
- nativeSessionId,
64
- dbPath,
65
- idle,
66
- error,
67
- compacted,
68
- });
69
- if (idle ||
70
- compacted ||
71
- error) {
72
- try {
73
- await refreshStartupBriefCache(project, storage, 900);
74
- }
75
- catch {
76
- // Derived cache must never break session capture.
77
- }
78
- }
79
- console.log(JSON.stringify(result, null, 2));
80
- return;
81
- }
82
- if (command ===
83
- "recover") {
84
- const limitValue = valueAfter(args, "--limit");
85
- const limit = limitValue
86
- ? Number(limitValue)
87
- : 100;
88
- const results = await recoverOpenCodeProject({
89
- project,
90
- storage,
91
- dbPath,
92
- limit: Number.isFinite(limit)
93
- ? limit
94
- : 100,
95
- });
96
- console.log(JSON.stringify({
97
- project: project.name,
98
- sessions: results.length,
99
- importedMessages: results.reduce((total, item) => total +
100
- item
101
- .importedMessages, 0),
102
- importedParts: results.reduce((total, item) => total +
103
- item
104
- .importedParts, 0),
105
- }, null, 2));
106
- return;
107
- }
108
- console.log(`OpenCode Session Adapter
109
-
110
- Commands:
111
- sync <session-id> [--project PATH] [--idle]
112
- recover [--project PATH] [--limit N]
113
- install-plugin [--bin PATH]
114
- `);
115
- }
116
- main().catch(error => {
117
- console.error(error instanceof Error
118
- ? error.message
119
- : error);
120
- process.exit(1);
121
- });
@@ -1,2 +0,0 @@
1
- export * from "./adapter.js";
2
- export * from "./plugin-installer.js";
@@ -1,230 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
2
- import { homedir, } from "node:os";
3
- import { join, } from "node:path";
4
- const START = "<!-- TOOLNET_MEMORY_BOOTSTRAP_START -->";
5
- const END = "<!-- TOOLNET_MEMORY_BOOTSTRAP_END -->";
6
- function installBootstrapInstructions() {
7
- const file = join(homedir(), ".config", "opencode", "AGENTS.md");
8
- mkdirSync(join(homedir(), ".config", "opencode"), {
9
- recursive: true,
10
- });
11
- const block = `${START}
12
- ## ToolNet Memory — Project Continuity
13
-
14
- When the current workspace belongs to a ToolNet project, identified by a nearest ancestor containing \`.toolnet/project.json\`:
15
-
16
- 1. Before planning, editing, or running implementation commands, read that project root's \`.toolnet/context/startup.md\`.
17
- 2. Treat its PROJECT RULES, MISSION, CURRENT OBJECTIVE, rationale, current phase/task, Definition of Done, blockers and next actions as project continuity context.
18
- 3. Do not restart work already marked completed unless repository evidence proves it must be revisited.
19
- 4. Verify current repository state before continuing old work.
20
- 5. If \`.toolnet/context/startup.md\` is missing, run \`toolnet-memory context:sync --project <project-root>\`, then read it.
21
- 6. Never invent missing rationale. If ToolNet says a reason was not explicitly recorded, inspect the implementation or ask rather than guessing.
22
-
23
- This applies automatically to every ToolNet-managed project.
24
- ${END}`;
25
- let content = existsSync(file)
26
- ? readFileSync(file, "utf8")
27
- : "";
28
- const start = content.indexOf(START);
29
- const end = content.indexOf(END);
30
- if (start >= 0 &&
31
- end >= start) {
32
- content =
33
- content.slice(0, start) +
34
- block +
35
- content.slice(end +
36
- END.length);
37
- }
38
- else {
39
- content =
40
- content.trimEnd();
41
- if (content) {
42
- content +=
43
- "\n\n";
44
- }
45
- content +=
46
- block;
47
- }
48
- writeFileSync(file, content.trimEnd() +
49
- "\n", {
50
- encoding: "utf8",
51
- mode: 0o600,
52
- });
53
- return file;
54
- }
55
- export function installOpenCodePlugin(options = {}) {
56
- const directory = options.directory ??
57
- join(homedir(), ".config", "opencode", "plugins");
58
- mkdirSync(directory, {
59
- recursive: true,
60
- });
61
- installBootstrapInstructions();
62
- const target = join(directory, "toolnet-memory.js");
63
- const binary = options.binary ??
64
- process.env
65
- .TOOLNET_MEMORY_BIN ??
66
- "toolnet-memory";
67
- const content = `// Generated by ToolNet Memory.
68
- // OpenCode session capture + continuity bootstrap.
69
-
70
- function getSessionId(event) {
71
- const p = event?.properties ?? {}
72
-
73
- const candidates = [
74
- p.sessionID,
75
- p.sessionId,
76
- p.info?.id,
77
- p.session?.id,
78
- ]
79
-
80
- return candidates.find(
81
- value => typeof value === "string" && value.length > 0
82
- ) ?? null
83
- }
84
-
85
- export const ToolNetMemoryPlugin = async ({ directory }) => {
86
- const binary = ${JSON.stringify(binary)}
87
-
88
- async function refreshContext() {
89
- try {
90
- const child = Bun.spawn(
91
- [
92
- binary,
93
- "context:sync",
94
- "--project",
95
- directory,
96
- ],
97
- {
98
- stdin: "ignore",
99
- stdout: "ignore",
100
- stderr: "ignore",
101
- }
102
- )
103
-
104
- await child.exited
105
- } catch {
106
- // Context sync must never break OpenCode startup.
107
- }
108
- }
109
-
110
- async function readContext() {
111
- try {
112
- const child = Bun.spawn(
113
- [
114
- binary,
115
- "context:print",
116
- "--project",
117
- directory,
118
- "--tokens",
119
- "900",
120
- ],
121
- {
122
- stdin: "ignore",
123
- stdout: "pipe",
124
- stderr: "ignore",
125
- }
126
- )
127
-
128
- const text =
129
- await new Response(
130
- child.stdout
131
- ).text()
132
-
133
- await child.exited
134
-
135
- return text.trim()
136
- } catch {
137
- return ""
138
- }
139
- }
140
-
141
- function sync(sessionId, flag) {
142
- if (!sessionId) return
143
-
144
- try {
145
- const args = [
146
- binary,
147
- "session:opencode-sync",
148
- sessionId,
149
- "--project",
150
- directory,
151
- ]
152
-
153
- if (flag) {
154
- args.push(flag)
155
- }
156
-
157
- const child = Bun.spawn(args, {
158
- stdin: "ignore",
159
- stdout: "ignore",
160
- stderr: "ignore",
161
- })
162
-
163
- if (
164
- typeof child.unref === "function"
165
- ) {
166
- child.unref()
167
- }
168
- } catch {
169
- // Memory capture must never break OpenCode.
170
- }
171
- }
172
-
173
- /*
174
- * Pull the latest project brief from ToolNet remote storage
175
- * before the new OpenCode session starts doing work.
176
- */
177
- await refreshContext()
178
-
179
- return {
180
- event: async ({ event }) => {
181
- const sessionId =
182
- getSessionId(event)
183
-
184
- if (!sessionId) {
185
- return
186
- }
187
-
188
- if (event.type === "session.idle") {
189
- sync(sessionId, "--idle")
190
- return
191
- }
192
-
193
- if (event.type === "session.compacted") {
194
- sync(sessionId, "--compacted")
195
- return
196
- }
197
-
198
- if (event.type === "session.error") {
199
- sync(sessionId, "--error")
200
- }
201
- },
202
-
203
- /*
204
- * Official OpenCode compaction hook.
205
- * Preserve ToolNet's semantic state after context compaction.
206
- */
207
- "experimental.session.compacting": async (_input, output) => {
208
- const context =
209
- await readContext()
210
-
211
- if (
212
- context &&
213
- Array.isArray(
214
- output.context
215
- )
216
- ) {
217
- output.context.push(
218
- context
219
- )
220
- }
221
- },
222
- }
223
- }
224
- `;
225
- writeFileSync(target, content, {
226
- encoding: "utf8",
227
- mode: 0o600,
228
- });
229
- return target;
230
- }
@@ -1,242 +0,0 @@
1
- import { sha256, } from "./utils.js";
2
- function padSequence(value) {
3
- return String(value).padStart(12, "0");
4
- }
5
- export class RemoteSessionStore {
6
- storage;
7
- maxEventsPerChunk;
8
- maxChunkBytes;
9
- constructor(storage, maxEventsPerChunk = 100, maxChunkBytes = 512 * 1024) {
10
- this.storage = storage;
11
- this.maxEventsPerChunk = maxEventsPerChunk;
12
- this.maxChunkBytes = maxChunkBytes;
13
- if (maxEventsPerChunk <
14
- 1) {
15
- throw new Error("maxEventsPerChunk must be positive");
16
- }
17
- if (maxChunkBytes <
18
- 1_024) {
19
- throw new Error("maxChunkBytes is too small");
20
- }
21
- }
22
- async getJson(key) {
23
- const text = await this.storage
24
- .getText(key);
25
- if (!text) {
26
- return null;
27
- }
28
- return JSON.parse(text);
29
- }
30
- async putJson(key, value) {
31
- await this.storage.put(key, JSON.stringify(value, null, 2) + "\n", "application/json");
32
- }
33
- async scan(identity) {
34
- const prefix = `${identity.remotePrefix}/events/`;
35
- const objects = await this.storage.list(prefix);
36
- const chunks = [];
37
- let maxSequence = 0;
38
- for (const object of objects) {
39
- const match = object.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);
40
- if (!match) {
41
- continue;
42
- }
43
- const start = Number(match[1]);
44
- const end = Number(match[2]);
45
- if (!Number.isFinite(start) ||
46
- !Number.isFinite(end)) {
47
- continue;
48
- }
49
- chunks.push({
50
- key: object.key,
51
- start,
52
- end,
53
- });
54
- maxSequence =
55
- Math.max(maxSequence, end);
56
- }
57
- chunks.sort((left, right) => left.start -
58
- right.start);
59
- return {
60
- chunks,
61
- maxSequence,
62
- };
63
- }
64
- split(events) {
65
- const result = [];
66
- let current = [];
67
- let bytes = 0;
68
- for (const event of events) {
69
- const lineBytes = Buffer.byteLength(JSON.stringify(event) + "\n", "utf8");
70
- if (current.length >
71
- 0 &&
72
- (current.length >=
73
- this
74
- .maxEventsPerChunk ||
75
- bytes +
76
- lineBytes >
77
- this
78
- .maxChunkBytes)) {
79
- result.push(current);
80
- current =
81
- [];
82
- bytes =
83
- 0;
84
- }
85
- current.push(event);
86
- bytes +=
87
- lineBytes;
88
- }
89
- if (current.length >
90
- 0) {
91
- result.push(current);
92
- }
93
- return result;
94
- }
95
- async loadManifest(identity) {
96
- return this.getJson(`${identity.remotePrefix}/session.json`);
97
- }
98
- async loadCursor(identity) {
99
- return this.getJson(`${identity.remotePrefix}/cursor.json`);
100
- }
101
- async recover(identity) {
102
- const scan = await this.scan(identity);
103
- return {
104
- maxSequence: scan.maxSequence,
105
- chunkCount: scan.chunks.length,
106
- };
107
- }
108
- async append(identity, events, sourceCursors, options = {}) {
109
- const previousManifest = await this.loadManifest(identity);
110
- const before = await this.scan(identity);
111
- /*
112
- * Crash recovery:
113
- * chunks may already exist even when cursor/session.json
114
- * was not successfully updated.
115
- */
116
- const pending = events.filter(event => event.sequence >
117
- before.maxSequence);
118
- let uploadedEvents = 0;
119
- for (const chunk of this.split(pending)) {
120
- const first = chunk[0];
121
- const last = chunk[chunk.length -
122
- 1];
123
- const content = chunk
124
- .map(event => JSON.stringify(event))
125
- .join("\n") +
126
- "\n";
127
- const digest = sha256(content).slice(0, 16);
128
- const key = [
129
- identity
130
- .remotePrefix,
131
- "events",
132
- `${padSequence(first.sequence)}-${padSequence(last.sequence)}-${digest}.jsonl`,
133
- ].join("/");
134
- if (!await this.storage
135
- .exists(key)) {
136
- await this.storage.put(key, content, "application/x-ndjson");
137
- }
138
- uploadedEvents +=
139
- chunk.length;
140
- }
141
- const after = await this.scan(identity);
142
- const lastInput = events[events.length -
143
- 1];
144
- let status = previousManifest
145
- ?.status ??
146
- "active";
147
- if ((lastInput
148
- ?.type ===
149
- "session_end" ||
150
- lastInput
151
- ?.type ===
152
- "session_idle")) {
153
- status =
154
- "idle";
155
- }
156
- else if (lastInput
157
- ?.type ===
158
- "error") {
159
- status =
160
- "error";
161
- }
162
- else if (events.length >
163
- 0) {
164
- status =
165
- "active";
166
- }
167
- const now = new Date()
168
- .toISOString();
169
- const firstInput = events[0];
170
- const manifest = {
171
- version: 1,
172
- projectId: identity.projectId,
173
- projectName: identity
174
- .projectName,
175
- agent: identity.agent,
176
- nativeSessionId: identity
177
- .nativeSessionId,
178
- sessionKey: identity.sessionKey,
179
- status,
180
- createdAt: previousManifest
181
- ?.createdAt ??
182
- firstInput
183
- ?.timestamp ??
184
- now,
185
- updatedAt: lastInput
186
- ?.timestamp ??
187
- now,
188
- firstEventAt: previousManifest
189
- ?.firstEventAt ??
190
- firstInput
191
- ?.timestamp,
192
- lastEventAt: lastInput
193
- ?.timestamp ??
194
- previousManifest
195
- ?.lastEventAt,
196
- eventCount: after.maxSequence,
197
- chunkCount: after.chunks.length,
198
- metadata: {
199
- ...previousManifest
200
- ?.metadata,
201
- ...options.metadata,
202
- },
203
- };
204
- if (options.title ??
205
- previousManifest
206
- ?.title) {
207
- manifest.title =
208
- options.title ??
209
- previousManifest
210
- ?.title;
211
- }
212
- const cursor = {
213
- version: 1,
214
- projectId: identity.projectId,
215
- agent: identity.agent,
216
- nativeSessionId: identity
217
- .nativeSessionId,
218
- lastLocalSequence: events.length >
219
- 0
220
- ? events[events.length -
221
- 1].sequence
222
- : after
223
- .maxSequence,
224
- lastRemoteSequence: after.maxSequence,
225
- sourceCursors,
226
- updatedAt: now,
227
- };
228
- /*
229
- * Chunk first, then cursor, then manifest.
230
- * Immutable chunks are the source of truth.
231
- */
232
- await this.putJson(`${identity.remotePrefix}/cursor.json`, cursor);
233
- await this.putJson(`${identity.remotePrefix}/session.json`, manifest);
234
- return {
235
- uploadedEvents,
236
- lastRemoteSequence: after.maxSequence,
237
- eventCount: manifest.eventCount,
238
- chunkCount: manifest.chunkCount,
239
- status,
240
- };
241
- }
242
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,47 +0,0 @@
1
- import { createHash, } from "node:crypto";
2
- import { dirname, } from "node:path";
3
- import { mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
4
- export function sha256(value) {
5
- return createHash("sha256")
6
- .update(value)
7
- .digest("hex");
8
- }
9
- function normalize(value) {
10
- if (Array.isArray(value)) {
11
- return value.map(normalize);
12
- }
13
- if (value &&
14
- typeof value ===
15
- "object") {
16
- const source = value;
17
- const result = {};
18
- for (const key of Object.keys(source).sort()) {
19
- result[key] =
20
- normalize(source[key]);
21
- }
22
- return result;
23
- }
24
- return value;
25
- }
26
- export function stableStringify(value) {
27
- return JSON.stringify(normalize(value));
28
- }
29
- export function readJsonFile(filePath) {
30
- try {
31
- return JSON.parse(readFileSync(filePath, "utf8"));
32
- }
33
- catch {
34
- return null;
35
- }
36
- }
37
- export function writeJsonAtomic(filePath, value) {
38
- mkdirSync(dirname(filePath), {
39
- recursive: true,
40
- });
41
- const temporary = `${filePath}.${process.pid}.tmp`;
42
- writeFileSync(temporary, JSON.stringify(value, null, 2) + "\n", {
43
- encoding: "utf8",
44
- mode: 0o600,
45
- });
46
- renameSync(temporary, filePath);
47
- }