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

@switchyardhq/switchyard

v0.4.0

Published

Manage multiple AI coding agents working on the same git repository: isolated worktrees per agent, collision detection before merge, safe cleanup.

Readme

Switchyard

One repo, many AI coding agents, zero collisions — Switchyard's fleet CLI gives every agent an isolated git worktree, with collision detection before you merge.

npm version npm downloads license CI coverage TypeScript PRs welcome website

Two AI coding agents on one checkout ends badly. This project exists because Codex silently ran a git reset on main mid-merge while Claude Code was mid-task on the same files — the merge state vanished and neither agent noticed. The failure mode isn't exotic: two agents, one working tree, no isolation. Switchyard (published as @switchyardhq/switchyard; the installed command is fleet) gives each agent its own git worktree and branch, tracks them centrally, and flags collisions between agents before anyone merges.

What it looks like

(The same flow as the demo video, in skimmable, copy-pasteable form.)

$ fleet spawn claude
Spawned agent claude
  branch:   fleet/claude (from main)
  worktree: ~/project/.fleet/worktrees/claude

Point your agent at it:
  cd ~/project/.fleet/worktrees/claude

$ fleet list
┌────────┬──────────────┬──────┬───────┬───────────────┬───────────────┬──────────────────────────┐
│ AGENT  │ BRANCH       │ BASE │ +/-   │ CHANGES       │ LAST ACTIVITY │ WORKTREE                 │
├────────┼──────────────┼──────┼───────┼───────────────┼───────────────┼──────────────────────────┤
│ claude │ fleet/claude │ main │ +3/-0 │ clean         │ 12m ago       │ .fleet/worktrees/claude  │
│ codex  │ fleet/codex  │ main │ +1/-2 │ 4 uncommitted │ just now      │ .fleet/worktrees/codex   │
└────────┴──────────────┴──────┴───────┴───────────────┴───────────────┴──────────────────────────┘

$ fleet check
1 collision risk detected:
┌───────────────────┬───────────────┬───────────────┐
│ FILE              │ AGENTS        │ VERDICT       │
├───────────────────┼───────────────┼───────────────┤
│ src/api/routes.ts │ claude, codex │ will conflict │
└───────────────────┴───────────────┴───────────────┘
Verdicts from git merge-tree simulation of each agent pair's committed work; uncommitted edits can't be simulated and stay blocking.

Installation

npm install -g @switchyardhq/switchyard

Requires Node.js >= 18.17 and git >= 2.31. The installed command is fleet.

Quickstart

cd your-repo
fleet init                      # config, ignore entry, and the agent-facing docs
fleet spawn claude              # isolated worktree on branch fleet/claude
cd .fleet/worktrees/claude      # point your agent here and let it work
fleet check                     # any files also touched by other agents?
fleet sync claude               # base moved on? catch the branch up
fleet exec claude -- npm test   # run commands in the worktree without cd'ing
fleet diff claude               # review the branch before merging
fleet merge claude              # merge into your current branch + clean up the agent
fleet undo                      # …and roll that merge back if it was a mistake
fleet pr claude                 # …or push it and open a PR via gh instead

Commands

| Command | Description | Key flags | | --- | --- | --- | | fleet init | Set the repo up for the fleet workflow: starter .fleetrc.json, .fleet/ in .git/info/exclude, the Claude Code skill in .claude/skills/, and a protocol block in AGENTS.md. Idempotent — re-run after upgrading to refresh the agent-facing docs | --check verify without writing; exits 1 on drift (CI-friendly), --force overwrite an existing .fleetrc.json, --json machine-readable output | | fleet spawn <agent> | Create a worktree in .fleet/worktrees/<agent>/ on a new branch fleet/<agent>, then provision it (copyOnSpawn / postSpawn below) | --from <branch> base branch (default: current branch) | | fleet list | All active agents: branch, base, ahead/behind, uncommitted count, last activity | --json machine-readable output | | fleet status <agent> | One agent in detail: uncommitted files, diff stat vs base, ahead/behind | --json machine-readable output | | fleet check | Table of files touched by more than one agent. On git ≥ 2.38 each shared file gets a merge-simulation verdict — files whose committed changes merge cleanly are reported but don't block or fail the check. Exits 1 on real collision risks (CI-friendly) | --lines only count overlapping line ranges, --files-only skip simulation; flag any shared file, --json machine-readable output | | fleet diff <agent> | Full diff of the agent's branch against its base | --base <branch> diff against a different branch | | fleet sync <agent> | Merge the agent's base branch into its branch, catching it up. A conflicting merge is aborted — never left half-done | --all sync every registered agent in one sweep, continuing past per-agent failures; exits 1 if any failed | | fleet exec <agent> -- <cmd> | Run a shell command inside the agent's worktree (e.g. fleet exec claude -- npm test) | --all run in every worktree sequentially; exits 1 if any run fails | | fleet merge <agent> | Check for collisions, run the preMerge hook, merge the agent's branch into the current branch, then remove the worktree and branch. A conflicting merge is aborted — never left half-done. Overlaps that provably merge cleanly no longer block; predicted conflicts and uncommitted overlaps still do | --no-clean keep the worktree and branch, --delete-branch explicit form of the default cleanup | | fleet undo | Roll back the last fleet merge: reset the target branch, restore the agent's branch, worktree, and state entry. Single-level; refuses if history moved on | — | | fleet pr <agent> | Push the agent's branch to origin and open a pull request with the GitHub CLI — the review-based alternative to a local merge | --title <t>, --base <branch>, --draft | | fleet remove <agent> | Remove the worktree; refuses if there are uncommitted changes | --force discard changes, --delete-branch also delete the branch | | fleet clean | Remove agents whose branches are fully merged into their base | --dry-run list only, --stale <days> also remove long-idle agents (clean worktrees only; their branches are kept) | | fleet watch | fleet list, re-rendered live until Ctrl+C | --interval <seconds> refresh rate (default 3) | | fleet doctor | Diagnose git version, state file validity, orphaned worktrees, and stale entries. Exits 1 if problems remain | --fix repair: rebuild state from git worktree list, adopt/remove orphans, prune stale entries; --json machine-readable output | | fleet completion <shell> | Print a completion script for bash, zsh, or fish (agent names are a snapshot from generation time) | — | | fleet mcp | Serve the read-only fleet tools to an AI agent over MCP (stdio). Not run by hand — see Use it from an AI agent | — |

