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,399 +0,0 @@
1
- /** Port #45 — rovecode, the weather-cloud pet of the sextant surface: sprite + quip tables, observation
2
- * of written lines, moods derived from real activity, storms, sleep, pokes. Ported from the user's own
3
- * sextant v0.4.0 prototype `src/pet.js` (user-owned; the mock typing/scenario hooks are gone — every
4
- * input is a RunEvent-derived call from the renderer). PURE: every method takes `now`; no wall clock,
5
- * no timers, no unseeded randomness, no environment access — randomness is a seeded PRNG stepped only
6
- * by caller-driven events (never by drawing), so identical scripts at identical clocks draw identically. */
7
-
8
- import type { ActivityState, SextantState } from "./types.ts";
9
-
10
- // ------------------------------------------------------------------ data tables (pet.js:10-85)
11
-
12
- /** outline cloud in the panels' rounded-line language: 18 cells wide, 6 rows */
13
- export const SPRITE: readonly string[] = [
14
- " ╭────╮ ",
15
- " ╭───╯ ╰──╮ ",
16
- " ╭╯ ╰╮ ",
17
- " │ │ ",
18
- " ╰╮ ╭╯ ",
19
- " ╰───────────╯ ",
20
- ];
21
- /** face anchors inside the sprite: eye columns, mouth column, eye/mouth rows */
22
- export const FACE = { EYE_L: 6, EYE_R: 12, MOUTH: 9, EYE_ROW: 3, MOUTH_ROW: 4 } as const;
23
- /** per row: [first, last] outline column — the storm fill paints strictly between them
24
- * (pet.js:19 searched /S/, a typo for /\S/ that filled the whole box; the intent is the interior) */
25
- export const INNER: readonly (readonly [number, number])[] = SPRITE.map((row) => {
26
- const a = row.search(/\S/);
27
- const b = row.length - 1 - [...row].reverse().join("").search(/\S/);
28
- return [a, b] as const;
29
- });
30
- /** glyphs that drizzle under the cloud while a file is being edited */
31
- export const CODE_RAIN = "{};=()<>:.";
32
-
33
- export type QuipKind =
34
- | "start" | "glob" | "grep" | "read" | "plan" | "permission" | "allowed" | "denied" | "edit" | "write"
35
- | "remove" | "run" | "pass" | "fail" | "error" | "done" | "stopped" | "fresh" | "theme" | "poke" | "idle"
36
- | "sleep" | "todo" | "long" | "failLine" | "risk" | "spawn" | "laneDone" | "laneFail" | "merge" | "thinking"
37
- | "fetch" | "crew" | "tinker"; // the network, a child's progress, housekeeping (providers/skills/memory/MCP) — acts no older kind covers
38
-
39
- /** what the cloud says on events; `{n} {f} {q} {r} {a} {d} {changed}` are filled from the event data.
40
- * `poke` is ordered so the first poke greets ("hi.") and later pokes cycle the pool. */
41
- export const QUIPS: Readonly<Record<QuipKind, readonly string[]>> = {
42
- start: ["on it.", "let's see what we've got.", "rolling in."],
43
- glob: ["sniffing for {q}…", "where is {q}…", "looking for {q}."], // a search STARTS here (glob and grep, {q} = the pattern); grep's count lands in `grep`
44
- grep: ["found {n}.", "{n}. noted."],
45
- fetch: ["fetching {f}.", "off to {f}.", "knocking on {f}."],
46
- crew: ["checking on {a}.", "{a}, how's it going.", "peeking at {a}."],
47
- tinker: ["poking at {f}.", "a look at {f}.", "fiddling with {f}."],
48
- read: ["reading {f}.", "let me skim {f}."],
49
- plan: ["{n} steps. easy.", "got a plan. {n} steps."],
50
- permission: ["your call ▸", "need a nod from you."],
51
- allowed: ["thanks ♥", "♥ on it."],
52
- denied: ["okay, hands off.", "fair. stopping."],
53
- edit: ["raining code on {f}.", "sprinkling {f}.", "a light shower over {f}."],
54
- write: ["a fresh {f}.", "new file, new weather: {f}."],
55
- remove: ["blowing {f} away.", "bye, {f}."],
56
- run: ["thunder time.", "rumble rumble.", "charging up…"],
57
- pass: ["{r}. sunny skies.", "clear skies ☼ {r}.", "{r}. told you."],
58
- fail: ["{r}. GRR.", "red. i hate red.", "{r}. fixing it. NOW."],
59
- error: ["storm's here.", "who wrote THAT.", "no. no no no.", "grr."],
60
- done: ["all clear ☼", "nice work, us.", "sun's out."],
61
- stopped: ["okay, stopping.", "pausing the rain."],
62
- fresh: ["fresh sky.", "clean slate."],
63
- theme: ["ooh, new sky.", "i like this light."],
64
- poke: ["hi.", "hehe.", "♪", "that tickles.", "yes?"],
65
- idle: ["humming ♪", "ready when you are.", "the files look calm.", "nice day for a refactor.", "♪ ♪"],
66
- sleep: ["zzz…", "…", "mm."],
67
- todo: ["one down.", "{d}/{n}. moving.", "check.", "that's {d} of {n}."],
68
- long: ["still going. hang tight.", "big one. i'm here."],
69
- failLine: ["GRR.", "red. RED.", "that one leaked. grr."],
70
- risk: ["hm. that one's risky.", "i'd look at that twice."],
71
- spawn: ["sending {a} in.", "{a}, you're up.", "go, {a}. i'll watch."],
72
- laneDone: ["{a} is back · {r}.", "{a}: {r}. nice.", "{a} done. {r}."],
73
- laneFail: ["{a} tripped · {r}.", "hm. {a} didn't make it."],
74
- merge: ["stitching it together.", "all hands back. merging."],
75
- // the run header's word while the model reasons and nothing else moves: weather for a cloud working
76
- // something out — the familiar word first, and the rotation (not a stuck spinner) is what says "still alive"
77
- thinking: ["thinking", "brewing", "gathering", "mulling", "sifting", "condensing", "circling", "weighing"],
78
- };
79
-
80
- /** the word for `elapsedMs` into a reasoning phase: one step every 4 s — slow enough to read, fast enough that 15 s changes it three times */
81
- export const thinkingWord = (elapsedMs: number): string => QUIPS.thinking[Math.floor(Math.max(0, elapsedMs) / 4000) % QUIPS.thinking.length] ?? "thinking";
82
-
83
- /** what the cloud notices in lines being written (first matching row wins, per line) */
84
- export const OBSERVE: readonly (readonly [RegExp, string])[] = [
85
- [/httpOnly/i, "httpOnly. good call."],
86
- [/secure:\s*true/, "secure cookie ♥"],
87
- [/sameSite/i, "sameSite too. tidy."],
88
- [/TODO|FIXME/, "a TODO. i'll remember it."],
89
- [/console\.log/, "leftover console.log?"],
90
- [/throw new/, "throwing. brave."],
91
- [/try \{/, "try… fingers crossed for the catch."],
92
- [/catch \(/, "…and a catch. phew."],
93
- [/^import .* from/, "imports rolling in."],
94
- [/^export (default |async )?(function|const|class)/, "a new export."],
95
- [/status\(4\d\d\)/, "a 4xx. firm but fair."],
96
- [/status\(5\d\d\)/, "a 5xx? hope that's on purpose."],
97
- [/sqlite|\bdb\.|prepare\(/i, "talking to the database."],
98
- [/crypto|randomBytes|timingSafeEqual/, "crypto. spooky."],
99
- [/\b(test|it|describe)\(/, "a test! my favorite."],
100
- [/req\.ip|forwarded/i, "who's calling? checking the ip."],
101
- [/SIGTERM|process\.exit|\.close\(/, "graceful. i like graceful."],
102
- [/rateLimit|429/, "rate limits. slow down, world."],
103
- [/csrf|verifyState|\bstate\b/i, "state check. no sneaky redirects."],
104
- [/expires|maxAge/i, "expiry set. nothing lives forever."],
105
- [/cookie/i, "cookies. i want one."],
106
- [/redirect\(/, "and… redirect."],
107
- [/async /, "async. i'll wait."],
108
- ];
109
- /** what the cloud notices in lines being removed */
110
- export const OBSERVE_DEL: readonly (readonly [RegExp, string])[] = [
111
- [/legacy/i, "goodbye, legacy."],
112
- [/new Map\(\)/, "bye, in-memory Map."],
113
- [/console\.log/, "console.log, gone. clean."],
114
- [/token\.access_token/, "raw token in a cookie, gone. good."],
115
- ];
116
-
117
- // ------------------------------------------------------------------ types + tunables
118
-
119
- /** the pinned mood table, in precedence order (see mood()) */
120
- export type Mood = "furious" | "patient" | "conducting" | "focused" | "zapping" | "sunny" | "sleepy" | "humming";
121
- export const MOODS: readonly Mood[] = ["furious", "patient", "conducting", "focused", "zapping", "sunny", "sleepy", "humming"];
122
-
123
- /** what the pet knows about the world this frame — derived from SextantState by moodCtxFrom() */
124
- export interface MoodCtx {
125
- state: ActivityState;
126
- running: boolean;
127
- /** an approval or ask_user card is open → WAITING */
128
- waiting: boolean;
129
- /** the crew has queued/running tasks → DELEGATING */
130
- delegating: boolean;
131
- /** clock of the last error the state knows about (null = none) — informational: the storm is armed by
132
- * tick() on the state's edge into ERROR, never by comparing this clock (a failed tool the model leaves
133
- * with endedAt null shares one clock across the whole run; one error = one storm must hold per episode) */
134
- errorAt: number | null;
135
- tokens: number;
136
- /** last run activity clock known to the state (0 = none) — keeps the pet awake */
137
- activeAt: number;
138
- /** startedAt of the run in flight (null when not running) — "still going" after 25 s */
139
- runStartedAt: number | null;
140
- /** modified files in the repo — the "busy branch" hum */
141
- changed: number;
142
- /** the prompt has text — the eyes glance at the input */
143
- typing: boolean;
144
- /** first 1.3 s after boot — the cloud opens its eyes last, no ambient hums yet */
145
- booting: boolean;
146
- }
147
-
148
- export type FxKind = "bounce" | "shiver" | "sparkle" | "hearts";
149
- export interface PetFx { kind: FxKind; until: number; seed: number }
150
- export type QuipTone = "event" | "observe" | "ambient";
151
- export interface PetQuip { text: string; until: number; kind: QuipTone }
152
-
153
- export interface PetState {
154
- name: string;
155
- pokes: number;
156
- quip: PetQuip | null;
157
- lastQuipAt: number;
158
- lastEventKind: PetEventKind | null; // the last event quip that took the bubble (the rate rule collapses same-kind repeats)
159
- /** null until the first tick/event — "born on first sight", since createPet takes no clock */
160
- lastActiveAt: number | null;
161
- fx: PetFx[];
162
- glance: { dir: -1 | 0 | 1; until: number } | null;
163
- nextObserveAt: number;
164
- /** an observation made while an event quip was showing; said once that quip ends — unless it is older than
165
- * OBSERVE_DEFER_MS by then (dropped: a 2-minute permission quip must not surface it minutes later) */
166
- pendingObserve: { text: string; at: number } | null;
167
- nextSuggestAt: number;
168
- lastSuggest: string;
169
- saidLong: boolean;
170
- stormUntil: number;
171
- /** the state was ERROR on the previous tick — the storm arms on the edge into ERROR, so a lingering ERROR
172
- * is one storm and a second ERROR episode in the same run is a second storm */
173
- wasError: boolean;
174
- todosDone: number;
175
- }
176
-
177
- export type PetEventKind = QuipKind | "tool_fail" | "todo_done";
178
- export type PetEventData = Readonly<Record<string, string | number | undefined>>;
179
- export type ReactKind = "fail-line" | "pass-line" | "risk";
180
-
181
- export interface Pet {
182
- readonly state: PetState;
183
- /** a line was written ("ins") or removed ("del"); one utterance per OBSERVE_GAP_MS */
184
- observe(text: string, kind: "ins" | "del", now: number): void;
185
- /** immediate reaction to an output line (a red test line storms at once) */
186
- react(kind: ReactKind, now: number): void;
187
- event(kind: PetEventKind, data: PetEventData | undefined, now: number): void;
188
- /** the user is typing; the cloud guesses the command ("/help? sure.") */
189
- suggest(label: string, now: number): void;
190
- /** a click: jump + hearts + a greeting; event("poke") is the same call — both count the poke, so the first
191
- * says "hi." and later pokes cycle the pool (the integration may use either) */
192
- poke(now: number): void;
193
- /** an event-tone quip from the surface itself — app.js used pet.say for `/pet <name>` ("<name>? i like it.",
194
- * after setting state.name), /mode and /crew; ms defaults to 4200 and observations defer behind it */
195
- say(text: string, now: number, ms?: number): void;
196
- /** 1 + floor(sqrt(tokens / 1500)) — grows stepwise with tokens */
197
- level(tokens: number): number;
198
- mood(ctx: MoodCtx, now: number): Mood;
199
- /** a quip, an effect or a storm is live (the renderer may want a faster frame) */
200
- animating(now: number): boolean;
201
- /** per-frame housekeeping: expire fx, arm a storm on the state's edge into ERROR, clear storms on SUCCESS,
202
- * flush (or drop, past 10 s) a deferred observation, ambient hums / snores / "still going" — drawPet calls
203
- * it once per frame */
204
- tick(now: number, ctx?: MoodCtx): void;
205
- }
206
-
207
- export const OBSERVE_GAP_MS = 5500;
208
- /** a deferred observation older than this is dropped instead of spoken late */
209
- export const OBSERVE_DEFER_MS = 10_000;
210
- export const STORM_MIN_MS = 5000;
211
- export const STORM_MAX_MS = 7000;
212
- export const SLEEP_AFTER_MS = 45_000;
213
- export const LONG_RUN_MS = 25_000;
214
- export const BOOT_MS = 1300;
215
- const IDLE_HUM_MS = 11_000;
216
- const SLEEP_HUM_MS = 16_000;
217
- const PERMISSION_QUIP_MS = 120_000;
218
-
219
- /** mulberry32 — a tiny seeded PRNG in [0, 1); stepped only by events, never by drawing */
220
- export function seededRandom(seed: number): () => number {
221
- let a = seed >>> 0;
222
- return () => {
223
- a = (a + 0x6d2b79f5) >>> 0;
224
- let t = a;
225
- t = Math.imul(t ^ (t >>> 15), t | 1);
226
- t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
227
- return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
228
- };
229
- }
230
-
231
- /** ROVECODE_PET=0 (or false/off/no) removes the panel; the renderer passes its environment map */
232
- export function petEnabled(env: Readonly<Record<string, string | undefined>>): boolean {
233
- const v = (env.ROVECODE_PET ?? "").trim().toLowerCase();
234
- return !(v === "0" || v === "false" || v === "off" || v === "no");
235
- }
236
-
237
- /** the pet's view of the surface state (app.js:749 ctx, minus the mock fields) */
238
- export function moodCtxFrom(s: SextantState, now: number): MoodCtx {
239
- const a = s.activity;
240
- return {
241
- state: a.state,
242
- running: s.running,
243
- waiting: s.card != null,
244
- delegating: s.crew.some((t) => t.status === "queued" || t.status === "running"),
245
- errorAt: a.state === "ERROR" ? (a.errorAt ?? a.endedAt ?? a.startedAt ?? 0) : null,
246
- tokens: s.usage.tokensIn + s.usage.tokensOut,
247
- activeAt: Math.max(a.startedAt ?? 0, a.endedAt ?? 0),
248
- runStartedAt: s.running ? a.startedAt : null,
249
- changed: s.repo.modified,
250
- typing: s.input.text.length > 0,
251
- booting: now - s.bootAt < BOOT_MS,
252
- };
253
- }
254
-
255
- // ------------------------------------------------------------------ the pet (pet.js makePet)
256
-
257
- const GLANCE_KINDS: readonly PetEventKind[] = ["read", "edit", "write", "plan", "grep", "glob", "run", "remove", "spawn", "laneDone", "fetch", "crew", "tinker"];
258
- const CALM_KINDS: readonly PetEventKind[] = ["done", "pass", "start", "fresh", "stopped"];
259
- /** kinds that always take the bubble (the rate rule in event()): outcomes, refusals, asks, the user */
260
- const URGENT_KINDS: ReadonlySet<PetEventKind> = new Set<PetEventKind>(["start", "done", "stopped", "pass", "fail", "error", "failLine", "denied", "permission", "allowed", "poke", "theme", "fresh", "laneDone", "laneFail", "merge", "risk", "long", "todo", "todo_done", "tool_fail"]);
261
- export const MIN_DWELL_MS = 1500; // a routine quip holds the floor at least this long before another routine kind may replace it
262
-
263
- export function createPet(opts: { name?: string; seed?: number } = {}): Pet {
264
- const rnd = seededRandom(opts.seed ?? 7);
265
- const P: PetState = {
266
- name: (opts.name || "rovecode").slice(0, 14),
267
- pokes: 0, quip: null, lastQuipAt: 0, lastEventKind: null, lastActiveAt: null, fx: [], glance: null,
268
- nextObserveAt: 0, pendingObserve: null, nextSuggestAt: 0, lastSuggest: "", saidLong: false,
269
- stormUntil: 0, wasError: false, todosDone: 0,
270
- };
271
- const pick = (arr: readonly string[], idx?: number): string => arr[(idx ?? Math.floor(rnd() * 1e6)) % arr.length] ?? "";
272
- const fmt = (t: string, d?: PetEventData): string =>
273
- t.replace(/\{(\w+)\}/g, (_m, k: string) => { const v = d?.[k]; return v == null ? "" : String(v); });
274
- /** first sight = birth (the prototype stamped creation with the wall clock) */
275
- const wake = (now: number): void => { if (P.lastActiveAt == null) { P.lastActiveAt = now; P.lastQuipAt = now - 5000; } };
276
- /** also the public Pet.say (event tone); wake() is a no-op for the internal callers, which already woke */
277
- const say = (text: string, now: number, ms = 4200, kind: QuipTone = "event"): void => { wake(now); P.quip = { text, until: now + ms, kind }; P.lastQuipAt = now; };
278
- const quipActive = (now: number): boolean => P.quip != null && P.quip.until > now;
279
- const eventQuipActive = (now: number): boolean => quipActive(now) && P.quip?.kind === "event";
280
- const glance = (dir: -1 | 0 | 1, now: number, ms: number): void => { P.glance = { dir, until: now + ms }; };
281
- const fx = (kind: FxKind, now: number, ms: number): void => { P.fx.push({ kind, until: now + ms, seed: Math.floor(rnd() * 9973) }); };
282
- /** a storm lasts 5-7 s (seeded); a new error never shortens a live one — cleared early by SUCCESS / done / start */
283
- const storm = (now: number): void => {
284
- P.stormUntil = Math.max(P.stormUntil, now + STORM_MIN_MS + Math.floor(rnd() * (STORM_MAX_MS - STORM_MIN_MS)));
285
- };
286
-
287
- function observe(text: string, kind: "ins" | "del", now: number): void {
288
- wake(now);
289
- if (now < P.nextObserveAt) return;
290
- const table = kind === "del" ? OBSERVE_DEL : OBSERVE;
291
- let found: string | null = null;
292
- for (const line of text.split(/\r?\n/)) {
293
- const hit = table.find(([re]) => re.test(line));
294
- if (hit) { found = hit[1]; break; }
295
- }
296
- if (found == null) return;
297
- P.nextObserveAt = now + OBSERVE_GAP_MS;
298
- // an edit's event quip ("raining code on x.ts.") keeps the floor; the observation follows it
299
- if (eventQuipActive(now)) P.pendingObserve = { text: found, at: now };
300
- else say(found, now, 3200, "observe");
301
- }
302
-
303
- function react(kind: ReactKind, now: number): void {
304
- wake(now);
305
- P.lastActiveAt = now;
306
- if (kind === "fail-line") { say(pick(QUIPS.failLine), now, 2600); fx("shiver", now, 640); storm(now); }
307
- else if (kind === "pass-line") fx("bounce", now, 400);
308
- else if (kind === "risk") say(pick(QUIPS.risk), now, 3600, "observe");
309
- }
310
-
311
- function suggest(label: string, now: number): void {
312
- wake(now);
313
- if (label === P.lastSuggest) return;
314
- P.lastSuggest = label;
315
- if (now < P.nextSuggestAt || eventQuipActive(now)) return;
316
- say(`${label}? sure.`, now, 2200, "observe");
317
- P.nextSuggestAt = now + 4000;
318
- }
319
-
320
- function event(kind: PetEventKind, data: PetEventData | undefined, now: number): void {
321
- wake(now);
322
- P.lastActiveAt = now;
323
- if (kind === "todo_done") {
324
- const d = Number(data?.d ?? P.todosDone + 1), n = data?.n;
325
- P.todosDone = d;
326
- const pool = n == null ? QUIPS.todo.filter((q) => !q.includes("{n}")) : QUIPS.todo;
327
- say(fmt(pick(pool), { d, n }), now, 2600, "observe");
328
- fx("bounce", now, 240);
329
- return;
330
- }
331
- if (kind === "tool_fail") { say(fmt(pick(QUIPS.error), data), now); fx("shiver", now, 640); storm(now); return; }
332
- // the rate rule — routine quips (tool starts) must not flap at machine speed: a live same-kind quip keeps the
333
- // floor (ten reads name the first file), a different routine kind waits MIN_DWELL_MS (the time to read six
334
- // words); verdicts, refusals, asks and the user's pokes always take it
335
- if (!URGENT_KINDS.has(kind) && eventQuipActive(now) && (kind === P.lastEventKind || now - P.lastQuipAt < MIN_DWELL_MS)) {
336
- if (GLANCE_KINDS.includes(kind)) glance(1, now, 2600); // the cloud still looks over at the work
337
- return;
338
- }
339
- P.lastEventKind = kind;
340
- if (kind === "poke") P.pokes++; // counted here so event("poke") and poke() are the same click
341
- const pool = QUIPS[kind];
342
- const text = kind === "poke" ? pick(pool, P.pokes - 1) : pick(pool);
343
- say(fmt(text, data), now, kind === "permission" ? PERMISSION_QUIP_MS : kind === "done" || kind === "pass" ? 6000 : 4200);
344
- if (kind === "pass" || kind === "done") fx("sparkle", now, 3600);
345
- if (kind === "allowed") fx("hearts", now, 1800);
346
- if (kind === "poke") { fx("bounce", now, 800); fx("hearts", now, 1800); glance(0, now, 1500); }
347
- if (kind === "theme") fx("sparkle", now, 1400);
348
- if (kind === "error" || kind === "fail") storm(now);
349
- if (CALM_KINDS.includes(kind)) P.stormUntil = 0;
350
- if (GLANCE_KINDS.includes(kind)) glance(1, now, 2600);
351
- if (kind === "start") { P.saidLong = false; P.lastSuggest = ""; }
352
- }
353
-
354
- function poke(now: number): void { event("poke", undefined, now); }
355
- const level = (tokens: number): number => 1 + Math.floor(Math.sqrt(Math.max(0, tokens) / 1500));
356
-
357
- function mood(ctx: MoodCtx, now: number): Mood {
358
- if (ctx.state === "ERROR" || now < P.stormUntil) return "furious";
359
- if (ctx.waiting || ctx.state === "WAITING") return "patient";
360
- if (ctx.delegating || ctx.state === "DELEGATING") return "conducting";
361
- if (ctx.state === "EDITING") return "focused";
362
- if (ctx.state === "RUNNING" || ctx.state === "TESTING") return "zapping";
363
- if (ctx.state === "SUCCESS") return "sunny";
364
- const last = Math.max(P.lastActiveAt ?? now, ctx.activeAt);
365
- if (!ctx.running && now - last >= SLEEP_AFTER_MS) return "sleepy";
366
- return "humming";
367
- }
368
-
369
- const animating = (now: number): boolean => quipActive(now) || now < P.stormUntil || P.fx.some((f) => f.until > now);
370
-
371
- function tick(now: number, ctx?: MoodCtx): void {
372
- wake(now);
373
- P.fx = P.fx.filter((f) => f.until > now);
374
- if (P.glance && P.glance.until <= now) P.glance = null;
375
- if (P.quip && P.quip.until <= now) P.quip = null;
376
- if (P.pendingObserve != null) {
377
- if (now - P.pendingObserve.at > OBSERVE_DEFER_MS) P.pendingObserve = null; // stale: dropped, never spoken late
378
- else if (!eventQuipActive(now)) { say(P.pendingObserve.text, now, 3200, "observe"); P.pendingObserve = null; }
379
- }
380
- if (!ctx) return;
381
- // edge-trigger: the storm arms when the state enters ERROR (one episode = one storm however long it lingers;
382
- // a second failed tool in the same run — ERROR → READING → ERROR — storms again even with one error clock)
383
- const inError = ctx.state === "ERROR";
384
- if (inError && !P.wasError) storm(now);
385
- P.wasError = inError;
386
- if (ctx.state === "SUCCESS") P.stormUntil = 0;
387
- const sleeping = mood(ctx, now) === "sleepy";
388
- if (!ctx.running && !ctx.booting && !quipActive(now) && now - P.lastQuipAt > (sleeping ? SLEEP_HUM_MS : IDLE_HUM_MS)) {
389
- const pool = sleeping ? QUIPS.sleep : ctx.changed > 8 ? [...QUIPS.idle, "{changed} modified files. busy branch."] : QUIPS.idle;
390
- say(fmt(pick(pool), { changed: ctx.changed }), now, 3800, "ambient");
391
- }
392
- if (ctx.running && ctx.runStartedAt != null && now - ctx.runStartedAt > LONG_RUN_MS && !P.saidLong && !quipActive(now)) {
393
- P.saidLong = true;
394
- say(pick(QUIPS.long), now, 3500, "ambient");
395
- }
396
- }
397
-
398
- return { state: P, observe, react, event, suggest, poke, say, level, mood, animating, tick };
399
- }