Skip to content

fix(claude-code): 默认透传 /effort 命令 - #649

Merged
deepcoldy merged 3 commits into
deepcoldy:masterfrom
xiaoxueSunn:fix/claude-effort-passthrough
Jul 29, 2026
Merged

fix(claude-code): 默认透传 /effort 命令#649
deepcoldy merged 3 commits into
deepcoldy:masterfrom
xiaoxueSunn:fix/claude-effort-passthrough

Conversation

@xiaoxueSunn

Copy link
Copy Markdown
Contributor

问题

Claude Code 2.1.220 已原生支持 /effort,但 Botmux 的 Claude Code adapter 默认只透传 /goal。用户从飞书发送 /effort max 时,daemon 因未命中透传集合而把它按普通聊天消息封装,Claude 最终看到的是 <user_message>.../effort max,不会切换推理强度。

改动

  • claude-code variant 的 defaultPassthroughCommands 中加入 /effort
  • 增加回归测试,确认 /effort
    • 不进入全局透传集合;
    • 只对 Claude Code adapter 生效;
    • 不会意外开放给 Codex adapter。

影响面

  • 仅改变 Claude Code adapter 的 slash 路由;Seed 及其它 CLI 不受影响。
  • 未修改公共输入、PTY/tmux、会话恢复或 sandbox 路径。
  • 已存在与新建的 Claude Code 会话都会把 /effort 原样交给底层 CLI;是否接受具体 effort 值仍由 Claude Code 自己校验。

验证

  • 本机 Botmux 3.7.0 实际配置同等透传后,用户在原 Relay-Claude 旧会话验证 /effort/effort max 均生效,不再进入 <user_message>;8/8 个旧 tmux/Claude 会话 PID 保持不变。
  • pnpm vitest run test/command-handler.test.ts:209/209 通过。
  • pnpm build:通过。
  • 全量 unit 初跑在无关的 codex-app-threads 超时用例出现 1 个失败;单文件复跑最终 11/11 通过,改动路径的定向用例持续通过。

@xiaoxueSunn
xiaoxueSunn requested a review from deepcoldy as a code owner July 29, 2026 04:06
@deepcoldy

Copy link
Copy Markdown
Owner

首次 review(Claude)— 🟢 无阻塞,建议可合(待作者/维护者最终确认)

PR 逻辑(白话)

让飞书用户能在对话里直接用 Claude Code 原生 /effort 临时调推理强度。此前 Claude adapter 只透传 /goal,/effort 未命中透传集合 → daemon 把它当普通聊天封进 <user_message>,Claude 只看到"请切 effort"的文字而非真正切档。本 PR 把 defaultPassthroughCommands['/goal']['/goal', '/effort'](1 行)+ 6 行回归测试。

机制核查

  • 透传命中 → raw_input IPC → worker sendRawCommandLineSerially(text→200ms beat→Enter),CLI 原生 slash parser 直接消费 /effort maxparseSlashCommandInvocation 返回 content: trimmed = 完整 /effort max(含前缀+参数),投递无误。
  • botmux 不追踪 effort 状态(全仓 grep 无 effort 状态机),纯透传,无 UI 同步问题。
  • /list-slash-commandresolveAdapterDefaultPassthroughCommands 自动展示 /effort(与 /goal 同段),UI 自动同步,无需额外改。
  • 副作用:/effort 继承 isInitialSessionPassthrough 冷启动能力(空 topic 内 /effort max 可拉起新会话),与 /goal 同款,合理。

前提坐实

  • 本机 claude --version = 2.1.220,与 PR 声明一致;/effort 为原生命令(已实测原生响应 "Set effort level to max")。

关键取舍(认为都正确)

  • Codex 排除正确:codex 的 /effort 走 startupCommands / RPC config(codex-rpc-lifecycle),TUI 语义 ≠ Claude 原生,PR 谨慎只给验证过的 claude-code。测试第 3 条断言 app-2(codex)不含 /effort 守住了这条边界。
  • 与既有 startupCommands 互补:后者是开会话默认档(如 /effort ultracode),本 PR 是运行时临时调档。

实测(独立 worktree,不触 live)

  • pnpm build:✅ 绿
  • pnpm vitest run test/command-handler.test.ts:✅ 209/209
  • 新测试隔离单跑:✅ 通过
  • 变异测试:将改动回退为 ['/goal'] 后,新测试如期失败(expected false to be true)→ 测试真实有效,非假阳性
  • origin/master merge-tree:✅ 无冲突(改动两文件在 base→master 间无交集)

