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.
- package/CHANGELOG.md +527 -0
- package/README.md +46 -48
- package/bin/rovecode.js +24 -0
- package/dist/cli/app-j6gn14w3.js +2 -0
- package/dist/cli/ask-user-cwstt8fz.js +2 -0
- package/dist/cli/auth-login-9bbp9915.js +2 -0
- package/dist/cli/auth-m8p9grty.js +2 -0
- package/dist/cli/bench-16zqdms5.js +9 -0
- package/dist/cli/catalog-1xchffa4.js +2 -0
- package/dist/cli/cli-1n1zb64f.js +2 -0
- package/dist/cli/client-2t9gjkck.js +2 -0
- package/dist/cli/commands-exafvm2b.js +2 -0
- package/dist/cli/connect-6zde0kn3.js +2 -0
- package/dist/cli/context-cmd-5t43wgqt.js +2 -0
- package/dist/cli/context-report-kt01pw8y.js +2 -0
- package/dist/cli/count-remote-ap7x3vh6.js +2 -0
- package/dist/cli/design-ne5zszyh.js +2 -0
- package/dist/cli/dispatch-2r5myxye.js +2 -0
- package/dist/cli/doctor-ws4fh4tn.js +3 -0
- package/dist/cli/executor-bdrjn634.js +2 -0
- package/dist/cli/export-1mxb9g5p.js +2 -0
- package/dist/cli/files-g104xghh.js +2 -0
- package/dist/cli/gauntlet-07xrjpj7.js +2 -0
- package/dist/cli/gauntlet-runner-xvy64436.js +10 -0
- package/dist/cli/gauntlet-wave3-jm91yt5w.js +5 -0
- package/dist/cli/gauntlet-wave4-r13py7p1.js +14 -0
- package/dist/cli/hashline-znvrat11.js +2 -0
- package/dist/cli/http-xafw6fsh.js +143 -0
- package/dist/cli/index-1sgjm25y.js +2 -0
- package/dist/cli/init-g2m0tn4m.js +51 -0
- package/dist/cli/install-avaqjjqq.js +2 -0
- package/dist/cli/loop-mmpfft01.js +2 -0
- package/dist/cli/main-0904f6ps.js +5 -0
- package/dist/cli/main-0ab9fc26.js +9 -0
- package/dist/cli/main-0jys2ccn.js +3 -0
- package/dist/cli/main-0mtcdbs7.js +3 -0
- package/dist/cli/main-0z1w2zsg.js +3 -0
- package/dist/cli/main-1dchs7xv.js +18 -0
- package/dist/cli/main-1ereejm1.js +3 -0
- package/dist/cli/main-1k1kw6b5.js +3 -0
- package/dist/cli/main-27y4sm2k.js +38 -0
- package/dist/cli/main-2wwjex5j.js +58 -0
- package/dist/cli/main-2yeveeve.js +6 -0
- package/dist/cli/main-2yfck9b5.js +3 -0
- package/dist/cli/main-2zmzgkwh.js +3 -0
- package/dist/cli/main-351pz3z7.js +7 -0
- package/dist/cli/main-3gjqfh7a.js +6 -0
- package/dist/cli/main-3nf3kgve.js +3 -0
- package/dist/cli/main-3pjrb2hd.js +3 -0
- package/dist/cli/main-3rxcvgna.js +19 -0
- package/dist/cli/main-4b3jgy66.js +19 -0
- package/dist/cli/main-4wndhjdc.js +7 -0
- package/dist/cli/main-4xcmvxnk.js +3 -0
- package/dist/cli/main-5tbz0wbz.js +4 -0
- package/dist/cli/main-5ywnwthm.js +3 -0
- package/dist/cli/main-6b62vkz0.js +14 -0
- package/dist/cli/main-6dnk69vp.js +3 -0
- package/dist/cli/main-6genrmhs.js +136 -0
- package/dist/cli/main-73g7eff4.js +15 -0
- package/dist/cli/main-7c5thhjd.js +5 -0
- package/dist/cli/main-7rn6bqje.js +3 -0
- package/dist/cli/main-80haw7qk.js +4 -0
- package/dist/cli/main-875s60s2.js +4 -0
- package/dist/cli/main-8kjxbpw4.js +8 -0
- package/dist/cli/main-90ds1z4e.js +10 -0
- package/dist/cli/main-9etavkew.js +3 -0
- package/dist/cli/main-a9njrkk1.js +3 -0
- package/dist/cli/main-aecrjq2d.js +12 -0
- package/dist/cli/main-ck9asesq.js +9 -0
- package/dist/cli/main-cta9racd.js +4 -0
- package/dist/cli/main-ddv7j2ag.js +3 -0
- package/dist/cli/main-dfreez27.js +10 -0
- package/dist/cli/main-f7rw7des.js +3 -0
- package/dist/cli/main-ggcn7rd7.js +5 -0
- package/dist/cli/main-gzkmycnv.js +3 -0
- package/dist/cli/main-hq51jg8v.js +18 -0
- package/dist/cli/main-jft389w9.js +8 -0
- package/dist/cli/main-k1eqkg83.js +3 -0
- package/dist/cli/main-k2y8a2aw.js +9 -0
- package/dist/cli/main-kcpbykxz.js +4 -0
- package/dist/cli/main-kd488vje.js +22 -0
- package/dist/cli/main-kh32yvgk.js +5 -0
- package/dist/cli/main-kqxnqjnv.js +25 -0
- package/dist/cli/main-kyn0xnsg.js +3 -0
- package/dist/cli/main-m1kk6fp5.js +21 -0
- package/dist/cli/main-mv40pcr2.js +4 -0
- package/dist/cli/main-n0t3973w.js +3 -0
- package/dist/cli/main-nqveez48.js +4 -0
- package/dist/cli/main-pknhvrmj.js +3 -0
- package/dist/cli/main-pn1w7a7j.js +3 -0
- package/dist/cli/main-prxxs70n.js +4 -0
- package/dist/cli/main-q3vsesf9.js +3 -0
- package/dist/cli/main-qsevpgsv.js +3 -0
- package/dist/cli/main-rdgdw24b.js +25 -0
- package/dist/cli/main-rfth4tbm.js +16 -0
- package/dist/cli/main-rg0wn0xf.js +5 -0
- package/dist/cli/main-sdmxhtv8.js +4 -0
- package/dist/cli/main-skbp13js.js +18 -0
- package/dist/cli/main-t4xnd213.js +7 -0
- package/dist/cli/main-vqak588n.js +4 -0
- package/dist/cli/main-w2n1303f.js +9 -0
- package/dist/cli/main-wbrdspr2.js +5 -0
- package/dist/cli/main-wsrg79c1.js +7 -0
- package/dist/cli/main-x4r0fne4.js +5 -0
- package/dist/cli/main-xea2f3tn.js +6 -0
- package/dist/cli/main-xg704a3c.js +3 -0
- package/dist/cli/main-xvnrabfp.js +16 -0
- package/dist/cli/main-xy53xf0r.js +4 -0
- package/dist/cli/main-y1fqy60y.js +3 -0
- package/dist/cli/main-yn8cd281.js +34 -0
- package/dist/cli/main-yr0ksc0h.js +4 -0
- package/dist/cli/main-z2ex2vyf.js +4 -0
- package/dist/cli/main-z3aayzvq.js +3 -0
- package/dist/cli/main-zaqh35jg.js +3 -0
- package/dist/cli/main-zc2e8e46.js +4 -0
- package/dist/cli/main-zzrfw6cf.js +13 -0
- package/dist/cli/main.js +280 -0
- package/dist/cli/market-cmd-e14kmx9n.js +5 -0
- package/dist/cli/mcp-login-wq7ktdek.js +2 -0
- package/dist/cli/mcp-market-cmd-9mg3jecy.js +2 -0
- package/dist/cli/notify-b7qc0cjb.js +2 -0
- package/dist/cli/oauth-z8whcgfx.js +2 -0
- package/dist/cli/output-b3ewj3ps.js +16 -0
- package/dist/cli/profiles-6mr5he5e.js +2 -0
- package/dist/cli/provider-config-g7j42q8x.js +2 -0
- package/dist/cli/provider-jr1y8vvm.js +2 -0
- package/dist/cli/registry-s8yk86g0.js +2 -0
- package/dist/cli/registry-t6p8d4mn.js +2 -0
- package/dist/cli/repl-bajwe1mh.js +11 -0
- package/dist/cli/resume-rwn9nz7y.js +2 -0
- package/dist/cli/run-flags-nah7ndpt.js +2 -0
- package/dist/cli/runtime-n7gafzhb.js +2 -0
- package/dist/cli/sandbox-config-emdy18x4.js +2 -0
- package/dist/cli/server-b0nvs2bn.js +5 -0
- package/dist/cli/session-arg-y75wd4kj.js +2 -0
- package/dist/cli/session-j62evmjq.js +2 -0
- package/dist/cli/sessions-cmd-tsnwz0ns.js +7 -0
- package/dist/cli/settings-df10wfez.js +2 -0
- package/dist/cli/setup-jzvv72fg.js +2 -0
- package/dist/cli/sextant-smoke-37m81ke6.js +5 -0
- package/dist/cli/skills-cmd-gjxnxnhx.js +2 -0
- package/dist/cli/smoke-p7748apt.js +8 -0
- package/dist/cli/start-chat-s4st3mm0.js +12 -0
- package/dist/cli/stream-gmeyewds.js +2 -0
- package/dist/cli/task-gh0kkp3n.js +2 -0
- package/dist/cli/tasks-z1kfpe8e.js +2 -0
- package/dist/cli/thinking-0eqkrz6t.js +2 -0
- package/dist/cli/todo-5brcrt9m.js +2 -0
- package/dist/cli/tools-7pzm0vj9.js +2 -0
- package/dist/cli/tools-s635p6s8.js +2 -0
- package/dist/cli/trust-cmd-cjav8zgm.js +2 -0
- package/dist/cli/update-check-pt31bm2f.js +2 -0
- package/dist/cli/update-cmd-tk131s9t.js +2 -0
- package/dist/cli/voice-56nabd8d.js +2 -0
- package/dist/cli/webfetch-xd8q596m.js +2 -0
- package/dist/cli/websearch-5hkf98k1.js +2 -0
- package/dist/cli/workflow-cmd-cy3cvzjp.js +4 -0
- package/dist/cli/workspace-q10g5z3e.js +2 -0
- package/dist/lib/index.js +62 -0
- package/dist/lib/models-index.json +1 -0
- package/dist/lib/plugins.js +55 -0
- package/dist/lib/providers.js +17 -0
- package/dist/lib/public-api.js +20 -0
- package/dist/lib/sdk.js +360 -0
- package/package.json +84 -72
- package/bin/rovecode.ts +0 -21
- package/src/acp/server.ts +0 -374
- package/src/cli/auth-login.ts +0 -122
- package/src/cli/connect.ts +0 -244
- package/src/cli/context-cmd.ts +0 -199
- package/src/cli/dispatch.ts +0 -82
- package/src/cli/doctor.ts +0 -362
- package/src/cli/export.ts +0 -276
- package/src/cli/help.ts +0 -293
- package/src/cli/is-tui-invocation.ts +0 -8
- package/src/cli/main.ts +0 -583
- package/src/cli/market-cmd.ts +0 -658
- package/src/cli/mcp-login.ts +0 -141
- package/src/cli/mcp-market-cmd.ts +0 -302
- package/src/cli/output.ts +0 -382
- package/src/cli/repl.ts +0 -250
- package/src/cli/repomap-root.ts +0 -14
- package/src/cli/resume.ts +0 -57
- package/src/cli/run-flags.ts +0 -43
- package/src/cli/run-limits.ts +0 -78
- package/src/cli/runtime.ts +0 -931
- package/src/cli/session-arg.ts +0 -30
- package/src/cli/sessions-cmd.ts +0 -145
- package/src/cli/setup.ts +0 -153
- package/src/cli/skills-cmd.ts +0 -194
- package/src/cli/start-chat.ts +0 -65
- package/src/cli/trust-cmd.ts +0 -52
- package/src/coding/bash.ts +0 -148
- package/src/coding/checkpoints.ts +0 -327
- package/src/coding/diff.ts +0 -138
- package/src/coding/files.ts +0 -341
- package/src/coding/hashline.ts +0 -274
- package/src/coding/lsp-gate.ts +0 -254
- package/src/coding/lsp-servers.ts +0 -147
- package/src/coding/lsp.ts +0 -283
- package/src/coding/repomap-cache.ts +0 -99
- package/src/coding/repomap-files.ts +0 -192
- package/src/coding/repomap.ts +0 -481
- package/src/core/agents.ts +0 -255
- package/src/core/compaction.ts +0 -259
- package/src/core/config.ts +0 -289
- package/src/core/context-report.ts +0 -228
- package/src/core/context.ts +0 -60
- package/src/core/count-remote.ts +0 -107
- package/src/core/execpolicy-rules.ts +0 -196
- package/src/core/execpolicy.ts +0 -385
- package/src/core/executor.ts +0 -454
- package/src/core/guardrails.ts +0 -400
- package/src/core/hooks.ts +0 -411
- package/src/core/images.ts +0 -230
- package/src/core/intro.ts +0 -266
- package/src/core/loop.ts +0 -567
- package/src/core/modes.ts +0 -372
- package/src/core/orchestrator.ts +0 -245
- package/src/core/proc-group.ts +0 -48
- package/src/core/project-trust.ts +0 -98
- package/src/core/reflection.ts +0 -165
- package/src/core/sandbox-config.ts +0 -186
- package/src/core/session-id.ts +0 -24
- package/src/core/session-images.ts +0 -73
- package/src/core/session-ops.ts +0 -183
- package/src/core/session-text.ts +0 -29
- package/src/core/session.ts +0 -469
- package/src/core/settings.ts +0 -170
- package/src/core/tasks.ts +0 -646
- package/src/core/token-scale.ts +0 -108
- package/src/core/tools.ts +0 -309
- package/src/core/trust.ts +0 -104
- package/src/core/types.ts +0 -330
- package/src/core/update-check.ts +0 -171
- package/src/core/usage.ts +0 -204
- package/src/core/validate.ts +0 -121
- package/src/core/verify-gate.ts +0 -159
- package/src/core/verify.ts +0 -236
- package/src/core/voice.ts +0 -158
- package/src/core/win-job.ts +0 -183
- package/src/core/workspace.ts +0 -184
- package/src/design/audit.ts +0 -797
- package/src/design/direction.ts +0 -190
- package/src/design/rules.ts +0 -157
- package/src/eval/bench.ts +0 -150
- package/src/eval/gauntlet-runner.ts +0 -215
- package/src/eval/gauntlet-support.ts +0 -84
- package/src/eval/gauntlet-wave3.ts +0 -269
- package/src/eval/gauntlet-wave4.ts +0 -217
- package/src/eval/gauntlet.ts +0 -253
- package/src/index.ts +0 -17
- package/src/lanes/agy.ts +0 -95
- package/src/lanes/approval.ts +0 -24
- package/src/lanes/claude.ts +0 -129
- package/src/lanes/codex.ts +0 -127
- package/src/lanes/events.ts +0 -130
- package/src/lanes/job.ts +0 -142
- package/src/lanes/opencode.ts +0 -122
- package/src/lanes/process.ts +0 -184
- package/src/lanes/progress.ts +0 -183
- package/src/lanes/registry.ts +0 -178
- package/src/lanes/runner.ts +0 -124
- package/src/lanes/types.ts +0 -112
- package/src/market/catalogs/mcp-docs.json +0 -111
- package/src/market/catalogs/plugins.json +0 -111
- package/src/market/catalogs/skills.json +0 -478
- package/src/market/clone.ts +0 -72
- package/src/market/context-cost.ts +0 -121
- package/src/market/digest.ts +0 -106
- package/src/market/index.ts +0 -22
- package/src/market/install.ts +0 -578
- package/src/market/manifest.ts +0 -187
- package/src/market/prereq.ts +0 -145
- package/src/market/registry.ts +0 -363
- package/src/market/resolve.ts +0 -111
- package/src/market/types.ts +0 -236
- package/src/market/validate.ts +0 -227
- package/src/mcp/client.ts +0 -449
- package/src/mcp/config.ts +0 -252
- package/src/mcp/local-package.ts +0 -211
- package/src/mcp/market-catalog.ts +0 -84
- package/src/mcp/market-install.ts +0 -289
- package/src/mcp/market.ts +0 -362
- package/src/mcp/oauth.ts +0 -251
- package/src/mcp/prompts-resources.ts +0 -249
- package/src/mcp/shared.ts +0 -149
- package/src/mcp/status.ts +0 -67
- package/src/mcp/tools.ts +0 -275
- package/src/mcp/transport.ts +0 -122
- package/src/mcp/trust.ts +0 -25
- package/src/memory/blocks.ts +0 -278
- package/src/memory/recall.ts +0 -355
- package/src/memory/scope.ts +0 -182
- package/src/memory/store.ts +0 -105
- package/src/memory/tools.ts +0 -99
- package/src/plugins/cli.ts +0 -119
- package/src/plugins/discover.ts +0 -108
- package/src/plugins/index.ts +0 -50
- package/src/plugins/install.ts +0 -184
- package/src/plugins/load.ts +0 -124
- package/src/plugins/manifest.ts +0 -92
- package/src/plugins/state.ts +0 -83
- package/src/providers/auth.ts +0 -408
- package/src/providers/cache.ts +0 -223
- package/src/providers/catalog-local.ts +0 -160
- package/src/providers/catalog.ts +0 -421
- package/src/providers/middleware-context.ts +0 -86
- package/src/providers/middleware.ts +0 -373
- package/src/providers/model-list.ts +0 -23
- package/src/providers/oauth/common.ts +0 -105
- package/src/providers/oauth/device-code.ts +0 -107
- package/src/providers/oauth/github-copilot.ts +0 -146
- package/src/providers/oauth/loopback.ts +0 -158
- package/src/providers/oauth/openai.ts +0 -163
- package/src/providers/oauth/openrouter.ts +0 -89
- package/src/providers/oauth/pkce.ts +0 -45
- package/src/providers/oauth/registry.ts +0 -39
- package/src/providers/oauth/seam.ts +0 -89
- package/src/providers/profile-glm53.ts +0 -111
- package/src/providers/profile-sonnet5-persona.ts +0 -65
- package/src/providers/profile-sonnet5-voice.ts +0 -23
- package/src/providers/profiles.ts +0 -156
- package/src/providers/provider-config.ts +0 -311
- package/src/providers/registry.ts +0 -333
- package/src/providers/responses.ts +0 -209
- package/src/providers/retry.ts +0 -234
- package/src/providers/router.ts +0 -294
- package/src/providers/sse.ts +0 -26
- package/src/providers/stream-errors.ts +0 -117
- package/src/providers/stream.ts +0 -566
- package/src/providers/thinking.ts +0 -189
- package/src/providers/wire-messages.ts +0 -129
- package/src/providers/wire-responses.ts +0 -79
- package/src/providers/wire-select.ts +0 -53
- package/src/server/http.ts +0 -291
- package/src/server/openapi.ts +0 -246
- package/src/sextant/card-hits.ts +0 -102
- package/src/sextant/card-keys.ts +0 -55
- package/src/sextant/context-source.ts +0 -157
- package/src/sextant/crew-cards.ts +0 -350
- package/src/sextant/draw-agents.ts +0 -273
- package/src/sextant/draw-code.ts +0 -388
- package/src/sextant/draw-context.ts +0 -222
- package/src/sextant/draw-frame.ts +0 -164
- package/src/sextant/draw-market.ts +0 -573
- package/src/sextant/draw-messages.ts +0 -386
- package/src/sextant/draw-pet.ts +0 -230
- package/src/sextant/draw-plan.ts +0 -187
- package/src/sextant/draw-tabs.ts +0 -85
- package/src/sextant/draw-util.ts +0 -65
- package/src/sextant/draw-wizard.ts +0 -378
- package/src/sextant/engine.ts +0 -230
- package/src/sextant/frame-hits.ts +0 -25
- package/src/sextant/frame.ts +0 -101
- package/src/sextant/git-status.ts +0 -197
- package/src/sextant/grid.ts +0 -59
- package/src/sextant/input.ts +0 -119
- package/src/sextant/keys.ts +0 -521
- package/src/sextant/layout.ts +0 -86
- package/src/sextant/local-commands.ts +0 -169
- package/src/sextant/market-source.ts +0 -287
- package/src/sextant/mentions.ts +0 -200
- package/src/sextant/message-hits.ts +0 -26
- package/src/sextant/model.ts +0 -387
- package/src/sextant/overlays.ts +0 -456
- package/src/sextant/panel-hits.ts +0 -38
- package/src/sextant/pet.ts +0 -399
- package/src/sextant/screen.ts +0 -324
- package/src/sextant/scroll-hits.ts +0 -66
- package/src/sextant/scrollbar.ts +0 -82
- package/src/sextant/sextant-bridge.ts +0 -174
- package/src/sextant/sextant-cards.ts +0 -142
- package/src/sextant/sextant-diff-base.ts +0 -63
- package/src/sextant/sextant-files.ts +0 -154
- package/src/sextant/sextant-frame-loop.ts +0 -335
- package/src/sextant/sextant-renderer.ts +0 -574
- package/src/sextant/sextant-repo.ts +0 -140
- package/src/sextant/theme.ts +0 -66
- package/src/sextant/tool-rows.ts +0 -189
- package/src/sextant/types.ts +0 -493
- package/src/skills/index.ts +0 -387
- package/src/skills/pack.ts +0 -220
- package/src/skills/spec.ts +0 -162
- package/src/skills/tools.ts +0 -69
- package/src/skills/versioned.ts +0 -227
- package/src/telemetry/otel-export.ts +0 -122
- package/src/telemetry/otel-lanes.ts +0 -89
- package/src/telemetry/otel-logs.ts +0 -131
- package/src/telemetry/otel-metrics.ts +0 -136
- package/src/telemetry/otel.ts +0 -397
- package/src/telemetry/otlp.ts +0 -76
- package/src/tools/ask-user.ts +0 -156
- package/src/tools/bash-bg.ts +0 -94
- package/src/tools/bash-jobs.ts +0 -237
- package/src/tools/design.ts +0 -151
- package/src/tools/evalcell.ts +0 -338
- package/src/tools/html-text.ts +0 -139
- package/src/tools/provider.ts +0 -149
- package/src/tools/task.ts +0 -250
- package/src/tools/todo.ts +0 -320
- package/src/tools/webfetch.ts +0 -332
- package/src/tools/websearch.ts +0 -359
- package/src/tui/agents-cmd.ts +0 -41
- package/src/tui/app.ts +0 -749
- package/src/tui/attach.ts +0 -127
- package/src/tui/boot-notes.ts +0 -41
- package/src/tui/builtin-prompts.ts +0 -59
- package/src/tui/checkpoints-cmd.ts +0 -70
- package/src/tui/clipboard-image.ts +0 -81
- package/src/tui/clipboard.ts +0 -78
- package/src/tui/commands.ts +0 -283
- package/src/tui/config-view.ts +0 -53
- package/src/tui/context-cmds.ts +0 -282
- package/src/tui/cost.ts +0 -108
- package/src/tui/crash-guard.ts +0 -173
- package/src/tui/focus-terminal.ts +0 -34
- package/src/tui/git-cmds.ts +0 -273
- package/src/tui/git-plain.ts +0 -58
- package/src/tui/info-cmd.ts +0 -150
- package/src/tui/input-plain.ts +0 -76
- package/src/tui/mcp-cmd.ts +0 -128
- package/src/tui/memory-note.ts +0 -77
- package/src/tui/modes-cmd.ts +0 -45
- package/src/tui/notify-seq.ts +0 -100
- package/src/tui/notify.ts +0 -318
- package/src/tui/overlays.ts +0 -97
- package/src/tui/pi-renderer.ts +0 -428
- package/src/tui/providers-cmd.ts +0 -377
- package/src/tui/reasoning-view.ts +0 -56
- package/src/tui/renderer.ts +0 -128
- package/src/tui/replay-marker.ts +0 -29
- package/src/tui/session-cmd.ts +0 -148
- package/src/tui/session-manage.ts +0 -95
- package/src/tui/sextant-attach.ts +0 -102
- package/src/tui/sextant-io.ts +0 -202
- package/src/tui/sextant-smoke.ts +0 -110
- package/src/tui/shell-cmd.ts +0 -158
- package/src/tui/smoke.ts +0 -72
- package/src/tui/staged-terminal.ts +0 -50
- package/src/tui/startup.ts +0 -12
- package/src/tui/theme.ts +0 -59
- package/src/tui/todo-label.ts +0 -7
- package/src/tui/trust-card.ts +0 -107
- package/src/tui/tui-commands.ts +0 -87
- package/tsconfig.json +0 -30
- package/vendor/pi-tui/LICENSE +0 -21
- package/vendor/pi-tui/PATCHES.md +0 -12
- package/vendor/pi-tui/PROVENANCE.md +0 -12
- package/vendor/pi-tui/README.upstream.md +0 -854
- package/vendor/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/vendor/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/vendor/pi-tui/src/alt-screen-search.ts +0 -158
- package/vendor/pi-tui/src/autocomplete.ts +0 -827
- package/vendor/pi-tui/src/components/alt-screen-flash.ts +0 -52
- package/vendor/pi-tui/src/components/box.ts +0 -138
- package/vendor/pi-tui/src/components/cancellable-loader.ts +0 -41
- package/vendor/pi-tui/src/components/editor.ts +0 -2364
- package/vendor/pi-tui/src/components/h-stack.ts +0 -45
- package/vendor/pi-tui/src/components/image.ts +0 -128
- package/vendor/pi-tui/src/components/input.ts +0 -448
- package/vendor/pi-tui/src/components/loader.ts +0 -93
- package/vendor/pi-tui/src/components/markdown.ts +0 -1016
- package/vendor/pi-tui/src/components/scroll-view.ts +0 -217
- package/vendor/pi-tui/src/components/select-list.ts +0 -230
- package/vendor/pi-tui/src/components/settings-list.ts +0 -277
- package/vendor/pi-tui/src/components/spacer.ts +0 -29
- package/vendor/pi-tui/src/components/stack.ts +0 -155
- package/vendor/pi-tui/src/components/text.ts +0 -108
- package/vendor/pi-tui/src/components/truncated-text.ts +0 -66
- package/vendor/pi-tui/src/components/v-stack.ts +0 -34
- package/vendor/pi-tui/src/editor-component.ts +0 -75
- package/vendor/pi-tui/src/fuzzy.ts +0 -138
- package/vendor/pi-tui/src/index.ts +0 -149
- package/vendor/pi-tui/src/keybindings.ts +0 -321
- package/vendor/pi-tui/src/keys.ts +0 -1402
- package/vendor/pi-tui/src/kill-ring.ts +0 -47
- package/vendor/pi-tui/src/latex.ts +0 -1381
- package/vendor/pi-tui/src/layout-node.ts +0 -52
- package/vendor/pi-tui/src/layout.ts +0 -411
- package/vendor/pi-tui/src/native-modifiers.ts +0 -60
- package/vendor/pi-tui/src/native-module-path.ts +0 -32
- package/vendor/pi-tui/src/stdin-buffer.ts +0 -445
- package/vendor/pi-tui/src/terminal-colors.ts +0 -74
- package/vendor/pi-tui/src/terminal-image.ts +0 -701
- package/vendor/pi-tui/src/terminal.ts +0 -554
- package/vendor/pi-tui/src/tui-alt-screen.ts +0 -1379
- package/vendor/pi-tui/src/tui-main-screen.ts +0 -655
- package/vendor/pi-tui/src/tui.ts +0 -1264
- package/vendor/pi-tui/src/undo-stack.ts +0 -29
- package/vendor/pi-tui/src/utils.ts +0 -1327
- package/vendor/pi-tui/src/word-navigation.ts +0 -118
- package/vendor/pi-tui/test/test-themes.ts +0 -39
- package/vendor/pi-tui/test/virtual-terminal.ts +0 -219
- /package/{src/providers → dist/cli}/models-index.json +0 -0
package/src/sextant/pet.ts
DELETED
|
@@ -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
|
-
}
|