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,91 @@
1
+ /**
2
+ * scope.ts — which glob-scoped rules this session has activated.
3
+ *
4
+ * A rule may carry `globs`, meaning "apply this once the work heads that way". The
5
+ * question is when that gets decided.
6
+ *
7
+ * It used to be decided AT RENDER: every model call rebuilt the set of every path the
8
+ * session had ever touched, relativized each one, and matched every scoped rule's globs
9
+ * against all of them. That is O(paths x rules) on every step of every turn, against a
10
+ * path set that only ever grew — so the cost of a rule the user set once climbed for as
11
+ * long as the session lasted.
12
+ *
13
+ * It is now decided AT ACCESS, which is the only shape that stays correct
14
+ * (`getManagedAndUserConditionalRules(targetPath, processedPaths)` resolves conditional
15
+ * rules for the ONE file being touched, with a processed-set for dedup). When a path is
16
+ * read or written we test it once, against only the rules that have not already fired,
17
+ * and remember the NAMES that matched. Rendering is then a set lookup per rule.
18
+ *
19
+ * Remembering the match rather than the path is what makes this durable. A compaction
20
+ * clears the read ledger because the contents it described are gone from the screen —
21
+ * but "this session has worked in src/api" is not a fact about the screen, and a name
22
+ * already in `matched` is never removed. The earlier fix for that bug carried a second
23
+ * copy of every path forward to re-derive the same answer; this needs no carry at all.
24
+ */
25
+ import { relative } from "node:path";
26
+ import { anyPathMatches } from "./glob.js";
27
+ /**
28
+ * How many project-relative paths are kept for RE-EVALUATION.
29
+ *
30
+ * Only used when the rule set itself changes (the user edits a rule file, or the model
31
+ * writes a new one) and rules that never ran must be judged against work already done.
32
+ * Matching for rules that have already fired does not consult this at all — those names
33
+ * are sticky — so overflowing the cap can only mean a NEWLY ADDED scoped rule misses
34
+ * paths touched long ago. It still fires on the next matching path.
35
+ *
36
+ * Bounded because this is the one structure here that would otherwise grow with session
37
+ * length, which is exactly the property being removed.
38
+ */
39
+ const MAX_REMEMBERED_PATHS = 2_000;
40
+ export function createRuleScope() {
41
+ return { matched: new Set(), paths: new Set() };
42
+ }
43
+ /** Project-relative POSIX form, computed ONCE per path instead of once per render. */
44
+ function relPosix(root, absPath) {
45
+ return relative(root, absPath).split("\\").join("/");
46
+ }
47
+ /**
48
+ * Record that the session touched `absPath`, and fire any scoped rule it matches.
49
+ *
50
+ * Cheap by construction: a rule already in `matched` is skipped, so the work per path
51
+ * shrinks as rules fire, and a project with no scoped rules does no matching at all.
52
+ */
53
+ export function noteScopePath(scope, rules, root, absPath) {
54
+ const rel = relPosix(root, absPath);
55
+ if (scope.paths.size < MAX_REMEMBERED_PATHS)
56
+ scope.paths.add(rel);
57
+ const one = [rel];
58
+ for (const rule of rules) {
59
+ if (!rule.globs || rule.globs.length === 0)
60
+ continue; // always-on: nothing to decide
61
+ if (scope.matched.has(rule.name))
62
+ continue; // already fired — never re-tested
63
+ if (anyPathMatches(one, rule.globs))
64
+ scope.matched.add(rule.name);
65
+ }
66
+ }
67
+ /**
68
+ * Re-judge every remembered path against the CURRENT rule set.
69
+ *
70
+ * Called when the rules themselves change — a reload from disk, or the model writing a
71
+ * new one — because a rule that did not exist when a path was touched never got its
72
+ * chance. This is the only O(paths x rules) pass left, and it runs on rule changes
73
+ * rather than on every model call.
74
+ *
75
+ * Additive: it never un-matches. A rule deleted from disk simply stops being rendered,
76
+ * because rendering filters by the live rule list, not by this set.
77
+ */
78
+ export function rescope(scope, rules) {
79
+ const paths = [...scope.paths];
80
+ if (paths.length === 0)
81
+ return;
82
+ for (const rule of rules) {
83
+ if (!rule.globs || rule.globs.length === 0)
84
+ continue;
85
+ if (scope.matched.has(rule.name))
86
+ continue;
87
+ if (anyPathMatches(paths, rule.globs))
88
+ scope.matched.add(rule.name);
89
+ }
90
+ }
91
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/governor/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C;;;;;;;;;;;GAWG;AACH,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAYnC,MAAM,UAAU,eAAe;IAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;AAClD,CAAC;AAED,sFAAsF;AACtF,SAAS,QAAQ,CAAC,IAAY,EAAE,OAAe;IAC7C,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAgB,EAChB,KAAsB,EACtB,IAAY,EACZ,OAAe;IAEf,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,oBAAoB;QAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS,CAAC,+BAA+B;QACrF,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS,CAAC,kCAAkC;QAC9E,IAAI,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC;YAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,OAAO,CAAC,KAAgB,EAAE,KAAsB;IAC9D,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACrD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAC3C,IAAI,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC;YAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,CAAC;AACH,CAAC"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * skills.ts — reusable procedures the model can run on demand.
3
+ *
4
+ * A skill is a named playbook: `<project-state>/skills/<name>/SKILL.md`, with a
5
+ * `name` / `description` / `when_to_use` header and a markdown body of steps.
6
+ * The key design is **progressive disclosure**: only
7
+ * the lightweight catalog (name + description + when-to-use) ever sits in the
8
+ * prompt, so a project can have many skills at near-zero token cost; the full
9
+ * body is read only when the skill is actually invoked — by the user typing
10
+ * `/name`, or by the model calling the `use_skill` tool when a description fits.
11
+ */
12
+ import { promises as fs } from "node:fs";
13
+ import { join } from "node:path";
14
+ import { parseFrontmatter } from "./frontmatter.js";
15
+ import { parseGlobs } from "./rules.js";
16
+ import { anyPathMatches } from "./glob.js";
17
+ const SKILL_FILE = "SKILL.md";
18
+ /** Discover the project's skills, reading only each one's frontmatter (catalog). */
19
+ export async function loadSkillCatalog(stateDir) {
20
+ const dir = join(stateDir, "skills");
21
+ let entries;
22
+ try {
23
+ entries = await fs.readdir(dir, { withFileTypes: true });
24
+ }
25
+ catch {
26
+ return []; // no skills dir yet
27
+ }
28
+ const skills = [];
29
+ for (const entry of entries) {
30
+ if (!entry.isDirectory())
31
+ continue; // skills are directories: <name>/SKILL.md
32
+ const skillDir = join(dir, entry.name);
33
+ try {
34
+ const raw = await fs.readFile(join(skillDir, SKILL_FILE), "utf8");
35
+ const { data } = parseFrontmatter(raw);
36
+ const globs = parseGlobs(data.globs || data.paths);
37
+ skills.push({
38
+ name: data.name || entry.name,
39
+ description: data.description || "",
40
+ whenToUse: data.when_to_use || data.whenToUse || "",
41
+ dir: skillDir,
42
+ ...(data["argument-hint"] ? { argumentHint: data["argument-hint"] } : {}),
43
+ ...(globs.length > 0 ? { globs } : {}),
44
+ });
45
+ }
46
+ catch {
47
+ // No SKILL.md (or unreadable) — not a skill directory; skip it.
48
+ }
49
+ }
50
+ skills.sort((a, b) => a.name.localeCompare(b.name));
51
+ return skills;
52
+ }
53
+ /** Load a skill's full body (the steps), read fresh on invocation. Null if gone. */
54
+ export async function loadSkillBody(skill) {
55
+ try {
56
+ const raw = await fs.readFile(join(skill.dir, SKILL_FILE), "utf8");
57
+ return parseFrontmatter(raw).body;
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ /** Find a skill by its invocation name (case-insensitive). */
64
+ export function findSkill(skills, name) {
65
+ const wanted = name.trim().toLowerCase().replace(/^\//, "");
66
+ return skills.find((s) => s.name.toLowerCase() === wanted);
67
+ }
68
+ /**
69
+ * The skills visible in the catalog this turn: every always-listed skill plus any
70
+ * glob-scoped skill whose patterns match the working set. (Scoped-out skills are
71
+ * still invokable by name — this only controls catalog noise.)
72
+ */
73
+ export function activeSkills(skills, workingSet = []) {
74
+ return skills.filter((s) => !s.globs || s.globs.length === 0 || anyPathMatches(workingSet, s.globs));
75
+ }
76
+ /**
77
+ * Render the catalog for the system prompt: one line per visible skill with its
78
+ * name (+ argument hint), description, and when-to-use. "" when none are visible.
79
+ * Content only — the engine frames it.
80
+ */
81
+ /**
82
+ * Caps on the always-loaded skill catalog.
83
+ *
84
+ * This block renders into the CACHED system prefix on every session and only ever
85
+ * grows: every create_skill adds a line, permanently, and nothing trims it.
86
+ *
87
+ * The cap is on LENGTH PER ENTRY rather than on the number of entries, and that is a
88
+ * deliberate departure from "keep the most recent N". A skill is only reachable by
89
+ * NAME — use_skill takes one, and there is no tool that lists them — so an entry
90
+ * dropped from this catalog is a skill the model can no longer invoke at all. Trading
91
+ * a capability away to save tokens is the wrong trade. Clipping a rambling description
92
+ * costs nothing by comparison: the name still appears, the skill stays callable, and
93
+ * its full text is loaded on use anyway.
94
+ *
95
+ * The entry cap below is a backstop against the absurd case, set far above any real
96
+ * project, and it says so when it bites.
97
+ */
98
+ const MAX_SKILL_LINE_CHARS = 200;
99
+ const MAX_SKILL_ENTRIES = 100;
100
+ /** Clip to `max` on a word boundary where possible, with an ellipsis. */
101
+ function clip(text, max) {
102
+ if (text.length <= max)
103
+ return text;
104
+ const cut = text.slice(0, max);
105
+ const space = cut.lastIndexOf(" ");
106
+ return `${(space > max * 0.6 ? cut.slice(0, space) : cut).trimEnd()}…`;
107
+ }
108
+ export function renderSkillCatalog(skills, workingSet) {
109
+ // OMITTING the working set means "list everything", not "list nothing". It used to
110
+ // default to `[]`, which quietly filtered every glob-scoped skill out — so a caller
111
+ // that had no working set to give showed an incomplete catalog, and a skill reachable
112
+ // only by name became uninvokable.
113
+ //
114
+ // The engine relies on this: the catalog renders into the CACHED system prompt, so it
115
+ // must be byte-identical all session. Filtering it by the working set made a
116
+ // glob-scoped skill appear the moment a matching file was read, changing the system
117
+ // prompt and invalidating the tools, system and message caches at once.
118
+ const visible = workingSet === undefined ? skills : activeSkills(skills, workingSet);
119
+ if (visible.length === 0)
120
+ return "";
121
+ const shown = visible.slice(0, MAX_SKILL_ENTRIES);
122
+ const lines = shown.map((s) => {
123
+ const hint = s.argumentHint ? ` ${s.argumentHint}` : "";
124
+ const desc = s.description ? `: ${s.description}` : "";
125
+ const when = s.whenToUse ? ` — use when: ${s.whenToUse}` : "";
126
+ // The name and its argument hint are never clipped — they are what makes the
127
+ // skill callable. Only the prose after them is.
128
+ return `- ${s.name}${hint}${clip(`${desc}${when}`, MAX_SKILL_LINE_CHARS)}`;
129
+ });
130
+ if (visible.length > shown.length) {
131
+ lines.push(`> WARNING: ${visible.length - shown.length} more skill(s) exist but are not listed here. ` +
132
+ `Keep the catalog under ${MAX_SKILL_ENTRIES} skills, or scope them with \`globs\` so they appear only when relevant.`);
133
+ }
134
+ return lines.join("\n");
135
+ }
136
+ /**
137
+ * Substitute a skill's argument string into its body: `$ARGUMENTS` → the whole
138
+ * string, `$1`/`$2`/… → positional tokens. If the body has no such placeholder
139
+ * but arguments were given, they're appended as additional context — so both
140
+ * parameterized and plain skills handle args sensibly.
141
+ */
142
+ export function substituteSkillArgs(body, argString) {
143
+ const args = argString.trim();
144
+ const positional = args.length > 0 ? args.split(/\s+/) : [];
145
+ const hasPlaceholder = /\$ARGUMENTS\b/.test(body) || POSITIONAL.test(body);
146
+ // ONE pass over the original body. Two chained replaces meant a `$1` inside the
147
+ // user's own argument string was then treated as a placeholder and substituted again.
148
+ const out = body.replace(SUBSTITUTION, (match, digit) => {
149
+ if (digit === undefined)
150
+ return args;
151
+ // Leave the placeholder visible when nothing was supplied for it. Blanking it makes
152
+ // a skill that expected an argument read as though it never wanted one.
153
+ return positional[Number(digit) - 1] ?? match;
154
+ });
155
+ if (!hasPlaceholder && args)
156
+ return `${out}\n\nAdditional context from the user: ${args}`;
157
+ return out;
158
+ }
159
+ /**
160
+ * A positional placeholder: `$1`–`$9`, and NOT the start of a longer number.
161
+ *
162
+ * A skill body is a markdown playbook, so it very reasonably contains shell
163
+ * (`awk '{print $1}'`) and money (`$100`). The old pattern was `/\$(\d+)/`, which
164
+ * matched `$100` as positional argument one hundred, found nothing, and substituted
165
+ * the empty string — so `Budget is $100` silently became `Budget is `, and with no
166
+ * arguments at all EVERY `$n` in the body was deleted. The instructions the model was
167
+ * told to follow were quietly not the instructions on disk. Single digit matches the
168
+ * shell convention the syntax is borrowed from.
169
+ */
170
+ const POSITIONAL_SRC = String.raw `\$([1-9])(?!\d)`;
171
+ /** Detects one, for deciding whether the skill declared any placeholder at all. */
172
+ const POSITIONAL = new RegExp(POSITIONAL_SRC);
173
+ /** Replaces every placeholder in one pass. Shares POSITIONAL's source so the two
174
+ * cannot drift into disagreeing about what counts as a placeholder. */
175
+ const SUBSTITUTION = new RegExp(String.raw `\$ARGUMENTS\b|` + POSITIONAL_SRC, "g");
176
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/governor/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * types.ts — the governor's data contracts.
3
+ *
4
+ * The "governor" is the per-project control layer: the user's standing **rules**
5
+ * (always followed), reusable **skills** (procedures loaded on demand), and the
6
+ * **forbidden** list (paths/actions the tools must never touch). All of it is
7
+ * scoped to one project and stored under that project's state directory — the
8
+ * same `~/.mindweave/projects/<project>/` folder sessions already use.
9
+ *
10
+ * Everything here is plain JSON-friendly data on purpose. The forbidden config
11
+ * in particular rides on `ToolContext` (which deliberately holds only plain
12
+ * data), and the path/command checks are pure functions over it — exactly like
13
+ * the existing `guard.ts` deny-list, just user-defined instead of built-in.
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/governor/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,182 @@
1
+ /**
2
+ * write.ts — persist a new rule or forbidden path for a project.
3
+ *
4
+ * The governor owns the on-disk formats, so the act of "make this a rule" or
5
+ * "forbid this" lives here; the tools in src/tools are thin wrappers that call
6
+ * these and then mirror the change into the live session so it takes effect
7
+ * immediately. Files land under the project's state dir (the same per-project
8
+ * folder sessions use), so they persist for every future launch in this project.
9
+ */
10
+ import { promises as fs } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { projectDir } from "../memory/store.js";
13
+ import { parseForbidden, parseForbiddenCommands } from "./forbidden.js";
14
+ /** A filesystem-safe slug from a human name/phrase (kebab, ≤50 chars). */
15
+ export function slugify(text) {
16
+ return (text
17
+ .toLowerCase()
18
+ .replace(/[^a-z0-9]+/g, "-")
19
+ .replace(/^-+|-+$/g, "")
20
+ .slice(0, 50) || "rule");
21
+ }
22
+ /**
23
+ * Flatten a value to a single line before it goes into frontmatter.
24
+ *
25
+ * These headers are a line-oriented `key: value` format, and every value here is
26
+ * model-supplied text. A newline inside one starts what the loader reads as a NEW
27
+ * key, so a rule whose name ended in "\nglobs: **" would come back scoped to
28
+ * everything, and a skill's description could rewrite its own `when_to_use`. The
29
+ * value is written, then read back and believed, so it has to stay one field.
30
+ */
31
+ function oneLine(value) {
32
+ return value.replace(/[\r\n]+/g, " ").trim();
33
+ }
34
+ /**
35
+ * Build a frontmatter header, flattening EVERY value on the way in.
36
+ *
37
+ * `oneLine` used to be applied field by field at each call site, and one field was
38
+ * missed: `globs` went in raw as `globs: ${globs.join(", ")}`. That is the field
39
+ * deciding when a rule fires, and a newline inside it writes whatever the model
40
+ * likes into the header — a second key, or a `---` that closes it early and turns
41
+ * the rest of the rule into body.
42
+ *
43
+ * Written as one place that flattens everything, so the next field added cannot
44
+ * repeat the mistake. Empty values are dropped rather than emitted blank.
45
+ */
46
+ function frontmatter(fields) {
47
+ const lines = ["---"];
48
+ for (const [key, raw] of Object.entries(fields)) {
49
+ const value = oneLine(raw ?? "");
50
+ if (value)
51
+ lines.push(`${key}: ${value}`);
52
+ }
53
+ lines.push("---", "");
54
+ return lines.join("\n");
55
+ }
56
+ /** A short name derived from a rule's text (first few words) when none is given. */
57
+ export function deriveRuleName(body) {
58
+ return slugify(body.split(/\s+/).slice(0, 6).join(" "));
59
+ }
60
+ /**
61
+ * Save a standing rule as `rules/<slug>.md` in the project's state dir and return
62
+ * it. Overwrites a rule file of the same slug (re-stating a rule updates it). Pass
63
+ * `globs` to SCOPE the rule (fires only when the work touches matching files);
64
+ * omit them for an always-on rule (the default).
65
+ */
66
+ export async function writeRule(cwd, name, body, description = "", globs = []) {
67
+ const dir = join(projectDir(cwd), "rules");
68
+ await fs.mkdir(dir, { recursive: true });
69
+ const file = join(dir, `${slugify(name)}.md`);
70
+ const header = frontmatter({
71
+ name,
72
+ description,
73
+ globs: globs.join(", "),
74
+ });
75
+ await fs.writeFile(file, `${header}${body}\n`, "utf8");
76
+ return { name: oneLine(name), description: oneLine(description), body, ...(globs.length > 0 ? { globs } : {}) };
77
+ }
78
+ /**
79
+ * Create (or overwrite) a skill at `skills/<slug>/SKILL.md` in the project's
80
+ * state dir and return its catalog metadata. The directory name is the skill's
81
+ * invocation name; the frontmatter carries description / when-to-use / hint /
82
+ * scope so it loads back identically.
83
+ */
84
+ export async function writeSkill(cwd, skill) {
85
+ const name = slugify(skill.name);
86
+ const dir = join(projectDir(cwd), "skills", name);
87
+ await fs.mkdir(dir, { recursive: true });
88
+ const description = oneLine(skill.description);
89
+ const whenToUse = oneLine(skill.whenToUse ?? "");
90
+ const argumentHint = oneLine(skill.argumentHint ?? "");
91
+ const header = frontmatter({
92
+ name, // already the slug: no newline can survive slugify
93
+ description,
94
+ when_to_use: whenToUse,
95
+ "argument-hint": argumentHint,
96
+ globs: skill.globs?.join(", ") ?? "",
97
+ });
98
+ await fs.writeFile(join(dir, "SKILL.md"), `${header}${skill.body}\n`, "utf8");
99
+ return {
100
+ name,
101
+ description,
102
+ whenToUse,
103
+ dir,
104
+ ...(argumentHint ? { argumentHint } : {}),
105
+ ...(skill.globs && skill.globs.length > 0 ? { globs: skill.globs } : {}),
106
+ };
107
+ }
108
+ /**
109
+ * Append a pattern to `forbidden.md` in the project's state dir. Idempotent —
110
+ * returns `{ added: false }` if it was already forbidden. The pattern is
111
+ * normalized the same way the loader normalizes (drop leading `./`, trailing `/`).
112
+ */
113
+ export async function appendForbidden(cwd, pattern) {
114
+ const normalized = pattern.trim().replace(/^\.?\//, "").replace(/\/+$/, "");
115
+ if (!normalized)
116
+ return { added: false, pattern: normalized };
117
+ const base = projectDir(cwd);
118
+ const file = join(base, "forbidden.md");
119
+ let text = "";
120
+ try {
121
+ text = await fs.readFile(file, "utf8");
122
+ }
123
+ catch {
124
+ /* no forbidden.md yet */
125
+ }
126
+ if (parseForbidden(text).includes(normalized))
127
+ return { added: false, pattern: normalized };
128
+ await fs.mkdir(base, { recursive: true });
129
+ const separator = text && !text.endsWith("\n") ? "\n" : "";
130
+ await fs.writeFile(file, `${text}${separator}${normalized}\n`, "utf8");
131
+ return { added: true, pattern: normalized };
132
+ }
133
+ /**
134
+ * Append an MCP tool name to `forbidden-mcp-tools.md`. Sibling of
135
+ * appendForbiddenCommand; tool names are identifiers, kept verbatim.
136
+ */
137
+ export async function appendForbiddenMcpTool(cwd, name) {
138
+ const normalized = name.trim();
139
+ if (!normalized)
140
+ return { added: false, pattern: normalized };
141
+ const base = projectDir(cwd);
142
+ const file = join(base, "forbidden-mcp-tools.md");
143
+ let text = "";
144
+ try {
145
+ text = await fs.readFile(file, "utf8");
146
+ }
147
+ catch {
148
+ /* no forbidden-mcp-tools.md yet */
149
+ }
150
+ if (parseForbiddenCommands(text).includes(normalized))
151
+ return { added: false, pattern: normalized };
152
+ await fs.mkdir(base, { recursive: true });
153
+ const separator = text && !text.endsWith("\n") ? "\n" : "";
154
+ await fs.writeFile(file, `${text}${separator}${normalized}\n`, "utf8");
155
+ return { added: true, pattern: normalized };
156
+ }
157
+ /**
158
+ * Append a command pattern to `forbidden-commands.md` in the project's state dir.
159
+ * Idempotent — `{ added: false }` if it was already forbidden. Sibling of
160
+ * appendForbidden; command patterns are kept verbatim (trimmed), not path-normalized.
161
+ */
162
+ export async function appendForbiddenCommand(cwd, pattern) {
163
+ const normalized = pattern.trim();
164
+ if (!normalized)
165
+ return { added: false, pattern: normalized };
166
+ const base = projectDir(cwd);
167
+ const file = join(base, "forbidden-commands.md");
168
+ let text = "";
169
+ try {
170
+ text = await fs.readFile(file, "utf8");
171
+ }
172
+ catch {
173
+ /* no forbidden-commands.md yet */
174
+ }
175
+ if (parseForbiddenCommands(text).includes(normalized))
176
+ return { added: false, pattern: normalized };
177
+ await fs.mkdir(base, { recursive: true });
178
+ const separator = text && !text.endsWith("\n") ? "\n" : "";
179
+ await fs.writeFile(file, `${text}${separator}${normalized}\n`, "utf8");
180
+ return { added: true, pattern: normalized };
181
+ }
182
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/governor/write.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Mindweave — entry point.
4
+ *
5
+ * This file does one thing: start the terminal UI. It deliberately stays tiny.
6
+ * All real logic lives in its own lane (cli / dynamo / tools / memory / alternator)
7
+ * so the project stays easy to understand as it grows.
8
+ *
9
+ * The shebang above + the `bin` entry in package.json make this the `mindweave`
10
+ * command: install once (`npm link` / `npm i -g`), then `cd` into any project and
11
+ * type `mindweave`. The session roots at the current directory (process.cwd()), so it
12
+ * just works wherever you run it.
13
+ */
14
+ import { render } from "ink";
15
+ import { createElement } from "react";
16
+ import { App } from "./cli/App.js";
17
+ import { loadConfig } from "./cli/bootstrap.js";
18
+ import { sweepTempInBackground } from "./tools/tempSweep.js";
19
+ import { parseStartupArgs, hasInteractiveInput, NO_TERMINAL_MESSAGE } from "./cli/startupArgs.js";
20
+ import { enterAltScreen } from "./cli/altScreen.js";
21
+ import { TERMINAL_RESTORE } from "./cli/terminalRestore.js";
22
+ import { instrumentStdout, flush as flushPerf, perf, perfEnabled } from "./cli/perfLog.js";
23
+ import { MAX_FPS } from "./cli/frameRate.js";
24
+ import { framebufferStdout } from "./cli/framebuffer/writer.js";
25
+ // --help / --version answer and exit, BEFORE anything reads config, sweeps a
26
+ // directory, or starts the UI. They used to fall through to the interactive app,
27
+ // which then hung forever with no TTY to render into — the one thing a packaging
28
+ // tool or a script does with a new CLI.
29
+ const startup = parseStartupArgs(process.argv.slice(2));
30
+ if (startup.kind === "print") {
31
+ process.stdout.write(startup.text + "\n");
32
+ process.exit(0);
33
+ }
34
+ // Nothing below this point can run without a terminal to read from, and the failure
35
+ // without one is a stack trace through React internals on a process that exits 0.
36
+ // --help, --version and --reset-terminal are answered above, so they still work
37
+ // wherever they are called from.
38
+ if (!hasInteractiveInput(process.stdin)) {
39
+ process.stderr.write(NO_TERMINAL_MESSAGE);
40
+ process.exit(1);
41
+ }
42
+ if (startup.kind === "reset") {
43
+ // Repairing a terminal a dead run left in mouse-reporting mode. Nothing else may run
44
+ // first: this is typed when the terminal is already misbehaving, and loading config or
45
+ // sweeping temp would only add ways for it to fail before it writes the one thing it
46
+ // came to write. Escapes go out only to a real terminal, since into a pipe they would
47
+ // be corruption rather than repair.
48
+ if (process.stdout.isTTY) {
49
+ process.stdout.write(TERMINAL_RESTORE);
50
+ process.stdout.write("terminal restored\n");
51
+ }
52
+ else {
53
+ process.stdout.write("not a terminal, nothing to restore\n");
54
+ }
55
+ process.exit(0);
56
+ }
57
+ // Load config (global ~/.mindweave/.env + project .env) so provider API keys are
58
+ // available no matter which project we're launched in.
59
+ loadConfig();
60
+ // Clear out the temp files and directories earlier runs left behind: screenshots past
61
+ // their retention window, and the scratch (cwd hand-off files, command wrappers, test
62
+ // fixtures) that every call site removes on its way out and nothing removes when a run
63
+ // ends badly. Startup rather than shutdown precisely because that catches what a crash
64
+ // left behind, and detached so a slow or unreadable temp directory cannot delay the UI.
65
+ sweepTempInBackground();
66
+ // Times every frame the renderer writes to the real terminal. No-op unless
67
+ // MINDWEAVE_PERF names a file — see cli/perfLog.ts for why this cannot be measured
68
+ // from a test probe.
69
+ instrumentStdout(process.stdout);
70
+ process.on("exit", flushPerf);
71
+ enterAltScreen();
72
+ // Ink renders into a FRAMEBUFFER rather than straight to the terminal: each frame is
73
+ // parsed into a cell grid, diffed against what is already on screen, and only the
74
+ // cells that actually differ are written. Measured on a transcript-shaped screen,
75
+ // that is ~13x fewer bytes per frame (2,345 -> 178). See `cli/framebuffer/`.
76
+ //
77
+ // `incrementalRendering` is deliberately NOT enabled alongside it, and this is load
78
+ // bearing rather than a preference: that mode makes Ink emit only the LINES it thinks
79
+ // changed, interleaved with its own cursor movements, instead of a complete frame.
80
+ // The framebuffer's parser expects a whole frame — a partial one would be read as a
81
+ // full screen and everything it omitted would be blanked. One diff or the other, and
82
+ // ours is per-cell where Ink's is per-line.
83
+ // The frame-rate cap is what sets typing latency — see `cli/frameRate.ts` for the
84
+ // measurements and for why it is a timer rather than a cost.
85
+ render(createElement(App), {
86
+ maxFps: MAX_FPS,
87
+ stdout: framebufferStdout(process.stdout, perfEnabled() ? (s) => perf(`frame in=${s.inBytes} out=${s.outBytes}`) : undefined),
88
+ });
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}