首页
/ caveman-help 速查卡解析:caveman 模式、命令与默认配置的源码级参考指南

caveman-help 速查卡解析:caveman 模式、命令与默认配置的源码级参考指南

2026-09-06 12:28:28作者:江焘钦

caveman 是一个以"压缩输出风格节省 token"为核心的 Claude Code 技能集,其中 caveman-help 是整个技能族的"一页速查卡":它一次性打印全部模式、兄弟技能、停用触发词以及默认模式配置方式,且严格保证一次输出(one-shot)——不改模式、不写标志文件、不落任何持久化状态。读完本文,你能完整掌握 /caveman-help 卡片的每一项内容,并理解这些"模式表"与"默认模式解析顺序"在 caveman-config.jscaveman-parse.js 中的真实实现路径与测试依据。

一、caveman-help 是什么:只读的一次性速查卡

skills/caveman-help/README.md 对它的定位非常明确:

Quick-reference card. One shot, no mode change.

即:打印一张包含全部 caveman 模式、兄弟技能、停用触发词、以及"如何通过环境变量或配置文件设置默认模式"的速查表。它属于纯展示型技能——调用后不切换当前活跃模式、不写 flag 文件、不持久化任何内容。README 建议的使用场景是"忘记斜杠命令时"随手一敲。

skills/registry.json 中它被列入 preserved_skill_ids(与 caveman-commitcaveman-reviewcaveman-statscaveman-compress 并列),说明它是 caveman 技能族中被明确保留的核心入口之一;docs/technical/skills-hooks-and-plugins.md 也将其标注为 "One-shot command card / Does not change active mode"。

二、如何调用:斜杠命令与自然语言触发

标准调用

/caveman-help

自然语言触发

README 说明以下表述同样会触发该速查卡:

  • caveman help
  • what caveman commands
  • how do I use caveman

