SuperAPI AI Directory

codex-tmux-echo

Agents & models

View repository

Updated 10-16 02:36

About this skill

codex-tmux-echo

Overview

This skill provides a "general-purpose tmux interaction orchestration toolchain" for reliably controlling any interactive CLI (Codex/Claude Code/REPL/TUI, etc.):

  • Reliably create/reuse tmux sessions (avoid shell initialization prompts stealing input)
  • Send text and key sequences (supports Tab/Enter/Escape+Enter , etc.)
  • Poll and capture pane output, waiting for "ready / progress / done" signatures to appear (avoid relying on sleep N guessing at timing)
  • Supports backchannel return: after the worker finishes, it sends a summary back to the controller's pane (supports two modes: "inject draft only" and "auto-submit as a conversation message")

Note: this skill does not by defaultappend --yolo / --full-auto and other parameters for Codex; whether to enable them is determined by the --cmd passed in by the caller.

⚠️ Risk warning (must read)

The core capability of this skill is tmux send-keys: it can "type" text/keystrokes into any tmux pane. This capability is very powerful, which also meansonce the target is chosen incorrectly, commands may be executed in the wrong window。

Please understand and accept the following risks and boundaries before use:

  • Misdelivery risk (high): if the controller/target is identified incorrectly, the return or keystrokes may land in another pane (or even a production shell).
  • "Keystroke = execution" risk (high):--report-submit keys(especially with Enter) may directly trigger shell execution; only recommended when you clearly know what the controller is and explicitly specify --scheduler-target .
  • Explicit override is more dangerous:--report-submit will override --report-mode 's safety policy; treat it as an "advanced/dangerous switch".
  • Privacy risk of reading screen contents (medium): the script will capture-pane to detect the Codex pane/wait for output; avoid displaying secrets (tokens, private keys, sensitive logs) in the controller pane.
  • worker --cmd is an arbitrary command (high):dispatch.sh will execute the --cmdyou pass in the worker session (the default is codex --no-alt-screen). If you pass in a high-privilege/destructive command, you bear the risk.
  • Risk control is only heuristic (medium):risk-gate only performs simple pattern matching; it is not a security sandbox; it can only "remind/block the first line of defense", and cannot guarantee absolute safety.

Recommended safe usage (strongly advised)

  1. Use a dedicated scheduler pane: open a separate tmux session/window dedicated to running the scheduling-side Codex; do not mix it with your everyday shell pane.
  2. Prefer the default return strategy:--report-mode auto(Codex controller sends automatically; non-Codex automatically degrades to inject-draft-only).
  3. When more stability is needed, explicitly bind the controller pane: dispatch within the scheduler pane; or set CODEX_TMUX_ECHO_CONTROLLER_TARGET; or pass --scheduler-target %<pane_id>。
  4. Unless you clearly know what you are doing, do not use:--report-submit keys --report-keys Enter。

Socket Strategy

--socket auto(default):

  • If you are currently inside tmux (environment variable TMUXexists): reuse the current tmux server (so the worker can send back to your pane)
  • If not in tmux: use an isolated socket (the default path is under ${TMPDIR:-/tmp} ), to avoid polluting the system tmux

Scripts

  • scripts/tmuxctl.sh: tmux controller (new/send/wait/capture/report/whoami)
  • scripts/interactive_runner.sh: general-purpose runner (start worker → send prompt → auto-submit → wait for done)
  • scripts/start_scheduler.sh: one-click start of the "scheduler-side Codex" (system tmux)
  • scripts/dispatch.sh: one-click dispatch of a natural-language task to a worker, and report back to the scheduler side (conversational collaboration; supports automatic identification of the scheduler/controller pane)
  • scripts/codex-tmux-echo: shorter wrapper (treat arguments directly as a natural-language task)
  • scripts/selftest.sh: offline self-test (does not depend on network/account)

Dependencies

  • tmux
  • bash
  • python3(wait subcommands are matched using Python regex, to avoid grep differences)

Command Reference

1) Offline self-test (recommended to run first)

bash scripts/selftest.sh

2) Get the current controller pane (for the scenario where you are inside tmux)

