wsb 0.275.7622

Workspace tools for every project under $PRJ: git across submodules, template stamping, GitHub, and the workbench
Documentation

wsb

Crates.io Downloads License

Multi-tool CLI suite for file operations, version management, and development workflow automation. All tools accessible through a single wsb binary, with wsb-daemon beside it serving the workbench.

Install

wsb starts wsb-daemon from its own directory, so the two are installed together:

cargo install wsb wsb-daemon

Or build from source (./dx build also builds the macOS app around them):

git clone https://github.com/jowharshamshiri/wsb.git
cd wsb/wsb
cargo install --path . && cargo install --path daemon

Building wsb-daemon builds its workbench frontend too, so it needs Node.js (^20.19, ^22.12 or >=24) and npm >=10.2.3.

Core Tools

Command Description
wsb refactor Recursive string replacement in files and directories
wsb scrap Local trash can with .scrap folder
wsb unscrap Restore files from .scrap folder
wsb ldiff Line difference visualization for pattern analysis
wsb status, wsb stage, wsb commit, wsb push, etc. Git operations over the current repo or fleet root
wsb discard Throw away local changes across every worktree, after showing what would go
wsb each Run a shell script once for each submodule
wsb update Update version file and render all templates
wsb wstemplate Cross-project version stamping with .wstemplate files
wsb local Point every manifest in the fleet at the working copies here, or take that back
wsb checkpoint Take the local render back, commit the fleet, push, and go local again
wsb version Version management (show, major, tag, info)
wsb code Code intelligence from omnicode: symbols, references, call graphs, diagnostics, search
wsb test Intelligent test runner based on project type
wsb catalog The worktree's test catalogue: numbering, duplicates, parity between families
wsb note, wsb link Notes, and links between any two things — boards, cards, projects, worktrees, files, machines, sessions — committed in the project's .wsb/
wsb serve Start the workbench: make sure the machine's wsb-daemon is running and print this worktree's page
wsb daemon The machine's daemon: what it is serving, stopping and restarting it, its log, running it as a service
wsb peer Pair with another machine and carry this worktree's working tree to it, without a commit
wsb init, wsb check A repository's committed .wsb/: create it, verify it
wsb migrate Bring this machine's checkouts and state from an older wsb's layout into this one
wsb machine This machine's name, as notes and peers know it
wsb github Issues, pull requests, CI, gists and every Projects board of your account and organisations, from one mirror per machine (also wsb-github)
wsb compact Compact a session transcript by removing low-signal noise
wsb ignore, wsb last-hash, wsb audit-path, wsb completions Utilities: a .gitignore line in every subdirectory, a file's last commit, shadowed executables on PATH, shell completions

Run wsb with no command to start the workbench (wsb serve).

Quick Start

# Recursive string replacement
wsb refactor ./src "OldClassName" "NewClassName" --verbose

# Safe file disposal and recovery
wsb scrap temp_files/ experimental/
wsb unscrap important_config.toml

# Git operations over the current repo or fleet root
wsb status
wsb checkout feature/my-change

# Cross-project version stamping
wsb init                     # .wsb/repo.json, committed, and the pre-commit hook
wsb wstemplate render

# A note on a file, committed with your next commit
wsb note add --title "Why this retries" --body "…" --on-file src/bridge.rs

# Line difference visualization
tail -f /var/log/app.log | wsb ldiff

# The workbench: every board, project and worktree on the machine, in the browser
wsb serve

Version Management

wsb uses a three-part versioning scheme: {major}.{minor}.{patch}

  • Major: Set via wsb version major (committed in .wsb/repo.json)
  • Minor: The commits of the repository and of every initialised submodule under it
  • Patch: The file changes since the newest release tag of that major

Version can be stamped into project files (Cargo.toml, package.json, pyproject.toml, etc.) via wsb update.

Cross-Project Version Stamping

.wstemplate files are Tera templates that render to the file with the suffix stripped (e.g., Cargo.toml.wstemplate renders to Cargo.toml). Templates can reference any sibling project's version:

[package]
name = "my-app"
version = "{{ project.version }}"

[dependencies]
my-lib = { path = "../my-lib", version = "{{ projects.my_lib.version }}" }

Templates see more than the version. Each repository — every submodule included — also exposes its newest published tag, HEAD commit, branch, worktree state, and path within the project:

[dependencies]
# Resolved from a local checkout: the version being built is the right one
my-lib = { path = "../my-lib", version = "{{ projects.my_lib.version }}" }
# Resolved from a registry by someone outside the project: must name a release
# that exists, and `version` is bumped on commit so it is always one step ahead
my-dep = "{{ projects.my_dep.latest_version }}"

Run wsb wstemplate vars to list every variable with its current value. A field that does not apply is an error naming the reason, never an empty string — a project with no tags fails the render instead of stamping "".

Cross-project references are resolved dynamically by scanning the templates root for .wsb/repo.json files — no explicit dependency declarations needed.

Where Things Live

wsb works with the folder every project lives in, $PRJ (the workshop): a project's folder $PRJ/<project>/ is its workspace, holding its worktrees — main-worktree, the clone of its main repository on GitHub, and <name>-worktree checkouts. GitHub Projects boards belong to their owners; a project lists the boards it works from.

A repository's .wsb/ is committed whole, each file refusing keys it does not know:

File What it declares
.wsb/repo.json In every repository wsb manages (wsb init): its name, its alias in templates, its templates_root, and its version — major, file, suffix, detect_manifests, manifests
.wsb/project.json In a project's main repository: the boards it works from (owner/number) and the ignored_submodules
.wsb/notes/<id>.md, .wsb/links/<id>.json Notes, and links between refs (board:, card:, issue:, repo:, project:, worktree:, path:, machine:, note:, session:, message:, url:)
.wsb/stamp.json For templates: declared (a JSON file {{ declared.… }} reads), build_root ({{ build.root_from_here }}), and local — the variable that selects the local render, with optional prepare/release commands for wsb local and wsb checkpoint
.wsb/test.json parity_families: which repositories hold the same numbered tests, for wsb catalog parity <family>
.wsb/peer.json continuity: include_ignored and exclude path prefixes — what continuity carries to a paired machine beyond what git tracks or would track, and what it leaves alone

What wsb keeps for a machine is never committed: one database, $PRJ/.state/wsb.db (agent sessions, peers, the GitHub mirror, every worktree's test catalogue and layout), each worktree's logs and lock under $PRJ/.state/workspaces/, and the machine's own folder under $PRJ/.state/hosts/. A machine set up by an older wsb is converted once with wsb migrate.

Documentation

License

MIT