CAT API
CAT RUNTIME · v1.0.0

任务跑完了,
总得有谁告诉你一声。

桌宠现在很流行,但它们大多只在你盯着的时候活着。 CAT RUNTIME 是一只真的会累、会闷、会记住你作息的猫—— 它接进 WorkBuddy、Codex、Claude Code,或者干脆只是你终端里的一条命令, 活干完了它抬头报一句,卡住了它叫你,失败的时候它趴你旁边不吭声。

0
依赖
5
种匮乏
12
种行为
12
条准则
5
个进化阶段
LIVE

现在这只,跑的是同一份引擎

下面这个终端窗口里跑的是 runtime/src/core/engine.js, 和你在自己机器上 catctl watch 看到的是同一份代码。 同一个种子,连打个哈欠的时机都一样。

catctl watch

      
发个事件给它
五种匮乏
它刚才在干什么
挑个时段看看
00:0006:0012:0018:0024:00
按住拖动选择时间段
演示按 2 倍速跑,好让你看见它换动作。 仔细看,它偶尔会自己挤个眼、歪着头好奇、打个哈欠、摊成侧躺——小动作不进状态机,演完接着干自己的事。 真实使用里它是实时推进的——而且没有后台进程: 你关掉终端它就睡在 ~/.cat-api/runtime/state.json 里, 下次任何一条命令进来,它先把这段时间补算完再回答你。
NEEDS

不是心情值,是「我缺什么」

高 = 缺得多。所有行为都由这五个数驱动,没有一个行为是随机挑的。 其中 警觉是这套东西和玩具的分界线:别的都靠时间慢慢涨, 只有警觉是被你的工作强行灌进去的——所以你一跑测试,它就抬头。

困 fatigue

醒着一直涨,约五小时见底。只有睡觉能掉,而且掉得比涨快得多。

+0.0034/分 · 睡时 −0.052/分

闷 boredom

一直涨。扑咬、疯跑、巡视、磨爪会真的把它往回压——用减法,不是抵消。

+0.011/分 · 扑咬 −0.085/分

孤 loneliness

没人理就涨。判断标准不是「被摸了几下」,而是「你手上有活吗」。

+0.0038/分 · 你在线时 −0.0053/分

饿 hunger

慢慢涨,约九小时见顶。吃一顿掉回一半,然后再慢慢涨。

+0.0018/分 · 吃时 −0.55/分

警觉 alertness

不自然涨,只由任务事件注入。半衰期 50 秒,掉得很快——所以它只在你要紧的时候盯着。

任务 +0.52~0.66 · 半衰期 50s
BEHAVIORS

十二种自发行为

每轮决策,所有「能做的」行为各自算一个分,最高的上岗。 两个细节让它不抽搐:习惯化——刚做过的事下次打分打折,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
REACTIONS

反应不替换行为,是盖在上面

这是整个模型里最关键的一条。猫可以正在舔毛,突然抬头看你一眼,然后低头继续舔—— 它的状态没变,只是被打断了。现实里的猫就是这么动的。 反应持续一到三秒,撤掉后姿势自动回到原来那个行为。

应声 ACK

活开始了。警觉 +0.52。task.start

得意 CHEER

成了。心情 +0.48,+12xp。task.ok

炸毛 ALARM

挂了。心情 −0.38,警觉 +0.66,+4xp。task.fail

叫你 MEW

卡住了。会弹系统通知。task.wait

呼噜 PURR

被摸到了。孤独 −0.30。pet · feed

打哈欠 YAWN

等到长蘑菇了。prompt.idle

RULES

十二条行为准则

印在文档上,也写在代码里。每一条都能在 src/core/engine.js 里搜到对应的实现, 自测里有对应断言。

EVOLUTION

它会自己长成自己的样子

失败也加经验,只是少一点——因为失败确实也学到了东西。 阶段会改行为:老猫每种动作都待得更久、睡得更沉、疯跑更少。进化只升不降。

形象更是从头到脚重画一遍:耳朵、脑袋、身板、尾巴各换一套——奶猫圆滚滚什么都短, 猫又是叉耳、带印、两条尾巴。点一点链上任意形态,终端里就预览它那个阶段的样子,没解锁的显示剪影。

同时它还在学你:几点干活、在哪个目录、跑什么命令、失败率高不高。 从这些压出五个性格维度(夜行 / 碎步 / 调试 / 傲娇 / 俏皮)直接进打分公式—— 同一套匮乏,不同主人的猫走不同的路。 傲娇的猫更爱瘫着舔毛、盯着你不承认,俏皮的多半在扑咬疯跑、随时踩奶。 没数据的时候,先按种子给一只猫一个脾气底子,所以每只都不一样。 跨过零点还没访问的时候,统计会按 0.86 的衰减一次性补算——搬了家、换了技术栈,它会跟着变。

它现在知道什么 catctl learn

●●●●● 你的活有 68% 落在 21:00–02:00,我按这个点儿调了作息,主要是夜里。
●●●●○ 最常待的是 cat-api-spec(134 次),那里算主领地,另外还有 3 处会去。
●●●●● 「npm test」跑了 41 次,挂掉 44%,一次大约 18 秒。你重试之前我一般不吵。
●●●●○ 你最常干的是跑测试(41 次,挂 44%)。这类活容易翻,我多陪一会儿。
●●●○○ 这周干了 12 件,比上周多 4 件,没歇着啊;「跑测试」多挂了 2 回,我不问,我趴着。
●●●●● 失败率 44%。我不催你——失败的时候我趴旁边,不盯着屏幕。

CLI

整个东西就是一条命令

为什么是 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 selftest

45 项不变量自测,含 172800 步的确定性断言。

事件只有这几种:task.start · task.ok · task.fail · task.wait · prompt.idle · pet · feed · laser · wake。宿主不需要知道猫的内部结构,只需要知道这九个词。

ADAPTERS

接到任何工作台

不知道你那个宿主怎么配 hook?没关系。包一层就行—— 任何能跑命令的地方,把命令前面加上 catctl run --,猫就接上了。

WorkBuddy / Codex

emit 一行命令
catctl emit task.ok
catctl emit task.wait --notify
catctl emit task.fail

Codex 没有外挂钩子,就写进 AGENTS.md 一句话,或者外面套一层 catctl run -- codex。

Claude Code

catctl init --host claude
settings.hooks.Stop
  → catctl emit task.ok
settings.hooks.Notification
  → catctl emit task.wait --notify

合并写入,改之前自动备份旧的 settings.json。

git

catctl init --host git
.git/hooks/post-commit
  → catctl emit task.ok \
      --name "git commit"

每次提交它看一眼。已有 hook 会先备份。

shell

catctl init --host shell
source 项目/.catctl/shell-hook.sh
# 写进 ~/.zshrc

之后你在终端里跑的每条命令,成没成它都知道。

不开 shell 的宿主

catctl serve
GET  /state
GET  /learn
POST /emit  {"type":"task.ok"}

只监听 127.0.0.1,不出网。给 Electron、Tauri、VSCode webview 用。

任何地方

万能的一条
catctl run -- <你平时的命令>

退出码原样返回。不需要宿主配合,也不需要你改任何配置。

桌宠的难点从来不是画一只猫。
难点是让它在你不看的时候,也真的活着。