Metadata-Version: 2.4
Name: zsh-tool-mcp
Version: 0.4.71
Summary: Zsh for Claude Code. PTY mode lets Claude type passwords. NEVERHANG + A.L.A.N.
Project-URL: Homepage, https://github.com/ArkTechNWA/zsh-tool
Project-URL: Repository, https://github.com/ArkTechNWA/zsh-tool.git
Project-URL: Issues, https://github.com/ArkTechNWA/zsh-tool/issues
Author-email: ArkTechNWA <claude@arktechnwa.com>
License: MIT
License-File: LICENSE
Keywords: anthropic,claude,cli,mcp,shell,zsh
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Shells
Requires-Python: >=3.11
Requires-Dist: anyio>=4.0.0
Requires-Dist: mcp>=1.0.0
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'test'
Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
Requires-Dist: pytest>=8.0.0; extra == 'test'
Description-Content-Type: text/markdown

<img align="right" src="logo.png" width="150">

<!-- mcp-name: io.github.ArkTechNWA/zsh-tool -->

<br><br><br>

# zsh-tool

[![CI](https://github.com/ArkTechNWA/zsh-tool/actions/workflows/ci.yml/badge.svg)](https://github.com/ArkTechNWA/zsh-tool/actions/workflows/ci.yml)
[![Coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ArkTechNWA/zsh-tool/master/.github/badges/coverage.json)](https://github.com/ArkTechNWA/zsh-tool/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/)
[![MCP](https://img.shields.io/badge/MCP-Compatible-green.svg)](https://modelcontextprotocol.io)

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.4.6)

**Author:** Claude + Meldrey

**License:** [MIT](LICENSE)

**Organization:** [ArkTechNWA](https://github.com/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. The 2-second MCP overhead pays for itself on the first avoided confusion.

zsh-tool is **intelligent shell execution**:

| Problem | zsh-tool Solution |
|---------|-------------------|
| Bash/zsh quotation confusion | **Native zsh** — no shell mismatch, no debug loops |
| Commands hang forever | **Yield-based execution** — always get control back |
| No visibility into running commands | **zsh_poll** — incremental output collection |
| Can't interact with prompts | **PTY mode** + **zsh_send** — full interactive support |
| Can't type passwords | **PTY mode** — let Claude Code type its own passwords |
| Timeouts cascade | **NEVERHANG circuit breaker** — fail fast, auto-recover |
| No memory between calls | **A.L.A.N. 2.0** — retry detection, streak tracking, proactive insights |
| No task management | **zsh_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 management** — `zsh_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 Matching** — `git push origin feature-1` → `git 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

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

| Observation | What it tracks | Example insight |
|-------------|----------------|-----------------|
| **Host connectivity** | Can we connect to this host? | *"Host 'vps' has 67% connection failure rate"* |
| **Remote command** | Does 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

| Tool | Purpose |
|------|---------|
| `zsh` | Execute command with yield-based oversight |
| `zsh_poll` | Get more output from running task |
| `zsh_send` | Send input to task's stdin |
| `zsh_kill` | Kill a running task |
| `zsh_tasks` | List all active tasks |
| `zsh_health` | Overall health status |
| `zsh_alan_stats` | A.L.A.N. database statistics |
| `zsh_alan_query` | Query pattern insights for a command |
| `zsh_neverhang_status` | Circuit breaker state |
| `zsh_neverhang_reset` | Reset circuit to CLOSED |

---

## Installation

### From Marketplace (Recommended)

Add the ArkTechNWA marketplace to Claude 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` creates a venv and installs automatically.

### 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.

---

## Architecture

```
zsh-tool/
├── .claude-plugin/
│   ├── plugin.json
│   └── CLAUDE.md
├── .mcp.json
├── src/
│   └── server.py      # MCP server
├── data/
│   └── alan.db        # A.L.A.N. SQLite database
├── .venv/             # Python virtual environment
└── 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)

### Disabling Bash (Optional)

To use zsh as the only shell, add to `~/.claude/settings.json`:
```json
{
  "permissions": {
    "deny": ["Bash"]
  }
}
```

---

## Changelog

### 0.4.6
**Configuration & Polish** — *User-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 Plugin** — *Zero-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 & CI** — *290 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 Intelligence** — *Separate 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](LICENSE) for details.

---

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