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

arbella

v1.1.1

Published

Set up your AI coding tools once, then rebuild that setup on any machine — MCP servers included. Claude Code, Codex, Cursor, opencode, GitHub Copilot CLI, Kilo Code & Antigravity — Linux, macOS, Windows.

Readme

⛵ Arbella

Set up your AI coding tools once. Rebuild that setup on any machine.

Backup and migration for your Claude Code, Codex, Cursor, opencode, Copilot CLI, Kilo Code, and Antigravity setup — skills, subagents, plugins, hooks, settings, memories — into a private Git repo you own.

License  Node  Platforms  Status

Quick start · Commands · How sign-in works · What still needs you after a pull · Secrets


The problem

You've spent months tuning Claude Code or Codex — custom skills, a stack of subagents, plugins, hooks, your CLAUDE.md. Then you get a new laptop and do it all again from scratch.

Arbella saves that whole setup into a private Git repo and puts it back on another machine with one command. Linux, macOS, Windows.

Quick start

arbella setup       # install what arbella leans on (git, gh, the tool CLIs)
arbella init        # point it at a private repo, pick your options
arbella push        # snapshot your setup and push it

# later, on another machine:
arbella pull https://github.com/you/your-setup

Install

Needs Node 18+.

npm install -g arbella
arbella --help
arbella update   # later: update arbella itself

What it does

  push   ~/.claude · ~/.codex · Cursor · $HOME  ──▶   strip · template   ──▶   private repo
  pull   private repo                          ──▶   install · place    ──▶   tools + Cursor User data + $HOME

push reads the parts of your setup that matter, strips anything secret, swaps machine-specific paths for placeholders, and pushes the result to your repo. pull does the reverse: installs the CLIs you don't have, drops files back with this machine's paths, merges MCP servers into ~/.claude.json, writes shared home files back under $HOME, reinstalls plugins, skills, and external tools, and wires shared Claude/Codex instructions back into CLAUDE.md and AGENTS.md.

Beyond the obvious config files, Arbella also carries:

| It also carries | Where it comes from | Notes | | --- | --- | --- | | MCP servers | ~/.claude.json → mcpServers | Never the whole file — only the server definitions, sanitized and templated; env values are redacted unless includeSecrets is on (switches such as "1", "true" or "off" under non-secret names are kept; header values and longer numbers never are) | | The rest of ~/.claude | rules/, scripts/, output-styles/, keybindings.json, mcp-configs/, AGENTS.md | The pieces your hooks and CLAUDE.md actually reference | | Shared home files | shared/home/ | Scripts your hooks, statusLine, or MCP commands point at outside any tool's home — picked up automatically (one hop, files only, 1 MiB cap) — plus anything you list in extraPaths, and the claude-mem companion ~/.claude-mem/settings.json | | Claude memories | claude/memories/ | Per-project memory, only when includeMemories is on | | External tools | manifest externalTools | Binaries behind an MCP/hook command that brew, uv tool, or pipx installed — reinstalled best-effort on pull |

Two things it deliberately won't do:

  • Excludes secrets by default. Whole credential files — auth.json, .credentials.json, and the like — sit on a hard denylist and are never read into the repo, no exceptions. Inline secret-shaped values (API keys, OAuth tokens) found in files that are captured are redacted by default; includeSecrets is the explicit opt-in that carries them verbatim into your (private) repo instead. You sign back in after a pull, or carry credentials yourself with arbella secrets.
  • Reinstalls plugins from their sources. Plugins are saved as a list and pulled fresh. Local and shared skills include their contents, preserving local edits and avoiding guesses about their original source.

