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

@bitmonk8/pi-theta

v0.12.0

Published

A scripting language for Pi agents: write the predictable parts of an agent task as code and leave only the fuzzy parts to the model.

Readme

pi-theta

pi-theta is a Pi Coding Agent extension that adds Theta, a scripting language for Pi agents. Write the predictable parts of an agent task as code and leave only the genuinely fuzzy parts to the model — no custom extension required.

A .theta file mixes ordinary code — variables, loops, conditionals, functions — with the text you send to the model. Running a theta adds turns to a conversation: either the caller's current one (prompt mode) or a fresh, isolated one (subagent mode). When it succeeds it can also return a final value — the theta's last expression, or the value you return — which callers can use and pass back across the subagent boundary. Thetas can't write files, use the network, or spawn processes on their own; those effects happen only through the Pi tools a theta is allowed to call (its callable set). .thetalib files are library modules that share Theta's grammar and types and are imported by .theta files; they are never run directly.

The problem

Pi's built-in prompt and subagent features are just Markdown with some fill-in-the-blanks — static text with YAML frontmatter. They can't branch, loop, read a model's response, carry a conversation across several turns, or hand a typed value back to the caller. Theta does all of that: your code decides what text goes to the model, the model's replies come back as values, and every run ends in one of three ways — success, failure, or cancellation — defined in Errors and Results.

Example: an agent loop

The pattern people call an agent loop (or a Ralph loop) is: run the model, check the result, then stop or go again. The usual version is a shell loop that re-runs the model and hopes it eventually declares itself done. In Theta the loop is real code, so your code owns the stop condition and the model just does the work inside each round.

The worker docs/examples/ralph-step.theta does one round of work on a fresh context and hands back a typed result. State lives on disk — the files it edits, the commits it makes — not in the conversation:

---
description: Do the next task toward the objective on a fresh context, then report status
mode: subagent
params:
  objective: string
tools:
  - read
  - bash
---
schema Progress {
  done: boolean,
  summary: string
}

let status: Progress = @`Objective: ${objective}

Inspect the current state of the project, do the single most important unfinished
task toward the objective, run the test suite with bash, commit the result, and
report whether the objective is now fully met.`?
status

The loop docs/examples/ralph.theta takes an objective, passes it to the worker, and re-runs the worker on a fresh context until it reports done — or hits the round ceiling:

---
description: Re-run the worker on a fresh context until the objective is met (a Ralph loop)
mode: subagent
params:
  objective: string
tools:
  - ./ralph-step.theta
---
let mut round = 0
while round < 20 {
  round += 1
  let status = ralph_step(objective)?
  if status.done {
    return status.summary
  }
}
"stopped at the 20-round ceiling"

Put both files on the discovery path with --theta, and ralph.theta is available as the /ralph slash command — the argument becomes its objective:

pi --theta docs/examples -p "/ralph get the integration tests passing"

Or, from inside a running pi session (once the directory is on your theta discovery path), just type the slash command:

/ralph get the integration tests passing

The while bound, the done check, and the round ceiling are ordinary code — not a magic "done" string grepped out of the model's prose. The two files can also be collapsed into one: a subagent fn (theta 1.2) is a fn whose body runs in a fresh isolated session per call, so the worker becomes an in-file function and the loop calls it by name — see docs/examples/ralph-inline.theta and How to write an agent loop, which also has a second, self-contained example you can run without any external tools.

Status

Theta is at 0.12.x. The whole documented language works and is tested end-to-end, but this is an early release and may still contain bugs. As of 0.9.0, a subagent-mode invocation runs the whole callee theta — interpreter included — in a spawned child pi process (params and the typed return value cross the process boundary structurally); as of 0.12.0 that child is spawned with stdin already closed, fixing a startup deadlock that hung every real subagent invocation under pi -p (bug 0002). As of 0.11.0 a theta's tools: list can name extension-registered Pi tools in both modes, not only in a subagent, and an admitted extension tool is reachable both by the theta's model and from theta code — a code-side call is dispatched deterministically through a host agent loop (the child's own in subagent mode, since 0.10.0; your live session's in prompt mode, since 0.11.0), zero model tokens. In prompt mode the code-side dispatch visibly appends tool-call cards to your own transcript — an accepted, documented cost — see the CHANGELOG and Guide — Extension tools.

Report issues against the behaviour the Reference defines.

Documentation

  • Guide — how Theta works: mixing code with the text you send to the model, prompt vs. subagent mode, .theta vs. .thetalib, and the final value.
  • Tutorial — build your first theta, from an empty file to a working one.
  • How-to guides — short recipes for specific tasks, including writing an agent loop and fanning out in parallel.
  • Reference — the full details: grammar, type system, frontmatter fields, errors and results, limits, diagnostics, and the CLI.