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-maestro-teammate

v0.4.2

Published

Pi extension — teammate agent dispatch with DAG task graphs, RPC messaging, and compact TUI

Readme

pi-teammate

Teammate dispatch tool for Pi — unified TaskSpec with DAG variable referencing + resident agent model

Pi extension implementing teammate dispatch with unified TaskSpec model. Single agent, parallel fan-out, sequential chains, and arbitrary DAGs all use the same schema — execution order is determined by {name} variable references between tasks.

Automatic Model Routing

Teammate maps task phases to models authenticated in the current Pi session. Supported task types are explore, analysis, debug, planning, development, review, and testing.

Open the mapping overlay with Alt+M or /teammate-models. Project mappings are saved to .pi/teammate-models.json; global defaults can be stored in ~/.pi/agent/teammate-models.json, with project values taking precedence.

{
  "version": 1,
  "mappings": {
    "explore": "google/gemini-2.5-pro",
    "analysis": "openai/gpt-5",
    "debug": "anthropic/claude-opus-4"
  }
}

Precedence is task-level model → top-level model → explicit taskType mapping → inferred task type → agent default. Omit model to use routing:

{
  "agent": "explorer",
  "taskType": "explore",
  "task": "FIND: auth middleware\nSCOPE: src/auth/",
  "background": false
}

Quick Start

Single Agent

{ agent: "delegate", task: "Implement the auth middleware" }

Parallel (no references = concurrent)

{ tasks: [
    { agent: "scout", task: "Find all API endpoints" },
    { agent: "scout", task: "Map database schemas" },
    { agent: "scout", task: "List external dependencies" }
  ],
  concurrency: 3
}

Chain (linear references = sequential)

{ tasks: [
    { agent: "scout", name: "recon", task: "Find the auth module structure" },
    { agent: "delegate", task: "Based on this context: {recon}\n\nRefactor the auth module" }
  ]
}

DAG (mixed references = auto-scheduling)

{ tasks: [
    { agent: "scout", name: "api", task: "List all API routes",
      outputSchema: {
        type: "object",
        properties: { routes: { type: "array", items: { type: "string" } } },
        required: ["routes"]
      } },
    { agent: "scout", name: "db", task: "Map the database schema" },
    { agent: "reviewer", task: "Routes: {api.routes}\nDB: {db}\n\nCheck consistency" }
  ]
}

api and db run in parallel. reviewer waits for both, with {api.routes} resolved from structured output and {db} from text output.

Structured Output

{ agent: "scout", task: "List all API routes",
  outputSchema: {
    type: "object",
    properties: { routes: { type: "array", items: { type: "string" } } },
    required: ["routes"]
  }
}

In multi-task mode, structured outputs are aggregated by task name in the result's structuredOutput field.

Core Concepts

Two Rules

  1. Reference = dependency: {name} in a task's description means "wait for the task named name to complete, then inject its output here"
  2. No reference = parallel: tasks with no dependencies run concurrently (bounded by concurrency)

No mode field needed — the execution engine infers parallel, chain, or graph from the reference topology.

Variable References

| Syntax | Resolves to | |--------|-------------| | {name} | Full text output; or JSON string if the task has outputSchema | | {name.field} | Field from structured output | | {name.arr[0].path} | Nested field with array indexing |

Only tasks with a name field can be referenced. Non-task {braces} (JSON, format strings) are left untouched.

Default Inheritance

Top-level fields serve as defaults for all tasks:

| Field | Scope | Override | |-------|-------|----------| | model | Default model for all tasks | Per-task model wins | | cwd | Default working directory | Per-task cwd wins | | outputSchema | Default schema for all tasks | Per-task outputSchema wins | | timeoutMs | Default timeout | Per-task timeoutMs wins |

Three-Axis Control

| Axis | Field | Values | Purpose | |------|-------|--------|---------| | Addressability | name | string | omit | Variable referencing + teammate-send routing | | Result Routing | reply_to | "caller" | "main" | Where results go | | Lifecycle | lifecycle | "ephemeral" | "resident" | One-shot or persistent |

