driving-claude-code-sessions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Driving Claude Code Sessions

管控Claude Code会话

Overview

概述

You can launch other Claude Code sessions as "workers" in tmux, send them prompts, monitor their progress through lifecycle events, read their output, and hand them off to a human operator. This gives you the ability to delegate work, run tasks in parallel, or set up supervised workflows.
Workers are full interactive Claude Code sessions launched with
--dangerously-skip-permissions
so they never block on interactive permission prompts. A plugin (claude-session-driver) injects hooks that emit lifecycle events to a JSONL file, which you poll to track worker state. A PreToolUse hook gives the controller a window to inspect and approve or deny every tool call before it executes. The scripts handle all the plumbing: tmux management, session IDs, event files, and cleanup.
你可以在tmux中启动其他Claude Code会话作为“worker”,向其发送提示词,通过生命周期事件监控进度,读取输出内容,还可以将其交接给人工操作员。这让你能够委派工作、并行运行任务或搭建受监督的工作流。
Worker是通过
--dangerously-skip-permissions
参数启动的完整交互式Claude Code会话,因此它们不会因交互式权限提示而停滞。一个名为claude-session-driver的插件会注入钩子,将生命周期事件输出到JSONL文件,你可以轮询该文件来跟踪worker状态。PreToolUse钩子让管控者能够在工具执行前检查并批准或拒绝每一次工具调用。相关脚本会处理所有底层工作:tmux管理、会话ID、事件文件以及清理工作。

Prerequisites

前提条件

These must be available on the system:
  • tmux - for running worker sessions in detached terminals
  • jq - for parsing JSON output from scripts and event files
  • claude CLI - the Claude Code binary
系统中必须安装以下工具:
  • tmux - 用于在后台终端运行worker会话
  • jq - 用于解析脚本和事件文件的JSON输出
  • claude CLI - Claude Code的二进制执行文件

Setup

配置步骤

All scripts live at
../../scripts/
relative to this skill's base directory. Set a convenience variable:
bash
SCRIPTS="<this-skill's-base-directory>/plugin/scripts"
所有脚本位于此技能基础目录的
../../scripts/
路径下。可以设置一个便捷变量:
bash
SCRIPTS="<this-skill's-base-directory>/plugin/scripts"

Workflow

工作流

1. Launch a Worker

1. 启动Worker

bash
RESULT=$("$SCRIPTS/launch-worker.sh" my-worker /path/to/project)
SESSION_ID=$(echo "$RESULT" | jq -r '.session_id')
TMUX_NAME=$(echo "$RESULT" | jq -r '.tmux_name')
The script:
  • Creates a detached tmux session named
    my-worker
  • Starts
    claude
    with the session-driver plugin loaded and
    --dangerously-skip-permissions
  • Waits for the
    session_start
    event (up to 30s)
  • Returns JSON with
    session_id
    ,
    tmux_name
    , and
    events_file
Permission bypass is automatic. The worker's PreToolUse hook provides controller-based gating (see Tool Approval below), so the built-in interactive permission dialog is redundant.
Pass extra
claude
CLI arguments after the working directory:
bash
undefined
bash
RESULT=$("$SCRIPTS/launch-worker.sh" my-worker /path/to/project)
SESSION_ID=$(echo "$RESULT" | jq -r '.session_id')
TMUX_NAME=$(echo "$RESULT" | jq -r '.tmux_name')
该脚本会:
  • 创建名为
    my-worker
    的后台tmux会话
  • 加载session-driver插件并通过
    --dangerously-skip-permissions
    参数启动
    claude
  • 等待
    session_start
    事件(最多等待30秒)
  • 返回包含
    session_id
    tmux_name
    events_file
    的JSON数据
权限绕过是自动的。Worker的PreToolUse钩子提供了基于管控者的权限控制(见下文的工具批准),因此内置的交互式权限对话框是多余的。
可以在工作目录后添加额外的
claude
CLI参数:
bash
undefined

Use a specific model

使用指定模型

