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

@topce/pizx

v2.4.0

Published

zx fork with native Pi AI integration on the cordis plugin framework — shell scripting with AI agents, user-definable letter tags, traceable runs with JSONL log export, and a local result cache. Ships with π (text generation), Π (coding agent), α (any ACP

Readme

pizx — zx fork with native Pi AI integration, on cordis

npm version GitHub Sponsors

pizx — zx fork with native Pi AI integration

AI-powered shell scripting for Node.js — a zx fork with native Pi AI integration, built on the cordis plugin framework. Core ships π (text generation), Π (coding agent), α (any ACP-compatible agent), ε (any CLI AI harness — claude, kiro-cli, …), and TypeSafe's typed decisions choice/score/noul — and you define your own letters as plugins. Every run is traceable and exportable as JSONL, and cacheable letters hit a local result cache.

#!/usr/bin/env pizx

const answer = await π`what is the capital of France?`
echo(answer)

await Π`fix the TypeScript errors in src/`

Quick Start

# Step 1: Install Pi CLI (one-time) — needed for AI credentials
npm install -g @earendil-works/pi
pi auth login

# Step 2: Install pizx in your project
npm install @topce/pizx

Write a script (hello.mjs):

#!/usr/bin/env pizx

// Simple AI query
const answer = await π`what is the capital of France?`
echo(answer)

// Shell + AI, zx-style
const files = await $`ls src/`
const summary = await π`summarize these files in one sentence: ${files}`
console.log(summary)

Run it:

chmod +x hello.mjs
./hello.mjs          # or: pizx hello.mjs

Prerequisites: Node.js >= 22.19.0, Pi AI CLI configured with pi auth login. No separate zx install needed — pizx bundles zx; $, cd, echo, fetch and friends come built-in.

The letters

| Letter | What it does | |---|---| | π (pi, ai) | Pi AI text generation — ask a model anything, stream it, cache it | | Π (Pi, piAgent, codingAgent) | Pi coding agent with tools (read, bash, edit, write, grep, …) | | α (acp, agent) | Any ACP-compatible coding agent (server required — no pi needed) | | ε (run, harness, cli) | Any CLI AI harness — claude, kiro-cli, opencode, … (binary required — no pi needed) | | noul (Noul) | TypeSafe yes/no probability — calibrated System One decisions | | choice (Choice) | TypeSafe pick-one-label classification, with confidence | | score (Score) | TypeSafe position on an ordered rubric, with confidence |

const answer = await π({ model: 'anthropic/claude-sonnet-4-5' })`explain async/await`
const json = await π.quiet()`generate a JSON array of 5 colors`
for await (const chunk of π.stream`tell me a story`) process.stdout.write(chunk)

await Π({ tools: ['read', 'bash', 'edit'] })`refactor the auth module`

// α speaks the generic Agent Client Protocol — any ACP v1 server works:
await α({ server: ['kiro-cli', 'acp'] })`fix the TypeScript errors in src/`

// ε runs any CLI AI harness; unknown options become its CLI flags:
await ε({ harness: 'claude', model: 'sonnet' })`review this diff`   // claude -p --model sonnet …

// TypeSafe turns a model's judgment into a typed, calibrated value:
const refund = await noul({ instructions: 'Is a refund requested?' })`${ticket}`
const team   = await choice({ instructions: 'Which team?', criteria: { billing: '…', tech: '…' } })`${ticket}`
refund.text            // '0.99' — the usable scalar
refund.answer.confidence  // full typed answer (confidence, probabilities, …)

All letters return a LetterOutput: text, modelId (alias modelUsed), isFromCache (alias fromCache), timing, and token/cost getters — plus output.trace with the LLM calls of that invocation. TypeSafe letters and pattern words additionally set .answer with the structured result. Full option tables: π, Π, α, ε, TypeSafe. α and ε are independent of pi entirely: α drives any ACP server command you name; ε drives any harness binary you have installed (e.g. Kiro, Claude Code).

TypeSafe letters need TYPESAFE_API_KEY (get one); the client is built lazily, so apps that never use them boot without a key.

Define your own letters

pizx is a plugin host. A letter is a cordis plugin that registers a template tag — full guide in docs/extension.md:

// plugins/summarize.mjs
import Schema from 'schemastery'

export const name = 'summarize'
export const inject = ['letters', 'llm']

export function apply(ctx) {
  ctx.letters.define('Σ', {
    aliases: ['summarize'],
    options: Schema.object({ maxWords: Schema.natural().default(30), model: Schema.string() }),
    run: async (prompt, opts, { ctx }) => {
      const result = await ctx.llm.ask(
        `Summarize in at most ${opts.maxWords} words:\n\n${prompt}`,
        { model: opts.model }
      )
      return result.text
    },
  })
}

export default { name, inject, apply }
// pizx.config.mjs — next to your script (loaded automatically)
import summarize from './plugins/summarize.mjs'
export const plugins = [summarize]
#!/usr/bin/env pizx
const summary = await Σ({ maxWords: 20 })`pizx is…`

Your letters get the full built-in DX automatically: option chaining, .quiet / .cache variants, .stream support, tracing, caching, and globals injection (pizx --letters lists them). Collisions are errors, unloading a plugin removes its letters (cordis effects), and inject dependencies make load order irrelevant.

Words — composable AI patterns

Words are named AI patterns built by composing letters; a word is itself a letter, so words compose recursively. Eleven ship as ready-made plugins in examples/plugins/ — the seven patterns from Anthropic's Building effective agents plus four TypeSafe patterns — and load through pizx.config.mjs like any plugin:

| Word | Aliases | Pattern | |---|---|---| | ralph | loop | Agent loop — iterative analyze/plan/execute/review | | fleet | parallel | Parallelization: sectioning — split prompt, fan out | | chain | pipeline | Prompt chaining — sequential steps + optional gate | | route | branch | Routing — classify, then dispatch | | vote | jury | Voting — N parallel answers, tallied | | refine | optimize | Evaluator-optimizer — revise against criteria until PASS | | orchestrate | director | Orchestrator-workers — decompose, fan out, synthesize | | fanout | fan-out | TypeSafe speculative fan-out — many questions, one call | | composite | composite-scoring | TypeSafe composite scoring — weighted dimensions | | gate | confidence-routing | TypeSafe confidence-gated routing | | intent | intent-routing | TypeSafe intent routing — classify and dispatch |

await chain({ steps: ['outline', 'π'] })`write a document about X`
await route({ routes: { refund: 'π', tech: 'Π' } })`support query`
await vote({ votes: 5 })`is this diff safe to merge?`
await refine({ criteria: 'no jargon, under 50 words' })`explain monads`
await orchestrate`audit the docs for inconsistencies`

Every word's letters live in replaceable slots — ralph({ execute: 'α' }), fleet({ worker: 'Π' }) — and letters needing options get them through the word (server, model, cwd, … are forwarded). Full reference: docs/words.md.

Traceable, exportable, cache-friendly

pizx --trace script.mjs                 # token/cache/cost summary on stderr
pizx --export-log script.mjs            # .pizx/logs/<runId>.jsonl
pizx --export-log /tmp/run.jsonl s.mjs  # explicit path (also on crashes)
pizx --cache script.mjs                 # enable the local result cache

Every run is a JSONL-exportable event log (run-start, letter-start, llm-call with disjoint input/output/cache-read/cache-write tokens, cache-hit/cache-miss, letter-end, run-end) — deepseek-harness style. --trace prints totals; repeated calls to cacheable letters hit a content-addressed local cache (.pizx/cache, TTL + LRU) and record cache-hit instead of an LLM call. Π sessions are pooled per model/tools, keeping provider prompt caches warm. Details: docs/trace.md.

const app = await createPizx({ cache: true })
const first = await app.π.cache`what is 7! + 5?`
const second = await app.π.cache`what is 7! + 5?`
second.fromCache            // true — no second LLM call
app.exportLog('jsonl')      // the whole run, one event per line
await app.dispose()

CLI

pizx script.mjs                # run a script (every registered letter is a global)
pizx -p "your prompt"          # quick pi-ai query
echo "your prompt" | pizx -p - # read the prompt from stdin
pizx --acp --acp-server "kiro-cli acp" "your prompt"  # quick ACP agent query
pizx --run --run-harness claude "your prompt"         # quick CLI harness query
pizx --Pi "your prompt"        # quick coding-agent query (Π, tools enabled)
pizx --Pi --session auth --tools read,edit "continue"  # durable Π conversation
pizx --Pi --codemode "count the TS files"  # + JS sandbox over tools
pizx --Pi --mcp "use the radius server"    # + MCP servers from mcp.json
pizx --model <id> script.mjs   # model for the run
pizx --config ./cfg.mjs s.mjs  # load plugins from a config file
pizx --letters                 # list registered letters
pizx --cache | --no-cache      # toggle the local result cache
pizx --json -p "your prompt"   # machine-readable output (implies --quiet/--no-color)
pizx --no-color script.mjs     # disable ANSI color (also honors NO_COLOR)
pizx --trace --export-log s.mjs
pizx --version | --help

Machine-readable output for agents: --json emits a result envelope ({ text, modelId, fromCache, durationMs, tokens, costUsd }) or, with --letters, the letter registry; failures print { error: { code, message } } to stderr and exit with a distinct code (2 usage · 3 auth · 4 agent · 5 acp · 6 cancelled · 7 internal · 8 harness). See AGENTS.md.

Programmatic use

import { $, π, Π } from '@topce/pizx'          // lazy default app
import '@topce/pizx/globals'                   // or everything as globals

import { createPizx } from '@topce/pizx'       // explicit app
const app = await createPizx({ cache: true, plugins: [summarize] })
await app.π`hello`
await app.letter('Σ')`summarize this`
console.log(app.traceSummary())
await app.flushLog('run.jsonl')
await app.dispose()

Docs

  • AGENTS.md — guide for AI agents writing pizx code (script template, letters, --json, exit codes)
  • Onboarding — architecture and file map
  • Defining letters — the plugin API
  • Words — composing letters into AI patterns (the word library)
  • Trace & logs — event format, export, cache-friendliness
  • π · Π · α · ε — built-in letter references
  • α idea — the ACP letter's design rationale and roadmap

What happened to the 0.9 patterns?

pizx 1.0 rewrote the core on cordis and ships π, Π, α, and ε — the 16 hardcoded pattern tags (Ralph, Fleet, Debate, Pipeline, …) are gone from the core and come back as letter plugins. Seven already have: ralph, fleet, chain (pipeline), route (branch), vote (jury), refine (optimize), and orchestrate (director) ship as word plugins in examples/plugins/ — plus the four TypeSafe pattern words (fanout, composite, gate, intent). See docs/words.md and docs/typesafe.md. The old code lives in the 0.9 branch.

License

MIT