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,187 +0,0 @@
1
- /** Sextant plan + usage painters (port #41). Ported from the user's sextant v0.4.0 app.js:675-744
2
- * (drawPlan steps/crew/next, drawUsage tokens/context bar/cost); the scenario phases are gone — the
3
- * steps ARE the session's todos (tools/todo.ts loadTodos), the crew rows are TaskManager TaskInfo,
4
- * usage comes from the run's real token/cost accounting. Pure: `now` only drives the crew spinner. */
5
-
6
- import { ATTR } from "./types.ts";
7
- import type { Rect, ScreenLike, Seg, SextantState, Theme } from "./types.ts";
8
- import type { TaskInfo } from "../core/tasks.ts";
9
- import { EMPTY } from "../core/voice.ts";
10
- import type { TodoItem } from "../tools/todo.ts";
11
- import { fmtK, planCounts } from "./model.ts";
12
- import { crewSummary, laneGlyph, laneStatus, laneTone } from "./draw-agents.ts";
13
- import { crewCardBlock, crewCardHeight, groupCrew, paintCrewCards, type CrewTask } from "./crew-cards.ts";
14
- import { panel } from "./layout.ts";
15
- import { st } from "./theme.ts";
16
- import { driftRow } from "./draw-context.ts";
17
-
18
- /** the crew section's row ceiling: two full cards and the separator between them (the card is 3 rows —
19
- * crew-cards.ts). Beyond that the plan's own steps lose their room, and the `+N more` footer says what is
20
- * not shown; the full board is `∷` (draw-agents.ts). */
21
- const CREW_ROWS_MAX = 7;
22
- export const STEP_GLYPH: Record<TodoItem["status"], string> = { completed: "◆", in_progress: "◈", pending: "◇" };
23
-
24
- const oneLine = (text: string): string => text.replace(/\s+/g, " ").trim();
25
- /** greedy word wrap (app.js wrap) — long words are split at the width */
26
- export function wrapText(text: string, width: number): string[] {
27
- const out: string[] = [];
28
- if (width <= 0) return out;
29
- for (const para of oneLine(text).split("\n")) {
30
- let line = "";
31
- for (const w of para.split(" ")) {
32
- if (!line) { line = w; continue; }
33
- if ([...line].length + 1 + [...w].length <= width) line += " " + w; else { out.push(line); line = w; }
34
- }
35
- while ([...line].length > width) { const cps = [...line]; out.push(cps.slice(0, width).join("")); line = cps.slice(width).join(""); }
36
- out.push(line);
37
- }
38
- return out;
39
- }
40
-
41
- /** `next` = the in_progress item, then the first pending one */
42
- export function nextSteps(todos: readonly TodoItem[]): TodoItem[] {
43
- const out: TodoItem[] = [];
44
- const cur = todos.find((t) => t.status === "in_progress"); if (cur) out.push(cur);
45
- const pend = todos.find((t) => t.status === "pending"); if (pend) out.push(pend);
46
- return out;
47
- }
48
- /** non-terminal tasks = "working" (queued + running) — crewSummary(crew).working agrees */
49
- export const crewWorking = (crew: readonly TaskInfo[]): number => crewSummary(crew).working;
50
- /** the crew board's glyph + tone (#46 draw-agents): ◇ queued · spinner running · ◆ done · × failed · ▪ cancelled */
51
- export function crewGlyph(t: TaskInfo, theme: Theme, now: number): [string, number] {
52
- return [laneGlyph(t.status, now), laneTone(t.status, theme)];
53
- }
54
- /** the crew board's status word (#46 laneStatus): `working mm:ss` while running, else the status */
55
- export const crewStatus = (t: TaskInfo, now = 0): string => laneStatus(t, now);
56
-
57
- /** Plan panel: `plan done/total` title, todo steps (◆ done · ◈ in_progress · ◇ pending, priority hint
58
- * at the right), then — anchored to the bottom — `crew k working` (when any) and `next`. */
59
- export function drawPlan(scr: ScreenLike, R: Rect, s: SextantState, theme: Theme, now = 0): void {
60
- const todos = s.plan.todos, c = planCounts(s);
61
- const B = panel(scr, R, "plan", false, todos.length ? [[`${c.completed}/${c.total}`, st(theme.muted)]] : [], theme);
62
- const yEnd = B.y + B.h;
63
- let y = B.y;
64
- if (s.plan.note) for (const line of wrapText(s.plan.note, B.w).slice(0, 2)) if (y < yEnd) scr.put(B.x, y++, line, st(theme.warn), B.w);
65
- const next = nextSteps(todos);
66
- // the crew section is CARDS now (Berkay's pick): one card per workflow — the tasks of one run — never one row
67
- // per task. The height is what the cards actually need, capped; the block itself drops spacing, then names,
68
- // then whole cards behind a footer (crew-cards.ts states the order).
69
- const groups = groupCrew(s.crew as readonly CrewTask[]);
70
- const crewNeed = groups.length ? Math.min(CREW_ROWS_MAX, crewCardHeight(groups, B.w, now)) : 0;
71
- let nextRows = next.length ? next.length + 1 : 0, crewRows = crewNeed ? crewNeed + 1 : 0;
72
- let nextY = yEnd - nextRows;
73
- let crewY = (nextRows ? nextY - 1 : yEnd) - crewRows;
74
- const minY = y + 2; // keep the steps header + one row above the anchored blocks
75
- if (crewRows && crewY < minY) { crewRows = 0; crewY = yEnd; }
76
- if (nextRows && nextY < minY) { nextRows = 0; nextY = yEnd; }
77
- const stepsEnd = crewRows ? crewY - 1 : nextRows ? nextY - 1 : yEnd;
78
- scr.text(B.x, y++, [["steps", st(theme.muted)], [todos.length ? ` ${c.completed}/${c.total}` : "", st(theme.dim)]], B.w);
79
- if (!todos.length && y < stepsEnd) { // empty plan: the hint's second line only when there is room
80
- scr.put(B.x, y++, EMPTY.plan[0], st(theme.dim), B.w);
81
- if (y < stepsEnd) scr.put(B.x, y++, EMPTY.plan[1], st(theme.dim), B.w);
82
- }
83
- // a long plan windows around the step in progress instead of always showing its head: the person
84
- // wants to see what is being done now, not steps 1-8 of 30. One row above says how many are earlier.
85
- const room = Math.max(0, stepsEnd - y), curIdx = todos.findIndex((t) => t.status === "in_progress");
86
- let start = 0;
87
- if (todos.length > room && curIdx >= room - 1) { // the current step would be hidden (or be the marker row)
88
- const visible = Math.max(1, room - 2); // minus the "earlier" row and the "+N more" row
89
- start = Math.max(0, Math.min(curIdx - Math.floor(visible / 2), todos.length - visible));
90
- }
91
- if (start > 0 && y < stepsEnd) scr.put(B.x, y++, ` …${start} earlier`, st(theme.dim), B.w);
92
- let shown = start;
93
- for (const t of todos.slice(start)) {
94
- if (y >= stepsEnd) break;
95
- const cur = t.status === "in_progress", done = t.status === "completed";
96
- const pr = t.priority === "high" ? "high" : t.priority === "low" ? "low" : "";
97
- scr.put(B.x, y, STEP_GLYPH[t.status], st(done ? theme.okDim : cur ? theme.accent : theme.dim));
98
- scr.clip(B.x + 3, y, oneLine(t.content), st(done ? theme.fg2 : cur ? theme.fg : theme.muted, -1, cur ? ATTR.BOLD : 0), B.w - 3 - (pr ? pr.length + 1 : 0));
99
- if (pr) scr.put(B.x + B.w - pr.length, y, pr, st(t.priority === "high" ? theme.warn : theme.dim));
100
- y++; shown++;
101
- }
102
- if (shown < todos.length && shown > 0) { y--; scr.fill(B.x, y, B.w, 1, " "); scr.put(B.x, y, ` +${todos.length - shown + 1} more`, st(theme.dim), B.w); }
103
- if (crewRows) {
104
- let cy = crewY;
105
- scr.text(B.x, cy++, [["crew", st(theme.muted)], [` ${crewSummary(s.crew).text}`, st(theme.dim)]], B.w);
106
- const block = crewCardBlock(groups, B.w, crewRows - 1, now);
107
- paintCrewCards(scr, B.x, cy, B.w, block.lines, theme);
108
- }
109
- if (nextRows) {
110
- let ny = nextY;
111
- scr.put(B.x, ny++, "next", st(theme.muted));
112
- for (const t of next) {
113
- const cur = t.status === "in_progress";
114
- scr.text(B.x, ny++, [[STEP_GLYPH[t.status] + " ", st(cur ? theme.accent : theme.dim)], [oneLine(t.content), st(cur ? theme.fg : theme.muted)]], B.w);
115
- }
116
- }
117
- }
118
-
119
- /** filled cells of a `width`-wide context bar at `pct` (0..100) */
120
- export const barFilled = (pct: number, width: number): number => Math.round((Math.max(0, Math.min(100, pct)) / 100) * width);
121
- /** the first candidate that fits `width` cells, else the last one clipped with an ellipsis */
122
- export function fitText(candidates: readonly string[], width: number): string {
123
- for (const c of candidates) if ([...c].length <= width) return c;
124
- const last = candidates[candidates.length - 1];
125
- if (last === undefined || width <= 0) return "";
126
- return width === 1 ? "…" : [...last].slice(0, width - 1).join("") + "…";
127
- }
128
-
129
- /** Usage panel (3 inner rows): `tokens 4.2k` (+ in/out split when it fits), `context ━━──── 12%`
130
- * (or `context ?` when the window is unknown), `cost $0.030` (or `cost —` when unpriced) +
131
- * provider/model (model alone, then clipped, when narrow). */
132
- /** Token counts for the context row, as short as they can be and still be read: `842`, `4.2k`, `24k`,
133
- * `200k`, `1M`. fmtK keeps a decimal at every size, which is right where a number stands alone and
134
- * wrong in a pair — `24.0k/200.0k` costs six characters that say nothing and eats the bar beside it. */
135
- function fmtCtx(n: number): string {
136
- if (n < 1000) return String(Math.round(n));
137
- if (n < 10_000) return `${(n / 1000).toFixed(1)}k`;
138
- if (n < 1_000_000) return `${Math.round(n / 1000)}k`;
139
- const m = n / 1_000_000;
140
- return m < 10 && m !== Math.round(m) ? `${m.toFixed(1)}M` : `${Math.round(m)}M`;
141
- }
142
-
143
- export function drawUsage(scr: ScreenLike, R: Rect, s: SextantState, theme: Theme): void {
144
- const B = panel(scr, R, "usage", false, [], theme);
145
- const u = s.usage;
146
- const label = (t: string): Seg => [t.padEnd(10), st(theme.muted)];
147
- const total = fmtK(u.tokensIn + u.tokensOut);
148
- const split = fitText([` ${fmtK(u.tokensIn)} in · ${fmtK(u.tokensOut)} out`, ` ${fmtK(u.tokensIn)}/${fmtK(u.tokensOut)}`, ""], B.w - 10 - total.length);
149
- if (u.tokensIn + u.tokensOut === 0) scr.text(B.x, B.y, [label("tokens"), [EMPTY.usage, st(theme.dim)]], B.w); // nothing spent yet
150
- else scr.text(B.x, B.y, [label("tokens"), [total, st(theme.fg)], [split, st(theme.dim)]], B.w);
151
- scr.text(B.x, B.y + 1, [label("context")]);
152
- if (u.contextPct === null) scr.put(B.x + 10, B.y + 1, "?", st(theme.dim));
153
- else {
154
- // A percentage alone goes blind on a large window. claude-opus-5 carries 1,000,000 tokens, so a
155
- // real working session sits at 0% for hours: you need 10k tokens to move the first digit, and
156
- // Berkay's report was exactly this — "context shows 0%, we cannot see how much context there is".
157
- // The numbers are what a person acts on ("42k of 1M" is a decision; "0%" is not), so they get the
158
- // room and the percent keeps only what is left. The bar stays: it is the at-a-glance channel, and
159
- // it is the only part that reads correctly when the window is small.
160
- const pct = `${Math.round(u.contextPct)}%`;
161
- const nums = u.contextWindow !== undefined ? `${fmtCtx(u.contextTokens ?? 0)}/${fmtCtx(u.contextWindow)}` : "";
162
- const tail = nums === "" ? pct : `${nums} ${pct}`;
163
- const barW = Math.max(4, B.w - 10 - tail.length - 2);
164
- const filled = barFilled(u.contextPct, barW);
165
- for (let i = 0; i < barW; i++) scr.put(B.x + 10 + i, B.y + 1, i < filled ? "━" : "─", st(i < filled ? theme.accent : theme.rule2));
166
- const tailX = B.x + 10 + barW + 2;
167
- if (nums !== "") scr.put(tailX, B.y + 1, nums, st(theme.dim));
168
- scr.put(tailX + (nums === "" ? 0 : nums.length + 1), B.y + 1, pct, st(u.contextPct > 80 ? theme.warn : theme.fg));
169
- }
170
- const cost = u.costUsd === null ? "—" : `$${u.costUsd.toFixed(3)}`;
171
- const model = u.model ? fitText([u.provider ? ` ${u.provider}/${u.model}` : ` ${u.model}`, ` ${u.model}`], B.w - 10 - cost.length) : "";
172
- scr.text(B.x, B.y + 2, [label("cost"), [cost, st(theme.fg)], [model, st(theme.dim)]], B.w);
173
-
174
- // How far the bar above is from what the provider actually counted. It matters here rather than only
175
- // inside /context because compaction fires on OUR estimate: a model whose real prompt is a fifth bigger
176
- // than the bar says gets compacted late, and the bar is the thing the human is looking at when they
177
- // decide whether one more turn fits.
178
- //
179
- // Drawn only once /context has been opened, and silent otherwise. The number comes from comparing our
180
- // count with a turn that reported usage, which the cockpit does not do on its own — and inventing a
181
- // placeholder ("drift —") would take a row to say nothing. `driftRow` returns undefined when there is
182
- // nothing honest to say, so this is one condition rather than a special case.
183
- const d = s.context ? driftRow(s.context.drift, s.context.tolerance) : undefined;
184
- if (d && B.h > 3) {
185
- scr.text(B.x, B.y + 3, [label("drift"), [fitText([d.text, ""], B.w - 10), st(d.warn ? theme.warn : theme.dim)]], B.w);
186
- }
187
- }
@@ -1,85 +0,0 @@
1
- /** The tab strip: paging between panels the terminal is too narrow to show at once.
2
- *
3
- * layout.ts hides the files panel under 140 columns and the plan/usage column under 110, and until
4
- * now a hidden panel was simply gone — ⌃e answered "the files panel needs ≥ 140 columns" and that was
5
- * that. Berkay asked for the panels to behave like tabs instead: on a narrow terminal the MAIN slot
6
- * (the code panel's rect) shows whichever panel `s.page` names, and a strip on that slot's top border
7
- * says which panels exist and which one is showing. Clicking a tab pages to it; ⌃e pages to files,
8
- * ⌃o cycles.
9
- *
10
- * Deliberately absent on a wide terminal: when every panel is on screen there is nothing to page,
11
- * and a strip would be one more thing to read. tabsFor() returns [] and nothing is drawn.
12
- *
13
- * Geometry and painting live together here so the hit zones the frame loop registers are the cells
14
- * that were actually painted — the same rule card-hits.ts and panel-hits.ts follow. The strip
15
- * overpaints the panel title on the top border (panel() draws the title at x+2); the active tab IS
16
- * the title. */
17
-
18
- import { st } from "./draw-util.ts";
19
- import { strWidth } from "./screen.ts";
20
- import { ATTR, PAGES, type Layout, type Page, type Rect, type ScreenLike, type SextantState, type Theme } from "./types.ts";
21
-
22
- export interface Tab {
23
- page: Page;
24
- /** the cells the label occupies on the border row */
25
- rect: Rect;
26
- active: boolean;
27
- }
28
-
29
- const LABEL: Record<Page, string> = { code: "code", files: "files", plan: "plan" };
30
- const SEP = " · ";
31
-
32
- /** is this page's own panel hidden by the layout, so it needs a tab to be reachable? */
33
- export function hiddenByLayout(L: Layout, page: Page): boolean {
34
- return page === "files" ? L.files === null : page === "plan" ? L.plan === null : false;
35
- }
36
-
37
- /** the page actually showing in the main slot: `s.page` if that panel is hidden by the layout (so
38
- * paging is what makes it visible), else code — a page pointing at a panel that is already on
39
- * screen is inert, never a duplicate */
40
- export function mainPage(L: Layout, s: SextantState): Page {
41
- return hiddenByLayout(L, s.page) ? s.page : "code";
42
- }
43
-
44
- /** The tabs to show, positioned on the main slot's top border; [] on a wide terminal. */
45
- export function tabsFor(L: Layout, s: SextantState): Tab[] {
46
- const hidden = PAGES.filter((p) => hiddenByLayout(L, p));
47
- if (hidden.length === 0) return [];
48
- const pages: Page[] = ["code", ...hidden];
49
- const active = mainPage(L, s);
50
- const y = L.code.y;
51
- const right = L.code.x + L.code.w - 2; // the border's last usable cell before the corner
52
- let x = L.code.x + 2;
53
- const out: Tab[] = [];
54
- for (const [i, page] of pages.entries()) {
55
- const w = strWidth(LABEL[page]) + 2; // ` label `
56
- if (x + w > right) break; // a strip the border cannot hold stops, never wraps
57
- out.push({ page, rect: { x, y, w, h: 1 }, active: page === active });
58
- x += w + (i < pages.length - 1 ? strWidth(SEP) : 0);
59
- }
60
- return out;
61
- }
62
-
63
- /** Paint the strip over the main slot's top border. Pure; returns what it painted. */
64
- export function drawTabs(scr: ScreenLike, L: Layout, s: SextantState, theme: Theme): Tab[] {
65
- const tabs = tabsFor(L, s);
66
- if (tabs.length === 0) return tabs;
67
- const focused = s.focus === "code" || s.focus === "files";
68
- for (const [i, t] of tabs.entries()) {
69
- const style = t.active
70
- ? st(theme.bg, focused ? theme.accent : theme.fg2, ATTR.BOLD)
71
- : st(theme.muted);
72
- scr.text(t.rect.x, t.rect.y, [[` ${LABEL[t.page]} `, style]], t.rect.w);
73
- const next = tabs[i + 1];
74
- if (next) scr.text(t.rect.x + t.rect.w, t.rect.y, [[SEP, st(theme.frame)]], next.rect.x - (t.rect.x + t.rect.w));
75
- }
76
- return tabs;
77
- }
78
-
79
- /** the page after `page` among the tabs on screen (⌃o); `page` itself when there is nothing to cycle */
80
- export function nextPage(L: Layout, s: SextantState): Page {
81
- const tabs = tabsFor(L, s);
82
- if (tabs.length < 2) return s.page;
83
- const i = tabs.findIndex((t) => t.active);
84
- return tabs[(i + 1) % tabs.length]!.page;
85
- }
@@ -1,65 +0,0 @@
1
- /** Sextant surface (port #42) — small pure drawing helpers shared by the code and messages panels.
2
- * Ported from the user's own sextant v0.4.0 prototype: src/app.js:37 (st), :66-78 (wrap), :210-220
3
- * (panel). Pure: no clock, no timers, no process access — `now` arrives as a parameter.
4
- * #44 dedupe: `st` and `panel` are the shared theme.ts / layout.ts ones, re-exported here so the
5
- * panels' imports stay put (layout.ts panel() = this file's former one: interior cleared to the
6
- * theme background, extras clipped with an ellipsis before they are dropped). */
7
-
8
- import { SPIN, type Rect } from "./types.ts";
9
-
10
- export { st } from "./theme.ts";
11
- export { panel } from "./layout.ts";
12
-
13
- /** the four-glyph diamond spinner, phase from the frame clock (140 ms per step) */
14
- export const spinner = (now: number): string => SPIN[Math.floor(now / 140) % SPIN.length] ?? "◇";
15
-
16
- /** split file content into lines; a trailing newline does not produce a phantom empty line */
17
- export function splitLines(s: string): string[] {
18
- const l = s.split("\n");
19
- if (l.length && l[l.length - 1] === "") l.pop();
20
- return l;
21
- }
22
-
23
- /** 1-slot cache: splitLines is called twice per frame (drawFileView + codeScrollTop/rowCount).
24
- * File content is a stable string reference within a frame; reference equality is the cheapest guard. */
25
- let _splitCache: { src: string; lines: string[] } | null = null;
26
- export function splitLinesCached(s: string): string[] {
27
- if (_splitCache && _splitCache.src === s) return _splitCache.lines;
28
- const lines = splitLines(s);
29
- _splitCache = { src: s, lines };
30
- return lines;
31
- }
32
-
33
- /** Word-wrap to `width` cells — one cell per code point (types.ts), so an emoji counts once and a
34
- * surrogate pair never straddles two rows — keeping explicit newlines (a blank paragraph stays a
35
- * blank row); a word longer than the width is hard-split wherever it starts. Never returns []. */
36
- export function wrap(text: string, width: number): string[] {
37
- const w = Math.max(1, width);
38
- const out: string[] = [];
39
- for (const para of String(text).split("\n")) {
40
- let line = "", len = 0;
41
- for (const word of para.split(" ")) {
42
- const cps = [...word];
43
- if (line && len + 1 + cps.length <= w) { line += " " + word; len += 1 + cps.length; continue; }
44
- if (line) out.push(line);
45
- while (cps.length > w) out.push(cps.splice(0, w).join(""));
46
- line = cps.join(""); len = cps.length;
47
- }
48
- out.push(line);
49
- }
50
- return out;
51
- }
52
-
53
- /** hard-split a line into `width`-cell chunks (terminal-style, no word boundaries; one cell per
54
- * code point — an astral glyph moves to the next row whole); "" → [""] */
55
- export function hardWrap(line: string, width: number): string[] {
56
- const w = Math.max(1, width);
57
- const cps = [...line];
58
- if (cps.length <= w) return [line];
59
- const out: string[] = [];
60
- for (let i = 0; i < cps.length; i += w) out.push(cps.slice(i, i + w).join(""));
61
- return out;
62
- }
63
-
64
- /** inner rect of a panel drawn at `r` (2 cells of horizontal padding, 1 row for each border) */
65
- export const inner = (r: Rect): Rect => ({ x: r.x + 2, y: r.y + 1, w: r.w - 4, h: r.h - 2 });