RESULT=$("$SCRIPTS/launch-worker.sh" my-worker /path/to/project --model sonnet)
undefined
RESULT=$("$SCRIPTS/launch-worker.sh" my-worker /path/to/project --model sonnet)
undefined

2. Converse (Preferred)

2. 对话交互(推荐方式)

For most interactions, use
converse.sh
— it sends the prompt, waits for the worker to finish, and returns the assistant's response in one call:
bash
RESPONSE=$("$SCRIPTS/converse.sh" my-worker "$SESSION_ID" "Refactor the auth module to use JWT tokens" 300)
echo "$RESPONSE"
It handles
--after-line
tracking automatically, so multi-turn conversations just work:
bash
R1=$("$SCRIPTS/converse.sh" my-worker "$SESSION_ID" "Write tests for the auth module" 300)
R2=$("$SCRIPTS/converse.sh" my-worker "$SESSION_ID" "Now add edge case tests for expired tokens" 300)
对于大多数交互场景,使用
converse.sh
——它会发送提示词,等待worker完成任务,并一次性返回助手的响应:
bash
RESPONSE=$("$SCRIPTS/converse.sh" my-worker "$SESSION_ID" "重构认证模块以使用JWT令牌" 300)
echo "$RESPONSE"
它会自动处理
--after-line
跟踪,因此多轮对话可以直接生效:
bash
R1=$("$SCRIPTS/converse.sh" my-worker "$SESSION_ID" "为认证模块编写测试用例" 300)
R2=$("$SCRIPTS/converse.sh" my-worker "$SESSION_ID" "现在添加针对过期令牌的边缘情况测试" 300)

3. Send a Prompt (Low-Level)

3. 发送提示词(底层方式)

For finer control, use the individual scripts.
send-prompt.sh
sends text without waiting:
bash
"$SCRIPTS/send-prompt.sh" my-worker "Refactor the auth module to use JWT tokens"
如需更精细的控制,可以使用独立脚本。
send-prompt.sh
会发送文本但不等待结果:
bash
"$SCRIPTS/send-prompt.sh" my-worker "重构认证模块以使用JWT令牌"

4. Wait for the Worker to Finish

4. 等待Worker完成任务

bash
"$SCRIPTS/wait-for-event.sh" "$SESSION_ID" stop 300
This blocks until the worker emits a
stop
event (meaning it finished processing and is waiting for input) or the timeout (in seconds) expires. Exit code 0 means the event arrived; exit code 1 means timeout.
The matching event JSON line is printed to stdout:
json
{"ts":"2025-01-15T10:30:00Z","event":"stop"}
bash
"$SCRIPTS/wait-for-event.sh" "$SESSION_ID" stop 300
该命令会阻塞直到worker发出
stop
事件(表示已完成处理并等待输入)或超时(以秒为单位)。退出码0表示事件已触发;退出码1表示超时。
匹配的事件JSON行会输出到标准输出:
json
{"ts":"2025-01-15T10:30:00Z","event":"stop"}

5. Read Worker Events

5. 读取Worker事件

bash
undefined
bash
undefined

All events

读取所有事件

"$SCRIPTS/read-events.sh" "$SESSION_ID"
"$SCRIPTS/read-events.sh" "$SESSION_ID"

Last 3 events

读取最后3个事件

"$SCRIPTS/read-events.sh" "$SESSION_ID" --last 3
"$SCRIPTS/read-events.sh" "$SESSION_ID" --last 3

Only stop events

仅读取stop事件

"$SCRIPTS/read-events.sh" "$SESSION_ID" --type stop
"$SCRIPTS/read-events.sh" "$SESSION_ID" --type stop

Follow in real-time (blocks -- run in background Bash job for monitoring)

实时跟踪(会阻塞——在后台Bash作业中运行以进行监控)

"$SCRIPTS/read-events.sh" "$SESSION_ID" --follow & MONITOR_PID=$!
"$SCRIPTS/read-events.sh" "$SESSION_ID" --follow & MONITOR_PID=$!

