wsb 0.275.7622

Workspace tools for every project under $PRJ: git across submodules, template stamping, GitHub, and the workbench
Documentation
//! The daemon, as the command line sees it.
//!
//! wsb is two programs. `wsb` is a command line that starts, does one thing
//! and exits; `wsb-daemon` is a process that stays and serves the workbench.
//! This module is everything the first needs to find, start and talk to the
//! second — the REST contract they share, the files they meet at, and the
//! rules about which daemon is the right one to talk to.
//!
//! # Why a daemon at all
//!
//! A command line cannot serve the workbench, which has to outlive whatever
//! started it or somebody has to keep a terminal open for it. The daemon also
//! keeps the machine's GitHub mirror current and carries peer continuity.
//!
//! # What the daemon is not
//!
//! It is not a place work happens. Commands still do their own work in their
//! own process; the daemon hosts the workbench. `--no-daemon` therefore loses
//! the workbench and changes nothing about what a command does.
//!
//! # One daemon, one MACHINE
//!
//! The daemon serves every worktree on this machine, from one process at one
//! port, with its state in the machine directory (see [`machine`]). It was one
//! daemon per checkout, and that made a machine with six checkouts run six
//! daemons, bind six ports and hold six copies of everything — and left peer
//! identity, which is a property of the MACHINE, with nowhere to live.

pub mod client;
pub mod machine;
pub mod launch;
pub mod protocol;
pub mod rendezvous;
pub mod service;

pub use client::Client;
pub use launch::{
    cli_executable, daemon_arguments, daemon_executable, ensure_running, log_path,
    wait_until_stopped, Port, Spawn,
};
pub use protocol::{route, ApiError, Info, WorktreeInfo};
pub use machine::{
    adopt_old_machine_dir, default_machine_name, family_of, home_dir, identify_shared, machine_dir, machine_name,
    new_control_token, MACHINE_DIR_ENV, MACHINE_NAME_ENV,
    place_worktree, staging_dir, Continuity, MachineRendezvous, RegisteredWorktree, WorktreeId,
    WorktreePlace,
};
pub use rendezvous::Rendezvous;

/// Saying "no daemon" to every wsb in a run, not just the first.
///
/// `--no-daemon` sets it, and every wsb started underneath reads it. Without
/// that, a command told to stay in one process would have children starting
/// daemons behind it — and the operator would find one running after a run
/// they explicitly asked to keep local.
///
/// It is also how a test harness declares that it must not touch this
/// machine's daemon: the suites drive wsb against fixture worktrees, and a
/// daemon started there would outlive the temporary directory it was serving.
pub const NO_DAEMON_ENV: &str = "WSB_NO_DAEMON";

/// Whether this run has been told to keep to itself.
///
/// One reading of the variable, so "does this run use the daemon" is one
/// question with one answer rather than a condition each caller writes out.
pub fn disabled() -> bool {
    std::env::var_os(NO_DAEMON_ENV).is_some_and(|value| !value.is_empty())
}

/// Where a daemon listens unless somebody says otherwise.
///
/// This machine and nothing else. The workbench has no authentication — it
/// reads and edits the worktree and runs git on it — so who can reach
/// it is a decision an operator makes deliberately, per start, with
/// `wsb serve --listen`. It is
/// not a stored preference: a daemon that came back up reachable because of
/// something switched on months ago is the failure this default exists to
/// prevent.
pub const LOOPBACK: std::net::IpAddr = std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST);

/// The default port the workbench is served on.
///
/// Where an unnamed port STARTS. A daemon told to take an exact port and
/// finding it held says so and stops; one that was not told takes the first
/// free port from here and publishes it, because the alternative is that the
/// second worktree on a machine can never have a daemon at all.
pub const DEFAULT_HTTP_PORT: u16 = 3000;