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

@tokenfactory/acc-runner

v0.44.1

Published

Agent Control Center CLI (`acc`). Sign in, read the task board, ask ACC, and run agents on this machine. `acc-runner` is retained as a deprecated alias.

Readme

@tokenfactory/acc-runner

The Agent Control Center CLI. Sign in as yourself, read the task board, ask ACC, and run agents on this machine.

Install

npm i -g @tokenfactory/acc-runner
# or
pnpm add -g @tokenfactory/acc-runner

This installs two commands:

| Command | Status | | ------------ | ------------------------------------------------------------------- | | acc | The CLI. Use this. | | acc-runner | Deprecated alias. Everything still works; prints a notice on stderr. |

Requires Node.js ≥ 20.6. Running agents on this machine additionally needs these binaries on PATH:

  • claude — Claude Code CLI, signed in
  • gh — GitHub CLI, signed in (gh auth login)
  • git — with user.email configured
  • A local clone of the target repo (the repoPath, see below)

Run acc doctor after install to verify everything resolves.

The two lanes

There are two different things a terminal can be, and they are separate credentials with separate lifecycles. A workstation can hold both at once.

You, signed in as yourself — a device-code login that leaves you with your own session (the same one your browser holds) and no runner registration:

acc login             # device-code sign-in; stores a session in the OS keychain
acc whoami            # who this terminal is signed in as
acc logout            # revoke this terminal's session, server-side and locally

The session shows up on Settings → Sessions as acc CLI · <hostname>, so you can revoke it from the browser like any other.

This machine, enrolled as a runner — the fleet credential that lets ACC assign tasks here:

acc runner login      # enrol this host, register a runner
acc runner logout     # clear the local session, mark this runner offline
acc watch             # long-running: receive assignments and execute them

Reading the board

Read-only, under your own token — RLS decides what you can see, exactly as in the UI.

acc task list                                   # 25 most recently updated
acc task list --status in_progress --limit 50
acc task list --repo owner/name --json
acc task show T-1234

Attaching a local repo (no GitHub App)

The other way to give ACC a repo. Instead of installing the GitHub App on it, point the CLI at a git working copy on this machine:

acc repo add-local ~/code/my-app                        # register it
acc repo add-local ~/code/my-app --project my-project   # …and attach to a project
acc repo add-local ~/code/scratch-2 --name pricing-service
acc repo list-local                                     # what this machine serves

The server records three things — a write grant for you (nobody else), a binding from the repo to this machine, and optionally the project attach. It does not record the path: that stays in this machine's config.json under local-repos, and the runner resolves it at task time.

Consequences worth knowing before you run it:

  • only your own runner can serve the repo, and only while it is online;
  • the slug the server mints is local.<fragment>/<name> — a reserved namespace derived from your user id, so it can never collide with (or grant access to) a real GitHub repo;
  • PRs need a push remote you set up yourself. Without one, tasks run and commit in the working copy and the push step fails; add-local warns at registration.

Full walkthrough: docs/acc/LOCAL_REPO_CLI_SETUP.md.

Asking ACC

Hits the same /api/chat/stream endpoint the browser uses, so the same tools, delegation ceiling and audit trail apply.

acc chat "which tasks are blocked?"             # one shot
acc chat                                        # interactive session on a TTY
git log --oneline -20 | acc chat                # piped
acc chat --conversation <id> "and the risky ones?"

If no provider key resolves for you, the turn is queued for a companion runner to drain and acc chat says so — read the reply in the ACC conversation.

Migrating from acc-runner

The alias is a true alias: every command keeps the meaning it already had, so no script needs changing today.

| You typed | Keeps working | New name | | ------------------------ | ------------- | --------------------- | | acc-runner login | yes | acc runner login | | acc-runner logout | yes | acc runner logout | | acc-runner auth login | yes | acc login | | acc-runner auth status | yes | acc whoami | | acc-runner auth logout | yes | acc logout | | acc-runner <anything> | yes | acc <anything> |

Note the one thing a blind rename would get wrong: acc login and acc-runner login are different lanes. acc-runner login enrols a machine (what it always did); acc login signs a person in. Use acc runner login when you mean the machine.

Set ACC_SUPPRESS_ALIAS_NOTICE=1 to silence the deprecation line — worth doing in launchd plists, docker entrypoints and CI where the output was quiet before.

Configuration

The runner resolves its settings from three layers, highest precedence first:

  1. Environment variables (ACC_*)
  2. ~/.config/acc-runner/config.json (or $XDG_CONFIG_HOME/acc-runner/config.json)
  3. Built-in defaults — production endpoints baked into the CLI so a fresh npm i -g works out of the box