... do other work ... then stop monitoring:

... 执行其他工作 ... 然后停止监控:

kill $MONITOR_PID 2>/dev/null

Event types emitted by the plugin:
| Event | Meaning | Extra fields |
|-------|---------|-------------|
| `session_start` | Worker session initialized | `cwd` |
| `user_prompt_submit` | A prompt was submitted to the worker | |
| `pre_tool_use` | Worker is about to call a tool | `tool`, `tool_input` |
| `stop` | Worker finished processing, waiting for input | |
| `session_end` | Worker session terminated | |
kill $MONITOR_PID 2>/dev/null

插件输出的事件类型:
| 事件 | 含义 | 额外字段 |
|-------|---------|-------------|
| `session_start` | Worker会话已初始化 | `cwd` |
| `user_prompt_submit` | 已向worker提交提示词 | |
| `pre_tool_use` | Worker即将调用工具 | `tool`, `tool_input` |
| `stop` | Worker完成处理,等待输入 | |
| `session_end` | Worker会话已终止 | |

6. Read Worker Conversation Log

6. 读取Worker对话日志

The worker's full conversation (prompts and responses) is stored in Claude's JSONL session log. The path uses an encoded form of the working directory where
/
becomes
-
with a leading
-
:
  • /Users/jesse/myproject
    encodes to
    -Users-jesse-myproject
The log is at:
~/.claude/projects/<encoded-path>/<session-id>.jsonl
To read the last assistant response:
bash
ENCODED_PATH=$(echo "/path/to/project" | sed 's|/|-|g')
LOG_FILE=~/.claude/projects/${ENCODED_PATH}/${SESSION_ID}.jsonl
grep '"type":"assistant"' "$LOG_FILE" | tail -1 | jq -r '.message.content[] | select(.type=="text") | .text'
Worker的完整对话记录(提示词和响应)存储在Claude的JSONL会话日志中。日志路径使用工作目录的编码形式,其中
/
会被替换为
-
并添加前缀
-
  • /Users/jesse/myproject
    会编码为
    -Users-jesse-myproject
日志路径为:
~/.claude/projects/<encoded-path>/<session-id>.jsonl
读取最后一条助手响应:
bash
ENCODED_PATH=$(echo "/path/to/project" | sed 's|/|-|g')
LOG_FILE=~/.claude/projects/${ENCODED_PATH}/${SESSION_ID}.jsonl
grep '"type":"assistant"' "$LOG_FILE" | tail -1 | jq -r '.message.content[] | select(.type=="text") | .text'

7. Stop a Worker

7. 停止Worker

bash
"$SCRIPTS/stop-worker.sh" my-worker "$SESSION_ID"
The script:
  • Sends
    /exit
    to the tmux session
  • Waits up to 10s for a
    session_end
    event
  • Kills the tmux session if still running
  • Cleans up event and metadata files in
    /tmp/claude-workers/
bash
"$SCRIPTS/stop-worker.sh" my-worker "$SESSION_ID"
该脚本会:
  • 向tmux会话发送
    /exit
    命令
  • 最多等待10秒以获取
    session_end
    事件
  • 如果会话仍在运行则终止tmux会话
  • 清理
    /tmp/claude-workers/
    下的事件和元数据文件

8. Hand Off to a Human

8. 交接给人工操作员

If you want a human to take over an active worker session:
The worker is running in tmux session 'my-worker'. You can:
- Watch live: tmux attach -t my-worker
- Take over: just start typing in the attached session
- Return to me: detach with Ctrl-B d
Leave the worker running. Do not stop it when handing off.
如果你想让人工接管活跃的worker会话:
Worker正在tmux会话'my-worker'中运行。你可以:
- 实时查看:tmux attach -t my-worker
- 接管会话:在附加的会话中直接输入内容
- 返回给我:按下Ctrl-B d分离会话
交接时请保持worker运行状态,不要停止它。

Script Reference

脚本参考

