Skip to content

Commands

Command What it does
bosun preflight [--quiet] Check what bosun needs on this machine, for each agent in use (Claude Code, Codex), and say exactly what to do about anything missing. It changes nothing. bosun init and bosun doctor start with the same check. See Setup
bosun init [--recommended \| --answers <file>] [--force] [--dry-run] / --detect / --print-answers Set bosun up from what this Mac shows: the repos you use your agents in (Claude Code and Codex), your usual hours, your logins. In a terminal it asks a few questions and shows the plan before it changes anything; otherwise it only prints the plan. See Setup
bosun update [--dry-run] [--yes] [--json] / update note --window <w> --stock\|--status / update advance Update bosun to the head of the branch it tracks (git config bosun.branch in the versions folder's bosun.git, default main) while the agents keep working, without losing a write. It fetches the new version into a folder of its own beside the running one, and that version shows the plan: the commits, the stores' migrations, the prompts that changed, what each window gets, the launchd jobs to reload, a running console to restart, and what stops it (something the new version needs and this Mac lacks, a store it cannot read, a link a backup cannot copy, a kg forget cut short). In a terminal it asks first; without one, or with --dry-run, it stops at the plan, and --yes goes ahead without asking. Then it rehearses the migrations and the stores' checks on a copy of the data, holds bosun's own background work, and pauses writes briefly: it backs the data up (backups/ in the state folder, the last 3 kept), migrates it, switches the install link to the new version and checks each store, and on any failure puts everything back as it was. Last it reloads the launchd jobs whose plist changed, restarts the check-in loop, lifts the hold and keeps what bosun doctor finds. Then it brings the agents along, each as the plan says but decided again from what it is doing now: the orchestrator re-reads its prompts when only they changed; a window something it was launched with changed for restarts on the new version once idle, after listing its background work if only that runs (a restart ends it, and the list goes back in the restart's prompt); a busy window is waited for, and one waiting for you is never touched; a window bosun did not start (outside the window list, with no launch recorded: a shell or a Claude you opened in its session) is left as it is, and the plan says so. Each gets a prompt to check for anything it missed and carry on, and answers with bosun update note --window <w> --status (the text on stdin; --stock is the list before a restart); the update waits for every answer, saying which windows it waits for. Ctrl-C stops the wait and leaves them to the check-in loop, whose bosun update advance takes a turn at them each tick (nothing while the update itself still runs; without a check-in loop, run it by hand); the next update is blocked at its plan while they are pending. See After an update. It ends with a short summary: the commits and how long it took, each store's migrations and version bumps, the config it changed and its new keys, what to change by hand in your own files, how many prompts changed, the jobs reloaded, the handed tasks that keep their old text, what came of each window, what fails after the switch that did not before (each bosun doctor FAIL with its detail that a doctor run before the hold did not show, with a count of those it did and of doctor's warnings), and where the backup is (the size of its files); it is saved as summary.md in the backup's folder once the update is done (by the update, the next bosun update or the check-in loop, whichever finishes it), and a failed update names its backup too. An update cut short is put back by the next write to a store, or by the next bosun update, which also finishes one whose checks had passed. --json prints one object on every path: the plan (null when none was made, as when it is up to date or refused), the update's record as it stands, and the summary (null unless an update ended in that run). A dry run never carries on or puts back an update cut short; it says one is there. It needs an install with its versions side by side (~/.local/share/bosun-versions, which get.sh makes); in a checkout of your own, update with git. The install line run again hands over to it, and its first run converts a checkout an older get.sh made, once: it refuses one with anything of yours in it; once every window is idle and nobody types, it stops bosun's own background work (the watchdog's and learning's jobs, the check-in loop), checks that the moment is still quiet (for two minutes at the most: past that it starts that work again and waits with everything running), swaps the checkout for the link in one step and keeps it as legacy-<its commit>, and restarts each of bosun's own windows; stopped short of the switch, or put back, it starts again what it stopped, as it was (after a crash, the install line run again does, as the old checkout has no bosun update; see Updating). An update deletes older version folders, but keeps one with a change or a commit of its own in it, as it keeps the checkout from before versions while anything of yours is in it, and its summary says so; one a running process still uses is left to a later update. See design/update.md
bosun morning [--dry-run] [--skip-setup] [--awake-minutes N] The scheduled entry point
bosun setup [--dry-run] Run (or just check) the setup steps
bosun alert [--dry-run] <message> Notify you: a macOS notification and, with BOSUN_ALERT_SLACK_USER set, a Slack DM to yourself sent by a headless Claude that can use only Slack's send-message tool and never waits for an approval
bosun attach Attach to the session on its own tmux server (tmux -L <socket> attach -t <session>)
bosun start [--restart] [--unless-active] / bosun stop Start the tmux session (or refresh it if it exists), or stop it; stop also releases the keep-awake
bosun refresh [--dry-run] [--drain-only] [--restart-idle] [--unless-active] [window...] / refresh [--dry-run] --update-restart <prompt-file> <window> / refresh [--dry-run] --checkin-loop Per window: restart idle sessions on an outdated agent or with a changed model or effort, send the drain prompt to idle ones with work in flight, relaunch exited ones (see Steady state). For an update: --update-restart restarts one window now if its turn is over (idle, or shell: only background work runs) and nobody is typing there (send's check), resuming its conversation with the prompt in the file instead of the drain prompt. A busy or waiting window, or one whose input box holds unsent text, is left running and refresh exits 3, so the caller can try again. An orchestrator still on yesterday's conversation starts today's with the morning chores instead, as on a new day, and a repo window with a fresh conversation pending starts that one; a window whose agent is not running is relaunched (a missing one created) with the update's prompt only when its launch resumes a conversation, and otherwise starts as a new conversation does. A window started into its next conversation gets that one's own prompt, not the update's, so refresh exits 4; every window starts on the agent its last launch ran, even if harness: or BOSUN_HARNESS now names another (that one takes over at the next refresh or start not for an update), and a window outside the window list (opened by send --new) keeps the directory and --model / --effort its launch recorded; one with no launch recorded is refused, as bosun did not start it. --checkin-loop restarts the check-in loop in the checkin window, which otherwise keeps the code it started with; it stops the loop at once, even in the middle of a tick, so call it while an update holds bosun's background work. Neither takes another mode, --unless-active included
bosun launch [--model M] [--effort E] [--harness H] [--no-prompt] <name> [prompt \| --prompt-file <file>] / launch --fingerprint <name> Resume a named session in the current directory, with the window's model and effort (--harness: on that agent instead of the configured one), and record what the agent was launched with (launches/<session>/<name>.json in the state folder: bosun's commit, the agent and the model and effort it runs with, the directory, a --model / --effort it was given, and a fingerprint of the agent's arguments and the files they name in the install, with the conversation's name and the orchestrator's policy text left out). --fingerprint prints the fingerprint a launch would record now, as an update would start the window again (on the agent it was launched on), and launches nothing: in the window's directory from the window list, or for a window outside it (opened by send --new) with the directory and --model / --effort its last launch recorded; it refuses a window with neither
bosun send --list / send <window> <msg> / send --new [--model M] [--effort E] <window> <dir> <msg> / send --start <window> [msg] List windows with their agent, status and version (claude:idle, codex:busy, no-agent); hand work to a running session (bracketed paste, so multi-line text arrives as one prompt; refused while Claude waits at a permission prompt or question; it waits while someone typed in that window within BOSUN_SEND_TYPING_MINUTES or its input line holds unsent text, up to BOSUN_SEND_WAIT_SECONDS, and fails unless Claude took the prompt, so the caller resends), open a new window, or start Claude in a window that has none (resuming its named session; without a message it gets the drain prompt). A message of - is read from stdin. --id <ledger id> names the work item (checked, prefixed, noted in its history); the orchestrator must give --id or --no-item. --new and --start run bosun launch as the pane's own command, with the task in a prompt file, and exit 0 only once Claude is running.
bosun delegate <type>[,<type>] --id <ledger id> --ask "<one line>" [--details ...] [--model M] [--effort E] (--print\|--window W\|--new W DIR\|--start W) [--again] / --update <ledger id> --details ... [--window W] / --list Hand a task to a repo session, with the rules for its task type from orchestrator/tasks/, and record the window on each item; refused while the item's last hand-over awaits a report, unless --again. --update sends an addendum to that window, framed with the item's id and kept in its history; with --window it moves the item: the new window gets the whole task, the old one is told to stop. --update <out-id> hands an outreach reply to the window holding its parent and marks it applied
bosun chores [morning\|check-in] [--dry-run [--fresh\|--continue]] Tell the orchestrator to run its chores now, or rehearse them headless with no side effects
bosun checkin [--loop] [--dry-run] Send /bosun:chores check-in if the orchestrator is idle and you are not typing (the checkin window loops this)
bosun ledger <command> Work-item ledger: list, show, upsert, transition, note, report and reports (repo sessions' outcomes, with --ci the CI status of a pushed PR; --since lists every one, with what I said in the window), delegation (where an item was handed over, and whether its window is working on it), said (what I typed in repo windows), working and idle (which item a window works on), in-flight (whether a window holds work), compact-context (what a window gets back after compaction), record-delegation, record-update and record-move (used by bosun delegate), propose (with --send, --run or --tool: the exact outward call), approve and approvals (see Approvals), resolve, resolve-carried-out (one-time: settle proposals whose approved call ran before the PostToolUse hook, by the transcript), seen, record-source, kinds (id formats, Slack classes, state machines), mark-run (also prints where the Slack scan starts), prune, render, diff; outreach (see Waiting on someone): reach-out (alias ask), sent, replied, outreach; tasks and links (see Tasks and links): spawn, link, unlink, fold, tree, migrate-links; tickets (see External tickets): ticket-sync, tickets; workstreams (see Workstreams): ws add|list|show|set-state|alias, assign, summary, lint, list --ws; checks: validate [--journal]
bosun guard [--approvals\|--permission-request\|--post-tool-use] PreToolUse hook for the orchestrator (see Permissions); with BOSUN_APPROVALS_ENABLED=1 also its approval hooks (see Approvals)
bosun hook user-prompt\|compact-context\|signal\|codex-turn-end What the agents call: Claude Code's hooks, and what Codex runs when a turn ends. Among them, what records what I type in a window (see Events)
bosun events [--once\|--dry-run\|--status\|--list [--all]\|--covered] Push events from repo sessions (reports, what I typed there, outreach drafts, follow-up tasks, windows waiting at a prompt) to the idle orchestrator as one summary; the check-in loop runs it with BOSUN_EVENTS_ENABLED=1
bosun slack-watch [--once\|--scheduled] [--dry-run] / --status Look for new Slack mentions, DMs and replies in your threads with a headless Claude that can only read Slack, and queue each new one as an event for the orchestrator; the check-in loop runs it with BOSUN_SLACK_WATCH_ENABLED=1 (see Slack watcher)
bosun context The orchestrator's working context: config, windows, owner/repo -> directory map, open items
bosun pr-threads <pr-url> [--awaiting-author] [--json] Review threads on a PR (read-only GraphQL): each unresolved thread with its replies and last commenter, whether it awaits the PR author (unresolved, last comment not by the author; bots are shown, marked, and never count, except reviewer bots: BOSUN_REVIEWER_BOTS, see below), the threads per review round, and each reviewer bot's latest verdict. --awaiting-author: only those, exit 3 while any are listed (the check before saying a review is addressed)
bosun review-watch [--dry-run] [--quiet] [--id <mypr id> ...] New reviews (changes requested or comments, by people other than the author or by reviewer bots, never other bots) on my PRs in addressing, awaiting-review or approved since their last hand-over (or report): recorded once on the item as review-arrived (no state change) and, with events on, queued as review events; prints each one still to act on with its next step. The chores run it in step 4; with events on, the check-in loop every BOSUN_REVIEW_WATCH_MINUTES (see Events)
bosun my-prs [--since 48h\|7d\|2w\|YYYY-MM-DD] [--by updated\|created] [--include-drafts] My open PRs within the repo mask and time window, as JSON lines
bosun resolve <dir> <name> / <dir> --list / --live <uuid> Inspect Claude Code's session-name resolution (exit 3: no such session, or none live). A Codex window is not covered: bosun's table for those is codex-sessions.json
bosun trust [--check\|--revoke] [--any] <dir>... Mark repo folders inside the repo mask as trusted by each agent in use, so unattended starts do not stall at its trust prompt
bosun uninstall [--dry-run] [--yes] [--delete-ledger] [--delete-knowledge] [--purge] Take bosun off this Mac. It says what goes and what stays, asks whether you are sure and whether to keep your ledger and knowledge graph, and changes nothing until you have answered. See Setup
bosun doctor Check tools (on launchd's PATH), the Claude Code login, config, names, schedule, the watchdog and learning agents, power, keychain, shells left behind by earlier window starts, setup, and the knowledge base and the ledger, each against its journal (bosun kg validate once there is a knowledge base, bosun ledger validate --journal once there is a ledger, each finding's line shown: journal damage, a position that does not match or a rebuild that differs fails, since writes are refused or data is at risk; a broken rule, a conflict, an update waiting for its fact, an outside edit the next write adopts or a knowledge file that does not parse, which the next write writes again, warns), and what the last bosun update left to you: what to change by hand in your own files (warns), and the config keys it added that bosun.env does not set, with the value each has now
bosun orphans [--apply] List the shells earlier window starts left behind: helpers a pane's launch shell (<shell> -lic <this checkout>/bin/bosun launch ... or ... checkin --loop ...) forked off while reading your startup files (a prompt theme's git-status daemon), adopted by launchd, with no children and not tmux itself. --apply stops them (SIGTERM, after checking the pid again). launch, checkin --loop, refresh and stop stop such helpers themselves
bosun watchdog [--once\|--dry-run\|--status\|--list\|--facts] [--only <check>,...] Alert you once per problem, among 17 checks: no or failed morning run, missing session or check-in loop, an agent stopped at a screen or waiting at a prompt, new ERROR lines in the logs, ledger items stuck in delegated, a background command keeping a Claude in shell for hours, an expired Claude Code login, and with BOSUN_LEARN_ENABLED=1 a missing, failed or stalled learning run. Its own launchd agent runs it every 5 minutes; --facts prints what it reads of tmux, ps and launchd as JSON (what the console reads)
bosun sessions [--json] Every window (configured or open) with its kind, folder, agent and status, session id and transcript path (.agent in --json; .conversation is the one its next launch takes up)
bosun learn [--since 24h\|3d\|<ISO time>] [--until <ISO time>] [--dry-run\|--collect-only] [--out <dir>] / --scheduled / --status (also status, list) / apply <learn-id> / done\|reject <learn-id> [--note <text>] Look back over the sessions, ledger and logs since the last run and propose memory notes, rules and setup changes, each a learn: ledger item waiting for your approval (see Learning). --scheduled is what its launchd agent runs: once a day, after BOSUN_LEARN_AT
bosun kg <command> Organizational knowledge (see Knowledge): add-entity, propose (with --from-user --quote: my own words, verified in the transcript), confirm, reject, supersede, batch and batch apply (the daily review), import (proposals only, a dry run unless --apply), identify, forget, expire; reading: lookup, facts (--as-of), search, neighbors, context --for, lint, validate (the files against the journal they are the rebuild of), stats, schema
bosun console [--port N] [--open] [--new-token] A local web console over the ledger, the sessions, bosun's health and the knowledge base; read-only except for knowledge review decisions (see Console)
bosun impact collect [--since YYYY-MM-DD] [--dry-run] Collect the console's Impact snapshot: my merged PRs and my reviews of other people's PRs (GitHub, read-only) and, per bosun window and day, agent busy time, the prompts I typed and tokens; daily from the morning run with BOSUN_IMPACT_COLLECT=1 (see Impact)
bosun status Schedule, recent sleep/wake events, assertions, windows, the Claude Code login per window, the watchdog's checks, proposals awaiting approval, open outreach, today's log
bosun wake-test [N] [--full] / --report / --cleanup Real sleep/wake end-to-end test