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

@fbuildai/runner

v0.1.54

Published

egos runner — app-managed machine agent for fbuild. TERMINAL `connect` IS DEPRECATED: the fbuild desktop app starts and supervises the runner (this package remains as the app's managed entrypoint; headless automation may set FBUILD_APP_MANAGED=1).

Downloads

4,593

Readme

@fbuildai/runner

The fbuild runner: connect a machine (your laptop, a VM, a CI box) to an fbuild team hub. The runner dials out over a WebSocket (no inbound ports), registers the machine, and runs tasks the workspace assigns — using that machine's own Claude Code login (or the egos spine). Zero dependencies (Node 22+).

Part of fbuild: console (UI) · hub (Cloudflare Worker) · runner (this).

Quick start

# 1) authorize Claude on this machine once (reused by the runner)
claude setup-token

# 2) connect to your team hub (token from the console → "Add a machine")
cd ~ && npx @fbuildai/runner@latest connect --hub https://<team>.fbuild.ai --token <TOKEN>

The machine now shows online in Soldiers. Leave it running (auto-reconnects on network drops). Run from any directory except the runner's own source folder (npx would resolve the local unlinked package).

Mapping repos

# map a repo to a local checkout, scoped to a workspace
npx @fbuildai/runner@latest add-project <owner>/<repo> \
  --dir ~/Developer/<repo> --hub https://<team>.fbuild.ai --org <workspace>
npx @fbuildai/runner@latest status --hub https://<team>.fbuild.ai

Mapped repos appear in Projects with live git status (branch, dirty, ahead/ behind, last commit), and New task dispatches runs into them.

Routing & discovery. A repo is resolved to its workspace deterministically from the checkout's git remote plus the hub's D1 workspace map — no owner-name inference guessing (0.1.27). Discovery also descends into umbrella / nested checkouts (0.1.29) and treats the repos it finds as first-class projects (they show up in runner.hello alongside explicitly-mapped ones), so you don't have to add-project every inner repo by hand.

Team machine (recommended)

One physical machine can serve every workspace in a team with a single connect:

# add repos per workspace first
npx @fbuildai/runner@latest add-project egosorg/fbuild-hub \
  --dir ~/Developer/aceware/egosorg/hub --hub https://aceware.fbuild.ai --org fbuild

# then connect once (no --org) — fans out to every workspace in config
npx @fbuildai/runner@latest connect --hub https://aceware.fbuild.ai --token <TOKEN>

What a run does

By default a run routes through the egos deterministic spine (a gated f-run.sh in a forked git worktree) — see --executor egos below. There is no silent fallback to Claude: a failed or empty egos run surfaces an honest run.failed with a concrete reason.

Under the explicit --executor claude path, a run instead spawns Claude Code headless (claude -p … --output-format stream-json --include-partial-messages) in the project dir and streams structured events to the hub: assistant text, tool calls + results, extended thinking, and a short auto-generated chat title. The Claude session id is captured so a reply continues the same context (--resume) — even after a runner restart.

Executors

The runner picks how a task runs from --executor (saved to config on connect):

| Executor | What it does | | --- | --- | | egos (default) | Runs the task through the egos deterministic spine — see below. | | claude | Explicit opt-in (no longer a silent fallback): Claude Code headless in the project dir; rich streamed tool timeline. Choose it with --executor claude. | | shell | Runs task.commands verbatim. For testing. | | demo | Prints machine output, edits nothing. Proves the loop safely. |

As of 0.1.32 the silent egos→claude fallback was removed (#45/#46): a failed, empty, or un-startable egos run reports run.failed + a run.artifact status:"failed" with a concrete reason — it is never silently re-served through Claude. Executor choice is unchanged; an explicit --executor claude is still honored, and egos can also run Claude wrapped inside f-run as a worker backend (--backend claude-code).

--executor egos

npx @fbuildai/runner@latest connect --hub https://<team>.fbuild.ai --token <T> \
  --executor egos [--egos-path <egos checkout or bindir>]

This is now the default executor. It routes each assigned task through egos' gated pipeline instead of calling Claude directly. For every order the runner:

  1. Builds a shape-valid egos Order from the hub task (synthesizes the fields egos requires: a sanitized id, successCriteria, a code_patch artifact, and a benign read-only command) and writes it to a temp file — never the repo.
  2. Spawns egos' f-run.sh with the claude-code backend, which forks a git worktree off the project dir, runs Claude headless inside egos' Tool Police (command allow/deny + budget gate), and writes artifacts/events to a runner-owned workdir under ~/.egos/runtime/ (kept out of your repo).
  3. Streams f-run's stdout+stderr verbatim to the task's Terminal tab.

Follow-up replies (order.reply) on an egos-served task route back through the egos spine. egos has no session --resume, so instead of resuming a session the runner builds a fresh follow-up Order carrying the reply text as the task instruction and drives it through egos' runEgosRun — a fresh gated f-run (same --worktree --budget-gate Tool Police as the original run) in its own git worktree forked off the project dir, auto-falling back to Claude only on an empty/failed artifact. (A claude-served run — native or an egos→claude fallback — instead resumes its real Claude session via claude --resume.) Reply context carries via the follow-up order rather than a live session id.

Prerequisites (on the runner machine): egos installed (its install.sh puts f-run.sh on PATH) or reachable via --egos-path / $EGOS_HOME; plus claude (the backend rides ambient Claude auth) and jq on PATH. The project must be a real git checkout (egos forks a worktree from it).

Scope — be aware (MVP): the Terminal tab shows egos' flow/governance progress (worktree created, command allow/deny, budget gate, manifest, gate verdict when a PR is attached) — not Claude's per-tool stream. Parsing egos' events.log into structured timeline rows is not yet implemented (tracked as runner#7 / egos#338).

Degrade: if egos, claude, or jq is missing, or the project dir isn't a git work tree, the run fails cleanly with an actionable reason in the Terminal tab — the runner never crashes and the task never gets stuck running.

A smoke test for this wiring lives at test/executor-egos.smoke.mjs (npm test) — it drives the real runner against a fake hub with a stubbed f-run.sh, no real LLM required.

Keeping it alive

  • Foreground — run connect and leave the terminal open. Simplest.

  • Backgroundnohup npx @fbuildai/runner@latest connect --hub … --token … &.

  • Service (recommended on a VM) — keep it up across reboots:

    macOS (launchd)~/Library/LaunchAgents/ai.fbuild.runner.plist:

    <?xml version="1.0" encoding="UTF-8"?>
    <plist version="1.0"><dict>
      <key>Label</key><string>ai.fbuild.runner</string>
      <key>ProgramArguments</key>
      <array><string>/usr/local/bin/npx</string><string>@fbuildai/runner@latest</string><string>connect</string><string>--hub</string><string>https://aceware.fbuild.ai</string></array>
      <key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
    </dict></plist>

    launchctl load ~/Library/LaunchAgents/ai.fbuild.runner.plist

    Linux (systemd)/etc/systemd/system/fbuild-runner.service:

    [Unit]
    Description=fbuild runner
    After=network-online.target
    [Service]
    ExecStart=/usr/bin/npx @fbuildai/runner@latest connect --hub https://aceware.fbuild.ai
    Restart=always
    [Install]
    WantedBy=multi-user.target

    sudo systemctl enable --now fbuild-runner

Config

Per-hub files under ~/.egos/:

  • runner.json — the default (aceware.fbuild.ai)
  • runner.<host>.json — one per additional hub (e.g. runner.carna.fbuild.ai.json)

Each holds { hub, token, name, machineId, executor, projects }. The token is saved on first connect, so the service form needs no --token. Executor defaults to egos (routes through the egos spine — see --executor egos), with claude as the fallback (Claude Code headless, available until egos is verified — see egos#344); shell and demo exist for testing.

Commands

| Command | Description | | --- | --- | | connect --hub <url> [--token <t>] [--name <n>] [--executor claude\|egos\|shell\|demo] [--egos-path <dir>] | join a team hub, run assigned tasks | | add-project <owner>/<repo> --dir <path> [--hub <url>] [--org <workspace>] | map a repo to a local checkout | | status [--hub <url>] | print the resolved config | | ui login\|orders\|prompt\|new\|init-soc | drive the console from the terminal |

CLI aliases: fbuild-runner and egos-runner (legacy) both resolve to the same binary.

What the runner reports (runner.hello)

On connect (and re-registration) the runner sends a runner.hello frame carrying name, os, cores, idleSlots, detected backends, and a projectInfo array — one entry per known project (explicitly mapped and discovered):

{
  "repo": "<owner>/<repo>",
  "discovered": false,          // true = found by discovery, not add-project'd
  "hasSoc": true,               // a soc/onboarding CLAUDE.md is present
  "lifecycle": "continue",      // compact egos verdict (new|continue|idle); null for discovered repos
  "exists": true, "branch": "main", "dirty": 0, "ahead": 0, "behind": 0,
  "lastCommit": "…", "lastWhen": "2 hours ago", "remote": "…",  // live git status
  "files": ["…"]               // gitignore-aware @-mention index; empty for discovered repos
}

Only presence/name booleans, git status, and file paths cross the wire — never file contents or secrets.

Order signing (per-order Ed25519 verification — WARN mode)

Since 0.1.32 the runner verifies a per-order Ed25519 signature on incoming order-control frames (ADR 0014 Phase B). The check runs at a chokepoint before any order.* branch acts on the frame, using a pinned public signing-root key committed at bin/signing-root.pub.jwk (the runner never holds a private key).

It runs in WARN mode: verdicts are emitted as telemetry (unsigned-order-accepted / invalid-order-signature) and never block an order — until a workspace is latched by a root-signed signing-required policy, at which point unsigned/invalid orders for that workspace are refused (no downgrade).

Fleet lane-config & LiteLLM proxy (fleet.* — ADR 0007 Phase 2)

Behind allowlisted verbs, the runner terminates the console → hub → DO fleet control path:

  • fleet.lane.config — routes a lane config op to the credential-blind f-lane ledger and (when the LiteLLM proxy is enabled) reconciles the machine-local proxy config. A mutating op mints a lane virtual key that resolves to a secret-manager name only — no key value ever crosses the wire.
  • fleet.proxy.{apply,up,down,health} — lifecycle for a machine-local LiteLLM proxy (docker/config standup, teardown, loopback health probe). The handler self-replies fleet.proxy.<verb>.result and never throws.
  • fleet.observe.queryfleet.observe.result — a read-only fleet-ledger snapshot (one observation per machine) so the hub's fleet view has real data.

The lane-config reconcile + key mint and the observe health/money enrichment are flag-gated and default OFF — dormant until EGOS_LITELLM_ENABLE is truthy on the runner; when OFF the runner touches no docker and mints no key. The operator fleet.proxy.{up,down} control path is deliberately not flag-gated — an authenticated console up/down is the enablement. Dispatch / acquire / failover stay founder-gated and are not wired here.

Workspace lifecycle probe (workspace.open)

The console's config / onboarding screen asks a machine, on demand, "what's the setup state of this workspace?" The runner answers by running the read-only egos open <dir> --json probe on the granted checkout and streaming a shaped verdict back. Zero-authority: it mutates nothing, reads no secrets, and emits only presence/name booleans — never file contents.

Request (hub → runner):

{ "type": "workspace.open", "repo": "<owner>/<repo>", "requestId": "<id>" }

repo is resolved to a local dir via the machine's granted projects config (projects.find(p => p.repo === repo).dir). requestId correlates the reply.

Response (runner → hub) — always type: "workspace.lifecycle", echoing requestId and repo:

// repo NOT granted / dir missing on this machine — fail-clean, never throws
{ "type": "workspace.lifecycle", "requestId": "<id>", "repo": "<owner>/<repo>",
  "lifecycle": null, "reason": "repo not granted on this machine" }

// granted — shaped verdict + full first-setup checklist
{ "type": "workspace.lifecycle", "requestId": "<id>", "repo": "<owner>/<repo>",
  "lifecycle": {
    "verdict": "maintain",              // maintain | first-setup
    "onboarding": {
      "state": "configured",            // raw egos onboarding verdict
      "socPresent": true,
      "designSystemPresent": false
    } | null,
    "firstSetup": {
      "allPass": false,
      "checklist": [                     // presence/name booleans ONLY
        { "name": "soc present", "pass": true },
        { "name": "design system present", "pass": false }
      ]
    } | null
  }
}

If the probe can't run (no egos on the machine, missing dir, timeout, bad JSON), lifecycle is null — the runner never throws and never fabricates a verdict.

Verdict vocabulary. The on-demand probe normalizes to the onboarding-guard two-word vocabulary — maintain | first-setup: egos onboarding first-setupfirst-setup; configured or an absent onboarding verdict → maintain. (The compact lifecycle field carried in the runner.hello registration frame uses egos' raw top-level verdict instead — new | continue | idle — falling back to it only when there's no onboarding verdict; the two shapes are intentionally distinct.)

First-setup checklist. Each checklist entry is { name, pass }name is the human label (or id) of an egos open first-setup item, pass is true only when that item's status === "pass". firstSetup.allPass mirrors egos' own all-pass flag. Only booleans and labels cross the wire; no file contents leave the machine.

Sibling messages workspace.create / workspace.addFeature / workspace.switch drive the platform CLI (egos create/add/switch) and reply on workspace.output / workspace.result; workspace.open is the read-only sibling that reports state without changing it.


© Carna · fbuild