caveman-parse.js 的源码结构看,这些问句之所以能"查而不切",是因为模式解析器把提问类语句显式排除在激活逻辑之外(见 caveman-parse.js#L184-L188):

// Questions about caveman are not activation commands
// ("what is caveman mode?", "does caveman lite drop articles?").
const isQuestion =
  /^(what|whats|what's|how|why|when|where|who|does|do|did|is|are|can|could|would|should|tell me|explain)\b/.test(nlPrompt);

也就是说,"what caveman commands"、"how do I use caveman" 这类 what/how 开头的问句会被识别为提问而非激活命令,因此只走速查卡展示,不会把会话切进 caveman 模式——这正是 caveman-help "one-shot, no mode change" 语义在解析层的落点。而 /caveman-help 本身以 /caveman 前缀进入命令分支,但它既不是 /caveman(主命令)也不是 /caveman-commit/caveman-review/caveman-compress 这三个独立模式命令(见 caveman-parse.js#L213-L232),解析结果返回 null(不改变状态),进一步印证其无副作用。

三、速查卡完整内容:模式、技能、停用与语言

以下卡片内容完整继承自 skills/caveman-help/SKILL.md(README 指向的 "full reference card")。

3.1 模式(Modes)

模式 触发命令 行为
Lite /caveman lite 去掉填充词,保留句子结构
Full /caveman 去掉冠词、填充词、客套话与含糊表述,允许短句碎片。默认模式
Ultra /caveman ultra 极限压缩。裸短句为主,能用表格不用散文
Wenyan-Lite /caveman wenyan-lite 文言风格,轻度压缩
Wenyan-Full /caveman wenyan 完整文言文。最极致的古典简洁
Wenyan-Ultra /caveman wenyan-ultra 极限文言。"省着字的古学者"

卡片的原话是 "Mode stick until changed or session end."(模式会持续生效,直到被改变或会话结束)。这与源码中的按会话存储设计一致:每个会话的状态写入 $CLAUDE_CONFIG_DIR/.caveman-sessions/<session_id>.mode,见 caveman-config.js#L380-L403 的说明注释——早期"整机单文件"存储导致并行会话互相串模式,改造后每个会话独立持有模式,会话结束即失效。

一个实现细节:模式参数是标点容忍的。/caveman ultra; still too verbose 这种把标点粘在模式名后面的写法,会由 normalizeModeArg 剥掉首尾非 [a-z0-9-] 字符后正常解析(见 caveman-parse.js#L82-L84),而不会静默失败。另外 wenyan-fullwenyan 的规范别名:写 /caveman wenyan-full 实际落到 wenyan 模式(caveman-parse.js#L102-L103)。

3.2 兄弟技能(Skills)

技能 触发命令 作用
caveman-commit /caveman-commit 生成精简 commit message,遵循 Conventional Commits,subject ≤50 字符
caveman-review /caveman-review 单行 PR 评论,形如 L42: bug: user null. Add guard.
caveman-compress /caveman-compress <file> 将 .md 文件压缩为 caveman 文体,约省 46% 输入 token
caveman-help /caveman-help 即本卡片

源码中有一个值得注意的约束:commitreviewcompress 被定义为独立模式INDEPENDENT_MODES,见 caveman-parse.js#L51-L53),不能通过 /caveman commit 这种子参数方式进入,只能用自己的斜杠命令。若用户真敲了 /caveman commit,解析器不会报错,而是返回 { action: 'unresolved', independentMode: 'commit' },让调用方提示其"使用独立命令"(caveman-parse.js#L105-L109)。这些独立模式也是"one-shot"语义的:用完会恢复被顶替前的会话模式。

3.3 停用(Deactivate)

卡片给出两个自然语言触发词:

Say "stop caveman" or "normal mode". Resume anytime with /caveman.

实际的正则比这两个词宽。caveman-parse.js#L150-L159 中的停用判定覆盖:

const wantsOff = naturalLanguage && (
  /\b(stop|disable|deactivate|quit|exit|kill)\s+(the\s+)?caveman\b/.test(nlPrompt) ||
  /\bcaveman(\s+mode)?\s+(off|stop|disabled?)\b/.test(nlPrompt) ||
  /\bturn\s+off\s+(the\s+)?caveman\b/.test(nlPrompt) ||
  /^(please\s+)?(go\s+|back\s+to\s+|switch\s+(back\s+)?to\s+|return\s+to\s+)?normal\s+mode\b/.test(nlPrompt) ||
  (/\bnormal\s+mode\b/.test(nlPrompt) && /\bcaveman\b/.test(nlPrompt))
);

stop/disable/deactivate/quit/exit/kill cavemancaveman offturn off caveman、句首的 normal mode(或带 "go back to / switch back to" 前缀)均可停用。两条防误触规则也值得了解:

  1. 引用不触发:如果触发词出现在引号内(比如你在贴一份文档,文档里恰好写着 "stop caveman"),引号区间会先被 QUOTED_SPAN_REGEX 抹空再匹配(caveman-parse.js#L54-L72),避免"引用了停用词却被停用"(对应历史问题 #838:bug 报告里引用了 help 卡片自己的停用示例行,导致任务中途被关掉)。
  2. 命令不误伤:以 / 开头的提示词是命令调用,其正文不会切换 caveman 模式;normal mode 也不会匹配句中非命令用法(例如 "how do I exit vim normal mode" 不会停用 caveman)。

3.4 语言策略

Keep user's language by default. User write Portuguese → reply Portuguese caveman. Compress the style, not the language.

压缩的是文体而非语言:用户写葡萄牙语,就回葡萄牙语版 caveman。技术术语、代码、命令、commit type 与精确错误字符串保持原样,除非用户明确要求翻译。

3.5 README 中的示例输出

skills/caveman-help/README.md 给出的卡片示例(节选形式):

Modes:
  /caveman              full (default)
  /caveman lite         lighter
  /caveman ultra        extreme
  /caveman wenyan       classical Chinese

Skills:
  /caveman-commit       terse Conventional Commits
  /caveman-review       one-line PR comments
  /caveman-stats        session token savings

Deactivate:
  "stop caveman" or "normal mode"

注意示例输出只列了部分项(如 wenyan 一族只展示 wenyan,skills 列表里出现的是 caveman-stats 而非 caveman-compress),完整清单以第三节 SKILL.md 的两张表为准。

四、配置默认模式:README 说的与环境变量、配置文件

卡片"Configure Default Mode"一节的原始内容:

  • 默认模式为 full
  • 环境变量(最高优先级):export CAVEMAN_DEFAULT_MODE=ultra
  • 配置文件~/.config/caveman/config.json):{ "defaultMode": "lite" }
  • "off" 可禁用会话开始时的自动激活,用户仍可用 /caveman 手动打开;
  • 优先级:env var > config file > full

4.1 源码中的完整解析顺序(比卡片多一层)

caveman-config.js#L118-L138getDefaultMode() 实际实现了四层解析,其中第二层"仓库级配置"是 README 未提及、但对团队场景很关键的一项:

function getDefaultMode(startDir) {
  // 1. Environment variable (highest priority)
  const envMode = process.env.CAVEMAN_DEFAULT_MODE;
  if (envMode && VALID_MODES.includes(envMode.toLowerCase())) {
    return envMode.toLowerCase();
  }
  // 2. Repo-local config (checked-in, per-project default)
  const repoConfigPath = findRepoConfigPath(startDir);
  if (repoConfigPath) {
    const repoMode = readModeFromConfigFile(repoConfigPath);
    if (repoMode) return repoMode;
  }
  // 3. User config file
  const userMode = readModeFromConfigFile(getConfigPath());
  if (userMode) return userMode;
  // 4. Default
  return 'full';
}

完整优先级为:

  1. CAVEMAN_DEFAULT_MODE 环境变量;
  2. 仓库级配置(可提交进版本库、按项目生效):从当前目录向上查找 .caveman/config.json.caveman.json,取最近命中者,最多向上 64 层以防符号链接循环(caveman-config.js#L67-L96);
  3. 用户级配置文件的 defaultMode 字段;
  4. 兜底 full

仓库级配置解决的正是"团队想钉住某个项目的默认模式,又不想污染每个贡献者的用户配置或环境"的问题(源码注释原话)。相关行为由 tests/test_repo_local_config.js 覆盖。

4.2 配置文件的平台位置

卡片只写了 ~/.config/caveman/config.json,而 caveman-config.js#L50-L61getConfigDir() 给出了各平台的实际取值:

function getConfigDir() {
  if (process.env.XDG_CONFIG_HOME) {
    return path.join(process.env.XDG_CONFIG_HOME, 'caveman');
  }
  if (process.platform === 'win32') {
    return path.join(
      process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'),
      'caveman'
    );
  }
  return path.join(os.homedir(), '.config', 'caveman');
}

即:设置了 XDG_CONFIG_HOME 时优先用 $XDG_CONFIG_HOME/caveman/config.json;Windows 上回落到 %APPDATA%\caveman\config.json;其余平台为 ~/.config/caveman/config.json

4.3 合法模式白名单

无论环境变量还是配置文件,defaultMode 的值都必须通过白名单校验,否则视为未配置、继续向下解析(caveman-config.js#L98-L110)。白名单定义在 caveman-config.js#L32-L36

const VALID_MODES = [
  'off', 'lite', 'full', 'ultra',
  'wenyan-lite', 'wenyan', 'wenyan-full', 'wenyan-ultra',
  'commit', 'review', 'compress'
];

这与第三节的模式表、技能表一一对应,且注意配置里可以写 wenyan-full(解析时归一化为 wenyan)。另外 getDefaultModestartDir 参数专门处理了"UserPromptSubmit hook 的 stdin 携带的会话 cwd 与 hook 进程 cwd 可能不同"的场景(源码注释标注为 #634),只有仓库级配置查找这一层依赖起始目录,其余各层与 cwd 无关。

当默认模式被配成 "off" 时的行为细节:裸 /caveman(不带参数)此时执行的是 clear(不激活);而自然语言激活(如 "activate caveman")则直接 no-op,不改动既有状态(caveman-parse.js#L92-L99L199-L205)。这也解释了 INSTALL.md 中"如果不想让它自动激活,可检查 CAVEMAN_DEFAULT_MODE 或仓库级配置"的排查建议。

五、"One-shot" 在状态层如何兑现:会话模式与标志文件

caveman-help 承诺"不写 flag 文件、不持久化",而要理解它不做什么,需要看它同层的会话模式状态机制(均在 caveman-config.js):

  • 写入writeSessionMode() 是唯一写入活跃模式的入口,写入 $CLAUDE_CONFIG_DIR/.caveman-sessions/<session_id>.mode(内容 0600 权限、临时文件+原子 rename),并同步维护一个兼容用的整机级镜像 .caveman-active;停用(off)时镜像文件被删除而非写入 "off",以避免旧版本状态栏脚本把 "off" 渲染出来(caveman-config.js#L476-L500);
  • 读取resolveActiveMode() 优先读本会话文件,再回退 legacy 镜像,用于每轮强化、状态栏与统计等所有读取方;
  • 模式日志:真正发生模式切换时,recordModeChange() 追加一条 {ts, mode, prev, session_id}.caveman-mode-log.jsonl,供 caveman-stats 把输出 token 归因到"消息生成时处于的模式"而非统计时刻的模式(caveman-config.js#L574-L603);
  • 清理:新会话启动时对超过 14 天 TTL 的会话文件做清扫(gcSessionStore,可通过 CAVEMAN_SESSION_TTL_MS 覆盖)。

caveman-help 的调用路径不触碰上述任何函数——它既不产生 writeSessionMode 调用,也不产生 recordModeChange 日志条目,这与卡片的自我描述一致。相关回归验证分布在 tests/test_caveman_parse.js(解析行为)、tests/test_mode_tracker.py(模式跟踪与 CAVEMAN_DEFAULT_MODE)与 tests/test_hooks.py(hook 集成)。

六、快速参考小结

想做的事 命令 / 配置
查速查卡(不改状态) /caveman-help 或 "caveman help"
切模式 /caveman(默认)、/caveman lite/caveman ultra/caveman wenyan-lite/caveman wenyan/caveman wenyan-ultra
关闭 "stop caveman" / "normal mode"(亦含 disable/quit/exit/kill 等变体)
commit / review / 压缩 md /caveman-commit/caveman-review/caveman-compress <file>(独立命令,不可作为 /caveman 子参数)
改默认模式 CAVEMAN_DEFAULT_MODE(最高优先级)→ 仓库级 .caveman/config.json / .caveman.json → 用户级 ~/.config/caveman/config.json(Windows 为 %APPDATA%\caveman\config.jsonXDG_CONFIG_HOME 优先)→ full
禁自动激活 任一层配置写 "off",仍可用 /caveman 手动开启

速查卡的价值在于"一眼可查",而它的每一行都可以在源码里找到对应的实现与测试:模式表对应 VALID_MODESINDEPENDENT_MODES,触发词对应 parseModeChange 的正则族,默认配置对应 getDefaultMode 的四层解析。以 skills/caveman-help/README.md 为索引、skills/caveman-help/SKILL.md 为完整卡片、src/hooks/caveman-config.jssrc/hooks/caveman-parse.js 为实现依据,构成了 caveman-help 从文档到代码的完整证据链。

登录后查看全文
热门项目推荐
相关项目推荐