All commands work from the main checkout or from inside any agent worktree.

Scripting and CI

list, status, check, and doctor all take --json for machine-readable output, so agents and CI can consume Switchyard state directly — e.g. a merge gate:

fleet check --json || exit 1                  # exit code alone is enough for CI
fleet list --json | jq -r '.[].name'          # enumerate active agents
fleet init --check                            # exits 1 when the agent-facing docs drifted

fleet check --lines refines collision detection from files to line ranges: two agents editing disjoint parts of one file are reported separately instead of blocking. Ranges are computed against each pair's merge base — exact when both agents share a base, a documented heuristic otherwise (see docs/architecture.md).

On git ≥ 2.38, fleet check upgrades from "same file" to "would actually conflict": each pair of overlapping agents is merged in memory with git merge-tree, and cleanly merging overlaps are demoted to an informational list (they no longer exit 1). --files-only restores plain file-level behavior; older git falls back to it automatically. JSON output carries prediction: "merge-tree" | "files" so scripts know which semantics ran.

Use it from an AI agent (MCP)

Everything above assumes a human at a terminal. fleet mcp gives the agents themselves a way to see the fleet: it serves Switchyard state over the Model Context Protocol on stdio, so an agent can check for collisions before it starts editing rather than discovering them at merge time.

Point an MCP client at it:

{
  "mcpServers": {
    "switchyard": {
      "command": "fleet",
      "args": ["mcp"]
    }
  }
}

Without a global install, use "command": "npx", "args": ["-y", "@switchyardhq/switchyard", "mcp"].

The tools

| Tool | Arguments | Returns | | --- | --- | --- | | fleet_list | — | Every active agent: branch, base, worktree path, ahead/behind, uncommitted count, last activity | | fleet_status | agent | One agent in detail: record, ahead/behind, uncommitted files, diffstat vs base | | fleet_check | lines?, filesOnly? | Files touched by more than one agent, with merge-simulation verdicts | | fleet_lock_status | — | Whether a fleet command is currently mutating the repo |

Each returns the same object the matching --json flag prints, so the CLI and the MCP surface can never disagree about what the state is.

What the agent actually sees

The demo GIF above shows the human side. This is the same collision from the agent's side — a real session against fleet mcp, two agents having both rewritten src/api/routes.ts:

// → the client opens the session
{"jsonrpc":"2.0","id":1,"method":"initialize",
 "params":{"protocolVersion":"2025-11-25","capabilities":{},
           "clientInfo":{"name":"demo-client","version":"1.0.0"}}}

