mindweave 0.0.1 → 2.1.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 (481) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +171 -14
  3. package/dist/alternator/chassis/cache.js +47 -0
  4. package/dist/alternator/chassis/cache.js.map +1 -0
  5. package/dist/alternator/chassis/domRefs.js +53 -0
  6. package/dist/alternator/chassis/domRefs.js.map +1 -0
  7. package/dist/alternator/chassis/extractWorker.js +65 -0
  8. package/dist/alternator/chassis/extractWorker.js.map +1 -0
  9. package/dist/alternator/chassis/graph.js +221 -0
  10. package/dist/alternator/chassis/graph.js.map +1 -0
  11. package/dist/alternator/chassis/index.js +463 -0
  12. package/dist/alternator/chassis/index.js.map +1 -0
  13. package/dist/alternator/chassis/isolation.js +336 -0
  14. package/dist/alternator/chassis/isolation.js.map +1 -0
  15. package/dist/alternator/chassis/langCases.js +69 -0
  16. package/dist/alternator/chassis/langCases.js.map +1 -0
  17. package/dist/alternator/chassis/lsp.js +469 -0
  18. package/dist/alternator/chassis/lsp.js.map +1 -0
  19. package/dist/alternator/chassis/markup.js +262 -0
  20. package/dist/alternator/chassis/markup.js.map +1 -0
  21. package/dist/alternator/chassis/provision.js +198 -0
  22. package/dist/alternator/chassis/provision.js.map +1 -0
  23. package/dist/alternator/chassis/rank.js +72 -0
  24. package/dist/alternator/chassis/rank.js.map +1 -0
  25. package/dist/alternator/chassis/servers.js +215 -0
  26. package/dist/alternator/chassis/servers.js.map +1 -0
  27. package/dist/alternator/chassis/treesitter.js +608 -0
  28. package/dist/alternator/chassis/treesitter.js.map +1 -0
  29. package/dist/alternator/chassis/types.js +24 -0
  30. package/dist/alternator/chassis/types.js.map +1 -0
  31. package/dist/alternator/lane.js +67 -0
  32. package/dist/alternator/lane.js.map +1 -0
  33. package/dist/cli/App.js +2586 -0
  34. package/dist/cli/App.js.map +1 -0
  35. package/dist/cli/altScreen.js +67 -0
  36. package/dist/cli/altScreen.js.map +1 -0
  37. package/dist/cli/approvalChannel.js +72 -0
  38. package/dist/cli/approvalChannel.js.map +1 -0
  39. package/dist/cli/attachments.js +188 -0
  40. package/dist/cli/attachments.js.map +1 -0
  41. package/dist/cli/bootstrap.js +279 -0
  42. package/dist/cli/bootstrap.js.map +1 -0
  43. package/dist/cli/chatAnchor.js +94 -0
  44. package/dist/cli/chatAnchor.js.map +1 -0
  45. package/dist/cli/commandArgs.js +79 -0
  46. package/dist/cli/commandArgs.js.map +1 -0
  47. package/dist/cli/commandRoute.js +78 -0
  48. package/dist/cli/commandRoute.js.map +1 -0
  49. package/dist/cli/compaction.js +69 -0
  50. package/dist/cli/compaction.js.map +1 -0
  51. package/dist/cli/components/ApprovalBox.js +100 -0
  52. package/dist/cli/components/ApprovalBox.js.map +1 -0
  53. package/dist/cli/components/BlockView.js +128 -0
  54. package/dist/cli/components/BlockView.js.map +1 -0
  55. package/dist/cli/components/FirstRunFrame.js +41 -0
  56. package/dist/cli/components/FirstRunFrame.js.map +1 -0
  57. package/dist/cli/components/KeyManager.js +197 -0
  58. package/dist/cli/components/KeyManager.js.map +1 -0
  59. package/dist/cli/components/KeySetup.js +125 -0
  60. package/dist/cli/components/KeySetup.js.map +1 -0
  61. package/dist/cli/components/MenuFrame.js +24 -0
  62. package/dist/cli/components/MenuFrame.js.map +1 -0
  63. package/dist/cli/components/Picker.js +82 -0
  64. package/dist/cli/components/Picker.js.map +1 -0
  65. package/dist/cli/components/PromptInput.js +509 -0
  66. package/dist/cli/components/PromptInput.js.map +1 -0
  67. package/dist/cli/components/SubagentView.js +86 -0
  68. package/dist/cli/components/SubagentView.js.map +1 -0
  69. package/dist/cli/components/ToolGroup.js +60 -0
  70. package/dist/cli/components/ToolGroup.js.map +1 -0
  71. package/dist/cli/components/ToolLine.js +123 -0
  72. package/dist/cli/components/ToolLine.js.map +1 -0
  73. package/dist/cli/components/TrustGate.js +37 -0
  74. package/dist/cli/components/TrustGate.js.map +1 -0
  75. package/dist/cli/costView.js +40 -0
  76. package/dist/cli/costView.js.map +1 -0
  77. package/dist/cli/frameRate.js +30 -0
  78. package/dist/cli/frameRate.js.map +1 -0
  79. package/dist/cli/framebuffer/paint.js +165 -0
  80. package/dist/cli/framebuffer/paint.js.map +1 -0
  81. package/dist/cli/framebuffer/parse.js +266 -0
  82. package/dist/cli/framebuffer/parse.js.map +1 -0
  83. package/dist/cli/framebuffer/screen.js +196 -0
  84. package/dist/cli/framebuffer/screen.js.map +1 -0
  85. package/dist/cli/framebuffer/writer.js +139 -0
  86. package/dist/cli/framebuffer/writer.js.map +1 -0
  87. package/dist/cli/groupReveal.js +51 -0
  88. package/dist/cli/groupReveal.js.map +1 -0
  89. package/dist/cli/help.js +55 -0
  90. package/dist/cli/help.js.map +1 -0
  91. package/dist/cli/inputView.js +105 -0
  92. package/dist/cli/inputView.js.map +1 -0
  93. package/dist/cli/keyManager.js +65 -0
  94. package/dist/cli/keyManager.js.map +1 -0
  95. package/dist/cli/keySetup.js +35 -0
  96. package/dist/cli/keySetup.js.map +1 -0
  97. package/dist/cli/keyStore.js +73 -0
  98. package/dist/cli/keyStore.js.map +1 -0
  99. package/dist/cli/markdown.js +460 -0
  100. package/dist/cli/markdown.js.map +1 -0
  101. package/dist/cli/messageQueue.js +96 -0
  102. package/dist/cli/messageQueue.js.map +1 -0
  103. package/dist/cli/modes.js +90 -0
  104. package/dist/cli/modes.js.map +1 -0
  105. package/dist/cli/mouse.js +78 -0
  106. package/dist/cli/mouse.js.map +1 -0
  107. package/dist/cli/pasteAssembler.js +44 -0
  108. package/dist/cli/pasteAssembler.js.map +1 -0
  109. package/dist/cli/pathComplete.js +39 -0
  110. package/dist/cli/pathComplete.js.map +1 -0
  111. package/dist/cli/perfLog.js +90 -0
  112. package/dist/cli/perfLog.js.map +1 -0
  113. package/dist/cli/reveal.js +32 -0
  114. package/dist/cli/reveal.js.map +1 -0
  115. package/dist/cli/revealPace.js +59 -0
  116. package/dist/cli/revealPace.js.map +1 -0
  117. package/dist/cli/sessionCarry.js +19 -0
  118. package/dist/cli/sessionCarry.js.map +1 -0
  119. package/dist/cli/smoothScroll.js +74 -0
  120. package/dist/cli/smoothScroll.js.map +1 -0
  121. package/dist/cli/startupArgs.js +96 -0
  122. package/dist/cli/startupArgs.js.map +1 -0
  123. package/dist/cli/terminalRestore.js +34 -0
  124. package/dist/cli/terminalRestore.js.map +1 -0
  125. package/dist/cli/toolDisplay.js +219 -0
  126. package/dist/cli/toolDisplay.js.map +1 -0
  127. package/dist/cli/toolItems.js +65 -0
  128. package/dist/cli/toolItems.js.map +1 -0
  129. package/dist/cli/transcript.js +351 -0
  130. package/dist/cli/transcript.js.map +1 -0
  131. package/dist/cli/trust.js +79 -0
  132. package/dist/cli/trust.js.map +1 -0
  133. package/dist/cli/updateCheck.js +107 -0
  134. package/dist/cli/updateCheck.js.map +1 -0
  135. package/dist/cli/version.js +39 -0
  136. package/dist/cli/version.js.map +1 -0
  137. package/dist/cli/viewport.js +179 -0
  138. package/dist/cli/viewport.js.map +1 -0
  139. package/dist/cli/virtualWindow.js +103 -0
  140. package/dist/cli/virtualWindow.js.map +1 -0
  141. package/dist/cli/workingVerb.js +37 -0
  142. package/dist/cli/workingVerb.js.map +1 -0
  143. package/dist/cli/wrap.js +145 -0
  144. package/dist/cli/wrap.js.map +1 -0
  145. package/dist/drivers/anthropic/cachePoints.js +77 -0
  146. package/dist/drivers/anthropic/cachePoints.js.map +1 -0
  147. package/dist/drivers/anthropic/client.js +432 -0
  148. package/dist/drivers/anthropic/client.js.map +1 -0
  149. package/dist/drivers/anthropic/index.js +10 -0
  150. package/dist/drivers/anthropic/index.js.map +1 -0
  151. package/dist/drivers/anthropic/manifest.js +221 -0
  152. package/dist/drivers/anthropic/manifest.js.map +1 -0
  153. package/dist/drivers/cerebras/client.js +69 -0
  154. package/dist/drivers/cerebras/client.js.map +1 -0
  155. package/dist/drivers/cerebras/index.js +5 -0
  156. package/dist/drivers/cerebras/index.js.map +1 -0
  157. package/dist/drivers/cerebras/manifest.js +140 -0
  158. package/dist/drivers/cerebras/manifest.js.map +1 -0
  159. package/dist/drivers/clientId.js +41 -0
  160. package/dist/drivers/clientId.js.map +1 -0
  161. package/dist/drivers/contextOverflow.js +77 -0
  162. package/dist/drivers/contextOverflow.js.map +1 -0
  163. package/dist/drivers/deepseek/client.js +168 -0
  164. package/dist/drivers/deepseek/client.js.map +1 -0
  165. package/dist/drivers/deepseek/index.js +16 -0
  166. package/dist/drivers/deepseek/index.js.map +1 -0
  167. package/dist/drivers/deepseek/inlineTools.js +46 -0
  168. package/dist/drivers/deepseek/inlineTools.js.map +1 -0
  169. package/dist/drivers/deepseek/manifest.js +166 -0
  170. package/dist/drivers/deepseek/manifest.js.map +1 -0
  171. package/dist/drivers/gemini/client.js +38 -0
  172. package/dist/drivers/gemini/client.js.map +1 -0
  173. package/dist/drivers/gemini/index.js +5 -0
  174. package/dist/drivers/gemini/index.js.map +1 -0
  175. package/dist/drivers/gemini/manifest.js +150 -0
  176. package/dist/drivers/gemini/manifest.js.map +1 -0
  177. package/dist/drivers/glm/client.js +90 -0
  178. package/dist/drivers/glm/client.js.map +1 -0
  179. package/dist/drivers/glm/index.js +9 -0
  180. package/dist/drivers/glm/index.js.map +1 -0
  181. package/dist/drivers/glm/manifest.js +183 -0
  182. package/dist/drivers/glm/manifest.js.map +1 -0
  183. package/dist/drivers/groq/client.js +80 -0
  184. package/dist/drivers/groq/client.js.map +1 -0
  185. package/dist/drivers/groq/index.js +5 -0
  186. package/dist/drivers/groq/index.js.map +1 -0
  187. package/dist/drivers/groq/manifest.js +160 -0
  188. package/dist/drivers/groq/manifest.js.map +1 -0
  189. package/dist/drivers/kimi/client.js +82 -0
  190. package/dist/drivers/kimi/client.js.map +1 -0
  191. package/dist/drivers/kimi/index.js +9 -0
  192. package/dist/drivers/kimi/index.js.map +1 -0
  193. package/dist/drivers/kimi/manifest.js +168 -0
  194. package/dist/drivers/kimi/manifest.js.map +1 -0
  195. package/dist/drivers/meta/client.js +30 -0
  196. package/dist/drivers/meta/client.js.map +1 -0
  197. package/dist/drivers/meta/index.js +5 -0
  198. package/dist/drivers/meta/index.js.map +1 -0
  199. package/dist/drivers/meta/manifest.js +101 -0
  200. package/dist/drivers/meta/manifest.js.map +1 -0
  201. package/dist/drivers/minimax/client.js +36 -0
  202. package/dist/drivers/minimax/client.js.map +1 -0
  203. package/dist/drivers/minimax/index.js +5 -0
  204. package/dist/drivers/minimax/index.js.map +1 -0
  205. package/dist/drivers/minimax/manifest.js +120 -0
  206. package/dist/drivers/minimax/manifest.js.map +1 -0
  207. package/dist/drivers/mistral/client.js +54 -0
  208. package/dist/drivers/mistral/client.js.map +1 -0
  209. package/dist/drivers/mistral/index.js +5 -0
  210. package/dist/drivers/mistral/index.js.map +1 -0
  211. package/dist/drivers/mistral/manifest.js +118 -0
  212. package/dist/drivers/mistral/manifest.js.map +1 -0
  213. package/dist/drivers/openai/client.js +290 -0
  214. package/dist/drivers/openai/client.js.map +1 -0
  215. package/dist/drivers/openai/index.js +9 -0
  216. package/dist/drivers/openai/index.js.map +1 -0
  217. package/dist/drivers/openai/manifest.js +133 -0
  218. package/dist/drivers/openai/manifest.js.map +1 -0
  219. package/dist/drivers/openaiCompat/wire.js +493 -0
  220. package/dist/drivers/openaiCompat/wire.js.map +1 -0
  221. package/dist/drivers/partialTurn.js +23 -0
  222. package/dist/drivers/partialTurn.js.map +1 -0
  223. package/dist/drivers/providerError.js +181 -0
  224. package/dist/drivers/providerError.js.map +1 -0
  225. package/dist/drivers/qwen/client.js +93 -0
  226. package/dist/drivers/qwen/client.js.map +1 -0
  227. package/dist/drivers/qwen/index.js +9 -0
  228. package/dist/drivers/qwen/index.js.map +1 -0
  229. package/dist/drivers/qwen/manifest.js +146 -0
  230. package/dist/drivers/qwen/manifest.js.map +1 -0
  231. package/dist/drivers/registry.js +177 -0
  232. package/dist/drivers/registry.js.map +1 -0
  233. package/dist/drivers/retryPolicy.js +129 -0
  234. package/dist/drivers/retryPolicy.js.map +1 -0
  235. package/dist/drivers/searchBlocks.js +61 -0
  236. package/dist/drivers/searchBlocks.js.map +1 -0
  237. package/dist/drivers/types.js +2 -0
  238. package/dist/drivers/types.js.map +1 -0
  239. package/dist/drivers/xai/client.js +63 -0
  240. package/dist/drivers/xai/client.js.map +1 -0
  241. package/dist/drivers/xai/index.js +5 -0
  242. package/dist/drivers/xai/index.js.map +1 -0
  243. package/dist/drivers/xai/manifest.js +137 -0
  244. package/dist/drivers/xai/manifest.js.map +1 -0
  245. package/dist/dynamo/_probe.tmp.js +20 -0
  246. package/dist/dynamo/_probe.tmp.js.map +1 -0
  247. package/dist/dynamo/cacheBreak.js +88 -0
  248. package/dist/dynamo/cacheBreak.js.map +1 -0
  249. package/dist/dynamo/contextWindow.js +243 -0
  250. package/dist/dynamo/contextWindow.js.map +1 -0
  251. package/dist/dynamo/engine.js +2011 -0
  252. package/dist/dynamo/engine.js.map +1 -0
  253. package/dist/dynamo/guard.js +132 -0
  254. package/dist/dynamo/guard.js.map +1 -0
  255. package/dist/dynamo/liveMeter.js +58 -0
  256. package/dist/dynamo/liveMeter.js.map +1 -0
  257. package/dist/dynamo/model.js +172 -0
  258. package/dist/dynamo/model.js.map +1 -0
  259. package/dist/dynamo/planArtifact.js +125 -0
  260. package/dist/dynamo/planArtifact.js.map +1 -0
  261. package/dist/dynamo/pricing.js +140 -0
  262. package/dist/dynamo/pricing.js.map +1 -0
  263. package/dist/dynamo/prompt.js +264 -0
  264. package/dist/dynamo/prompt.js.map +1 -0
  265. package/dist/dynamo/spend.js +45 -0
  266. package/dist/dynamo/spend.js.map +1 -0
  267. package/dist/dynamo/verify.js +483 -0
  268. package/dist/dynamo/verify.js.map +1 -0
  269. package/dist/governor/forbidden.js +181 -0
  270. package/dist/governor/forbidden.js.map +1 -0
  271. package/dist/governor/freshness.js +83 -0
  272. package/dist/governor/freshness.js.map +1 -0
  273. package/dist/governor/frontmatter.js +38 -0
  274. package/dist/governor/frontmatter.js.map +1 -0
  275. package/dist/governor/glob.js +75 -0
  276. package/dist/governor/glob.js.map +1 -0
  277. package/dist/governor/index.js +87 -0
  278. package/dist/governor/index.js.map +1 -0
  279. package/dist/governor/rules.js +80 -0
  280. package/dist/governor/rules.js.map +1 -0
  281. package/dist/governor/scope.js +91 -0
  282. package/dist/governor/scope.js.map +1 -0
  283. package/dist/governor/skills.js +176 -0
  284. package/dist/governor/skills.js.map +1 -0
  285. package/dist/governor/types.js +16 -0
  286. package/dist/governor/types.js.map +1 -0
  287. package/dist/governor/write.js +182 -0
  288. package/dist/governor/write.js.map +1 -0
  289. package/dist/index.js +89 -0
  290. package/dist/index.js.map +1 -0
  291. package/dist/mcp/catalog.js +232 -0
  292. package/dist/mcp/catalog.js.map +1 -0
  293. package/dist/mcp/config.js +116 -0
  294. package/dist/mcp/config.js.map +1 -0
  295. package/dist/mcp/configWrite.js +254 -0
  296. package/dist/mcp/configWrite.js.map +1 -0
  297. package/dist/mcp/connection.js +504 -0
  298. package/dist/mcp/connection.js.map +1 -0
  299. package/dist/mcp/deferred.js +104 -0
  300. package/dist/mcp/deferred.js.map +1 -0
  301. package/dist/mcp/discover.js +128 -0
  302. package/dist/mcp/discover.js.map +1 -0
  303. package/dist/mcp/manager.js +679 -0
  304. package/dist/mcp/manager.js.map +1 -0
  305. package/dist/mcp/paramHeaders.js +163 -0
  306. package/dist/mcp/paramHeaders.js.map +1 -0
  307. package/dist/mcp/prompts.js +136 -0
  308. package/dist/mcp/prompts.js.map +1 -0
  309. package/dist/mcp/protocol.js +171 -0
  310. package/dist/mcp/protocol.js.map +1 -0
  311. package/dist/mcp/resources.js +119 -0
  312. package/dist/mcp/resources.js.map +1 -0
  313. package/dist/mcp/resultStore.js +180 -0
  314. package/dist/mcp/resultStore.js.map +1 -0
  315. package/dist/mcp/subscriptions.js +74 -0
  316. package/dist/mcp/subscriptions.js.map +1 -0
  317. package/dist/mcp/transport/headerValue.js +40 -0
  318. package/dist/mcp/transport/headerValue.js.map +1 -0
  319. package/dist/mcp/transport/http.js +321 -0
  320. package/dist/mcp/transport/http.js.map +1 -0
  321. package/dist/mcp/transport/stdio.js +234 -0
  322. package/dist/mcp/transport/stdio.js.map +1 -0
  323. package/dist/mcp/transport/types.js +27 -0
  324. package/dist/mcp/transport/types.js.map +1 -0
  325. package/dist/mcp/trust.js +98 -0
  326. package/dist/mcp/trust.js.map +1 -0
  327. package/dist/mcp/trustStore.js +55 -0
  328. package/dist/mcp/trustStore.js.map +1 -0
  329. package/dist/memory/autoMemory.js +340 -0
  330. package/dist/memory/autoMemory.js.map +1 -0
  331. package/dist/memory/compaction.js +513 -0
  332. package/dist/memory/compaction.js.map +1 -0
  333. package/dist/memory/images.js +173 -0
  334. package/dist/memory/images.js.map +1 -0
  335. package/dist/memory/presence.js +59 -0
  336. package/dist/memory/presence.js.map +1 -0
  337. package/dist/memory/projectNotes.js +247 -0
  338. package/dist/memory/projectNotes.js.map +1 -0
  339. package/dist/memory/restore.js +72 -0
  340. package/dist/memory/restore.js.map +1 -0
  341. package/dist/memory/session.js +472 -0
  342. package/dist/memory/session.js.map +1 -0
  343. package/dist/memory/sessionMemory.js +142 -0
  344. package/dist/memory/sessionMemory.js.map +1 -0
  345. package/dist/memory/sessionMemoryCompact.js +136 -0
  346. package/dist/memory/sessionMemoryCompact.js.map +1 -0
  347. package/dist/memory/store.js +217 -0
  348. package/dist/memory/store.js.map +1 -0
  349. package/dist/memory/types.js +14 -0
  350. package/dist/memory/types.js.map +1 -0
  351. package/dist/memory/workingSet.js +383 -0
  352. package/dist/memory/workingSet.js.map +1 -0
  353. package/dist/project/context.js +425 -0
  354. package/dist/project/context.js.map +1 -0
  355. package/dist/tools/approval.js +189 -0
  356. package/dist/tools/approval.js.map +1 -0
  357. package/dist/tools/askUser.js +103 -0
  358. package/dist/tools/askUser.js.map +1 -0
  359. package/dist/tools/atomicWrite.js +151 -0
  360. package/dist/tools/atomicWrite.js.map +1 -0
  361. package/dist/tools/backgroundShells.js +468 -0
  362. package/dist/tools/backgroundShells.js.map +1 -0
  363. package/dist/tools/captureSweep.js +77 -0
  364. package/dist/tools/captureSweep.js.map +1 -0
  365. package/dist/tools/chassisMux.js +92 -0
  366. package/dist/tools/chassisMux.js.map +1 -0
  367. package/dist/tools/checkpoints.js +328 -0
  368. package/dist/tools/checkpoints.js.map +1 -0
  369. package/dist/tools/codeIntel.js +267 -0
  370. package/dist/tools/codeIntel.js.map +1 -0
  371. package/dist/tools/deferredNative.js +121 -0
  372. package/dist/tools/deferredNative.js.map +1 -0
  373. package/dist/tools/detail.js +135 -0
  374. package/dist/tools/detail.js.map +1 -0
  375. package/dist/tools/diagnostics.js +174 -0
  376. package/dist/tools/diagnostics.js.map +1 -0
  377. package/dist/tools/edit.js +167 -0
  378. package/dist/tools/edit.js.map +1 -0
  379. package/dist/tools/editCore.js +283 -0
  380. package/dist/tools/editCore.js.map +1 -0
  381. package/dist/tools/editFile.js +183 -0
  382. package/dist/tools/editFile.js.map +1 -0
  383. package/dist/tools/editRipple.js +126 -0
  384. package/dist/tools/editRipple.js.map +1 -0
  385. package/dist/tools/editTarget.js +131 -0
  386. package/dist/tools/editTarget.js.map +1 -0
  387. package/dist/tools/editWindow.js +49 -0
  388. package/dist/tools/editWindow.js.map +1 -0
  389. package/dist/tools/eol.js +56 -0
  390. package/dist/tools/eol.js.map +1 -0
  391. package/dist/tools/exitPlan.js +175 -0
  392. package/dist/tools/exitPlan.js.map +1 -0
  393. package/dist/tools/focus.js +42 -0
  394. package/dist/tools/focus.js.map +1 -0
  395. package/dist/tools/gitignore.js +148 -0
  396. package/dist/tools/gitignore.js.map +1 -0
  397. package/dist/tools/glob.js +134 -0
  398. package/dist/tools/glob.js.map +1 -0
  399. package/dist/tools/governorTools.js +258 -0
  400. package/dist/tools/governorTools.js.map +1 -0
  401. package/dist/tools/grep.js +450 -0
  402. package/dist/tools/grep.js.map +1 -0
  403. package/dist/tools/guard.js +220 -0
  404. package/dist/tools/guard.js.map +1 -0
  405. package/dist/tools/killTree.js +215 -0
  406. package/dist/tools/killTree.js.map +1 -0
  407. package/dist/tools/listDir.js +143 -0
  408. package/dist/tools/listDir.js.map +1 -0
  409. package/dist/tools/mcpAdd.js +176 -0
  410. package/dist/tools/mcpAdd.js.map +1 -0
  411. package/dist/tools/mcpResources.js +116 -0
  412. package/dist/tools/mcpResources.js.map +1 -0
  413. package/dist/tools/mcpSearch.js +123 -0
  414. package/dist/tools/mcpSearch.js.map +1 -0
  415. package/dist/tools/multiEdit.js +168 -0
  416. package/dist/tools/multiEdit.js.map +1 -0
  417. package/dist/tools/paths.js +225 -0
  418. package/dist/tools/paths.js.map +1 -0
  419. package/dist/tools/posixShell.js +123 -0
  420. package/dist/tools/posixShell.js.map +1 -0
  421. package/dist/tools/readFile.js +371 -0
  422. package/dist/tools/readFile.js.map +1 -0
  423. package/dist/tools/readSymbol.js +145 -0
  424. package/dist/tools/readSymbol.js.map +1 -0
  425. package/dist/tools/registry.js +120 -0
  426. package/dist/tools/registry.js.map +1 -0
  427. package/dist/tools/replaceSymbol.js +141 -0
  428. package/dist/tools/replaceSymbol.js.map +1 -0
  429. package/dist/tools/results.js +15 -0
  430. package/dist/tools/results.js.map +1 -0
  431. package/dist/tools/ripgrep.js +145 -0
  432. package/dist/tools/ripgrep.js.map +1 -0
  433. package/dist/tools/runCommand.js +633 -0
  434. package/dist/tools/runCommand.js.map +1 -0
  435. package/dist/tools/saveMemory.js +102 -0
  436. package/dist/tools/saveMemory.js.map +1 -0
  437. package/dist/tools/screenshot.js +200 -0
  438. package/dist/tools/screenshot.js.map +1 -0
  439. package/dist/tools/screenshotWin.js +227 -0
  440. package/dist/tools/screenshotWin.js.map +1 -0
  441. package/dist/tools/search.js +121 -0
  442. package/dist/tools/search.js.map +1 -0
  443. package/dist/tools/sessionTools.js +187 -0
  444. package/dist/tools/sessionTools.js.map +1 -0
  445. package/dist/tools/shellCheckpoint.js +123 -0
  446. package/dist/tools/shellCheckpoint.js.map +1 -0
  447. package/dist/tools/shellLint.js +102 -0
  448. package/dist/tools/shellLint.js.map +1 -0
  449. package/dist/tools/shellTools.js +203 -0
  450. package/dist/tools/shellTools.js.map +1 -0
  451. package/dist/tools/spanCore.js +78 -0
  452. package/dist/tools/spanCore.js.map +1 -0
  453. package/dist/tools/subagent.js +224 -0
  454. package/dist/tools/subagent.js.map +1 -0
  455. package/dist/tools/subagentReport.js +114 -0
  456. package/dist/tools/subagentReport.js.map +1 -0
  457. package/dist/tools/tempSweep.js +118 -0
  458. package/dist/tools/tempSweep.js.map +1 -0
  459. package/dist/tools/todo.js +117 -0
  460. package/dist/tools/todo.js.map +1 -0
  461. package/dist/tools/types.js +2 -0
  462. package/dist/tools/types.js.map +1 -0
  463. package/dist/tools/untrusted.js +46 -0
  464. package/dist/tools/untrusted.js.map +1 -0
  465. package/dist/tools/useSkill.js +62 -0
  466. package/dist/tools/useSkill.js.map +1 -0
  467. package/dist/tools/walk.js +152 -0
  468. package/dist/tools/walk.js.map +1 -0
  469. package/dist/tools/web.js +61 -0
  470. package/dist/tools/web.js.map +1 -0
  471. package/dist/tools/webFetch.js +444 -0
  472. package/dist/tools/webFetch.js.map +1 -0
  473. package/dist/tools/webSearch.js +130 -0
  474. package/dist/tools/webSearch.js.map +1 -0
  475. package/dist/tools/workspace.js +212 -0
  476. package/dist/tools/workspace.js.map +1 -0
  477. package/dist/tools/workspaceDiscover.js +216 -0
  478. package/dist/tools/workspaceDiscover.js.map +1 -0
  479. package/dist/tools/writeFile.js +162 -0
  480. package/dist/tools/writeFile.js.map +1 -0
  481. package/package.json +74 -28