Protocol version gate — v2 (default) routes results to caller; v1 compat routes named agents to main. Explicit reply_to always wins.

Resident Agent Model

Agents don't exit after completing a task. Instead they enter a sleeping state and can be woken up for follow-up work.

Lifecycle

dispatch → running → turn complete → sleeping → teammate-send → running → ...
                                                                         ↓
                                                              abort → terminated

| Status | Description | |--------|-------------| | running | Agent is actively processing a task | | sleeping | Turn complete, process alive, waiting for teammate-send to wake | | completed | Agent terminated (via abort or session shutdown) |

How It Works

  1. Agent completes its turn → agent_end event fires
  2. Result is reported to the main session (background notification)
  3. Agent enters sleeping state — RPC process stays alive, stdin open
  4. teammate-send({ to: "name", message: "new task" }) sends a follow_up → agent wakes up and processes the new message
  5. teammate-send({ to: "name", mode: "abort" }) terminates the agent

Active Time Tracking

Time spent sleeping is excluded from the displayed duration. sleepMs accumulates total sleep time; displayed uptime = wall clock − sleep time.

Agent Fallback

Any agent name works — if no .md definition file exists, a generic config is used:

  • tools: read, grep, find, ls, bash, edit, write (+ teammate proxy tools)
  • systemPromptMode: append (inherits pi default system prompt)
  • inheritProjectContext: true

TaskSpec Schema

interface TaskSpec {
  agent: string;        // Agent name (matches agents/*.md, or any name with fallback)
  task?: string;        // Task description with {name} variable support
  name?: string;        // Identifier for referencing and teammate-send
  model?: string;       // Model override
  cwd?: string;         // Working directory
  outputSchema?: object; // JSON Schema for structured output
  timeoutMs?: number;   // Timeout in milliseconds
}

Full Parameters

interface TeammateParams extends TaskSpec {
  // Multi-task
  tasks?: TaskSpec[];     // Multiple tasks with {name} references
  concurrency?: number;   // Max concurrent tasks (default: 4)

  // Execution control (applies to ALL modes)
  background?: boolean;   // Run in background (default: true)
  context?: "fresh" | "fork";

  // P0 three-axis
  reply_to?: "caller" | "main";
  protocol_version?: number;

  // Deprecated
  chain?: Array<{ agent, task?, model? }>; // Use tasks with {name} references
}

Validation & Error Handling

  • Duplicate names: detected before execution, all tasks fail with error
  • Circular dependencies: detected before execution via cycle detection
  • Missing reference: {unknown} left as literal text (not a task name)
  • Field access without schema: error when {name.field} used but task has no outputSchema
  • Upstream failure: dependent tasks are skipped with "upstream dependency failed"

Deprecated: chain[]

The chain field is preserved for backward compatibility. It normalizes internally to tasks with sequential {_stepN} references:

// This chain:
{ chain: [
    { agent: "scout", task: "Find auth code" },
    { agent: "delegate", task: "Fix: {previous}" }
  ]
}

// Is equivalent to:
{ tasks: [
    { agent: "scout", name: "_step0", task: "Find auth code" },
    { agent: "delegate", name: "_step1", task: "Fix: {_step0}" }
  ]
}

Flat Agent Model

All agents are managed by the root process in a single flat activeRuns pool, regardless of who requested the spawn. Child agents that call the teammate tool send a proxy request to the root via IPC, which spawns the new agent as a peer — not a nested subprocess.

How It Works

coordinator calls teammate({ agent: "scout", name: "recon" })
  │  IPC: teammate_proxy_request (process.send)
  ▼
Root spawns scout → registers in root's activeRuns/namedAgents
  │  IPC: teammate_proxy_result (child.send)
  ▼
coordinator receives result