唯一可议(非阻塞,至多 P3)

seed / relay(含 hermes)同为 Claude Code fork、同样支持 /effort,但被 variant.id === 'claude-code' 精确排除 → 这些 bot 的用户发 /effort 仍落入 <user_message>。这属既有 /goal 的同款保守 scoping,非本 PR 引入的回归,后续如需扩展可另议。


已请 @codex 复审(重点:① raw_input 投递 /effort max 的 beat/Enter 时序在 pty 与 tmux 后端是否都稳;② seed/relay 排除是否顺手放开)。在维护者(申晗)明确确认前不合码。

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@deepcoldy

Copy link
Copy Markdown
Owner

补充实证:seed/relay 也原生支持 /effort(与 /goal)—— 建议门放宽到 Claude 家族级

复审讨论中 @codex 提出「seed/relay 是否值得顺手开放 /effort」。我做了本机 bundle 直查,证据链已齐:

1. seed/relay 就是 Claude Code 的同源 rebrand

  • realpath $(which relay)@bytedance-relay/claude-code/dist/cli.js
  • realpath $(which seed)@bytedance-seed/claude-code/dist/cli.js

2. 两个 bundle 都含 /effort slash + 完整 effort 状态机

  • /effort 字面各出现 2 次;EffortConfig×8、effortChanged×2、EffortCallout×11 等
  • 决定性证据:relay bundle 内含 /effort 触发后喂给模型的系统提示模板 —— The user has requested reasoning effort level: ${attachment.level}. Apply this to the current turn.

3. 顺带发现:relay bundle 里 /goal 也是原生的(上下文 e.g. /goal Follow PLAN.md until the test suite is green)。

一个易踩的坑:真 Claude Code 2.1.220 的 bundle 是 minified,/effort / EffortConfig 字面 grep = 0 —— 不能用"字面计数"对照三者。claude 支持 /effort 的活证据是原生执行(/effort max → "Set effort level to max");relay/seed 靠 bundle 保留的可读字面自证。

结论

当前 variant.id === 'claude-code' 这道门把 seed/relay 排除,导致这两个同源 fork /goal 都吃不到(不止 /effort)—— 这是既有缺口,本 PR 顺手可补。最小改:

- defaultPassthroughCommands: variant.id === 'claude-code' ? ['/goal', '/effort'] : undefined,
+ // /goal 与 /effort 均为 Claude Code 原生 slash;seed/relay 是同源 rebrand
+ // (@bytedance-*/claude-code),bundle 内均含 /effort 命令 + reasoning-effort
+ // 系统提示模板,整个家族一致放行。
+ defaultPassthroughCommands: ['/goal', '/effort'],

配一条测试断言(relay/seed 也含 /goal+/effort)即可。零风险。

⚠️ 注意勿与相邻同写法的 buildSessionRenameCommand 窄门混为一谈:那道窄是因为 "seed native rename 未验证"(真·不确定);而 /effort+/goal 的支持性已由上述实证消除不确定性,两者不应绑定。

范围决策:本 PR 按原范围(仅 claude-code)已可合、无阻塞;是否在本 PR 顺手放宽到家族级,属范围决策,交作者 / 维护者拍板。

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@deepcoldy

Copy link
Copy Markdown
Owner

双审收敛结论(Claude 首审 + Codex 复审)—— 🟢 无阻塞,建议可合;范围待维护者拍板

两名 reviewer 已就本 PR(head 3bda1cb5)完全收敛。均未执行批准 / 合并,等维护者(申晗)明确确认。

一致结论

raw_input 投递 /effort max 时序无风险

  • 链路:parseSlashCommandInvocation(返回 trim 后完整 /effort max)→ daemon raw_input → worker sendRawCommandLineSerially
  • PTY:write('/effort max') → 200ms → CR;生产 tmux 路径 TmuxPipe:literal send-keys '/effort max' → 200ms → Enter。共用命令行写入 mutex;restart / rename / TUI injection / cwd barrier / 启动 settle 等既有 gate 均仍生效。
  • Codex 用真实 PtyBackend + TmuxPipeBackend 各跑一次行接收探针,两端精确收到 GOT</effort max>。这 1 行 adapter 配置未引入 backend 时序分叉。