ScriptUsageDescription
converse.sh
<tmux-name> <session-id> <prompt> [timeout=120]
Send prompt, wait, return response
launch-worker.sh
<tmux-name> <working-dir> [claude-args...]
Start a worker session
send-prompt.sh
<tmux-name> <prompt-text>
Send a prompt to a worker
wait-for-event.sh
<session-id> <event-type> [timeout=60] [--after-line N]
Block until event or timeout
read-events.sh
<session-id> [--last N] [--type T] [--follow]
Read event stream
stop-worker.sh
<tmux-name> <session-id>
Gracefully stop and clean up
approve-tool.sh
<session-id> <allow|deny>
Respond to a pending tool approval
read-turn.sh
<session-id> [--full]
Format last turn as markdown
All scripts exit 0 on success, non-zero on failure. Error messages go to stderr.
脚本使用方式描述
converse.sh
<tmux-name> <session-id> <prompt> [timeout=120]
发送提示词,等待结果,返回响应
launch-worker.sh
<tmux-name> <working-dir> [claude-args...]
启动worker会话
send-prompt.sh
<tmux-name> <prompt-text>
向worker发送提示词
wait-for-event.sh
<session-id> <event-type> [timeout=60] [--after-line N]
阻塞直到事件触发或超时
read-events.sh
<session-id> [--last N] [--type T] [--follow]
读取事件流
stop-worker.sh
<tmux-name> <session-id>
优雅停止并清理会话
approve-tool.sh
<session-id> <allow|deny>
响应待处理的工具批准请求
read-turn.sh
<session-id> [--full]
将最后一轮对话格式化为markdown
所有脚本成功时返回0,失败时返回非0值。错误信息输出到标准错误流。

Common Patterns

常见模式

Single Worker: Delegate and Wait

单Worker:委派并等待

bash
RESULT=$("$SCRIPTS/launch-worker.sh" task-worker ~/myproject)
SESSION_ID=$(echo "$RESULT" | jq -r '.session_id')

"$SCRIPTS/send-prompt.sh" task-worker "Run the test suite and fix any failures"
"$SCRIPTS/wait-for-event.sh" "$SESSION_ID" stop 600
bash
RESULT=$("$SCRIPTS/launch-worker.sh" task-worker ~/myproject)
SESSION_ID=$(echo "$RESULT" | jq -r '.session_id')

"$SCRIPTS/send-prompt.sh" task-worker "运行测试套件并修复所有失败用例"
"$SCRIPTS/wait-for-event.sh" "$SESSION_ID" stop 600

Read what happened, then clean up

查看执行结果,然后清理

"$SCRIPTS/read-events.sh" "$SESSION_ID" "$SCRIPTS/stop-worker.sh" task-worker "$SESSION_ID"
undefined
"$SCRIPTS/read-events.sh" "$SESSION_ID" "$SCRIPTS/stop-worker.sh" task-worker "$SESSION_ID"
undefined

Fan-Out: Multiple Workers in Parallel

扇出模式:多Worker并行

bash
undefined
bash
undefined

Launch workers for different tasks

为不同任务启动worker

R1=$("$SCRIPTS/launch-worker.sh" worker-api ~/myproject) S1=$(echo "$R1" | jq -r '.session_id')
R2=$("$SCRIPTS/launch-worker.sh" worker-ui ~/myproject) S2=$(echo "$R2" | jq -r '.session_id')
R1=$("$SCRIPTS/launch-worker.sh" worker-api ~/myproject) S1=$(echo "$R1" | jq -r '.session_id')
R2=$("$SCRIPTS/launch-worker.sh" worker-ui ~/myproject) S2=$(echo "$R2" | jq -r '.session_id')

Send each their task

为每个worker分配任务

"$SCRIPTS/send-prompt.sh" worker-api "Add pagination to the /users endpoint" "$SCRIPTS/send-prompt.sh" worker-ui "Add a loading spinner to the user list page"
"$SCRIPTS/send-prompt.sh" worker-api "为/users端点添加分页功能" "$SCRIPTS/send-prompt.sh" worker-ui "为用户列表页面添加加载动画"

