npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mporenta/pi-claude-code

v0.2.1

Published

Pi extension that runs Claude Code headlessly through an agent-safe CLI runner with a no-silent-hang guarantee (wall-clock + stall watchdogs, process-group kill, guaranteed completion hook), injects a completion hook back into Pi, and bundles a delegation

Readme

Pi Claude Code Extension

@mporenta/pi-claude-code runs Claude Code headlessly from Pi through an agent-safe CLI runner. It spawns Claude as a normal child process, keeps the (potentially large) result out of Pi's context by writing it to a disk artifact, and injects a claude-code-complete message back into Pi when the worker exits. That message uses triggerTurn: true with deliverAs: "steer": while Pi is active, the completion enters at the next safe turn boundary so relevant evidence can be incorporated before the main response; while Pi is idle, it starts a turn immediately.

No cmux dependency is used. A bundled claude-code skill teaches Pi to delegate through the extension tools instead of shelling out to claude -p directly.

No-silent-hang guarantee

The orchestrating Pi agent can never be left waiting on a worker that quietly wedged. Every spawned run reaches exactly one claude-code-complete hook within a bounded time, tagged with a terminationReason:

  • completed — Claude exited cleanly.
  • claude_error — Claude exited non-zero or reported an error subtype.
  • timeout — exceeded the wall-clock ceiling (timeoutMs, default 30 min, clamped to a non-disableable 30s–6h range); killed.
  • stallstallKillMs defaults to 0 (disabled): inactivity normally only emits a non-blocking alert. When stallKillMs > 0, the worker is killed after producing no output for that duration.
  • stopped — terminated via stop_claude_code_run.
  • spawn_error — the worker never started.
  • shutdown — Pi tore down the session while the worker was still running.

Normal terminal paths (completed, claude_error, timeout, stall, stopped, spawn_error) steer a claude-code-complete hook into the active run, or trigger a turn immediately when Pi is idle. This prevents worker completions from accumulating as separate follow-up turns after the main agent stops. shutdown is the exception: session_shutdown suppresses hook injection during teardown, since Pi is already exiting and cannot receive it.

Enforcement layers:

  1. Idempotent completion funnelclose, spawn error, and both watchdogs converge on one hook; a force-finalize fallback fires even if a truly wedged child never reports a clean exit.
  2. Wall-clock + stall watchdogs in the extension, with SIGTERM→SIGKILL escalation against the whole process group (claude grandchild included, not just the runner shell).
  3. Runner-level --timeout backstop (via timeout/gtimeout when present) so a wedged worker still self-terminates even if the Pi process dies and orphans it. Degrades to a no-op with a logged note where coreutils timeout is absent (e.g. stock macOS).
  4. Non-disableable 6-hour absolute hard-kill ceiling. timeoutMs is clamped server-side to [30_000, 21_600_000] ms (30s–6h) before the wall timer and runner --timeout are armed. There is no way to pass 0 or an oversized value to disable or extend past this ceiling — even a caller that bypasses the tool schema is clamped in spawn_claude_code.execute.
  5. Max active runs (3, hard-coded). spawn_claude_code refuses to start a new worker while 3 runs spawned by this session are still unfinalized, so a runaway loop cannot pile up unbounded paid Claude processes. Stop or wait for a run to finish before spawning another; this limit is not configurable via env or settings.

Workers are deliberately not tied to the tool-call abort signal — they are background jobs that outlive the immediately-returning spawn call, so an ending turn can't silently kill one.

bare: true is rejected at runtime with a clear error — it bypasses hooks/plugins/MCP/CLAUDE.md and breaks the orchestration safety model described above. The bare parameter remains in the schema only so existing calls get this explicit rejection instead of a silent schema failure; do not pass bare: true.

Non-blocking inactivity alerts

Separately from termination, the orchestrator is kept aware of a quiet worker. The runner spawns Claude with --output-format stream-json --verbose --include-partial-messages and writes the JSONL event log to the artifact as it is produced, so the file grows in real time. The extension polls that file's size; if it has not grown for inactivityAlertMs (default 120000) while the worker is still running, it injects a claude-code-inactivity hook — without killing the worker — and repeats every interval that silence continues (with an escalating inactivityAlertCount).

This is an alert, not a kill: a long test run or slow build legitimately produces no events for a while, so the orchestrator is told to inspect (get_claude_code_run) and decide, rather than the worker being terminated automatically. A hard inactivity kill is available but opt-in via stallKillMs (default 0 = off); the 30-minute wall-clock timeout remains the only default hard kill.

Install

pi install npm:@mporenta/pi-claude-code

Project-scoped install (writes to .pi/settings.json so a team shares it):

pi install -l npm:@mporenta/pi-claude-code

Temporary trial without installing:

pi -e npm:@mporenta/pi-claude-code

Requires the Claude Code CLI (claude) and jq on PATH, plus existing Claude authentication. The runner never performs auth bootstrap.