② 前提坐实:本机 claude --version = 2.1.220,/effort 为原生命令(实测原生执行)。

③ 风险刻画(两点修正,双审一致):

  • "零风险"措辞过强,已收回。准确表述:改动本身在代码路径上无副作用。
  • 残留的是版本漂移兼容性——装了旧版 CLI 的用户收到不认识的 slash,最坏退化为 unknown-command UX,不涉崩溃 / 状态破坏 / 安全边界。
  • 该兼容性条件对 claude-code / seed / relay 对称共享,并非"放宽家族门"新增,也非 seed/relay 独有;PR 当前范围同样承载它。

待维护者拍板:范围 A / B

双审均发现既有缺口——seed/relay 是 Claude Code 同源 rebrand(@bytedance-*/claude-code,本机 Seed 2.7.0 / Relay 3.2.10 bundle 均含完整 /effort 实现;仓库 seed.ts/relay.ts 亦声明与 Claude Code flags/slash 相同并复用整个 Claude-family adapter)。当前 variant.id === 'claude-code' 窄门把它们排除 → seed/relay 用户/goal 都吃不到(不止 /effort)。

  • B(双审倾向):本 PR 顺手把门放宽到家族级 ['/goal', '/effort'],补 seed/relay adapter 测试断言 + 各做一次真实 CLI 验证。改动仍小,语义更完整,一并补掉 seed/relay 的 /goal 缺口。增量风险定为
  • A(可接受):保持当前"只修 claude-code"的明确范围直接合,seed/relay 单开 follow-up。因当前 PR 未制造其回归,属非阻塞 P3 建议。

Hermes 0.19 是独立 hermes.ts adapter(非 Claude-family),不应在本次一起开放

复审侧实测(Codex)

  • pnpm build:通过
  • 相关 6 个测试文件:301/301 通过
  • pnpm test 全量 unit:722 files / 11096 tests passed(1 file / 5 tests skipped)
  • 真实 PTY + TmuxPipe /effort max 输入探针:两端通过
  • git diff --check:通过
  • 未切换 checkout、未重启 live daemon。

范围(A/B)与合并授权交维护者拍板。在明确确认前,两名 reviewer 均不合码。

原改动把 /effort 加进 claude-code adapter 的 defaultPassthroughCommands,
只对 Claude Code 生效。按维护者要求「全局放开、其它 CLI 早晚也支持」,改为
把 /effort 提升到全局 PASSTHROUGH_COMMANDS 集合,并把它从 adapter 层移除。

为什么放全局而非逐 adapter 加:
- 一处改动,所有 CLI(含未来新增)自动继承 —— 前向兼容「早晚都支持」;
  全局集合本就是「尽力透传」语义(/plugin /mcp /btw 也非所有 CLI 支持),
  CLI 认得就生效、认不得顶多回 unknown-command(不崩溃/不损坏/不泄露)。
- 冷启动语义更干净:isInitialSessionPassthrough 只认 adapter 层的
  defaultPassthroughCommands,不认全局集合。/effort 是「调档」而非「开一段
  工作」的命令,进全局天然不获得空 topic 冷启动能力(空话题单发 /effort
  不会凭空拉起会话)。/goal 仍留在 adapter 层,保留其冷启动语义。

影响面:
- 仅改 slash 路由的命令归属(adapter 层 → 全局集合);未动公共输入、
  PTY/tmux 投递、会话恢复、sandbox 路径。
- Claude Code(2.1.220+)/ Seed / Relay 原生支持 /effort;Codex 亦有
  reasoning effort。其它 CLI 无此命令时最坏为 unknown-command UX。
- 已知 pre-existing 非阻塞点:codex 若开 hybrid RPC 模式(默认关),
  raw_input 会被纯 viewer pane 静默吞掉 —— 但现有 /goal /btw /model 同样
  走此路径,本改动只是把既有 gap 多扩一个命令,非新问题、不崩溃。

验证:
- pnpm build 通过。
- pnpm vitest run test/command-handler.test.ts:209/209 通过。
- 测试更新:`enables /effort only for the Claude Code adapter` 重写为
  `exposes /effort globally to every CLI`(app-1/app-2/无 bot 均含 /effort);
  `should contain expected slash commands` 加入 /effort。
- 变异测试:删除全局 /effort 后新测试如期失败,证断言有效。

