io.github.ArkTechNWA/zsh-tool

编码与调试

by arktechnwa

为 Claude Code 提供 Zsh 支持;PTY 模式可让 Claude 输入密码,并集成 NEVERHANG 与 A.L.A.N.

什么是 io.github.ArkTechNWA/zsh-tool

为 Claude Code 提供 Zsh 支持;PTY 模式可让 Claude 输入密码,并集成 NEVERHANG 与 A.L.A.N.

README

<img align="right" src="logo.png" width="150"> <!-- mcp-name: io.github.ArkTechNWA/zsh-tool -->

<br><br><br>

zsh-tool

CI/CD License: MIT Rust

Zsh execution tool for Claude Code with full Bash parity, yield-based oversight, PTY mode, NEVERHANG circuit breaker, and A.L.A.N. short-term learning.

Status: Beta (v0.6.3)

Author: Claude + Meldrey

License: MIT

Organization: ArkTechNWA


Built with obsessive attention to reliability.


Why?

The #1 reason: If you use zsh, Claude Code's Bash tool causes quotation mismatches and shell confusion. Every debug loop costs tokens. zsh-tool eliminates this instantly and permanently.

The token math: One avoided debug spiral = 30+ seconds saved, hundreds of tokens preserved.

zsh-tool is intelligent shell execution:

Problemzsh-tool Solution
Bash/zsh quotation confusionNative zsh — no shell mismatch, no debug loops
Commands hang foreverYield-based execution — always get control back
No visibility into running commandszsh_poll — incremental output collection
Can't interact with promptsPTY mode + zsh_send — full interactive support
Can't type passwordsPTY mode — let Claude Code type its own passwords
Timeouts cascadeNEVERHANG circuit breaker — fail fast, auto-recover
No memory between callsA.L.A.N. 2.0 — retry detection, streak tracking, proactive insights
Polling wastes tokensIntelligent polling — 2s listen window, adaptive suggestions, duration estimates
Blind kills, no learningKill-aware A.L.A.N. — classifies impatience vs genuine hangs
Retrying with wrong flagsmanopt — auto-surfaces command options on repeated failures
No task managementzsh_tasks, zsh_kill — full control

This is the difference between "run commands" and "intelligent shell integration."


Features

Yield-Based Execution

Commands return after yield_after seconds with partial output if still running:

  • No more hanging — you always get control back
  • Incremental output — collect with zsh_poll
  • Interactive input — send with zsh_send
  • Task managementzsh_kill and zsh_tasks

PTY Mode

Full pseudo-terminal emulation for interactive programs:

bash
# Enable with pty: true
zsh(command="pass insert mypass", pty=true)
# See prompts, send input with zsh_send
  • Proper handling of interactive prompts
  • Programs that require a TTY
  • Color output and terminal escape sequences
  • Full stdin/stdout/stderr merging

NEVERHANG Circuit Breaker

Prevents hanging commands from blocking sessions:

  • Tracks timeout patterns per command hash
  • Opens circuit after 3 timeouts in rolling 1-hour window
  • Auto-recovers after 5 minutes
  • States: CLOSED (normal) → OPEN (blocking) → HALF_OPEN (testing)

A.L.A.N. 2.0 (As Long As Necessary)

Intelligent short-term learning — "Maybe you're fuckin' up, maybe you're doing it right."

  • Retry Detection — warns when you're repeating failed commands
  • Streak Tracking — celebrates success streaks, warns on failure streaks
  • Fuzzy Matchinggit push origin feature-1git push origin *
  • Proactive Insights — contextual feedback before you run commands
  • Session Memory — 15-minute rolling window tracks recent activity
  • Temporal Decay — exponential decay (24h half-life), auto-prunes
  • SSH Intelligence — separates host connectivity from remote command success
  • Pipeline Segment Tracking — when cat foo | grep -badopts | sort fails, A.L.A.N. knows which segment failed

Delta Output with Line Numbers (v0.6.3)

zsh_poll returns only new output since the last poll, prefixed with global line numbers. No more dumping 800 lines every poll call.