@@ -0,0 +1,472 @@
1
+ /**
2
+ * session.ts — create a fresh session or resume a saved one.
3
+ *
4
+ * A `Session` bundles the transcript, the tool context (live cwd + read ledger),
5
+ * and the project memory. This is the client-side init that does the disk reads
6
+ * (MINDWEAVE.md, a saved transcript); the engine receives a ready Session and never
7
+ * touches the filesystem itself.
8
+ */
9
+ import { promises as fs, existsSync } from "node:fs";
10
+ import { randomUUID } from "node:crypto";
11
+ import { resolvePath, nextTouch, canonicalRoot } from "../tools/paths.js";
12
+ import { latestSession, listSessions, loadMeta, loadTranscript, loadSessionNotes } from "./store.js";
13
+ import { startChassis } from "../alternator/lane.js";
14
+ import { BackgroundShells } from "../tools/backgroundShells.js";
15
+ import { Checkpoints } from "../tools/checkpoints.js";
16
+ import { projectContextText } from "../project/context.js";
17
+ import { loadGovernance, governanceStamp } from "../governor/index.js";
18
+ import { createRuleScope } from "../governor/scope.js";
19
+ import { loadModelConfig } from "../dynamo/model.js";
20
+ import { ensureMemoryDir, loadMemoryIndex, memoryDir } from "./autoMemory.js";
21
+ import { loadMcpConfig } from "../mcp/config.js";
22
+ import { McpManager } from "../mcp/manager.js";
23
+ import { assembleNotes } from "./projectNotes.js";
24
+ /**
25
+ * Read the project's notes: MINDWEAVE.md, the user's own, and everything they import.
26
+ *
27
+ * The layers and their rules live in projectNotes.ts. This is only the seam the
28
+ * session uses, kept as a single string because that is what the cached prefix takes.
29
+ */
30
+ async function loadProjectMemory(cwd) {
31
+ return (await assembleNotes(cwd)).text;
32
+ }
33
+ /**
34
+ * Re-read MINDWEAVE.md into the live session, but only when it is FREE to do so.
35
+ *
36
+ * The model maintains MINDWEAVE.md, so it edits the file mid-session; `projectMemory`
37
+ * is frozen into the cached system prompt at session start. Re-reading it every turn
38
+ * kept the two in step, at a price that turned out to be the single most expensive
39
+ * line in prompt assembly: changing the system prompt string invalidates the WHOLE
40
+ * cached prefix — base prompt, tool schemas, project snapshot, governance — and the
41
+ * next request pays a full cache rewrite at 1.25x normal input rate. One edit to a
42
+ * small markdown file re-billed everything.
43
+ *
44
+ * The codebase already knew this hazard: standing rules were deliberately moved OUT of
45
+ * the cached prefix precisely so a mid-session remember_rule could not bust it. This
46
+ * does the same thing for the same reason.
47
+ *
48
+ * Serving the frozen copy is safe because of where the fresh copy already is. The model
49
+ * that just edited MINDWEAVE.md has the new content in its own transcript — it wrote it
50
+ * — so nothing is hidden from it. The frozen prefix is only how the NEXT session starts,
51
+ * and it refreshes at points where the cache is being thrown away regardless: after a
52
+ * compaction (which rewrites the transcript, taking the edit with it), and at session
53
+ * start.
54
+ */
55
+ export async function reloadProjectMemory(session, opts = {}) {
56
+ if (!opts.force && !session.projectMemoryStale)
57
+ return;
58
+ session.projectMemory = await loadProjectMemory(session.cwd);
59
+ session.projectMemoryStale = false;
60
+ }
61
+ /**
62
+ * Attach the MCP server pool to a session.
63
+ *
64
+ * Deliberately NOT awaited. Servers are third-party processes and a slow one would sit
65
+ * between the user pressing enter and the first paint, so the pool comes up in the
66
+ * background and its tools appear once they are ready. Failures are already states
67
+ * rather than exceptions, so nothing here can reject; the `catch` is belt and braces.
68
+ *
69
+ * The cost of not awaiting is that a server landing mid-session changes the tool list
70
+ * and invalidates the cached prompt prefix. That cost is real and it is NOT designed
71
+ * away: tool schemas are a structural API field rendered before every provider's cache
72
+ * breakpoint, so there is no volatile tail to move them into (docs/mcp-plan.md §6, which
73
+ * corrects an earlier claim that there was). What Phase 3 actually bought is a stable
74
+ * catalog and one frozen snapshot per turn, so the cost lands once per real change
75
+ * instead of once per turn — which is cheap enough that the fast start is worth keeping.
76
+ */
77
+ function attachMcp(ctx, cwd) {
78
+ const manager = new McpManager();
79
+ ctx.mcp = manager;
80
+ // Before anything connects: a tool can be dispatched as soon as its server is up, and
81
+ // spilled results have to land in this project's state dir rather than wherever the
82
+ // process happened to start.
83
+ manager.setProjectRoot(cwd);
84
+ void loadMcpConfig(cwd)
85
+ .then(async (configs) => {
86
+ await manager.start(configs);
87
+ // Governance is applied AFTER connecting, because both gates are about the tools
88
+ // a server actually turned out to advertise: a forbidden name only matters once
89
+ // it exists, and a changed description can only be noticed against a live one.
90
+ manager.setForbidden(ctx.governance?.forbidden.mcpTools ?? []);
91
+ // Rug-pull check. `requestApproval` may not be attached yet (the CLI wires it
92
+ // just after session creation), in which case `verifyTrust` fails closed and
93
+ // changed tools stay blocked until the next session — the safe direction.
94
+ await manager.verifyTrust(cwd, ctx.requestApproval);
95
+ })
96
+ .catch(() => { });
97
+ }
98
+ /**
99
+ * Seed the read-ledger with MINDWEAVE.md when it exists on disk, so the model can UPDATE
100
+ * the project's own memory file without a redundant read_file first. MINDWEAVE.md's content
101
+ * is already loaded into the system prompt (projectMemory), so the read-before-edit gate
102
+ * would otherwise trip on a file the model effectively already has — surfacing the
103
+ * confusing "MINDWEAVE.md has not been read this session" error on routine housekeeping.
104
+ * Keyed via resolvePath so it matches exactly what the edit gate looks up. Recorded
105
+ * full:false (the model works from a window, never a held whole-file copy) so it can
106
+ * never wrongly short-circuit a genuine read_file. Best-effort; no MINDWEAVE.md => no-op.
107
+ */
108
+ async function seedProjectMemoryRead(ctx, projectMemory) {
109
+ if (!projectMemory)
110
+ return;
111
+ const abs = resolvePath(ctx, "MINDWEAVE.md");
112
+ try {
113
+ const st = await fs.stat(abs);
114
+ ctx.reads.set(abs, { mtimeMs: st.mtimeMs, size: st.size, full: false, touchedAt: nextTouch() });
115
+ }
116
+ catch {
117
+ // No MINDWEAVE.md on disk — nothing to seed.
118
+ }
119
+ }
120
+ /** Ensure the memory dir exists (so the model never mkdirs) and read its index. */
121
+ async function loadMemory(cwd) {
122
+ await ensureMemoryDir(cwd);
123
+ return loadMemoryIndex(cwd);
124
+ }
125
+ function freshToolContext(cwd, governance, roots) {
126
+ // Start the alternator: one code map per root warms up in the background while
127
+ // the session is already usable. The forbidden config + skill catalog come from
128
+ // the governor so the tools can enforce/invoke them.
129
+ const chassisByRoot = new Map(roots.map((root) => [root, startChassis(root)]));
130
+ return {
131
+ cwd,
132
+ roots,
133
+ reads: new Map(),
134
+ chassis: chassisByRoot.get(cwd), // the primary root's map (drives the auto-map)
135
+ chassisByRoot,
136
+ backgroundShells: new BackgroundShells(),
137
+ checkpoints: new Checkpoints(),
138
+ todos: [],
139
+ // Deferred tools the model has surfaced via find_tools become callable from then on
140
+ // (registry.toolSchemas). Empty at start; grows as the model searches; restored from
141
+ // meta on resume.
142
+ activatedTools: new Set(),
143
+ // Same governance object as Session.governance — shared so mid-session edits
144
+ // (a new rule, a new forbidden path) are visible to both the tools and the
145
+ // engine's prompt without a reload.
146
+ governance,
147
+ // Which glob-scoped rules this session has activated. Filled as paths are touched
148
+ // (governor/scope.ts) rather than re-derived on every model call.
149
+ ruleScope: createRuleScope(),
150
+ };
151
+ }
152
+ /** The framing prepended to a sub-agent's task — it works alone and reports back. */
153
+ const SUBAGENT_PREAMBLE = "You are a focused sub-agent spawned by the main Mindweave agent to complete ONE task and report back. " +
154
+ "Work autonomously with your tools — you cannot ask the user questions, and you do not see the main " +
155
+ "conversation, so rely only on the task below. Do EXACTLY what it asks and stay inside its boundaries — " +
156
+ "don't widen the scope, and don't change files the task didn't name. Stop as soon as the objective is met " +
157
+ "rather than exploring further. When finished, reply with a DISTILLED result — the answer the main agent " +
158
+ "needs, with concrete file:line references, and nothing else (no play-by-play). If the task specifies an " +
159
+ "output format, follow it exactly. Keep it tight (aim for well under a page): the main agent sees only " +
160
+ "your final message, not your intermediate steps.\n\nTask:\n";
161
+ /**
162
+ * A scoped child session for a sub-agent. It gets its OWN transcript (seeded with
163
+ * the task) and its OWN read ledger + todo list, so its work is isolated and never
164
+ * pollutes the parent's working set. It SHARES the parent's code map, checkpoints
165
+ * (so its edits are undoable too) and governance by reference — everything the parent
166
+ * already stood up. What it does NOT get is anything the user granted in person: the
167
+ * approval channel, session permission grants, and the parent's approved plan all stop
168
+ * here. Only the child's final reply crosses back to the parent, through the spawn tool.
169
+ */
170
+ export function forkSession(parent, task, opts = {}) {
171
+ const p = parent.toolContext;
172
+ const id = randomUUID();
173
+ const childContext = {
174
+ ...p,
175
+ reads: new Map(),
176
+ todos: [],
177
+ // Its OWN activation set, seeded with the parent's so it can call what is already
178
+ // active. Without the copy the spread would share the parent's Set by reference, and a
179
+ // sub-agent's find_tools would silently change the parent's advertised list.
180
+ activatedTools: new Set(p.activatedTools),
181
+ // Its own id, not the parent's. The spread carries `sessionId`, so a child asking
182
+ // "which conversation am I?" answered with the parent's — harmless while nothing
183
+ // writes session-scoped state from a child, and wrong the moment something does.
184
+ sessionId: id,
185
+ subagentDepth: (p.subagentDepth ?? 0) + 1,
186
+ readOnlyTools: opts.readOnly === true ? true : p.readOnlyTools,
187
+ // CLEARED, not inherited. This line used to copy the parent's value under a
188
+ // comment claiming it cleared it, and the engine's gate is
189
+ // `guarded && !guardAllowed.has(tool)` — so an inherited grant skipped the check
190
+ // outright. Combined with the missing approval channel below, a sub-agent the user
191
+ // never saw start could edit files with no prompt at all, while SECURITY.md
192
+ // promised Sentinel "covers every tool including sub-agent edits".
193
+ //
194
+ // "Allow all" is a judgement the user made about work they could see. It does not
195
+ // transfer to an agent they did not know would run. A guarded child has no channel
196
+ // to ask through, so its mutating tools are refused and it reports back instead —
197
+ // which is the failing direction to pick.
198
+ guardAllowed: undefined,
199
+ // Cleared for the same reason, and it was missed when this one was added: a folder
200
+ // the user allowed writing to is a judgement about work they were watching. Claude
201
+ // Code draws the identical line when it scopes a child — it keeps the permissions
202
+ // given on the command line and clears the SESSION ones, "to prevent unintended
203
+ // leakage".
204
+ allowedOutsideDirs: undefined,
205
+ // The parent's approved plan is NOT the child's work. Two things go wrong when it
206
+ // rides along: the child is handed a binding instruction to follow a plan it was not
207
+ // spawned for, on top of the one task it was given — and because a child runs the
208
+ // same turn loop, its turn ending settles that plan, marking the artifact DONE on
209
+ // disk while the parent is still in the middle of carrying it out.
210
+ //
211
+ // Empty string, not undefined: undefined means "not looked for yet" and would send
212
+ // the child to load the plan straight back off disk.
213
+ activePlan: "",
214
+ activePlanApprovedAt: undefined,
215
+ // A child CANNOT reach the user. The spread above inherited the parent's approval
216
+ // channel, so `ask_user` (which is read-only, and therefore offered even to a
217
+ // read-only child) put a question on screen from an agent the user never saw start
218
+ // — and a parallel fan-out could stack several, none of them attributable. It also
219
+ // made spawn_subagent's own briefing advice false: "write a COMPLETE, standalone
220
+ // task" only holds if the child truly cannot come back and ask.
221
+ // Every consumer of this channel already degrades correctly without it: ask_user
222
+ // tells the child to assume a sensible default and state it, and the guards fail
223
+ // closed. The child's findings reach the user through its result, where the parent
224
+ // can weigh them.
225
+ requestApproval: undefined,
226
+ };
227
+ return {
228
+ ...parent,
229
+ id,
230
+ createdAt: Date.now(),
231
+ transcript: [{ role: "user", content: SUBAGENT_PREAMBLE + task }],
232
+ toolContext: childContext,
233
+ };
234
+ }
235
+ /** A brand-new session rooted at `cwd` (defaults to the process cwd). */
236
+ /**
237
+ * A brand-new session.
238
+ *
239
+ * `carryRoots` is for starting over WITHOUT losing the workspace: `/clear` builds a
240
+ * fresh session in the same folder, and the folders someone added with `/include` or
241
+ * `/link` belong to the folder they are working in, not to the conversation they just
242
+ * ended. Dropping them was silent — every tool quietly narrowed to one root and
243
+ * nothing said so. Missing folders are filtered and the primary is de-duplicated, the
244
+ * same way `resumeSession` treats the roots it restores.
245
+ */
246
+ export async function createSession(rawCwd = process.cwd(), carryRoots = []) {
247
+ // Canonicalise the root ONCE, here, before anything derives from it. run_command
248
+ // reports where it ended up as a physical path, and on macOS a great deal sits
249
+ // behind symlinks (/tmp, and all of os.tmpdir()), so a session opened at a logical
250
+ // path would compare unequal to its own cwd after the first command. See
251
+ // canonicalRoot. Doing it at the single point of entry is what keeps every root,
252
+ // every recorded cwd, and every relativized path speaking the same form.
253
+ const cwd = await canonicalRoot(rawCwd);
254
+ const [projectMemory, memoryIndex, projectContext, governance, stamp, modelConfig, earlier] = await Promise.all([
255
+ loadProjectMemory(cwd),
256
+ loadMemory(cwd),
257
+ projectContextText(cwd),
258
+ loadGovernance(cwd),
259
+ governanceStamp(cwd),
260
+ loadModelConfig(cwd),
261
+ listSessions(cwd),
262
+ ]);
263
+ const id = randomUUID();
264
+ // Canonicalised BEFORE comparing. `cwd` has already been through canonicalRoot, so a
265
+ // raw string comparison misses the primary root arriving in another spelling — an 8.3
266
+ // short path, a symlinked temp directory, different drive-letter case — and adds it a
267
+ // second time. CI caught exactly that: its temp directory canonicalises differently
268
+ // from the path handed in, so the workspace came back with the same folder twice.
269
+ const carried = await Promise.all(carryRoots.map((r) => canonicalRoot(r)));
270
+ const seenRoot = new Set([cwd]);
271
+ const extra = carried.filter((r) => {
272
+ if (seenRoot.has(r) || !existsSync(r))
273
+ return false;
274
+ seenRoot.add(r);
275
+ return true;
276
+ });
277
+ const toolContext = freshToolContext(cwd, governance, [cwd, ...extra]);
278
+ // So the session tools can exclude this conversation from "your past sessions".
279
+ toolContext.sessionId = id;
280
+ attachMcp(toolContext, cwd);
281
+ await seedProjectMemoryRead(toolContext, projectMemory);
282
+ return {
283
+ id,
284
+ cwd,
285
+ createdAt: Date.now(),
286
+ transcript: [],
287
+ toolContext,
288
+ projectMemory,
289
+ memoryDir: memoryDir(cwd),
290
+ memoryIndex,
291
+ // Everything already saved predates this brand-new session.
292
+ priorSessions: earlier.length,
293
+ projectContext,
294
+ governance,
295
+ // Stamped at load so the first turn's freshness check settles instead of reloading
296
+ // what was just read. See governor/freshness.ts.
297
+ governanceStamp: stamp,
298
+ modelConfig,
299
+ };
300
+ }
301
+ /**
302
+ * Resume the most recent saved session for `cwd` (or a specific `id`), returning
303
+ * a live Session with its transcript loaded. Returns null when there's nothing
304
+ * to resume. The tool context starts fresh — the model re-reads files before it
305
+ * edits them (that's the read-before-edit contract), so a resumed session simply
306
+ * re-reads as needed rather than trusting a stale ledger.
307
+ */
308
+ /**
309
+ * Repair a transcript that was cut off mid-tool. If the session was closed between the
310
+ * model issuing tool calls and their results being recorded (PC shutdown, force-kill,
311
+ * crash), some `tool_calls` have no matching `tool` result — which the provider rejects
312
+ * (breaking /continue) and which hides that the tool never finished. For every
313
+ * unanswered call we insert a synthetic result, right after its assistant message so the
314
+ * tool group stays contiguous, marking it interrupted so the model re-checks the real
315
+ * state before trusting or repeating it. Pure; returns a new array (unchanged if nothing
316
+ * was dangling). Exported for tests.
317
+ */
318
+ /**
319
+ * Move anything that got wedged BETWEEN a `tool_calls` message and its results back
320
+ * out to after them. Pure; returns a new array (unchanged when nothing is stranded).
321
+ *
322
+ * Providers require a message carrying `tool_calls` to be followed immediately by one
323
+ * `tool` message per call. A build of Mindweave briefly appended its narration nudge
324
+ * the moment it judged the fault — right after the assistant message and before any
325
+ * result — so sessions written in that window hold a permanently invalid order and
326
+ * every resume of one dies on the first request:
327
+ *
328
+ * assistant(tool_calls) → user(nudge) → tool → tool ← rejected
329
+ * assistant(tool_calls) → tool → tool → user(nudge) ← what it should be
330
+ *
331
+ * The engine no longer produces this, but a fix that only stops NEW corruption leaves
332
+ * the already-saved sessions unopenable, and those hold the user's actual work. The
333
+ * stranded message is MOVED rather than dropped: it may be something the person typed,
334
+ * and repair is not a licence to lose it.
335
+ */
336
+ export function repairToolCallOrder(transcript) {
337
+ const out = [];
338
+ let moved = false;
339
+ let i = 0;
340
+ while (i < transcript.length) {
341
+ const entry = transcript[i];
342
+ out.push(entry);
343
+ i++;
344
+ if (entry.role !== "assistant" || !entry.toolCalls?.length)
345
+ continue;
346
+ const owed = new Set(entry.toolCalls.map((c) => c.id));
347
+ const results = [];
348
+ const stranded = [];
349
+ // Walk forward while results are still outstanding, keeping them in order and
350
+ // setting aside anything that does not belong inside the group. A new assistant
351
+ // message means the group was abandoned — stop and let reconcile fill the gaps.
352
+ while (i < transcript.length && owed.size > 0) {
353
+ const next = transcript[i];
354
+ if (next.role === "assistant")
355
+ break;
356
+ if (next.role === "tool" && owed.has(next.toolCallId)) {
357
+ owed.delete(next.toolCallId);
358
+ results.push(next);
359
+ }
360
+ else {
361
+ stranded.push(next);
362
+ moved = true;
363
+ }
364
+ i++;
365
+ }
366
+ out.push(...results, ...stranded);
367
+ }
368
+ return moved ? out : transcript;
369
+ }
370
+ export function reconcileInterruptedTools(transcript) {
371
+ const answered = new Set();
372
+ for (const e of transcript)
373
+ if (e.role === "tool")
374
+ answered.add(e.toolCallId);
375
+ let repaired = false;
376
+ const out = [];
377
+ for (const e of transcript) {
378
+ out.push(e);
379
+ if (e.role === "assistant" && e.toolCalls?.length) {
380
+ for (const call of e.toolCalls) {
381
+ if (answered.has(call.id))
382
+ continue;
383
+ answered.add(call.id); // guard against a (malformed) duplicate id
384
+ repaired = true;
385
+ out.push({
386
+ role: "tool",
387
+ toolCallId: call.id,
388
+ content: `[interrupted] '${call.name}' did not finish — the session was closed before this tool ` +
389
+ `returned, so its effect on disk/state is unknown. Re-check the current state (files, ` +
390
+ `processes, installs) before relying on it or running it again.`,
391
+ summary: `${call.name} — interrupted (session closed)`,
392
+ isError: true,
393
+ });
394
+ }
395
+ }
396
+ }
397
+ return repaired ? out : transcript;
398
+ }
399
+ export async function resumeSession(cwd = process.cwd(), id) {
400
+ const meta = id ? await loadMeta(cwd, id) : await latestSession(cwd);
401
+ if (!meta)
402
+ return null;
403
+ const loaded = await loadTranscript(cwd, meta.id);
404
+ if (!loaded || loaded.length === 0)
405
+ return null;
406
+ // A session closed mid-tool (PC shutdown, force-kill) leaves the model's tool_calls
407
+ // with no results — invalid to replay and silent about what didn't finish. Repair it
408
+ // so /continue resumes cleanly and the model re-checks the interrupted step.
409
+ // Order first, then fill gaps: reconcile inserts results right after their assistant
410
+ // message, so it must see a group that is already contiguous.
411
+ const transcript = reconcileInterruptedTools(repairToolCallOrder(loaded));
412
+ const [projectMemory, memoryIndex, projectContext, governance, stamp, modelConfig, sessionMemory, saved] = await Promise.all([
413
+ loadProjectMemory(cwd),
414
+ loadMemory(cwd),
415
+ projectContextText(cwd),
416
+ loadGovernance(cwd),
417
+ governanceStamp(cwd),
418
+ loadModelConfig(cwd),
419
+ loadSessionNotes(cwd, meta.id),
420
+ listSessions(cwd),
421
+ ]);
422
+ // Restore any added roots that still exist on disk (primary first).
423
+ const extra = (meta.extraRoots ?? []).filter((r) => existsSync(r));
424
+ const roots = [cwd, ...extra];
425
+ const toolContext = freshToolContext(cwd, governance, roots);
426
+ // Undo history is in-memory, so a resumed session starts with none even though the
427
+ // earlier turns really did change files. Marking it lets /undo explain that rather
428
+ // than claim nothing has happened.
429
+ toolContext.checkpoints?.noteResumed();
430
+ toolContext.sessionId = meta.id;
431
+ // Re-advertise the deferred tools this session had already surfaced, so a continued
432
+ // session keeps them callable instead of stripping a tool the model was mid-use of.
433
+ if (meta.activatedTools && meta.activatedTools.length > 0) {
434
+ toolContext.activatedTools = new Set(meta.activatedTools);
435
+ }
436
+ attachMcp(toolContext, cwd);
437
+ await seedProjectMemoryRead(toolContext, projectMemory);
438
+ return {
439
+ id: meta.id,
440
+ cwd,
441
+ createdAt: meta.createdAt ?? Date.now(),
442
+ transcript,
443
+ toolContext,
444
+ projectMemory,
445
+ memoryDir: memoryDir(cwd),
446
+ memoryIndex,
447
+ // The session being resumed is not "prior" to itself.
448
+ priorSessions: Math.max(0, saved.filter((m) => m.id !== meta.id).length),
449
+ projectContext,
450
+ governance,
451
+ // Stamped at load so the first turn's freshness check settles instead of reloading
452
+ // what was just read. See governor/freshness.ts.
453
+ governanceStamp: stamp,
454
+ modelConfig,
455
+ // The maintained session notes survive a resume, so a continued session keeps its
456
+ // crisp running state. The watermark starts fresh; it'll refresh as it grows again.
457
+ ...(sessionMemory ? { sessionMemory, sessionMemoryInit: true } : {}),
458
+ // What the session has already cost, and the per-call detail behind it.
459
+ //
460
+ // Restored, not restarted. Leaving these out did not merely forget the earlier
461
+ // turns — the next save OVERWRITES the meta file, so a resumed session replaced a
462
+ // true running total with a smaller one and the earlier spend was gone for good. A
463
+ // session's cost is the cost of the whole session; `/continue` is not a new session.
464
+ //
465
+ // Deliberately unlike `prefixPrint`, which is NOT restored: that one asserts the
466
+ // provider still holds a cache, and after a resume it does not. These are records of
467
+ // what happened, and what happened does not stop being true.
468
+ ...(meta.spend ? { spend: meta.spend } : {}),
469
+ ...(meta.callLog ? { callLog: meta.callLog } : {}),
470
+ };
471
+ }
472
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/memory/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ import { estimateEntriesTokens, estimateTokens, formatTranscriptForSummary } from "./compaction.js";
2
+ import { activeDriver } from "../drivers/registry.js";
3
+ const env = (name, fallback) => {
4
+ const v = Number(process.env[name]);
5
+ return Number.isFinite(v) && v > 0 ? v : fallback;
6
+ };
7
+ /**
8
+ * First update once the transcript passes this (let a session warm up first).
9
+ *
10
+ * Deliberately LOW. At 10K a session could do a whole piece of real work and end
11
+ * having never written a note, so a later `read_session` found nothing and fell back
12
+ * to the raw transcript — a worse answer, for more tokens, after an extra round trip.
13
+ * The bar only exists so a two-message session doesn't pay for a model call; 4K is
14
+ * enough warm-up for that and cheap enough that ordinary sessions get real notes.
15
+ */
16
+ const INIT_THRESHOLD = env("MINDWEAVE_SESSION_MEMORY_INIT", 4_000);
17
+ /** Refresh the notes after this much further growth (token-gated). */
18
+ const UPDATE_THRESHOLD = env("MINDWEAVE_SESSION_MEMORY_UPDATE", 12_000);
19
+ /** How many recent transcript entries feed an update (the notes carry the older state). */
20
+ const RECENT_ENTRIES = env("MINDWEAVE_SESSION_MEMORY_RECENT", 40);
21
+ /** Hard cap on the notes so they can't themselves bloat context (~12K tokens total,
22
+ * ~2K per section). */
23
+ export const SESSION_MEMORY_MAX_TOKENS = env("MINDWEAVE_SESSION_MEMORY_MAX_TOKENS", 12_000);
24
+ /** Per-section soft budget — condense a section past this (~2K/section). */
25
+ export const SESSION_MEMORY_SECTION_TOKENS = env("MINDWEAVE_SESSION_MEMORY_SECTION_TOKENS", 2_000);
26
+ /** The structured skeleton the model fills in and keeps current. The
27
+ * italic _descriptions_ are template instructions (kept intact); the model only fills
28
+ * the content beneath each. "Current State" is first-class: it's what lets the model
29
+ * pick up cleanly after a compaction. */
30
+ export const SESSION_MEMORY_TEMPLATE = `# Session Title
31
+ _A short and distinctive 5-10 word descriptive title for the session. Super info dense, no filler_
32
+
33
+ # Current State
34
+ _What is actively being worked on right now? Pending tasks not yet completed. Immediate next steps._
35
+
36
+ # Task specification
37
+ _What did the user ask to build? Any design decisions or other explanatory context_
38
+
39
+ # Files and Functions
40
+ _What are the important files? In short, what do they contain and why are they relevant?_
41
+
42
+ # Workflow
43
+ _What commands are usually run and in what order? How to interpret their output if not obvious?_
44
+
45
+ # Errors & Corrections
46
+ _Errors encountered and how they were fixed. What did the user correct? What approaches failed and should not be tried again?_
47
+
48
+ # Codebase and System Documentation
49
+ _What are the important system components? How do they work/fit together?_
50
+
51
+ # Learnings
52
+ _What has worked well? What has not? What to avoid? Do not duplicate items from other sections_
53
+
54
+ # Key results
55
+ _If the user asked a specific output such as an answer to a question, a table, or other document, repeat the exact result here_
56
+
57
+ # Worklog
58
+ _Step by step, what was attempted, done? Very terse summary for each step_`;
59
+ const UPDATE_SYSTEM = "You maintain a running notes document that captures the live state of a software " +
60
+ "engineering session, so work can continue seamlessly across context compaction. You " +
61
+ "will be given the CURRENT notes and the RECENT conversation. Return the COMPLETE updated " +
62
+ "notes document. Rules:\n" +
63
+ "- Keep EVERY section header exactly, and keep the italic _description_ line under each " +
64
+ "header intact (those are template instructions, not content) — only update the content " +
65
+ "beneath them.\n" +
66
+ "- Fold new activity into the right sections; write DENSE, specific content (file paths, " +
67
+ "function names, exact commands, error messages, decisions).\n" +
68
+ `- Keep each section under ~${SESSION_MEMORY_SECTION_TOKENS} tokens: when one grows past that, ` +
69
+ "CYCLE OUT the least important details while preserving the most critical.\n" +
70
+ "- Leave a section unchanged if there's nothing substantial to add (no filler like 'N/A').\n" +
71
+ "- ALWAYS keep 'Current State' accurate to the latest turn — it's what continues the work " +
72
+ "after compaction.\n" +
73
+ "Output ONLY the notes document — no preamble, no commentary, no code fences.";
74
+ const UPDATE_REQUEST = "Update the notes with anything new from the recent conversation, then output the full " +
75
+ "updated notes document (same section headers and italic descriptions, dense, concise).";
76
+ /**
77
+ * Whether to refresh the notes now (pure). The token threshold is ALWAYS the gate,
78
+ * so updates don't fire too often; before the first update we wait for the
79
+ * session to warm past the init bar.
80
+ */
81
+ export function shouldUpdateSessionMemory(currentTokens, lastUpdateTokens, initialized) {
82
+ if (!initialized)
83
+ return currentTokens >= INIT_THRESHOLD;
84
+ return currentTokens - lastUpdateTokens >= UPDATE_THRESHOLD;
85
+ }
86
+ /** The injected block (volatile tail — it changes as it's refreshed, so it must NOT
87
+ * sit in the cached prefix). "" when there are no notes yet. */
88
+ export function renderSessionMemory(notes) {
89
+ const trimmed = notes.trim();
90
+ if (!trimmed)
91
+ return "";
92
+ return ("Your maintained notes on THIS session's state (kept current across compaction — " +
93
+ "trust these for what's done, what's in flight, and what already failed):\n" +
94
+ `<session_memory>\n${trimmed}\n</session_memory>`);
95
+ }
96
+ /** Keep the notes under budget: if the model over-produces, trim to the cap (pure). */
97
+ export function boundSessionMemory(notes, maxTokens = SESSION_MEMORY_MAX_TOKENS) {
98
+ if (estimateTokens(notes) <= maxTokens)
99
+ return notes;
100
+ const maxChars = Math.floor(maxTokens * 3.5);
101
+ return notes.slice(0, maxChars).trimEnd() + "\n\n(notes truncated to stay within budget)";
102
+ }
103
+ /**
104
+ * Refresh the session notes from the recent transcript (one cheap model call, thinking
105
+ * off). Mutates `session.sessionMemory` + the token watermark IN MEMORY only — the CLI
106
+ * persists the notes file, keeping the engine filesystem-pure. Degrade-safe: on any
107
+ * failure the previous notes are kept untouched.
108
+ */
109
+ export async function updateSessionMemory(session) {
110
+ const recent = session.transcript.slice(-RECENT_ENTRIES);
111
+ if (recent.length === 0)
112
+ return false;
113
+ const current = session.sessionMemory?.trim() || SESSION_MEMORY_TEMPLATE;
114
+ try {
115
+ const { content } = await activeDriver().toolTurn({
116
+ system: UPDATE_SYSTEM,
117
+ messages: [
118
+ {
119
+ role: "user",
120
+ content: `CURRENT NOTES:\n${current}\n\n` +
121
+ `RECENT CONVERSATION:\n${formatTranscriptForSummary(recent)}\n\n${UPDATE_REQUEST}`,
122
+ },
123
+ ],
124
+ model: { ...session.modelConfig, thinking: false },
125
+ });
126
+ const notes = content.trim();
127
+ if (!notes)
128
+ return false;
129
+ session.sessionMemory = boundSessionMemory(notes);
130
+ session.sessionMemoryTokens = estimateEntriesTokens(session.transcript);
131
+ // The boundary compaction-from-notes splits on: everything up to here is written
132
+ // down, everything after it has to be kept verbatim. Recorded at the same moment
133
+ // as the notes so the two can never describe different transcripts.
134
+ session.sessionMemoryEntries = session.transcript.length;
135
+ session.sessionMemoryInit = true;
136
+ return true;
137
+ }
138
+ catch {
139
+ return false; // keep the last good notes
140
+ }
141
+ }
142
+ //# sourceMappingURL=sessionMemory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionMemory.js","sourceRoot":"","sources":["../../src/memory/sessionMemory.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAU,EAAE;IACrD,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpD,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,cAAc,GAAG,GAAG,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;AACnE,sEAAsE;AACtE,MAAM,gBAAgB,GAAG,GAAG,CAAC,iCAAiC,EAAE,MAAM,CAAC,CAAC;AACxE,2FAA2F;AAC3F,MAAM,cAAc,GAAG,GAAG,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;AAClE;wBACwB;AACxB,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC,qCAAqC,EAAE,MAAM,CAAC,CAAC;AAC5F,4EAA4E;AAC5E,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;AAEnG;;;0CAG0C;AAC1C,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;2EA4BoC,CAAC;AAE5E,MAAM,aAAa,GACjB,mFAAmF;IACnF,sFAAsF;IACtF,2FAA2F;IAC3F,0BAA0B;IAC1B,yFAAyF;IACzF,yFAAyF;IACzF,iBAAiB;IACjB,0FAA0F;IAC1F,+DAA+D;IAC/D,8BAA8B,6BAA6B,qCAAqC;IAChG,6EAA6E;IAC7E,6FAA6F;IAC7F,2FAA2F;IAC3F,qBAAqB;IACrB,8EAA8E,CAAC;AAEjF,MAAM,cAAc,GAClB,wFAAwF;IACxF,wFAAwF,CAAC;AAE3F;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,aAAqB,EACrB,gBAAwB,EACxB,WAAoB;IAEpB,IAAI,CAAC,WAAW;QAAE,OAAO,aAAa,IAAI,cAAc,CAAC;IACzD,OAAO,aAAa,GAAG,gBAAgB,IAAI,gBAAgB,CAAC;AAC9D,CAAC;AAED;iEACiE;AACjE,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,OAAO,CACL,kFAAkF;QAClF,4EAA4E;QAC5E,qBAAqB,OAAO,qBAAqB,CAClD,CAAC;AACJ,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,YAAoB,yBAAyB;IAC7F,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,SAAS;QAAE,OAAO,KAAK,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,OAAO,EAAE,GAAG,6CAA6C,CAAC;AAC5F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAgB;IACxD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAC;IACzD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,uBAAuB,CAAC;IACzE,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC,QAAQ,CAAC;YAChD,MAAM,EAAE,aAAa;YACrB,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EACL,mBAAmB,OAAO,MAAM;wBAChC,yBAAyB,0BAA0B,CAAC,MAAM,CAAC,OAAO,cAAc,EAAE;iBACrF;aACF;YACD,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE;SACnD,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,OAAO,CAAC,aAAa,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAClD,OAAO,CAAC,mBAAmB,GAAG,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACxE,iFAAiF;QACjF,iFAAiF;QACjF,oEAAoE;QACpE,OAAO,CAAC,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;QACzD,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,2BAA2B;IAC3C,CAAC;AACH,CAAC"}