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

@arcqdev/deadpool-runner

v0.2.0

Published

Self-healing command runner for CLI and SDK usage with ACP-powered fixes.

Readme

@arcqdev/deadpool-runner

Install

Use it as a local dependency for SDK or repo-level CLI usage:

vp add @arcqdev/deadpool-runner

Or install the CLI globally:

npm i -g @arcqdev/deadpool-runner

CLI Quick Start

Run a command directly:

dpr -- vp test

Pass context and a retry budget:

dpr --retries 3 --prompt "Vite+ monorepo, fix root causes" -- vp check

Or define a config file:

import { defineDeadpoolRunnerConfig } from "@arcqdev/deadpool-runner";

export default defineDeadpoolRunnerConfig({
  command: ["vp", "test"],
  retries: 5,
  initialPrompt: "Fix the actual regression, not the assertion.",
  acpClient: {
    name: "codex",
    model: "gpt-5.4",
    fullAuto: true,
  },
  critique: {
    enabled: true,
    repeatFailureLimit: 1,
    failureConditions: {
      instructions: "Exit early for blockers the repo cannot repair on its own.",
      conditions: [
        {
          id: "third-party-api-down",
          description: "A required external API is unavailable or returning a sustained outage.",
          stop: true,
          output: {
            code: "third_party_api_down",
            retryable: false,
          },
        },
      ],
    },
    acpClient: {
      sandbox: "read-only",
      fullAuto: false,
    },
  },
});

Then run:

dpr

SDK Quick Start

The package now exposes a first-class SDK entrypoint for running repairs programmatically:

import { runDeadpoolRunner } from "@arcqdev/deadpool-runner";

const result = await runDeadpoolRunner({
  cwd: process.cwd(),
  command: ["vp", "test"],
  retries: 2,
  initialPrompt: "TypeScript package. Keep fixes minimal and rerunnable.",
  acpClient: {
    name: "codex",
    model: "gpt-5.4",
    sandbox: "workspace-write",
  },
  critique: {
    failureConditions: {
      instructions: "Classify external dependency outages before spending more repair attempts.",
      conditions: [
        {
          id: "third-party-api-down",
          description: "A required external API is unavailable.",
          stop: true,
          output: {
            code: "third_party_api_down",
            retryable: false,
          },
        },
      ],
    },
  },
});

if (result.failureCondition) {
  console.error("Terminal failure condition:", result.failureCondition.output);
}

if (result.code !== 0) {
  throw new Error(`Repair loop failed with exit code ${result.code}`);
}

For advanced integrations, the lower-level runner is still available:

import { createRunner } from "@arcqdev/deadpool-runner";

const runner = createRunner({
  runCommand: async (command, options) => {
    return {
      code: 0,
      signal: null,
      stdout: `stubbed ${String(command)}`,
      stderr: "",
      combinedOutput: `stubbed ${String(command)}`,
    };
  },
});

await runner.run({
  command: ["vp", "test"],
});

Register a Custom ACP Client

Deadpool Runner is SDK-friendly because the ACP client registry is public:

import {
  registerACPClient,
  runDeadpoolRunner,
  type ACPClient,
  type ACPClientConfig,
} from "@arcqdev/deadpool-runner";

registerACPClient(
  "internal-agent",
  (config?: ACPClientConfig): ACPClient => ({
    name: "internal-agent",
    async fixFailure(context) {
      console.log("Repairing", context.command, "with", config?.model ?? "default model");
      return { summary: "Applied internal-agent repair." };
    },
  }),
);

await runDeadpoolRunner({
  command: ["vp", "test"],
  acpClient: {
    name: "internal-agent",
    model: "my-internal-model",
  },
});

Failure Conditions

By default, Deadpool Runner does not ask critique to classify named terminal conditions. If you set critique.failureConditions, the critique step gets a list of allowed condition IDs, descriptions, and optional structured outputs.

  • id is the stable identifier the critique model can return.
  • description tells critique when that condition applies.
  • stop: true exits the loop immediately when that condition matches.
  • output is copied into result.failureCondition.output for SDK consumers and printed by the CLI when a match stops the run.

Example SDK config:

import { runDeadpoolRunner } from "@arcqdev/deadpool-runner";

const result = await runDeadpoolRunner({
  command: ["vp", "test"],
  critique: {
    failureConditions: {
      instructions: "Only match a condition when the command output clearly supports it.",
      conditions: [
        {
          id: "third-party-api-down",
          description: "A required hosted API is down or returning a sustained outage.",
          stop: true,
          output: {
            code: "third_party_api_down",
            retryable: false,
            notify: "platform-team",
          },
        },
        {
          id: "missing-secret",
          description: "The command is blocked by a missing runtime secret or token.",
          stop: true,
          output: {
            code: "missing_secret",
            retryable: false,
          },
        },
      ],
    },
  },
});

if (result.failureCondition) {
  console.error(result.failureCondition.id, result.failureCondition.output);
}

Example CLI usage:

dpr \
  --failure-conditions-json '{"conditions":[{"id":"third-party-api-down","description":"A required hosted API is down.","stop":true,"output":{"code":"third_party_api_down","retryable":false}}]}' \
  -- vp test

Or load them from a separate file:

dpr --failure-conditions-file ./failure-conditions.json -- vp test

The failure conditions file can export either the failureConditions object directly or a larger config object with critique.failureConditions.

CLI Flags

| Flag | What it does | | ---------------------------------- | ------------------------------------------------------- | | --retries <n> | Max fix attempts after the initial failure | | --prompt <text> | Extra repo context for the fixer | | --cwd, --repo <path> | Target a different repo or working directory | | --client <name> | ACP client name, currently codex by default | | --model <name> | Model override for the ACP client | | --sandbox <mode> | read-only, workspace-write, or danger-full-access | | --max-output-chars <n> | Limit the trailing error text sent to the fixer | | --verbose, -v | Stream ACP client logs during fix attempts | | --config <path> | Explicit config file path | | --failure-conditions-json <json> | Inline JSON for critique.failureConditions | | --failure-conditions-file <path> | Load critique.failureConditions from a file |

Repeat-Failure Critique

Deadpool Runner keeps the normal retry budget and adds an optional loop guard for repeated failures.

  • retries caps the total number of fixer attempts.
  • critique.repeatFailureLimit stops early when the same failure repeats consecutively.
  • critique.failureConditions optionally lets critique classify named terminal failures.
  • The default repeat-failure limit is 1.
  • Critique defaults to the main ACP client unless you override it.
  • Critique runs read-only by default.

Environment overrides:

  • DEADPOOL_RUNNER_REPEAT_FAILURE_LIMIT
  • DEADPOOL_RUNNER_DISABLE_CRITIQUE=1
  • DEADPOOL_RUNNER_CRITIQUE_CLIENT
  • DEADPOOL_RUNNER_CRITIQUE_MODEL
  • DEADPOOL_RUNNER_CRITIQUE_COLOR
  • DEADPOOL_RUNNER_CRITIQUE_SANDBOX
  • DEADPOOL_RUNNER_CRITIQUE_BYPASS_SANDBOX
  • DEADPOOL_RUNNER_CRITIQUE_FULL_AUTO
  • DEADPOOL_RUNNER_CRITIQUE_EXECUTABLE

Package Exports

The published package includes typed ESM exports for both direct use and tooling compatibility:

  • @arcqdev/deadpool-runner
  • @arcqdev/deadpool-runner/cli
  • @arcqdev/deadpool-runner/bin

How It Works

  1. Run the wrapped command.
  2. If it fails, the ACP client gets the repo context and captured error output.
  3. Deadpool Runner writes per-run artifacts under ~/.deadpool-runner/runs/.
  4. The command reruns until it passes, repeats the same failure too many times, or exhausts the retry budget.

Development

This repo uses Vite+.

./node_modules/.bin/vp check
./node_modules/.bin/vp test
./node_modules/.bin/vp run build

GitHub Pages is deployed from the committed docs/ directory through the workflow in .github/workflows/ci-pages.yml.

License

MIT