Production defaults are baked in; you only need to set anything if you want to point the runner at a preview deploy, change the repo clone location, or declare capabilities.

Environment variables

| Variable | Default | Notes | | ------------------------- | ---------------------------------------- | --------------------------------------------------------------------- | | ACC_PUBLIC_URL | production Vercel URL | Used for cost-pricing fetches and OAuth callback links. | | ACC_SUPABASE_URL | production project URL | Supabase project the runner talks to. | | ACC_SUPABASE_ANON_KEY | production anon key | Public; RLS does the gating. | | ACC_REPO_PATH | ~/work/TechArch | Local clone of the target repo. See "Repo path resolution" below. | | ACC_TARGET_REPO | tokenfactory-pvt-ltd/TechArch | Slug fallback. A task's own repo wins when present. | | ACC_INTEGRATION_BRANCH | acc/integration | Base branch for new PRs. A task's integration_branch wins. | | ACC_RUNNER_CAPABILITIES | (unset) | Comma-separated tags, e.g. code,docs. See "Capabilities" below. | | ACC_RUNNER_PROFILE | (unset) | Profile slug (developer, designer, tester, manager). | | ACC_RUNNER_TOKEN_MODE | keychain | env sources credentials from env vars instead of the OS keychain. See "Ephemeral runners" below. | | ACC_RUNNER_ACCESS_TOKEN | (unset) | Required when ACC_RUNNER_TOKEN_MODE=env. The Supabase JWT minted by the device-code exchange or autoscale provider. | | ACC_RUNNER_REFRESH_TOKEN| (unset) | Optional. Enables in-process token rotation in env mode; rotated successors stay in memory only. | | ACC_RUNNER_ID | minted acc-eph-<hex8> | Optional pre-assigned runner id (env mode). The acc-eph- prefix marks the ephemeral fleet — don't reuse it for desktop runners. Also keys the singleton lock and (when no ACC_RUNNER_CACHE_DIR) namespaces the cache dir, so distinct ids coexist on one host. | | ACC_RUNNER_CACHE_DIR | ~/.cache/acc-runner (or …/runners/<ACC_RUNNER_ID>) | Cache root for locks, worktrees, quarantine, and the singleton lock. When unset and ACC_RUNNER_ID is set, defaults to a per-identity subdir. Set explicitly to override. | | ACC_RUNNER_CONCURRENCY | 5 | Max tasks this runner processes simultaneously. Parsed with Number.parseInt, clamped to 1..50, falls back to 5 on non-numeric input (default raised from 2 in T-1784135000001, operator decision 2026-07-14). With the default ACC_REVIEW_RESERVED_SLOT=1 this leaves 4 parallel tasks + 1 review slot out of the box. Each slot is a live Claude session plus a git worktree, so high values are only viable on API-key runners on high-resource hosts. On a Claude subscription they will 429 — subscription runners should set this back down to fit their plan's concurrent-session capacity. The serial integration-merge queue still caps end-to-end throughput, so real-world gains plateau around ~2–2.5× regardless of how high this is set. |

~/.config/acc-runner/config.json

For settings you don't want to repeat in your shell profile (especially when acc-runner watch runs under launchd and inherits a stripped environment), drop a JSON file at ~/.config/acc-runner/config.json. All fields are optional.

{
  "repo-path": "/Users/you/code/TechArch",
  "capabilities": ["code", "migration"],
  "runner-profile": "developer"
}

| Field | Notes | | ---------------- | -------------------------------------------------------------------------------------- | | repo-path | Local clone path. Overrides the ~/work/TechArch default; ACC_REPO_PATH overrides this. | | capabilities | Array of capability tags. Overridden by ACC_RUNNER_CAPABILITIES when set. | | runner-profile | Profile slug; overridden by ACC_RUNNER_PROFILE when set. | | local-repos | { "local.<frag>/<name>": "/abs/path" } — written by acc repo add-local. No env form. Edit by hand only if you have moved a working copy. |

The file is read at process startup. Missing file or malformed JSON falls back to the next layer silently — the runner never crashes on a config-file read error.

Repo path resolution

acc-runner picks the local repo clone in this order — the first non-empty value wins:

  1. The task row's repo_path_hint (set by the operator when assigning the task) — lets a single runner span repos.
  2. local-repos[task.repo] in ~/.config/acc-runner/config.json, for a local.… slug registered by acc repo add-local. A local repo has no remote to clone from, so this also suppresses the clone cache below.
  3. ACC_REPO_PATH environment variable.
  4. repo-path field in ~/.config/acc-runner/config.json.
  5. ~/work/TechArch — the built-in default.