Wait for both (sequentially -- first one to finish unblocks its wait)

等待所有worker完成(按顺序——第一个完成的会解除阻塞)

"$SCRIPTS/wait-for-event.sh" "$S1" stop 600 "$SCRIPTS/wait-for-event.sh" "$S2" stop 600
"$SCRIPTS/wait-for-event.sh" "$S1" stop 600 "$SCRIPTS/wait-for-event.sh" "$S2" stop 600

Clean up

清理资源

"$SCRIPTS/stop-worker.sh" worker-api "$S1" "$SCRIPTS/stop-worker.sh" worker-ui "$S2"
undefined
"$SCRIPTS/stop-worker.sh" worker-api "$S1" "$SCRIPTS/stop-worker.sh" worker-ui "$S2"
undefined

Pipeline: Chained Workers

流水线模式:链式Worker

Pass one worker's output to the next:
bash
undefined
将一个worker的输出传递给下一个:
bash
undefined

Worker 1: Generate an API spec

Worker 1:生成API规格

R1=$("$SCRIPTS/launch-worker.sh" worker-spec ~/myproject) S1=$(echo "$R1" | jq -r '.session_id') "$SCRIPTS/send-prompt.sh" worker-spec "Generate an OpenAPI spec for the users endpoint and save it to /tmp/api-spec.yaml" "$SCRIPTS/wait-for-event.sh" "$S1" stop 300
R1=$("$SCRIPTS/launch-worker.sh" worker-spec ~/myproject) S1=$(echo "$R1" | jq -r '.session_id') "$SCRIPTS/send-prompt.sh" worker-spec "为用户端点生成OpenAPI规格并保存到/tmp/api-spec.yaml" "$SCRIPTS/wait-for-event.sh" "$S1" stop 300

Worker 2: Implement from the spec that Worker 1 produced

Worker 2:基于Worker 1生成的规格实现功能

R2=$("$SCRIPTS/launch-worker.sh" worker-impl ~/myproject) S2=$(echo "$R2" | jq -r '.session_id') "$SCRIPTS/send-prompt.sh" worker-impl "Implement the API endpoint defined in /tmp/api-spec.yaml" "$SCRIPTS/wait-for-event.sh" "$S2" stop 600
R2=$("$SCRIPTS/launch-worker.sh" worker-impl ~/myproject) S2=$(echo "$R2" | jq -r '.session_id') "$SCRIPTS/send-prompt.sh" worker-impl "实现/tmp/api-spec.yaml中定义的API端点" "$SCRIPTS/wait-for-event.sh" "$S2" stop 600

Clean up both

清理两个worker

"$SCRIPTS/stop-worker.sh" worker-spec "$S1" "$SCRIPTS/stop-worker.sh" worker-impl "$S2"

The key: workers communicate through files on disk. The controller orchestrates the sequence.
"$SCRIPTS/stop-worker.sh" worker-spec "$S1" "$SCRIPTS/stop-worker.sh" worker-impl "$S2"

核心要点:worker通过磁盘上的文件进行通信,管控者负责编排执行顺序。

Supervised: Multi-Turn Conversation

受监督模式:多轮对话

converse.sh
handles
--after-line
tracking automatically, so multi-turn is straightforward:
bash
RESULT=$("$SCRIPTS/launch-worker.sh" supervised ~/myproject)
SESSION_ID=$(echo "$RESULT" | jq -r '.session_id')

R1=$("$SCRIPTS/converse.sh" supervised "$SESSION_ID" "Write tests for the auth module" 300)
R2=$("$SCRIPTS/converse.sh" supervised "$SESSION_ID" "Now add edge case tests for expired tokens" 300)

"$SCRIPTS/stop-worker.sh" supervised "$SESSION_ID"
converse.sh
会自动处理
--after-line
跟踪,因此多轮对话非常简单:
bash
RESULT=$("$SCRIPTS/launch-worker.sh" supervised ~/myproject)
SESSION_ID=$(echo "$RESULT" | jq -r '.session_id')

