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

subharness

v0.0.7

Published

Run native coding agents from application code or a local CLI, with sessions and optional specialists.

Readme

subharness

Stay with your favorite coding agent. Ask it to delegate tasks across Codex, Claude Code, fx, OpenCode, GitHub Copilot, and Cursor, and bring results back to one conversation. The main agent uses the local subharness CLI to start independent native sessions, check their status, read complete responses, and report the results.

TypeScript definitions are optional. Add them when your coding agent needs reusable specialists with shared instructions, tools, or harness alternatives. Codex and Claude Code use eligible native subscription logins or explicitly configured API access. fx, OpenCode, and GitHub Copilot accept explicitly configured native logins, direct API keys, or Vercel AI Gateway access. Cursor uses an explicitly configured native CLI login or Cursor API key.

Use the Node.js execution SDK to build an agent-running UI or expose a specialist as a tool in an existing chat. The application owns its runner and can observe task states, approval requests, and complete responses without invoking the Subharness CLI.

The library coordinates sessions, queues, and subagents. Harnesses own model execution, native tools, and context. You supply the working directory and any sandbox or worktree isolation.

Installation

Node.js 22.18 or newer is required. Install the CLI from npm:

npm install --global subharness

cd /path/to/your-project
subharness --help

Global installation exposes subharness on PATH, with agent retained as a compatibility alias. You can also use npx subharness without installing a global executable. Direct harness runs need no TypeScript file or SDK dependency in the target project. Install and authenticate the native harness separately. Specialist definitions need a project-local SDK dependency so imports resolve; global definitions likewise need a reachable SDK dependency.

Optionally install the agent skill to teach your coding agent how to delegate with subharness:

npx skills add vercel-labs/subharness

The installer requires access to the subharness repository while the repository is internal. See the agent-skill reference for installation behavior and boundaries.

See package distribution for development checkouts, local tarballs, and package boundaries. Maintainers publish through the GitHub release procedure. subharness uses the Apache License 2.0.

Delegate from your coding agent

In the conversation you already use, ask your coding agent:

Delegate the pagination fix and its tests to Claude Code. While that runs, ask Codex to review the README's setup instructions.

With shell access to your project, the main agent uses commands like these:

subharness run claude --prompt "Fix the pagination bug in search results. Add a regression test and run the relevant checks."
subharness run codex --prompt "Review the README's setup instructions against the current installation and authentication behavior. Report any inaccuracies."

Each command starts an independent session. The delegated agent receives the explicit task prompt and the project context it can inspect, not a copy of the main conversation's transcript. Overlapping work requires the main agent's host to support background shell execution. A completed command makes its result available, but notification and automatic reactivation of the main conversation also depend on that host. During the coordinator's lifetime, the main agent can retrieve the complete latest retained response with subharness status <task-id> --full; records and queues are not restored after coordinator loss.

You can also invoke a harness manually:

subharness run claude "Review the current diff."
subharness run codex --cwd /path/to/worktree "Implement the documented feature."
subharness run fx --model "provider/model" "Compare the proposed implementations."
subharness run opencode --model "creator/model" "Inspect the current implementation."
subharness run copilot --model "creator/model" "Review the current diff."
subharness run cursor --model "CURSOR_MODEL_ID" "Implement the documented change."
subharness run claude --help

Replace provider/model or creator/model with an available Gateway model identifier. fx, OpenCode, and Copilot require an explicit compatible connection as described under Access below. Non-Gateway routes use their documented native model identifiers. Cursor requires explicit subscription or Cursor API-key access. OpenCode, Copilot, and Cursor require --model and reject --effort. Codex, Claude Code, and fx use a verifiable native default when possible and accept their documented effort values. These options do not override a TypeScript specialist.

Prompts can be one quoted argument, --prompt, or a UTF-8 file. --prompt-file - reads piped stdin explicitly. Exactly one prompt source is accepted, with a 1 MiB limit.

subharness run claude --prompt-file ./review-task.txt
subharness run codex --prompt-file - < ./task.txt

Use subharness dashboard in a terminal to watch agents managed by the local coordinator. The live view groups agents by repository/worktree, pins the checkout containing the launch directory first, and orders other groups by their latest agent update. Each group shows current agents followed by finished runs, with harness, task title, elapsed time, and status. Finished history is retained for the coordinator’s lifetime. Use Up/Down to select a run and Enter to open its agent session’s request history. Queued requests appear first, followed by remaining requests newest first. Enter expands a request’s prompt and response; Escape returns to the overview. Completed statuses are green, and a compact Sub-agents footer summarizes direct child agents. The overview has no application banner or footer. Ctrl+C closes the view without stopping agents.

Run agents from application code

Install subharness as an application dependency:

npm install subharness

Create an application-owned runner and pass an in-memory definition:

import { agent, codex, createRunner } from "subharness";

