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,279 @@
1
+ /**
2
+ * bootstrap.ts — make `mindweave` runnable from any directory.
3
+ *
4
+ * The whole point of a global command is that you `cd` into ANY project, type
5
+ * `mindweave`, and it works — including the API key. A random project won't carry
6
+ * Mindweave's `.env`, so the key has to live somewhere global. We layer config the
7
+ * way every CLI does, lowest priority first:
8
+ *
9
+ * 1. ~/.mindweave/.env — the global store (write your key here once).
10
+ * 2. <project>/.env — per-project overrides (optional).
11
+ * 3. real shell env — always wins (export a provider's key for a one-off).
12
+ *
13
+ * We parse `.env` ourselves (a tiny, dependency-free reader) so we control that
14
+ * precedence exactly: a value is only applied if the variable isn't already set,
15
+ * and we load project before global — so shell > project > global falls out
16
+ * naturally. On first run we also drop a commented template at ~/.mindweave/.env so
17
+ * the user has an obvious place to paste their key.
18
+ */
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
20
+ import { join } from "node:path";
21
+ import { stateRoot } from "../memory/store.js";
22
+ import { allProviders } from "../drivers/registry.js";
23
+ import { keysFor, slotVar } from "./keyStore.js";
24
+ /**
25
+ * The global Mindweave config directory (~/.mindweave).
26
+ *
27
+ * The SAME directory the state lives in, and now the same function that resolves it.
28
+ * They were computed separately and only one honoured `MINDWEAVE_STATE_DIR`, so a test
29
+ * run — or anyone relocating Mindweave's files — moved the sessions and left the config
30
+ * behind in the real home. The suite creates this template, which meant a clean machine
31
+ * got a config file written into `~/.mindweave` by `npm test`: exactly the pollution
32
+ * scripts/testState.mjs exists to prevent, still open on the config side.
33
+ */
34
+ export function globalConfigDir() {
35
+ return stateRoot();
36
+ }
37
+ /** The global env file (~/.mindweave/.env) — where the API key lives. */
38
+ export function globalEnvPath() {
39
+ return join(globalConfigDir(), ".env");
40
+ }
41
+ /**
42
+ * Load configuration into process.env. Call once, before anything reads a key.
43
+ * Order matters: project first, then global, each set-if-absent, so already-set
44
+ * shell variables win and a project `.env` overrides the global one.
45
+ */
46
+ export function loadConfig(cwd = process.cwd()) {
47
+ ensureGlobalTemplate();
48
+ reloadConfig(cwd);
49
+ }
50
+ /**
51
+ * Re-read the env files into process.env without recreating the template. Used to
52
+ * pick up a key the user just pasted while Mindweave is already running — once a real
53
+ * key appears we adopt it with no restart. (Empty values are ignored, so the
54
+ * blank key lines in the fresh template never count as "set".)
55
+ */
56
+ export function reloadConfig(cwd = process.cwd()) {
57
+ applyEnvFile(join(cwd, ".env"));
58
+ applyEnvFile(globalEnvPath());
59
+ activateStoredKeys();
60
+ }
61
+ /**
62
+ * Point each provider at its first stored key, unless something already has.
63
+ *
64
+ * Storage is `VAR_1..VAR_9` and the LIVE key is the bare `VAR` that every driver reads —
65
+ * two roles, deliberately two variables. Nothing on disk fills the live one, so without
66
+ * this a key added through /key would be written, reloaded, and then invisible on the
67
+ * next launch: the app would ask for a key it already had.
68
+ *
69
+ * Set-if-absent, so a shell export still wins and a key chosen for this session with
70
+ * /key is not overwritten by a later reload.
71
+ */
72
+ function activateStoredKeys() {
73
+ for (const provider of allProviders()) {
74
+ if (process.env[provider.apiKeyEnv]?.trim())
75
+ continue;
76
+ const first = keysFor(provider.apiKeyEnv)[0];
77
+ if (first)
78
+ process.env[provider.apiKeyEnv] = first.value;
79
+ }
80
+ }
81
+ /**
82
+ * True once the named provider's key is available from any source.
83
+ *
84
+ * The variable name is a parameter rather than a constant because which key is
85
+ * needed depends on which model the user is about to run — each provider declares
86
+ * its own in its manifest. This module stays a plain config utility and never
87
+ * imports the driver registry.
88
+ */
89
+ export function hasApiKey(envVar) {
90
+ return Boolean(process.env[envVar]);
91
+ }
92
+ /**
93
+ * Persist a key the user typed in the terminal: write it into ~/.mindweave/.env (so
94
+ * it's there next launch too) and apply it to this process right away (so the
95
+ * chat can start immediately — no restart). Updates that provider's line in place,
96
+ * preserving every other line, so adding a second provider's key never disturbs
97
+ * the first one.
98
+ */
99
+ /**
100
+ * Write a variable into the global env file, or remove it when `value` is null.
101
+ *
102
+ * One place, because saving and removing have to agree about the file's shape — a
103
+ * remover that only deleted from `process.env` would leave the key on disk and it would
104
+ * come back on the next launch.
105
+ */
106
+ function writeEnvVar(envVar, value) {
107
+ const NL = String.fromCharCode(10);
108
+ const dir = globalConfigDir();
109
+ if (!existsSync(dir))
110
+ mkdirSync(dir, { recursive: true });
111
+ const path = globalEnvPath();
112
+ let existing = "";
113
+ try {
114
+ existing = readFileSync(path, "utf8");
115
+ }
116
+ catch {
117
+ /* no file yet */
118
+ }
119
+ // Find the variable's line the way applyEnvFile READS it: leading spaces or tabs, and
120
+ // an optional `export ` prefix, are both accepted there. A writer that matched neither
121
+ // would fail to find a line the reader had loaded, append a second one, and let the
122
+ // stale line win on the next launch — a key updated in the app but not on disk. Only
123
+ // spaces and tabs, never `\s`, so the match cannot run across a line break.
124
+ const body = `(?:export[ \\t]+)?${envVar}=`;
125
+ let next;
126
+ if (value === null) {
127
+ // Take the trailing newline with the line, then collapse any blank run left behind.
128
+ const remove = new RegExp(`^[ \\t]*${body}.*(?:\\r?\\n|$)`, "m");
129
+ next = existing.replace(remove, "").replace(new RegExp(`${NL}{3,}`, "g"), NL + NL);
130
+ }
131
+ else {
132
+ const line = `${envVar}=${value}`;
133
+ const replace = new RegExp(`^[ \\t]*${body}.*$`, "m");
134
+ next = replace.test(existing)
135
+ ? existing.replace(replace, line)
136
+ : (existing ? existing.replace(/\s*$/, NL) : "") + line + NL;
137
+ }
138
+ writeFileSync(path, next, { mode: 0o600 });
139
+ }
140
+ /**
141
+ * Move a bare `VAR=value` into `VAR_1`, once, so storage and the live key stop sharing a
142
+ * variable. An existing config or a shell export arrives that way; everything written
143
+ * after this point is numbered.
144
+ */
145
+ function normalizeLegacy(apiKeyEnv) {
146
+ const bare = process.env[apiKeyEnv]?.trim();
147
+ if (!bare)
148
+ return;
149
+ if (process.env[slotVar(apiKeyEnv, 1)]?.trim())
150
+ return;
151
+ process.env[slotVar(apiKeyEnv, 1)] = bare;
152
+ writeEnvVar(slotVar(apiKeyEnv, 1), bare);
153
+ writeEnvVar(apiKeyEnv, null);
154
+ }
155
+ /** Store a key in a slot. Slot 1 also becomes the live key when nothing else is. */
156
+ export function saveApiKey(apiKeyEnv, key, slot = 1) {
157
+ const trimmed = key.trim();
158
+ if (!trimmed)
159
+ return;
160
+ normalizeLegacy(apiKeyEnv);
161
+ const envVar = slotVar(apiKeyEnv, slot);
162
+ process.env[envVar] = trimmed;
163
+ writeEnvVar(envVar, trimmed);
164
+ if (!process.env[apiKeyEnv]?.trim() || slot === 1)
165
+ process.env[apiKeyEnv] = trimmed;
166
+ }
167
+ /**
168
+ * Remove one stored key, closing the gap behind it.
169
+ *
170
+ * Slots are renumbered so there is never a hole: with `_2` gone, `_3` becomes `_2`. A
171
+ * hole reads fine to a program and badly to a person opening the file. Cleared first and
172
+ * rewritten from 1, because renumbering in place would overwrite a value before it had
173
+ * been moved.
174
+ */
175
+ export function removeApiKey(apiKeyEnv, slot) {
176
+ normalizeLegacy(apiKeyEnv);
177
+ const before = keysFor(apiKeyEnv);
178
+ const live = process.env[apiKeyEnv]?.trim();
179
+ const remaining = before.filter((k) => k.slot !== slot);
180
+ for (const k of before) {
181
+ delete process.env[k.envVar];
182
+ writeEnvVar(k.envVar, null);
183
+ }
184
+ remaining.forEach((k, i) => {
185
+ const envVar = slotVar(apiKeyEnv, i + 1);
186
+ process.env[envVar] = k.value;
187
+ writeEnvVar(envVar, k.value);
188
+ });
189
+ // Removing the key that was in use must not leave the provider pointing at nothing.
190
+ if (!remaining.some((k) => k.value === live)) {
191
+ if (remaining[0])
192
+ process.env[apiKeyEnv] = remaining[0].value;
193
+ else
194
+ delete process.env[apiKeyEnv];
195
+ }
196
+ }
197
+ /**
198
+ * Make a stored key the one the drivers send, for this session.
199
+ *
200
+ * Assigned into the variable they already read, and the stored slots are left alone: a
201
+ * key that is merely rate-limited today belongs back in its usual place tomorrow, and
202
+ * choosing one should not reorder a file the user maintains.
203
+ */
204
+ export function useApiKey(apiKeyEnv, slot) {
205
+ const found = keysFor(apiKeyEnv).find((k) => k.slot === slot);
206
+ if (!found)
207
+ return false;
208
+ process.env[apiKeyEnv] = found.value;
209
+ return true;
210
+ }
211
+ /**
212
+ * What lands in ~/.mindweave/.env the first time Mindweave runs.
213
+ *
214
+ * Every provider, because this is the file a new user actually opens — it listed two of
215
+ * thirteen, and someone who came for Gemini or Groq found no sign their provider existed.
216
+ * Built from the registry rather than typed out, so a new driver cannot be forgotten
217
+ * here (docsCurrent.test.ts holds the same line for .env.example and PROVIDERS.md).
218
+ */
219
+ const GLOBAL_ENV_TEMPLATE = [
220
+ "# Mindweave global config — applies in every project.",
221
+ "# Paste a key below (no quotes needed). You only need the one for the provider you",
222
+ "# actually use; fill in several and /provider moves between them.",
223
+ "",
224
+ // The name on its OWN line, never trailing the assignment. `KEY= # DeepSeek` reads
225
+ // fine and parses as a VALUE of "# DeepSeek", so every provider would have reported a
226
+ // key it did not have: no first-run prompt, and every request rejected with no
227
+ // explanation. Caught by reading the parsed result rather than the file.
228
+ ...allProviders().flatMap((p) => [`# ${p.label}`, `${p.apiKeyEnv}=`]),
229
+ "",
230
+ "# Optional:",
231
+ "# MINDWEAVE_MODEL — which model to open with. Run /model in Mindweave for the list.",
232
+ "# MINDWEAVE_MODEL=",
233
+ "",
234
+ ].join(String.fromCharCode(10));
235
+ /** Create ~/.mindweave/.env with a commented template the first time we run. */
236
+ function ensureGlobalTemplate() {
237
+ try {
238
+ const dir = globalConfigDir();
239
+ if (!existsSync(dir))
240
+ mkdirSync(dir, { recursive: true });
241
+ const path = globalEnvPath();
242
+ if (!existsSync(path)) {
243
+ writeFileSync(path, GLOBAL_ENV_TEMPLATE, { mode: 0o600 });
244
+ }
245
+ }
246
+ catch {
247
+ // Best-effort: if we can't write the template, config loading still works.
248
+ }
249
+ }
250
+ /** Apply a single .env file (set-if-absent), tolerating a missing/garbled file. */
251
+ function applyEnvFile(path) {
252
+ let text;
253
+ try {
254
+ text = readFileSync(path, "utf8");
255
+ }
256
+ catch {
257
+ return; // no file here — fine
258
+ }
259
+ for (const raw of text.split(/\r?\n/)) {
260
+ const line = raw.trim();
261
+ if (!line || line.startsWith("#"))
262
+ continue;
263
+ const body = line.startsWith("export ") ? line.slice(7) : line;
264
+ const eq = body.indexOf("=");
265
+ if (eq <= 0)
266
+ continue;
267
+ const key = body.slice(0, eq).trim();
268
+ if (!key || key in process.env)
269
+ continue; // already set wins
270
+ let value = body.slice(eq + 1).trim();
271
+ if (value.length >= 2 && (value[0] === '"' || value[0] === "'") && value[value.length - 1] === value[0]) {
272
+ value = value.slice(1, -1);
273
+ }
274
+ if (!value)
275
+ continue; // ignore empty assignments (e.g. the blank template line)
276
+ process.env[key] = value;
277
+ }
278
+ }
279
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/cli/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * chatAnchor.ts — where the transcript sits inside the chat viewport.
3
+ *
4
+ * The viewport is a fixed-height clipped box and the transcript renders in FULL
5
+ * inside it; a vertical offset decides which part shows. That mechanism is
6
+ * deliberately dumb — no height estimation, no per-block scrolling — because both
7
+ * of those were tried and both are why it broke. This module owns the decision that
8
+ * positions it, so the rule can be tested instead of eyeballed.
9
+ *
10
+ * Two regimes, and the whole point of the shape below is that they cannot interfere:
11
+ *
12
+ * - The transcript OVERFLOWS. Then it scrolls, and the offset is negative:
13
+ * `-shift` slides the content up so the newest lines are on screen. `scrollUp`
14
+ * counts lines back from the bottom, so 0 always means pinned to the newest and
15
+ * fresh output stays put with no special case.
16
+ * - The transcript FITS. Then there is nothing to scroll, and the only question is
17
+ * where the spare rows go. They used to go below the text, stranding a short
18
+ * conversation at the top of the screen with a growing void above the input box.
19
+ * They now go above it, so the conversation rests on the input the way a chat is
20
+ * expected to.
21
+ *
22
+ * HOW the spare rows are moved matters more than it looks. The obvious version — pad
23
+ * the transcript down by `chatRows - contentHeight` — was written first and a render
24
+ * probe rejected it: `chatRows` is a MEASURED value that lags a frame, and on the
25
+ * first render it is not yet known at all. Padding by a stale number leaves a gap on
26
+ * a good frame and, when the number is too large, pushes the whole conversation down
27
+ * past the clip edge and off the screen.
28
+ *
29
+ * So the offset here is only ever the scroll offset, and the resting case is done in
30
+ * the layout instead: `restsOnFooter` tells the view to put a flex-grow spacer ABOVE
31
+ * the transcript. Yoga then measures the leftover space itself, in the same pass that
32
+ * lays the frame out, and no stale measurement can be wrong about it.
33
+ */
34
+ /**
35
+ * Position the transcript.
36
+ *
37
+ * @param contentHeight measured height of the whole transcript, in rows
38
+ * @param chatRows measured height of the viewport it renders into
39
+ * @param scrollUp lines the user has scrolled back from the newest
40
+ */
41
+ export function chatLayout(contentHeight, chatRows, scrollUp) {
42
+ // A viewport of zero rows would compute an offset that slides the ENTIRE
43
+ // transcript off the top — every line hidden, with nothing on screen to explain
44
+ // it. App already clamps this, but a positioning rule should not depend on its
45
+ // caller to stay sane: one row always shows the newest line, which is the right
46
+ // failure for a viewport too small to be useful.
47
+ const rows = Math.max(1, chatRows);
48
+ const maxScroll = Math.max(0, contentHeight - rows);
49
+ const scrolled = Math.min(Math.max(0, scrollUp), maxScroll);
50
+ const shift = maxScroll - scrolled;
51
+ return {
52
+ // `|| 0` because negating zero yields `-0`, which is the same frame but a
53
+ // different value to anything comparing with Object.is.
54
+ marginTop: -shift || 0,
55
+ // Nothing to scroll means nothing to scroll TO — the transcript is short, and
56
+ // the spare rows belong above it.
57
+ restsOnFooter: maxScroll === 0,
58
+ maxScroll,
59
+ scrolled,
60
+ };
61
+ }
62
+ /**
63
+ * Where the reader should sit after the transcript re-wraps at a new width.
64
+ *
65
+ * `scrollUp` counts LINES back from the newest, and a line is not a stable unit
66
+ * across a resize: narrow the terminal and every wrapped paragraph grows more rows,
67
+ * so the same count lands somewhere else entirely. Being at the bottom survives that
68
+ * by luck, because zero is zero at any width, but any scrolled-back reader is moved
69
+ * without touching anything.
70
+ *
71
+ * The position is therefore carried as a PROPORTION of the scrollable range, which is
72
+ * the one thing about "where I was reading" that a re-wrap preserves. It is not exact
73
+ * — the same fraction of a taller transcript is a slightly different paragraph — but
74
+ * it keeps the reader within a line or two of where they were, where a raw line count
75
+ * can move them by pages.
76
+ *
77
+ * Pinned to the newest stays pinned, though that falls out of the arithmetic on its
78
+ * own — a red-check showed the guard below is not what produces it. What the guard is
79
+ * really for is a NEGATIVE position, which the proportion would carry through into a
80
+ * negative offset and slide the transcript off the top of the viewport.
81
+ */
82
+ export function reflowScroll(scrolled, oldMaxScroll, newMaxScroll) {
83
+ if (scrolled <= 0)
84
+ return 0;
85
+ if (newMaxScroll <= 0)
86
+ return 0;
87
+ // Nothing scrollable before means there is no proportion to carry; the reader was
88
+ // looking at the whole transcript, and the bottom is where they still belong.
89
+ if (oldMaxScroll <= 0)
90
+ return 0;
91
+ const fraction = Math.min(1, scrolled / oldMaxScroll);
92
+ return Math.min(newMaxScroll, Math.round(fraction * newMaxScroll));
93
+ }
94
+ //# sourceMappingURL=chatAnchor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatAnchor.js","sourceRoot":"","sources":["../../src/cli/chatAnchor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAqBH;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,aAAqB,EAAE,QAAgB,EAAE,QAAgB;IAClF,yEAAyE;IACzE,gFAAgF;IAChF,+EAA+E;IAC/E,gFAAgF;IAChF,iDAAiD;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAC;IACnC,OAAO;QACL,0EAA0E;QAC1E,wDAAwD;QACxD,SAAS,EAAE,CAAC,KAAK,IAAI,CAAC;QACtB,8EAA8E;QAC9E,kCAAkC;QAClC,aAAa,EAAE,SAAS,KAAK,CAAC;QAC9B,SAAS;QACT,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,YAAoB,EAAE,YAAoB;IACvF,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC5B,IAAI,YAAY,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,kFAAkF;IAClF,8EAA8E;IAC9E,IAAI,YAAY,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * commandArgs.ts — turning what someone typed after a command into a choice.
3
+ *
4
+ * `/model`, `/think` and `/compact` all took an argument and threw it away without a
5
+ * word. Naming a model after `/model` opened the picker as if you had typed nothing,
6
+ * which reads as the app not having heard you — and is worse than an error, because an
7
+ * error tells you to try something else and silence tells you nothing.
8
+ *
9
+ * Terminal agents generally accept an argument on all three, so it is what someone
10
+ * will type without thinking about it — which is exactly when silence is worst.
11
+ *
12
+ * Nothing here knows any provider's lineup: the candidates are handed in by the caller,
13
+ * which reads them from the registry. That is the rule for core code, and it is also
14
+ * what makes this testable without a key.
15
+ *
16
+ * The matching is deliberately forgiving in a bounded way: exact id, then exact label,
17
+ * then a UNIQUE prefix, then a UNIQUE substring. Never a "closest guess" — picking a
18
+ * model or a reasoning budget is a decision with a cost attached, and quietly choosing
19
+ * the nearest thing to a typo is how you end up billed for the wrong one. Ambiguity
20
+ * and misses both come back as a message naming the real options.
21
+ */
22
+ function norm(s) {
23
+ return s.trim().toLowerCase();
24
+ }
25
+ /** "a, b or c" — a list a person reads, not a machine dump. */
26
+ function list(items) {
27
+ if (items.length <= 1)
28
+ return items[0] ?? "";
29
+ return `${items.slice(0, -1).join(", ")} or ${items[items.length - 1]}`;
30
+ }
31
+ /**
32
+ * Which candidate the typed argument means.
33
+ *
34
+ * `what` names the thing being chosen, so the message reads as a sentence rather than
35
+ * as a template ("No model called…", "No reasoning level called…").
36
+ */
37
+ export function resolveChoice(arg, candidates, what) {
38
+ const wanted = norm(arg);
39
+ if (!wanted)
40
+ return { kind: "error", message: `Which ${what}?` };
41
+ const names = candidates.map((c) => c.label);
42
+ // Exact wins outright, and is checked against BOTH the id and the label — the id is
43
+ // what a script or a copied command line carries, the label is what the picker shows.
44
+ const exact = candidates.findIndex((c) => norm(c.label) === wanted || (c.id !== undefined && norm(c.id) === wanted));
45
+ if (exact >= 0)
46
+ return { kind: "match", index: exact };
47
+ const starts = matchesFor(candidates, (c) => startsWith(c, wanted));
48
+ if (starts.length === 1)
49
+ return { kind: "match", index: starts[0] };
50
+ if (starts.length > 1)
51
+ return { kind: "error", message: ambiguous(arg, starts.map((i) => names[i])) };
52
+ const contains = matchesFor(candidates, (c) => includes(c, wanted));
53
+ if (contains.length === 1)
54
+ return { kind: "match", index: contains[0] };
55
+ if (contains.length > 1)
56
+ return { kind: "error", message: ambiguous(arg, contains.map((i) => names[i])) };
57
+ return {
58
+ kind: "error",
59
+ message: `No ${what} called "${arg.trim()}". Available: ${list(names)}.`,
60
+ };
61
+ }
62
+ function matchesFor(candidates, pred) {
63
+ const out = [];
64
+ candidates.forEach((c, i) => {
65
+ if (pred(c))
66
+ out.push(i);
67
+ });
68
+ return out;
69
+ }
70
+ function startsWith(c, wanted) {
71
+ return norm(c.label).startsWith(wanted) || (c.id !== undefined && norm(c.id).startsWith(wanted));
72
+ }
73
+ function includes(c, wanted) {
74
+ return norm(c.label).includes(wanted) || (c.id !== undefined && norm(c.id).includes(wanted));
75
+ }
76
+ function ambiguous(arg, matched) {
77
+ return `"${arg.trim()}" matches ${list(matched)}. Which one?`;
78
+ }
79
+ //# sourceMappingURL=commandArgs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandArgs.js","sourceRoot":"","sources":["../../src/cli/commandArgs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * commandRoute.ts — deciding WHICH command a typed line is.
3
+ *
4
+ * This used to be the condition half of a 460-line `if (name === "/x")` chain inside a
5
+ * React component, which is why every one of the eighteen commands had zero coverage:
6
+ * there was nothing to call. The bodies still live in `App.tsx`. Only the decision
7
+ * moved here, because the decision is where the defects were:
8
+ *
9
+ * - **`/mcp add` and `/mcp remove` were DEAD.** The guard read
10
+ * `/^(add|remove|rm)\b/` on screen, but the byte where `\b` should have been was a
11
+ * literal backspace (0x08) — an escape lost somewhere in editing. The pattern
12
+ * therefore required the user to type a backspace character, so it never matched
13
+ * anything, and every `/mcp add …` silently opened the server-health view instead.
14
+ * The command was advertised in its own `/help` description the whole time.
15
+ * - The unknown-command reply listed thirteen of the eighteen commands, hardcoded. It
16
+ * had drifted, and the four it omitted included `/help`.
17
+ *
18
+ * Both are the same shape as the bugs found in the queue and the first run: the feature
19
+ * worked, the routing to it did not, and reading the code did not show it — the first
20
+ * one was INVISIBLE in the source, which is why the verb list here is data rather than
21
+ * a pattern. There is nothing in `["add","remove","rm"]` that can be mistyped into
22
+ * something that still compiles and never matches.
23
+ *
24
+ * Order matters and is deliberate: a builtin beats a project skill, a project skill
25
+ * beats a third-party server's prompt. A server cannot shadow `/undo`, and a project's
26
+ * own command always wins over something a dependency installed.
27
+ */
28
+ import { findSkill } from "../governor/skills.js";
29
+ import { parsePromptCommand } from "../mcp/prompts.js";
30
+ /** The sub-commands `/mcp` understands as configuration rather than as a status view. */
31
+ export const MCP_CONFIG_VERBS = ["add", "remove", "rm"];
32
+ /**
33
+ * Split a typed line into the command word and its argument.
34
+ *
35
+ * The name is lowercased so `/Help` works; the argument is not, because it is as
36
+ * likely to be a path, a label or a directive, and lowercasing `/include SRC/Api`
37
+ * would break it on a case-sensitive checkout.
38
+ */
39
+ export function parseCommandLine(raw) {
40
+ const trimmed = raw.trim();
41
+ const first = trimmed.split(/\s+/)[0] ?? "";
42
+ return { name: first.toLowerCase(), arg: trimmed.slice(first.length).trim() };
43
+ }
44
+ export function routeCommand(raw, catalog) {
45
+ const { name, arg } = parseCommandLine(raw);
46
+ if (catalog.builtins.includes(name)) {
47
+ // `/mcp` is the one builtin that splits: with a configuration verb it writes the
48
+ // server config, bare it shows server health. An EXACT first word — a prefix match
49
+ // would send `/mcp rmdir-server` to the remove branch, which fails its own exact
50
+ // check one layer down and falls through to being parsed as an ADD.
51
+ if (name === "/mcp") {
52
+ const verb = arg.split(/\s+/)[0]?.toLowerCase() ?? "";
53
+ if (MCP_CONFIG_VERBS.includes(verb)) {
54
+ return { kind: "mcp-config", arg };
55
+ }
56
+ }
57
+ return { kind: "builtin", name, arg };
58
+ }
59
+ // A project's own skill beats a server's prompt of the same name.
60
+ const skill = findSkill(catalog.skills, name);
61
+ if (skill)
62
+ return { kind: "skill", skill, arg };
63
+ const promptRef = parsePromptCommand(name);
64
+ if (promptRef)
65
+ return { kind: "prompt", server: promptRef.server, prompt: promptRef.name, arg };
66
+ return { kind: "unknown", name };
67
+ }
68
+ /**
69
+ * What to say when nothing matched.
70
+ *
71
+ * The old message hardcoded thirteen command names and had drifted from the real
72
+ * eighteen — including omitting `/help`, the one that would have answered the
73
+ * question. Pointing at `/help` cannot drift, and is shorter than the list it replaces.
74
+ */
75
+ export function unknownCommandMessage(name) {
76
+ return `Unknown command ${name}. /help lists every command.`;
77
+ }
78
+ //# sourceMappingURL=commandRoute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandRoute.js","sourceRoot":"","sources":["../../src/cli/commandRoute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,yFAAyF;AACzF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAU,CAAC;AASjE;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;AAChF,CAAC;AAuBD,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,OAAqB;IAC7D,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE5C,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,iFAAiF;QACjF,mFAAmF;QACnF,iFAAiF;QACjF,oEAAoE;QACpE,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YACtD,IAAK,gBAAsC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3D,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC;YACrC,CAAC;QACH,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACxC,CAAC;IAED,kEAAkE;IAClE,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,MAAqB,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAEhD,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;IAEhG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,mBAAmB,IAAI,8BAA8B,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * compaction.ts — how a compaction reports itself, as pure text (no React).
3
+ *
4
+ * [████████████████████] 100% context full
5
+ * ✔ Reclaimed 106K tokens (22K / 128K)
6
+ * [███░░░░░░░░░░░░░░░░░] 17% context used
7
+ *
8
+ * Compaction is the one piece of background machinery worth showing. Everything else
9
+ * Mindweave does to manage context is invisible on purpose, but a summarizing pass
10
+ * REWRITES the conversation — the model will not remember the middle of it afterwards
11
+ * — and a user who does not know that happened is left wondering why it forgot.
12
+ *
13
+ * ONE block, already settled. There is no "Compacting…" state that later fills in: the
14
+ * before-figure is only interesting next to the after-figure, and a row that changes
15
+ * under the reader is the exact transition the transcript design removes elsewhere.
16
+ *
17
+ * The numbers are the SAME arithmetic the compaction thresholds run on (transcript
18
+ * estimate + measured overhead). That coupling is deliberate. If the estimate is off,
19
+ * the bar is wrong in precisely the way the decision to compact was wrong, so what the
20
+ * user sees is what the system actually believed — rather than a second, prettier
21
+ * number that disagrees with the machinery.
22
+ */
23
+ import { formatTokens } from "../dynamo/pricing.js";
24
+ /** Cells in a bar. Matches the reference design; shrinks only on a narrow terminal. */
25
+ const BAR_CELLS = 20;
26
+ const FULL = "█";
27
+ const EMPTY = "░";
28
+ /** A `[████░░░░]` bar for a fraction of the window (pure). Clamped, so a measurement
29
+ * that overshoots the window renders as full rather than overflowing the row. */
30
+ export function bar(used, window, cells = BAR_CELLS) {
31
+ const safeCells = Math.max(4, cells);
32
+ const frac = window > 0 ? Math.min(1, Math.max(0, used / window)) : 0;
33
+ // Round rather than floor, so a nearly-full context does not read as one cell short —
34
+ // but never round UP to full while any room remains, which would say "full" wrongly.
35
+ let filled = Math.round(frac * safeCells);
36
+ if (frac < 1 && filled === safeCells)
37
+ filled = safeCells - 1;
38
+ if (frac > 0 && filled === 0)
39
+ filled = 1; // and never show a used context as empty
40
+ return `[${FULL.repeat(filled)}${EMPTY.repeat(safeCells - filled)}]`;
41
+ }
42
+ /** The percentage shown beside a bar (pure), right-aligned to three columns so the
43
+ * before/after pair line up whatever the digits. */
44
+ export function percent(used, window) {
45
+ const pct = window > 0 ? Math.round((used / window) * 100) : 0;
46
+ return `${Math.min(100, Math.max(0, pct))}%`.padStart(4);
47
+ }
48
+ /**
49
+ * The finished block, one string per row (pure).
50
+ *
51
+ * `width` shrinks the bars on a narrow terminal rather than letting a row wrap, since
52
+ * a wrapped bar reads as two broken bars.
53
+ */
54
+ export function compactionLines(r, width = 80) {
55
+ // Row overhead: the two-space indent, the brackets, a space, four percent columns,
56
+ // two spaces, and the label. Leave the bar whatever is left, within reason.
57
+ const cells = Math.max(4, Math.min(BAR_CELLS, width - 26));
58
+ const reclaimed = Math.max(0, r.before - r.after);
59
+ // Labelled "before"/"after" rather than the reference's "Context Full"/"Context
60
+ // Used". That wording only reads correctly when the pass ran at 100%, and `/compact`
61
+ // can be typed at any moment — a bar showing 75% next to the words "context full"
62
+ // is a caption contradicting the picture directly above it.
63
+ return [
64
+ `${bar(r.before, r.window, cells)} ${percent(r.before, r.window)} before`,
65
+ `✔ Reclaimed ${formatTokens(reclaimed)} tokens (${formatTokens(r.after)} / ${formatTokens(r.window)})`,
66
+ `${bar(r.after, r.window, cells)} ${percent(r.after, r.window)} after`,
67
+ ];
68
+ }
69
+ //# sourceMappingURL=compaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../src/cli/compaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKpD,uFAAuF;AACvF,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,IAAI,GAAG,GAAG,CAAC;AACjB,MAAM,KAAK,GAAG,GAAG,CAAC;AAElB;kFACkF;AAClF,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,MAAc,EAAE,KAAK,GAAG,SAAS;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,sFAAsF;IACtF,qFAAqF;IACrF,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;IAC1C,IAAI,IAAI,GAAG,CAAC,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,GAAG,SAAS,GAAG,CAAC,CAAC;IAC7D,IAAI,IAAI,GAAG,CAAC,IAAI,MAAM,KAAK,CAAC;QAAE,MAAM,GAAG,CAAC,CAAC,CAAC,yCAAyC;IACnF,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC;AACvE,CAAC;AAED;qDACqD;AACrD,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,MAAc;IAClD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,CAAmB,EAAE,KAAK,GAAG,EAAE;IAC7D,mFAAmF;IACnF,4EAA4E;IAC5E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAClD,gFAAgF;IAChF,qFAAqF;IACrF,kFAAkF;IAClF,4DAA4D;IAC5D,OAAO;QACL,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU;QAC1E,eAAe,YAAY,CAAC,SAAS,CAAC,YAAY,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG;QACtG,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS;KACxE,CAAC;AACJ,CAAC"}