R1=$("$SCRIPTS/converse.sh" supervised "$SESSION_ID" "为认证模块编写测试用例" 300)
R2=$("$SCRIPTS/converse.sh" supervised "$SESSION_ID" "现在添加针对过期令牌的边缘情况测试" 300)

"$SCRIPTS/stop-worker.sh" supervised "$SESSION_ID"

Reviewing Worker Output

审查Worker输出

converse.sh
returns only the final text response. To see the full turn (thinking, tool calls, results), use
read-turn.sh
:
bash
undefined
converse.sh
仅返回最终文本响应。如需查看完整对话轮次(思考过程、工具调用、结果),请使用
read-turn.sh
bash
undefined

After a converse.sh call, review what the worker actually did

在converse.sh调用后,审查worker的实际执行过程

"$SCRIPTS/read-turn.sh" "$SESSION_ID"
"$SCRIPTS/read-turn.sh" "$SESSION_ID"

Show complete tool results (default truncates to 5 lines)

显示完整的工具执行结果(默认截断为5行)

"$SCRIPTS/read-turn.sh" "$SESSION_ID" --full

Output is formatted as markdown: thinking in blockquotes, tool calls as code blocks, results in fenced blocks, and text responses inline.
"$SCRIPTS/read-turn.sh" "$SESSION_ID" --full

输出内容会格式化为markdown:思考过程用块引用,工具调用用代码块,结果用围栏块,文本响应直接显示。

Edge Cases

边缘情况处理

Worker Crashes or tmux Dies

Worker崩溃或tmux异常终止

If the tmux session disappears,
send-prompt.sh
will fail with "tmux session does not exist." Check before sending:
bash
if ! tmux has-session -t my-worker 2>/dev/null; then
  echo "Worker is gone -- need to relaunch"
fi
The event file at
/tmp/claude-workers/<session-id>.events.jsonl
will still contain events emitted before the crash.
如果tmux会话消失,
send-prompt.sh
会返回错误“tmux session does not exist”。发送前请检查:
bash
if ! tmux has-session -t my-worker 2>/dev/null; then
  echo "Worker已失效——需要重新启动"
fi
崩溃前输出的事件仍会保存在
/tmp/claude-workers/<session-id>.events.jsonl
文件中。

Timeout While Waiting

等待超时

wait-for-event.sh
exits 1 on timeout. The worker may still be running. Choose how to handle it:
  • Extend the wait: Call
    wait-for-event.sh
    again with a new timeout
  • Give up: Stop the worker with
    stop-worker.sh
  • Hand off: Tell the human to take over
wait-for-event.sh
超时后会返回1。Worker可能仍在运行,你可以选择以下处理方式:
  • 延长等待时间:再次调用
    wait-for-event.sh
    并设置新的超时时间
  • 放弃任务:使用
    stop-worker.sh
    停止worker
  • 交接人工:通知人工操作员接管会话

Long Prompts

超长提示词

send-prompt.sh
sends text literally via
tmux send-keys -l
, which handles multi-line text and special characters correctly. Very long prompts (tens of KB) may hit tmux buffer limits. For extremely large inputs, consider writing the instructions to a file and telling the worker to read it:
bash
echo "Your detailed instructions here..." > /tmp/worker-instructions.txt
"$SCRIPTS/send-prompt.sh" my-worker "Read /tmp/worker-instructions.txt and follow those instructions"
send-prompt.sh
通过
tmux send-keys -l
直接发送文本,可正确处理多行文本和特殊字符。但超长篇提示词(数十KB)可能会触发tmux缓冲区限制。对于极大型输入,建议将指令写入文件并让worker读取:
bash
echo "你的详细指令内容..." > /tmp/worker-instructions.txt
"$SCRIPTS/send-prompt.sh" my-worker "读取/tmp/worker-instructions.txt并按照其中的指令执行"

Tool Approval

工具调用批准