const reviewer = agent({
  name: "reviewer",
  description: "Reviews the requested changes.",
  instructions: "Report concrete findings with file references.",
  harness: codex({ model: "CODEX_MODEL_ID" }),
});
const runner = createRunner();
try {
  const session = await runner.createSession(reviewer, { cwd: "/absolute/project/path" });
  const { task } = await session.prompt("Review the current diff.");
  // A separate UI handler must answer any pending approvals.
  console.log((await task.result).text);
  // Reuse session.prompt(...) for follow-ups in the same conversation.
} finally {
  await runner.close();
}

Replace the model placeholder with an available native model. A UI can consume task.watch({ signal }) for current and changed snapshots. Aborting observation leaves execution running; a Stop action calls task.cancel(). Keep the runner for the chat/job lifetime and await runner.close() when that scope ends. Native harnesses still need installation and authorized access.

Tool functions can close over application services. Embedded sessions keep them in the host process, with its unchanged cwd and environment. Declared subagents use hosted tools instead of CLI launchers. An existing chat app can register a tool whose execute calls session.prompt, while retaining its own model loop, authorization, and UI transport.

To connect a UI backend to agents started by the CLI, use the shared coordinator:

import { connect } from "subharness";

const client = await connect(); // Connects or starts an empty coordinator.
try {
  const { items: sessions } = await client.sessions.list();
  console.log(sessions);
  // client.sessions.get(id) retrieves the same conversation used by the CLI.
} finally {
  await client.disconnect(); // Execution continues in the shared coordinator.
}

Use connect({ start: false }) for strict attachment. Approval requests advertise actions; submit a chosen action with client.approvals.respond(request.id, { actionId: action.id }), adding explicitly selected grants when required. Applications can render the supplied labels without provider-specific branches.

The SDK exposes complete responses, task states, and approvals, without token deltas or native tool-progress events. History lasts for the owning coordinator's lifetime; restart recovery is not provided. See the execution API and chat-tool example for lifecycle and integration details. Embedded access is explicit through createRunner({ access, env }); connected sessions use the CLI's existing project access settings.

Define a reusable specialist

Install the SDK in the project before adding definitions:

npm install --save-dev subharness

Create .subharness/agents/developer.ts in your repository:

import { agent, codex, claudeCode } from "subharness";

export default agent({
  name: "developer",
  description: "Implements features and verifies changes.",
  instructions: "Follow the repository's documented requirements and run its checks.",
  harness: [
    codex({ model: "CODEX_MODEL_ID", effort: "high" }),
    claudeCode({ model: "CLAUDE_MODEL_ID", effort: "high" }),
  ],
});

Replace the model placeholders with identifiers available through your native harnesses. Each file default-exports one definition. Global definitions live in ~/.subharness/agents/; repository and global names never silently override one another. The bare targets codex, claude, fx, opencode, copilot, and cursor are reserved for harnesses; a specialist with one of those names requires a scope qualifier such as repo:claude.

Run and follow up

subharness list
subharness run repo:developer --cwd /path/to/worktree --prompt "Implement the documented feature."
subharness send <session-id> --delivery queue --prompt "Add the integration tests."
subharness send <session-id> --delivery steer --prompt "Keep the existing API compatible."
subharness wait <task-id> [--after <response-id>]
subharness status <task-id> --full
subharness cancel <task-id>

Commands print task/session identifiers and return one complete response with its response identifier and task state. wait returns or awaits the first retained response when --after is omitted, and the next response after that cursor when it is supplied. Pending descendant work can continue after that command exits. Run or wait commands can use your assistant's background-task facilities. Native steering is used when supported; otherwise steer behaves as interrupt, cancels affected descendants, preserves independently queued tasks, and reports the effective mode.

Long prompts can use --prompt-file. Output is compact text by default; --format jsonl selects typed integration records without forwarding native token or tool streams.

Access

Codex and Claude Code need no personal access configuration when an eligible native subscription login is available. Other harnesses require an explicit connection. Login remains with the native harness. Ambient API keys do not silently enable paid fallback.

Personal access preferences can be placed in the ignored .subharness/agents.local.json. Linked worktrees read that file from the main checkout, while their agent definitions come from the selected worktree.

{
  "access": {
    "codex": [{ "type": "subscription" }],
    "claudeCode": [{ "type": "vercel-api-key", "env": "AI_GATEWAY_API_KEY" }]
  }
}

Only credential references belong in that file. Access configuration also describes direct API keys, project OIDC, explicit connection fallback, and token-lifetime limits.

For fx, select a connection explicitly. This example uses Gateway:

{
  "access": {
    "fx": [{ "type": "vercel-api-key", "env": "API_KEY", "envFile": ".env" }]
  }
}

Use fx({ model: "google/gemini-3.8-flash" }) in the agent's harness field. Native fx must select the supplied environment credential instead of a saved login. Gateway model and provider restrictions remain effective; catalog availability alone does not establish access for a particular team.