Supported today: Claude Code, Codex, Cursor (IDE + the cursor-agent CLI), opencode, GitHub Copilot CLI, Kilo Code, and Google Antigravity. Claude Code coverage also reaches into ~/.claude.json for MCP servers, per-project memories, and any linked scripts living under $HOME. Cursor support covers global MCP config, user settings, keybindings, snippets, local skills, shared skill contents with their symlinks, the cursor-agent CLI config + global commands, and extension IDs; runtime state and credentials stay out. opencode, Copilot CLI, and Kilo are config-dir CLIs — Arbella captures each one's config dir (the JSON/JSONC config, custom agents/commands, MCP config), strips token-shaped values, and skips machine-local state, plugin install artifacts, and reinstallable skills (regenerated from the config on first run). Antigravity spans three roots — its VS Code-style User settings, the ~/.antigravity extension list, and the shared ~/.gemini agent config (global rules, MCP servers, skills) — while its Google OAuth tokens never leave your machine.

Commands

| Command | What it does | | --- | --- | | arbella setup | Install git, the provider CLIs, and the AI tool CLIs | | arbella init | One-time wiring: pick a repo and your options | | arbella push | Snapshot your setup and push it — the everyday one | | arbella pull <url> | Rebuild your setup on a fresh machine | | arbella status | Show what a push would change — read-only | | arbella update | Update arbella itself through npm | | arbella auth | Sign in to your repo host | | arbella secrets | Move credentials between machines, off Git |

Every prompt has a flag, so anything interactive can be scripted. --dry-run works wherever it makes sense.

arbella setup

Checks what's installed and offers to fill the gaps — a checklist, so you tick what you actually use.

arbella setup                   # interactive checklist
arbella setup --all             # everything, no prompts
arbella setup --deps git,gh -y  # just these
  • Covers git (required), gh / glab (handle sign-in for you), and the AI CLIs (claude, codex, cursor, opencode, copilot, kilo).
  • Installs through your system's package manager: apt, dnf, or pacman on Linux, Homebrew on macOS, winget on Windows.
  • init and pull also install on demand — if something's missing when you run them, Arbella stops and asks first.

arbella init

The one-time wiring. Pick a host (GitHub, GitLab, or a plain Git URL); if the repo doesn't exist yet, Arbella creates it private for you.

arbella init
arbella init --provider github --repo you/your-setup --auto-push daily -y
arbella init --extra-paths ~/.agents/hooks,~/.agents/memory -y

Saves your preferences:

  • which tools Arbella should manage
  • who wins a conflict — your machine or the repo
  • auto-push cadence — off, once per session, or daily
  • whether secrets are allowed into the repo (off by default), and whether to include memories (also off)
  • extra $HOME paths to carry along (--extra-paths, comma-separated, or the interactive prompt) — Arbella pre-fills the prompt with suggestions from the scripts your hooks and MCP servers already point at. Suggestions are never accepted on your behalf: -y keeps whatever is already configured, so pass --extra-paths to carry them non-interactively

arbella push

The one you'll run most. Captures your current setup, sanitizes it, commits, and pushes. Run it whenever you've changed something worth keeping, or let the auto-push hook do it in the background.

arbella push
arbella push --dry-run   # show exactly what goes in (and what's skipped), write nothing

Worth a --dry-run before your first real push, so there are no surprises.

Before it builds on the repo, push pulls in whatever is already there, and if that does not merge cleanly it stops with nothing pushed. It then asks before two things: another machine pushed since you last pushed or pulled, or the push would delete a lot from the repo (25 or more files, or 3 or more memories). In a terminal you get a prompt (default No); without one, or from the auto-push hook, it does not push. --yes pushes through both.

A machine set up by arbella pull is a follower: it only pulls. push refuses there (--yes does not change that), the auto-push hook does nothing, and --dry-run still works. To make it a source that pushes, run arbella init; it asks first, since that machine's setup can then overwrite the repo. Memories are only mirrored when includeMemories is on; otherwise a push leaves the ones in the repo alone.

arbella pull

The reason the whole thing exists.

arbella pull https://github.com/you/your-setup
arbella pull <url> --dry-run

pull --dry-run does not alter your tool setup or persistent backup clone. It plans from an existing local clone without refreshing it; when there is no clone yet, it makes a temporary download for the preview and removes it afterwards.

  • First copies your current ~/.claude and ~/.codex to a timestamped safety folder, so a pull can't quietly wreck what's already there.
  • Installs any missing CLIs — reaching for sudo only when the global npm folder actually needs root.
  • Writes files with this machine's paths, then reinstalls your plugins and skills from the manifest.
  • Merges MCP servers into ~/.claude.json — a safety copy is taken first; the file is read in full, only the mcpServers keys (user- and project-scope) are changed, every other key (auth, telemetry) is carried over unchanged, and the whole file is rewritten atomically so it's never left half-written.
  • Writes shared home files (linked scripts, extraPaths) back under $HOME — an existing file is snapshotted first and never overwritten while your machine is the source of truth.
  • Reinstalls external tools behind MCP/hook commands via brew, uv tool, or pipx, best-effort.
  • Deploys your shared instructions to CLAUDE.md and AGENTS.md.
  • Reminds you to sign back in for credential stores that never travel. With the default secret setting, it also lists inline values that were redacted and need to be supplied again.

arbella status

Read-only. It answers one question: if you ran push right now, what would change?

arbella status
arbella status --json   # pipe it somewhere

New and modified files, plugin drift, MCP server and external-tool drift, and the secrets it would skip. Files it doesn't recognize print as not backed up (unknown to arbella) — add them via extraPaths or open an issue. Writes nothing, installs nothing.

arbella update

Updates the Arbella CLI package itself. It does not touch your backed-up Claude, Codex, or Cursor setup.

arbella update                  # npm install -g arbella@latest
arbella update --version 0.1.2  # pin a specific release
arbella update --dry-run        # show the npm command only

arbella auth

Handles sign-in to your repo host. You rarely call it yourself — push and pull sign in on their own when they hit a private repo. It's here for when you'd rather log in ahead of time, or check where you stand.

arbella auth login
arbella auth status
arbella auth login --provider gitlab
arbella auth login --device-flow   # skip gh/glab, use Arbella's own flow

arbella secrets

For the credentials that never belong in the repo. Git is never involved — you carry the blob between your own machines yourself.

arbella secrets export   # encrypted, passphrase-protected blob (AES-256-GCM)
arbella secrets import   # unpack it on the other machine

How sign-in works

Short version: gh and glab are preferred, not required. They're the smoothest route, and the one I'd point you to — but Arbella works without them.

| Situation | What Arbella does | | --- | --- | | CLI installed and signed in | Uses it directly. gh/glab already do OAuth properly and configure Git's credentials, so nothing sensitive passes through Arbella. | | CLI installed, signed out | Runs its auth login for you — prints a URL and a code you type into your browser. | | CLI missing | Offers to install it, or falls back to its own path: an OAuth device flow, or a pasted token kept in a local 0600 file. |

For the device flow, point Arbella at your own registered OAuth app with ARBELLA_GITHUB_CLIENT_ID (or ARBELLA_GITLAB_CLIENT_ID). There's no sensible default to ship — the client ID is public but tied to your account — so with none set, Arbella skips the device flow and asks for a token instead. SSH and file:// remotes are left alone, so those keep working however your Git already has them.

What still needs you after a pull

Arbella restores everything it safely can. A few things are yours to finish:

  • Credentials. Credential stores never travel, so sign back in when Arbella tells you to, or carry them yourself with arbella secrets. By default, inline API keys and OAuth tokens are redacted too; includeSecrets is the explicit private-repo opt-in that carries those inline values.
  • Redacted values. If a config held a secret-shaped value, push replaced it with {{REDACTED}}. Pull never writes that marker into a live config: a real value already on this machine is kept, otherwise only that one key is left out. Each key still to fill in is listed at the end of the pull and in arbella status, e.g. secret missing: codex mcp unifi-network → UNIFI_NETWORK_PASSWORD.
  • Kept files. Pull ends with a summary per tool. A file that differs from the repo and was changed on this machine is kept and listed; arbella pull --force replaces those (a safety copy is taken first). A file holding a real secret where the repo only has {{REDACTED}} is never replaced, not even with --force; delete it locally to take the repo version.
  • Per-project MCP servers for a project you haven't cloned yet. A project's MCP servers are only registered when its directory exists on this machine; if it doesn't, pull skips them and warns you which directory was skipped. Clone the project, then run arbella pull again.
  • External tools Arbella couldn't classify or install. brew/uv tool/pipx tools are reinstalled best-effort; anything unknown, or that failed, is listed by name and by what uses it, so you can install it yourself.
  • ~/.claude.json is only merged, key by key. Pull touches mcpServers (and per-project mcpServers) and nothing else in that file — your oauthAccount, telemetry, and everything else stay exactly as they were.
  • The repo is trusted. A pull writes the hooks, MCP commands, and install lists your repo describes, and runs brew / uv tool / pipx / npm for the tools it lists — exactly like the machine you pushed from. Keep the repo private, and run arbella pull <url> --dry-run first on anything you did not push yourself: the plan prints every command and target path.

Secrets

This is the part I most wanted to get right.

  • Whole credential files (auth.json, .credentials.json, and the like) sit on a hard denylist and are never read into the repo.

  • Everything that does get committed runs through a sanitizer that redacts token-shaped values.

  • ~/.claude.json itself is still never stored — only its mcpServers sub-objects are lifted out, sanitized, and templated; the rest of that file (OAuth account, telemetry) never leaves your machine.

  • Shared home files go through the same sanitizer, plus a home-specific denylist — .env, *.pem, *.key, id_rsa*, .netrc, .npmrc, .git-credentials, and friends are never captured even when something points at them.

  • Any token Arbella holds for itself lives in one local file with 0600 permissions — not in the repo, not in a logged command, not baked into a Git remote.

  • A test fails the build if a credential can reach the repo. This isn't on the honor system.

  • Arbella's own auto-push hook is never stored in the repo, so a pulled machine does not inherit it.

  • A real local secret is only reused when nothing else in its server, provider or settings block changed; otherwise the local version is kept and reported. That guard stops a secret from quietly following a changed endpoint. It is not a sandbox: the repo stays trusted, because it can ship hooks and MCP commands that run code.

Putting secrets in the repo is opt-in, and the default is off. It's your private repo and your call — but I'd leave it there.

Cross-platform notes

Paths get templated, so a setup captured on a Mac under /Users/you restores correctly on Linux under /home/you, or on Windows. The one place the machine matters is global npm installs: on a system Node the folder is root-owned, so Arbella elevates with sudo and tells you it's doing so; on nvm, Homebrew, or Windows it's already yours, so it skips sudo. It checks first instead of guessing.

Why "Arbella"

The Arbella was the flagship of the 1630 Winthrop Fleet — a few hundred settlers, their livestock, and the colony's founding charter, carried across the Atlantic to start over somewhere new. That's the idea here: pack up the things that make your environment yours, carry them across, and unpack on the other side.

Status

v1.0.0 — builds clean, the full test suite passes, and I use it daily. Issues and pull requests welcome.

Releases

Merging to main runs the Linux, macOS, and Windows checks first. When they pass, publish.yml publishes to npm and creates the GitHub tag and release automatically. The first release from the existing 0.x tags is 1.0.0. This jump is one-time; subsequent commits determine the next version:

  • fix: ..., documentation, maintenance, or other changes increment the patch version (for example, 1.0.0 → 1.0.1).
  • feat: ... increments the minor version (for example, 1.0.1 → 1.1.0).
  • A BREAKING CHANGE: footer or a ! after the commit type/scope increments the major version.

Use the same conventions in the PR title when squash merging. No manual version bump, tag, or GitHub release is needed. Re-running a successful release does not bump again. The published package and arbella --version use the computed version; the source package.json stays at its baseline because release versions are tracked by Git tags.

Publishing uses npm trusted publishing. The arbella package's npm Settings must have a GitHub Actions trusted publisher with owner Fafoooo, repository arbella, and workflow filename publish.yml (no environment name). This avoids maintaining an npm token in GitHub secrets. Release tooling runs separately on Node 24; Arbella itself continues to support Node 18+.

License

Copyright (c) 2026 Fafoooo.

Arbella is licensed under the GNU Affero General Public License v3.0 only (AGPL-3.0-only). See LICENSE.