All agents are flat peers:

  • teammate-send({ to: "name" }) = one lookup in namedAgents → stdin. Direct delivery.
  • teammate-list = iterate activeRuns. Flat, simple.
  • teammate-watch = read agent's outputLog. Direct.

Child Proxy Tools

Every child process automatically gets proxy versions of all 4 teammate tools (injected into --tools whitelist regardless of agent definition). Each proxy:

  1. Sends a teammate_proxy_request via Node.js IPC (process.send())
  2. Awaits the result via IPC (process.on("message"))

The root's IPC message listener (child.on("message")) intercepts these requests and executes them locally.

Reliability

  • Model fallback chain — primary model → fallbackModels[] from agent config → automatic retry
  • Flat agent pool — all agents managed by root process; child proxy tools forward spawn requests to root; depth guard (PI_TEAMMATE_DEPTH) prevents runaway recursion
  • Resident lifecycle — agents sleep after turn completion; process stays alive for follow-up; only killed on explicit abort or session shutdown
  • IPC disconnect guard — child proxy resolves all pending requests with error on disconnect (root crash / agent abort)
  • Windows-safe pi resolutiongetPiSpawnCommand() resolves the pi binary via env override, Windows script detection, or PATH
  • Abort signal — SIGTERM → 5s grace → SIGKILL

Agent Definition Format

Create agents/my-agent.md:

---
name: my-agent
description: Short description of what this agent does
tools: read, grep, find, ls, bash, edit, write
model: anthropic/claude-sonnet-4
fallbackModels: google/gemini-2.5-pro, anthropic/claude-haiku-4
systemPromptMode: replace
inheritProjectContext: true
inheritSkills: false
defaultContext: fresh
---

You are a specialized agent. Your system prompt goes here.

Frontmatter Fields

| Field | Type | Default | Description | |-------|------|---------|-------------| | name | string | required | Agent identifier | | description | string | required | Short description | | tools | comma-sep | all | Available tools | | model | string | parent model | Primary model | | fallbackModels | comma-sep | — | Fallback model chain | | thinking | string | — | Thinking level (low/medium/high) | | systemPromptMode | append|replace | replace | How system prompt is applied | | inheritProjectContext | bool | false | Inherit parent project context | | inheritSkills | bool | false | Inherit parent skills | | defaultContext | fresh|fork | fresh | Default context mode |

Install

pi install npm:pi-maestro-teammate
# or from local path
pi install ./pi-teammate

Environment Variables

| Variable | Description | |----------|-------------| | PI_TEAMMATE_PI_BINARY | Override pi binary path | | PI_TEAMMATE_CHILD | Set to "1" in child processes | | PI_TEAMMATE_DEPTH | Current nesting depth | | PI_TEAMMATE_CORRELATION_ID | Correlation ID for routing | | PI_TEAMMATE_REPLY_TO | Resolved reply target | | PI_TEAMMATE_PARENT_SESSION | Parent session file path |

License

MIT

Agent discovery

Agent Markdown files are loaded with project-over-user-over-builtin precedence:

  1. nearest project .pi/agents/*.md
  2. ~/.pi/agent/extensions/teammate/agents/*.md
  3. this npm package's bundled agents/*.md

Pi has no native pi.agents package manifest field. Builtin teammate agents are resolved relative to the installed extension module, so npm, git, global and local Pi package installs all use the same package-local agents/ directory.

Fixed prompt templates

teammate can load Pi-compatible Markdown prompt templates with prompt and promptArgs. Discovery priority is project .pi/prompts/*.md, user ~/.pi/agent/prompts/*.md, then this package's prompts/*.md. Template syntax uses Pi's $1, $2, $@, $ARGUMENTS, ${1:-default}, and ${@:N:L} forms. The task value is $1; promptArgs start at $2.

{
  "agent": "delegate",
  "prompt": "analysis",
  "task": "Analyze the authentication flow",
  "promptArgs": ["@src/auth/**/*.ts", "file:line evidence"],
  "model": "provider/model",
  "background": true
}