# pi-zsh

[![npm](https://img.shields.io/npm/v/@4meta5/pi-zsh)](https://www.npmjs.com/package/@4meta5/pi-zsh)

Allowlist-only zsh script runner extension for pi coding agents.

`pi-zsh` does one job: run explicitly allowlisted `.zsh` scripts through one tool, `zsh_script_run`. It does not provide arbitrary shell execution, scheduling, or orchestration.

## Project Docs

- [README](README.md)
- [Code of Conduct](CODE_OF_CONDUCT.md)
- [Contributing](CONTRIBUTING.md)
- [Security](SECURITY.md)
- [Changelog](CHANGELOG.md)
- [MIT License](LICENSE)

## Why This Exists

Most shell integrations start tight and then drift into "run anything." `pi-zsh` keeps a stricter boundary:

- only allowlisted `script_id` values can execute
- each script path must be absolute, executable, and `.zsh`
- environment variables are allowlisted
- output is truncated for context safety, with optional full-output file pointer
- non-zero exit, timeout, and abort are surfaced as `isError: true`

## Install

```bash
npm install @4meta5/pi-zsh
```

This package includes the `pi-package` keyword so it is discoverable by pi package indexing flows.

## Quick Start

1. Create an allowlist file:

```json
{
  "allowlist": {
    "cron_review": {
      "path": "/absolute/path/to/cron-review.zsh",
      "defaultArgs": [],
      "defaultCwdMode": "script_root"
    }
  },
  "envAllowlist": ["PATH", "HOME", "SHELL", "LANG", "LC_ALL"],
  "defaultTimeoutMs": 120000,
  "maxTimeoutMs": 900000
}
```

2. Set required config:

```bash
export PI_ZSH_ALLOWLIST_FILE=/absolute/path/to/pi-zsh-allowlist.json
```

3. Load as a pi extension:

```bash
pi -e /absolute/path/to/pi-zsh/src/index.ts
```

## Tool Contract

### `zsh_script_run`

Parameters:

- `script_id` (required): allowlisted script identifier
- `args` (optional): extra args appended after allowlist defaults
- `cwd_mode` (optional): `script_root` or `caller_cwd`
- `timeout_ms` (optional): per-call timeout clamped by config max

Returns:

- text summary plus truncated output preview
- structured `details` including path, argv, duration, and truncation metadata
- `isError: true` for non-zero exit, timeout, or abort

## Config

Required:

- `PI_ZSH_ALLOWLIST_FILE`: absolute path to JSON config

Optional env overrides:

- `PI_ZSH_ENV_ALLOWLIST`
- `PI_ZSH_DEFAULT_TIMEOUT_MS`
- `PI_ZSH_MAX_TIMEOUT_MS`

Empty `envAllowlist` behavior:

- if config sets `"envAllowlist": []`, `pi-zsh` requires an interactive decision at runtime
- in non-UI mode, execution returns an error with remediation guidance

Author-convenience default env allowlist:

- `AGENT_DISPATCH_DIR`
- `AGENT_DISPATCH_CMD`
- `CLONES_DIR`
- `GITHUB_TOKEN`
- `PATH`
- `HOME`
- `SHELL`
- `LANG`
- `LC_ALL`

## Scope Boundaries

In scope:

- one extension package
- one tool (`zsh_script_run`)
- allowlist-only script execution
- explicit failure semantics and output truncation

Out of scope:

- arbitrary command execution
- script discovery frameworks
- schedulers and orchestrators
- auth plugin orchestration
- update and migration surfaces

## Development

```bash
npm run check
npm test
npm run build
```

## License

MIT
