桌宠现在很流行,但它们大多只在你盯着的时候活着。 CAT RUNTIME 是一只真的会累、会闷、会记住你作息的猫—— 它接进 WorkBuddy、Codex、Claude Code,或者干脆只是你终端里的一条命令, 活干完了它抬头报一句,卡住了它叫你,失败的时候它趴你旁边不吭声。
下面这个终端窗口里跑的是 runtime/src/core/engine.js,
和你在自己机器上 catctl watch 看到的是同一份代码。
同一个种子,连打个哈欠的时机都一样。
~/.cat-api/runtime/state.json 里,
下次任何一条命令进来,它先把这段时间补算完再回答你。
高 = 缺得多。所有行为都由这五个数驱动,没有一个行为是随机挑的。 其中 警觉是这套东西和玩具的分界线:别的都靠时间慢慢涨, 只有警觉是被你的工作强行灌进去的——所以你一跑测试,它就抬头。
醒着一直涨,约五小时见底。只有睡觉能掉,而且掉得比涨快得多。
+0.0034/分 · 睡时 −0.052/分一直涨。扑咬、疯跑、巡视、磨爪会真的把它往回压——用减法,不是抵消。
+0.011/分 · 扑咬 −0.085/分没人理就涨。判断标准不是「被摸了几下」,而是「你手上有活吗」。
+0.0038/分 · 你在线时 −0.0053/分慢慢涨,约九小时见顶。吃一顿掉回一半,然后再慢慢涨。
+0.0018/分 · 吃时 −0.55/分不自然涨,只由任务事件注入。半衰期 50 秒,掉得很快——所以它只在你要紧的时候盯着。
任务 +0.52~0.66 · 半衰期 50s每轮决策,所有「能做的」行为各自算一个分,最高的上岗。 两个细节让它不抽搐:习惯化——刚做过的事下次打分打折,90 秒半衰期; 停留上限——到了上限就不许再选自己,否则一只爱巡视的猫可以巡视一整夜。
| 行为 | 触发 | 说明 | 停留 |
|---|---|---|---|
| SLEEP | 困 > 0.34 | 你夜里干活多,它夜里就不睡。准则六 | 26s – 25min |
| LOAF | 保底项 | 什么都不想干的时候就是这个姿势。猫的主业。 | 8s – 4min |
| GROOM | 不闷 + 有精神 | 低成本自娱。顺序不能乱,先从爪子开始。 | 7s – 90s |
| PATROL | 闷 | 沿墙走。这间屋子归它。 | 9s – 2min |
| PLAY | 闷 + 不困 | 扑咬任何会动的东西。 | 9s – 40s |
| ZOOMIES | 闷 + 极有精神 + 没人看 | 准则三:没人在的时候才疯跑。 | 2.6s – 12s |
| EAT | 饿 > 0.66 | 先闻一下,吃两口就走。 | 10s – 60s |
| WATCH | 警觉 > 0.34 | 盯着屏幕。别按第二次。 | 5s – 10min |
| STRETCH | 刚睡醒 | 前爪推出去,咔。 | 3s – 8s |
| SCRATCH | 闷 | 这个角正好。不是你的椅子。 | 9s – 45s |
| BOXED | 闷 + 3% 概率 | 进去了就不出来,半小时起。 | 40s – 10min |
| KNEAD | 心情好 + 有点孤单 | 踩奶。左右左右。 | 5s – 16s |
这是整个模型里最关键的一条。猫可以正在舔毛,突然抬头看你一眼,然后低头继续舔—— 它的状态没变,只是被打断了。现实里的猫就是这么动的。 反应持续一到三秒,撤掉后姿势自动回到原来那个行为。
活开始了。警觉 +0.52。task.start
成了。心情 +0.48,+12xp。task.ok
挂了。心情 −0.38,警觉 +0.66,+4xp。task.fail
卡住了。会弹系统通知。task.wait
被摸到了。孤独 −0.30。pet · feed
等到长蘑菇了。prompt.idle
印在文档上,也写在代码里。每一条都能在 src/core/engine.js 里搜到对应的实现,
自测里有对应断言。
失败也加经验,只是少一点——因为失败确实也学到了东西。 阶段会改行为:老猫每种动作都待得更久、睡得更沉、疯跑更少。进化只升不降。
形象更是从头到脚重画一遍:耳朵、脑袋、身板、尾巴各换一套——奶猫圆滚滚什么都短, 猫又是叉耳、带印、两条尾巴。点一点链上任意形态,终端里就预览它那个阶段的样子,没解锁的显示剪影。
同时它还在学你:几点干活、在哪个目录、跑什么命令、失败率高不高。 从这些压出五个性格维度(夜行 / 碎步 / 调试 / 傲娇 / 俏皮)直接进打分公式—— 同一套匮乏,不同主人的猫走不同的路。 傲娇的猫更爱瘫着舔毛、盯着你不承认,俏皮的多半在扑咬疯跑、随时踩奶。 没数据的时候,先按种子给一只猫一个脾气底子,所以每只都不一样。 跨过零点还没访问的时候,统计会按 0.86 的衰减一次性补算——搬了家、换了技术栈,它会跟着变。
●●●●● 你的活有 68% 落在 21:00–02:00,我按这个点儿调了作息,主要是夜里。
●●●●○ 最常待的是 cat-api-spec(134 次),那里算主领地,另外还有 3 处会去。
●●●●● 「npm test」跑了 41 次,挂掉 44%,一次大约 18 秒。你重试之前我一般不吵。
●●●●○ 你最常干的是跑测试(41 次,挂 44%)。这类活容易翻,我多陪一会儿。
●●●○○ 这周干了 12 件,比上周多 4 件,没歇着啊;「跑测试」多挂了 2 回,我不问,我趴着。
●●●●● 失败率 44%。我不催你——失败的时候我趴旁边,不盯着屏幕。
为什么是 CLI:任何能 fork 一个进程的地方都能养这只猫。 编辑器插件、CI、make、git hook、WorkBuddy 的 hook、tmux、ssh——都只需要执行一条命令。
npm install,一行软链就行:ln -s "$(pwd)/runtime/bin/catctl.js" ~/.local/bin/catctl
catctl看它一眼。状态、匮乏、它在干嘛。
catctl watch让它动起来。空格摸它,f 喂,l 激光笔,q 退出。
catctl run -- npm test包住一条命令。退出码原样返回,CI 不会出错。挂了的话,最后几行报错会记进日志。
catctl run -- npm run build --kind ship活动类型自动从命令名猜(测试、构建、部署、装依赖……),猜错了用 --kind 指定。
catctl log --fail只看挂掉的。--kind test 按类型筛,失败会附上报错尾巴。
catctl emit task.ok宿主主动汇报。9 种事件,见下表。
catctl init --host claude写 .claude/settings.json,改之前自动备份。
catctl serve --port 9177不给开 shell 的宿主一个 HTTP 口子,只听 127.0.0.1。
catctl learn它学会了什么,带置信度。错了可以 catctl teach 纠正。
catctl selftest45 项不变量自测,含 172800 步的确定性断言。
事件只有这几种:task.start · task.ok · task.fail ·
task.wait · prompt.idle · pet · feed ·
laser · wake。宿主不需要知道猫的内部结构,只需要知道这九个词。
不知道你那个宿主怎么配 hook?没关系。包一层就行——
任何能跑命令的地方,把命令前面加上 catctl run --,猫就接上了。
catctl emit task.ok catctl emit task.wait --notify catctl emit task.fail
Codex 没有外挂钩子,就写进 AGENTS.md 一句话,或者外面套一层 catctl run -- codex。
settings.hooks.Stop → catctl emit task.ok settings.hooks.Notification → catctl emit task.wait --notify
合并写入,改之前自动备份旧的 settings.json。
.git/hooks/post-commit
→ catctl emit task.ok \
--name "git commit"
每次提交它看一眼。已有 hook 会先备份。
source 项目/.catctl/shell-hook.sh # 写进 ~/.zshrc
之后你在终端里跑的每条命令,成没成它都知道。
GET /state
GET /learn
POST /emit {"type":"task.ok"}
只监听 127.0.0.1,不出网。给 Electron、Tauri、VSCode webview 用。
catctl run -- <你平时的命令>
退出码原样返回。不需要宿主配合,也不需要你改任何配置。
桌宠的难点从来不是画一只猫。
难点是让它在你不看的时候,也真的活着。