OpenCode and Copilot use the same explicit Gateway connection types under their own access keys. Cursor accepts an explicit subscription connection for the current cursor-agent login, or an api-key connection that defaults to CURSOR_API_KEY. This example selects the local login:

{
  "access": {
    "opencode": [{ "type": "vercel-api-key" }],
    "copilot": [{ "type": "vercel-oidc", "project": ".", "envFile": ".env.local" }],
    "cursor": [{ "type": "subscription" }]
  }
}

Gateway is optional for OpenCode and Copilot. For example, select direct Anthropic access in OpenCode and a native GitHub login in Copilot:

{
  "access": {
    "opencode": [{ "type": "api-key", "provider": "anthropic", "env": "ANTHROPIC_API_KEY" }],
    "copilot": [{ "type": "subscription" }]
  }
}

Copilot also supports explicit GitHub tokens and OpenAI, Anthropic, or Azure BYOK keys. fx supports its own saved Vercel, Codex, or Grok login and keys for native named Chat Completions connections. Model identifiers and required setup depend on the selected route.

See the OpenCode, Copilot, and Cursor adapter contracts for native behavior.

Tools and delegation

Agents can expose validated custom tools and declare subagents. A managed parent invokes its child with the same CLI:

subharness run subagent:reviewer --cwd /path/to/worktree --prompt "Review the implementation."

The library supplies the parent context. Declaring subagents authorizes their invocation. Claude Code receives permissions scoped to its session launcher, declared children, and coordination commands; native approval rules and sandbox restrictions still apply. Children receive explicit task context rather than a copy of the parent's transcript. Cancellation propagates through delegated descendants; a parent task completes after child results and its own continuation are handled.

This checkout includes nine repository roles: the Astra architect and planner; Sol developer and integrator; Luna api-researcher and systems-researcher; Opus reviewer; Gemini researcher; and Fable 5.1 visual-engineer through fx. Reusable techniques live in .agents/skills/ and are read only when the task needs them; a new technique does not require another agent definition. Discover the roles with subharness list and invoke them through repo:<name>. Skill loading, native capability limits, and the image-task execution path are documented with the team.

Boundaries

The local coordinator retains sessions and responses across command exits, but does not restore queues after coordinator or environment loss. External assistant reactivation depends on that assistant's host. Supported native permission requests return structured schemas and keep the original operation pending. The caller answers with subharness respond <request-id> --content <json> and observes the same task. See permission request examples. Unsupported interactive input still fails with actionable INPUT_REQUIRED; no request is automatically approved. CLI delegation requires the native shell to reach the coordinator over loopback HTTP; a sandbox that blocks local networking must be configured by the caller.

resume is available as a command, but v1 adapters report RECOVERY_UNSUPPORTED when prompt-free native recovery is unavailable. Failed work is not automatically replayed or migrated.

Live subscription checks with Codex and Claude Code cover execution, conversation follow-ups, custom tools, and queuing. Codex native steering and interruption preserve queued work. Claude's steer fallback also interrupts the active task, runs its replacement, and preserves queued work.

Live Claude checks also cover launching a declared child and sending follow-ups to that same child session. Explicit native approval rules remain effective. Codex nested delegation remains blocked by local network restrictions in the tested sandbox.

Live fx checks through an explicit Gateway API key cover execution, conversation follow-ups, and custom tools with Gemini 3.8 Flash and Kimi K3. Gemini checks also cover interruption, pending tool completion, and preservation of queued tasks. Native fx permissions remain unchanged. OIDC billing attribution has not been validated end to end. Automated tests use external-protocol fixtures and do not require model access.

Checks and contracts

The private apps/docs workspace contains the Geistdocs website. Its reference pages are generated from the authoritative sdk/ Markdown files; edit those originals rather than generated MDX.

Source development uses pnpm 11.20.0, pinned in package.json. Run pnpm install --frozen-lockfile from the repository root to install the SDK and website workspaces.

pnpm run dev:site
pnpm run check:site
pnpm run build:site

The website contracts describe the application boundaries, and the mascot asset documentation records the reproducible geometry conversion and poster rendering commands.

pnpm run check
pnpm run check:package

pnpm run check builds the current SDK first, then runs TypeScript checking and behavioral tests. Building first lets repository agent definitions import the package's current exports on a clean checkout and prevents tests from exercising stale build output. Tests cover native protocol boundaries, credential selection, worktrees, task queues, cancellation races, nested CLI execution, and process lifetime. The default suite runs two test files at a time to keep subprocess-heavy protocol fixtures within their timing budgets.

pnpm run check:package packs the SDK and verifies installation, public types, embedded execution, shared CLI/SDK sessions, the chat-tool example, and CLI agent discovery in a temporary consumer project. It downloads dependencies from the public npm registry with install lifecycle scripts disabled and uses a fake native harness without calling a coding model.

The SDK documentation describes the final contracts. AGENTS.md defines the project's documentation, TDD, and review workflow. Comparative research and review evidence are kept in the ignored .context directory.