First prompts to try

Use spawn_claude_code to review this repository for correctness. Do not edit files. Run read-only validation only and return actionable findings. Use allowedTools Read,Bash(git status *),Bash(git diff *),Bash(npm test).

Use get_claude_code_run with the run ID from the last completion hook and summarize the artifact.

Use stop_claude_code_run to terminate run .

Tools

  • spawn_claude_code — starts a headless worker and returns immediately with a run ID. Completion arrives as a claude-code-complete hook; a claude-code-inactivity hook fires if it goes quiet. Params: prompt, cwd, tools, allowedTools, disallowedTools, model, fallbackModel, appendSystemPrompt, addDir, permissionMode, bare, maxTurns, timeoutMs, inactivityAlertMs, stallKillMs.
    • tools — optional Claude --tools expression that restricts which built-in tools are available, for example Read,Edit or an empty string to disable tools.
    • allowedTools — optional Claude allowed-tools expression that pre-approves matching calls. This is not a sandbox boundary; use tools / disallowedTools to constrain availability.
    • disallowedTools — optional Claude deny rules, passed through to --disallowed-tools, for denying specific tools/patterns.
    • timeoutMs — wall-clock ceiling in ms; clamped to [30_000, 21_600_000] (30s–6h). This ceiling cannot be disabled, including by passing 0.
    • bare — rejected at runtime when true (see "No-silent-hang guarantee" above). Do not pass bare: true.
  • get_claude_code_run — returns liveness (elapsed, timeout budget remaining, ms since last output, inactivity-alert count), termination reason, and a bounded artifact excerpt when finished.
  • list_claude_code_runs — enumerates every run in the session with liveness and termination reason (activeOnly to filter), for monitoring a fleet of workers.
  • stop_claude_code_run — SIGTERM (escalating to SIGKILL) a running worker; a stopped completion hook follows.

The runner is always invoked with an explicit workdir, a live-streamed JSONL event-log artifact at /tmp/pi-claude-code/<run-id>/result.json, and its own --timeout backstop. The completion hook and get_claude_code_run surface the final result via the status envelope's result_text. Pass maxTurns to cap agentic turns; omit it for the runner's unlimited-turn default.

Bundled skill

The extension registers its bundled claude-code skill at runtime via resources_discover, so the skill loads automatically when the package is installed — there is no separate skill registration to configure. The skill instructs Pi to use the three tools above, to never pass bare: true, and to independently verify Claude's claims.

The npm package version and bundled skill version are tracked independently: the package version describes the extension release; the skill version describes the delegation guidance bundled with it.

Configuration

Narrow which resources load from the package in global (~/.pi/agent/settings.json) or project (.pi/settings.json) settings:

{
  "packages": [
    { "source": "npm:@mporenta/pi-claude-code" }
  ]
}

Per-call configuration is passed as tool arguments: prompt, cwd, tools, allowedTools, disallowedTools, model, fallbackModel, appendSystemPrompt, addDir, permissionMode, bare, maxTurns, timeoutMs, inactivityAlertMs, and stallKillMs.

Security

The Claude process inherits Pi's environment and filesystem permissions. Notes:

  • Shell scope: restrict allowedTools to the narrowest useful set. A broad Bash permission is not read-only.
  • Paths: the runner writes artifacts under ${TMPDIR:-/tmp}/claude-cli-runner/ and the extension under /tmp/pi-claude-code/<run-id>/. Working directory is the resolved cwd argument.
  • Environment: the child inherits process.env, including any credentials present in Pi's environment.
  • Network: the Claude CLI contacts Anthropic's API using existing local auth.
  • Cleanup / disable: session shutdown sends SIGTERM (escalating to SIGKILL) to the process group of every worker this session owns. Remove the package with pi remove npm:@mporenta/pi-claude-code.

Troubleshooting

  • Runner not found: confirm scripts/claude_cli_runner.sh shipped and is executable (ls -l scripts/).
  • Missing dependency: the runner exits 2 if claude or jq is not on PATH.
  • Non-zero exit / error subtype: inspect the artifact with get_claude_code_run; the runner status envelope reports status, subtype, exit_code, and artifact paths. See references/claude-cli-runner-status-contract.md.

Development

npm install
npm run typecheck          # tsc --noEmit
npm test                   # bundled runner regression (fake claude, no network/auth)
npm run pack:dry-run       # inspect the publishable tarball file list

Local Pi smoke test (loads the extension and its bundled skill without launching a Claude worker):

pi --no-session -p "Reply with exactly OK" -e ./index.ts

Reload after editing when installed for auto-discovery: restart Pi or run /reload inside a session.

Publish

npm run typecheck && npm test && npm run pack:dry-run
npm publish --access public

Then install anywhere with pi install npm:@mporenta/pi-claude-code.

License

MIT — see LICENSE.