Co-Authored-By: Riff <noreply@riff.dev>
@deepcoldy

Copy link
Copy Markdown
Owner

已按维护者决策改为「全局放开」并推送(head 16e38cf6)

维护者(申晗)拍板:/effort 全局放开给所有 CLI(「其它 CLI 早晚也支持」),并授权直接在本 PR 上修改。已推送新 commit 16e38cf6,将方案从 adapter 层加 改为 全局提升

改动(相对原 head 3bda1cb5)

  • src/core/passthrough-commands.ts:/effort 加入全局 PASSTHROUGH_COMMANDS 集合(与 /compact /model /context 同级)。
  • src/adapters/cli/claude-code.ts:claude-code adapter 的 defaultPassthroughCommands['/goal', '/effort'] 回退为 ['/goal'](/effort 已上升到全局,不再 adapter-scoped)。
  • test/command-handler.test.ts:enables /effort only for the Claude Code adapter 重写为 exposes /effort globally to every CLI(app-1/app-2/无 bot 均含 /effort);should contain expected slash commands 加入 /effort

为什么放全局而非逐 adapter 加

  1. 一处改动,所有 CLI(含未来新增)自动继承 —— 正是「早晚都支持」的前向兼容。全局集合本就是「尽力透传」语义(/plugin /mcp /btw 也并非所有 CLI 支持),CLI 认得就生效、认不得顶多回 unknown-command(不崩溃 / 不损坏 / 不泄露)。
  2. 冷启动语义更干净:isInitialSessionPassthrough(daemon.ts)只认 adapter 层的 defaultPassthroughCommands,不认全局集合。/effort 是「调档」而非「开一段工作」的命令,进全局天然不获得空 topic 冷启动能力(空话题单发 /effort 不会凭空拉起会话)。而原 adapter 层写法会让 /effort 获得冷启动能力(为设 effort 而 spawn 空会话)。/goal 仍留在 adapter 层,保留其冷启动语义。

影响面

  • 仅改 slash 路由的命令归属(adapter 层 → 全局集合);未动公共输入、PTY/tmux 投递、会话恢复、sandbox 路径。
  • Claude Code(2.1.220+)/ Seed / Relay 原生支持 /effort;Codex 亦有 reasoning effort。其它 CLI 无此命令时最坏为 unknown-command UX。
  • 已知 pre-existing 非阻塞点:codex 若开 hybrid RPC 模式(默认关),raw_input 会被纯 viewer pane 静默吞掉 —— 但现有 /goal /btw /model 同样走此路径,本改动只是把既有 gap 多扩一个命令,非新问题、不崩溃。

验证

  • pnpm build:通过。
  • pnpm vitest run test/command-handler.test.ts:209/209 通过。
  • 变异测试:删除全局 /effort 后新测试如期失败(expected false to be true),证断言有效。
  • 独立第二 agent 盲审 8 项(冷启动 / 权限门 / 展示 / DAEMON 冲突 / codex RPC / 隐藏语义 / 测试 / 去重):全 CLEAN,无阻塞。

已请 @codex 复审全局方案。维护者已授权:codex 复审通过即合码。

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

采纳 codex 复审建议补强。原有 `/effort` 测试只断言「全局可见」
(resolvePassthroughCommands 各 CLI 都含 /effort),但锁不住本次核心语义:
/effort 必须留在全局 PASSTHROUGH_COMMANDS、绝不进 adapter 层的
defaultPassthroughCommands —— 因为冷启动能力(空 topic 里发命令能否拉起
新会话)只认 adapter 层(见 isInitialSessionPassthrough →
resolveAdapterDefaultPassthroughCommands),不认全局集合。

盲区:若日后有人误把 /effort 加回某 adapter 的 default,全局也有 /effort,
resolvePassthroughCommands 层的可见性断言仍会全绿,回归无人察觉。

新增 `keeps /effort OUT of the adapter default layer` 直接断言
resolveAdapterDefaultPassthroughCommands('app-1'/'app-2') 不含 /effort、
但含 /goal(/goal 是「开启目标工作」命令,刻意保留 adapter 层冷启动语义)。

验证(变异测试确认护栏有效):
- 把 /effort 误加回 claude-code adapter default 后:
  · 旧「全局可见」测试仍全绿(证明它抓不住该回归);
  · 新护栏测试如期失败(证明它精确锁住语义)。
- pnpm build 通过;pnpm vitest run test/command-handler.test.ts:210/210 通过。

