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,107 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
2
- import { dirname, join, } from "node:path";
3
- import { sha256, writeJsonAtomic, } from "../session/utils.js";
4
- import { buildStartupBrief, } from "./brief.js";
5
- export function startupBriefFile(project) {
6
- return join(project.rootPath, ".toolnet", "context", "startup.md");
7
- }
8
- function startupMetaFile(project) {
9
- return join(project.rootPath, ".toolnet", "context", "startup.json");
10
- }
11
- function persistLocal(project, cache) {
12
- const file = startupBriefFile(project);
13
- mkdirSync(dirname(file), {
14
- recursive: true,
15
- });
16
- writeFileSync(file, cache.text.endsWith("\n")
17
- ? cache.text
18
- : cache.text + "\n", {
19
- encoding: "utf8",
20
- mode: 0o600,
21
- });
22
- writeJsonAtomic(startupMetaFile(project), cache);
23
- }
24
- export async function refreshStartupBriefCache(project, storage, maxTokens = 900) {
25
- const brief = await buildStartupBrief({
26
- project,
27
- storage,
28
- maxTokens,
29
- });
30
- const cache = {
31
- version: 1,
32
- projectId: project.id,
33
- projectName: project.name,
34
- text: brief.text,
35
- digest: sha256(brief.text),
36
- estimatedTokens: brief.estimatedTokens,
37
- generatedAt: new Date()
38
- .toISOString(),
39
- };
40
- persistLocal(project, cache);
41
- await storage.put(`projects/${project.id}/context/startup.md`, cache.text + "\n", "text/markdown");
42
- await storage.put(`projects/${project.id}/context/startup.json`, JSON.stringify(cache, null, 2) + "\n", "application/json");
43
- return cache;
44
- }
45
- /*
46
- * Startup injection always prefers remote.
47
- *
48
- * Reason:
49
- * OpenCode may have worked on VPS A,
50
- * then Agy/Codex may start immediately on VPS B.
51
- *
52
- * One small remote GET at session start is much safer than
53
- * trusting a potentially stale local cache.
54
- */
55
- export async function getStartupBriefForInjection(project, storage, maxTokens = 900) {
56
- try {
57
- const remote = await storage.getText(`projects/${project.id}/context/startup.md`);
58
- if (remote &&
59
- remote.trim()) {
60
- const text = remote.trim();
61
- const cache = {
62
- version: 1,
63
- projectId: project.id,
64
- projectName: project.name,
65
- text,
66
- digest: sha256(text),
67
- estimatedTokens: Math.ceil(text.length /
68
- 3.5),
69
- generatedAt: new Date()
70
- .toISOString(),
71
- };
72
- persistLocal(project, cache);
73
- return cache;
74
- }
75
- }
76
- catch {
77
- // Network unavailable -> local fallback.
78
- }
79
- const local = startupBriefFile(project);
80
- if (existsSync(local)) {
81
- try {
82
- const text = readFileSync(local, "utf8").trim();
83
- if (text) {
84
- return {
85
- version: 1,
86
- projectId: project.id,
87
- projectName: project.name,
88
- text,
89
- digest: sha256(text),
90
- estimatedTokens: Math.ceil(text.length /
91
- 3.5),
92
- generatedAt: new Date()
93
- .toISOString(),
94
- };
95
- }
96
- }
97
- catch {
98
- // Fall through.
99
- }
100
- }
101
- try {
102
- return await refreshStartupBriefCache(project, storage, maxTokens);
103
- }
104
- catch {
105
- return null;
106
- }
107
- }
@@ -1,349 +0,0 @@
1
- import { loadProjectManual, projectManualPath, } from "../project-manual/manager.js";
2
- import { loadLatestHandoff, } from "./handoff.js";
3
- import { loadWorkState, } from "./reducer.js";
4
- import { loadSemanticWorkState, } from "./semantic-reducer.js";
5
- function estimateTokens(value) {
6
- if (!value) {
7
- return 0;
8
- }
9
- const chars = Array.from(value).length;
10
- const words = value
11
- .trim()
12
- .split(/\s+/u)
13
- .filter(Boolean)
14
- .length;
15
- /*
16
- * Lightweight conservative approximation.
17
- * No tokenizer dependency required.
18
- */
19
- return Math.ceil(Math.max(chars / 3.5, words * 1.3));
20
- }
21
- function clip(value, maxChars) {
22
- const clean = value
23
- .replace(/\s+/g, " ")
24
- .trim();
25
- if (clean.length <=
26
- maxChars) {
27
- return clean;
28
- }
29
- return (clean.slice(0, Math.max(0, maxChars - 1))
30
- .trimEnd() +
31
- "…");
32
- }
33
- function manualNotes(content) {
34
- const output = [];
35
- let inComment = false;
36
- for (const raw of content.split(/\r?\n/u)) {
37
- let line = raw.trim();
38
- if (line.includes("<!--")) {
39
- inComment =
40
- true;
41
- }
42
- if (inComment) {
43
- if (line.includes("-->")) {
44
- inComment =
45
- false;
46
- }
47
- continue;
48
- }
49
- const lower = line.toLowerCase();
50
- if (!line ||
51
- line.startsWith("#") ||
52
- line === "```" ||
53
- lower.startsWith("- [enforce]") ||
54
- lower.startsWith("* [enforce]") ||
55
- lower.startsWith("- [advisory]") ||
56
- lower.startsWith("* [advisory]")) {
57
- continue;
58
- }
59
- line =
60
- line.replace(/^[-*]\s+/u, "");
61
- if (line) {
62
- output.push(clip(line, 280));
63
- }
64
- if (output.length >=
65
- 16) {
66
- break;
67
- }
68
- }
69
- return output;
70
- }
71
- function parseRemoteRules(content) {
72
- const enforce = [];
73
- const advisory = [];
74
- for (const raw of content.split(/\\r?\\n/u)) {
75
- const line = raw.trim();
76
- const lower = line.toLowerCase();
77
- const prefixes = [
78
- "- [enforce]",
79
- "* [enforce]",
80
- "- [advisory]",
81
- "* [advisory]",
82
- ];
83
- const prefix = prefixes.find(item => lower.startsWith(item));
84
- if (!prefix) {
85
- continue;
86
- }
87
- const text = line
88
- .slice(prefix.length)
89
- .trim();
90
- if (!text) {
91
- continue;
92
- }
93
- if (prefix.includes("enforce")) {
94
- enforce.push(text);
95
- }
96
- else {
97
- advisory.push(text);
98
- }
99
- }
100
- return {
101
- enforce,
102
- advisory,
103
- };
104
- }
105
- function fitLines(lines, maxTokens) {
106
- const output = [];
107
- for (const line of lines) {
108
- const candidate = [
109
- ...output,
110
- line,
111
- ].join("\n");
112
- if (estimateTokens(candidate) <=
113
- maxTokens) {
114
- output.push(line);
115
- continue;
116
- }
117
- const used = estimateTokens(output.join("\n"));
118
- const remaining = Math.max(0, maxTokens -
119
- used);
120
- if (remaining >=
121
- 16) {
122
- const maxChars = Math.floor(remaining *
123
- 3.2);
124
- const partial = clip(line, maxChars);
125
- if (partial) {
126
- output.push(partial);
127
- }
128
- }
129
- break;
130
- }
131
- return output
132
- .join("\n")
133
- .trim();
134
- }
135
- export async function buildStartupBrief(options) {
136
- const maxTokens = Math.max(256, Math.min(2000, options.maxTokens ??
137
- 1000));
138
- const localManual = loadProjectManual(options.project, false);
139
- let manualContent = localManual?.content ??
140
- "";
141
- /*
142
- * Cross-machine/VPS fallback.
143
- * If PROJECT.md isn't local yet, read the project-scoped
144
- * copy from remote storage.
145
- */
146
- if (!manualContent) {
147
- manualContent =
148
- await options.storage
149
- .getText(`projects/${options.project.id}/project/manual.md`) ??
150
- "";
151
- }
152
- const parsedRemote = parseRemoteRules(manualContent);
153
- const enforce = localManual
154
- ? localManual.rules
155
- .filter(rule => rule.mode ===
156
- "enforce")
157
- .map(rule => rule.text)
158
- : parsedRemote.enforce;
159
- const advisory = localManual
160
- ? localManual.rules
161
- .filter(rule => rule.mode ===
162
- "advisory")
163
- .map(rule => rule.text)
164
- : parsedRemote.advisory;
165
- const notes = manualContent
166
- ? manualNotes(manualContent)
167
- : [];
168
- const state = await loadWorkState(options.project, options.storage);
169
- const semantic = await loadSemanticWorkState(options.project, options.storage);
170
- const handoff = await loadLatestHandoff(options.project, options.storage);
171
- const lines = [];
172
- lines.push("[TOOLNET PROJECT CONTEXT]");
173
- lines.push(`Project: ${options.project.name}`);
174
- lines.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary.");
175
- if (manualContent) {
176
- lines.push(`Full operating manual: ${projectManualPath(options.project)}`);
177
- }
178
- /*
179
- * Highest priority:
180
- * project operating rules.
181
- */
182
- if (enforce.length) {
183
- lines.push("", "PROJECT RULES — MUST FOLLOW");
184
- for (const rule of enforce.slice(0, 24)) {
185
- lines.push(`- [ENFORCE] ${clip(rule, 240)}`);
186
- }
187
- }
188
- if (advisory.length) {
189
- lines.push("", "PROJECT PREFERENCES");
190
- for (const rule of advisory.slice(0, 10)) {
191
- lines.push(`- ${clip(rule, 220)}`);
192
- }
193
- }
194
- /*
195
- * Semantic continuity:
196
- * tell the new agent WHAT it is doing and WHY,
197
- * before telling it which checkbox comes next.
198
- */
199
- if (semantic) {
200
- if (semantic.mission) {
201
- lines.push("", "MISSION", clip(semantic.mission.value, 420));
202
- }
203
- if (semantic.activeObjective) {
204
- lines.push("", "CURRENT OBJECTIVE", clip(semantic.activeObjective.value, 420));
205
- }
206
- if (semantic.why) {
207
- lines.push("", "WHY THIS WORK MATTERS", clip(semantic.why.value, 420));
208
- }
209
- if (semantic.desiredOutcome) {
210
- lines.push("", "DESIRED OUTCOME", clip(semantic.desiredOutcome.value, 420));
211
- }
212
- if (semantic.planRationale) {
213
- lines.push("", "WHY THIS APPROACH", clip(semantic.planRationale.value, 420));
214
- }
215
- }
216
- /*
217
- * Next priority:
218
- * unfinished execution state.
219
- */
220
- if (state) {
221
- lines.push("", "ACTIVE WORK");
222
- if (state.goal) {
223
- lines.push(`Goal: ${clip(state.goal, 320)}`);
224
- }
225
- if (state.plan) {
226
- lines.push(`Plan: ${clip(state.plan, 320)}`);
227
- }
228
- lines.push(`Progress: phases ${state.progress.phasesCompleted}/${state.progress.phasesTotal}; tasks ${state.progress.tasksCompleted}/${state.progress.tasksTotal}; blocked ${state.progress.blocked}`);
229
- if (state.currentPhase) {
230
- lines.push(`Current phase: ${state.currentPhase.title} [${state.currentPhase.status}]`);
231
- }
232
- if (state.currentPhase &&
233
- semantic) {
234
- const semanticPhase = semantic.phases.find(item => item.order ===
235
- state.currentPhase
236
- ?.order);
237
- if (semanticPhase) {
238
- if (semanticPhase.objective) {
239
- lines.push(`Phase objective: ${clip(semanticPhase.objective.value, 340)}`);
240
- }
241
- if (semanticPhase.why) {
242
- lines.push(`Why this phase: ${clip(semanticPhase.why.value, 340)}`);
243
- }
244
- else {
245
- lines.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent.");
246
- }
247
- if (semanticPhase.deliverable) {
248
- lines.push(`Deliverable: ${clip(semanticPhase.deliverable.value, 340)}`);
249
- }
250
- if (semanticPhase.dependencies.length) {
251
- lines.push(`Depends on: ${semanticPhase.dependencies
252
- .slice(0, 4)
253
- .map(item => clip(item.value, 180))
254
- .join("; ")}`);
255
- }
256
- if (semanticPhase.acceptanceCriteria.length) {
257
- lines.push("", "DEFINITION OF DONE");
258
- semanticPhase.acceptanceCriteria
259
- .slice(0, 6)
260
- .forEach(item => {
261
- lines.push(`- ${clip(item.value, 260)}`);
262
- });
263
- }
264
- if (semanticPhase.openQuestions.length) {
265
- lines.push("", "OPEN QUESTIONS FOR CURRENT PHASE");
266
- semanticPhase.openQuestions
267
- .slice(0, 4)
268
- .forEach(item => {
269
- lines.push(`- ${clip(item.value, 260)}`);
270
- });
271
- }
272
- }
273
- }
274
- if (state.currentTask) {
275
- lines.push(`Current task: ${state.currentTask.title} [${state.currentTask.status}]`);
276
- }
277
- if (state.nextActions.length) {
278
- lines.push("", "NEXT ACTIONS");
279
- state.nextActions
280
- .slice(0, 6)
281
- .forEach((action, index) => {
282
- lines.push(`${index + 1}. ${clip(action, 260)}`);
283
- });
284
- }
285
- if (state.blockers.length) {
286
- lines.push("", "BLOCKERS");
287
- state.blockers
288
- .slice(0, 5)
289
- .forEach(blocker => {
290
- lines.push(`- ${clip(blocker, 260)}`);
291
- });
292
- }
293
- if (state.warnings.length) {
294
- lines.push("", "ATTENTION");
295
- state.warnings
296
- .slice(-5)
297
- .forEach(warning => {
298
- lines.push(`- ${clip(warning, 260)}`);
299
- });
300
- }
301
- if (state.decisions.length) {
302
- lines.push("", "RECENT DECISIONS");
303
- state.decisions
304
- .slice(-5)
305
- .forEach(decision => {
306
- lines.push(`- ${clip(decision, 260)}`);
307
- });
308
- }
309
- if (state.lastSession) {
310
- lines.push("", `Last work session: ${state.lastSession.agent} / ${state.lastSession.nativeSessionId}`);
311
- }
312
- }
313
- if (semantic &&
314
- semantic.openQuestions.length) {
315
- lines.push("", "UNRESOLVED QUESTIONS");
316
- semantic.openQuestions
317
- .slice(0, 5)
318
- .forEach(item => {
319
- lines.push(`- ${clip(item.value, 260)}`);
320
- });
321
- }
322
- if (handoff) {
323
- lines.push(`Latest handoff: ${handoff.reason} / ${handoff.sourceSession.agent}`);
324
- }
325
- /*
326
- * Lower priority operational notes.
327
- */
328
- if (notes.length) {
329
- lines.push("", "OPERATING NOTES");
330
- for (const note of notes) {
331
- lines.push(`- ${note}`);
332
- }
333
- }
334
- lines.push("", "Before changing anything: verify the current repository state and continue from the active phase/task above.");
335
- const text = fitLines(lines, maxTokens);
336
- return {
337
- version: 1,
338
- projectId: options.project.id,
339
- projectName: options.project.name,
340
- text,
341
- estimatedTokens: estimateTokens(text),
342
- maxTokens,
343
- hasManual: Boolean(manualContent),
344
- hasWorkState: Boolean(state),
345
- hasHandoff: Boolean(handoff),
346
- generatedAt: new Date()
347
- .toISOString(),
348
- };
349
- }
@@ -1,96 +0,0 @@
1
- import { loadConfig, ProjectManager, } from "../core/index.js";
2
- import { createStorageProvider, ProjectScopedStorageProvider, withStorageRetry, } from "../storage/index.js";
3
- import { loadWorkState, reconcileWorkState, } from "./reducer.js";
4
- function after(args, flag) {
5
- const index = args.indexOf(flag);
6
- return index >=
7
- 0
8
- ? args[index + 1]
9
- : undefined;
10
- }
11
- function storageFor(project) {
12
- const config = loadConfig();
13
- const raw = withStorageRetry(createStorageProvider({
14
- provider: config.storage
15
- .provider,
16
- huggingface: config.storage
17
- .huggingface,
18
- localRoot: config.storage
19
- .localRoot,
20
- }), {
21
- attempts: 3,
22
- });
23
- return new ProjectScopedStorageProvider(raw, project.id, project.name, project.remote ??
24
- project.name);
25
- }
26
- function printState(state) {
27
- console.log();
28
- console.log(`Project: ${state.projectName}`);
29
- if (state.goal) {
30
- console.log(`Goal: ${state.goal}`);
31
- }
32
- if (state.currentPhase) {
33
- console.log(`Current phase: ${state.currentPhase.title} [${state.currentPhase.status}]`);
34
- }
35
- if (state.currentTask) {
36
- console.log(`Current task: ${state.currentTask.title} [${state.currentTask.status}]`);
37
- }
38
- console.log(`Phases: ${state.progress.phasesCompleted}/${state.progress.phasesTotal}`);
39
- console.log(`Tasks: ${state.progress.tasksCompleted}/${state.progress.tasksTotal}`);
40
- if (state.nextActions.length) {
41
- console.log();
42
- console.log("Next actions:");
43
- state.nextActions.forEach((item, index) => console.log(`${index + 1}. ${item}`));
44
- }
45
- if (state.blockers.length) {
46
- console.log();
47
- console.log("Blockers:");
48
- state.blockers.forEach(item => console.log(`- ${item}`));
49
- }
50
- if (state.lastSession) {
51
- console.log();
52
- console.log(`Last session: ${state.lastSession.agent} / ${state.lastSession.nativeSessionId}`);
53
- }
54
- }
55
- async function main() {
56
- const [command = "help", ...args] = process.argv.slice(2);
57
- const project = new ProjectManager()
58
- .detect(after(args, "--project") ??
59
- process.cwd());
60
- const storage = storageFor(project);
61
- if (command ===
62
- "reconcile") {
63
- const state = await reconcileWorkState(project, storage);
64
- printState(state);
65
- return;
66
- }
67
- if (command ===
68
- "status") {
69
- const state = await loadWorkState(project, storage);
70
- if (!state) {
71
- console.log("No active work state yet.");
72
- return;
73
- }
74
- printState(state);
75
- return;
76
- }
77
- if (command ===
78
- "json") {
79
- const state = await loadWorkState(project, storage);
80
- console.log(JSON.stringify(state, null, 2));
81
- return;
82
- }
83
- console.log(`Work Continuity
84
-
85
- Commands:
86
- status [--project PATH]
87
- json [--project PATH]
88
- reconcile [--project PATH]
89
- `);
90
- }
91
- main().catch(error => {
92
- console.error(error instanceof Error
93
- ? error.message
94
- : error);
95
- process.exit(1);
96
- });
@@ -1,106 +0,0 @@
1
- import { loadConfig, ProjectManager, } from "../core/index.js";
2
- import { createStorageProvider, ProjectScopedStorageProvider, withStorageRetry, } from "../storage/index.js";
3
- import { createSessionIdentity, } from "../session/identity.js";
4
- import { buildStartupBrief, } from "./brief.js";
5
- import { loadLatestHandoff, SmartHandoffManager, } from "./handoff.js";
6
- function after(args, flag) {
7
- const index = args.indexOf(flag);
8
- return index >=
9
- 0
10
- ? args[index + 1]
11
- : undefined;
12
- }
13
- function storageFor(project) {
14
- const config = loadConfig();
15
- const raw = withStorageRetry(createStorageProvider({
16
- provider: config.storage
17
- .provider,
18
- huggingface: config.storage
19
- .huggingface,
20
- localRoot: config.storage
21
- .localRoot,
22
- }), {
23
- attempts: 3,
24
- });
25
- return new ProjectScopedStorageProvider(raw, project.id, project.name, project.remote ??
26
- project.name);
27
- }
28
- async function main() {
29
- const [command = "help", ...args] = process.argv.slice(2);
30
- const project = new ProjectManager()
31
- .detect(after(args, "--project") ??
32
- process.cwd());
33
- const storage = storageFor(project);
34
- if (command ===
35
- "brief") {
36
- const maxTokens = Number(after(args, "--tokens") ??
37
- 1000);
38
- const brief = await buildStartupBrief({
39
- project,
40
- storage,
41
- maxTokens: Number.isFinite(maxTokens)
42
- ? maxTokens
43
- : 1000,
44
- });
45
- process.stdout.write(brief.text +
46
- "\n");
47
- return;
48
- }
49
- if (command ===
50
- "brief-json") {
51
- const brief = await buildStartupBrief({
52
- project,
53
- storage,
54
- maxTokens: Number(after(args, "--tokens") ??
55
- 1000),
56
- });
57
- console.log(JSON.stringify(brief, null, 2));
58
- return;
59
- }
60
- if (command ===
61
- "handoff-latest") {
62
- const handoff = await loadLatestHandoff(project, storage);
63
- console.log(JSON.stringify(handoff, null, 2));
64
- return;
65
- }
66
- if (command ===
67
- "handoff-create") {
68
- const agent = (after(args, "--agent") ??
69
- "manual");
70
- if (agent ===
71
- "manual") {
72
- /*
73
- * Manual maintenance command only.
74
- * Session adapters use native IDs automatically.
75
- */
76
- throw new Error("--agent must be opencode, agy, or codex");
77
- }
78
- const session = after(args, "--session");
79
- if (!session) {
80
- throw new Error("--session is required");
81
- }
82
- const identity = createSessionIdentity(project, agent, session);
83
- const manager = new SmartHandoffManager({
84
- project,
85
- storage,
86
- identity,
87
- });
88
- const result = await manager.capture("manual", 0);
89
- console.log(JSON.stringify(result, null, 2));
90
- return;
91
- }
92
- console.log(`Work Context
93
-
94
- Commands:
95
- brief [--project PATH] [--tokens N]
96
- brief-json [--project PATH] [--tokens N]
97
- handoff-latest [--project PATH]
98
- handoff-create --agent <opencode|agy|codex> --session <id>
99
- `);
100
- }
101
- main().catch(error => {
102
- console.error(error instanceof Error
103
- ? error.message
104
- : error);
105
- process.exit(1);
106
- });