code
801: Installing package foo...
802: Compiling module bar...
803: Done.
FieldWhat it tells you
from_line / to_lineLine range in this delta (e.g., 801-803)
new_bytesByte count of new output since last poll
full_output (param)Pass true to get entire buffer with line numbers

First poll returns all output from line 1. Subsequent polls continue where the last left off. Completed tasks return the final delta, then empty on re-poll.

Intelligent Polling

zsh_poll performs a 2-second listen window before returning. If output arrives within 2s, it comes back immediately. If not, poll metadata tells the agent what's happening:

FieldWhat it tells you
polls_since_outputHow many empty polls in a row
elapsed_since_last_output_sIdle time since last output
alan_estimateA.L.A.N.'s duration prediction based on command history
suggestionAdaptive advice: space out polls, check soon, or consider killing

Suggestions are advisory only — the agent always decides. A 2-minute pip install no longer generates 40 empty round-trips.

Kill-Aware A.L.A.N.

When the agent kills a command, A.L.A.N. records it as a KILLED outcome and classifies why:

CategoryMeaningExample
EARLY_KILLKilled well before median completion"Killed at 30s. Median is 120s. Needs more time."
LATE_KILLRan way past expected duration"Killed after 180s. Median is 45s. Something is wrong."
PATTERN_PROBLEMTemplate gets killed >50% of the time"This pattern may need a different approach entirely."

Kill classification compares kill_elapsed / median_duration to distinguish impatience from genuine hangs.

manopt — Man Page Options on Failure

When a command fails repeatedly, A.L.A.N. surfaces its available options:

  • 1st failure — normal feedback, no manopt
  • 2nd failure — triggers async manopt lookup in background (2s timeout)
  • 3rd+ failure — presents cached option table in A.L.A.N. insight

Parsed from local man pages. Cached in SQLite. On by default (ALAN_MANOPT_ENABLED=1).

SSH Tracking

A.L.A.N. treats SSH commands specially, recording two separate observations:

ObservationWhat it tracksExample insight
Host connectivityCan we connect to this host?"Host 'vps' has 67% connection failure rate"
Remote commandDoes this command work across hosts?"Remote command 'git pull' reliable across 3 hosts"

