bbx Command Reference
These are the bbx commands most relevant to agents working in a box.
bbx template
When bbx health or bbx status reports a parked update, use its box-relative path:
bbx template diff _config/intake.guide.card bbx template accept _config/intake.guide.card
diff shows local, parked upstream, and last stock. Older tracker entries retain only the stock hash, so exact last stock may be unavailable. Inspect learned or box-specific content before accept, which replaces the local file. To keep or combine local content, edit the local file and run bbx template resolve <path>. This records the reviewed upstream version and clears the park, so the same version will not park again. Later upstream revisions can still park. The installer merges separate edits automatically when it has a last-stock snapshot; conflicts remain parked for judgment.
bbx create
Create a new card from a template.
bbx create <path> [options]
The card type is inferred from the filename (e.g., my-question.question.card → question template).
Options:
<path> [key=value ...]— the card's path, then the template's arguments askey=valuepairs (see the examples)-t, --template <name>— Override the template (usually inferred from the card type in the filename)-a, --attachment <path>— Path to an attachment file--commit— Commit the new card immediately--list-templates— List every template this box can use--describe-template <name>— Show a template's arguments
Examples:
# Create a doc bbx create _content/inbox/my-note.doc.card title="Check the logs" body="Remember to check the logs" # Create a yes/no question bbx create _bookkeeping/questions/confirm.question.card -t question-confirm \ memo="The capture session is ready to archive" prompt="Archive it?" # Create a scheduled script bbx create _config/schedules/check.scheduled-script.card runs="bbx engine wakeup" cron="0 6 * * *"
For array or structured frontmatter values, use JSON (options='["Red","Blue"]') — JSON is the default for anything machine-set. Two-step pattern: for a complex card, bbx create a minimal one, then edit it to fill in the details.
bbx create --list-templates lists every template this box can use, its own included; the built-in ones are below.
Available Templates
guide
A generic guide card — triage rules, actions, experiments, reactions
Card types: guide
Arguments:
name— Domain name (intake, calendar, drive, chat, or custom)
record
A record card — generic extracted unit from capture sessions
Card types: record
Arguments:
name— Short identifying label for the recorddescription(optional) — Description of the thing
scheduled-script
A scheduled script card — declarative scheduling for commands
Card types: scheduled-script
Arguments:
runs— The command to executedescription(optional) — Human-readable summary of what this schedule doescron(optional) — Cron expression (e.g.,0 6 * * *)at(optional) — ISO datetime for one-shot executionrrule(optional) — iCalendar RRULE stringnotBefore(optional) — Minimum interval since last run (e.g., '5m', '1h')onWakeup(optional) — Also run during bbx wakeuponce(optional) — Delete after successful executionreason(optional) — Why this schedule existslock-group(optional) — Named concurrency group
todo-view
A todos display surface — the box-wide Todos page, or a project-local subtree instance
Card types: todo-view
Arguments:
title(optional) — Display title for the viewglob(optional) — Glob scoping which cards to scan (default: this card's own directory subtree)todo-status(optional) — Restrict to todos with these statuses (default: open and parked)assigned(optional) — Restrict to todos with this exactassignedvalue
briefing
A briefing card — core situational context for a box or directory
Card types: briefing
doc
A generic typed document — use instead of .md when an agent creates a new document
Card types: doc
Arguments:
title— Display title for the documentbody(optional) — Initial markdown body content
person
A person card — key people referenced from briefings
Card types: person
Arguments:
name— Full name of the personaliases(optional) — Alias or nicknamerole(optional) — Relationship or function
place
A place card — a named location the box can recognize (Home, Office)
Card types: place
Arguments:
name— Name of the placealiases(optional) — Another name for the placeaddress(optional) — Human-readable address (street, city)
figure
An embeddable interactive figure (p5.js / three.js / D3 / canvas-loop); scaffolds a runnable starter sketch
Card types: figure
Arguments:
runtime— Runtime: p5js | three | d3 | canvas-looptitle(optional) — Display title
browser-task
A prompt for someone with a logged-in browser; the card is the inbox for what they find
Card types: browser-task
Arguments:
title— Display titlestart— The URL the executor starts atprompt(optional) — The prompt body; omit to get the four-heading scaffold to fill in
question
A multiple-choice question card
Card types: question
Arguments:
memo— Context/background for the questionprompt— The question to askoptions— Answer options (at least 2)directive(optional) — What to do with the answer — creates a follow-up job using this text as instructionslearning(optional) — Durable belief the answer teaches: {sink: guide|briefing|personality, ref?, proposal}expires-after(optional) — ISO-8601 duration overriding the default expiry window (e.g. P30D, PT12H)
question-text
A free-text question card
Card types: question
Arguments:
memo— Context/background for the questionprompt— The question to askdirective(optional) — What to do with the answer — creates a follow-up job using this text as instructionslearning(optional) — Durable belief the answer teaches: {sink: guide|briefing|personality, ref?, proposal}expires-after(optional) — ISO-8601 duration overriding the default expiry window (e.g. P30D, PT12H)
question-confirm
A yes/no confirmation question card
Card types: question
Arguments:
memo— Context/background for the questionprompt— The question to askdirective(optional) — What to do with the answer — creates a follow-up job using this text as instructionslearning(optional) — Durable belief the answer teaches: {sink: guide|briefing|personality, ref?, proposal}expires-after(optional) — ISO-8601 duration overriding the default expiry window (e.g. P30D, PT12H)
dashboard
Canonical dashboard card. Restore only at _config/interface/dashboard.card; additional instances are invalid.
Card types: dashboard
settings
Canonical settings card. Restore only at _config/interface/settings.card; additional instances are invalid.
Card types: settings
browse
Canonical browse card. Restore only at _config/interface/browse.card; additional instances are invalid.
Card types: browse
questions
Canonical questions card. Restore only at _config/interface/questions.card; additional instances are invalid.
Card types: questions
landmarks
Canonical landmarks card. Restore only at _config/interface/landmarks.card; additional instances are invalid.
Card types: landmarks
history
Canonical history card. Restore only at _config/interface/history.card; additional instances are invalid.
Card types: history
inventory
Canonical inventory card. Restore only at _config/interface/inventory.card; additional instances are invalid.
Card types: inventory
admin
Canonical admin card. Restore only at _config/interface/admin.card; additional instances are invalid.
Card types: admin
search
A copyable Search interface card with optional durable defaults.
Card types: search
bbx mv
Move or rename a card, updating references in other cards.
bbx mv <source> <destination>
Use this instead of git mv or mv — it updates cross-references.
Examples:
# File an inbox item into its permanent home bbx mv _content/inbox/Recipe.recipe.card _content/recipes/Recipe.recipe.card # Archive a processed item bbx mv _content/notes/Old_Note.doc.card _bookkeeping/archive/done/Old_Note.doc.card
bbx rm
Soft-delete a card by moving it to _bookkeeping/trash/.
bbx rm <path>
bbx validate
Validate a card against its schema.
bbx validate <path>
<path> is a card, a Markdown file, or a directory. A directory validates every card and Markdown file under it, skipping the same files a whole-box bbx validate skips.
Validation already runs after every edit (a hook installed by bbx engine init) and on commit, so you rarely call this yourself; run it to re-check one card while debugging. Returns a non-zero exit code on failure.
bbx view check
Render every agent-authored view (views/<slug>.tsx) in Node and report which fail.
bbx view check [--json]
Compiles each view, loads the real cards its dependencies select, renders it once, and prints ✓ <slug> or ✗ <slug> with the error and a stack mapped to your .tsx source. Exits non-zero if any view fails. Run it after writing or changing a view. It's a synchronous render (no effects/async helpers); see node_modules/beebox/box-docs/views.md for what it does and doesn't cover.
bbx answer
Answer a pending question card.
bbx answer <question> <answer>
<answer> is the answer text, or an option ID (a, b, c, …) for a select question.
bbx contains
Maintain the contains: field across the box.
bbx contains list [--missing] [--stale] [--json] bbx contains update <card> --text "..."
If you edit content and the sentence still holds, bbx contains update <card> --text "..." clears the staleness flag; bbx contains list --missing / --stale shows which cards still need one written or refreshed.
bbx status
Show a summary of the box state — item counts in each directory, git status, etc.
bbx status
bbx session
Read a past session's transcript (chats, wakeups, job runs).
bbx session [<id>] [--list] [--latest] [--dialogue-only] [--tool-report] [--since <when>]
--list to find recent sessions, --latest or <id> to view (--dialogue-only for just the conversation, --tool-report for tool usage, --since 2d for a window). To search a large transcript, spawn a subagent (Task tool) to read it and report back the relevant part instead of pulling the whole transcript into your own context.
bbx reactor
Process all pending jobs in _bookkeeping/jobs/.
bbx reactor [--dry-run]
The reactor finds all *.job.card files in _bookkeeping/jobs/, spawns an agent session, and processes them according to each job type's instructions (from .claude/rules/). The agent calls bbx finish for each completed job.
bbx finish
Complete a job by deleting its card file and committing the deletion.
bbx finish <job-file>
Call this after all work for a job is done and committed. It only handles the job card deletion.
bbx search
Full-text search over the box's cards, its standalone .md files (kind markdown), and the engine's reference docs (kind engine-doc), ranked by relevance.
bbx search "<query>" [--kind <type>...] [--path <prefix>] [--limit <n>] [--mode <text|hybrid>] [--json] [--rebuild]
Query style: when the box has an embeddings key configured, search ranks by meaning as well as words (each card's contains: sentence is matched semantically, fused with keyword ranking). So for vague recall, describe the card in one sentence — shaped like the contains: line you hope exists — and include any exact tokens you remember (names, numbers, IDs): the sentence carries the semantic match, the rare tokens nail the keyword match. Both in one query is the optimum, not a compromise. For an exact-identifier hunt the bare token alone works. Without an embeddings key, ranking is keyword-only: lead with distinctive words. Either way it's relevance-ranked — quoting a phrase does not do exact-match.
Examples:
bbx search "the letter about the pension from the insurance company"— vague recall: describe it; meaning-ranked even though no word may match exactlybbx search "dentist appointment moved to a new date" --kind email-message— a summary-shaped sentence, emails onlybbx search "Priya phone" --path _content/people— exact tokens + a path filterbbx search "10494" --mode text— an exact identifier;--mode textforces keyword-only ranking (offline, deterministic)
Filters: --kind <type> (repeatable), --path <prefix> (box-relative, so _content/…), --limit N (default 10); --mode <text|hybrid> (omitted = automatic: semantic+keyword when available); --json for the structured envelope.
A result shows the card's path (with a #fragment locator when the match is inside the card) and title, then the card's contains: sentence and a matched excerpt — so you see both which card and where in it. A truncated run reports "N of total."
bbx procedure
Run and manage declarative procedures. See node_modules/beebox/box-docs/procedures.md for details.
bbx procedure run <name-or-path> # Run a procedure bbx procedure run <name> --step <id> # Run a single step bbx procedure run <name> --dry-run # Preview without executing bbx procedure run <name> --directive "text" # Pass a directive to agents bbx procedure list # List available procedures bbx procedure status [run-dir] # Show status of latest/specific run
The <name-or-path> argument can be a bare name (resolves to _config/procedures/<name>.procedure.card) or a direct path to any .procedure.card file.
The --directive flag passes an opaque string that appears as <directive>...</directive> in every agent's system prompt within the procedure. Use it to customize behavior without modifying the procedure card.
bbx tick
Evaluate scheduled scripts and run any that are due.
bbx tick [--dry-run] [--script <name>] [--force] [--json] [--box <path>]
Checks all _config/schedules/*.scheduled-script.card files against their cron/at/rrule schedules. Runs due scripts, updates last-run timestamps, and deletes one-shot (once) scripts after execution.
Options:
--dry-run— Show which scripts would run without executing them--script <name>— Only evaluate a specific script (by filename stem)--force— Run the--scriptnow, bypassing schedule, budget, and active-chat checks. Use this when the boxholder asks for a run from chat — a plain tick defers on the chat session itself. Running scripts/procedures and live lock-group holders still defer; force never preempts running work.--json— Print one JSON object instead of text:dryRun, the counts, and ascriptslist with one record per script:statusran,skipped(withreason: not due, disabled, budget exceeded, system busy, a deferral),error(witherror), orinconclusive. The exit status stays 0 when a script errored, so readerrorCountor theerrorrecords.--box <path>— Target a specific box instead of the current directory
Note: scripts with on-wakeup="true" also run during bbx engine wakeup, subject to their not-before interval.
bbx scheduled
List all scheduled scripts and their status.
bbx scheduled
Shows each schedule's name, type (cron/at/rrule), next due time, last run, and flags (on-wakeup, once, enabled).
bbx run-summary
End a scheduled run with a summary the boxholder sees in the dashboard's run history.
bbx run-summary "Filed 3 receipts" --body "- 2 from email\n- 1 skipped: no amount" bbx run-summary "2 imports failed" --priority attention --notes - < details.md
Headline up to 120 characters; --body (1 KB) and --notes (4 KB, shown collapsed) are Markdown, and - reads stdin. --priority attention marks a run worth a look; the default is normal. It writes to $BBX_SUMMARY_FILE, set by the scheduler; outside a scheduled run it prints the summary instead. The last call in a run wins.
bbx health
Show scheduled-task health: failing, overdue, blocked, inconclusive, or invalid tasks, plus whether the scheduler daemon is alive.
bbx health [--json] [--all] [--box <path>]
Per task: status, last attempt vs last success (they diverge while failing), consecutive-failure count, and the last error. --all includes disabled tasks. Exit code 1 when anything is failing/overdue/invalid or the scheduler heartbeat is stale, so scripts can gate on it. Deliberate skips (budget exhausted, missing connector, disabled) show as blocked/disabled, never as failures. A task whose last run completed its work but whose check reached no verdict shows as ? inconclusive — unknown, not broken — and does not affect the exit code. inconclusive means the last run did its work but its check never reached a verdict — unknown, not broken; do not redo the work on that basis.
bbx scheduler
Read the state of the background scheduler daemon that runs bbx tick on a recurring basis. Starting and installing the daemon is an operator act and lives under bbx engine scheduler.
bbx scheduler status # Show boxes + launchd status bbx scheduler log [--box <path>] [--limit <n>] [--errors] [--json]
The daemon polls every 60 seconds (configurable). Config at ~/.config/beebox/scheduler.json. Per-box logs are written to .beebox/scheduler.jsonl (JSONL, auto-rotated at 1MB). Each log entry records which scripts ran/skipped/errored with timestamps and durations. Agents can read .beebox/scheduler.jsonl to understand recent scheduling activity.
bbx finalize
Run outbound connectors to flush pending output cards.
bbx finalize [-c, --connector <name>]
Symmetric counterpart to bbx engine wakeup. Sends any pending cards in _bookkeeping/output/ (e.g. Gmail drafts). Called automatically by the reactor after job processing, or run manually to flush output.
bbx notify
Send the boxholder a notification now. Run bbx notify --check first when you are about to promise a reminder or a watch: it prints which channels can reach the person and exits 1 when none can.
You cannot turn a channel on. The person does it in the app. Send them to the place that fits:
- This browser or computer: the profile menu, then Admin, the Host tab, Notifications, and "Enable notifications". Each device turns this on for itself. On an iPhone or iPad, the person first adds the app to the Home Screen and opens it from there. If the browser blocks notifications for the site, the section says so instead; the person allows them in the browser's site settings and reloads.
- The Bee Box iPhone app: the profile menu, then Settings, Companion Apps, and "Show QR Code (iPhone)". The person scans the code with the phone. The app registers for notifications when it opens, if the person allowed notifications for it in iOS.
--loudness is dot (badge only), quiet (muted; held back while they are in the app), or loud (sound). --target is where a tap lands: chat:<sessionId>, chat:new, card:<path>, question:<path>, admin:<section>, dashboard. --tag <key> makes a later notification replace this one. A long body goes on stdin with --body -; without it stdin is never read. --dry-run prints what a send would do without sending. A failure the person must fix, after they left the chat it came from:
bbx notify "I couldn't read the receipt you photographed" --loudness quiet \ --target chat:<that sessionId> --body "The total is cut off. Can you retake it?"
In a chat turn, <callout loudness="quiet"> does this for the turn's outcome. A reminder at a time is a scheduled-script card with notify:; a watch that notifies when something happens is a scheduled-script card whose runs: pipes bbx changes into bbx judge and then an agent or bbx notify. Both examples are in card-scheduled-script.md; the judgment card is card-judgment.md.
bbx chat
Talk to the live chat session.
bbx chat self-note "<body>" [--ref <path>] [--commit <hash>]— Post an agent-authored record into the chat transcript without triggering a reply.bbx chat screenshot [--session <id>] [--timeout <seconds>]— Ask the user's connected chat tab for a screenshot of what they currently see in the box UI, and print the saved image path (Read it) plus afidelity:line. Reach for it on visual/layout questions — how a card or custom view actually renders — wherewhats-changed(content) and reading the source can't help. It asks the user's browser, so instead of a path it may print one ofdeclined:/no-client:/timeout:/failed:/error:telling you it was declined or unavailable. Defaults: the session fromBBX_CHAT_SESSION_ID, a 45s wait.bbx chat ask-about-audio "<question>" --message <id> [--context <text>]— Ask an audio-capable model (Gemini) a question about a specific voice message (or--file <path>for any audio file).--messageis required unless--fileis given: read themessage-id="…"attribute off the<speech>wrapper of the message you mean — never fabricate it. Claude can't listen to audio itself; use this when the exact audio matters — a mangled-but-important transcription, pronunciation, tone — not routine chat. The system's own transcript rides along automatically so the model can flag transcription flaws;--contextsupplies conversational background (what the message responds to), and--transcriptoverrides the known transcription.bbx chat retranscribe --message <id> [--diarize] [--service <name>]— Re-run a specific voice message (same--messagetargeting, or--file <path>) through the high-quality transcription pass (Whisper/Voxtral; default is the box'shqServiceconfig). For when the realtime transcript looks wrong and you just need the correct text — cheaper and more direct thanask-about-audio. Worth it only when the message's wrapper saysstt="live": every other current voice message already came from the HQ pass, so retranscribing adds nothing. (Older messages may be live too:stt="deepgram",hq="failed", or nosttat all.)--diarizelabels speakers. Prints the HQ transcript plus arealtime-transcript:line for comparison. A successful run shows the corrected text on the user's message automatically — don't paste it back unless asked.bbx chat get-last-audio --message <id> [--out <path>]— Fetch the raw recording of a specific voice message to a temp file; prints the path. Use when you need the file itself rather than an answer about it.
A bare command (no --message) errors — these commands never guess which recording you mean. The recording is available only while the chat tab that recorded it is open, and only for the last few voice messages (the retention window).
bbx browser
bbx browser <agent-browser command>— Drive the box's one shared browser:open <url>,snapshot -i(interactive elements with refs such as@e3),click @e3,fill @e4 "text",get text @e5,wait,tab list,screenshot(saved under_tmp/browser/). Logins persist. The person opens the same live browser from the profile menu's Browser item on a computer. Use WebFetch for public pages; use this for a page that needs a login, scripts, or the person's help.bbx browserwith no arguments prints the short help. When to stop and ask the person, and what it refuses: thebrowserskill (.claude/skills/browser/SKILL.md).
Credentialed commands
The drive, calendar, and connector families need a Google credential, which your shell deliberately does not hold. They still work: the box's own server does the credentialed half and hands back the same typed result the settings page gets. When something is missing, the command says which of three parties can fix it — you (adjust the command), the boxholder (enable or authorize), or the machine.
Every verb that asks Google takes --json, which prints exactly one object — the result, or {kind, message, fix} for a refusal — so you never parse prose. gws is the exception: it prints what the upstream command printed.
bbx force-wakeup
Run a wakeup now on the server and report what each connector did.
bbx force-wakeup [--connector <name>] [--json]
--connector matches the connector's registered name exactly (google-drive, google-calendar, gmail). The result says, per connector, what was created, updated, and pushed — or that it was skipped, and why. Reach for it after mounting a Drive folder or changing connector configuration, and whenever the boxholder asks "did it sync?"
bbx drive
Mirror and point at Google Drive content. A mount is a card, so everything here writes cards you can read.
bbx drive inspect <url-or-id> # What is this, and does a card already claim it? bbx drive mount <url-or-id> <dir> # Mirror a folder into a directory bbx drive link <url-or-id> <path> # Point at any item, copying nothing bbx drive add <url-or-id> <path> # Two-way sync one Doc or Sheet bbx drive unmount <dir-or-card> # Stop mirroring; children stay put bbx drive list [folder] # Browse Drive without writing anything
inspect writes nothing — run it before a mount to check the id resolves, and after one to confirm what landed. A mount reports whether the box's hourly Drive sync (check-drive) is off; if it is, ask the boxholder whether to turn it on, and use bbx force-wakeup --connector google-drive meanwhile.
bbx drive sync runs the connector in your own process, so it works only for the box's own tooling; bbx force-wakeup --connector google-drive is the equivalent you can run.
bbx calendar
bbx calendar [timespan] # Upcoming events: today, 3d, 2w, 1m (m = months; default 7d) bbx calendar calendars # Every calendar the grant sees, and which sync bbx calendar add <id> # Start syncing one bbx calendar remove <id> # Stop syncing one bbx calendar vtimezone # This box's VTIMEZONE block, for .ics events
Reading events, add, and remove work off the box's own files. Only calendars asks Google, so only it needs the server.
bbx connector gmail
bbx connector gmail track <thread-id> # Materialize one thread as a card bbx connector gmail pending [rule] # Untracked rule matches, from local state bbx connector gmail gws <args...> # A read-only Google Workspace CLI command
gws passes its arguments through to the upstream vocabulary and prints what that command printed; only read operations are accepted, and anything else is refused before a token is minted. pending reads local state and needs nothing from Google.
bbx engine wakeup — system-run
The cycle itself: connectors, jobs, on-wakeup scripts, push. It lives under bbx engine because it needs the server's credentials. The scheduler and the server run it, with the credentials it needs; running it yourself syncs nothing and reports that as "nothing new". bbx force-wakeup above is how you trigger a real one.
bbx secrets
The agent-facing bbx secrets verbs. Where credentials live, and why never in the box, is in the agent guide's SECRETS section.
bbx secrets declare <name> --note "<what it is and where to get it>" --use "<why you need it>" bbx secrets describe <name> --add-use "<reason>" bbx secrets status <box>
bbx secrets status <this box> shows what this box has and what it is still waiting on (your own box only — the machine's other boxes are the boxholder's business).
- Building something new on a key that is already granted? Say so:
bbx secrets describe <name> --add-use "the umbrella reminder trick". Reasons are additive — one key usually serves several tricks — and this is the list the boxholder reads when deciding whether a key still earns its keep. You may add a reason; removing one is theirs.
bbx host install
bbx host install <pkg...> --why "<reason>"
Missing a command-line tool that Debian/Ubuntu packages (e.g. glabels)? bbx host install <pkg> --why "<reason>" records it in _config/host-packages.json and installs it from the distro repositories; commit the file. The host refuses packages that add a service or upgrade anything, and a host without support (macOS) only records the need. After either, ask the boxholder; don't suggest sudo apt. Python libraries are not host packages.