Co-Authored-By: Riff <noreply@riff.dev>
@deepcoldy

Copy link
Copy Markdown
Owner

补强推送:锁住「/effort 不进 adapter 层冷启动」的语义护栏(head → 77d30c69)

采纳 @codex 复审建议。原 /effort 测试只断言「全局可见」,锁不住本次核心语义 —— 遂新增一条直接护栏。

新增 commit 77d30c69(test/command-handler.test.ts,+16/-1)

新增 keeps /effort OUT of the adapter default layer so it never gains cold-start:

expect(resolveAdapterDefaultPassthroughCommands('app-1')).not.toContain('/effort'); // claude-code
expect(resolveAdapterDefaultPassthroughCommands('app-2')).not.toContain('/effort'); // codex
expect(resolveAdapterDefaultPassthroughCommands('app-1')).toContain('/goal');
expect(resolveAdapterDefaultPassthroughCommands('app-2')).toContain('/goal');

为什么需要这条(codex 指出的盲区)

冷启动能力(空 topic 发命令能否拉起新会话)只认 adapter 层 defaultPassthroughCommands(isInitialSessionPassthroughresolveAdapterDefaultPassthroughCommands),不认全局 PASSTHROUGH_COMMANDS。若日后有人误把 /effort 加回某 adapter 的 default,全局也有 /effort,resolvePassthroughCommands 层的可见性断言仍会全绿 —— 回归无人察觉。唯有直接断言 adapter 层不含 /effort 能锁住语义。

变异测试确认护栏有效

/effort 误加回 claude-code adapter default 后:

  • 旧「全局可见」测试仍全绿(证明它抓不住该回归);
  • 新护栏测试如期失败(证明它精确锁住语义)。

验证

  • pnpm build:通过。
  • pnpm vitest run test/command-handler.test.ts:210/210 通过(护栏使 command-handler 从 209 → 210)。
  • 全量 unit 唯一失败为无关的 group-join-shared-routing.beforeAll 10s 超时(pre-existing flaky,隔离复跑 5/5 通过),非本改动引入。

PR 当前 head:77d30c69(= 3bda1cb5 原 PR + 16e38cf6 全局提升 + 77d30c69 护栏)。已请 codex 核对远端 patch / build / mergeability 后给最终结论。

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@deepcoldy
deepcoldy merged commit 12bf0f3 into deepcoldy:master Jul 29, 2026
@deepcoldy

Copy link
Copy Markdown
Owner

✅ 已合并 — merge commit 12bf0f36

按维护者(申晗)授权 + @codex 最终 APPROVE 执行 admin-merge(REST core API,graphql 侧限额中)。merged_at: 2026-07-29T08:45:20Z,state: closed。

最终落地 master 的三个 commit

  1. 3bda1cb5 fix(claude-code): 默认透传 /effort 命令(原 PR,作者 @xiaoxueSunn)
  2. 16e38cf6 refactor(command-handler): /effort 改由全局 PASSTHROUGH_COMMANDS 放开给所有 CLI
  3. 77d30c69 test(command-handler): 锁住 /effort 不进 adapter 层的冷启动语义护栏

采用 merge commit(非 squash)保留三 commit 原始归属,与本仓 PR 合并习惯一致。

最终形态

  • /effort 位于全局 PASSTHROUGH_COMMANDS → 所有 CLI 尽力透传(Claude 家族/Codex 原生支持;其它 CLI 认不得回 unknown-command,不崩溃);未来新 CLI 零改动自动继承。
  • claude-code adapter defaultPassthroughCommands = ['/goal'];/effort 不在 adapter 层,故不获空 topic 冷启动能力(/goal 保留)。

codex 最终验证(head 77d30c69)

  • SHA 一致;mergeable=true;master + PR 临时合并无冲突。
  • 合并树 pnpm build 通过;相关 6 文件 311/311(含 command-handler 210/210);git diff --check 通过。
  • 全量 unit 唯一失败为无关 group-join-shared-routing.beforeAll 10s 负载超时(pre-existing flaky,隔离复跑 5/5),其余 721 files / 11090 tests 通过。

后续

  • 未发版、未上 live。本次仅合入 master。
  • ⚠️ 改动涉及 worker/命令路由,要在 live 生效需 pnpm switch:here && pnpm daemon:restart(由维护者按需决定)。

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants