wb

module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 19, 2026 License: MIT

README

wb

Fleet-wide operations across your GitHub repositories, from the terminal: keep every local clone in sync with GitHub, and run config-driven recipes across every repo that matches — no per-repo scripting.

Part of the Sneat Developer Platform.

Install

go install github.com/sneat-dev/wb/cmd/wb@latest

A Homebrew cask (brew install --cask sneat-dev/tap/wb) is coming soon.

Commands

wb sync   [flags]            # clone/pull/prune local clones to match GitHub, in parallel
wb run    [recipe] [flags]   # run a fleet-wide recipe defined in config
Persistent flags
Flag Default Meaning
--projects-root P ~/projects Root dir holding {org}/{repo} clones.
--filter S Only process repos whose org/name contains S.
--org O Query an additional GitHub owner (repeatable). Not used by sync — see below.
wb sync

Reconciles ~/projects/{org}/{repo} with GitHub:

  • non-archived, missing locally → clone
  • non-archived, present locally → pull (skip if the working tree is dirty)
  • archived, present + safe (clean, no stash, nothing unpushed) → remove
  • archived, present + unsafe → keep, report why
  • archived, missing → nothing

Runs against every repo owned by your GitHub account and every org you belong to, in parallel, with a live progress UI (overall + per-org bars, a live tail of in-flight repos). Anything left needing your attention (a hard error, or a repo skipped/kept because it's dirty) opens an interactive drill-down after the run — pick a repo to see exactly what's wrong (modified/untracked/conflicted files, unpushed commits, stash entries). Non-interactive runs (piped output, no TTY) print a plain summary instead and skip the drill-down.

Flags:

Flag Default Meaning
--dry-run, -n off Print the plan; change nothing.
--workers, -j 8 Max concurrent git/gh operations.
--org, -o — (all your orgs + your account) Only sync this org (repeatable). Restricts, rather than adds — unlike the persistent --org on run.
wb sync --dry-run              # preview
wb sync -o your-org            # sync only one org
wb sync -j 16                  # more parallelism
wb run — config-driven recipes

wb run <recipe> applies one recipe, defined in a YAML config, across every repo it matches. Dry-run by default — pass --apply to commit & push.

wb run --list                     # show configured recipe names
wb run dev-approach               # preview
wb run dev-approach --apply       # land it
wb run some-lint --filter x       # preview, scoped to repos matching "x"

Flags:

Flag Default Meaning
--apply off (dry-run) Commit & push changes. Without it, only reports what would change.
--config PATH ~/.config/wb/wb.yaml Path to the recipe config.
--list off Print configured recipe names and exit.
Config format

One YAML file, ~/.config/wb/wb.yaml by default (override with --config). Two recipe kinds:

template-section — merge a versioned block from a template file into a target file (default README.md) in every matching repo:

recipes:
  dev-approach:
    type: template-section
    target: README.md                          # default: README.md
    template: ~/path/to/dev-approach.md         # required
    marker: dev-approach                        # default: the recipe's own name
    applies_if: "has_source:go,ts"

The template file must contain the block wrapped in <!-- {marker}:vN --><!-- /{marker} -->. Bumping the version number in the template propagates it to every repo that already has an older section; repos with a current-or-newer section, or no target file at all, are left untouched.

command — run a shell command in the worktree; "changed" means git status --porcelain is non-empty afterward:

recipes:
  some-lint:
    type: command
    command: "some-linter --fix"                 # required
    dry_run_command: "some-linter"                # optional: a read-only preview
    count_regex: '(\d+)\s+problem'                # optional: extract a count from dry_run_command's output
    applies_if: has_file:some-linter.yaml

dry_run_command's exit code (not the count) determines whether --apply would do anything; count_regex only prettifies the dry-run summary. If dry_run_command is omitted, dry-run mode can only report "would run: ...".

applies_if (all recipe kinds; default always):

  • always
  • has_file:<path> — e.g. has_file:specscore.yaml
  • has_source:go, has_source:ts, or has_source:go,ts (comma = OR)

Landing options (all optional, defaulted from the recipe's name): commit_message, pr_branch, pr_title, pr_body.

How it lands

Same worktree/commit/push-or-PR flow for both recipe kinds:

  1. Discover repos across your GitHub orgs, same as wb sync.
  2. Skip: forks, archived repos, local-only clones not under one of your owners, and any repo applies_if excludes.
  3. Land, in a detached worktree off the default branch: if the local clone is dirty (uncommitted/unpushed) or the default branch is protected → push to {pr_branch} and open an auto-merge PR; otherwise → push directly to the default branch.

wb itself ships with no recipes — you define your own in ~/.config/wb/wb.yaml.

Build from source

go build -o ~/.local/bin/wb ./cmd/wb   # install on PATH
go test ./...                          # run tests
wb sync --dry-run                      # preview a fleet sync
wb run --list                          # see your configured recipes

Adding a new operation

For anything expressible as "detect matching repos, mutate, land the result," add a recipe to your wb.yaml — no code change needed. For something structurally different (like sync, which reconciles local clones with GitHub existence rather than mutating already-cloned content), a new fleet command adds a case in cmd/wb, reusing internal/discover and internal/gitops.

Known limitation

Discovery keys on org/name. If a repo is cloned locally under a directory name that differs from its GitHub org (e.g. ~/projects/dalgo/... vs the dal-go org), the mislabeled local copy is treated as local-only and skipped, and the correctly-named repo is cloned fresh under ~/projects/<org>/ during sync. Use matching org directory names to avoid duplicate clones.

License

MIT — see LICENSE.

Directories

Path Synopsis
cmd
wb command
Command wb is the workbench CLI: fleet-wide operations across the user's GitHub repositories, plus repo-sync.
Command wb is the workbench CLI: fleet-wide operations across the user's GitHub repositories, plus repo-sync.
internal
discover
Package discover finds the repositories to operate on by reconciling the local ~/projects/{org}/{repo} tree with the non-archived repositories GitHub reports for the relevant orgs.
Package discover finds the repositories to operate on by reconciling the local ~/projects/{org}/{repo} tree with the non-archived repositories GitHub reports for the relevant orgs.
fleetsync
Package fleetsync decides and performs the sync action for a single repo: clone or pull an active repo, or remove/keep an archived one's local clone.
Package fleetsync decides and performs the sync action for a single repo: clone or pull an active repo, or remove/keep an archived one's local clone.
gitops
Package gitops wraps the git and gh commands needed to read the default branch of a repo and to land a change on it — pushing directly when allowed, or opening an auto-merge PR when the branch is protected.
Package gitops wraps the git and gh commands needed to read the default branch of a repo and to land a change on it — pushing directly when allowed, or opening an auto-merge PR when the branch is protected.
recipe
Package recipe implements wb's config-driven fleet operations: a Recipe describes how to detect and mutate matching repos, and how to land the result via the same worktree/commit/push-or-PR flow used everywhere else in wb.
Package recipe implements wb's config-driven fleet operations: a Recipe describes how to detect and mutate matching repos, and how to land the result via the same worktree/commit/push-or-PR flow used everywhere else in wb.
scan
Package scan inspects a repository working tree.
Package scan inspects a repository working tree.
tui
Package tui holds the bubbletea models for `wb sync`'s progress display and its post-run interactive results browser.
Package tui holds the bubbletea models for `wb sync`'s progress display and its post-run interactive results browser.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL