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

pi-recurse

v0.1.1

Published

Recursive agent extension for Pi — spawn subagents programmatically with depth guardrails

Readme

🔁 pi-recurse

Programmatic recursive subagent spawning for pi

LLM makes ONE tool call, extension code handles parallel spawning and result aggregation.

pi extension license


This project is the spiritual successor to ypi by @rawwerks, originally created as a bash wrapper around Pi that enabled recursive LLM calls with guardrails.

Why the conversion? The original ypi proved that recursive subagents could work effectively, but required the LLM to generate bash scripts for parallelization. By converting to a proper Pi extension, pi-recurse achieves:

  • True programmatic looping — parallel execution happens in TypeScript code, not bash generated by the LLM
  • Better integration — hot-reload with /reload, automatic tool discovery, native Pi packaging
  • Structured results — full TypeScript types instead of bash string manipulation
  • Single entry point — just pi, no wrapper scripts needed

Thank you to the original ypi for pioneering the concept of depth-limited recursive LLM calls in a coding agent context.


Installation

Via npm (Recommended)

pi install npm:pi-recurse

Local Development

git clone https://github.com/monotykamary/pi-recurse.git
cd pi-recurse
pi install .

The extension will be auto-discovered by Pi on next start, or use /reload to load it immediately.


Usage

The extension adds a recurse tool to Pi, enabling three execution modes:

Single Mode — One-off delegation

recurse({
  mode: 'single',
  prompt: 'Analyze the error handling in src/auth.ts',
  context: fileContent, // optional context to pipe
});

Parallel Mode — Batch processing

recurse({
  mode: 'parallel',
  tasks: [
    { id: 'auth', prompt: 'Review auth module' },
    { id: 'db', prompt: 'Review database layer' },
    { id: 'api', prompt: 'Review API routes' },
  ],
  concurrency: 3,
  timeoutPerTask: 120,
});

Key advantage: All 3 subagents spawn from a single LLM tool call. The extension handles Promise.all() style concurrency internally — no autoregressive steps between spawns.

Chain Mode — Sequential dependencies

recurse({
  mode: 'chain',
  chain: [
    { id: 'read', prompt: 'Read README.md and summarize' },
    { id: 'analyze', prompt: 'Given this summary: {previous} — identify risks' },
    { id: 'plan', prompt: 'Given these risks: {previous} — suggest mitigations' },
  ],
});

Guardrails

Environment variables control recursion limits across the entire call tree:

| Variable | Default | Description | | --------------------- | ------- | ------------------------------------ | | RLM_MAX_DEPTH | 3 | Maximum recursion depth (0 = root) | | RLM_MAX_CALLS | 100 | Maximum total recurse invocations | | RLM_TIMEOUT | 600 | Wall-clock seconds for entire tree | | RLM_BUDGET | — | Max dollar spend (e.g., 0.50) | | RLM_CHILD_MODEL | — | Model override for depth > 0 | | RLM_DISABLE_TOOL_AT | 3 | Disable recurse tool at this depth | | RLM_TRACE_ID | auto | Links all sessions in recursive tree |

At deep depths (≥ RLM_DISABLE_TOOL_AT), the recurse tool automatically disables itself and guides agents to work directly instead of delegating.


Architecture: From Bash to Extension

Original ypi (Bash Wrapper)

ypi "analyze this codebase"
    ↓
Launcher sets env, execs pi with custom system prompt
    ↓
LLM generates bash loop for parallel tasks:
    for f in $(find src -name "*.ts"); do
        rlm_query --async "Review $f"
    done
    ↓
Wait on sentinel files, aggregate in bash

Limitation: The LLM had to generate the loop structure, and parallelization required autoregressive generation of bash code.

pi-recurse (Pi Extension)

pi (with pi-recurse extension loaded)
    ↓
LLM calls once: recurse({mode: "parallel", tasks: [...]})
    ↓
Extension execute() runs in Node.js:
    ├── Check guardrails (depth, budget, timeout)
    ├── runParallel(tasks, spawnFn, concurrency)
    │   └── Promise.all(concurrent batches)
    ├── Aggregate structured results
    └── Return {results, stats, depth}
    ↓
LLM receives aggregated data, continues reasoning

Advantage: Parallel execution happens in code, not in LLM-generated bash. One tool call → many subagents → aggregated result.


Comparison: ypi vs pi-recurse

| Feature | ypi (Wrapper) | pi-recurse (Extension) | | --------------------- | ------------------------ | --------------------------------- | | Entry point | ypi "prompt" | pi (extension auto-loaded) | | Parallel spawning | LLM writes bash loop | Code executes Promise.all() | | Result aggregation | Bash string manipulation | TypeScript structured objects | | Hot reload | Restart ypi process | /reload in pi | | Distribution | npm global bin | pi install / git URL | | Extension integration | Manual env/PATH setup | Native auto-discovery | | Tool disabling | Manual depth checks | Automatic at configured depth | | Status visibility | Footer via ypi.ts | Native Pi status bar |


Development

# Clone and install dependencies
git clone https://github.com/monotykamary/pi-recurse.git
cd pi-recurse
npm install

# Run tests
npm test

# Type check
npm run typecheck

# Build (optional - jiti handles TypeScript at runtime)
npm run build

Testing the Extension

# Install locally
pi install .

# Or test without installing
pi -e ./index.ts

# In pi, test recursion
/recurse-status
recurse({mode: "single", prompt: "What is 2+2?"})

Design Principles

  1. Single tool call, parallel execution — The LLM describes intent; code handles concurrency
  2. Depth-aware degradation — At deep levels, disable recursion to prevent runaway costs
  3. Structured over stringly — Full TypeScript types for inputs and outputs
  4. Guardrails in code — Budget, timeout, depth checked programmatically
  5. Pi-native integration — Use Pi's extension API, not wrapper scripts

Related Projects

  • ypi — The original bash wrapper that inspired this extension
  • pi-messenger — Multi-agent coordination for Pi (another extension)
  • pi — The Pi coding agent itself

License

MIT — See LICENSE for details.