{"id":51392837,"url":"https://github.com/cristianelias/beaver","last_synced_at":"2026-07-04T01:06:57.219Z","repository":{"id":369162996,"uuid":"1287749047","full_name":"cristianelias/beaver","owner":"cristianelias","description":"🦫 A git worktree pool manager — grab a fresh worktree, work, release it back. Warm caches, .env files carried, TUI included.","archived":false,"fork":false,"pushed_at":"2026-07-03T23:16:11.000Z","size":210,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-03T23:19:41.461Z","etag":null,"topics":["cli","developer-tools","git","rust","tui","worktree"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cristianelias.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-03T01:17:04.000Z","updated_at":"2026-07-03T23:16:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cristianelias/beaver","commit_stats":null,"previous_names":["cristianelias/beaver"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/cristianelias/beaver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristianelias%2Fbeaver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristianelias%2Fbeaver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristianelias%2Fbeaver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristianelias%2Fbeaver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cristianelias","download_url":"https://codeload.github.com/cristianelias/beaver/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristianelias%2Fbeaver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35105484,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-03T02:00:05.635Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","developer-tools","git","rust","tui","worktree"],"created_at":"2026-07-04T01:06:56.754Z","updated_at":"2026-07-04T01:06:57.204Z","avatar_url":"https://github.com/cristianelias.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🦫 beaver\n\n**A git worktree pool manager.** Get a fresh worktree in one command, work, release it back. Worktrees get reused — warm `node_modules`, build caches and local `.env` files included — so parallel work is instant and worktrees never pile up again.\n\n![the beaver gui: gradient banner, worktree cards with status pills, pool gauge and key-cap hints](docs/gui.png)\n\nThe banner sweeps an ember gradient across block lettering, statuses are solid color pills, and everything collapses gracefully on small terminals — the banner hides below 24 rows.\n\n## Why\n\n`git worktree` is the right tool for parallel work — especially with coding agents, where you want N isolated checkouts running at once. But raw worktrees have two chronic problems:\n\n1. **They accumulate.** Every task spawns a new worktree; nobody deletes them; eventually you spend an afternoon figuring out which ones are safe to remove.\n2. **They start cold.** A fresh worktree has no `node_modules`, no build cache, and none of the gitignored local config (`.env`, `settings.local.json`) the app needs to actually run.\n\nbeaver fixes both with a **pool** of stable, reusable worktrees. `beaver get` hands you a free one refreshed to the latest default branch — with the previous session's dependency caches still warm and your local configs freshly copied from the main repo. `beaver release` resets it and puts it back in the pool. The pool converges to your real level of parallelism instead of growing forever.\n\n## Install\n\n**Prerequisites:** macOS or Linux · `git` ≥ 2.31 · zsh or bash. Building from source additionally needs a recent stable [Rust](https://rustup.rs) (≥ 1.88); every other method needs nothing else.\n\n### Install with an AI agent (recommended)\n\nbeaver is built for agent-heavy workflows, so the best installer is your agent: one paste installs the binary, wires the shell integration, **and teaches every future agent session to manage worktrees through the pool** — which is the whole point. Paste this into Claude Code, Codex, or any coding agent running on your machine:\n\n```text\nSet up beaver (https://github.com/cristianelias/beaver), a git worktree pool\nmanager, on this machine. Every step must be idempotent — check before you\nchange, re-runs must be no-ops.\n\n1. Install the binary. Try in order until one works, then verify with\n   `beaver --version`:\n     a. curl -fsSL https://raw.githubusercontent.com/cristianelias/beaver/main/install.sh | sh\n     b. npm i -g @cristian-elias/beaver\n     c. cargo install --git https://github.com/cristianelias/beaver\n\n2. Wire the shell integration. Detect the user's login shell from $SHELL.\n   Unless that rc file already contains a line with `beaver init`, append:\n   for zsh, to ~/.zshrc:   eval \"$(beaver init zsh)\"   (preceded by the\n   comment line `# beaver — git worktree pool manager`); for bash the same\n   with ~/.bashrc and `beaver init bash`.\n\n3. Teach agents to use it. Run `beaver agent-guide` and read it. Then in\n   every user-level agent memory file that exists on this machine\n   (~/.claude/CLAUDE.md, ~/.codex/AGENTS.md, ~/AGENTS.md — plus your own\n   memory file if it lives elsewhere; create yours if missing), upsert the\n   following block, replacing any previous copy between the markers:\n\n   \u003c!-- beaver:start --\u003e\n   ## Git worktrees\n   Use beaver (a worktree pool) instead of raw `git worktree`. Acquire an\n   isolated checkout with `WT=$(beaver get --print-path \u003ctask-label\u003e)` then\n   `cd \"$WT\"`; when the work is merged or abandoned, run `beaver release`\n   inside it to return it to the pool. Full agent reference: run\n   `beaver agent-guide`.\n   \u003c!-- beaver:end --\u003e\n\n4. Verify and report: run `beaver --version` and `beaver agent-guide`, then\n   summarize for the user exactly which files you changed and how.\n```\n\nWhy this shape: the prompt prefers the standalone binary (no runtime coupling), the memory-file edit is marker-delimited so re-running never duplicates it, and the block stays tiny on purpose — the full reference lives in `beaver agent-guide`, embedded in the binary itself so it is always in sync with the installed version.\n\n### Manual install\n\n**Prebuilt binary** (no toolchains involved):\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/cristianelias/beaver/main/install.sh | sh\n```\n\n**npm** — delivers the same native binary; npm auto-picks the right one for your OS/CPU and node is not involved at runtime:\n\n```sh\nnpm i -g @cristian-elias/beaver\n```\n\n**From source:**\n\n```sh\ncargo install --git https://github.com/cristianelias/beaver\n```\n\n**Then, the shell integration** (once — this is what lets beaver `cd` you into worktrees; safe to re-run, never duplicates the line):\n\n```sh\n{ grep -qs 'beaver init zsh' ~/.zshrc || printf '\\n# beaver — git worktree pool manager\\neval \"$(beaver init zsh)\"\\n' \u003e\u003e ~/.zshrc; } \u0026\u0026 exec zsh\n```\n\nOn bash, swap in `~/.bashrc`, `beaver init bash` and `exec bash`.\n\n## Uninstall\n\n```sh\nbeaver uninstall\n```\n\nLeaves zero traces, regardless of how (or how many times) beaver was installed: deletes every pooled worktree (pruning the git metadata in each repo), removes `~/.beaver` entirely, strips the integration lines from your shell rc files, removes the beaver block from agent memory files (`~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, `~/AGENTS.md` — so no agent is left instructed to use a tool that's gone), then removes **every install it can find** — the npm global package, the cargo install, and any remaining binary on your PATH (curl installs, stray copies), each verified to actually be beaver before deletion. It shows the plan and asks for confirmation first (`--force` skips it; `--keep-binary` leaves binaries alone, for package managers).\n\n## Usage\n\nAll commands run from anywhere inside a repo — the main checkout or any beaver worktree.\n\n```sh\nbeaver get payments   # get a worktree (reuse free / create), label it \"payments\",\n                      # refresh to origin/main, copy local configs, cd into it\nbeaver get            # same, without a label\n\n# ... work, commit, push ...\n\nbeaver release        # discard everything, refresh, return the worktree to the pool\nbeaver destroy        # permanently delete the worktree you're standing in\nbeaver destroy myrepo-A3F2 --force\nbeaver status         # this repo's pool        (--all: every repo)\nbeaver gui            # interactive browser     (--all: start at the repo list)\n```\n\n### The lifecycle\n\n- **`get`** picks the warmest free worktree (or creates one), fetches, and parks it on a **detached HEAD** at `origin/\u003cdefault\u003e`. Pooled worktrees never sit on branches, so there are no branch-collision issues — create a branch inside one only when you're ready to push. The optional label is beaver metadata for your own tracking; git never sees it.\n- **`release`** is destructive by design: `reset --hard` + `clean -fd`, then re-detach at the fresh default tip. Untracked junk dies; **gitignored files survive** — `node_modules`, `target/`, build caches stay warm, which is what makes reuse fast. Branches you created are left untouched.\n- **`destroy`** deletes the worktree. If it has uncommitted changes or commits that exist nowhere else, beaver asks first (`--force` to skip); a clean worktree is destroyed without ceremony. When run from inside it, you land back in the main repo.\n\n### What gets copied into a worktree\n\nOn every `get`, beaver copies **loose gitignored files** from the main repo: files matched by `.gitignore` that are *not inside an ignored directory*. In practice that means `.env`, `apps/web/.env.local`, `.claude/settings.local.json` — any local config a repo invents — while `node_modules/`, `dist/` and friends are skipped (those live in the worktree itself, warm across reuses). Files over 5 MB are skipped too.\n\n### GUI\n\n`beaver gui` opens the pool browser for the current repo (`..` goes up to the all-repos view). Navigate with **wasd or arrow keys**, `Enter` opens the action menu — **open** (quit + cd into the worktree), **release**, **destroy** (with a confirmation if work would be lost). Press **`g`** anywhere — even on an empty pool — to get a worktree exactly like `beaver get`: the new worktree appears in the list already selected and marked in use, so you can jump in with `Enter → open` whenever you're ready; in the all-repos view `g` targets the selected repo.\n\nPress **`c`** to open settings and edit the global `on_get` hook — the command that runs inside the worktree after every `beaver get` (e.g. `claude`). It writes to `~/.beaver/config.toml` preserving your comments and formatting; leave it empty to disable the hook.\n\n## Configuration\n\nOptional, at `~/.beaver/config.toml`:\n\n```toml\n[copy]\nmax_file_size_mb = 5\nexclude = [\"*.log\", \".DS_Store\"]   # never copy these\ninclude = [\"fixtures/big.db\"]      # always copy these (bypasses cap \u0026 excludes)\n\n[hooks]\non_get = \"claude\"                  # run in the worktree after every `beaver get`\n\n[repos.\"/Users/me/dev/api\"]\non_get = \"npm install \u0026\u0026 claude\"   # per-repo override\ncopy_exclude = [\"*.pem\"]\n```\n\nState lives in `~/.beaver/state.json` (managed by beaver — repos, worktrees, in-use/free, labels) and worktrees under `~/.beaver/worktrees/`. State is self-healing: beaver reconciles it against `git worktree list` on every run, so hand-deleted worktrees just disappear from the pool.\n\n## Prior art\n\nbeaver grew out of `wt`, a personal bash function that created descriptively-named worktrees and copied `.env` files into them. beaver keeps that \"configs travel with you\" behavior and adds the reusable worktree pool, labels, a hard focus on the get/release/destroy loop, and a TUI.\n\n## License\n\nMIT — built by [Cris](https://www.linkedin.com/in/cristianelias/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcristianelias%2Fbeaver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcristianelias%2Fbeaver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcristianelias%2Fbeaver/lists"}