🚀 zsh-tool
zsh-tool 是一款专为 Claude Code 设计的 Zsh 执行工具,具备与 Bash 完全兼容的特性。它采用基于 yield 的监督机制、PTY 模式、NEVERHANG 断路器以及 A.L.A.N. 短期学习功能,有效解决了使用 Claude Code 时在 zsh 环境下的诸多问题。
🚀 快速开始
如果你使用 zsh,Claude Code 的 Bash 工具会导致引号不匹配和 shell 混乱,每次调试循环都会消耗大量令牌。而 zsh-tool 能立即且永久地消除这些问题。避免一次调试循环,就能节省 30 多秒时间和数百个令牌。
✨ 主要特性
基于 Yield 的执行
命令在运行 yield_after 秒后,如果仍在执行,会返回部分输出:
- 不再出现命令挂起的情况,你始终能重新获得控制权。
- 支持增量输出,可使用
zsh_poll 进行收集。
- 支持交互式输入,可使用
zsh_send 发送。
- 提供任务管理功能,可使用
zsh_kill 和 zsh_tasks。
PTY 模式
为交互式程序提供完整的伪终端仿真:
zsh(command="pass insert mypass", pty=true)
- 能正确处理交互式提示。
- 支持需要 TTY 的程序。
- 支持彩色输出和终端转义序列。
- 实现标准输入、标准输出和标准错误的完全合并。
NEVERHANG 断路器
防止挂起的命令阻塞会话:
- 跟踪每个命令哈希的超时模式。
- 在滚动的 1 小时窗口内出现 3 次超时后,打开断路器。
- 5 分钟后自动恢复。
- 状态包括:
CLOSED(正常)→ OPEN(阻塞)→ HALF_OPEN(测试)。
A.L.A.N. 2.0(按需学习系统)
智能短期学习系统:
- 重试检测:当你重复执行失败的命令时发出警告。
- 连胜追踪:庆祝成功连胜,在失败连胜时发出警告。
- 模糊匹配:例如
git push origin feature-1 可匹配 git push origin *。
- 主动洞察:在你运行命令之前提供上下文反馈。
- 会话记忆:15 分钟滚动窗口跟踪最近的活动。
- 时间衰减:指数衰减(半衰期 24 小时),自动清理。
- SSH 智能:将主机连接性与远程命令成功情况分开记录。
- 管道段跟踪:当
cat foo | grep -badopts | sort 失败时,A.L.A.N. 能知道哪个段失败。
智能轮询
zsh_poll 在返回之前执行 2 秒的监听窗口。如果在 2 秒内有输出到达,则立即返回。否则,轮询元数据会告知代理当前的情况:
| 字段 |
说明 |
polls_since_output |
连续空轮询的次数 |
elapsed_since_last_output_s |
自上次输出以来的空闲时间 |
alan_estimate |
A.L.A.N. 根据命令历史记录的持续时间预测 |
suggestion |
自适应建议:间隔轮询、尽快检查或考虑终止 |
建议仅作参考,最终决策由代理决定。例如 2 分钟的 pip install 操作,不会再产生 40 次空往返。
支持终止检测的 A.L.A.N.
当代理终止命令时,A.L.A.N. 会将其记录为 KILLED 结果,并对原因进行分类:
| 类别 |
含义 |
示例 |
EARLY_KILL |
在中位完成时间之前过早终止 |
"在 30 秒时终止。中位时间是 120 秒。需要更多时间。" |
LATE_KILL |
运行时间远远超过预期持续时间 |
"在 180 秒后终止。中位时间是 45 秒。可能存在问题。" |
PATTERN_PROBLEM |
模板被终止的次数超过 50% |
"这种模式可能需要完全不同的方法。" |
终止分类通过比较 kill_elapsed / median_duration 来区分是用户的不耐烦还是真正的挂起。
manopt — 失败时显示手册页选项
当命令多次失败时,A.L.A.N. 会显示其可用选项:
- 首次失败:正常反馈,不显示 manopt。
- 第二次失败:触发后台异步
manopt 查找(超时 2 秒)。
- 第三次及以后失败:在 A.L.A.N. 洞察中显示缓存的选项表。
选项从本地手册页解析,缓存在 SQLite 中,默认启用(ALAN_MANOPT_ENABLED=1)。
SSH 跟踪
A.L.A.N. 对 SSH 命令进行特殊处理,记录两个独立的观察结果:
| 观察结果 |
跟踪内容 |
示例洞察 |
| 主机连接性 |
是否可以连接到该主机? |
"主机 'vps' 的连接失败率为 67%" |
| 远程命令 |
该命令在各主机上是否有效? |
"远程命令 'git pull' 在 3 台主机上都可靠" |
退出码分类:
0 — 成功(连接成功且命令执行成功)
255 — 连接失败(SSH 无法连接)
1 - 254 — 命令失败(连接成功,但远程命令执行失败)
这意味着当 ssh host3 'git pull' 以退出码 255 失败时,A.L.A.N. 知道是主机不可达,而不是 git pull 命令本身有问题。
工具列表
| 工具 |
用途 |
zsh |
执行命令并进行基于 yield 的监督 |
zsh_poll |
从正在运行的任务中获取更多输出 |
zsh_send |
向任务的标准输入发送输入 |
zsh_kill |
终止正在运行的任务 |
zsh_tasks |
列出所有活动任务 |
zsh_health |
显示整体健康状态 |
zsh_alan_stats |
显示 A.L.A.N. 数据库统计信息 |
zsh_alan_query |
查询命令的模式洞察 |
zsh_neverhang_status |
显示断路器状态 |
zsh_neverhang_reset |
将断路器重置为 CLOSED 状态 |
📦 安装指南
从市场安装(推荐)
将 ArkTechNWA 市场添加到 Claude Code:
ArkTechNWA/claude-plugins
然后安装:/plugin install arktechnwa/zsh-tool
插件会在首次运行时自动安装依赖项。
手动安装
git clone https://github.com/ArkTechNWA/zsh-tool.git ~/.claude/plugins/zsh-tool
在 ~/.claude/settings.json 中启用:
{
"enabledPlugins": {
"zsh-tool": true
}
}
捆绑的 scripts/run-mcp.sh 脚本会在首次运行时构建 Rust 二进制文件并启动 MCP 服务器。
本地开发
对于本地开发/测试,包装脚本会自动检测 CLAUDE_PLUGIN_ROOT 是否未展开,并使用计算出的插件根目录代替,无需更改配置。
或者,创建一个 .mcp.local.json 文件,使用绝对路径:
{
"mcpServers": {
"zsh-tool": {
"type": "stdio",
"command": "/path/to/zsh-tool/scripts/run-mcp.sh",
"env": {
"NEVERHANG_TIMEOUT_DEFAULT": "120",
"NEVERHANG_TIMEOUT_MAX": "600"
}
}
}
}
如果未明确提供,ALAN_DB_PATH 将自动设置为 {plugin_root}/data/alan.db。
要求:必须安装 Rust 工具链(cargo)和 zsh。
📚 详细文档
架构
zsh-tool/
├── .claude-plugin/
│ ├── plugin.json
│ └── CLAUDE.md
├── .mcp.json
├── zsh-tool-rs/
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs # CLI 入口点
│ ├── lib.rs # 模块导出
│ ├── executor.rs # 管道/PTY 命令执行
│ ├── config.rs # 用户配置 (~/.config/zsh-tool/)
│ ├── circuit.rs # NEVERHANG 断路器
│ ├── meta.rs # 任务元数据 (退出码, pipestatus)
│ ├── alan/ # A.L.A.N. 2.0 学习引擎
│ │ ├── mod.rs # 记录 + 洞察
│ │ ├── hash.rs # 模糊命令哈希
│ │ ├── insights.rs # 主动反馈
│ │ ├── manopt.rs # 手册页选项解析
│ │ ├── ssh.rs # SSH 主机/命令跟踪
│ │ ├── streak.rs # 成功/失败连胜
│ │ ├── pipeline.rs # 管道段跟踪
│ │ ├── prune.rs # 时间衰减 + 清理
│ │ └── stats.rs # 数据库统计信息
│ └── serve/ # MCP JSON-RPC 服务器
│ ├── mod.rs # 请求分发 + 工具处理程序
│ ├── protocol.rs # JSON-RPC 框架
│ └── tools.rs # 工具模式定义
├── scripts/
│ └── run-mcp.sh # 构建 + 启动包装器
├── data/
│ └── alan.db # A.L.A.N. SQLite 数据库
└── README.md
配置
环境变量(在 .mcp.json 中设置):
ALAN_DB_PATH — A.L.A.N. 数据库位置
NEVERHANG_TIMEOUT_DEFAULT — 默认超时时间(120 秒)
NEVERHANG_TIMEOUT_MAX — 最大超时时间(600 秒)
ALAN_MANOPT_ENABLED — 启用失败时的手册页选项提示(默认:1)
ALAN_MANOPT_TIMEOUT — 等待 manopt 解析的最大秒数(默认:2.0)
ALAN_MANOPT_FAIL_TRIGGER — 触发异步查找的失败次数(默认:2)
ALAN_MANOPT_FAIL_PRESENT — 显示缓存选项的失败次数(默认:3)
禁用 Bash(可选)
若要仅使用 zsh 作为 shell,可在 ~/.claude/settings.json 中添加:
{
"permissions": {
"deny": ["Bash"]
}
}
变更日志
0.6.1
协议修复 — 支持 Claude Code v2.1+ 的裸 JSON-RPC
- 修复:MCP 服务器现在能自动检测裸换行分隔的 JSON(Claude Code v2.1.42+)与 Content-Length 框架。
- 调试日志:stderr 诊断信息,用于协议协商、请求/响应生命周期和关闭。
- 日志文件:
run-mcp.sh 将 stderr 重定向到 /tmp/zsh-tool-mcp.log,用于 MCP 调试。
0.6.0
完全用 Rust 重写 — 告别 Python,迎接速度提升
- 用 Rust 完全重写:MCP 服务器、执行器、A.L.A.N.、NEVERHANG 等全部采用原生实现。
- 79 个 Rust 测试:单元测试 + 完整的 MCP 集成测试(JSON-RPC 往返)。
- CI 管道重写:
cargo test + cargo clippy 取代 pytest + ruff。
- 移除 Python:删除 7600 多行 Python 代码,零 Python 依赖。
- CI 速度提升约 2 倍:冷构建从 97 秒降至 48 秒(缓存后),而 Python 版本为 60 - 120 秒。
- 保留所有功能:yield/轮询/发送/终止、PTY 模式、A.L.A.N. 2.0、NEVERHANG、manopt、SSH 跟踪、管道段。
0.5.0
A.L.A.N. v2 升级 — 智能轮询、支持终止检测、manopt 功能
- 智能轮询:
zsh_poll 中的 2 秒监听窗口减少了空往返;轮询元数据包含持续时间估计和自适应建议。
- 支持终止检测的 A.L.A.N.:新增
KILLED 结果类型并跟踪执行时间;对过早终止(用户不耐烦)、过晚终止(真正的挂起)和模式问题(错误的方法)进行分类。
- manopt 集成:在命令多次失败时异步解析手册页选项;缓存在 SQLite 中;在同一命令模板第三次及以后失败时显示。
- 观察结果表新增
outcome_type 和 kill_elapsed_ms 列。
- 新增
manopt_cache 表用于持久存储手册页选项。
- 环境变量:
ALAN_MANOPT_ENABLED、ALAN_MANOPT_TIMEOUT、ALAN_MANOPT_FAIL_TRIGGER、ALAN_MANOPT_FAIL_PRESENT。
0.4.90
反馈改进 — 更好的信号,更少的噪音
- ALAN 洞察现在分类为信息/警告元组。
- 命令感知:grep 退出码 1 表示 "无匹配"(信息),退出码 127 表示 "命令未找到"(警告)。
- 执行后洞察:静默检测、管道屏蔽警告、排除 SIGPIPE。
- 元数据行使用 ANSI 颜色(绿色 = 成功,红色 = 失败,青色 = 运行中,黄色 = 超时)。
- 根据退出码显示 COMPLETED/FAILED 状态字。
- 原始 pipestatus 列表取代格式化的
[cmd:code] 字符串。
- 分组显示洞察信息:
[info: A.L.A.N.: ...] 和 [warning: A.L.A.N.: ...]。
0.4.83
支持 Python 3.14 — 面向未来的兼容性
- 添加 Python 3.14 分类器和徽章。
- 移除已弃用的
asyncio.DefaultEventLoopPolicy 夹具(计划在 3.16 中移除)。
- 所有 331 个测试在 Python 3.14.2 上通过。
0.4.81
修复 Pipestatus 标记泄漏问题 — 数据完整性保障
- 修复了
___ZSH_PIPESTATUS_MARKER___ 可能泄漏到输出中的竞态条件。
- 在
_build_task_response() 中将标记从返回给调用者的结果中移除。
- 防止在执行过程中捕获输出时文件内容损坏。
- CI:运行器切换到 Docker 执行器,添加 PEP 668 合规性。
0.4.80
支持每段退出码 — 精确知道哪个命令失败
- 退出码现在显示为
[cmd1:0,cmd2:1,cmd3:0] 格式,而不是单个整数。
- 每个管道段与其从 zsh
$pipestatus 获得的实际退出状态配对。
- A.L.A.N. 学习接收到准确的每个命令的结果。
- 输出具有自解释性,便于人类和 AI 分析。
- 修复了所有命令无论实际状态如何都报告
exit=0 的错误。
0.4.79
服务器模块化重构 — 更清晰的架构
- 将 MCP 服务器提取到
zsh_tool/server.py 模块中。
- 在
zsh_tool/config.py 中集中配置。
- 修复了 plugin.json 版本与包版本的同步问题。
0.4.75
管道智能 — 知道管道的哪个段失败
- A.L.A.N. 现在捕获每个管道的 zsh
$pipestatus 数组。
- 每个段作为独立的观察结果记录,有自己的退出码。
- 当
cat foo | grep -badopts | sort 失败时,你知道是 grep 出了问题。
- 支持引号/转义的管道解析能正确处理复杂命令。
- 向后兼容:完整的管道仍与段一起记录。
- 新增 248 行测试用例,覆盖段跟踪和边缘情况。
0.4.6
配置与优化 — 用户可配置默认值,测试覆盖率达 91%
- 用户配置文件 (
~/.config/zsh-tool/config.yaml) 用于自定义 yield_after。
- 测试覆盖率提高:303 个测试,91% 覆盖率。
- 修复任务清理中的空检查错误。
- 合并并修复徽标文件。
0.4.5
捆绑插件 — 零摩擦的市场安装
- 自动安装包装器 (
scripts/run-mcp.sh) 在首次运行时创建虚拟环境。
- 可移植的
.mcp.json 使用 ${CLAUDE_PLUGIN_ROOT}。
- 支持 ArkTechNWA 市场。
- 无需手动执行 pip install。
0.4.0
测试套件与 CI — 290 个测试,89% 覆盖率
- 全面的测试套件覆盖所有模块。
- 包含测试和 lint 阶段的 CI 管道。
- 动态管道和覆盖率徽章。
- 温和的测试运行器 (
run_tests.sh) 在文件之间使用 nice 和 sleep。
- 修复弃用警告和 lint 错误。
- 添加 pytest-asyncio 以支持异步测试。
0.3.1
SSH 智能 — 区分主机连接性和远程命令成功情况
- SSH 命令现在记录双重观察结果(主机 + 远程命令)。
- 退出码分类:0 = 成功,255 = 连接失败,1 - 254 = 命令失败。
- 新增
ssh_observations 表用于 SSH 特定跟踪。
get_ssh_host_stats() — 每台主机的连接/命令成功率。
get_ssh_command_stats() — 所有主机上每个命令的统计信息。
- SSH 特定洞察:不稳定的主机、可靠的主机、失败的命令。
- 新增 31 个 SSH 跟踪测试用例。
0.3.0
A.L.A.N. 2.0 — “也许你搞砸了,也许你做对了。”
- 重试检测:当重复执行失败的命令时发出警告。
- 连胜追踪:庆祝成功,在失败时发出警告。
- 模糊模板匹配:将类似的命令分组。
- 主动洞察:在执行前提供上下文反馈。
- 会话记忆:15 分钟滚动窗口。
- 新增数据库表:
recent_commands、streaks。
0.2.0
- 基于 yield 的执行,实时监督。
- 支持 PTY 模式,实现完整的终端仿真。
- 通过
zsh_send 支持交互式输入。
- 任务管理:
zsh_poll、zsh_kill、zsh_tasks。
- 修复了子进程使用 PIPE 时标准输入阻塞的问题。
0.1.0
- 初始版本发布。
- 包含 NEVERHANG 断路器。
- 具备 A.L.A.N. 学习数据库。
📄 许可证
本项目采用 MIT 许可证,详情请见 LICENSE。