// ← the server answers, and states the read-only contract up front
{"jsonrpc":"2.0","id":1,"result":{
  "protocolVersion":"2025-11-25",
  "capabilities":{"tools":{}},
  "serverInfo":{"name":"switchyard","title":"Switchyard","version":"0.3.0"},
  "instructions":"... These tools are read-only by design. Spawning agents,
                  merging, and removing worktrees are human actions in this
                  release — there are no tools for them. Ask for
                  `fleet spawn <name>` rather than creating a worktree yourself."}}

// → before editing anything, the agent checks
{"jsonrpc":"2.0","id":2,"method":"tools/call",
 "params":{"name":"fleet_check","arguments":{}}}

The reply's content block carries the same object fleet check --json prints:

{
  "collisions": [
    { "file": "src/api/routes.ts", "agents": ["claude", "codex"], "verdict": "conflicts" }
  ],
  "prediction": "merge-tree",
  "agentsChecked": 2,
  "cleanMerges": []
}

"verdict": "conflicts" is the agent's cue to stop and coordinate — reached before it wrote a line, rather than at merge time.

These tools are read-only, deliberately

There is no fleet_spawn, fleet_merge, or fleet_remove. Agents can observe the fleet; they cannot join or change it. Provisioning and merging stay human actions in this release.

That is a real limitation, not a technicality, and it has a failure mode worth naming: an agent that goes looking for a spawn tool, finds none, and falls back to a raw git worktree add has produced exactly the untracked, uncoordinated state Switchyard exists to prevent. The server therefore says so at handshake time, and the shipped skill says so again — an agent should ask for fleet spawn <name> instead.

A pleasant consequence: since spawn is not exposed, the postSpawn hook (arbitrary shell from .fleetrc.json) is not reachable from an agent at all.

Teaching agents the convention

The tools report state; they cannot convey that you are expected to check before editing rather than before merging, or that provisioning is something to ask a human for. That convention is the actual product, and fleet init installs it in two forms:

| Artifact | Audience | | --- | --- | | .claude/skills/switchyard/SKILL.md | Claude Code, which loads the full skill on demand | | A marked block in AGENTS.md | Any agent that reads AGENTS.md up front — Codex, Cursor, and others |

Two texts rather than one generated from the other, because the audiences differ: a skill loaded on demand can afford a hundred lines, an always-read file cannot.

Both are package-managed and refreshed on every fleet init, so upgrading the package and re-running is enough to keep them current. In AGENTS.md only the region between <!-- switchyard:begin --> and <!-- switchyard:end --> is rewritten — the rest of the file is yours and is never touched. .fleetrc.json is treated the opposite way: it is your file, so init never overwrites it without --force.

If the markers are ever half-deleted or inverted, init refuses rather than guessing where your content ends.

Configuration

An optional .fleetrc.json at the repo root sets per-repo defaults. Precedence everywhere: CLI flag > .fleetrc.json > built-in default.

{
  "$schema": "https://unpkg.com/@switchyardhq/switchyard/schema/fleetrc.schema.json",
  "defaultBase": "main",
  "watchInterval": 3,
  "autoClean": false,
  "copyOnSpawn": [".env"],
  "postSpawn": "npm ci",
  "preMerge": "npm test"
}
  • $schema — optional; points editors at the config's JSON schema for autocomplete and validation. The schema ships with the package (node_modules/@switchyardhq/switchyard/schema/fleetrc.schema.json).
  • defaultBase — base branch for fleet spawn when --from is not passed (built-in default: the current branch).
  • watchInterval — refresh interval for fleet watch, in seconds (built-in default: 3).
  • autoClean — when true, every successful fleet merge also runs a fleet clean sweep for other fully merged agents (built-in default: false).
  • copyOnSpawn — repo-root-relative files/directories copied into every new worktree by fleet spawn. Worktrees don't carry gitignored files, so a fresh one has no .env or local config — this fixes that. Missing entries are skipped with a note.
  • postSpawn — shell command run inside the new worktree after fleet spawn (e.g. npm ci), so the worktree is ready to work in. A failing hook is reported but the worktree is kept.
  • preMerge — shell command run inside the agent's worktree before fleet merge starts (e.g. npm test). A non-zero exit aborts the merge before anything is touched.

A malformed config file is a hard error with the offending key named; a missing one is fine.

[!NOTE] postSpawn and preMerge run shell commands straight from the repo's .fleetrc.json — the same trust you already extend to a repo's npm scripts or git hooks. Review that file before running fleet spawn or fleet merge in a repository you didn't author (details in SECURITY.md).

How it works

fleet spawn runs git worktree add under the hood: each agent gets a real, separate directory with its own checkout of a dedicated fleet/<agent> branch, so one agent's git reset physically cannot touch another agent's files. A single gitignored .fleet/state.json in the main repo maps each agent to its branch, base, and worktree, and fleet check uses it to diff every agent branch against its base (git diff base...branch, plus uncommitted edits) and cross-reference the changed files. Switchyard also adds .fleet/ to .git/info/exclude automatically, so it never dirties the repos it manages. Design rationale and limitations live in docs/architecture.md.

Contributing

PRs are welcome. Clone, npm install, npm test — every command is tested against real throwaway git repositories, and any change to a command must come with such a test (no git mocks; see CLAUDE.md and AGENTS.md for the ground rules). Commits follow Conventional Commits. Read docs/architecture.md before structural changes, and docs/deployment.md for the release process.

License

MIT © Mohammed Alkindi — see LICENSE.