bash scripts/tmuxctl.sh whoami

3) Start a clean shell and send a command

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) General-purpose runner: start any interactive CLI in tmux and send a 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) Recommended workflow: natural-language dispatch (the scheduler side is fixed in system tmux)

  1. Start the scheduler-side Codex:
bash scripts/start_scheduler.sh --socket system --session scheduler --workdir "$PWD"
tmux attach -t scheduler
  1. In the scheduler-side pane (or anywhere that can locate the scheduler-side pane), dispatch a natural-language task to a worker:
bash scripts/codex-tmux-echo 'hello,你好呀'

4.2) Make the skill "globally available" (optional)

If your Skill Runner scans a certain skills directory, you can execute this in the repository root (copy install, do not use symlinks):

SKILLS_DIR=<skills-scan-dir>
mkdir -p "$SKILLS_DIR"
cp -R "$(pwd)/agent/skills/codex-tmux-echo" "$SKILLS_DIR/codex-tmux-echo"

If you also want to turn the dispatch command into a global CLI (codex-tmux-echo), you can copy the wrapper into PATH (for example ~/.local/bin):

mkdir -p ~/.local/bin
cp -f "$SKILLS_DIR/codex-tmux-echo/scripts/codex-tmux-echo" ~/.local/bin/codex-tmux-echo

dispatch.sh by default automatically identifies the scheduler-side controller pane (preferring TMUX_PANE / CODEX_TMUX_ECHO_CONTROLLER_TARGET), therefore usually does not need to specify the session name。

4.1.2) Report-back mode selection (Draft vs Send)

There are two common semantics for report-back:

  • Draft (only injected into the input box/Pane, not automatically sent): more suitable for tasks such as "reports/notifications/requiring manual confirmation", and it will not interrupt a draft currently being edited on the scheduler side.
  • Send (submit as a conversation message): more suitable for scenarios where the result needs to be incorporated into the scheduler-side context, or where two Codex instances need to form conversational collaboration (after the worker reports back, the scheduler side will immediately start processing).

The default behavior is --report-mode auto:

  • If the controller is identified as Codex pane: default Send(otherwise automatic conversational collaboration is impossible).
  • If the controller is not Codex: default Draft(to avoid carrying the assumption that "keypress = execute/send" into general-purpose CLIs and causing accidental execution).

You can specify explicitly:

# 强制仅注入草稿(不自动发送)
bash scripts/codex-tmux-echo --report-mode draft '...'

# 强制提交为对话消息(仅当 controller 是 Codex)
bash scripts/codex-tmux-echo --report-mode send '...'

The report-back text will include source information (to make it easier for the scheduler side to locate the source in follow-up dialogue):

ECHO-REPORT: from=<worker_session> | result=<ok|fail|blocked> | details=<one-line>

4.1.1) Semantic rewriting and risk control (enabled by default)

To avoid passing "scheduler-layer meta-instructions" unchanged to the worker (causing the worker to "start another codex"),dispatch.sh by default will:

  • --normalize auto: try to rewrite "natural language/meta-instructions" into concrete steps the worker can directly execute, and add [我的理解] paragraphs to the prompt.
  • --risk auto: upon encountering high-risk operations (such as sudo, writing to system directories,rm -rf / , etc.) it willfirst report back to the scheduler and block execution。
    • If the scheduler confirms it is allowed, you can dispatch again and add:--risk allow

5) Worker-side backchannel (send a message to the scheduling-side Codex and process it immediately)

If the runner injects the following environment variables:

  • CODEX_TMUX_ECHO_CONTROLLER_TARGET
  • CODEX_TMUX_ECHO_HOME

Then the worker can send back a message at the end of the task (recommended --submit codex, which will attempt to submit and detect that the scheduling side has started processing):

"$CODEX_TMUX_ECHO_HOME/scripts/tmuxctl.sh" report \
  --to "$CODEX_TMUX_ECHO_CONTROLLER_TARGET" \
  --text 'DONE: ok' \
  --submit codex

If you only want to "write + press the key to submit" (without waiting for detection), you can use --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"