toolnet-memory 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/README.md +55 -28
  2. package/bin/toolnet-memory +55 -55
  3. package/bundle/agy.js +88 -0
  4. package/bundle/codex.js +92 -0
  5. package/bundle/context-runtime.js +56 -0
  6. package/bundle/context.js +62 -0
  7. package/bundle/doctor.js +3 -0
  8. package/bundle/full-index.js +8 -0
  9. package/bundle/learner.js +8 -0
  10. package/bundle/mcp.js +7 -0
  11. package/bundle/opencode.js +314 -0
  12. package/bundle/project-manual.js +54 -0
  13. package/bundle/setup.js +31 -0
  14. package/bundle/snapshot.js +4 -0
  15. package/bundle/work-continuity.js +12 -0
  16. package/package.json +9 -6
  17. package/dist/packages/cli/commands.js +0 -1
  18. package/dist/packages/cli/index.js +0 -1
  19. package/dist/packages/sdk/client.js +0 -78
  20. package/dist/packages/sdk/index.js +0 -1
  21. package/dist/packages/sdk/types.js +0 -1
  22. package/dist/src/api/index.js +0 -1
  23. package/dist/src/api/routes/health.js +0 -1
  24. package/dist/src/api/routes/index.js +0 -1
  25. package/dist/src/api/routes/memory.js +0 -1
  26. package/dist/src/api/routes/projects.js +0 -1
  27. package/dist/src/api/routes/search.js +0 -1
  28. package/dist/src/api/server.js +0 -1
  29. package/dist/src/capture/activity-capture.js +0 -21
  30. package/dist/src/capture/command-capture.js +0 -12
  31. package/dist/src/capture/error-capture.js +0 -14
  32. package/dist/src/capture/event-deduplicator.js +0 -28
  33. package/dist/src/capture/event-queue.js +0 -20
  34. package/dist/src/capture/file-capture.js +0 -23
  35. package/dist/src/capture/index.js +0 -8
  36. package/dist/src/capture/session-capture.js +0 -18
  37. package/dist/src/capture/tool-capture.js +0 -13
  38. package/dist/src/code-intelligence/analysis/analysis-engine.js +0 -26
  39. package/dist/src/code-intelligence/analysis/dead-code-analyzer.js +0 -127
  40. package/dist/src/code-intelligence/analysis/dependency-analyzer.js +0 -66
  41. package/dist/src/code-intelligence/analysis/index.js +0 -4
  42. package/dist/src/code-intelligence/analysis/types.js +0 -1
  43. package/dist/src/code-intelligence/architecture/architecture-engine.js +0 -48
  44. package/dist/src/code-intelligence/architecture/clusters.js +0 -322
  45. package/dist/src/code-intelligence/architecture/entry-points.js +0 -150
  46. package/dist/src/code-intelligence/architecture/hotspots.js +0 -136
  47. package/dist/src/code-intelligence/architecture/index.js +0 -6
  48. package/dist/src/code-intelligence/architecture/layers.js +0 -197
  49. package/dist/src/code-intelligence/architecture/types.js +0 -1
  50. package/dist/src/code-intelligence/chunks/index.js +0 -2
  51. package/dist/src/code-intelligence/chunks/smart-chunker.js +0 -125
  52. package/dist/src/code-intelligence/chunks/types.js +0 -1
  53. package/dist/src/code-intelligence/git/git-diff.js +0 -109
  54. package/dist/src/code-intelligence/git/index.js +0 -1
  55. package/dist/src/code-intelligence/graph/architecture.js +0 -26
  56. package/dist/src/code-intelligence/graph/graph-builder.js +0 -213
  57. package/dist/src/code-intelligence/graph/graph-store.js +0 -57
  58. package/dist/src/code-intelligence/graph/index.js +0 -1
  59. package/dist/src/code-intelligence/graph/relationships.js +0 -1
  60. package/dist/src/code-intelligence/graph/trace.js +0 -65
  61. package/dist/src/code-intelligence/impact/blast-radius.js +0 -160
  62. package/dist/src/code-intelligence/impact/change-mapper.js +0 -69
  63. package/dist/src/code-intelligence/impact/edit-tool-detector.js +0 -92
  64. package/dist/src/code-intelligence/impact/impact-analyzer.js +0 -60
  65. package/dist/src/code-intelligence/impact/impact-guard.js +0 -33
  66. package/dist/src/code-intelligence/impact/index.js +0 -5
  67. package/dist/src/code-intelligence/incremental/file-hash.js +0 -8
  68. package/dist/src/code-intelligence/incremental/incremental-indexer.js +0 -106
  69. package/dist/src/code-intelligence/incremental/manifest-builder.js +0 -19
  70. package/dist/src/code-intelligence/incremental/manifest.js +0 -31
  71. package/dist/src/code-intelligence/index.js +0 -23
  72. package/dist/src/code-intelligence/indexer/file-watcher.js +0 -1
  73. package/dist/src/code-intelligence/indexer/incremental-indexer.js +0 -1
  74. package/dist/src/code-intelligence/indexer/index.js +0 -1
  75. package/dist/src/code-intelligence/indexer/repository-indexer.js +0 -31
  76. package/dist/src/code-intelligence/indexer/repository-scanner.js +0 -50
  77. package/dist/src/code-intelligence/parsers/index.js +0 -1
  78. package/dist/src/code-intelligence/parsers/tree-sitter/index.js +0 -1
  79. package/dist/src/code-intelligence/parsers/tree-sitter/languages.js +0 -1
  80. package/dist/src/code-intelligence/parsers/tree-sitter/parser.js +0 -1
  81. package/dist/src/code-intelligence/parsers/typescript-parser.js +0 -190
  82. package/dist/src/code-intelligence/query/graph-query-engine.js +0 -275
  83. package/dist/src/code-intelligence/query/index.js +0 -2
  84. package/dist/src/code-intelligence/query/types.js +0 -1
  85. package/dist/src/code-intelligence/resolution/index.js +0 -2
  86. package/dist/src/code-intelligence/resolution/types.js +0 -1
  87. package/dist/src/code-intelligence/resolution/typescript-resolver.js +0 -316
  88. package/dist/src/code-intelligence/rich/index.js +0 -1
  89. package/dist/src/code-intelligence/rich/rich-graph-enricher.js +0 -463
  90. package/dist/src/code-intelligence/semantic/index.js +0 -2
  91. package/dist/src/code-intelligence/semantic/semantic-code-engine.js +0 -213
  92. package/dist/src/code-intelligence/semantic/source-priority.js +0 -22
  93. package/dist/src/code-intelligence/symbols/index.js +0 -1
  94. package/dist/src/code-intelligence/symbols/reference-resolver.js +0 -21
  95. package/dist/src/code-intelligence/symbols/symbol-extractor.js +0 -1
  96. package/dist/src/code-intelligence/test-analysis.js +0 -72
  97. package/dist/src/code-intelligence/test-architecture.js +0 -67
  98. package/dist/src/code-intelligence/test-impact.js +0 -47
  99. package/dist/src/code-intelligence/test-incremental.js +0 -24
  100. package/dist/src/code-intelligence/test-index.js +0 -39
  101. package/dist/src/code-intelligence/test-resolution.js +0 -54
  102. package/dist/src/code-intelligence/test-rich-graph.js +0 -48
  103. package/dist/src/code-intelligence/test-semantic.js +0 -57
  104. package/dist/src/code-intelligence/test-visualization.js +0 -36
  105. package/dist/src/code-intelligence/types.js +0 -1
  106. package/dist/src/code-intelligence/visualization/index.js +0 -2
  107. package/dist/src/code-intelligence/visualization/types.js +0 -1
  108. package/dist/src/code-intelligence/visualization/visualization-builder.js +0 -104
  109. package/dist/src/core/config.js +0 -66
  110. package/dist/src/core/global-env.js +0 -70
  111. package/dist/src/core/importance.js +0 -30
  112. package/dist/src/core/index.js +0 -5
  113. package/dist/src/core/memory-engine.js +0 -183
  114. package/dist/src/core/project-manager.js +0 -243
  115. package/dist/src/core/types.js +0 -1
  116. package/dist/src/embeddings/batch-embedder.js +0 -1
  117. package/dist/src/embeddings/cache.js +0 -1
  118. package/dist/src/embeddings/embedder.js +0 -51
  119. package/dist/src/embeddings/index.js +0 -4
  120. package/dist/src/embeddings/local.js +0 -37
  121. package/dist/src/embeddings/provider.js +0 -1
  122. package/dist/src/embeddings/remote.js +0 -76
  123. package/dist/src/embeddings/test-connection.js +0 -16
  124. package/dist/src/hooks/after-edit.js +0 -3
  125. package/dist/src/hooks/after-tool.js +0 -3
  126. package/dist/src/hooks/auto-context.js +0 -68
  127. package/dist/src/hooks/auto-impact-guard.js +0 -94
  128. package/dist/src/hooks/auto-retrieval.js +0 -27
  129. package/dist/src/hooks/before-agent.js +0 -18
  130. package/dist/src/hooks/before-compact.js +0 -3
  131. package/dist/src/hooks/before-edit.js +0 -20
  132. package/dist/src/hooks/index.js +0 -11
  133. package/dist/src/hooks/runtime.js +0 -110
  134. package/dist/src/hooks/session-end.js +0 -3
  135. package/dist/src/hooks/session-start.js +0 -3
  136. package/dist/src/index.js +0 -22
  137. package/dist/src/mcp/bootstrap.js +0 -68
  138. package/dist/src/mcp/context.js +0 -1
  139. package/dist/src/mcp/index.js +0 -3
  140. package/dist/src/mcp/server.js +0 -45
  141. package/dist/src/mcp/tools/analyze-impact.js +0 -41
  142. package/dist/src/mcp/tools/dead-code.js +0 -55
  143. package/dist/src/mcp/tools/find-callers.js +0 -24
  144. package/dist/src/mcp/tools/find-dependencies.js +0 -57
  145. package/dist/src/mcp/tools/find-symbol.js +0 -7
  146. package/dist/src/mcp/tools/get-architecture.js +0 -11
  147. package/dist/src/mcp/tools/graph-dependents.js +0 -24
  148. package/dist/src/mcp/tools/graph-neighborhood.js +0 -58
  149. package/dist/src/mcp/tools/graph-path.js +0 -43
  150. package/dist/src/mcp/tools/graph-query-utils.js +0 -32
  151. package/dist/src/mcp/tools/impact-guard.js +0 -34
  152. package/dist/src/mcp/tools/index-repository.js +0 -1
  153. package/dist/src/mcp/tools/index.js +0 -20
  154. package/dist/src/mcp/tools/memory-decisions.js +0 -1
  155. package/dist/src/mcp/tools/memory-forget.js +0 -14
  156. package/dist/src/mcp/tools/memory-recent.js +0 -1
  157. package/dist/src/mcp/tools/memory-remember.js +0 -33
  158. package/dist/src/mcp/tools/memory-rules.js +0 -1
  159. package/dist/src/mcp/tools/memory-search.js +0 -18
  160. package/dist/src/mcp/tools/memory-todos.js +0 -1
  161. package/dist/src/mcp/tools/project-context.js +0 -25
  162. package/dist/src/mcp/tools/search-code.js +0 -21
  163. package/dist/src/mcp/tools/semantic-code-search.js +0 -33
  164. package/dist/src/mcp/tools/snapshot-create.js +0 -13
  165. package/dist/src/mcp/tools/snapshot-list.js +0 -7
  166. package/dist/src/mcp/tools/snapshot-restore.js +0 -13
  167. package/dist/src/mcp/tools/trace-calls.js +0 -37
  168. package/dist/src/memory/activity.js +0 -5
  169. package/dist/src/memory/conflict-detector.js +0 -105
  170. package/dist/src/memory/consolidator.js +0 -104
  171. package/dist/src/memory/decay.js +0 -59
  172. package/dist/src/memory/decisions.js +0 -3
  173. package/dist/src/memory/deduplicate.js +0 -25
  174. package/dist/src/memory/index.js +0 -11
  175. package/dist/src/memory/maintenance.js +0 -16
  176. package/dist/src/memory/remember.js +0 -3
  177. package/dist/src/memory/rules.js +0 -3
  178. package/dist/src/memory/search.js +0 -3
  179. package/dist/src/memory/summaries.js +0 -1
  180. package/dist/src/memory/todos.js +0 -3
  181. package/dist/src/processor/decision-extractor.js +0 -13
  182. package/dist/src/processor/importance-scorer.js +0 -22
  183. package/dist/src/processor/index.js +0 -7
  184. package/dist/src/processor/memory-extractor.js +0 -59
  185. package/dist/src/processor/memory-processor.js +0 -105
  186. package/dist/src/processor/rule-extractor.js +0 -13
  187. package/dist/src/processor/summarizer.js +0 -71
  188. package/dist/src/processor/todo-extractor.js +0 -12
  189. package/dist/src/production/config-check.js +0 -34
  190. package/dist/src/production/doctor.js +0 -58
  191. package/dist/src/production/full-index.js +0 -114
  192. package/dist/src/production/health.js +0 -58
  193. package/dist/src/production/index-pipeline.js +0 -151
  194. package/dist/src/production/index.js +0 -4
  195. package/dist/src/production/project-lock.js +0 -95
  196. package/dist/src/production/project-status.js +0 -16
  197. package/dist/src/production/recovery.js +0 -15
  198. package/dist/src/production/setup.js +0 -219
  199. package/dist/src/production/snapshot-cli.js +0 -58
  200. package/dist/src/project-manual/cli.js +0 -77
  201. package/dist/src/project-manual/index.js +0 -2
  202. package/dist/src/project-manual/manager.js +0 -147
  203. package/dist/src/project-manual/types.js +0 -1
  204. package/dist/src/retrieval/bm25/index.js +0 -1
  205. package/dist/src/retrieval/bm25/search.js +0 -1
  206. package/dist/src/retrieval/bm25.js +0 -30
  207. package/dist/src/retrieval/context-budget.js +0 -1
  208. package/dist/src/retrieval/context-builder.js +0 -22
  209. package/dist/src/retrieval/graph/index.js +0 -1
  210. package/dist/src/retrieval/graph/search.js +0 -1
  211. package/dist/src/retrieval/hybrid/hybrid-search.js +0 -1
  212. package/dist/src/retrieval/hybrid/index.js +0 -1
  213. package/dist/src/retrieval/hybrid-search.js +0 -68
  214. package/dist/src/retrieval/importance.js +0 -16
  215. package/dist/src/retrieval/index.js +0 -12
  216. package/dist/src/retrieval/query-analyzer.js +0 -32
  217. package/dist/src/retrieval/query-classifier.js +0 -1
  218. package/dist/src/retrieval/query-expansion.js +0 -1
  219. package/dist/src/retrieval/recency.js +0 -12
  220. package/dist/src/retrieval/reranker/index.js +0 -1
  221. package/dist/src/retrieval/reranker/reranker.js +0 -1
  222. package/dist/src/retrieval/retrieval-engine.js +0 -17
  223. package/dist/src/retrieval/tokenizer.js +0 -9
  224. package/dist/src/retrieval/type-priority.js +0 -10
  225. package/dist/src/retrieval/types.js +0 -1
  226. package/dist/src/retrieval/vector/index.js +0 -4
  227. package/dist/src/retrieval/vector/metadata-filter.js +0 -1
  228. package/dist/src/retrieval/vector/persistence.js +0 -67
  229. package/dist/src/retrieval/vector/search.js +0 -12
  230. package/dist/src/retrieval/vector/test-persistence.js +0 -36
  231. package/dist/src/retrieval/vector/upsert.js +0 -40
  232. package/dist/src/retrieval/vector/vector-store.js +0 -89
  233. package/dist/src/retrieval/vector-hybrid-engine.js +0 -91
  234. package/dist/src/runtime/bootstrap.js +0 -28
  235. package/dist/src/runtime/graceful.js +0 -17
  236. package/dist/src/runtime/index.js +0 -3
  237. package/dist/src/runtime/toolnet-memory-runtime.js +0 -156
  238. package/dist/src/security/encryption.js +0 -1
  239. package/dist/src/security/file-filter.js +0 -30
  240. package/dist/src/security/index.js +0 -3
  241. package/dist/src/security/sanitizer.js +0 -49
  242. package/dist/src/security/secret-scanner.js +0 -56
  243. package/dist/src/session/agy/adapter.js +0 -159
  244. package/dist/src/session/agy/cli.js +0 -87
  245. package/dist/src/session/agy/hook-installer.js +0 -62
  246. package/dist/src/session/agy/hook.js +0 -167
  247. package/dist/src/session/agy/index.js +0 -5
  248. package/dist/src/session/agy/project-resolver.js +0 -27
  249. package/dist/src/session/agy/recovery.js +0 -112
  250. package/dist/src/session/agy/transcript.js +0 -191
  251. package/dist/src/session/codex/adapter.js +0 -138
  252. package/dist/src/session/codex/cli.js +0 -236
  253. package/dist/src/session/codex/context-hook-installer.js +0 -70
  254. package/dist/src/session/codex/context-hook.js +0 -69
  255. package/dist/src/session/codex/discovery.js +0 -138
  256. package/dist/src/session/codex/index.js +0 -6
  257. package/dist/src/session/codex/notify-installer.js +0 -135
  258. package/dist/src/session/codex/project-resolver.js +0 -25
  259. package/dist/src/session/codex/recovery.js +0 -27
  260. package/dist/src/session/codex/rollout.js +0 -186
  261. package/dist/src/session/core.js +0 -239
  262. package/dist/src/session/identity.js +0 -57
  263. package/dist/src/session/index.js +0 -9
  264. package/dist/src/session/learner/cli.js +0 -62
  265. package/dist/src/session/learner/extractor.js +0 -461
  266. package/dist/src/session/learner/index.js +0 -4
  267. package/dist/src/session/learner/journal.js +0 -159
  268. package/dist/src/session/learner/learner.js +0 -124
  269. package/dist/src/session/learner/types.js +0 -1
  270. package/dist/src/session/opencode/adapter.js +0 -553
  271. package/dist/src/session/opencode/cli.js +0 -121
  272. package/dist/src/session/opencode/index.js +0 -2
  273. package/dist/src/session/opencode/plugin-installer.js +0 -230
  274. package/dist/src/session/store.js +0 -242
  275. package/dist/src/session/types.js +0 -1
  276. package/dist/src/session/utils.js +0 -47
  277. package/dist/src/session/wal.js +0 -303
  278. package/dist/src/snapshot/index.js +0 -2
  279. package/dist/src/snapshot/manager.js +0 -130
  280. package/dist/src/snapshot/test-snapshot.js +0 -28
  281. package/dist/src/snapshot/types.js +0 -1
  282. package/dist/src/storage/architecture-store.js +0 -37
  283. package/dist/src/storage/cleanup-health.js +0 -20
  284. package/dist/src/storage/code-analysis-store.js +0 -35
  285. package/dist/src/storage/code-chunk-store.js +0 -25
  286. package/dist/src/storage/code-graph-store.js +0 -24
  287. package/dist/src/storage/code-manifest-store.js +0 -24
  288. package/dist/src/storage/code-vector-store.js +0 -25
  289. package/dist/src/storage/github/client.js +0 -1
  290. package/dist/src/storage/github/index.js +0 -1
  291. package/dist/src/storage/google-drive/client.js +0 -1
  292. package/dist/src/storage/google-drive/index.js +0 -1
  293. package/dist/src/storage/huggingface/client.js +0 -116
  294. package/dist/src/storage/huggingface/index.js +0 -1
  295. package/dist/src/storage/index.js +0 -16
  296. package/dist/src/storage/list-bucket-raw.js +0 -14
  297. package/dist/src/storage/list-bucket-tree.js +0 -38
  298. package/dist/src/storage/local/client.js +0 -99
  299. package/dist/src/storage/local/index.js +0 -1
  300. package/dist/src/storage/memory-store.js +0 -30
  301. package/dist/src/storage/project/cleanup-layout-v1.js +0 -72
  302. package/dist/src/storage/project/folder.js +0 -15
  303. package/dist/src/storage/project/index.js +0 -3
  304. package/dist/src/storage/project/layout.js +0 -74
  305. package/dist/src/storage/project/migrate-layout-v2.js +0 -101
  306. package/dist/src/storage/project/migrate.js +0 -73
  307. package/dist/src/storage/project/scoped-provider.js +0 -165
  308. package/dist/src/storage/provider.js +0 -26
  309. package/dist/src/storage/retrying-provider.js +0 -23
  310. package/dist/src/storage/test-connection.js +0 -32
  311. package/dist/src/storage/type-resolution-store.js +0 -26
  312. package/dist/src/storage/types.js +0 -1
  313. package/dist/src/storage/vector-store.js +0 -30
  314. package/dist/src/storage/visualization-store.js +0 -25
  315. package/dist/src/sync/compressor.js +0 -1
  316. package/dist/src/sync/conflict-resolver.js +0 -1
  317. package/dist/src/sync/downloader.js +0 -1
  318. package/dist/src/sync/index.js +0 -1
  319. package/dist/src/sync/sync-engine.js +0 -1
  320. package/dist/src/sync/upload-queue.js +0 -1
  321. package/dist/src/utils/retry.js +0 -29
  322. package/dist/src/visualization/server.js +0 -270
  323. package/dist/src/work-continuity/brief-cache.js +0 -107
  324. package/dist/src/work-continuity/brief.js +0 -349
  325. package/dist/src/work-continuity/cli.js +0 -96
  326. package/dist/src/work-continuity/context-cli.js +0 -106
  327. package/dist/src/work-continuity/context-runtime-cli.js +0 -88
  328. package/dist/src/work-continuity/extractor.js +0 -339
  329. package/dist/src/work-continuity/handoff.js +0 -185
  330. package/dist/src/work-continuity/index.js +0 -14
  331. package/dist/src/work-continuity/injection.js +0 -84
  332. package/dist/src/work-continuity/journal.js +0 -49
  333. package/dist/src/work-continuity/learner.js +0 -127
  334. package/dist/src/work-continuity/reducer.js +0 -316
  335. package/dist/src/work-continuity/semantic-extractor.js +0 -360
  336. package/dist/src/work-continuity/semantic-journal.js +0 -55
  337. package/dist/src/work-continuity/semantic-learner.js +0 -125
  338. package/dist/src/work-continuity/semantic-reducer.js +0 -268
  339. package/dist/src/work-continuity/semantic-types.js +0 -1
  340. package/dist/src/work-continuity/types.js +0 -1
  341. package/dist/visualization/public/index.html +0 -2896
  342. package/dist/visualization/public/vendor/3d-force-graph.min.js +0 -5