Every tool call the worker makes emits a
pre_tool_use
event and waits up to 30 seconds for a controller decision before auto-approving. This gives you a window to inspect and approve or deny each tool call.
To monitor and auto-approve (default): Do nothing. If no decision is written within the timeout, the tool call proceeds.
To actively review tool calls:
bash
undefined
Worker的每一次工具调用都会触发
pre_tool_use
事件,并等待最多30秒以获取管控者的决策,超时后会自动批准。这让你有机会检查并批准或拒绝每一次工具调用。
监控并自动批准(默认):无需任何操作。如果超时前未做出决策,工具调用会自动执行。
主动审查工具调用
bash
undefined

Watch for pending tool approvals

监控待处理的工具批准请求

PENDING_FILE="/tmp/claude-workers/${SESSION_ID}.tool-pending"
PENDING_FILE="/tmp/claude-workers/${SESSION_ID}.tool-pending"

Check if a tool call is waiting for approval

检查是否有工具调用等待批准

if [ -f "$PENDING_FILE" ]; then cat "$PENDING_FILE" # Shows tool_name and tool_input

Approve it

"$SCRIPTS/approve-tool.sh" "$SESSION_ID" allow

Or deny it

"$SCRIPTS/approve-tool.sh" "$SESSION_ID" deny fi

The timeout is configurable via the `CLAUDE_SESSION_DRIVER_APPROVAL_TIMEOUT` environment variable (default: 30 seconds). To change it, pass the env var when launching:
```bash
RESULT=$(CLAUDE_SESSION_DRIVER_APPROVAL_TIMEOUT=60 "$SCRIPTS/launch-worker.sh" my-worker ~/project)
if [ -f "$PENDING_FILE" ]; then cat "$PENDING_FILE" # 显示工具名称和工具输入参数

批准调用

"$SCRIPTS/approve-tool.sh" "$SESSION_ID" allow

或拒绝调用

"$SCRIPTS/approve-tool.sh" "$SESSION_ID" deny fi

超时时间可通过环境变量`CLAUDE_SESSION_DRIVER_APPROVAL_TIMEOUT`配置(默认:30秒)。启动时传递该变量即可修改:
```bash
RESULT=$(CLAUDE_SESSION_DRIVER_APPROVAL_TIMEOUT=60 "$SCRIPTS/launch-worker.sh" my-worker ~/project)

Important Notes

重要注意事项

  • One controller per worker. Do not have multiple controllers sending prompts to the same tmux session.
  • Clean up on failure. If something goes wrong, always try to stop the worker and remove temp files.
    stop-worker.sh
    handles this, but if the script itself fails, clean up manually:
    bash
    tmux kill-session -t my-worker 2>/dev/null
    rm -f /tmp/claude-workers/<session-id>.events.jsonl
    rm -f /tmp/claude-workers/<session-id>.meta
  • Event files are append-only JSONL. Each line is a self-contained JSON object with
    ts
    and
    event
    fields.
  • Workers are full Claude Code sessions. They have their own tools, context, and conversation history. They do not share state with the controller except through files on disk and the event stream.
  • The tmux session name must be unique.
    launch-worker.sh
    will fail if a session with that name already exists.
  • 一个worker对应一个管控者:不要让多个管控者向同一个tmux会话发送提示词。
  • 失败时清理资源:如果出现异常,请始终尝试停止worker并删除临时文件。
    stop-worker.sh
    会处理这些操作,但如果脚本本身执行失败,请手动清理:
    bash
    tmux kill-session -t my-worker 2>/dev/null
    rm -f /tmp/claude-workers/<session-id>.events.jsonl
    rm -f /tmp/claude-workers/<session-id>.meta
  • 事件文件为追加式JSONL:每一行都是包含
    ts
    event
    字段的独立JSON对象。
  • Worker是完整的Claude Code会话:它们拥有独立的工具、上下文和对话历史。除了通过磁盘文件和事件流外,不会与管控者共享状态。
  • tmux会话名称必须唯一:如果同名会话已存在,
    launch-worker.sh
    会执行失败。