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

@productfactory/agent-supervisor

v0.5.5

Published

A runtime supervisor for ACP-based coding-agent prompts running inside a sandboxed environment.

Readme

@productfactory/agent-supervisor

A runtime supervisor for ACP-based coding-agent prompts running inside a sandboxed environment.

The supervisor launches a single ACP prompt, auto-approves tool permission prompts, streams raw session notifications back to a caller-supplied HTTP callback, emits heartbeats, and exits when the prompt finishes.

Run

The supervisor reads its config from FACTORY_SUPERVISOR_CONFIG_PATH:

FACTORY_SUPERVISOR_CONFIG_PATH=/path/to/config.json factory-agent-supervisor

Config

Required fields in the JSON config:

  • runId
  • taskId
  • sandboxId
  • callbackUrl
  • token
  • promptId
  • prompt

Optional fields:

  • agentTarget ("claude" or "codex", default "claude")
  • sessionId
  • modelId
  • mcpServers
  • repoDir

Environment

Optional runtime environment variables:

  • CODING_AGENT_ACP_COMMAND
  • CLAUDE_ACP_COMMAND
  • CODEX_ACP_COMMAND

By default the supervisor launches the bundled @agentclientprotocol/claude-agent-acp dependency through the current Node executable. The resolved command is equivalent to:

node ./node_modules/@agentclientprotocol/claude-agent-acp/dist/index.js

The ACP agent package is a pinned dependency intentionally. This keeps prompt runtime off the npm registry and makes ACP behavior part of the supervisor release. To upgrade it, check the @agentclientprotocol/claude-agent-acp changelog, update the dependency version, update @agentclientprotocol/sdk if the agent depends on a newer SDK, and run pnpm typecheck, pnpm test, and pnpm build.

Claude remains the default unless agentTarget is explicitly set. Future Codex support is dormant behind agentTarget: "codex", which launches the bundled @zed-industries/codex-acp adapter instead. The resolved command is equivalent to:

node ./node_modules/@zed-industries/codex-acp/bin/codex-acp.js

CODING_AGENT_ACP_COMMAND overrides every target. CLAUDE_ACP_COMMAND and CODEX_ACP_COMMAND override only their matching target.

Other ACP adapters are not bundled yet. If an adapter needs a different runtime or process lifecycle, run it through CODING_AGENT_ACP_COMMAND for experiments until sandbox compatibility and cleanup behavior are proven.

Callback contract (0.3.0)

Every POST to callbackUrl is HMAC-SHA256 signed over `${timestamp}.${nonce}.${body}` with token as the key. Three supervisor headers carry the proof alongside a Bearer for identification:

  • authorization: Bearer <token>
  • x-supervisor-timestamp: <unix ms> — callers should enforce a ±5min window.
  • x-supervisor-nonce: <uuid> — unique per request; callers should reject reuse.
  • x-supervisor-signature: sha256=<hex> — the HMAC over the raw body.

For every ACP sessionUpdate callback, the supervisor pushes the raw SessionNotification onto a batch buffer. The buffer flushes on:

  • 750ms elapsed since the first notification in the batch (fixed window), or
  • 50 notifications accumulated, or
  • ~1MB of estimated serialized size, or
  • any terminal report (prompt_complete, prompt_failed, destroy()).

Each flush is one report with payload shape:

{
  "kind": "session_update",
  "runId": "...", "taskId": "...", "sandboxId": "...",
  "promptId": "...", "sequence": 42, "sessionId": "...",
  "notifications": [/* raw SessionNotification[], in arrival order */],
  "snapshot": {/* cumulative state -- a recovery backstop, not the source of truth */}
}

Callers should render UI off notifications[] and treat snapshot as the reconciliation layer for dropped or out-of-order callbacks.

Parity invariant

For any given prompt, the notifications emitted by the supervisor — their order, sessionUpdate kind, and update payload — are identical to those a caller would see from an in-process ACP loop.

snapshot is the cumulative view of the session: at-notification in in-process, end-of-batch in supervisor mode. Callers that render off notifications[] get exact parity; callers that render off snapshot see monotonically-advancing state with per-batch granularity (typically sub-second).

Across report boundaries, retry-induced reorder can drop a late report; the next report's snapshot reconciles state.

Heartbeats and sequence

Heartbeats fire outside the sequenced chain and always carry sequence: 0. Callers must exempt kind === "heartbeat" from any monotonic-sequence check and must not advance lastSequence from a heartbeat. This prevents a wire-reorder race where a heartbeat lands ahead of an in-flight chained report and steals its sequence slot.

Deferred: permission requests

ACP's requestPermission is a request/response handler, not a SessionNotification, so it does not flow through notifications[]. If the ACP agent is launched with --dangerously-skip-permissions (the current default for this supervisor's callers), the handler never fires. A bidirectional permission channel is a candidate for a future version if that flag is disabled.

Testing

pnpm --filter @productfactory/agent-supervisor test

The suite covers signing, batching/flushing, terminal flush resilience, 401-as-terminal, retries, and adversarial edge cases. Every change to reporter.ts must keep the suite green.