name: codex-tmux-echo version: 0.1.13 author: 肆〇柒/ForOhZen description: 用 tmux 稳定驱动交互式 CLI:启动 session、发送按键、等待输出就绪,并支持 worker 向 controller pane 回传结果(backchannel)。
codex-tmux-echo
Overview
这个 skill 提供一套“通用的 tmux 交互编排工具链”,用于稳定控制任意交互式 CLI(Codex/Claude Code/REPL/TUI 等):
- 可靠创建/复用 tmux session(避免 shell 初始化提示抢输入)
- 发送文本与按键序列(支持
Tab/Enter/Escape+Enter等) - 轮询抓取 pane 输出,等待 “ready / progress / done” 特征出现(避免靠
sleep N猜时序) - 支持 backchannel 回传:worker 完成后把摘要回传到 controller 的 pane(支持“仅注入草稿”与“自动提交为对话消息”两种模式)
注意:本 skill 不默认为 Codex 附加
--yolo/--full-auto等参数;是否开启由调用方传入--cmd决定。
⚠️ 风险提示(必读)
本 skill 的核心能力是 tmux send-keys:它可以把文本/按键“打到”任意 tmux pane。这个能力非常强,也意味着一旦 target 选错,就可能在错误窗口里执行命令。
请在使用前理解并接受以下风险与边界:
- 误投递风险(高):如果 controller/target 识别错了,回传或按键可能落到别的 pane(甚至是生产 shell)。
- “按键=执行”风险(高):
--report-submit keys(尤其带Enter)可能直接触发 shell 执行;只有在你明确知道 controller 是什么、并且明确指定--scheduler-target时才建议使用。 - 显式覆盖更危险:
--report-submit会覆盖--report-mode的安全策略;请把它当成“高级/危险开关”。 - 读取屏幕内容的隐私风险(中):脚本会
capture-pane用于探测 Codex pane/等待输出;避免在 controller pane 里显示 secrets(token、私钥、敏感日志)。 - worker
--cmd是任意命令(高):dispatch.sh会在 worker session 里执行你传入的--cmd(默认是codex --no-alt-screen)。如果你传入了高权限/破坏性命令,风险由你承担。 - 风控仅是启发式(中):
risk-gate只做简单模式匹配,不是安全沙盒;它只能“提醒/挡第一道”,不能保证绝对安全。
推荐的安全使用方式(强烈建议)
- 用专用 scheduler pane:单独开一个 tmux session/window 专门跑调度侧 Codex,不要混用你日常的 shell pane。
- 优先使用默认回传策略:
--report-mode auto(Codex controller 自动发送;非 Codex 自动降级为仅注入草稿)。 - 需要更稳时,显式绑定 controller pane:在 scheduler pane 内执行派发;或设置
CODEX_TMUX_ECHO_CONTROLLER_TARGET;或直接传--scheduler-target %<pane_id>。 - 除非你明确知道自己在做什么,否则不要用:
--report-submit keys --report-keys Enter。
Socket Strategy
--socket auto(默认):
- 如果你当前就在 tmux 里(存在环境变量
TMUX):复用当前 tmux server(这样 worker 才能回传到你的 pane) - 如果不在 tmux:使用隔离 socket(默认路径在
${TMPDIR:-/tmp}下),避免污染系统 tmux
Scripts
scripts/tmuxctl.sh:tmux 控制器(new/send/wait/capture/report/whoami)scripts/interactive_runner.sh:通用 runner(启动 worker → 发送 prompt → 自动提交 → 等待 done)scripts/start_scheduler.sh:一键启动“调度侧 Codex”(system tmux)scripts/dispatch.sh:一键派发自然语言任务到 worker,并回传到调度侧(对话式协同;支持自动识别 scheduler/controller pane)scripts/codex-tmux-echo:更短的 wrapper(直接把参数当成自然语言任务)scripts/selftest.sh:离线自测(不依赖网络/账号)
Dependencies
tmuxbashpython3(wait子命令用 Python regex 匹配,规避 grep 差异)
Command Reference
1) 离线自测(推荐先跑)
bash scripts/selftest.sh
2) 获取当前 controller pane(你在 tmux 内的场景)
bash scripts/tmuxctl.sh whoami
3) 启动一个干净 shell 并发送命令
SESSION=demo
bash scripts/tmuxctl.sh --session "$SESSION" new --dir "$(pwd)" --cmd "bash --noprofile --norc"
bash scripts/tmuxctl.sh --target "$SESSION" send --text 'echo READY' --keys 'Enter'
bash scripts/tmuxctl.sh --target "$SESSION" wait --pattern 'READY' --timeout 10
4) 通用 runner:tmux 里启动任意交互式 CLI 并发送 prompt
bash scripts/interactive_runner.sh \
--session tmtest \
--workdir "$PWD" \
--cmd 'codex --dangerously-bypass-approvals-and-sandbox --no-alt-screen' \
--prompt 'hello,你好呀。请在完成后回传 DONE。' \
--wait-pattern 'DONE' \
--timeout 120
4.1) 推荐工作流:自然语言派发(调度侧固定在 system tmux)
- 启动调度侧 Codex:
bash scripts/start_scheduler.sh --socket system --session scheduler --workdir "$PWD"
tmux attach -t scheduler
- 在调度侧 pane 里(或任何能定位到调度侧 pane 的地方)派发自然语言任务到 worker:
bash scripts/codex-tmux-echo 'hello,你好呀'
4.2) 让 skill “全局可用”(可选)
如果你的 Skill Runner 会扫描某个 skills 目录,可以在仓库根目录执行(复制安装,不使用软链接):
SKILLS_DIR=<skills-scan-dir>
mkdir -p "$SKILLS_DIR"
cp -R "$(pwd)/agent/skills/codex-tmux-echo" "$SKILLS_DIR/codex-tmux-echo"
如果你还希望把派发命令变成一个全局 CLI(codex-tmux-echo),可以把 wrapper 复制到 PATH(例如 ~/.local/bin):
mkdir -p ~/.local/bin
cp -f "$SKILLS_DIR/codex-tmux-echo/scripts/codex-tmux-echo" ~/.local/bin/codex-tmux-echo
dispatch.sh 默认会自动识别调度侧 controller pane(优先使用 TMUX_PANE / CODEX_TMUX_ECHO_CONTROLLER_TARGET),因此 通常不需要指定 session 名称。
4.1.2) 回传模式选择(Draft vs Send)
回传有两种常见语义:
- Draft(仅注入到输入框/Pane,不自动发送):更适合“汇报/通知/需要人工确认”的任务,也不会打断调度侧正在编辑的草稿。
- Send(提交为对话消息):更适合需要把结果纳入调度侧上下文、或需要两个 Codex 形成对话协作的场景(worker 回传后调度侧会立即开始处理)。
默认行为为 --report-mode auto:
- 如果 controller 被识别为 Codex pane:默认 Send(否则无法自动对话协作)。
- 如果 controller 不是 Codex:默认 Draft(避免把“按键=执行/发送”的假设带到通用 CLI,造成误执行)。
你可以显式指定:
# 强制仅注入草稿(不自动发送)
bash scripts/codex-tmux-echo --report-mode draft '...'
# 强制提交为对话消息(仅当 controller 是 Codex)
bash scripts/codex-tmux-echo --report-mode send '...'
回传文本会带上来源信息(便于调度侧二次对话定位来源):
ECHO-REPORT: from=<worker_session> | result=<ok|fail|blocked> | details=<one-line>
4.1.1) 语义重写与风控(默认开启)
为避免把“调度层元指令”原封不动传给 worker(导致 worker 去“再启动一个 codex”),dispatch.sh 默认会:
--normalize auto:尽量把“自然语言/元指令”改写成 worker 可直接执行的具体步骤,并在 prompt 中加入[我的理解]段落。--risk auto:遇到高风险操作(如sudo、写系统目录、rm -rf /等)会先回传给调度者并阻断执行。- 如调度者确认允许,可重新派发并加:
--risk allow
- 如调度者确认允许,可重新派发并加:
5) worker 侧回传(backchannel:给调度侧 Codex 发消息并立即处理)
如果 runner 注入了下面这些环境变量:
CODEX_TMUX_ECHO_CONTROLLER_TARGETCODEX_TMUX_ECHO_HOME
那么 worker 可以在任务结束时回传(推荐 --submit codex,会尝试提交并检测调度侧开始处理):
"$CODEX_TMUX_ECHO_HOME/scripts/tmuxctl.sh" report \
--to "$CODEX_TMUX_ECHO_CONTROLLER_TARGET" \
--text 'DONE: ok' \
--submit codex
如果你只想“写入+按键提交”(不等待检测),可以用 --submit keys + --keys "Tab":
"$CODEX_TMUX_ECHO_HOME/scripts/tmuxctl.sh" report \
--to "$CODEX_TMUX_ECHO_CONTROLLER_TARGET" \
--text 'DONE: ok' \
--submit keys \
--keys "Tab"