Until v0.8.1, only steps 1, 2, and 4 were consulted: a repo-path in config.json was silently ignored, and a runner launched by launchd (which strips most environment variables) would default to ~/work/TechArch and fail every task pickup with spawn git ENOENT. Set either ACC_REPO_PATH or repo-path in config.json and verify with acc-runner doctor.

Capabilities

Tags declare what kinds of tasks this runner is willing to pick up. The server's task-router only dispatches a task to a runner whose capability set covers the task's required_capabilities. The canonical vocabulary is:

code, design, test, docs, migration, review, orchestration

An empty list (the default) matches any task with an empty required_capabilities — that's backward-compatible with pre-v0.6.4 behavior. Resolution order, highest first:

  1. ACC_RUNNER_CAPABILITIES (comma-separated)
  2. capabilities field in config.json
  3. The active runner profile's capabilities
  4. []

Runner profiles

A runner profile bundles capabilities and model defaults under a single name. Profiles ship inside the package at packages/acc-runner/runner-profiles/<name>.json. Available profiles:

  • developer — code + migration work (default fleet member)
  • designer — design work
  • tester — test authoring + review
  • manager — orchestration

Select a profile via ACC_RUNNER_PROFILE=designer or "runner-profile": "designer" in config.json. Unknown profile names abort CLI startup with a clear error rather than failing at task pickup. Env vars and config.json capabilities still override the profile's defaults when both are set.

Ephemeral runners (env-token mode)

Desktop runners read their session from the OS keychain (the default, ACC_RUNNER_TOKEN_MODE=keychain). Containerized / autoscaled runners have no keychain, so set ACC_RUNNER_TOKEN_MODE=env and source the session from environment variables instead:

export ACC_RUNNER_TOKEN_MODE=env
export ACC_RUNNER_ACCESS_TOKEN=<jwt-from-device-code-exchange>
export ACC_RUNNER_REFRESH_TOKEN=<refresh-token>   # optional; enables rotation
export ACC_RUNNER_ID=acc-eph-1a2b3c4d              # optional; minted if unset
acc-runner doctor    # validates the env-token config (see below)
acc-runner watch
  • ACC_RUNNER_ACCESS_TOKEN is required. user_id / email / expiry are decoded from the JWT — no extra env needed. A missing or undecodable token fails doctor and aborts watch at startup, not on the first RPC.
  • ACC_RUNNER_REFRESH_TOKEN is optional. With it, the runner rotates the access token in process memory (never written to disk). Without it, the runner simply exits when the access token expires — fine for an idle-TTL-bounded ephemeral runner. Provision a fresh access/refresh pair per container: replaying a previously-rotated refresh token trips the server's reuse detection and revokes the chain.
  • ACC_RUNNER_ID lets the orchestrator pre-assign a stable id. When unset, the runner mints one acc-eph-<hex8> per process; the acc-eph- prefix is the autoscale sweep's ephemeral-fleet discriminator.

acc-runner doctor adds an env-token config check in this mode: it confirms the access token is present and decodable, then reports the resolved runner id (and whether it came from ACC_RUNNER_ID or was minted), whether refresh is wired, and the access-token expiry. The check is a silent no-op for keychain runners.

Running multiple runners on one host

Each runner keeps its locks, per-task worktrees, quarantine sentinel, and single-instance lock under a cache root that defaults to ~/.cache/acc-runner. As of v1.02-A, giving each co-located runner a distinct ACC_RUNNER_ID is enough to run them concurrently on one host:

ACC_RUNNER_ID=acc-eph-aaaa0001 acc-runner watch &
ACC_RUNNER_ID=acc-eph-bbbb0002 acc-runner watch &

The single-instance lock is keyed by (repo path + runner id), so two distinct ids serving the same repo each acquire their own lock and coexist; only a true duplicate — same repo, same identity — is refused. With no explicit ACC_RUNNER_CACHE_DIR, each id also gets its own cache subdir (~/.cache/acc-runner/runners/<id>), so their locks, worktrees, and quarantine state never collide. You can still pin an explicit ACC_RUNNER_CACHE_DIR per runner if you want the cache somewhere specific:

ACC_RUNNER_ID=acc-eph-aaaa0001 ACC_RUNNER_CACHE_DIR=/var/run/acc/a acc-runner watch &
ACC_RUNNER_ID=acc-eph-bbbb0002 ACC_RUNNER_CACHE_DIR=/var/run/acc/b acc-runner watch &

Two runners with the same identity (or both with no ACC_RUNNER_ID) serving the same repo are still caught by the singleton lock. acc-runner doctor prints the resolved token mode and cache dir in its Runtime block, and names the holding identity if a duplicate is detected.

Named instances (keychain mode)

The ACC_RUNNER_ID recipe above suits env-token runners. A keychain-mode runner cannot use it: the keychain holds one runner session per OS user, and the server dedups runner identity on (user, machine) — a second login on one Mac resolves back to the first runner's id. Name the instance instead: --instance <name> (env ACC_RUNNER_INSTANCE, ^[a-z0-9][a-z0-9-]{0,31}$) on login, watch, logout and doctor:

acc-runner login --instance dev2   # own keychain slot, own runner row
acc-runner watch --instance dev2 &

The name folds into all four identity surfaces at once: the keychain account (instance:dev2), the machine string sent to the server (…#dev2, so the dedup mints each name its own stable runner id — re-login reuses it), the cache root (…/acc-runner/runners/instance-dev2) and the singleton lock key. logout --instance dev2 clears only that slot; a second watch under the same name is still refused; doctor reports the instance, its slot and the resolved id. Unnamed, every surface keeps its historic value byte-for-byte, and ACC_RUNNER_ID / an explicit ACC_RUNNER_CACHE_DIR still win where set.

PATH under launchd

launchd resets PATH to /usr/bin:/bin:/usr/sbin:/sbin, which omits the Homebrew bin dirs where git and gh typically live. The runner prepends /opt/homebrew/{bin,sbin} and /usr/local/{bin,sbin} to its own PATH before spawning these binaries — no launchd plist edits required. If acc-runner doctor reports git or gh as missing under launchd, install them via Homebrew and re-run.

node itself is the exception: the repo pins node 22 and launchd sources neither ~/.zshrc nor ~/.zprofile, so the LaunchAgent bakes node@22's bin dir onto PATH (and the ACC_* config vars into EnvironmentVariables) instead of inheriting them. Install it with packages/acc-runner/scripts/install-launchd.sh; see docs/acc/RUNNER_LAUNCHD.md for the install, reboot-survival check and rollback.

Quickstart

acc-runner login          # device-code OAuth in your browser
acc-runner doctor         # verify config + binaries are all green
acc-runner watch          # long-running; receives + executes tasks

Then, in ACC, assign a task to this machine and click Start. The runner will:

  1. Transition the task to running.
  2. git fetch && git checkout -B acc/T-XX-<slug> in the resolved repoPath.
  3. Pipe the rendered prompt into claude --print --dangerously-skip-permissions.
  4. Stream stdout/stderr to acc.task_events (visible in the History tab in ACC).
  5. git push and open a PR titled [T-XX] <task title> via gh.

Commands

acc-runner login

Device-code OAuth flow. Stores a Supabase JWT in your OS keychain (acc-runner service) and registers this machine in acc.runners with its capability tags.

acc-runner logout

Clears the keychain entry and marks this runner offline.

acc-runner watch

Subscribes to a Realtime broadcast channel scoped to your runner. Sends a heartbeat every 4s. Cancellation is honored via task_cancelled broadcasts (sends SIGTERM to the in-flight claude child).

acc repo add-local <path> · acc repo list-local

Register a git working copy on this machine as a repo ACC can run tasks against, with no GitHub App installed anywhere. --project <slug> also attaches it to a project; --name <name> overrides the name derived from the directory. list-local prints what this machine has registered and flags entries the server no longer grants. Both run in the person lane (acc login), not the machine lane — the grant being written is yours. See "Attaching a local repo" above.

acc-runner doctor

Runs every environment check (binaries, keychain access, env-token config, Supabase reachability, repo path, orphan worktrees) and prints a green/red list, preceded by the resolved Config and Runtime (token mode + cache dir) blocks. Exits 0 if all pass, 1 otherwise. A single check that throws is reported as one [FAIL] row rather than crashing the run. Suitable for CI and for diagnosing a silent failure mode after install.

acc-runner version

Prints the CLI version and the protocol version it speaks. The server exposes a minimum-protocol-version pin at /api/runner/min-version; the CLI refuses to start if it's behind.

Troubleshooting

spawn git ENOENT on every task pickuprepoPath resolves to a directory that doesn't exist. Set ACC_REPO_PATH or repo-path in config.json to the absolute path of your local clone, then re-run acc-runner doctor.

**✗ Not signed in. Run \acc-runner login` first.** — keychain entry was cleared or never created. Run acc-runner login`.

✗ keychain read/write (FAIL) — on Linux, install libsecret. On macOS, ensure your login keychain is unlocked. On Windows, run from a session with credential manager access.

✗ register_runner failed — the migration shipping acc.register_runner may not be applied to the deploy you're pointed at. Coordinate with the operator who applies migrations.

Task transitions to failed immediately — open the History tab in ACC. Common causes: git fetch permission denied, claude --print returned non-zero, or the rendered prompt lacked acceptance criteria.

Runner version rejected (426 Upgrade Required) — the server's MIN_VERSION was bumped past your installed CLI. Run npm i -g @tokenfactory/acc-runner@latest.

Runner quarantined after a single flaky run (v0.53+) — a lone instant-empty claude exit no longer benches the machine: the runner logs an env_broken_blip event and retries the spawn once. Only two consecutive instant-empty exits — or a definitive failure (missing dyld library, OOM, exit 127) — quarantine the runner. acc-runner doctor and acc-runner quarantine status print the cause, the consecutive count, and the acc-runner quarantine clear command to resume.

GitHub rate-limit awareness (v0.53)

src/github-client.ts is a budget-aware GitHub REST wrapper (ported from the server's T-52-4 client): per-resource quota tracking, one jittered backoff retry on a 429 / secondary-limit 403, and a per-task-execution soft call budget that fails clean as a retryable infra error (never quarantines).

Scope: the runner currently performs all of its GitHub work through the gh CLI — gh pr create/list (src/gh.ts), gh api conflict resolution (src/runtime/conflict-resolver.ts), gh pr view head-ref lookup (src/runtime/rework.ts), and gh pr view/gh pr diff for reviews (src/runtime/reviewer.ts). Those are separate processes with their own rate-limit handling and are not routed through github-client.ts — they remain uncovered by its budget/backoff. The client is the sanctioned path for any future direct REST call (fetch against api.github.com) the runner adds.

Conflict-resolution integrity guardrail (v0.57, T-57-2)

When a Claude/worktree task whose job is to resolve a merge conflict finishes, the runner does not trust the agent's self-reported gate results. Before the resolution is pushed, src/runtime/resolution-integrity.ts re-verifies it from the runner's own vantage point. The invariant — a conflict resolution is shippable only if all three hold:

  1. Zero conflict markers remain in any tracked file (<<<<<<< / ======= / >>>>>>>).
  2. pnpm typecheck passes (or the task's typecheck_cmd).
  3. No version regression: if a package.json "version" changed in the resolution it must move forward (semver-greater than the base ref, never backward) and CHANGELOG.md must carry a matching entry for the new version.

On ANY failure the resolution is rejected: the runner does not push and does not mark the task resolved. The task transitions to failed (so it is reworked, not merged broken), an append_task_event of kind resolution_integrity_failed records the offending assertion(s), and a conflict.integrity_rejected activity event surfaces it to the operator. A guardrail that itself errors fails closed (rejects). The check is a no-op for every non-conflict task — it is gated by isConflictResolutionTask.

This exists because v0.55–v0.56 agent resolutions repeatedly shipped broken merges that were still marked "resolved": stale-variable splices (task-runner.ts), duplicate declarations (health.ts), and a silently dropped version bump (#496 reverted package.json 0.14.0 → 0.13.0).

Security notes

  • The CLI never reads or writes your git, gh, or Anthropic credentials. It calls binaries that are already authenticated on your machine.
  • The Supabase JWT is short-lived and stored in your OS keychain via keytar, never on disk in plaintext.
  • Heartbeat interval is 4s — do not tighten this. Tighter intervals consume the Realtime budget.

Runner sandbox

acc-runner spawns claude --print --dangerously-skip-permissions so non-interactive task execution doesn't hang on per-edit approval prompts. The permission boundary is enforced by the surrounding context, not by claude itself:

  • cwd boundary: the spawn is bounded to the resolved repoPath. Claude cannot read or edit files outside this repo.
  • allowed/forbidden globs: the task's acc.tasks.allowed and acc.tasks.forbidden arrays are rendered into the prompt; claude is instructed which paths it may or may not touch.
  • operator-controlled install: an operator deliberately runs acc-runner watch on their own laptop. The runner is not a daemon and exits when the operator stops it.

License

Proprietary. Not for redistribution.