rovecode 0.3.3 → 0.4.0-beta.3

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 (495) hide show
  1. package/CHANGELOG.md +527 -0
  2. package/README.md +46 -48
  3. package/bin/rovecode.js +24 -0
  4. package/dist/cli/app-j6gn14w3.js +2 -0
  5. package/dist/cli/ask-user-cwstt8fz.js +2 -0
  6. package/dist/cli/auth-login-9bbp9915.js +2 -0
  7. package/dist/cli/auth-m8p9grty.js +2 -0
  8. package/dist/cli/bench-16zqdms5.js +9 -0
  9. package/dist/cli/catalog-1xchffa4.js +2 -0
  10. package/dist/cli/cli-1n1zb64f.js +2 -0
  11. package/dist/cli/client-2t9gjkck.js +2 -0
  12. package/dist/cli/commands-exafvm2b.js +2 -0
  13. package/dist/cli/connect-6zde0kn3.js +2 -0
  14. package/dist/cli/context-cmd-5t43wgqt.js +2 -0
  15. package/dist/cli/context-report-kt01pw8y.js +2 -0
  16. package/dist/cli/count-remote-ap7x3vh6.js +2 -0
  17. package/dist/cli/design-ne5zszyh.js +2 -0
  18. package/dist/cli/dispatch-2r5myxye.js +2 -0
  19. package/dist/cli/doctor-ws4fh4tn.js +3 -0
  20. package/dist/cli/executor-bdrjn634.js +2 -0
  21. package/dist/cli/export-1mxb9g5p.js +2 -0
  22. package/dist/cli/files-g104xghh.js +2 -0
  23. package/dist/cli/gauntlet-07xrjpj7.js +2 -0
  24. package/dist/cli/gauntlet-runner-xvy64436.js +10 -0
  25. package/dist/cli/gauntlet-wave3-jm91yt5w.js +5 -0
  26. package/dist/cli/gauntlet-wave4-r13py7p1.js +14 -0
  27. package/dist/cli/hashline-znvrat11.js +2 -0
  28. package/dist/cli/http-xafw6fsh.js +143 -0
  29. package/dist/cli/index-1sgjm25y.js +2 -0
  30. package/dist/cli/init-g2m0tn4m.js +51 -0
  31. package/dist/cli/install-avaqjjqq.js +2 -0
  32. package/dist/cli/loop-mmpfft01.js +2 -0
  33. package/dist/cli/main-0904f6ps.js +5 -0
  34. package/dist/cli/main-0ab9fc26.js +9 -0
  35. package/dist/cli/main-0jys2ccn.js +3 -0
  36. package/dist/cli/main-0mtcdbs7.js +3 -0
  37. package/dist/cli/main-0z1w2zsg.js +3 -0
  38. package/dist/cli/main-1dchs7xv.js +18 -0
  39. package/dist/cli/main-1ereejm1.js +3 -0
  40. package/dist/cli/main-1k1kw6b5.js +3 -0
  41. package/dist/cli/main-27y4sm2k.js +38 -0
  42. package/dist/cli/main-2wwjex5j.js +58 -0
  43. package/dist/cli/main-2yeveeve.js +6 -0
  44. package/dist/cli/main-2yfck9b5.js +3 -0
  45. package/dist/cli/main-2zmzgkwh.js +3 -0
  46. package/dist/cli/main-351pz3z7.js +7 -0
  47. package/dist/cli/main-3gjqfh7a.js +6 -0
  48. package/dist/cli/main-3nf3kgve.js +3 -0
  49. package/dist/cli/main-3pjrb2hd.js +3 -0
  50. package/dist/cli/main-3rxcvgna.js +19 -0
  51. package/dist/cli/main-4b3jgy66.js +19 -0
  52. package/dist/cli/main-4wndhjdc.js +7 -0
  53. package/dist/cli/main-4xcmvxnk.js +3 -0
  54. package/dist/cli/main-5tbz0wbz.js +4 -0
  55. package/dist/cli/main-5ywnwthm.js +3 -0
  56. package/dist/cli/main-6b62vkz0.js +14 -0
  57. package/dist/cli/main-6dnk69vp.js +3 -0
  58. package/dist/cli/main-6genrmhs.js +136 -0
  59. package/dist/cli/main-73g7eff4.js +15 -0
  60. package/dist/cli/main-7c5thhjd.js +5 -0
  61. package/dist/cli/main-7rn6bqje.js +3 -0
  62. package/dist/cli/main-80haw7qk.js +4 -0
  63. package/dist/cli/main-875s60s2.js +4 -0
  64. package/dist/cli/main-8kjxbpw4.js +8 -0
  65. package/dist/cli/main-90ds1z4e.js +10 -0
  66. package/dist/cli/main-9etavkew.js +3 -0
  67. package/dist/cli/main-a9njrkk1.js +3 -0
  68. package/dist/cli/main-aecrjq2d.js +12 -0
  69. package/dist/cli/main-ck9asesq.js +9 -0
  70. package/dist/cli/main-cta9racd.js +4 -0
  71. package/dist/cli/main-ddv7j2ag.js +3 -0
  72. package/dist/cli/main-dfreez27.js +10 -0
  73. package/dist/cli/main-f7rw7des.js +3 -0
  74. package/dist/cli/main-ggcn7rd7.js +5 -0
  75. package/dist/cli/main-gzkmycnv.js +3 -0
  76. package/dist/cli/main-hq51jg8v.js +18 -0
  77. package/dist/cli/main-jft389w9.js +8 -0
  78. package/dist/cli/main-k1eqkg83.js +3 -0
  79. package/dist/cli/main-k2y8a2aw.js +9 -0
  80. package/dist/cli/main-kcpbykxz.js +4 -0
  81. package/dist/cli/main-kd488vje.js +22 -0
  82. package/dist/cli/main-kh32yvgk.js +5 -0
  83. package/dist/cli/main-kqxnqjnv.js +25 -0
  84. package/dist/cli/main-kyn0xnsg.js +3 -0
  85. package/dist/cli/main-m1kk6fp5.js +21 -0
  86. package/dist/cli/main-mv40pcr2.js +4 -0
  87. package/dist/cli/main-n0t3973w.js +3 -0
  88. package/dist/cli/main-nqveez48.js +4 -0
  89. package/dist/cli/main-pknhvrmj.js +3 -0
  90. package/dist/cli/main-pn1w7a7j.js +3 -0
  91. package/dist/cli/main-prxxs70n.js +4 -0
  92. package/dist/cli/main-q3vsesf9.js +3 -0
  93. package/dist/cli/main-qsevpgsv.js +3 -0
  94. package/dist/cli/main-rdgdw24b.js +25 -0
  95. package/dist/cli/main-rfth4tbm.js +16 -0
  96. package/dist/cli/main-rg0wn0xf.js +5 -0
  97. package/dist/cli/main-sdmxhtv8.js +4 -0
  98. package/dist/cli/main-skbp13js.js +18 -0
  99. package/dist/cli/main-t4xnd213.js +7 -0
  100. package/dist/cli/main-vqak588n.js +4 -0
  101. package/dist/cli/main-w2n1303f.js +9 -0
  102. package/dist/cli/main-wbrdspr2.js +5 -0
  103. package/dist/cli/main-wsrg79c1.js +7 -0
  104. package/dist/cli/main-x4r0fne4.js +5 -0
  105. package/dist/cli/main-xea2f3tn.js +6 -0
  106. package/dist/cli/main-xg704a3c.js +3 -0
  107. package/dist/cli/main-xvnrabfp.js +16 -0
  108. package/dist/cli/main-xy53xf0r.js +4 -0
  109. package/dist/cli/main-y1fqy60y.js +3 -0
  110. package/dist/cli/main-yn8cd281.js +34 -0
  111. package/dist/cli/main-yr0ksc0h.js +4 -0
  112. package/dist/cli/main-z2ex2vyf.js +4 -0
  113. package/dist/cli/main-z3aayzvq.js +3 -0
  114. package/dist/cli/main-zaqh35jg.js +3 -0
  115. package/dist/cli/main-zc2e8e46.js +4 -0
  116. package/dist/cli/main-zzrfw6cf.js +13 -0
  117. package/dist/cli/main.js +280 -0
  118. package/dist/cli/market-cmd-e14kmx9n.js +5 -0
  119. package/dist/cli/mcp-login-wq7ktdek.js +2 -0
  120. package/dist/cli/mcp-market-cmd-9mg3jecy.js +2 -0
  121. package/dist/cli/notify-b7qc0cjb.js +2 -0
  122. package/dist/cli/oauth-z8whcgfx.js +2 -0
  123. package/dist/cli/output-b3ewj3ps.js +16 -0
  124. package/dist/cli/profiles-6mr5he5e.js +2 -0
  125. package/dist/cli/provider-config-g7j42q8x.js +2 -0
  126. package/dist/cli/provider-jr1y8vvm.js +2 -0
  127. package/dist/cli/registry-s8yk86g0.js +2 -0
  128. package/dist/cli/registry-t6p8d4mn.js +2 -0
  129. package/dist/cli/repl-bajwe1mh.js +11 -0
  130. package/dist/cli/resume-rwn9nz7y.js +2 -0
  131. package/dist/cli/run-flags-nah7ndpt.js +2 -0
  132. package/dist/cli/runtime-n7gafzhb.js +2 -0
  133. package/dist/cli/sandbox-config-emdy18x4.js +2 -0
  134. package/dist/cli/server-b0nvs2bn.js +5 -0
  135. package/dist/cli/session-arg-y75wd4kj.js +2 -0
  136. package/dist/cli/session-j62evmjq.js +2 -0
  137. package/dist/cli/sessions-cmd-tsnwz0ns.js +7 -0
  138. package/dist/cli/settings-df10wfez.js +2 -0
  139. package/dist/cli/setup-jzvv72fg.js +2 -0
  140. package/dist/cli/sextant-smoke-37m81ke6.js +5 -0
  141. package/dist/cli/skills-cmd-gjxnxnhx.js +2 -0
  142. package/dist/cli/smoke-p7748apt.js +8 -0
  143. package/dist/cli/start-chat-s4st3mm0.js +12 -0
  144. package/dist/cli/stream-gmeyewds.js +2 -0
  145. package/dist/cli/task-gh0kkp3n.js +2 -0
  146. package/dist/cli/tasks-z1kfpe8e.js +2 -0
  147. package/dist/cli/thinking-0eqkrz6t.js +2 -0
  148. package/dist/cli/todo-5brcrt9m.js +2 -0
  149. package/dist/cli/tools-7pzm0vj9.js +2 -0
  150. package/dist/cli/tools-s635p6s8.js +2 -0
  151. package/dist/cli/trust-cmd-cjav8zgm.js +2 -0
  152. package/dist/cli/update-check-pt31bm2f.js +2 -0
  153. package/dist/cli/update-cmd-tk131s9t.js +2 -0
  154. package/dist/cli/voice-56nabd8d.js +2 -0
  155. package/dist/cli/webfetch-xd8q596m.js +2 -0
  156. package/dist/cli/websearch-5hkf98k1.js +2 -0
  157. package/dist/cli/workflow-cmd-cy3cvzjp.js +4 -0
  158. package/dist/cli/workspace-q10g5z3e.js +2 -0
  159. package/dist/lib/index.js +62 -0
  160. package/dist/lib/models-index.json +1 -0
  161. package/dist/lib/plugins.js +55 -0
  162. package/dist/lib/providers.js +17 -0
  163. package/dist/lib/public-api.js +20 -0
  164. package/dist/lib/sdk.js +360 -0
  165. package/package.json +84 -72
  166. package/bin/rovecode.ts +0 -21
  167. package/src/acp/server.ts +0 -374
  168. package/src/cli/auth-login.ts +0 -122
  169. package/src/cli/connect.ts +0 -244
  170. package/src/cli/context-cmd.ts +0 -199
  171. package/src/cli/dispatch.ts +0 -82
  172. package/src/cli/doctor.ts +0 -362
  173. package/src/cli/export.ts +0 -276
  174. package/src/cli/help.ts +0 -293
  175. package/src/cli/is-tui-invocation.ts +0 -8
  176. package/src/cli/main.ts +0 -583
  177. package/src/cli/market-cmd.ts +0 -658
  178. package/src/cli/mcp-login.ts +0 -141
  179. package/src/cli/mcp-market-cmd.ts +0 -302
  180. package/src/cli/output.ts +0 -382
  181. package/src/cli/repl.ts +0 -250
  182. package/src/cli/repomap-root.ts +0 -14
  183. package/src/cli/resume.ts +0 -57
  184. package/src/cli/run-flags.ts +0 -43
  185. package/src/cli/run-limits.ts +0 -78
  186. package/src/cli/runtime.ts +0 -931
  187. package/src/cli/session-arg.ts +0 -30
  188. package/src/cli/sessions-cmd.ts +0 -145
  189. package/src/cli/setup.ts +0 -153
  190. package/src/cli/skills-cmd.ts +0 -194
  191. package/src/cli/start-chat.ts +0 -65
  192. package/src/cli/trust-cmd.ts +0 -52
  193. package/src/coding/bash.ts +0 -148
  194. package/src/coding/checkpoints.ts +0 -327
  195. package/src/coding/diff.ts +0 -138
  196. package/src/coding/files.ts +0 -341
  197. package/src/coding/hashline.ts +0 -274
  198. package/src/coding/lsp-gate.ts +0 -254
  199. package/src/coding/lsp-servers.ts +0 -147
  200. package/src/coding/lsp.ts +0 -283
  201. package/src/coding/repomap-cache.ts +0 -99
  202. package/src/coding/repomap-files.ts +0 -192
  203. package/src/coding/repomap.ts +0 -481
  204. package/src/core/agents.ts +0 -255
  205. package/src/core/compaction.ts +0 -259
  206. package/src/core/config.ts +0 -289
  207. package/src/core/context-report.ts +0 -228
  208. package/src/core/context.ts +0 -60
  209. package/src/core/count-remote.ts +0 -107
  210. package/src/core/execpolicy-rules.ts +0 -196
  211. package/src/core/execpolicy.ts +0 -385
  212. package/src/core/executor.ts +0 -454
  213. package/src/core/guardrails.ts +0 -400
  214. package/src/core/hooks.ts +0 -411
  215. package/src/core/images.ts +0 -230
  216. package/src/core/intro.ts +0 -266
  217. package/src/core/loop.ts +0 -567
  218. package/src/core/modes.ts +0 -372
  219. package/src/core/orchestrator.ts +0 -245
  220. package/src/core/proc-group.ts +0 -48
  221. package/src/core/project-trust.ts +0 -98
  222. package/src/core/reflection.ts +0 -165
  223. package/src/core/sandbox-config.ts +0 -186
  224. package/src/core/session-id.ts +0 -24
  225. package/src/core/session-images.ts +0 -73
  226. package/src/core/session-ops.ts +0 -183
  227. package/src/core/session-text.ts +0 -29
  228. package/src/core/session.ts +0 -469
  229. package/src/core/settings.ts +0 -170
  230. package/src/core/tasks.ts +0 -646
  231. package/src/core/token-scale.ts +0 -108
  232. package/src/core/tools.ts +0 -309
  233. package/src/core/trust.ts +0 -104
  234. package/src/core/types.ts +0 -330
  235. package/src/core/update-check.ts +0 -171
  236. package/src/core/usage.ts +0 -204
  237. package/src/core/validate.ts +0 -121
  238. package/src/core/verify-gate.ts +0 -159
  239. package/src/core/verify.ts +0 -236
  240. package/src/core/voice.ts +0 -158
  241. package/src/core/win-job.ts +0 -183
  242. package/src/core/workspace.ts +0 -184
  243. package/src/design/audit.ts +0 -797
  244. package/src/design/direction.ts +0 -190
  245. package/src/design/rules.ts +0 -157
  246. package/src/eval/bench.ts +0 -150
  247. package/src/eval/gauntlet-runner.ts +0 -215
  248. package/src/eval/gauntlet-support.ts +0 -84
  249. package/src/eval/gauntlet-wave3.ts +0 -269
  250. package/src/eval/gauntlet-wave4.ts +0 -217
  251. package/src/eval/gauntlet.ts +0 -253
  252. package/src/index.ts +0 -17
  253. package/src/lanes/agy.ts +0 -95
  254. package/src/lanes/approval.ts +0 -24
  255. package/src/lanes/claude.ts +0 -129
  256. package/src/lanes/codex.ts +0 -127
  257. package/src/lanes/events.ts +0 -130
  258. package/src/lanes/job.ts +0 -142
  259. package/src/lanes/opencode.ts +0 -122
  260. package/src/lanes/process.ts +0 -184
  261. package/src/lanes/progress.ts +0 -183
  262. package/src/lanes/registry.ts +0 -178
  263. package/src/lanes/runner.ts +0 -124
  264. package/src/lanes/types.ts +0 -112
  265. package/src/market/catalogs/mcp-docs.json +0 -111
  266. package/src/market/catalogs/plugins.json +0 -111
  267. package/src/market/catalogs/skills.json +0 -478
  268. package/src/market/clone.ts +0 -72
  269. package/src/market/context-cost.ts +0 -121
  270. package/src/market/digest.ts +0 -106
  271. package/src/market/index.ts +0 -22
  272. package/src/market/install.ts +0 -578
  273. package/src/market/manifest.ts +0 -187
  274. package/src/market/prereq.ts +0 -145
  275. package/src/market/registry.ts +0 -363
  276. package/src/market/resolve.ts +0 -111
  277. package/src/market/types.ts +0 -236
  278. package/src/market/validate.ts +0 -227
  279. package/src/mcp/client.ts +0 -449
  280. package/src/mcp/config.ts +0 -252
  281. package/src/mcp/local-package.ts +0 -211
  282. package/src/mcp/market-catalog.ts +0 -84
  283. package/src/mcp/market-install.ts +0 -289
  284. package/src/mcp/market.ts +0 -362
  285. package/src/mcp/oauth.ts +0 -251
  286. package/src/mcp/prompts-resources.ts +0 -249
  287. package/src/mcp/shared.ts +0 -149
  288. package/src/mcp/status.ts +0 -67
  289. package/src/mcp/tools.ts +0 -275
  290. package/src/mcp/transport.ts +0 -122
  291. package/src/mcp/trust.ts +0 -25
  292. package/src/memory/blocks.ts +0 -278
  293. package/src/memory/recall.ts +0 -355
  294. package/src/memory/scope.ts +0 -182
  295. package/src/memory/store.ts +0 -105
  296. package/src/memory/tools.ts +0 -99
  297. package/src/plugins/cli.ts +0 -119
  298. package/src/plugins/discover.ts +0 -108
  299. package/src/plugins/index.ts +0 -50
  300. package/src/plugins/install.ts +0 -184
  301. package/src/plugins/load.ts +0 -124
  302. package/src/plugins/manifest.ts +0 -92
  303. package/src/plugins/state.ts +0 -83
  304. package/src/providers/auth.ts +0 -408
  305. package/src/providers/cache.ts +0 -223
  306. package/src/providers/catalog-local.ts +0 -160
  307. package/src/providers/catalog.ts +0 -421
  308. package/src/providers/middleware-context.ts +0 -86
  309. package/src/providers/middleware.ts +0 -373
  310. package/src/providers/model-list.ts +0 -23
  311. package/src/providers/oauth/common.ts +0 -105
  312. package/src/providers/oauth/device-code.ts +0 -107
  313. package/src/providers/oauth/github-copilot.ts +0 -146
  314. package/src/providers/oauth/loopback.ts +0 -158
  315. package/src/providers/oauth/openai.ts +0 -163
  316. package/src/providers/oauth/openrouter.ts +0 -89
  317. package/src/providers/oauth/pkce.ts +0 -45
  318. package/src/providers/oauth/registry.ts +0 -39
  319. package/src/providers/oauth/seam.ts +0 -89
  320. package/src/providers/profile-glm53.ts +0 -111
  321. package/src/providers/profile-sonnet5-persona.ts +0 -65
  322. package/src/providers/profile-sonnet5-voice.ts +0 -23
  323. package/src/providers/profiles.ts +0 -156
  324. package/src/providers/provider-config.ts +0 -311
  325. package/src/providers/registry.ts +0 -333
  326. package/src/providers/responses.ts +0 -209
  327. package/src/providers/retry.ts +0 -234
  328. package/src/providers/router.ts +0 -294
  329. package/src/providers/sse.ts +0 -26
  330. package/src/providers/stream-errors.ts +0 -117
  331. package/src/providers/stream.ts +0 -566
  332. package/src/providers/thinking.ts +0 -189
  333. package/src/providers/wire-messages.ts +0 -129
  334. package/src/providers/wire-responses.ts +0 -79
  335. package/src/providers/wire-select.ts +0 -53
  336. package/src/server/http.ts +0 -291
  337. package/src/server/openapi.ts +0 -246
  338. package/src/sextant/card-hits.ts +0 -102
  339. package/src/sextant/card-keys.ts +0 -55
  340. package/src/sextant/context-source.ts +0 -157
  341. package/src/sextant/crew-cards.ts +0 -350
  342. package/src/sextant/draw-agents.ts +0 -273
  343. package/src/sextant/draw-code.ts +0 -388
  344. package/src/sextant/draw-context.ts +0 -222
  345. package/src/sextant/draw-frame.ts +0 -164
  346. package/src/sextant/draw-market.ts +0 -573
  347. package/src/sextant/draw-messages.ts +0 -386
  348. package/src/sextant/draw-pet.ts +0 -230
  349. package/src/sextant/draw-plan.ts +0 -187
  350. package/src/sextant/draw-tabs.ts +0 -85
  351. package/src/sextant/draw-util.ts +0 -65
  352. package/src/sextant/draw-wizard.ts +0 -378
  353. package/src/sextant/engine.ts +0 -230
  354. package/src/sextant/frame-hits.ts +0 -25
  355. package/src/sextant/frame.ts +0 -101
  356. package/src/sextant/git-status.ts +0 -197
  357. package/src/sextant/grid.ts +0 -59
  358. package/src/sextant/input.ts +0 -119
  359. package/src/sextant/keys.ts +0 -521
  360. package/src/sextant/layout.ts +0 -86
  361. package/src/sextant/local-commands.ts +0 -169
  362. package/src/sextant/market-source.ts +0 -287
  363. package/src/sextant/mentions.ts +0 -200
  364. package/src/sextant/message-hits.ts +0 -26
  365. package/src/sextant/model.ts +0 -387
  366. package/src/sextant/overlays.ts +0 -456
  367. package/src/sextant/panel-hits.ts +0 -38
  368. package/src/sextant/pet.ts +0 -399
  369. package/src/sextant/screen.ts +0 -324
  370. package/src/sextant/scroll-hits.ts +0 -66
  371. package/src/sextant/scrollbar.ts +0 -82
  372. package/src/sextant/sextant-bridge.ts +0 -174
  373. package/src/sextant/sextant-cards.ts +0 -142
  374. package/src/sextant/sextant-diff-base.ts +0 -63
  375. package/src/sextant/sextant-files.ts +0 -154
  376. package/src/sextant/sextant-frame-loop.ts +0 -335
  377. package/src/sextant/sextant-renderer.ts +0 -574
  378. package/src/sextant/sextant-repo.ts +0 -140
  379. package/src/sextant/theme.ts +0 -66
  380. package/src/sextant/tool-rows.ts +0 -189
  381. package/src/sextant/types.ts +0 -493
  382. package/src/skills/index.ts +0 -387
  383. package/src/skills/pack.ts +0 -220
  384. package/src/skills/spec.ts +0 -162
  385. package/src/skills/tools.ts +0 -69
  386. package/src/skills/versioned.ts +0 -227
  387. package/src/telemetry/otel-export.ts +0 -122
  388. package/src/telemetry/otel-lanes.ts +0 -89
  389. package/src/telemetry/otel-logs.ts +0 -131
  390. package/src/telemetry/otel-metrics.ts +0 -136
  391. package/src/telemetry/otel.ts +0 -397
  392. package/src/telemetry/otlp.ts +0 -76
  393. package/src/tools/ask-user.ts +0 -156
  394. package/src/tools/bash-bg.ts +0 -94
  395. package/src/tools/bash-jobs.ts +0 -237
  396. package/src/tools/design.ts +0 -151
  397. package/src/tools/evalcell.ts +0 -338
  398. package/src/tools/html-text.ts +0 -139
  399. package/src/tools/provider.ts +0 -149
  400. package/src/tools/task.ts +0 -250
  401. package/src/tools/todo.ts +0 -320
  402. package/src/tools/webfetch.ts +0 -332
  403. package/src/tools/websearch.ts +0 -359
  404. package/src/tui/agents-cmd.ts +0 -41
  405. package/src/tui/app.ts +0 -749
  406. package/src/tui/attach.ts +0 -127
  407. package/src/tui/boot-notes.ts +0 -41
  408. package/src/tui/builtin-prompts.ts +0 -59
  409. package/src/tui/checkpoints-cmd.ts +0 -70
  410. package/src/tui/clipboard-image.ts +0 -81
  411. package/src/tui/clipboard.ts +0 -78
  412. package/src/tui/commands.ts +0 -283
  413. package/src/tui/config-view.ts +0 -53
  414. package/src/tui/context-cmds.ts +0 -282
  415. package/src/tui/cost.ts +0 -108
  416. package/src/tui/crash-guard.ts +0 -173
  417. package/src/tui/focus-terminal.ts +0 -34
  418. package/src/tui/git-cmds.ts +0 -273
  419. package/src/tui/git-plain.ts +0 -58
  420. package/src/tui/info-cmd.ts +0 -150
  421. package/src/tui/input-plain.ts +0 -76
  422. package/src/tui/mcp-cmd.ts +0 -128
  423. package/src/tui/memory-note.ts +0 -77
  424. package/src/tui/modes-cmd.ts +0 -45
  425. package/src/tui/notify-seq.ts +0 -100
  426. package/src/tui/notify.ts +0 -318
  427. package/src/tui/overlays.ts +0 -97
  428. package/src/tui/pi-renderer.ts +0 -428
  429. package/src/tui/providers-cmd.ts +0 -377
  430. package/src/tui/reasoning-view.ts +0 -56
  431. package/src/tui/renderer.ts +0 -128
  432. package/src/tui/replay-marker.ts +0 -29
  433. package/src/tui/session-cmd.ts +0 -148
  434. package/src/tui/session-manage.ts +0 -95
  435. package/src/tui/sextant-attach.ts +0 -102
  436. package/src/tui/sextant-io.ts +0 -202
  437. package/src/tui/sextant-smoke.ts +0 -110
  438. package/src/tui/shell-cmd.ts +0 -158
  439. package/src/tui/smoke.ts +0 -72
  440. package/src/tui/staged-terminal.ts +0 -50
  441. package/src/tui/startup.ts +0 -12
  442. package/src/tui/theme.ts +0 -59
  443. package/src/tui/todo-label.ts +0 -7
  444. package/src/tui/trust-card.ts +0 -107
  445. package/src/tui/tui-commands.ts +0 -87
  446. package/tsconfig.json +0 -30
  447. package/vendor/pi-tui/LICENSE +0 -21
  448. package/vendor/pi-tui/PATCHES.md +0 -12
  449. package/vendor/pi-tui/PROVENANCE.md +0 -12
  450. package/vendor/pi-tui/README.upstream.md +0 -854
  451. package/vendor/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  452. package/vendor/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  453. package/vendor/pi-tui/src/alt-screen-search.ts +0 -158
  454. package/vendor/pi-tui/src/autocomplete.ts +0 -827
  455. package/vendor/pi-tui/src/components/alt-screen-flash.ts +0 -52
  456. package/vendor/pi-tui/src/components/box.ts +0 -138
  457. package/vendor/pi-tui/src/components/cancellable-loader.ts +0 -41
  458. package/vendor/pi-tui/src/components/editor.ts +0 -2364
  459. package/vendor/pi-tui/src/components/h-stack.ts +0 -45
  460. package/vendor/pi-tui/src/components/image.ts +0 -128
  461. package/vendor/pi-tui/src/components/input.ts +0 -448
  462. package/vendor/pi-tui/src/components/loader.ts +0 -93
  463. package/vendor/pi-tui/src/components/markdown.ts +0 -1016
  464. package/vendor/pi-tui/src/components/scroll-view.ts +0 -217
  465. package/vendor/pi-tui/src/components/select-list.ts +0 -230
  466. package/vendor/pi-tui/src/components/settings-list.ts +0 -277
  467. package/vendor/pi-tui/src/components/spacer.ts +0 -29
  468. package/vendor/pi-tui/src/components/stack.ts +0 -155
  469. package/vendor/pi-tui/src/components/text.ts +0 -108
  470. package/vendor/pi-tui/src/components/truncated-text.ts +0 -66
  471. package/vendor/pi-tui/src/components/v-stack.ts +0 -34
  472. package/vendor/pi-tui/src/editor-component.ts +0 -75
  473. package/vendor/pi-tui/src/fuzzy.ts +0 -138
  474. package/vendor/pi-tui/src/index.ts +0 -149
  475. package/vendor/pi-tui/src/keybindings.ts +0 -321
  476. package/vendor/pi-tui/src/keys.ts +0 -1402
  477. package/vendor/pi-tui/src/kill-ring.ts +0 -47
  478. package/vendor/pi-tui/src/latex.ts +0 -1381
  479. package/vendor/pi-tui/src/layout-node.ts +0 -52
  480. package/vendor/pi-tui/src/layout.ts +0 -411
  481. package/vendor/pi-tui/src/native-modifiers.ts +0 -60
  482. package/vendor/pi-tui/src/native-module-path.ts +0 -32
  483. package/vendor/pi-tui/src/stdin-buffer.ts +0 -445
  484. package/vendor/pi-tui/src/terminal-colors.ts +0 -74
  485. package/vendor/pi-tui/src/terminal-image.ts +0 -701
  486. package/vendor/pi-tui/src/terminal.ts +0 -554
  487. package/vendor/pi-tui/src/tui-alt-screen.ts +0 -1379
  488. package/vendor/pi-tui/src/tui-main-screen.ts +0 -655
  489. package/vendor/pi-tui/src/tui.ts +0 -1264
  490. package/vendor/pi-tui/src/undo-stack.ts +0 -29
  491. package/vendor/pi-tui/src/utils.ts +0 -1327
  492. package/vendor/pi-tui/src/word-navigation.ts +0 -118
  493. package/vendor/pi-tui/test/test-themes.ts +0 -39
  494. package/vendor/pi-tui/test/virtual-terminal.ts +0 -219
  495. /package/{src/providers → dist/cli}/models-index.json +0 -0
