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,266 @@
1
+ /**
2
+ * parse.ts — Ink's frame string into a cell grid.
3
+ *
4
+ * Ink hands the terminal one string per frame: lines separated by `\n`, with SGR
5
+ * escape sequences (`\x1b[...m`) inline wherever the style changes. To diff frames
6
+ * cell by cell we first have to know what each frame ACTUALLY PUTS in each cell,
7
+ * which means interpreting those sequences the way a terminal would.
8
+ *
9
+ * So this is a very small terminal emulator: it walks the string carrying the
10
+ * current pen (foreground, background, attributes), and every printable character
11
+ * it meets is stamped into the grid at the cursor, which then advances.
12
+ *
13
+ * ## Scope, deliberately
14
+ *
15
+ * It handles what Ink emits and nothing else. Ink's frame content is styled text
16
+ * and newlines — it does not move the cursor around inside a frame, because it
17
+ * builds the whole frame as a string first (see `ink/build/ink.js`, which writes
18
+ * `eraseLines(previousHeight) + wrappedOutput`). Any other CSI sequence is SKIPPED
19
+ * rather than guessed at: skipping leaves the grid exactly as it was, which is the
20
+ * safe direction to be wrong in, where guessing would corrupt every cell after it.
21
+ *
22
+ * The one non-SGR sequence that matters is the `eraseLines` prefix, and the caller
23
+ * strips that before we ever see it — see `writer.ts`.
24
+ */
25
+ import { ATTR, DEFAULT_COLOR, WIDE_CONTINUATION, paletteColor, rgbColor, } from "./screen.js";
26
+ import { eastAsianWidth } from "get-east-asian-width";
27
+ /** A fresh pen: the terminal's own colours, no attributes. */
28
+ function resetPen(pen) {
29
+ pen.fg = DEFAULT_COLOR;
30
+ pen.bg = DEFAULT_COLOR;
31
+ pen.attrs = 0;
32
+ }
33
+ /**
34
+ * Apply one SGR sequence's parameters to the pen.
35
+ *
36
+ * Returns nothing; mutates `pen`. Written as a loop with an index rather than a
37
+ * `for..of` because the extended colour forms (`38;5;n` and `38;2;r;g;b`) consume
38
+ * following parameters, so the cursor into the list has to move by more than one.
39
+ */
40
+ function applySgr(pen, params) {
41
+ if (params.length === 0) {
42
+ // A bare `\x1b[m` is `\x1b[0m` — a full reset.
43
+ resetPen(pen);
44
+ return;
45
+ }
46
+ for (let i = 0; i < params.length; i++) {
47
+ const p = params[i];
48
+ switch (p) {
49
+ case 0:
50
+ resetPen(pen);
51
+ break;
52
+ case 1:
53
+ pen.attrs |= ATTR.bold;
54
+ break;
55
+ case 2:
56
+ pen.attrs |= ATTR.dim;
57
+ break;
58
+ case 3:
59
+ pen.attrs |= ATTR.italic;
60
+ break;
61
+ case 4:
62
+ pen.attrs |= ATTR.underline;
63
+ break;
64
+ case 7:
65
+ pen.attrs |= ATTR.inverse;
66
+ break;
67
+ case 8:
68
+ pen.attrs |= ATTR.hidden;
69
+ break;
70
+ case 9:
71
+ pen.attrs |= ATTR.strikethrough;
72
+ break;
73
+ // 21/22 both end bold. 22 also ends dim, and clearing both for either is
74
+ // deliberate: chalk emits 22 to close a bold span, and leaving dim set would
75
+ // tint every cell after it.
76
+ case 21:
77
+ case 22:
78
+ pen.attrs &= ~(ATTR.bold | ATTR.dim);
79
+ break;
80
+ case 23:
81
+ pen.attrs &= ~ATTR.italic;
82
+ break;
83
+ case 24:
84
+ pen.attrs &= ~ATTR.underline;
85
+ break;
86
+ case 27:
87
+ pen.attrs &= ~ATTR.inverse;
88
+ break;
89
+ case 28:
90
+ pen.attrs &= ~ATTR.hidden;
91
+ break;
92
+ case 29:
93
+ pen.attrs &= ~ATTR.strikethrough;
94
+ break;
95
+ case 39:
96
+ pen.fg = DEFAULT_COLOR;
97
+ break;
98
+ case 49:
99
+ pen.bg = DEFAULT_COLOR;
100
+ break;
101
+ case 38:
102
+ case 48: {
103
+ // Extended colour: `38;5;n` (palette) or `38;2;r;g;b` (truecolour).
104
+ const isFg = p === 38;
105
+ const mode = params[i + 1];
106
+ if (mode === 5 && params.length > i + 2) {
107
+ const c = paletteColor(params[i + 2]);
108
+ if (isFg)
109
+ pen.fg = c;
110
+ else
111
+ pen.bg = c;
112
+ i += 2;
113
+ }
114
+ else if (mode === 2 && params.length > i + 4) {
115
+ const c = rgbColor(params[i + 2], params[i + 3], params[i + 4]);
116
+ if (isFg)
117
+ pen.fg = c;
118
+ else
119
+ pen.bg = c;
120
+ i += 4;
121
+ }
122
+ else {
123
+ // Malformed — consume the mode byte and carry on rather than
124
+ // misreading the remaining parameters as colours.
125
+ i += 1;
126
+ }
127
+ break;
128
+ }
129
+ default:
130
+ if (p >= 30 && p <= 37)
131
+ pen.fg = paletteColor(p - 30);
132
+ else if (p >= 90 && p <= 97)
133
+ pen.fg = paletteColor(p - 90 + 8);
134
+ else if (p >= 40 && p <= 47)
135
+ pen.bg = paletteColor(p - 40);
136
+ else if (p >= 100 && p <= 107)
137
+ pen.bg = paletteColor(p - 100 + 8);
138
+ // Anything else is a code we do not model. Ignored, not guessed.
139
+ break;
140
+ }
141
+ }
142
+ }
143
+ /** Reset a run of cells to default-styled blanks, the way an erase sequence does. */
144
+ function blank(screen, from, to) {
145
+ const lo = Math.max(0, Math.min(from, screen.chars.length));
146
+ const hi = Math.max(lo, Math.min(to, screen.chars.length));
147
+ screen.chars.fill(32, lo, hi);
148
+ screen.fg.fill(DEFAULT_COLOR, lo, hi);
149
+ screen.bg.fill(DEFAULT_COLOR, lo, hi);
150
+ screen.attrs.fill(0, lo, hi);
151
+ }
152
+ /**
153
+ * Draw `frame` into `screen`, starting at row `top`.
154
+ *
155
+ * The screen is NOT cleared first — the caller decides that, because a resize
156
+ * wants a clean grid while an ordinary frame is a complete repaint of the rows it
157
+ * covers and clearing would be redundant work. Rows the frame does not reach are
158
+ * left alone.
159
+ */
160
+ export function parseFrame(screen, frame, top = 0) {
161
+ const pen = { fg: DEFAULT_COLOR, bg: DEFAULT_COLOR, attrs: 0 };
162
+ let x = 0;
163
+ let y = top;
164
+ for (let i = 0; i < frame.length;) {
165
+ const ch = frame[i];
166
+ if (ch === "") {
167
+ // CSI: ESC [ params... final-byte
168
+ if (frame[i + 1] === "[") {
169
+ let j = i + 2;
170
+ while (j < frame.length) {
171
+ const c = frame.charCodeAt(j);
172
+ // Parameter bytes are 0x30-0x3F, intermediates 0x20-0x2F; the final byte
173
+ // is 0x40-0x7E and ends the sequence.
174
+ if (c >= 0x40 && c <= 0x7e)
175
+ break;
176
+ j++;
177
+ }
178
+ const final = frame[j];
179
+ const body = frame.slice(i + 2, j);
180
+ const params = body === "" ? [] : body.split(";").map((s) => (s === "" ? 0 : Number.parseInt(s, 10) || 0));
181
+ if (final === "m") {
182
+ applySgr(pen, params);
183
+ }
184
+ else if (final === "H" || final === "f") {
185
+ // Absolute cursor position, 1-based on the real screen. `top` is where
186
+ // row 0 of this grid sits, so it comes back off to get a grid row.
187
+ y = (params[0] ?? 1) - 1 + top;
188
+ x = (params[1] ?? 1) - 1;
189
+ }
190
+ else if (final === "C") {
191
+ x += Math.max(1, params[0] ?? 1);
192
+ }
193
+ else if (final === "D") {
194
+ x = Math.max(0, x - Math.max(1, params[0] ?? 1));
195
+ }
196
+ else if (final === "J") {
197
+ // Erase display. A real terminal blanks the cells; skipping it left this
198
+ // parser believing text was still there that the terminal had already wiped,
199
+ // which is a difference that only shows up on a resize (the one time the
200
+ // writer sends one). 2 = whole screen, 1 = up to the cursor, 0 = from it on.
201
+ const mode = params[0] ?? 0;
202
+ const from = mode === 2 ? 0 : mode === 1 ? 0 : y * screen.width + x;
203
+ const to = mode === 2 ? screen.chars.length : mode === 1 ? y * screen.width + x : screen.chars.length;
204
+ blank(screen, from, to);
205
+ }
206
+ else if (final === "K") {
207
+ // Erase in line, same three modes but bounded to the current row.
208
+ const mode = params[0] ?? 0;
209
+ const rowStart = y * screen.width;
210
+ const from = mode === 0 ? rowStart + x : rowStart;
211
+ const to = mode === 1 ? rowStart + x + 1 : rowStart + screen.width;
212
+ blank(screen, from, to);
213
+ }
214
+ // Every other CSI is skipped whole — see the file header.
215
+ i = j + 1;
216
+ continue;
217
+ }
218
+ // A non-CSI escape (OSC, single-character escapes). Skip the ESC and let the
219
+ // following bytes be read normally; Ink does not emit these inside a frame,
220
+ // and dropping one byte is far less damaging than misparsing a run.
221
+ i += 1;
222
+ continue;
223
+ }
224
+ if (ch === "\n") {
225
+ y++;
226
+ x = 0;
227
+ i += 1;
228
+ continue;
229
+ }
230
+ if (ch === "\r") {
231
+ x = 0;
232
+ i += 1;
233
+ continue;
234
+ }
235
+ // A printable character. Read a full codepoint, because a surrogate pair is one
236
+ // character occupying (usually) two columns, and splitting it would write two
237
+ // meaningless halves.
238
+ const code = frame.codePointAt(i);
239
+ const size = code > 0xffff ? 2 : 1;
240
+ i += size;
241
+ if (y >= screen.height || y < 0) {
242
+ // Past the bottom of the grid: keep scanning so the pen stays correct if the
243
+ // frame comes back into range, but write nothing.
244
+ continue;
245
+ }
246
+ const w = eastAsianWidth(code);
247
+ if (x < screen.width) {
248
+ const at = screen.index(x, y);
249
+ screen.chars[at] = code;
250
+ screen.fg[at] = pen.fg;
251
+ screen.bg[at] = pen.bg;
252
+ screen.attrs[at] = pen.attrs;
253
+ // A wide character claims the next column too. Marking it is what keeps every
254
+ // later column on the row aligned with what the terminal will actually do.
255
+ if (w === 2 && x + 1 < screen.width) {
256
+ const next = screen.index(x + 1, y);
257
+ screen.chars[next] = WIDE_CONTINUATION;
258
+ screen.fg[next] = pen.fg;
259
+ screen.bg[next] = pen.bg;
260
+ screen.attrs[next] = pen.attrs;
261
+ }
262
+ }
263
+ x += w;
264
+ }
265
+ }
266
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/cli/framebuffer/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * screen.ts — the cell grid, and the colour model that packs into it.
3
+ *
4
+ * This is the memory the whole framebuffer renderer is built on: one entry per
5
+ * character cell on the terminal, held as a STRUCTURE OF ARRAYS rather than an
6
+ * array of cell objects.
7
+ *
8
+ * Why SoA, concretely: a 200x50 terminal is 10,000 cells. As objects that is
9
+ * 10,000 allocations per frame for the garbage collector to walk, and the fields
10
+ * of one cell land wherever the allocator put them. As four flat typed arrays it
11
+ * is four allocations TOTAL, reused for the life of the process, laid out
12
+ * contiguously so the diff loop reads straight down memory. The diff runs over
13
+ * every cell on every frame, so this is the loop whose cache behaviour decides
14
+ * whether the renderer can hit a frame budget. Same layout OpenTUI's Zig core and
15
+ * ratatui's Buffer use, for the same reason.
16
+ *
17
+ * Everything a cell needs is an integer, so comparing two cells is four integer
18
+ * comparisons and no allocation, no string compare, no property lookup.
19
+ *
20
+ * ## The colour encoding
21
+ *
22
+ * A terminal colour is one of four things, and they must round-trip exactly — a
23
+ * cell that was written as 256-palette colour 33 has to be re-emitted as palette
24
+ * 33, not as its RGB approximation, or the diff would rewrite cells that never
25
+ * actually changed. So the encoding is a tagged integer:
26
+ *
27
+ * 0 default (terminal's own foreground/background)
28
+ * PALETTE | n 256-colour palette index n (0-255)
29
+ * RGB | (r<<16|g<<8|b) 24-bit truecolour
30
+ *
31
+ * The tag lives above the 24 bits of payload, so an entire colour is one Uint32
32
+ * and equality is `===`.
33
+ */
34
+ /** Tag marking a packed colour as a 256-colour palette index. */
35
+ export const PALETTE = 1 << 25;
36
+ /** Tag marking a packed colour as 24-bit RGB. */
37
+ export const RGB = 1 << 26;
38
+ /** The terminal's own default colour — what a cell has when nothing set it. */
39
+ export const DEFAULT_COLOR = 0;
40
+ /** Text attributes, as bit flags in one integer. */
41
+ export const ATTR = {
42
+ bold: 1 << 0,
43
+ dim: 1 << 1,
44
+ italic: 1 << 2,
45
+ underline: 1 << 3,
46
+ inverse: 1 << 4,
47
+ hidden: 1 << 5,
48
+ strikethrough: 1 << 6,
49
+ };
50
+ /**
51
+ * A cell holding the RIGHT half of a double-width character.
52
+ *
53
+ * Wide characters (CJK, most emoji) occupy two terminal columns but are a single
54
+ * character. The left cell carries the codepoint; the right carries this marker so
55
+ * that the diff knows the column is spoken for and the painter knows never to emit
56
+ * anything for it — the terminal advances the cursor two columns by itself when it
57
+ * prints the wide character.
58
+ *
59
+ * It is a distinct value rather than a blank because the difference matters: a
60
+ * blank would be legitimately printable and would desynchronise every column after
61
+ * it on that row.
62
+ */
63
+ export const WIDE_CONTINUATION = 0xffff_ffff;
64
+ /** A grid of terminal cells. */
65
+ export class Screen {
66
+ width;
67
+ height;
68
+ /** Unicode codepoint per cell. 32 (space) is empty; WIDE_CONTINUATION is the
69
+ * right half of a wide character. */
70
+ chars;
71
+ /** Packed foreground colour per cell. */
72
+ fg;
73
+ /** Packed background colour per cell. */
74
+ bg;
75
+ /** Packed attribute flags per cell. */
76
+ attrs;
77
+ constructor(width, height) {
78
+ this.width = Math.max(0, width);
79
+ this.height = Math.max(0, height);
80
+ const n = this.width * this.height;
81
+ this.chars = new Uint32Array(n);
82
+ this.fg = new Uint32Array(n);
83
+ this.bg = new Uint32Array(n);
84
+ this.attrs = new Uint32Array(n);
85
+ this.clear();
86
+ }
87
+ /** Row-major index of a cell. Callers are expected to be in bounds; this is the
88
+ * hot path and a check here would run millions of times a second. */
89
+ index(x, y) {
90
+ return y * this.width + x;
91
+ }
92
+ /** Reset every cell to a default-styled blank. */
93
+ clear() {
94
+ this.chars.fill(32);
95
+ this.fg.fill(DEFAULT_COLOR);
96
+ this.bg.fill(DEFAULT_COLOR);
97
+ this.attrs.fill(0);
98
+ }
99
+ /**
100
+ * Resize, discarding contents.
101
+ *
102
+ * Deliberately does NOT preserve the old grid. A resize re-wraps every line, so
103
+ * the previous contents are not a valid picture of the new screen at any size —
104
+ * keeping them would mean diffing against a frame that never existed and leaving
105
+ * stale text on screen. The caller repaints in full instead.
106
+ *
107
+ * Reuses the existing buffers when the cell count is unchanged (a pure rotation,
108
+ * e.g. 80x50 to 50x80), which is the one case where reallocating would be waste.
109
+ */
110
+ resize(width, height) {
111
+ const w = Math.max(0, width);
112
+ const h = Math.max(0, height);
113
+ const n = w * h;
114
+ if (n !== this.chars.length) {
115
+ this.chars = new Uint32Array(n);
116
+ this.fg = new Uint32Array(n);
117
+ this.bg = new Uint32Array(n);
118
+ this.attrs = new Uint32Array(n);
119
+ }
120
+ this.width = w;
121
+ this.height = h;
122
+ this.clear();
123
+ }
124
+ /** Copy `other` into this screen. Both must be the same size; the caller resizes
125
+ * first. `set` on a typed array is a memcpy, which is the point. */
126
+ copyFrom(other) {
127
+ if (other.width !== this.width || other.height !== this.height) {
128
+ this.resize(other.width, other.height);
129
+ }
130
+ this.chars.set(other.chars);
131
+ this.fg.set(other.fg);
132
+ this.bg.set(other.bg);
133
+ this.attrs.set(other.attrs);
134
+ }
135
+ /** Whether two cells are identical in every respect — the diff's inner test. */
136
+ sameAs(other, i) {
137
+ return (this.chars[i] === other.chars[i] &&
138
+ this.fg[i] === other.fg[i] &&
139
+ this.bg[i] === other.bg[i] &&
140
+ this.attrs[i] === other.attrs[i]);
141
+ }
142
+ }
143
+ /** Pack a 256-colour palette index. */
144
+ export function paletteColor(index) {
145
+ return PALETTE | (index & 0xff);
146
+ }
147
+ /** Pack a 24-bit RGB colour. */
148
+ export function rgbColor(r, g, b) {
149
+ return RGB | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
150
+ }
151
+ /**
152
+ * The SGR parameters that produce `color` as a foreground (`fg`) or background.
153
+ *
154
+ * Returns the numeric parameters rather than a finished escape string so the
155
+ * painter can join a whole cell's worth — colour, background and attributes — into
156
+ * ONE `\x1b[...m` instead of three. Fewer, longer sequences is measurably less to
157
+ * write than more, shorter ones.
158
+ */
159
+ export function colorParams(color, fg) {
160
+ if (color === DEFAULT_COLOR)
161
+ return [fg ? 39 : 49];
162
+ if (color & RGB) {
163
+ const v = color & 0xff_ffff;
164
+ return [fg ? 38 : 48, 2, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];
165
+ }
166
+ const index = color & 0xff;
167
+ // The first 16 palette entries have short, universally supported forms. Worth the
168
+ // branch: they are by far the most common colours a TUI actually uses, and the
169
+ // short form is 3-4 bytes against 11 for the indexed form, on every cell that
170
+ // changes colour.
171
+ if (index < 8)
172
+ return [(fg ? 30 : 40) + index];
173
+ if (index < 16)
174
+ return [(fg ? 90 : 100) + (index - 8)];
175
+ return [fg ? 38 : 48, 5, index];
176
+ }
177
+ /** The SGR parameters that turn `attrs` on, assuming a reset state. */
178
+ export function attrParams(attrs) {
179
+ const out = [];
180
+ if (attrs & ATTR.bold)
181
+ out.push(1);
182
+ if (attrs & ATTR.dim)
183
+ out.push(2);
184
+ if (attrs & ATTR.italic)
185
+ out.push(3);
186
+ if (attrs & ATTR.underline)
187
+ out.push(4);
188
+ if (attrs & ATTR.inverse)
189
+ out.push(7);
190
+ if (attrs & ATTR.hidden)
191
+ out.push(8);
192
+ if (attrs & ATTR.strikethrough)
193
+ out.push(9);
194
+ return out;
195
+ }
196
+ //# sourceMappingURL=screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../../../src/cli/framebuffer/screen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * writer.ts — sits between Ink and the terminal, and writes only what changed.
3
+ *
4
+ * Ink's contract with the terminal is "erase everything I drew last time, then draw
5
+ * all of it again", on every render. That is tens of kilobytes per frame on a large
6
+ * terminal, pushed through a write that blocks the event loop on Windows — which is
7
+ * why typing and scrolling lag in proportion to how much is on screen rather than
8
+ * how much actually changed.
9
+ *
10
+ * This replaces that contract with a framebuffer:
11
+ *
12
+ * Ink renders a frame -> parse it into a cell grid -> diff against the grid
13
+ * already on screen -> emit only the cells that differ -> keep the new grid
14
+ *
15
+ * Ink is untouched, and so is every component. The interception is a PROXY STDOUT
16
+ * handed to `render()`, not a patch of `process.stdout`: everything arriving here is
17
+ * therefore known to be Ink's renderer output, where a global patch would also catch
18
+ * unrelated writes and have to guess which was which.
19
+ *
20
+ * ## What is passed through untouched
21
+ *
22
+ * Only frame CONTENT can be diffed. Control sequences that are not a frame — entering
23
+ * the alternate screen, hiding the cursor, the synchronized-update markers Ink wraps
24
+ * frames in — carry no cells and are forwarded exactly as sent. The test is whether a
25
+ * write contains anything printable once its escape sequences are removed.
26
+ */
27
+ import { Screen } from "./screen.js";
28
+ import { parseFrame } from "./parse.js";
29
+ import { paint } from "./paint.js";
30
+ /**
31
+ * The prefix Ink puts before a frame to remove the previous one:
32
+ * `\x1b[2K` (erase line) and `\x1b[1A` (cursor up) repeated, then `\x1b[G`.
33
+ *
34
+ * We drop it. The whole point of the framebuffer is that the previous frame is NOT
35
+ * erased — the parts of it that are still correct stay on screen untouched, which is
36
+ * exactly the work being saved.
37
+ */
38
+ const ERASE_PREFIX = /^(?:\x1b\[2K(?:\x1b\[1A)?)+\x1b\[G/;
39
+ /** Any escape sequence, for deciding whether a write carries visible content. */
40
+ const ANY_ESCAPE = /\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[[\]()#;?]*[0-9;]*[A-Za-z]|\x1b./g;
41
+ /**
42
+ * Wrap `real` so Ink's frames are diffed before they reach it.
43
+ *
44
+ * `onFrame` is called after each frame with what it cost, so the perf log can report
45
+ * the saving without this module knowing anything about logging.
46
+ */
47
+ export function framebufferStdout(real, onFrame) {
48
+ // The grid currently on the terminal, and the one being built for this frame. Two
49
+ // long-lived buffers, swapped — never reallocated per frame, which is the whole
50
+ // reason the cell data is in typed arrays.
51
+ let onScreen = new Screen(real.columns ?? 80, real.rows ?? 24);
52
+ let pending = new Screen(onScreen.width, onScreen.height);
53
+ /**
54
+ * Match the grids to the terminal. Returns true when the size changed, which the
55
+ * caller must answer by erasing the real screen before it paints.
56
+ *
57
+ * The erase is the whole point and it used to be missing. Resizing reset `onScreen`
58
+ * to blanks, on the reasoning that a blank model would make every cell differ and
59
+ * force a full repaint. It does the opposite: the new frame's blank regions are also
60
+ * blanks, so the diff finds them identical and writes nothing for them, while the real
61
+ * terminal still holds whatever was in those cells before. That is what fused an old
62
+ * line onto a new one, leaving rows like `Tools(session)s, ask_user, create_skill,`.
63
+ *
64
+ * Erasing for real is also the cheap fix rather than the expensive one. Filling the
65
+ * model with a sentinel no cell can equal would work too, and would then write every
66
+ * space on screen as an explicit character. One escape sequence costs four bytes and
67
+ * leaves the diff free to stay minimal for the frame itself.
68
+ */
69
+ function syncSize() {
70
+ const w = real.columns ?? onScreen.width;
71
+ const h = real.rows ?? onScreen.height;
72
+ if (w === onScreen.width && h === onScreen.height)
73
+ return false;
74
+ onScreen.resize(w, h);
75
+ pending.resize(w, h);
76
+ // Now TRUE rather than assumed: the model says blank, and the caller is about to
77
+ // make the terminal blank to match.
78
+ onScreen.clear();
79
+ return true;
80
+ }
81
+ /**
82
+ * Replaces `write` and nothing else.
83
+ *
84
+ * A hand-written object listing the members Ink "needs" was tried first and BROKE
85
+ * THE APP: Ink reads `stdout.isTTY` in five places to decide whether it is driving
86
+ * a terminal at all, the substitute did not have it, and Ink quietly took its
87
+ * non-interactive path — a blank screen, no error. The tests did not catch it
88
+ * because they pass a fake stdout that has no `isTTY` either, so both sides agreed
89
+ * on the wrong thing.
90
+ *
91
+ * A Proxy is the fix that cannot have that class of bug again: every property, every
92
+ * method, the prototype and `instanceof` all still resolve to the real stream, and
93
+ * only `write` is ours. Nothing has to be enumerated, so nothing can be forgotten.
94
+ */
95
+ const fbWrite = (data, callback) => {
96
+ const body = data.replace(ERASE_PREFIX, "");
97
+ // No printable content: a control sequence, not a frame. Forward verbatim —
98
+ // these are how the alternate screen is entered, the cursor hidden, and frames
99
+ // wrapped in synchronized-update markers, none of which we may swallow.
100
+ if (body.replace(ANY_ESCAPE, "").trim() === "") {
101
+ return real.write(data, callback);
102
+ }
103
+ const resized = syncSize();
104
+ // Build the new frame. Cleared first because a frame is a complete statement
105
+ // about the rows it covers: a line that got shorter must leave blanks behind,
106
+ // not the tail of what used to be there.
107
+ pending.clear();
108
+ parseFrame(pending, body);
109
+ // `` erases the display, `` homes the cursor. Sent only on a resize,
110
+ // to bring the real screen into line with the freshly blanked model above.
111
+ const escape = (resized ? "" : "") + paint(onScreen, pending, 1);
112
+ // Swap rather than copy. Both grids are the same shape and `pending` is fully
113
+ // rewritten at the start of every frame, so the old on-screen grid is free to
114
+ // become the next scratch buffer — no allocation, no memcpy.
115
+ const previous = onScreen;
116
+ onScreen = pending;
117
+ pending = previous;
118
+ onFrame?.({ inBytes: data.length, outBytes: escape.length });
119
+ if (escape === "") {
120
+ // Nothing changed. Writing zero bytes is the correct output, but the caller
121
+ // may be waiting on the callback, so it still has to be settled.
122
+ callback?.(null);
123
+ return true;
124
+ }
125
+ return real.write(escape, callback);
126
+ };
127
+ return new Proxy(real, {
128
+ get(target, prop, receiver) {
129
+ if (prop === "write")
130
+ return fbWrite;
131
+ const value = Reflect.get(target, prop, target);
132
+ // Methods are bound to the REAL stream, not to the proxy. A stream's own
133
+ // methods reach into its internal state, and calling them with the proxy as
134
+ // `this` would have them look for that state on the wrong object.
135
+ return typeof value === "function" ? value.bind(target) : value;
136
+ },
137
+ });
138
+ }
139
+ //# sourceMappingURL=writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../../src/cli/framebuffer/writer.ts"],"names":[],"mappings":"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"}