caveman CLI 深度解析:零依赖构建管线、双门命令面与诚实计量约束
【免费下载链接】caveman🪨 why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman项目地址: https://gitcode.com/GitHub_Trending/caveman1/caveman
Caveman("🪨 why use many token when few token do trick")是一个面向编码 Agent 的本地上下文压缩与计量方案,而packages/cli是它与用户对话的唯一终端入口。本文以 packages/cli/CLAUDE.md 为主体,完整拆解cavemanCLI 的包布局、构建管线、"porcelain + 命名空间"命令面设计、cavemanBin()二进制解析链、首次运行体验与遥测契约,以及一组用测试钉死的"诚实规则"(no-fake-savings)与能力晋升规则。读完你能在源码级理解:为什么caveman claude一个命令可以同时是"持久化安装器"和"临时包装门",以及 CLI 如何保证降级路径永远响亮、绝不误报节省。
一、包定位:零运行时依赖的 JS 前端 + Go 伴生二进制
pkg 描述 直接点明了分工:TypeScript CLI 负责"驱动本地代理、包装 control-api 的 REST 调用",压缩、计量、流恢复等重活全部落在伴生 Go 二进制里。package.json 中dependencies为空对象,bin同时暴露caveman与cave两个入口,均指向dist/index.js,要求 Node>=22.13。
这意味着 npm 分发物只含 JS 前端,README 将其总结为"一个 CLI 入口 + 一个懒加载的 25 KB 交互式 learn 分片",真正干活的是这些二进制:
| 二进制 | 支撑的命令 |
|---|---|
caveman-proxy | start·wrap·stats— 本地压缩 + 诚实计量 |
caveman-engine | compress·shrink·retrieve·toon·evals |
caveman-mcp | Agent 侧恢复工具,让流式请求可以安全压缩 |
cavemem | 本地 remember / recall / learned-context 卸载 |
caveman-browse | 压缩后的网页快照(可选) |
caveman-shrink | tools compress catalog— 工具 schema 压缩(可选) |
缺二进制时的行为在 src/index.ts 中 cavemanBin() 有明确定义:解析顺序为环境变量覆盖(CAVEMAN_*_BIN)→ PATH →~/.caveman/bin(由仓库根目录的 scripts/install-local-cli.sh 或 scripts/install-local-cli.ps1 构建产出)→ 最终兜底返回裸名字。最后一步看似冗余,其实刻意为之——"这样缺失二进制时,命令面板依然会被触发并打印降级警告",而不是无声失败。caveman setup则是反"静默降级"的正门:逐项打印哪些二进制可用、哪些会退化为"响亮且字节安全的直通",缺必要二进制(proxy/engine/mcp/mem)时以非零退出。
一个容易踩坑的例外来自 README:wrap不是普通直通——它把 Agent 的ANTHROPIC_BASE_URL/OPENAI_BASE_URL指向本地代理(src/index.ts 中固定为127.0.0.1:8787),代理没起来时请求会路由失败而非穿透;交互式 wrap 会捕获并建议直接启动 Agent,非交互式 wrap 打印警告后仍会启动,所以脚本/CI 调用方必须自行保证代理在线(或使用--no-proxy)。
二、包布局与构建管线
CLAUDE.md 给出的布局(Layout)与 package.json 的 build 脚本 完全对应,构建是一条"生成 → 编译 → 打包 → shebang"的流水线:
src/index.ts— 整个 CLI 本体:参数分发、HTTP 辅助函数(get/post)、token 存储、全部命令。文件长达 1.6 万余行,是单文件命令枢纽;src/learn-tui.ts— 有边界的交互式 learn 视图,与 Clack(@clack/prompts)一起打包为独立分片dist/learn-tui.js,仅在 stdin/stdout/stderr 都是真实 TTY 时才加载——这是"TUI 库必须打包、懒加载、被测量,不得移入普通命令启动路径"这一 gotcha 的直接体现;tests/*.runtime.mjs— Node 内置node --test运行时测试,spawn 构建后的二进制并对接 HTTP 桩(providers-verify、wrap、login、compress等,见 tests 目录 中 90 余个*.runtime.mjs);- scripts/bundle-delegate.mjs — 把无依赖的 delegate 服务器副本放入发布的
dist/(对应产物dist/caveman-delegate-mcp.mjs); - scripts/bundle-tui.mjs — 用 esbuild 把 Clack 打进自包含的 learn TUI 分片;
- scripts/shebang.mjs — 后置步骤:在
dist/index.js头部插入#!/usr/bin/env node并chmod 0o755(源码仅 8 行,逻辑即"无 shebang 则补一行,然后改执行位")。
此外 build 还包含gen-binaries.mjs、gen-wedge-installer.mjs、compile-registries.mjs等前置生成步骤:Agent 档案、二进制发布清单、集成配方等都被编译为src/*.generated.ts(如agents.generated.ts、recipes.generated.ts),所以"新增一个可包装 Agent"只需加一份 profile 文件而非改代码——src/index.ts 的注释明确写道:这些生成数据驱动检测、交互选择器和"每个 Agent 如何被指向网关(env 注入 vs 内联配置注入)"。测试命令与 build 相同前置 +node --test --test-force-exit --test-concurrency=4 tests/*.runtime.mjs,另有裁剪过用例的test:fast变体。
三、命令面设计:四动词 porcelain + 双命名空间 + Agent 快捷方式
命令面是这份文档信息密度最高的部分,核心设计可以概括为三层:
1. 顶层 Agent 快捷方式是"持久化默认门"。caveman <agent>(如caveman claude)对支持 hook 的原生 Agent(claude/codex/hermes/gemini/opencode ——aider 除外,因为其无 hook 的原生安装根本无法启动代理)执行:若不存在安装日志则先跑用户作用域的caveman enable <agent>原生安装;若本地代理未监听则预先启动(原生 SessionStart hook 也会再做一遍,但那要等宿主批准 hook 之后);然后直接启动宿主二进制。效果是"裸<agent>在之后的每个会话里都保持 caveman 化"。一旦原生安装就位,持久路由会一直生效,直到caveman disable <agent>;此后的--off/wrap运行只是临时的。
2. 回退保证"快捷方式永远不会比会话级 wrap 更差"。只要原生路径撑不住——传入了 wrap 会话标志(--off/--pixel/--workflow)、目标不是原生 Agent、当前目录存在 Cave Build 锁(锁的强制执行只在 wrap 门生效)、或 enable 失败(例如缺 caveman-mcp/proxy 二进制)——就回退到临时wrap门。caveman wrap <agent>/caveman run <agent>始终是显式的会话级路径;cave则是字节兼容的永久 bin 别名,迁移过的动词保留裸拼写作为静默legacy 别名(文档强调"禁止输出弃用文本,以免污染管道输出")。
3. 分发优先级:真实命令永远遮蔽 Agent 名。Agent 快捷方式在所有命令最后分发,因此任何已注册动词都会抢占同名的 Agent 标识;Agent 名之后的参数则原样透传给宿主。
打印出来的 porcelain 只有四个动词run、learn、login、status加 Agent 快捷方式;本地能力归入caveman tools,账户/网络相关操作归入caveman cloud,两个命名空间的打印动词上限均为 15(当前 tools 15、cloud 14),而dev/deploy是未文档化的维护者别名。src/index.ts 中的发现表 印证了这一组织:TOOL_DISCOVERY按 think/remember/execute/inspect 四组列出(shrink-hook、practices、check带hidden: true标记,仍可经既有路径调用但永不打印,包括 legacy 的help tools --all);CLOUD_DISCOVERY按 account/evidence/governance 分组(whoami、projects、keys、providers、billing、score、costs、plan、traces、experiments、receipts、audit 等 14 个)。doctor、opportunities、snippets等未打印 legacy 别名的公开职责已被status、plan与tools sdk snippets吸收。
无账户的本地命令集
文档列出的本地命令与行为约束值得逐条保留:
start— 通过CAVEMAN_PROXY_BIN启动代理;二进制缺失或端口已被服务时渲染状态面板(构建/make dev+实时 docker 状态/环境),而非裸 spawn 报错;wrap [agent]— 注入路由并 exec 子进程;Claude、Codex、Hermes、Gemini、OpenCode、Aider、OpenClaw 均可按 id 启动;原生宿主只获得临时 pack/home/config,退出后清理,不写用户/项目配置;enable|disable <agent>— 显式用户作用域原生安装,带原子日志、锁、可逆的 owned-path 恢复与组件 doctor;inspect/why <decision-id>— 内容盲的原生收据与 Decision Ledger 解释;compress— 调起caveman-engine;二进制缺失时字节安全直通,标注inferred;mcp install|uninstall [agent]— 显式的持久恢复注册;wrap 仅在execute.mcp = auto且存在本地 MCP 二进制时使用临时恢复配置,marker-only或false抑制注入但绝不静默删除用户已有注册;skills add <source>— 与官方npx skills add相同的 Git/URL/本地来源与标志;上游负责下载与选择,强制 copy 模式让 Caveman 只对新/变更的 Claude Code/CodexSKILL.md正文做 pixel 化,第三方资源原样保留且明确声明未做安全审查,--no-pixel可退出;skills import <dir|SKILL.md>— 阻塞的、未求值的原生 skill 草稿;导入的资源永不执行;evals run、stats、convert。
连接命名空间与登录
连接类动词共 14 个:whoami · projects · keys · providers · billing · score · costs · plan · traces · experiments · receipts · audit · sync · agent。login轮询 control-api 的/api/v1/auth/device/{code,token},organization_id从返回的 token 绑定;CAVE_TOKEN是不交互 CI 路径。未登录时所有连接类动词打印一行并以非零退出(CI 跳过而非崩溃)。非机密配置存于~/.caveman-cloud/config.json(0o600),而认证 token 存放在 OS 钥匙串(macOSsecurity),兜底为~/.caveman/credentials(0o600)——绝不落明文配置。
四、首次运行体验:一次性的 TTY 时刻与诚实扫描
首次交互 wrap(仅 TTY,每机一次,以 config 中firstRunAt标记)是 CLI 最复杂的一段体验逻辑,src/index.ts 给出了完整预算契约:
- 品牌横幅 + 30 天回顾扫描(
caveman-proxy learn scan --retro,只读本地 Claude Code/Codex 会话日志)。子进程超时由两段独立预算推导:base 行为扫描FIRST_RUN_BEHAVIOR_SCAN_BUDGET_MS = 20_000(实测 base 解析约 2.5s),retro 通道FIRST_RUN_RETRO_SCAN_BUDGET_MS = 60_000(覆盖约 1GB/2k 会话的完整一遍,实测约 29s),再加 10s 清理/序列化余量,得FIRST_RUN_SCAN_TIMEOUT_SECONDS = 90。注释特别解释:独立预算 + 推导式超时保证"改动某段预算不会让子进程杀掉另一段的有效部分结果"。 - 三个数字的计数动画揭示(sent / would-have-cut / rides-every-turn 流式数字):全部是对所扫描会话的求和,从不外推;标注
inferred;tokens 永不换算成 dollars;sent 按每个 API 响应去重一次;base cut 不与 sent 共享比例,只有流式数字与 sent 同基准。 - 遥测披露 + 一个
[y/N]账户问题(选是 → 设备登录 → 回填既有 span)。
诚实护栏("no-fake-savings")在源码注释里逐条重申:CLI 只持久化"已闭合的、无内容的聚合";登录或显式sync才把它上传到已认证项目的local-scan导入通道;提示词、输出、路径、会话行、自由文本 caveat 与匿名遥测永不进入该上传;仪表板保持inferred并与 spend/verified 节省分离。任何一步失败都退化为"一行暗色文字 + Agent 照常启动"。回放入口是未打印的caveman welcome(porcelain 上限不变)。firstRunUIEligible()同时要求 interactive、CAVEMAN_PLAIN未置真、TERM !== "dumb"。
遥测契约
匿名遥测默认开启(opt-out):持久化的 v1 决定、DO_NOT_TRACK/CAVEMAN_TELEMETRY=0/caveman telemetry off永远优先;CI/非 TTY 永不发送也永不持久化默认值;首个合格的交互式运行持久化稳定的匿名 id 并打印披露行。command_run事件携带tokens_processed/tokens_saved,取自本地代理存储、相对 config 中telemetryTokens水位线的增量(src/index.ts 的类型注释解释了水位语义:每次事件只带 delta 而非重放全生命周期历史),始终附带tokens_basis(inferred,tokens 永不 dollars);读取是 400ms spawn 预算内的尽力而为,存储或二进制缺失时直接省略这两个字段。扩大披露范围意味着递增TELEMETRY_PROMPT_VERSION(当前为 4)——这只会对过期版本的 opt-in 者重印一次披露行,永不重新提问、永不触碰 opt-out。
五、能力晋升规则与配置分层
这是文档中"给贡献者立规矩"的部分,规则原文值得保留:
一个能力只有在字节安全、或被适用的路径级 gate 保护时才可默认开启:托管网关用 eval gate;本地 wrap 用 recovery + CCR —— 而不是账户或权益。本地
run里不存在 eval gate。任何翻转默认值的 PR 必须点名条款与路径。
动词进入 porcelain 的门槛是其能力在run内"默认自动且安全"且用户不再需要手敲;porcelain 永远封顶四动词 + Agent 快捷方式 + 恰好两个命名空间,第五个动词或任一命名空间第 16 个打印动词都要求一次退役决定。record模式永远直通。
配置分层同样写死在文档里:能力配置在~/.caveman-cloud/config.json中按think/remember/execute三组组织;./.caveman/config.json只能收窄其白名单内的项目本地键,不能改think.mode、pixel 设置、账户状态、consent 或权益。解析优先级为:default < proxy YAML < legacy wrap < global groups < project overlay < env,且 env 对齐是按旋钮(knob-specific)的。逐键查来源用caveman tools config get。
六、值得逐条记住的工程约定与 Gotchas
CLAUDE.md 的 Conventions 与 Gotchas 两节是测试断言直接钉住的行为契约:
- 分发约定:用 handler 表;每个 handler 拿到自己 rebased 的 argv 切片,绝不在 handler 内按位置读进程级 argv;
flag("--name", fallback)从当前调用解析命名参数;测试用node --test(先跑tsc,测试会起真实 HTTP 服务器);本地安装走仓库根的 scripts/install-local-cli.sh(macOS/Linux)或 scripts/install-local-cli.ps1(Windows)。 - no-placeholder 规则:
providers verify <conn>必须真实 POST/api/v1/projects/{id}/providers/{conn}/verify并回显服务器值——测试断言 CLI 不得返回硬编码状态。 - plan 的诚实规则:
plan用"一个运营者声音"渲染 Cave Plan(--json输出原始响应);刻意移除了 caveman 语音/--engineer双声线;标题标注basis("inferred"),节省永远按天展示,绝不外推月度。 ANTHROPIC_BASE_URL陷阱(#865):Claude Code 把任何 host 不是api.anthropic.com的ANTHROPIC_BASE_URL视为自定义端点并扣留第一方能力——最显眼的是 1M token 上下文窗口,丢失后自动压缩窗口静默缩回 200k 默认。因此两条 Claude 路由门(临时buildWrapEnv与持久原生安装)都设置_CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL=1,但仅当断言可验证为真时:本地模式且代理的 anthropic 上游是api.anthropic.com(默认值或显式providers.anthropic.base_url指向该 host,经一个无依赖的 scoped YAML 扫描判定,flow-style 块按不可验证处理);用户自己设置的值永不被覆盖,托管网关永不断言;disable仅在变量仍精确等于我们写入的值时才删除它。- 订阅/OAuth 会话(Claude Pro/Max)只在本地压缩、仅 live zone、且无账户:
CAVEMAN_WRAPPER_ENTITLED已从两扇门和代理中移除,两扇门还会delete任何继承副本,防止 stray export 复活它。两扇门真正盖章的是恢复路径CAVEMAN_RECOVERY(显式"mcp"或空,永不继承):wrap的回答来自Agent 自己的MCP 安装(导出的CAVEMAN_RECOVERY=mcp不能比那个回答活得更久——否则代理会省略字节而该 Agent 根本没有caveman_retrieve工具来展开);start则依据机器级 MCP 安装证据 + 显式CAVEMAN_RECOVERY=mcp(算作运营者自己的 opt-in,重新盖章以保证披露行与代理永不矛盾)。压缩披露行只在恢复成立时打印;无 MCP 时说明压缩关闭并点名caveman mcp install <agent>。subscription_compress: off开关始终归运营者。这类会话的节省只有 tokens——席位没有按 token 计价,所以任何地方(本地或同步 span)都不得出现美元数字;会话节省行把oauth视作subscription对待(OAuth 仅在 Vertex 上享有 list-price 资格),且其封顶认证窗口被截断时无条件受限。 learn的呈现契约:摘要优先,真实终端获得动画进度、有边界的 score 与 move 卡片、一个键盘动作菜单;--plain恢复紧凑文本,--all恢复全部 sink id/class/practice/suggestion,--json与--md保持完整;--plain、CAVEMAN_PLAIN=1、TERM=dumb、机器模式与管道永不提示。learn implement [claude|codex] [--prompt <focus>]在缺失时安装既有caveman-learn安全指南并启动所选交互 Agent,指南中逐次编辑同意、承重保护、复测与 inferred-only 规则仍然约束生效。完整呈现契约见 TERMINAL_UX.md。- 非 PAYG 覆盖包含 Claude Pro/Max、Codex ChatGPT、Gemini OAuth 与路由兼容 Agent;Codex 订阅模式把 provider 配置临时放在
CODEX_HOME下、自动安装 MCP 恢复、并以 compress 模式启动/chatgpt/responses而非强制 record/直通。显式禁用 MCP 的普通 OpenAI/responses与 GeminigenerateContent请求没有服务端检索语法,因此必须字节恒等且压缩记账为零——压缩一致性矩阵(tests/agent-compression-conformance.runtime.mjs)正是用来钉住这些协议级 fail-closed 用例的,而不是要求每个 profile 都发 CCR 标记。 - TUI 纪律:发布的运行时依赖保持为零,TUI 库必须打包、懒加载、被测量;状态面板与 wrap picker 等其余终端 UX 住在 src/index.ts 底部的小型工具包里,管道/非交互路径保持纯文本且由运行时测试断言。
- Skills 路径分裂:官方 Skills CLI 现在把全局 Codex 源装到
~/.agents/skills,而旧版/直装 Caveman 用~/.codex/skills——第三方安装后的发现逻辑必须同时扫描两处。
七、如何本地构建与验证
从源码验证这套 CLI 的最小闭环(仓库为只读参考,以下为查看/构建说明):
# 构建(registry 生成 → tsc → delegate/TUI 打包 → shebang) pnpm build # 完整运行时测试(Node 内置 runner,起真实 HTTP 桩服务器) pnpm test # 本地安装 CLI 与 Go 二进制(macOS/Linux / Windows) ./scripts/install-local-cli.sh pwsh -File scripts/install-local-cli.ps1caveman setup打印逐二进制的安装状态——什么可用、什么退化为响亮直通、以及唯一的一条安装命令;PUBLISHING.md 记录了发布清单。若某条命令行为与预期不符,优先查看 tests 中对应的*.runtime.mjs——它们以构建后二进制 + HTTP 桩(tests/harness 提供 stub-control-api、stub-upstream、stub-agent 等)端到端断言了本文所述的大多数契约,是比文档更新的行为事实来源。
小结
packages/cli的设计哲学可以浓缩为三句话:入口要薄(零运行时依赖的单文件 TS,重活外包给签名校验的 Go 二进制);降级要响(任何缺失能力都退化为打印警告的字节安全直通,且setup是修复正门);数字要诚(inferred标注、按天不按月的节省、tokens 永不 dollars、遥测 opt-out 且增量上报)。配合能力晋升规则与 porcelain 封顶,这个 CLI 把"省 token"这件容易变成营销的事,约束成了一组可用node --test复验的断言。
【免费下载链接】caveman🪨 why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman项目地址: https://gitcode.com/GitHub_Trending/caveman1/caveman
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考