@@ -1,49 +0,0 @@
1
- import { sha256, } from "../session/utils.js";
2
- function pad(value) {
3
- return String(value).padStart(12, "0");
4
- }
5
- export class WorkObservationJournal {
6
- storage;
7
- constructor(storage) {
8
- this.storage = storage;
9
- }
10
- async write(identity, observations) {
11
- if (observations.length ===
12
- 0) {
13
- return null;
14
- }
15
- const firstSequence = Math.min(...observations.map(item => item.sequence));
16
- const lastSequence = Math.max(...observations.map(item => item.sequence));
17
- const batch = {
18
- version: 1,
19
- projectId: identity.projectId,
20
- agent: identity.agent,
21
- nativeSessionId: identity.nativeSessionId,
22
- sessionKey: identity.sessionKey,
23
- createdAt: new Date()
24
- .toISOString(),
25
- firstSequence,
26
- lastSequence,
27
- observations,
28
- };
29
- const content = JSON.stringify(batch, null, 2) +
30
- "\n";
31
- const digest = sha256(observations
32
- .map(item => item.id)
33
- .sort()
34
- .join("|")).slice(0, 16);
35
- const key = [
36
- `projects/${identity.projectId}`,
37
- "work",
38
- "observations",
39
- identity.agent,
40
- identity.nativeSessionId,
41
- `${pad(firstSequence)}-${pad(lastSequence)}-${digest}.json`,
42
- ].join("/");
43
- if (!await this.storage
44
- .exists(key)) {
45
- await this.storage.put(key, content, "application/json");
46
- }
47
- return key;
48
- }
49
- }
@@ -1,127 +0,0 @@
1
- import { closeSync, existsSync, openSync, readSync, statSync, } from "node:fs";
2
- import { extractWorkObservations, } from "./extractor.js";
3
- import { WorkObservationJournal, } from "./journal.js";
4
- import { reconcileWorkState, } from "./reducer.js";
5
- function readEvents(filePath, offset) {
6
- if (!existsSync(filePath)) {
7
- return {
8
- events: [],
9
- nextOffset: offset,
10
- };
11
- }
12
- const size = statSync(filePath).size;
13
- let start = Number.isFinite(offset)
14
- ? Math.max(0, offset)
15
- : 0;
16
- if (start >
17
- size) {
18
- start =
19
- 0;
20
- }
21
- if (start ===
22
- size) {
23
- return {
24
- events: [],
25
- nextOffset: size,
26
- };
27
- }
28
- const length = size -
29
- start;
30
- const buffer = Buffer.alloc(length);
31
- const fd = openSync(filePath, "r");
32
- try {
33
- readSync(fd, buffer, 0, length, start);
34
- }
35
- finally {
36
- closeSync(fd);
37
- }
38
- const text = buffer.toString("utf8");
39
- const lastNewline = text.lastIndexOf("\n");
40
- if (lastNewline <
41
- 0) {
42
- return {
43
- events: [],
44
- nextOffset: start,
45
- };
46
- }
47
- const complete = text.slice(0, lastNewline +
48
- 1);
49
- const events = complete
50
- .split("\n")
51
- .filter(Boolean)
52
- .flatMap(line => {
53
- try {
54
- return [
55
- JSON.parse(line),
56
- ];
57
- }
58
- catch {
59
- return [];
60
- }
61
- });
62
- return {
63
- events,
64
- nextOffset: start +
65
- Buffer.byteLength(complete, "utf8"),
66
- };
67
- }
68
- export class WorkContinuityLearner {
69
- options;
70
- journal;
71
- constructor(options) {
72
- this.options = options;
73
- this.journal =
74
- new WorkObservationJournal(options.storage);
75
- }
76
- async learnNew() {
77
- const state = this.options
78
- .wal
79
- .loadState();
80
- const rawOffset = Number(state.sourceCursors["work.continuity.offset"] ??
81
- 0);
82
- const read = readEvents(this.options
83
- .wal
84
- .eventsFile, Number.isFinite(rawOffset)
85
- ? rawOffset
86
- : 0);
87
- if (read.events.length ===
88
- 0) {
89
- return {
90
- scannedEvents: 0,
91
- observations: 0,
92
- journalWritten: false,
93
- reconciled: false,
94
- nextOffset: read.nextOffset,
95
- };
96
- }
97
- const observations = extractWorkObservations(this.options
98
- .identity, read.events);
99
- let journalWritten = false;
100
- let reconciled = false;
101
- if (observations.length >
102
- 0) {
103
- const key = await this.journal
104
- .write(this.options
105
- .identity, observations);
106
- journalWritten =
107
- Boolean(key);
108
- if (journalWritten) {
109
- await reconcileWorkState(this.options
110
- .project, this.options
111
- .storage);
112
- reconciled =
113
- true;
114
- }
115
- }
116
- this.options
117
- .wal
118
- .setSourceCursor("work.continuity.offset", read.nextOffset);
119
- return {
120
- scannedEvents: read.events.length,
121
- observations: observations.length,
122
- journalWritten,
123
- reconciled,
124
- nextOffset: read.nextOffset,
125
- };
126
- }
127
- }
@@ -1,316 +0,0 @@
1
- import { join, } from "node:path";
2
- import { mkdirSync, } from "node:fs";
3
- import { sha256, writeJsonAtomic, } from "../session/utils.js";
4
- function normalizedKey(value) {
5
- return value
6
- .normalize("NFKC")
7
- .toLowerCase()
8
- .replace(/[^\p{L}\p{N}]+/gu, " ")
9
- .replace(/\s+/g, " ")
10
- .trim();
11
- }
12
- function uniqueRecent(values, limit = 20) {
13
- const output = [];
14
- const seen = new Set();
15
- for (const value of values
16
- .slice()
17
- .reverse()) {
18
- const key = normalizedKey(value);
19
- if (!key ||
20
- seen.has(key)) {
21
- continue;
22
- }
23
- seen.add(key);
24
- output.push(value);
25
- if (output.length >=
26
- limit) {
27
- break;
28
- }
29
- }
30
- return output.reverse();
31
- }
32
- function isPlaceholderTitle(observation) {
33
- if (observation.kind ===
34
- "phase") {
35
- return /^Phase\s+\d+$/iu
36
- .test(observation.text);
37
- }
38
- if (observation.kind ===
39
- "task") {
40
- return /^(?:TODO|Task|Việc)\s+\d+$/iu
41
- .test(observation.text);
42
- }
43
- return false;
44
- }
45
- function mergeItem(previous, observation) {
46
- const incomingStatus = observation.status ??
47
- previous?.status ??
48
- "pending";
49
- let status = incomingStatus;
50
- if (previous) {
51
- /*
52
- * Completed work is sticky.
53
- * A stale plan from another agent must not reopen it.
54
- */
55
- if (previous.status ===
56
- "completed" &&
57
- incomingStatus !==
58
- "completed") {
59
- status =
60
- "completed";
61
- }
62
- /*
63
- * A plain plan restatement is pending.
64
- * It must not downgrade active/blocked work.
65
- */
66
- else if (incomingStatus ===
67
- "pending" &&
68
- (previous.status ===
69
- "in_progress" ||
70
- previous.status ===
71
- "blocked")) {
72
- status =
73
- previous.status;
74
- }
75
- }
76
- /*
77
- * Status-only update:
78
- *
79
- * TODO 2: Viết adapter
80
- * TODO 2 đang làm
81
- *
82
- * keeps descriptive title "Viết adapter".
83
- */
84
- const title = previous &&
85
- isPlaceholderTitle(observation)
86
- ? previous.title
87
- : observation.text;
88
- return {
89
- id: previous?.id ??
90
- sha256(observation.key).slice(0, 24),
91
- title,
92
- status,
93
- order: observation.order ??
94
- previous?.order,
95
- confidence: Math.max(observation.confidence, previous?.confidence ??
96
- 0),
97
- updatedAt: observation.occurredAt,
98
- updatedBy: {
99
- agent: observation.agent,
100
- nativeSessionId: observation.nativeSessionId,
101
- eventId: observation.eventId,
102
- },
103
- };
104
- }
105
- async function loadBatches(project, storage) {
106
- const prefix = `projects/${project.id}/work/observations/`;
107
- const objects = await storage.list(prefix);
108
- const batches = [];
109
- for (const object of objects
110
- .filter(item => item.key.endsWith(".json"))
111
- .sort((left, right) => left.key.localeCompare(right.key))) {
112
- const text = await storage.getText(object.key);
113
- if (!text) {
114
- continue;
115
- }
116
- try {
117
- const batch = JSON.parse(text);
118
- if (batch.version ===
119
- 1 &&
120
- Array.isArray(batch.observations)) {
121
- batches.push(batch);
122
- }
123
- }
124
- catch {
125
- // Ignore corrupt/incomplete optional batch.
126
- }
127
- }
128
- return batches;
129
- }
130
- export async function reconcileWorkState(project, storage) {
131
- const batches = await loadBatches(project, storage);
132
- /*
133
- * Important:
134
- * batches come from multiple agents and each session has
135
- * its own sequence counter.
136
- *
137
- * Never assume global sequence ordering.
138
- * Timestamp is primary; sequence is only a local tie-breaker.
139
- */
140
- const observations = batches
141
- .flatMap(batch => batch.observations)
142
- .sort((left, right) => {
143
- const time = left.occurredAt
144
- .localeCompare(right.occurredAt);
145
- if (time !== 0) {
146
- return time;
147
- }
148
- const sequence = left.sequence -
149
- right.sequence;
150
- if (sequence !== 0) {
151
- return sequence;
152
- }
153
- return left.id
154
- .localeCompare(right.id);
155
- });
156
- const phases = new Map();
157
- const tasks = new Map();
158
- let goal;
159
- let plan;
160
- let lastSession;
161
- const decisions = [];
162
- const blockers = [];
163
- const warnings = [];
164
- const explicitNext = [];
165
- const files = [];
166
- const tests = [];
167
- for (const observation of observations) {
168
- switch (observation.kind) {
169
- case "goal":
170
- goal =
171
- observation.text;
172
- break;
173
- case "plan":
174
- plan =
175
- observation.text;
176
- break;
177
- case "phase":
178
- phases.set(observation.key, mergeItem(phases.get(observation.key), observation));
179
- break;
180
- case "task":
181
- tasks.set(observation.key, mergeItem(tasks.get(observation.key), observation));
182
- break;
183
- case "decision":
184
- decisions.push(observation.text);
185
- break;
186
- case "blocker":
187
- blockers.push(observation.text);
188
- break;
189
- case "warning":
190
- warnings.push(observation.text);
191
- break;
192
- case "next_action":
193
- explicitNext.push(observation.text);
194
- break;
195
- case "file":
196
- files.push(observation.text);
197
- break;
198
- case "test":
199
- tests.push(observation.text);
200
- break;
201
- case "session":
202
- lastSession = {
203
- agent: observation.agent,
204
- nativeSessionId: observation.nativeSessionId,
205
- sessionKey: observation.sessionKey,
206
- updatedAt: observation.occurredAt,
207
- };
208
- break;
209
- }
210
- }
211
- const phaseList = Array.from(phases.values()).sort((left, right) => (left.order ??
212
- Number.MAX_SAFE_INTEGER) -
213
- (right.order ??
214
- Number.MAX_SAFE_INTEGER));
215
- const taskList = Array.from(tasks.values()).sort((left, right) => (left.order ??
216
- Number.MAX_SAFE_INTEGER) -
217
- (right.order ??
218
- Number.MAX_SAFE_INTEGER));
219
- const currentPhase = phaseList.find(item => item.status ===
220
- "in_progress") ??
221
- phaseList.find(item => item.status ===
222
- "blocked") ??
223
- phaseList.find(item => item.status ===
224
- "pending");
225
- const currentTask = taskList.find(item => item.status ===
226
- "in_progress") ??
227
- taskList.find(item => item.status ===
228
- "blocked") ??
229
- taskList.find(item => item.status ===
230
- "pending");
231
- const nextActions = uniqueRecent([
232
- ...explicitNext,
233
- ...(currentTask
234
- ? [
235
- currentTask.title,
236
- ]
237
- : []),
238
- ...(!currentTask &&
239
- currentPhase
240
- ? [
241
- currentPhase.title,
242
- ]
243
- : []),
244
- ...taskList
245
- .filter(item => item.status ===
246
- "pending")
247
- .slice(0, 5)
248
- .map(item => item.title),
249
- ], 8);
250
- const activeBlockers = uniqueRecent([
251
- ...blockers,
252
- ...phaseList
253
- .filter(item => item.status ===
254
- "blocked")
255
- .map(item => item.title),
256
- ...taskList
257
- .filter(item => item.status ===
258
- "blocked")
259
- .map(item => item.title),
260
- ], 20);
261
- const state = {
262
- version: 1,
263
- projectId: project.id,
264
- projectName: project.name,
265
- goal,
266
- plan,
267
- phases: phaseList,
268
- tasks: taskList,
269
- decisions: uniqueRecent(decisions, 20),
270
- blockers: activeBlockers,
271
- warnings: uniqueRecent(warnings, 20),
272
- nextActions,
273
- filesTouched: uniqueRecent(files, 30),
274
- tests: uniqueRecent(tests, 20),
275
- currentPhase,
276
- currentTask,
277
- progress: {
278
- phasesTotal: phaseList.length,
279
- phasesCompleted: phaseList.filter(item => item.status ===
280
- "completed").length,
281
- tasksTotal: taskList.length,
282
- tasksCompleted: taskList.filter(item => item.status ===
283
- "completed").length,
284
- blocked: phaseList.filter(item => item.status ===
285
- "blocked").length +
286
- taskList.filter(item => item.status ===
287
- "blocked").length,
288
- },
289
- lastSession,
290
- updatedAt: observations.length
291
- ? observations[observations.length -
292
- 1].occurredAt
293
- : new Date()
294
- .toISOString(),
295
- };
296
- const localDirectory = join(project.rootPath, ".toolnet", "work");
297
- mkdirSync(localDirectory, {
298
- recursive: true,
299
- });
300
- writeJsonAtomic(join(localDirectory, "current.json"), state);
301
- await storage.put(`projects/${project.id}/work/current.json`, JSON.stringify(state, null, 2) +
302
- "\n", "application/json");
303
- return state;
304
- }
305
- export async function loadWorkState(project, storage) {
306
- const text = await storage.getText(`projects/${project.id}/work/current.json`);
307
- if (!text) {
308
- return null;
309
- }
310
- try {
311
- return JSON.parse(text);
312
- }
313
- catch {
314
- return null;
315
- }
316
- }