rovecode 0.3.2 → 0.4.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (491) hide show
  1. package/CHANGELOG.md +512 -0
  2. package/README.md +33 -45
  3. package/bin/rovecode.js +24 -0
  4. package/dist/cli/app-dybnr56b.js +2 -0
  5. package/dist/cli/ask-user-p8hq4xgj.js +2 -0
  6. package/dist/cli/auth-login-ewpgw5sm.js +2 -0
  7. package/dist/cli/auth-m8p9grty.js +2 -0
  8. package/dist/cli/bench-xv3ypwev.js +9 -0
  9. package/dist/cli/catalog-737wb2s0.js +2 -0
  10. package/dist/cli/cli-arhg40m0.js +2 -0
  11. package/dist/cli/client-cf2pxx8q.js +2 -0
  12. package/dist/cli/commands-3p7e4xxs.js +2 -0
  13. package/dist/cli/connect-3q93d7cb.js +2 -0
  14. package/dist/cli/context-cmd-eqxmxhzq.js +2 -0
  15. package/dist/cli/context-report-hbw9zfes.js +2 -0
  16. package/dist/cli/count-remote-mby98cd0.js +2 -0
  17. package/dist/cli/design-122y0axd.js +2 -0
  18. package/dist/cli/dispatch-b4egzvvh.js +2 -0
  19. package/dist/cli/doctor-x4jkv72e.js +3 -0
  20. package/dist/cli/executor-ftvg6tsy.js +2 -0
  21. package/dist/cli/export-pdgdhkch.js +2 -0
  22. package/dist/cli/files-cez9a96p.js +2 -0
  23. package/dist/cli/gauntlet-r3xxaszc.js +2 -0
  24. package/dist/cli/gauntlet-runner-r515m7kk.js +10 -0
  25. package/dist/cli/gauntlet-wave3-bnkjk2v2.js +5 -0
  26. package/dist/cli/gauntlet-wave4-acs9s60q.js +14 -0
  27. package/dist/cli/hashline-ewg5hbe3.js +2 -0
  28. package/dist/cli/http-n0kehsk8.js +5 -0
  29. package/dist/cli/index-z5qt1s76.js +2 -0
  30. package/dist/cli/install-80mp63kx.js +2 -0
  31. package/dist/cli/loop-12twjcat.js +2 -0
  32. package/dist/cli/main-01pv9206.js +4 -0
  33. package/dist/cli/main-0jys2ccn.js +3 -0
  34. package/dist/cli/main-1ztz6fkj.js +10 -0
  35. package/dist/cli/main-23q7cmww.js +9 -0
  36. package/dist/cli/main-2rzbexn2.js +3 -0
  37. package/dist/cli/main-2wyax8k9.js +9 -0
  38. package/dist/cli/main-2yeveeve.js +6 -0
  39. package/dist/cli/main-2z3dek0b.js +3 -0
  40. package/dist/cli/main-2zgsknth.js +3 -0
  41. package/dist/cli/main-45ejth3a.js +4 -0
  42. package/dist/cli/main-45rn3trk.js +22 -0
  43. package/dist/cli/main-4p4e2w7x.js +4 -0
  44. package/dist/cli/main-4y0tnfpa.js +16 -0
  45. package/dist/cli/main-5py0rkmc.js +4 -0
  46. package/dist/cli/main-6dtqmbt6.js +7 -0
  47. package/dist/cli/main-6h9x282m.js +4 -0
  48. package/dist/cli/main-6vjeds42.js +3 -0
  49. package/dist/cli/main-78gq4bt9.js +6 -0
  50. package/dist/cli/main-7jd5vh3x.js +4 -0
  51. package/dist/cli/main-7kt6r53y.js +4 -0
  52. package/dist/cli/main-8c1tbazx.js +58 -0
  53. package/dist/cli/main-9a9rnh47.js +19 -0
  54. package/dist/cli/main-9ht36z12.js +3 -0
  55. package/dist/cli/main-a2yfvcy9.js +7 -0
  56. package/dist/cli/main-a3f51n0x.js +5 -0
  57. package/dist/cli/main-b8zq261k.js +3 -0
  58. package/dist/cli/main-bxtvnf6d.js +13 -0
  59. package/dist/cli/main-edxc3yzt.js +4 -0
  60. package/dist/cli/main-evgz4mp5.js +21 -0
  61. package/dist/cli/main-f33fc5je.js +9 -0
  62. package/dist/cli/main-fvnpq46y.js +12 -0
  63. package/dist/cli/main-gbbty4d4.js +3 -0
  64. package/dist/cli/main-gth53dnt.js +25 -0
  65. package/dist/cli/main-hqbz10aw.js +9 -0
  66. package/dist/cli/main-hrrvcfan.js +38 -0
  67. package/dist/cli/main-hzwtsb2m.js +5 -0
  68. package/dist/cli/main-j7ttv0sd.js +34 -0
  69. package/dist/cli/main-jak598k9.js +5 -0
  70. package/dist/cli/main-kba6zeyd.js +6 -0
  71. package/dist/cli/main-kwwsz6rq.js +3 -0
  72. package/dist/cli/main-m8vm17zq.js +3 -0
  73. package/dist/cli/main-mg4f96e1.js +3 -0
  74. package/dist/cli/main-mg9b20ac.js +18 -0
  75. package/dist/cli/main-mgb9ccnx.js +3 -0
  76. package/dist/cli/main-mjt2p7aj.js +3 -0
  77. package/dist/cli/main-n6qrdbmy.js +3 -0
  78. package/dist/cli/main-na7wse0x.js +5 -0
  79. package/dist/cli/main-nqveez48.js +4 -0
  80. package/dist/cli/main-ntqef02r.js +10 -0
  81. package/dist/cli/main-nvc3yjay.js +136 -0
  82. package/dist/cli/main-p0cfn6nr.js +16 -0
  83. package/dist/cli/main-qj2djy17.js +19 -0
  84. package/dist/cli/main-qsevpgsv.js +3 -0
  85. package/dist/cli/main-qvarybsp.js +3 -0
  86. package/dist/cli/main-rebtt91r.js +5 -0
  87. package/dist/cli/main-rpg7h8mb.js +3 -0
  88. package/dist/cli/main-rsy72qmw.js +15 -0
  89. package/dist/cli/main-rvetps99.js +18 -0
  90. package/dist/cli/main-s4bb0jav.js +3 -0
  91. package/dist/cli/main-s9v8k74e.js +3 -0
  92. package/dist/cli/main-tjvwmscs.js +3 -0
  93. package/dist/cli/main-tkgarpjj.js +4 -0
  94. package/dist/cli/main-v8y60bb2.js +3 -0
  95. package/dist/cli/main-vhrrq337.js +3 -0
  96. package/dist/cli/main-vp2dfb7s.js +4 -0
  97. package/dist/cli/main-vqbr22sz.js +8 -0
  98. package/dist/cli/main-vxnwe5xx.js +18 -0
  99. package/dist/cli/main-wgph00xf.js +5 -0
  100. package/dist/cli/main-wk2csfnj.js +5 -0
  101. package/dist/cli/main-wm997zjx.js +3 -0
  102. package/dist/cli/main-wpkyraxh.js +3 -0
  103. package/dist/cli/main-wqt32p5x.js +4 -0
  104. package/dist/cli/main-x9ct6y1a.js +3 -0
  105. package/dist/cli/main-xfekqh9m.js +7 -0
  106. package/dist/cli/main-xt9zc3n6.js +7 -0
  107. package/dist/cli/main-xx2z3zh5.js +4 -0
  108. package/dist/cli/main-y5c82rxr.js +3 -0
  109. package/dist/cli/main-yrjt2sqt.js +14 -0
  110. package/dist/cli/main-ys6zj3yr.js +3 -0
  111. package/dist/cli/main-ywbxshqc.js +8 -0
  112. package/dist/cli/main-z13755t8.js +25 -0
  113. package/dist/cli/main-zc7pyrbj.js +4 -0
  114. package/dist/cli/main.js +279 -0
  115. package/dist/cli/market-cmd-bm5xvn9f.js +5 -0
  116. package/dist/cli/mcp-login-bthtfpt7.js +2 -0
  117. package/dist/cli/mcp-market-cmd-mbeshfyd.js +2 -0
  118. package/dist/cli/notify-54v5z9dz.js +2 -0
  119. package/dist/cli/oauth-g5gme95c.js +2 -0
  120. package/dist/cli/output-satndjap.js +16 -0
  121. package/dist/cli/profiles-sfhpbq3m.js +2 -0
  122. package/dist/cli/provider-config-hv3xtdt4.js +2 -0
  123. package/dist/cli/provider-kwzq6g84.js +2 -0
  124. package/dist/cli/registry-fh0hdnyn.js +2 -0
  125. package/dist/cli/registry-y1y8e94r.js +2 -0
  126. package/dist/cli/repl-t4z03mqq.js +11 -0
  127. package/dist/cli/resume-fqt4chg8.js +2 -0
  128. package/dist/cli/run-flags-rysbag9t.js +2 -0
  129. package/dist/cli/runtime-j19fjbsa.js +2 -0
  130. package/dist/cli/sandbox-config-g4qxd7y5.js +2 -0
  131. package/dist/cli/server-r0b6bksk.js +5 -0
  132. package/dist/cli/session-arg-txmn5g4x.js +2 -0
  133. package/dist/cli/session-ed250d9j.js +2 -0
  134. package/dist/cli/sessions-cmd-adw7svfn.js +7 -0
  135. package/dist/cli/settings-y9rzcqx8.js +2 -0
  136. package/dist/cli/setup-jmbr11j0.js +2 -0
  137. package/dist/cli/sextant-smoke-tcth0vea.js +5 -0
  138. package/dist/cli/skills-cmd-zbdy99v6.js +2 -0
  139. package/dist/cli/smoke-1bg937kx.js +8 -0
  140. package/dist/cli/start-chat-p01cdks3.js +12 -0
  141. package/dist/cli/stream-4wmyaypz.js +2 -0
  142. package/dist/cli/task-eg4s093s.js +2 -0
  143. package/dist/cli/tasks-12v9rr9k.js +2 -0
  144. package/dist/cli/thinking-a5ngvqyh.js +2 -0
  145. package/dist/cli/todo-1wxpcecx.js +2 -0
  146. package/dist/cli/tools-2ftsya7w.js +2 -0
  147. package/dist/cli/tools-x1tj4fxm.js +2 -0
  148. package/dist/cli/trust-cmd-hccxehzb.js +2 -0
  149. package/dist/cli/update-check-ygt3vd7m.js +2 -0
  150. package/dist/cli/update-cmd-v23qhr8c.js +2 -0
  151. package/dist/cli/voice-g1gtck92.js +2 -0
  152. package/dist/cli/webfetch-0nnrjgb5.js +2 -0
  153. package/dist/cli/websearch-f0vr2p7d.js +2 -0
  154. package/dist/cli/workspace-9rq1w4ta.js +2 -0
  155. package/dist/lib/index.js +62 -0
  156. package/dist/lib/models-index.json +1 -0
  157. package/dist/lib/plugins.js +6 -0
  158. package/dist/lib/providers.js +17 -0
  159. package/dist/lib/public-api.js +20 -0
  160. package/dist/rovecode.exe +4 -0
  161. package/package.json +38 -11
  162. package/bin/rovecode.ts +0 -21
  163. package/src/acp/server.ts +0 -374
  164. package/src/cli/auth-login.ts +0 -122
  165. package/src/cli/connect.ts +0 -244
  166. package/src/cli/context-cmd.ts +0 -199
  167. package/src/cli/dispatch.ts +0 -82
  168. package/src/cli/doctor.ts +0 -362
  169. package/src/cli/export.ts +0 -276
  170. package/src/cli/help.ts +0 -293
  171. package/src/cli/is-tui-invocation.ts +0 -8
  172. package/src/cli/main.ts +0 -583
  173. package/src/cli/market-cmd.ts +0 -658
  174. package/src/cli/mcp-login.ts +0 -141
  175. package/src/cli/mcp-market-cmd.ts +0 -302
  176. package/src/cli/output.ts +0 -382
  177. package/src/cli/repl.ts +0 -250
  178. package/src/cli/repomap-root.ts +0 -14
  179. package/src/cli/resume.ts +0 -57
  180. package/src/cli/run-flags.ts +0 -43
  181. package/src/cli/run-limits.ts +0 -78
  182. package/src/cli/runtime.ts +0 -931
  183. package/src/cli/session-arg.ts +0 -30
  184. package/src/cli/sessions-cmd.ts +0 -145
  185. package/src/cli/setup.ts +0 -153
  186. package/src/cli/skills-cmd.ts +0 -194
  187. package/src/cli/start-chat.ts +0 -65
  188. package/src/cli/trust-cmd.ts +0 -52
  189. package/src/coding/bash.ts +0 -148
  190. package/src/coding/checkpoints.ts +0 -327
  191. package/src/coding/diff.ts +0 -138
  192. package/src/coding/files.ts +0 -341
  193. package/src/coding/hashline.ts +0 -274
  194. package/src/coding/lsp-gate.ts +0 -254
  195. package/src/coding/lsp-servers.ts +0 -147
  196. package/src/coding/lsp.ts +0 -283
  197. package/src/coding/repomap-cache.ts +0 -99
  198. package/src/coding/repomap-files.ts +0 -192
  199. package/src/coding/repomap.ts +0 -481
  200. package/src/core/agents.ts +0 -255
  201. package/src/core/compaction.ts +0 -259
  202. package/src/core/config.ts +0 -289
  203. package/src/core/context-report.ts +0 -228
  204. package/src/core/context.ts +0 -60
  205. package/src/core/count-remote.ts +0 -107
  206. package/src/core/execpolicy-rules.ts +0 -196
  207. package/src/core/execpolicy.ts +0 -385
  208. package/src/core/executor.ts +0 -454
  209. package/src/core/guardrails.ts +0 -400
  210. package/src/core/hooks.ts +0 -411
  211. package/src/core/images.ts +0 -230
  212. package/src/core/intro.ts +0 -266
  213. package/src/core/loop.ts +0 -567
  214. package/src/core/modes.ts +0 -372
  215. package/src/core/orchestrator.ts +0 -245
  216. package/src/core/proc-group.ts +0 -48
  217. package/src/core/project-trust.ts +0 -98
  218. package/src/core/reflection.ts +0 -165
  219. package/src/core/sandbox-config.ts +0 -186
  220. package/src/core/session-id.ts +0 -24
  221. package/src/core/session-images.ts +0 -73
  222. package/src/core/session-ops.ts +0 -183
  223. package/src/core/session-text.ts +0 -29
  224. package/src/core/session.ts +0 -469
  225. package/src/core/settings.ts +0 -170
  226. package/src/core/tasks.ts +0 -646
  227. package/src/core/token-scale.ts +0 -108
  228. package/src/core/tools.ts +0 -309
  229. package/src/core/trust.ts +0 -104
  230. package/src/core/types.ts +0 -330
  231. package/src/core/update-check.ts +0 -171
  232. package/src/core/usage.ts +0 -204
  233. package/src/core/validate.ts +0 -121
  234. package/src/core/verify-gate.ts +0 -159
  235. package/src/core/verify.ts +0 -236
  236. package/src/core/voice.ts +0 -158
  237. package/src/core/win-job.ts +0 -183
  238. package/src/core/workspace.ts +0 -184
  239. package/src/design/audit.ts +0 -797
  240. package/src/design/direction.ts +0 -190
  241. package/src/design/rules.ts +0 -157
  242. package/src/eval/bench.ts +0 -150
  243. package/src/eval/gauntlet-runner.ts +0 -215
  244. package/src/eval/gauntlet-support.ts +0 -84
  245. package/src/eval/gauntlet-wave3.ts +0 -269
  246. package/src/eval/gauntlet-wave4.ts +0 -217
  247. package/src/eval/gauntlet.ts +0 -253
  248. package/src/index.ts +0 -17
  249. package/src/lanes/agy.ts +0 -95
  250. package/src/lanes/approval.ts +0 -24
  251. package/src/lanes/claude.ts +0 -129
  252. package/src/lanes/codex.ts +0 -127
  253. package/src/lanes/events.ts +0 -130
  254. package/src/lanes/job.ts +0 -142
  255. package/src/lanes/opencode.ts +0 -122
  256. package/src/lanes/process.ts +0 -184
  257. package/src/lanes/progress.ts +0 -183
  258. package/src/lanes/registry.ts +0 -178
  259. package/src/lanes/runner.ts +0 -124
  260. package/src/lanes/types.ts +0 -112
  261. package/src/market/catalogs/mcp-docs.json +0 -111
  262. package/src/market/catalogs/plugins.json +0 -111
  263. package/src/market/catalogs/skills.json +0 -478
  264. package/src/market/clone.ts +0 -72
  265. package/src/market/context-cost.ts +0 -121
  266. package/src/market/digest.ts +0 -106
  267. package/src/market/index.ts +0 -22
  268. package/src/market/install.ts +0 -578
  269. package/src/market/manifest.ts +0 -187
  270. package/src/market/prereq.ts +0 -145
  271. package/src/market/registry.ts +0 -363
  272. package/src/market/resolve.ts +0 -111
  273. package/src/market/types.ts +0 -236
  274. package/src/market/validate.ts +0 -227
  275. package/src/mcp/client.ts +0 -449
  276. package/src/mcp/config.ts +0 -252
  277. package/src/mcp/local-package.ts +0 -211
  278. package/src/mcp/market-catalog.ts +0 -84
  279. package/src/mcp/market-install.ts +0 -289
  280. package/src/mcp/market.ts +0 -362
  281. package/src/mcp/oauth.ts +0 -251
  282. package/src/mcp/prompts-resources.ts +0 -249
  283. package/src/mcp/shared.ts +0 -149
  284. package/src/mcp/status.ts +0 -67
  285. package/src/mcp/tools.ts +0 -275
  286. package/src/mcp/transport.ts +0 -122
  287. package/src/mcp/trust.ts +0 -25
  288. package/src/memory/blocks.ts +0 -278
  289. package/src/memory/recall.ts +0 -355
  290. package/src/memory/scope.ts +0 -182
  291. package/src/memory/store.ts +0 -105
  292. package/src/memory/tools.ts +0 -99
  293. package/src/plugins/cli.ts +0 -119
  294. package/src/plugins/discover.ts +0 -108
  295. package/src/plugins/index.ts +0 -50
  296. package/src/plugins/install.ts +0 -184
  297. package/src/plugins/load.ts +0 -124
  298. package/src/plugins/manifest.ts +0 -92
  299. package/src/plugins/state.ts +0 -83
  300. package/src/providers/auth.ts +0 -408
  301. package/src/providers/cache.ts +0 -223
  302. package/src/providers/catalog-local.ts +0 -160
  303. package/src/providers/catalog.ts +0 -421
  304. package/src/providers/middleware-context.ts +0 -86
  305. package/src/providers/middleware.ts +0 -373
  306. package/src/providers/model-list.ts +0 -23
  307. package/src/providers/oauth/common.ts +0 -105
  308. package/src/providers/oauth/device-code.ts +0 -107
  309. package/src/providers/oauth/github-copilot.ts +0 -146
  310. package/src/providers/oauth/loopback.ts +0 -158
  311. package/src/providers/oauth/openai.ts +0 -163
  312. package/src/providers/oauth/openrouter.ts +0 -89
  313. package/src/providers/oauth/pkce.ts +0 -45
  314. package/src/providers/oauth/registry.ts +0 -39
  315. package/src/providers/oauth/seam.ts +0 -89
  316. package/src/providers/profile-glm53.ts +0 -111
  317. package/src/providers/profile-sonnet5-persona.ts +0 -65
  318. package/src/providers/profile-sonnet5-voice.ts +0 -23
  319. package/src/providers/profiles.ts +0 -156
  320. package/src/providers/provider-config.ts +0 -311
  321. package/src/providers/registry.ts +0 -333
  322. package/src/providers/responses.ts +0 -209
  323. package/src/providers/retry.ts +0 -234
  324. package/src/providers/router.ts +0 -294
  325. package/src/providers/sse.ts +0 -26
  326. package/src/providers/stream-errors.ts +0 -117
  327. package/src/providers/stream.ts +0 -566
  328. package/src/providers/thinking.ts +0 -189
  329. package/src/providers/wire-messages.ts +0 -129
  330. package/src/providers/wire-responses.ts +0 -79
  331. package/src/providers/wire-select.ts +0 -53
  332. package/src/server/http.ts +0 -291
  333. package/src/server/openapi.ts +0 -246
  334. package/src/sextant/card-hits.ts +0 -102
  335. package/src/sextant/card-keys.ts +0 -55
  336. package/src/sextant/context-source.ts +0 -157
  337. package/src/sextant/crew-cards.ts +0 -350
  338. package/src/sextant/draw-agents.ts +0 -273
  339. package/src/sextant/draw-code.ts +0 -388
  340. package/src/sextant/draw-context.ts +0 -222
  341. package/src/sextant/draw-frame.ts +0 -164
  342. package/src/sextant/draw-market.ts +0 -573
  343. package/src/sextant/draw-messages.ts +0 -386
  344. package/src/sextant/draw-pet.ts +0 -230
  345. package/src/sextant/draw-plan.ts +0 -187
  346. package/src/sextant/draw-tabs.ts +0 -85
  347. package/src/sextant/draw-util.ts +0 -65
  348. package/src/sextant/draw-wizard.ts +0 -378
  349. package/src/sextant/engine.ts +0 -230
  350. package/src/sextant/frame-hits.ts +0 -25
  351. package/src/sextant/frame.ts +0 -101
  352. package/src/sextant/git-status.ts +0 -197
  353. package/src/sextant/grid.ts +0 -59
  354. package/src/sextant/input.ts +0 -119
  355. package/src/sextant/keys.ts +0 -521
  356. package/src/sextant/layout.ts +0 -86
  357. package/src/sextant/local-commands.ts +0 -169
  358. package/src/sextant/market-source.ts +0 -287
  359. package/src/sextant/mentions.ts +0 -200
  360. package/src/sextant/message-hits.ts +0 -26
  361. package/src/sextant/model.ts +0 -387
  362. package/src/sextant/overlays.ts +0 -456
  363. package/src/sextant/panel-hits.ts +0 -38
  364. package/src/sextant/pet.ts +0 -399
  365. package/src/sextant/screen.ts +0 -324
  366. package/src/sextant/scroll-hits.ts +0 -66
  367. package/src/sextant/scrollbar.ts +0 -82
  368. package/src/sextant/sextant-bridge.ts +0 -174
  369. package/src/sextant/sextant-cards.ts +0 -142
  370. package/src/sextant/sextant-diff-base.ts +0 -63
  371. package/src/sextant/sextant-files.ts +0 -154
  372. package/src/sextant/sextant-frame-loop.ts +0 -335
  373. package/src/sextant/sextant-renderer.ts +0 -574
  374. package/src/sextant/sextant-repo.ts +0 -140
  375. package/src/sextant/theme.ts +0 -66
  376. package/src/sextant/tool-rows.ts +0 -189
  377. package/src/sextant/types.ts +0 -493
  378. package/src/skills/index.ts +0 -387
  379. package/src/skills/pack.ts +0 -220
  380. package/src/skills/spec.ts +0 -162
  381. package/src/skills/tools.ts +0 -69
  382. package/src/skills/versioned.ts +0 -227
  383. package/src/telemetry/otel-export.ts +0 -122
  384. package/src/telemetry/otel-lanes.ts +0 -89
  385. package/src/telemetry/otel-logs.ts +0 -131
  386. package/src/telemetry/otel-metrics.ts +0 -136
  387. package/src/telemetry/otel.ts +0 -397
  388. package/src/telemetry/otlp.ts +0 -76
  389. package/src/tools/ask-user.ts +0 -156
  390. package/src/tools/bash-bg.ts +0 -94
  391. package/src/tools/bash-jobs.ts +0 -237
  392. package/src/tools/design.ts +0 -151
  393. package/src/tools/evalcell.ts +0 -338
  394. package/src/tools/html-text.ts +0 -139
  395. package/src/tools/provider.ts +0 -149
  396. package/src/tools/task.ts +0 -250
  397. package/src/tools/todo.ts +0 -320
  398. package/src/tools/webfetch.ts +0 -332
  399. package/src/tools/websearch.ts +0 -359
  400. package/src/tui/agents-cmd.ts +0 -41
  401. package/src/tui/app.ts +0 -749
  402. package/src/tui/attach.ts +0 -127
  403. package/src/tui/boot-notes.ts +0 -41
  404. package/src/tui/builtin-prompts.ts +0 -59
  405. package/src/tui/checkpoints-cmd.ts +0 -70
  406. package/src/tui/clipboard-image.ts +0 -81
  407. package/src/tui/clipboard.ts +0 -78
  408. package/src/tui/commands.ts +0 -283
  409. package/src/tui/config-view.ts +0 -53
  410. package/src/tui/context-cmds.ts +0 -282
  411. package/src/tui/cost.ts +0 -108
  412. package/src/tui/crash-guard.ts +0 -173
  413. package/src/tui/focus-terminal.ts +0 -34
  414. package/src/tui/git-cmds.ts +0 -273
  415. package/src/tui/git-plain.ts +0 -58
  416. package/src/tui/info-cmd.ts +0 -150
  417. package/src/tui/input-plain.ts +0 -76
  418. package/src/tui/mcp-cmd.ts +0 -128
  419. package/src/tui/memory-note.ts +0 -77
  420. package/src/tui/modes-cmd.ts +0 -45
  421. package/src/tui/notify-seq.ts +0 -100
  422. package/src/tui/notify.ts +0 -318
  423. package/src/tui/overlays.ts +0 -97
  424. package/src/tui/pi-renderer.ts +0 -428
  425. package/src/tui/providers-cmd.ts +0 -377
  426. package/src/tui/reasoning-view.ts +0 -56
  427. package/src/tui/renderer.ts +0 -128
  428. package/src/tui/replay-marker.ts +0 -29
  429. package/src/tui/session-cmd.ts +0 -148
  430. package/src/tui/session-manage.ts +0 -95
  431. package/src/tui/sextant-attach.ts +0 -102
  432. package/src/tui/sextant-io.ts +0 -202
  433. package/src/tui/sextant-smoke.ts +0 -110
  434. package/src/tui/shell-cmd.ts +0 -158
  435. package/src/tui/smoke.ts +0 -72
  436. package/src/tui/staged-terminal.ts +0 -50
  437. package/src/tui/startup.ts +0 -12
  438. package/src/tui/theme.ts +0 -59
  439. package/src/tui/todo-label.ts +0 -7
  440. package/src/tui/trust-card.ts +0 -107
  441. package/src/tui/tui-commands.ts +0 -87
  442. package/tsconfig.json +0 -30
  443. package/vendor/pi-tui/LICENSE +0 -21
  444. package/vendor/pi-tui/PATCHES.md +0 -12
  445. package/vendor/pi-tui/PROVENANCE.md +0 -12
  446. package/vendor/pi-tui/README.upstream.md +0 -854
  447. package/vendor/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  448. package/vendor/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  449. package/vendor/pi-tui/src/alt-screen-search.ts +0 -158
  450. package/vendor/pi-tui/src/autocomplete.ts +0 -827
  451. package/vendor/pi-tui/src/components/alt-screen-flash.ts +0 -52
  452. package/vendor/pi-tui/src/components/box.ts +0 -138
  453. package/vendor/pi-tui/src/components/cancellable-loader.ts +0 -41
  454. package/vendor/pi-tui/src/components/editor.ts +0 -2364
  455. package/vendor/pi-tui/src/components/h-stack.ts +0 -45
  456. package/vendor/pi-tui/src/components/image.ts +0 -128
  457. package/vendor/pi-tui/src/components/input.ts +0 -448
  458. package/vendor/pi-tui/src/components/loader.ts +0 -93
  459. package/vendor/pi-tui/src/components/markdown.ts +0 -1016
  460. package/vendor/pi-tui/src/components/scroll-view.ts +0 -217
  461. package/vendor/pi-tui/src/components/select-list.ts +0 -230
  462. package/vendor/pi-tui/src/components/settings-list.ts +0 -277
  463. package/vendor/pi-tui/src/components/spacer.ts +0 -29
  464. package/vendor/pi-tui/src/components/stack.ts +0 -155
  465. package/vendor/pi-tui/src/components/text.ts +0 -108
  466. package/vendor/pi-tui/src/components/truncated-text.ts +0 -66
  467. package/vendor/pi-tui/src/components/v-stack.ts +0 -34
  468. package/vendor/pi-tui/src/editor-component.ts +0 -75
  469. package/vendor/pi-tui/src/fuzzy.ts +0 -138
  470. package/vendor/pi-tui/src/index.ts +0 -149
  471. package/vendor/pi-tui/src/keybindings.ts +0 -321
  472. package/vendor/pi-tui/src/keys.ts +0 -1402
  473. package/vendor/pi-tui/src/kill-ring.ts +0 -47
  474. package/vendor/pi-tui/src/latex.ts +0 -1381
  475. package/vendor/pi-tui/src/layout-node.ts +0 -52
  476. package/vendor/pi-tui/src/layout.ts +0 -411
  477. package/vendor/pi-tui/src/native-modifiers.ts +0 -60
  478. package/vendor/pi-tui/src/native-module-path.ts +0 -32
  479. package/vendor/pi-tui/src/stdin-buffer.ts +0 -445
  480. package/vendor/pi-tui/src/terminal-colors.ts +0 -74
  481. package/vendor/pi-tui/src/terminal-image.ts +0 -701
  482. package/vendor/pi-tui/src/terminal.ts +0 -554
  483. package/vendor/pi-tui/src/tui-alt-screen.ts +0 -1379
  484. package/vendor/pi-tui/src/tui-main-screen.ts +0 -655
  485. package/vendor/pi-tui/src/tui.ts +0 -1264
  486. package/vendor/pi-tui/src/undo-stack.ts +0 -29
  487. package/vendor/pi-tui/src/utils.ts +0 -1327
  488. package/vendor/pi-tui/src/word-navigation.ts +0 -118
  489. package/vendor/pi-tui/test/test-themes.ts +0 -39
  490. package/vendor/pi-tui/test/virtual-terminal.ts +0 -219
  491. /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
- }