@@ -1,335 +0,0 @@
1
- /** Sextant frame loop (port #44): the ONE timer of the surface. Owns the Screen (#40) over the
2
- * TerminalIO, the layout, the per-frame hit zones, the painters wiring (#41 frame/files/plan/usage,
3
- * #42 code/messages, #45 pet, #43 suggest/palette/help overlays), the scroll write-backs the pure
4
- * #42 painters cannot do, the cursor placement and the input pipeline (parseInput → keys.handleInput).
5
- * Ported from the user's sextant v0.4.0 app.js:1599-1632 (the boot: 40 ms tick, paint only when
6
- * dirty / animating / every 170 ms, input and resize handlers; idle, the timer now sleeps until the next ambient change — see the class note). No git/fs here — the renderer
7
- * schedules its I/O from `onTick`, off the paint path. `clock` is injected: tests drive time. */
8
-
9
- import { agentsScrollTop, laneCells } from "./draw-agents.ts";
10
- import { drawCode, codeScrollTop } from "./draw-code.ts";
11
- import { drawMessages, messagesScroll, promptCursor } from "./draw-messages.ts";
12
- import { drawPet, SWAY_MS } from "./draw-pet.ts";
13
- import { fuzzy, tokenize } from "./engine.ts";
14
- import { renderFrame } from "./frame.ts";
15
- import { parseInput } from "./input.ts";
16
- import { handleInput, type KeyCtx } from "./keys.ts";
17
- import { layout as layoutFn } from "./layout.ts";
18
- import { treeRows } from "./model.ts";
19
- import { drawHelp, drawPalette, drawSuggest, suggestions } from "./overlays.ts";
20
- import { drawMarket } from "./draw-market.ts";
21
- import { drawWizard } from "./draw-wizard.ts";
22
- import { drawContext } from "./draw-context.ts";
23
- import { petEnabled, type Pet } from "./pet.ts";
24
- import { Screen } from "./screen.ts";
25
- import { cardHits } from "./card-hits.ts";
26
- import { fileRowHits } from "./panel-hits.ts";
27
- import { followTailIfAtEnd, scrollThumbHits } from "./scroll-hits.ts";
28
- import { frameHits } from "./frame-hits.ts";
29
- import { messageRowHits } from "./message-hits.ts";
30
- import { drawTabs, mainPage } from "./draw-tabs.ts";
31
- import type { HitZone, InputEvent, Layout, SextantState, TerminalIO, Theme, TreeRow } from "./types.ts";
32
-
33
- /** the frame period while something moves (app.js: setInterval(tick, 40)) */
34
- export const FRAME_MS = 40;
35
- /** a tick repaints a frame older than this even when nothing asked (tests drive the clock and tick by hand) */
36
- export const IDLE_REPAINT_MS = 170;
37
- /** the loop never sleeps longer than this: the repo's idle scan and the pet's due hum ride on the tick */
38
- export const IDLE_TICK_MS = 2000;
39
- /** the idle header glyph steps through its four colours every 500 ms (draw-frame.ts activityGlyph) */
40
- export const PULSE_MS = 500;
41
- /** the suggestion box shows at most this many rows (#43 fix-wave cap) */
42
- export const MAX_SUGGESTIONS = 8;
43
- /** the boot reveal animates for this long after bootAt (5 × 90 ms steps + slack) */
44
- const REVEAL_MS = 600;
45
- /** a chunk that ENDS in a lone ESC is held this long: parseInput reports a lone ESC as Escape at once
46
- * (the esc-esc arm needs that), so a sequence split right after its ESC byte would otherwise be typed
47
- * as text — the next chunk (or the timer) completes it */
48
- export const ESC_HOLD_MS = 20;
49
-
50
- export interface FrameLoopDeps {
51
- io: TerminalIO;
52
- clock: () => number;
53
- state: SextantState;
54
- theme: () => Theme;
55
- pet: Pet;
56
- truecolor: boolean;
57
- /** RendererHooks + the renderer-owned local effects keys.ts needs */
58
- keyCtx: () => Pick<KeyCtx, "hooks" | "local">;
59
- /** renderer-level intercept BEFORE keys.handleInput (picker Enter/Esc, the ⌃c arm); true = swallowed */
60
- beforeInput?: (ev: InputEvent, now: number) => boolean;
61
- /** after keys.handleInput ran for `ev` */
62
- afterInput?: (ev: InputEvent, now: number) => void;
63
- /** every tick, BEFORE the paint decision — the renderer reloads the code panel's file and schedules
64
- * its git/fs work here, so a reload an event asked for lands in the same frame (never a one-frame
65
- * `cannot read <file>` between an edit's end and the next tick) */
66
- onTick?: (now: number) => void;
67
- }
68
-
69
- /** The loop is one re-armed setTimeout, not a setInterval. Its period is FRAME_MS while something MOVES
70
- * (a spinner, a storm, the boot reveal: a new picture every frame). Otherwise the surface is only
71
- * AMBIENT — the header glyph steps colour every 500 ms, the pet sways every 1.8 s, a quip or a toast
72
- * expires at a known time — and the loop sleeps until the earliest of those instants (nextAmbient), so an
73
- * idle session paints ~2 frames a second instead of 6 and wakes ~2 times instead of 25; after a run,
74
- * when the glyph holds still, well under one a second. Nothing waits for the sleeping timer: a keystroke
75
- * paints in parse(), and every state change goes through markDirty() (dispatch, resize, the renderer),
76
- * which pulls the next tick forward to one frame from now (wake()). */
77
- export class FrameLoop {
78
- private screen: Screen | null = null;
79
- private timer: ReturnType<typeof setTimeout> | null = null;
80
- /** performance.now() at which `timer` fires (wake() only re-arms when that is further than a frame away) */
81
- private dueAt = 0;
82
- /** the delay the last tick chose for the next one (fire() arms it) */
83
- private _pace = FRAME_MS;
84
- /** clock time of the next ambient change the last tick saw (a tick at or past it paints) */
85
- private ambientDue = -Infinity;
86
- private unsubs: (() => void)[] = [];
87
- private carry = "";
88
- private held = "";
89
- private holdTimer: ReturnType<typeof setTimeout> | null = null;
90
- private dirty = true;
91
- private lastRender = -Infinity;
92
- private L: Layout;
93
- private hits: HitZone[] = [];
94
- /** the grabbed zone (a scrollbar thumb) and the row it was pressed on; outlives the per-frame hits */
95
- private readonly drag = { zone: null as HitZone | null, y0: 0 };
96
- private rows: TreeRow[] = [];
97
- /** frames painted (tests: "a render happened") */
98
- frames = 0;
99
-
100
- constructor(private readonly d: FrameLoopDeps) {
101
- const { cols, rows } = d.io.size();
102
- this.L = layoutFn(cols, rows, this.layoutOpts());
103
- }
104
-
105
- private layoutOpts(): { pet: boolean } { return { pet: petEnabled(this.d.io.env) }; }
106
- /** the interval is live */
107
- get active(): boolean { return this.timer !== null; }
108
- /** the layout of the last frame (before the first frame: computed from the io size) */
109
- get layout(): Layout { return this.L; }
110
- /** the delay between the last tick and the next (tests: the idle backoff) */
111
- get pace(): number { return this._pace; }
112
- markDirty(): void { this.dirty = true; this.wake(); }
113
- /** the last painted frame as text (tests/smoke); "" before start() */
114
- frameText(): string { return this.screen?.toText() ?? ""; }
115
-
116
- /** Build the entire layout, textbox/cursor and hit zones in memory. No writes, input or timers. */
117
- prepare(): void {
118
- const { cols, rows } = this.d.io.size();
119
- this.screen = new Screen(this.d.io, cols, rows, { truecolor: this.d.truecolor });
120
- this.render(this.d.clock(), false);
121
- }
122
-
123
- /** build the Screen, subscribe input/resize, paint the first frame, start the interval */
124
- start(beforeFlush?: () => void, synchronized = false): void {
125
- if (this.timer) return;
126
- const { cols, rows } = this.d.io.size();
127
- let handoff = beforeFlush;
128
- this.screen = new Screen({ write: (text) => {
129
- const ready = handoff; handoff = undefined;
130
- // Synchronized output keeps terminals from showing the intro-clear or half a frame mid-write.
131
- if (ready && synchronized) {
132
- const esc = String.fromCharCode(27);
133
- this.d.io.write(`${esc}[?2026h`);
134
- try { ready(); this.d.io.write(text); } finally { this.d.io.write(`${esc}[?2026l`); }
135
- } else { ready?.(); this.d.io.write(text); }
136
- } }, cols, rows, { truecolor: this.d.truecolor });
137
- this.unsubs.push(this.d.io.onInput((chunk) => this.feed(chunk)));
138
- this.unsubs.push(this.d.io.onResize((c, r) => { this.screen?.resize(c, r); this.markDirty(); }));
139
- this._pace = FRAME_MS;
140
- this.arm(FRAME_MS);
141
- this.render(this.d.clock());
142
- }
143
-
144
- /** (re)arm the one timer */
145
- private arm(ms: number): void {
146
- if (this.timer !== null) clearTimeout(this.timer);
147
- this.dueAt = performance.now() + ms;
148
- this.timer = setTimeout(() => this.fire(), ms);
149
- }
150
- /** the timer fired: tick, then arm the pace the tick chose — unless the tick stopped the loop (timer
151
- * gone) or a wake() inside it already re-armed (timer replaced): then it is no longer ours to arm */
152
- private fire(): void {
153
- const fired = this.timer;
154
- this.tick();
155
- if (this.timer === fired) { this.timer = null; this.arm(this._pace); }
156
- }
157
- /** something changed: if the loop is asleep, pull the next tick forward to one frame from now */
158
- private wake(): void {
159
- if (this.timer !== null && this.dueAt - performance.now() > FRAME_MS) this.arm(FRAME_MS);
160
- }
161
-
162
- /** clear the frame timer and the ESC-hold timer, unsubscribe; the screen keeps its last frame for frameText() */
163
- stop(): void {
164
- if (this.timer) { clearTimeout(this.timer); this.timer = null; }
165
- if (this.holdTimer) { clearTimeout(this.holdTimer); this.holdTimer = null; }
166
- this.held = "";
167
- for (const u of this.unsubs) u();
168
- this.unsubs = [];
169
- }
170
-
171
- /** raw bytes → events: a chunk ending in a lone ESC waits ESC_HOLD_MS for its continuation; an
172
- * incomplete CSI/paste is carried by parseInput into the next chunk */
173
- feed(chunk: string): void {
174
- if (this.holdTimer) { clearTimeout(this.holdTimer); this.holdTimer = null; }
175
- const data = this.held + chunk;
176
- this.held = "";
177
- if (data.endsWith("\x1b")) {
178
- this.held = data;
179
- this.holdTimer = setTimeout(() => { this.holdTimer = null; this.flushInput(); }, ESC_HOLD_MS);
180
- return;
181
- }
182
- this.parse(data);
183
- }
184
- /** parse the held bytes now (the hold timer fired, or a test wants determinism) */
185
- flushInput(): void {
186
- if (this.holdTimer) { clearTimeout(this.holdTimer); this.holdTimer = null; }
187
- const data = this.held;
188
- this.held = "";
189
- if (data) this.parse(data);
190
- }
191
- private parse(data: string): void {
192
- const r = parseInput(data, this.carry);
193
- this.carry = r.rest;
194
- for (const ev of r.events) this.dispatch(ev);
195
- // Paint the result of this chunk NOW rather than waiting for the next 40 ms tick. A keystroke was
196
- // always handled immediately, but its echo waited for the timer — invisible on an idle machine, and
197
- // on a loaded one, where setInterval is starved, it is the difference between a responsive prompt
198
- // and one that appears to have stopped accepting input. This costs no extra frame: the tick would
199
- // have painted the same state a moment later, and it clears `dirty` so the tick then skips.
200
- // Once per CHUNK, not once per event, so a paste of two hundred characters still paints once.
201
- // `this.timer` is the guard, not `this.screen`: a key can END the session — ⌃c, /exit, a click on
202
- // the exit row — and by the time this line runs the loop has been stopped and the terminal handed
203
- // back. Painting then writes a frame over the shell the user has just been returned to. The screen
204
- // object is still there; the loop is what says whether it is ours to paint on.
205
- if (this.timer !== null && r.events.length > 0) this.render(this.d.clock());
206
- }
207
-
208
- dispatch(ev: InputEvent): void {
209
- const now = this.d.clock();
210
- this.markDirty(); // and wake: the tick that follows this key (onTick: file reload) must come in one frame, not one sleep
211
- if (this.d.beforeInput?.(ev, now)) return;
212
- const kc = this.d.keyCtx();
213
- const ctx: KeyCtx = { layout: this.L, hooks: kc.hooks, local: kc.local, hits: this.hits, rows: this.rows, fuzzy, drag: this.drag };
214
- handleInput(this.d.state, ev, ctx, now);
215
- this.d.afterInput?.(ev, now);
216
- }
217
-
218
- /** a new picture EVERY frame: a run's spinners, a waiting card's blink, touched-file spinners, the pet's
219
- * storms and effects, the boot reveal. These hold the loop at FRAME_MS. */
220
- moving(now: number): boolean {
221
- const s = this.d.state, P = this.d.pet.state;
222
- return s.running || s.card !== null || s.files.touched.size > 0 || now - s.bootAt < REVEAL_MS
223
- || now < P.stormUntil || P.fx.some((f) => f.until > now);
224
- }
225
-
226
- /** the clock time the picture next changes on its own while nothing moves — Infinity when it never will:
227
- * the idle header glyph's next colour step (only while the activity state is IDLE and no card is up —
228
- * draw-frame.ts modeOf; after a run the glyph holds), the pet's next sway step (only while it is on
229
- * screen — the pet also hums from drawPet, so its due hum lands on the sway wake), and the instants a
230
- * quip, a glance, a toast or the esc arm expire */
231
- nextAmbient(now: number): number {
232
- const s = this.d.state, P = this.d.pet.state;
233
- let due = Infinity;
234
- if (s.card === null && s.activity.state === "IDLE") due = Math.min(due, (Math.floor(now / PULSE_MS) + 1) * PULSE_MS);
235
- if (this.L.pet) due = Math.min(due, (Math.floor(now / SWAY_MS) + 1) * SWAY_MS);
236
- if (P.quip && P.quip.until > now) due = Math.min(due, P.quip.until);
237
- if (P.glance && P.glance.until > now) due = Math.min(due, P.glance.until);
238
- for (const t of s.toasts) if (t.until > now) due = Math.min(due, t.until);
239
- if (now < s.escUntil) due = Math.min(due, s.escUntil);
240
- return due;
241
- }
242
-
243
- tick(): void {
244
- const now = this.d.clock();
245
- this.d.onTick?.(now); // first: a reload marks dirty and paints below, in this very frame
246
- if (this.dirty || this.moving(now) || now >= this.ambientDue || now - this.lastRender >= IDLE_REPAINT_MS) this.render(now);
247
- this._pace = this.nextPace(now);
248
- }
249
-
250
- /** the delay to the next tick, decided AFTER the paint (a painter can mark dirty or start a quip): a
251
- * frame while anything moves or is dirty, else the time to the next ambient change, never under a frame
252
- * (a timer that fires a millisecond early must not spin) and never over IDLE_TICK_MS */
253
- private nextPace(now: number): number {
254
- if (this.dirty || this.moving(now)) { this.ambientDue = -Infinity; return FRAME_MS; }
255
- this.ambientDue = this.nextAmbient(now);
256
- return Math.min(IDLE_TICK_MS, Math.max(FRAME_MS, this.ambientDue - now));
257
- }
258
-
259
- /** paint one frame: panels (renderFrame) → suggestion box → palette → help → scroll write-backs → cursor → flush */
260
- render(now: number, flush = true): void {
261
- const scr = this.screen;
262
- if (!scr) return;
263
- const s = this.d.state, theme = this.d.theme(), pet = this.d.pet;
264
- scr.begin(theme.bg);
265
- this.rows = treeRows(s, now); // the same (version, now) key drawFiles uses → one build per frame (model.ts cache)
266
- const hits: HitZone[] = [];
267
- const L = renderFrame(scr, s, theme, now, {
268
- layout: layoutFn,
269
- layoutOpts: this.layoutOpts(),
270
- painters: {
271
- code: (g, r, st, th, t) => drawCode(g, r, st, th, t, { tokenize }),
272
- messages: drawMessages,
273
- pet: (g, r, st, th, t) => drawPet(g, r, pet, st, th, t),
274
- },
275
- });
276
- this.L = L;
277
- if (L.pet) hits.push({ rect: L.pet, onClick: () => pet.poke(this.d.clock()) });
278
- // the frame's border rows (frame-hits.ts): unread badge → notices, theme name → next theme, effort → /effort
279
- for (const z of frameHits(L.frame, s, theme, now)) hits.push(z);
280
- // paging (draw-tabs.ts): on a narrow terminal the main slot may be showing files or plan instead
281
- // of code; the strip is painted over the slot's top border and each tab is a click zone
282
- const main = mainPage(L, s);
283
- for (const t of drawTabs(scr, L, s, theme)) {
284
- hits.push({ rect: t.rect, onClick: () => { s.page = t.page; s.focus = t.page === "files" ? "files" : "code"; } });
285
- }
286
- // the body rect drawCode hands its mode painter (inner rect minus the 3-wide rail and its gutter)
287
- const body = { x: L.code.x + 2, y: L.code.y + 1, w: L.code.w - 9, h: L.code.h - 2 };
288
- if (main === "code" && s.code.mode === "agents" && !s.code.laneOpen) {
289
- for (const { index, rect } of laneCells(body, s).cells) hits.push({ rect, onClick: () => { s.code.lane = index; s.focus = "code"; } });
290
- }
291
- // the files tree rows (panel-hits.ts): click = select + Enter, i.e. fold a dir / open a file.
292
- // The rows live in the files panel, or in the main slot when files is paged in there.
293
- const filesRect = L.files ?? (main === "files" ? L.code : null);
294
- for (const hit of fileRowHits(filesRect, s, this.rows)) {
295
- hits.push({
296
- rect: hit.rect,
297
- onClick: () => { s.focus = "files"; s.files.cursor = hit.index; },
298
- key: { type: "key", name: "enter" },
299
- });
300
- }
301
- // scrollbar thumbs (scroll-hits.ts): grab + drag scrolls; after the row zones so the thumb column wins
302
- for (const hit of scrollThumbHits(L, main, s, theme, now, this.rows)) hits.push(hit);
303
- followTailIfAtEnd(L, s, theme, now); // scrolled back to the end → follow new text again
304
- // tool rows that name a file (message-hits.ts): click = open it in the code panel, like /open
305
- for (const hit of messageRowHits(L.messages, s, theme, now)) hits.push({ rect: hit.rect, onClick: () => this.d.keyCtx().local.openFile(hit.path) });
306
- // the modal card's buttons (card-hits.ts). Registered BEFORE the palette/help so those overlays,
307
- // which draw over the card, still win the last-registered-wins walk in keys.ts.
308
- for (const hit of cardHits(L.messages, s, theme)) {
309
- hits.push({
310
- rect: hit.rect,
311
- onClick: () => { if (s.card) s.card.selected = hit.index; },
312
- // a click on a labelled button IS the decision; the free-text row only takes the caret
313
- ...(hit.confirm ? { key: { type: "key" as const, name: "enter" } } : {}),
314
- });
315
- }
316
- drawSuggest(scr, L.messages, s, suggestions(s, s.files.paths, fuzzy).slice(0, MAX_SUGGESTIONS), theme, hits);
317
- const paletteCursor = drawPalette(scr, L, theme, s, fuzzy, hits);
318
- const marketCursor = drawMarket(scr, L, theme, s, fuzzy, hits);
319
- const contextCursor = drawContext(scr, L, theme, s, hits);
320
- const wizardCursor = drawWizard(scr, L, theme, s, hits);
321
- if (s.help) drawHelp(scr, L, theme, s, hits);
322
- this.hits = hits;
323
- // the #42/#46 seams: the painters are pure, so the effective scroll positions are written back here
324
- // (codeScrollTop counts 0 rows in agents mode and would pin the open lane to its top)
325
- s.code.scroll = s.code.mode === "agents" ? agentsScrollTop(body, s) : codeScrollTop(L.code, s);
326
- s.msgScroll = messagesScroll(L.messages, s, theme, now).offset;
327
- const cursor = s.palette ? paletteCursor : s.market ? marketCursor : s.context ? contextCursor : s.wizard ? wizardCursor : s.help ? null : promptCursor(L.messages, s);
328
- if (flush) {
329
- scr.flush(cursor);
330
- this.frames++;
331
- }
332
- this.dirty = false;
333
- this.lastRender = now;
334
- }
335
- }