Exit code classification:

  • 0 — Success (connected AND command succeeded)
  • 255 — Connection failed (SSH couldn't connect)
  • 1-254 — Command failed (connected but remote command failed)

This means when ssh host3 'git pull' fails with exit 255, A.L.A.N. knows the host was unreachable—not that git pull is broken.


Tools

ToolPurpose
zshExecute command with yield-based oversight
zsh_pollGet new output (delta) from running task with line numbers
zsh_sendSend input to task's stdin
zsh_killKill a running task
zsh_tasksList all active tasks
zsh_healthOverall health status
zsh_alan_statsA.L.A.N. database statistics
zsh_alan_queryQuery pattern insights for a command
zsh_neverhang_statusCircuit breaker state
zsh_neverhang_resetReset circuit to CLOSED

Installation

From Marketplace (Recommended)

Add the ArkTechNWA marketplace to Claude Code:

code
ArkTechNWA/claude-plugins

Then install: /plugin install arktechnwa/zsh-tool

That's it. The plugin auto-installs dependencies on first run.

Manual Installation

bash
git clone https://github.com/ArkTechNWA/zsh-tool.git ~/.claude/plugins/zsh-tool

Enable in ~/.claude/settings.json:

json
{
  "enabledPlugins": {
    "zsh-tool": true
  }
}

The bundled scripts/run-mcp.sh builds the Rust binary on first run and launches the MCP server.

Local Development

For local development/testing, the wrapper script automatically detects when CLAUDE_PLUGIN_ROOT isn't expanded and uses the calculated plugin root directory instead. No configuration changes needed.

Alternatively, create a .mcp.local.json with absolute paths:

json
{
  "mcpServers": {
    "zsh-tool": {
      "type": "stdio",
      "command": "/path/to/zsh-tool/scripts/run-mcp.sh",
      "env": {
        "NEVERHANG_TIMEOUT_DEFAULT": "120",
        "NEVERHANG_TIMEOUT_MAX": "600"
      }
    }
  }
}

The ALAN_DB_PATH will be automatically set to {plugin_root}/data/alan.db if not explicitly provided.

Requirements: Rust toolchain (cargo) and zsh must be installed.


Architecture

code
zsh-tool/
├── .claude-plugin/
│   ├── plugin.json
│   └── CLAUDE.md
├── .mcp.json
├── zsh-tool-rs/
│   ├── Cargo.toml
│   └── src/
│       ├── main.rs          # CLI entry point
│       ├── lib.rs           # Module exports
│       ├── executor.rs      # Pipe/PTY command execution
│       ├── config.rs        # User config (~/.config/zsh-tool/)
│       ├── circuit.rs       # NEVERHANG circuit breaker
│       ├── meta.rs          # Task metadata (exit code, pipestatus)
│       ├── alan/            # A.L.A.N. 2.0 learning engine
│       │   ├── mod.rs       #   Recording + insights
│       │   ├── hash.rs      #   Fuzzy command hashing
│       │   ├── insights.rs  #   Proactive feedback
│       │   ├── manopt.rs    #   Man-page option parsing
│       │   ├── ssh.rs       #   SSH host/command tracking
│       │   ├── streak.rs    #   Success/failure streaks
│       │   ├── pipeline.rs  #   Pipeline segment tracking
│       │   ├── prune.rs     #   Temporal decay + pruning
│       │   └── stats.rs     #   Database statistics
│       └── serve/           # MCP JSON-RPC server
│           ├── mod.rs       #   Request dispatch + tool handlers
│           ├── protocol.rs  #   JSON-RPC framing
│           └── tools.rs     #   Tool schema definitions
├── scripts/
│   └── run-mcp.sh           # Build + launch wrapper
├── data/
│   └── alan.db              # A.L.A.N. SQLite database
└── README.md

Configuration

Environment variables (set in .mcp.json):

  • ALAN_DB_PATH — A.L.A.N. database location
  • NEVERHANG_TIMEOUT_DEFAULT — Default timeout (120s)
  • NEVERHANG_TIMEOUT_MAX — Maximum timeout (600s)
  • ALAN_MANOPT_ENABLED — Enable man-page option hints on failure (default: 1)
  • ALAN_MANOPT_TIMEOUT — Max seconds to wait for manopt parsing (default: 2.0)
  • ALAN_MANOPT_FAIL_TRIGGER — Fail count to trigger async lookup (default: 2)
  • ALAN_MANOPT_FAIL_PRESENT — Fail count to present cached options (default: 3)

Disabling Bash (Optional)

To use zsh as the only shell, add to ~/.claude/settings.json:

json
{
  "permissions": {
    "deny": ["Bash"]
  }
}

Changelog

0.6.1

Protocol FixBare JSON-RPC support for Claude Code v2.1+

  • Fix: MCP server now auto-detects bare newline-delimited JSON (Claude Code v2.1.42+) vs Content-Length framing
  • Debug logging: stderr diagnostics for protocol negotiation, request/response lifecycle, shutdown
  • Log file: run-mcp.sh redirects stderr to /tmp/zsh-tool-mcp.log for MCP debugging

0.6.0

Full Rust RewriteGoodbye Python, hello speed

  • Complete rewrite in Rust — MCP server, executor, A.L.A.N., NEVERHANG, all native
  • 79 Rust tests — unit tests + full MCP integration tests (JSON-RPC round-trip)
  • CI pipeline rewrittencargo test + cargo clippy replace pytest + ruff
  • Python removed — 7,600+ lines of Python deleted, zero Python dependencies
  • ~2x faster CI — cold build 97s → cached 48s (vs Python's 60-120s)
  • All features preserved: yield/poll/send/kill, PTY mode, A.L.A.N. 2.0, NEVERHANG, manopt, SSH tracking, pipeline segments

0.5.0

A.L.A.N. v2 UpgradeIntelligent polling, kill awareness, manopt

  • Intelligent polling: 2s listen window in zsh_poll reduces empty round-trips; poll metadata with duration estimates and adaptive suggestions
  • Kill-aware A.L.A.N.: KILLED outcome type with elapsed tracking; classifies early kills (impatience), late kills (genuine hangs), and pattern problems (wrong approach)
  • manopt integration: Async man-page option parsing on repeated command failures; cached in SQLite; presented on 3rd+ failure for the same command template
  • New outcome_type and kill_elapsed_ms columns on observations
  • New manopt_cache table for persistent man-page option storage
  • ENV vars: ALAN_MANOPT_ENABLED, ALAN_MANOPT_TIMEOUT, ALAN_MANOPT_FAIL_TRIGGER, ALAN_MANOPT_FAIL_PRESENT

0.4.90

Feedback ImprovementsBetter signal, less noise

  • ALAN insights now classified as info/warning tuples
  • Command awareness: grep exit 1 = "no match" (info), exit 127 = "command not found" (warning)
  • Post-execution insights: silent detection, pipe masking warnings, SIGPIPE exclusion
  • ANSI coloring on metadata lines (green=success, red=failure, cyan=running, yellow=timeout)
  • COMPLETED/FAILED status word based on exit code
  • Raw pipestatus lists replace formatted [cmd:code] strings
  • Grouped insight display: [info: A.L.A.N.: ...] and [warning: A.L.A.N.: ...]

0.4.83

Python 3.14 SupportFuture-proofing

  • Added Python 3.14 classifier and badge
  • Removed deprecated asyncio.DefaultEventLoopPolicy fixture (slated for removal in 3.16)
  • All 331 tests pass on Python 3.14.2

0.4.81

Pipestatus Marker Leak FixData integrity

  • Fixed race condition where ___ZSH_PIPESTATUS_MARKER___ could leak into output
  • Marker now stripped in _build_task_response() before returning to caller
  • Prevents corrupted file content when output is captured mid-execution
  • CI: Runner switched to docker executor, added PEP 668 compliance

0.4.80

Per-Segment Exit CodesKnow exactly which command failed

  • Exit codes now show [cmd1:0,cmd2:1,cmd3:0] format instead of single integer
  • Each pipeline segment paired with its actual exit status from zsh $pipestatus
  • A.L.A.N. learning receives accurate per-command outcomes
  • Self-documenting output for human and AI analysis
  • Fixes bug where all commands reported exit=0 regardless of actual status

0.4.79

Server Modular RefactoringCleaner architecture

  • Extracted MCP server into zsh_tool/server.py module
  • Centralized configuration in zsh_tool/config.py
  • Fixed plugin.json version sync with package version

0.4.75

Pipeline IntelligenceKnow which segment of your pipeline is failing

  • A.L.A.N. now captures zsh's $pipestatus array for every pipeline
  • Each segment recorded as independent observation with its own exit code
  • When cat foo | grep -badopts | sort fails, you know grep was the problem
  • Quote/escape-aware pipeline parsing handles complex commands correctly
  • Backwards compatible: full pipeline still recorded alongside segments
  • 248 new test lines covering segment tracking and edge cases

0.4.6

Configuration & PolishUser-configurable defaults, 91% coverage

  • User config file (~/.config/zsh-tool/config.yaml) for custom yield_after
  • Test coverage improved: 303 tests, 91% coverage
  • Fixed null-check bug in task cleanup
  • Logo files consolidated and fixed

0.4.5

Bundled PluginZero-friction marketplace install

  • Auto-install wrapper (scripts/run-mcp.sh) creates venv on first run
  • Portable .mcp.json using ${CLAUDE_PLUGIN_ROOT}
  • ArkTechNWA marketplace support
  • No manual pip install required

0.4.0

Test Suite & CI290 tests, 89% coverage

  • Comprehensive test suite covering all modules
  • CI pipeline with test and lint stages
  • Dynamic pipeline and coverage badges
  • Gentle test runner (run_tests.sh) with nice and sleep between files
  • Fixed deprecation warnings and lint errors
  • Added pytest-asyncio for async test support

0.3.1

SSH IntelligenceSeparate host connectivity from remote command success

  • SSH commands now record dual observations (host + remote command)
  • Exit code classification: 0=success, 255=connection_failed, 1-254=command_failed
  • New ssh_observations table for SSH-specific tracking
  • get_ssh_host_stats() — per-host connection/command success rates
  • get_ssh_command_stats() — per-command stats across all hosts
  • SSH-specific insights: flaky hosts, reliable hosts, failing commands
  • 31 new tests for SSH tracking

0.3.0

A.L.A.N. 2.0"Maybe you're fuckin' up, maybe you're doing it right."

  • Retry detection: warns when repeating failed commands
  • Streak tracking: celebrates success, warns on failure
  • Fuzzy template matching: similar commands grouped
  • Proactive insights: contextual feedback before execution
  • Session memory: 15-minute rolling window
  • New database tables: recent_commands, streaks

0.2.0

  • Yield-based execution with live oversight
  • PTY mode for full terminal emulation
  • Interactive input support via zsh_send
  • Task management: zsh_poll, zsh_kill, zsh_tasks
  • Fixed stdin blocking with subprocess.PIPE

0.1.0

  • Initial release
  • NEVERHANG circuit breaker
  • A.L.A.N. learning database

License

MIT License - see LICENSE for details.


<p align="center"> <b>For Johnny5. For us.</b><br> <i>ArkTechNWA</i> </p>

常见问题

io.github.ArkTechNWA/zsh-tool 是什么?

为 Claude Code 提供 Zsh 支持;PTY 模式可让 Claude 输入密码,并集成 NEVERHANG 与 A.L.A.N.

相关 Skills

网页构建器

by anthropics

Universal
热门

面向复杂 claude.ai HTML artifact 开发,快速初始化 React + Tailwind CSS + shadcn/ui 项目并打包为单文件 HTML,适合需要状态管理、路由或多组件交互的页面。

在 claude.ai 里做复杂网页 Artifact 很省心,多组件、状态和路由都能顺手搭起来,React、Tailwind 与 shadcn/ui 组合效率高、成品也更精致。

编码与调试
未扫描114.1k

前端设计

by anthropics

Universal
热门

面向组件、页面、海报和 Web 应用开发,按鲜明视觉方向生成可直接落地的前端代码与高质感 UI,适合做 landing page、Dashboard 或美化现有界面,避开千篇一律的 AI 审美。

想把页面做得既能上线又有设计感,就用前端设计:组件到整站都能产出,难得的是能避开千篇一律的 AI 味。

编码与调试
未扫描114.1k

网页应用测试

by anthropics

Universal
热门

用 Playwright 为本地 Web 应用编写自动化测试,支持启动开发服务器、校验前端交互、排查 UI 异常、抓取截图与浏览器日志,适合调试动态页面和回归验证。

借助 Playwright 一站式验证本地 Web 应用前端功能,调 UI 时还能同步查看日志和截图,定位问题更快。

编码与调试
未扫描114.1k

相关 MCP Server

GitHub

编辑精选

by GitHub

热门

GitHub 是 MCP 官方参考服务器,让 Claude 直接读写你的代码仓库和 Issues。

这个参考服务器解决了开发者想让 AI 安全访问 GitHub 数据的问题,适合需要自动化代码审查或 Issue 管理的团队。但注意它只是参考实现,生产环境得自己加固安全。

编码与调试
83.4k

by Context7

热门

Context7 是实时拉取最新文档和代码示例的智能助手,让你告别过时资料。

它能解决开发者查找文档时信息滞后的问题,特别适合快速上手新库或跟进更新。不过,依赖外部源可能导致偶尔的数据延迟,建议结合官方文档使用。

编码与调试
52.2k

by tldraw

热门

tldraw 是让 AI 助手直接在无限画布上绘图和协作的 MCP 服务器。

这解决了 AI 只能输出文本、无法视觉化协作的痛点——想象让 Claude 帮你画流程图或白板讨论。最适合需要快速原型设计或头脑风暴的开发者。不过,目前它只是个基础连接器,你得自己搭建画布应用才能发挥全部潜力。

编码与调试
46.3k

评论