taw-fleet command reference
Every taw-fleet command and flag, the JSON output, the doctor finding codes, the Keychain items, the environment variables and the files taw-fleet uses.
taw-fleet on its own opens the dashboard. Every command below also takes -h or --help.
Global flags
| Flag | Default | Does |
|---|---|---|
--offline | off | Don't ask GitHub for the newest versions; use the cache. Works on every command. doctor and show also skip production, BugSmash and pull requests, comments uses BugSmash's 5-minute cache, and the dashboard has no PR or DEPLOY columns |
--window | true | taw-fleet alone only. Opens the dashboard in a new terminal window. --window=false keeps it in the current terminal. Wins over the window setting |
--site <site> | taw-fleet alone only. Opens the dashboard on that site, its details showing. What a notification's click runs |
There is no --version flag: use taw-fleet version.
Naming a site
<site> is the site's folder name in ~/Local Sites, its name in Local, its domain (with or without .local), its Local id, or one of its TAW theme folders. Names, domains and theme folders are matched without regard to case. A term that matches several sites is an error that lists them.
When a site has several TAW themes, commands that work on a theme take --theme <folder>. Naming a theme folder as <site> picks that theme too.
Output, questions and exit codes
- Output is colored in a terminal and never when piped.
--jsonoutput is never colored. - Commands that change something ask first (
[y/N]). Without a terminal they refuse with “not a terminal: add --yes to confirm”, so a script never changes a site by accident.--yes(or-y) skips the question. - Progress goes to stderr, the summary to stdout.
- The exit code is
0on success and1on an error.wpexits with wp-cli's own code.doctorexits0whatever it finds: read its findings, or its JSON.
JSON output
Only these commands take --json:
| Command | Top-level shape |
|---|---|
list | { "sites": [Site], "scanned_at", "latest": {…}, "errors": [{ "stage", "error" }] }. TAW sites with their TAW themes only, unless --all. latest holds the newest taw/core, taw-theme, taw-gutenberg and taw-fleet tags |
show | { "site": Site, "findings": [Finding], "latest": {…} } |
doctor | { "scanned_at", "counts": { "error", "warn", "info" }, "findings": [Finding], "clean": ["<folder>"] }. clean lists the TAW sites with no finding |
live | { "<folder>": Production }, one entry per production site |
comments | { "<folder>": Feedback }, one entry per site with a BugSmash project. Each carries open, oldest_at and the five newest comments |
comments projects | [{ "id", "name", "type", "short_url", "frontend_url", "project_versions" }] |
prs | { "themes": [{ "site", "theme", "github": RepoState }] } |
sync | bin/taw sync's report: { "taw_core", "tier1", "tier2", "applied", "errors", "clean" } |
inspect | bin/taw inspect's JSON, unchanged |
create | { "name", "slug", "site_id", "url", "admin_url", "admin_user", "admin_password", "kind", "theme_dir", "theme_path", "taw_core", "commit", "warnings" }. It includes the password |
A Finding is { "severity": "error" | "warn" | "info", "code", "site_id", "site", "theme", "message", "fix" }. A Site carries its Local details, its themes (each with core, git, drift, github, account, skills_missing…; git.remote is taw.json's delivery remote when it isn't origin, git.foreign_upstream the other repository a branch tracks), and production and feedback once they've been read. taw-fleet show <site> --json is the quickest way to see every field.
Commands at a glance
| Command | Does |
|---|---|
list | Every Local site with a TAW theme |
tag | A site's tags: show, set, add, remove |
notes | A site's notes: show them, or add one |
show | One site in full |
doctor | What needs attention, with finding codes |
refresh | Everything again, past the caches |
open | The theme in your editor, Finder or a terminal; the site, wp-admin, production or GitHub in the browser |
work | Site, editor, Vite and browser in one go |
start, stop, restart | A site, through the Local app |
unstick | End Local's leftover processes in a site's way |
wp | wp-cli on a Local site |
sync | bin/taw sync: compare with the taw-theme scaffold |
update | Update a site in one step: the theme's vendor/bin/taw update. --all for every theme |
inspect | bin/taw inspect: blocks, fields and forms of a running site |
handoff | The update prompt for Claude Code |
create | A new Local site with a TAW theme |
live | The production sites through their companion |
pull | Production content into the Local site |
publish | The Local site's content to production, after a field-by-field review; undo, history |
wp-remote | The production site's REST API, as its bot user |
prs | Open pull requests, CI and deploys |
merge | Merge a pull request (deploys production) |
ready | What a site has and still needs (the SETUP checklist) |
repo | Put a new site's theme on GitHub |
deploy | Set up a site's deploy to any host |
launch-report | Check a live site and write its launch report |
comments | Open BugSmash comments |
watch | A macOS notification when something needs you |
restore | A site's restore points, and putting one back |
report | A site's monthly report for its client |
chat | What the dashboard's chat (>) tells Claude |
init | Set up the fleet folder (~/TAW Fleet) |
config | The settings file |
self-update | Replace taw-fleet with the newest release |
version | The version |
completion | Shell completion scripts |
help | Help for any command: taw-fleet help <command> |
Look at the fleet
list
taw-fleet list [--all] [--json] [--tag <tag>]
The Local sites that have a TAW theme, with their status, themes, kind, taw/core, git, domain and tags.
| Flag | Does |
|---|---|
--all | Also sites and themes that aren't TAW |
--json | Print JSON (each site with its tags) |
--tag <tag> | Only the sites with that tag. Repeat it for several, which must all match. A tag ending in : matches any tag that starts with it (--tag client:) |
tag
taw-fleet tag <site> [tag…] [--add <tag>] [--remove <tag>] [--clear] [--yes]
With only the site, prints its tags. With tags, sets them, replacing the old ones. --add and --remove change a few; --clear removes them all. A tag is lower case letters, digits, :, _ or -, up to 12 per site. Asks first; --yes doesn't. The dashboard's #. See Tags and groups.
notes
taw-fleet notes <site> [text…] [--by you|claude] [--last N] [--json] [--path]
With only the site, prints its notes, newest first. With text, adds a note (- reads it from stdin). Adding doesn't ask: a note only goes into ~/TAW Fleet/sites/<site>/notes.md. note works too. The dashboard's N. See Site notes.
| Flag | Does |
|---|---|
--by | Who writes it: you (the default) or claude |
--last, -n | Only the newest N |
--json | Print JSON: {site, file, notes: [{at, by, text}]}, or {site, file, note} after adding one |
--path | Print the notes file's path |
Put -- before a note that starts with -: taw-fleet notes acme-shop -- "-50% sale page is live".
show
taw-fleet show <site> [--json]
One site in full: Local, its themes, production, BugSmash, its findings and its five newest notes (notes in the JSON).
| Flag | Does |
|---|---|
--json | Print JSON |
doctor
taw-fleet doctor [site] [--json]
Every TAW site, or one, with what needs attention, most serious first, each with its fix. It only reads. Production, BugSmash and pull requests are included unless --offline. See Doctor finding codes.
| Flag | Does |
|---|---|
--json | Print JSON |
refresh
taw-fleet refresh
Everything the dashboard shows, read again for every site, past the caches (the dashboard's ctrl+r): the Local sites with the newest versions from GitHub, the pull requests, CI and deploys, the production sites, the BugSmash comments, and the scaffold check of every classic theme. It writes nothing but taw-fleet's own cache. No flags.
Open and work
open
taw-fleet open <site> [flags]
With no flag, opens the theme in your editor. Several flags open several things.
| Flag | Opens |
|---|---|
--editor | The theme in your editor (the default) |
--finder | The theme folder in Finder |
--terminal | A terminal in the theme folder |
--browser | The Local site in your browser |
--admin | The Local site's wp-admin |
--production | The production site (production_url) |
--github | The theme's repository on GitHub |
--prs | The repository's pull requests |
--theme <folder> | Which TAW theme, when the site has several |
work
taw-fleet work <site> [--stop] [--theme <folder>] [--yes]
Starts the site when it's stopped, opens the theme in your editor, runs Vite (npm run dev, or pnpm or yarn) in its own terminal window, and opens the site once Vite answers. The dashboard's w.
| Flag | Does |
|---|---|
--stop | Stop the theme's Vite and the site instead |
--theme <folder> | Which TAW theme, when the site has several |
-y, --yes | Don't ask |
start, stop, restart
taw-fleet start <site> [--yes]
taw-fleet stop <site> [--yes]
taw-fleet restart <site> [--yes]
Through the Local app, which must be open. Each waits until the site is up or down, up to three minutes. Before it acts, it looks for Local's leftover processes in the way and names them instead of trying against them (see unstick).
| Flag | Does |
|---|---|
-y, --yes | Don't ask (needed in scripts) |
unstick
taw-fleet unstick <site> [--yes]
After a lot of starting and stopping, Local can leave nginx or php-fpm workers behind whose master is gone. They hold the site's PHP socket, its port, or the router's ports 80 and 443, so the site hangs or Local reports a port conflict. unstick lists them and ends them after asking. It only touches Local's own nginx and php-fpm whose parent is gone.
| Flag | Does |
|---|---|
-y, --yes | Don't ask |
wp
taw-fleet wp <site> [wp-cli arguments]
wp-cli with the site's PHP, Local's wp-cli and the site's MySQL socket. Everything after the site goes to wp-cli unchanged, flags included, and wp-cli's exit code is kept.
taw-fleet wp john-seed option get stylesheet
taw-fleet wp taw plugin list --format=json
Theme tools
These run the theme's own tools with the site's PHP and Local's Composer. sync, update and handoff refuse the umbrella's own taw-theme and taw-gutenberg; update --all and handoff --all leave them out.
sync
taw-fleet sync <site> [--apply] [--json] [--theme <folder>] [--yes]
taw-fleet sync --all
Runs the theme's php bin/taw sync: compares its framework files (Tier 1) and docs and config (Tier 2) with the newest taw-theme. Read-only unless --apply. For classic themes with bin/taw only.
| Flag | Does |
|---|---|
--apply | Write the Tier 1 changes. Tier 2 is never written |
--all | Check every classic TAW theme, read-only. Can't go with --apply |
--json | Print bin/taw sync's JSON report |
--theme <folder> | Which TAW theme, when the site has several |
-y, --yes | Don't ask (with --apply) |
update
taw-fleet update <site> [--theme <folder>] [--yes]
taw-fleet update --all [--yes]
Runs the theme's own vendor/bin/taw update with the site's PHP and Local's Composer, after one question worded from the theme's taw.json. On a new branch it updates taw/core, applies the framework files (classic themes), runs the migrations and the checks, commits, and opens a pull request (or what taw.json's deliver says). It asks nothing after the first question. See Update a theme.
- It refuses a theme that isn't a git repository, has uncommitted changes, or isn't on its default branch, before anything runs.
- A theme on taw/core older than 1.91.2 first gets the newest taw/core in
vendor/(itscomposer.lockgoes back), so its first update is one step too. - If a step fails, nothing is pushed: the theme's
.taw/update-report.mdsays what failed and how to finish it. In the dashboard,uoffers Fix with Claude on the same report. - Progress goes to stderr, the summary to stdout. It exits
1when the update stops or doesn't start.
| Flag | Does |
|---|---|
--all | Every client theme that needs an update, one after another, each ending in its own pull request. Themes with uncommitted changes or off their default branch are left out, with the reason. A theme that stops doesn't stop the others; it exits 1 if any stopped or couldn't run |
--theme <folder> | Which TAW theme, when the site has several |
-y, --yes | Don't ask |
inspect
taw-fleet inspect <site> [--json] [--theme <folder>]
Runs php bin/taw inspect --json against the site's database: its blocks, fields and forms. The site must be running, and the theme must have bin/taw.
| Flag | Does |
|---|---|
--json | Print bin/taw inspect's JSON |
--theme <folder> | Which TAW theme, when the site has several |
handoff
taw-fleet handoff <site> [--copy] [--launch] [--out <file>] [--theme <folder>]
taw-fleet handoff --all [--launch]
Prints the prompt that hands the theme's update to Claude Code: the update-theme skill, where everything is on this Mac, what taw-fleet found, and the rules (work on a chore/taw-core-<version> branch, Tier 2 changes need your OK, ask before pushing).
| Flag | Does |
|---|---|
--copy | Copy the prompt to the clipboard |
--launch | Open a terminal running Claude Code in the theme folder with the prompt |
--out <file> | Also write the prompt to this file |
--all | Every client TAW theme that needs an update. Without --launch, lists the themes it would take and the ones it leaves out. With --launch, one Claude Code session with a subagent per theme. To update every theme without an agent, use update --all |
--theme <folder> | Which TAW theme, when the site has several |
create
taw-fleet create [name] [flags]
Creates a Local site, installs taw-theme (classic) or taw-gutenberg (block) into it with taw-create, builds its assets, activates it and makes the theme a git repository with a first commit. The admin password is generated and shown once. Local must be open.
In a terminal, anything missing is asked in a form. Otherwise give the name, --classic or --block, --admin-user, --admin-email (or set them in the [create] settings) and --yes.
| Flag | Default | Does |
|---|---|---|
--classic | Start from taw-theme | |
--block | Start from taw-gutenberg | |
--admin-user <name> | [create] admin_user | WordPress admin username |
--admin-email <email> | [create] admin_email | WordPress admin email |
--domain <host> | <name>.local | The site's domain |
--theme-dir <folder> | From the name | The theme's folder in wp-content/themes |
--php <version> | Local's preferred | A PHP version Local has downloaded, such as 8.2 or 8.2.30 |
--web-server <name> | Local's preferred | nginx or apache, optionally with a version |
--json | Print the result as JSON, password included | |
-y, --yes | Don't ask |
taw-fleet create "Acme Shop" --classic --php 8.2 --admin-user marco --admin-email me@example.com --yes
Production
See Production, pull requests and deploys for how these work.
live
taw-fleet live [site] [--logs <n>] [--json]
Asks each production site's companion for its health: WordPress, PHP, taw/core and companion versions, plugin updates, known vulnerabilities and recent taw/core log lines. Sites come from production_url. It always asks the sites now, past the cache.
| Flag | Default | Does |
|---|---|---|
--logs <n> | 5 | Log lines to fetch per site |
--json | Print JSON |
| Subcommand | Flags | Does |
|---|---|---|
live key new | --key-id <id> (default taw-fleet), --force | Generate a new Ed25519 signing key in the Keychain. --force replaces a stored one |
live key import | --key-id <id> (default hub-local) | Store a signing key read from stdin: base64, a 64-byte libsodium secret key or a 32-byte seed |
live key show | Print the key id and public key, never the secret | |
live trust <site> | --key <base64>, --key-id <id>, -y/--yes | Pin the key the site signs its answers with. Without --key, the site is asked and you confirm the key it presents. --key needs --key-id |
pull
taw-fleet pull <site> [--theme <folder>] [--yes]
Fetches the production site's published content through its companion (0.4+), previews the import into the Local site, then imports it after you confirm. Starts the Local site when it's stopped. The dashboard's C.
| Flag | Does |
|---|---|
--theme <folder> | Which TAW theme, when the site has several |
-y, --yes | Don't ask, at either step |
publish
taw-fleet publish <site> [--theme <folder>] [--no-review] [--json] [--decisions <file>] [--yes]
taw-fleet publish undo <site> [--journal <file>] [--yes]
taw-fleet publish history <site> [--json]
Compares the Local site's content with production's (the base a pull or the last publish saved), asks production what publishing would change, and opens the review in your browser. Nothing is written until you press Publish there. Needs taw/core 1.98+ and companion 0.5+ on production, with "publish": true in the theme's composer.json. The dashboard's p. See Publish content to production.
| Flag | Does |
|---|---|
--theme <folder> | Which TAW theme, when the site has several |
--no-review | Print the review instead of opening it in the browser |
--json | Print the review, or the result, as JSON (with the record and change keys) |
--decisions <file> | A JSON file: the records to publish (include) and which side wins each value changed on both sides (sides: keep or take) |
-y, --yes | Publish without asking: as reviewed, or as --decisions says. Refuses while a value changed on both sides has no side |
publish undo says what undoing the last publish would do, then asks (the dashboard's x). --journal picks an older one. publish history lists the site's publishes, newest first, each with its kept review.
wp-remote
taw-fleet wp-remote <site> <GET|POST|PUT|PATCH> <rest-route> [--data <json>] [--file <path>] [--type <mime>]
Calls the production site's WordPress REST API as its bot user. The answer's JSON goes to stdout; a WordPress error exits non-zero with its code and message. There is no DELETE.
| Flag | Does |
|---|---|
--data <json> | JSON body: inline, @file, or - for stdin |
--file <path> | Upload this file as the body (media). Can't go with --data |
--type <mime> | The file's content type. Default: from its extension |
| Subcommand | Does |
|---|---|
wp-remote key import <site> | Store user:application password from stdin in the Keychain |
wp-remote key show <site> | Say which bot is stored and whether the site accepts it, never the password |
prs
taw-fleet prs [site] [--json]
For every TAW theme with a GitHub repository: its open pull requests with their CI, and its deploy workflow (the commit production has, a deploy running or failed, the commits not deployed yet). Needs a GitHub token.
| Flag | Does |
|---|---|
--json | Print JSON |
merge
taw-fleet merge <site> [--pr <number>] [--theme <folder>] [--yes]
Merges an open pull request with the repository's default merge method, deletes its branch, and pulls the default branch into the local theme when its tree is clean. Refused for a draft, a conflict, or CI that failed or still runs. Merging a client theme deploys its production site.
| Flag | Does |
|---|---|
--pr <number> | The pull request, when there are several |
--theme <folder> | Which TAW theme, when the site has several |
-y, --yes | Don't ask |
comments
taw-fleet comments [site] [--json]
The open comments in each site's BugSmash project, newest first: the count and the oldest's age, then the three newest per site (the five newest when you name one site). Sites come from bugsmash_project. It only reads. To resolve them, use the theme's resolve-comments skill (X in the dashboard).
| Flag | Does |
|---|---|
--json | Print JSON |
| Subcommand | Flags | Does |
|---|---|---|
comments projects | --json | Your BugSmash projects and their ids, for bugsmash_project |
comments link <site> <project id> | -y/--yes | Check the project with BugSmash, then set bugsmash_project for the site in the settings. Asks first |
comments key import | Store the BugSmash API key from stdin in the Keychain. In a terminal, it asks without echo | |
comments key show | Say where the key comes from and whether BugSmash accepts it, never the key |
watch
taw-fleet watch [--once] [--json] [--no-notify] [--every 5m]
Checks the fleet and tells you, once, with a macOS notification, what changed since the last check: a failed deploy, CI failing on the default branch, a production site down (two checks in a row) or back, a site that answered without its pinned key's signature, new BugSmash comments, an update's pull request ready to merge. Clicking a notification opens the dashboard on its site. The first check only notes what it sees. Alone, it checks every 5 minutes in this terminal. See Notifications.
| Flag | Does |
|---|---|
--once | Check once and stop (what the background agent runs) |
--json | Print {first, events, problems} (with --once) |
--no-notify | Print what changed, without notifications |
--every | How often to check (at least 1m) |
| Subcommand | Flags | Does |
|---|---|---|
watch install | --every | Check in the background (a launchd agent, com.relmaur.taw-fleet.watch), also after a restart |
watch uninstall | Stop checking in the background | |
watch status | --json | On or off, the last check, what it can't check, what it told lately |
watch test [site] | Send a notification now, to see it arrive and where a click goes |
Event kinds in --json and watch status --json: deploy.failed, ci.failed, production.down, production.up, production.unverified, comments.new, pr.ready, report.ready.
ready
taw-fleet ready [site] [--json]
The SETUP checklist from the dashboard's details, for one site or every client site: repository, secrets check, deploy, production, companion, bot, BugSmash, skills. Each step says what's there, or how to do it. See Set up a site.
repo
taw-fleet repo <site> [--owner <account>] [--name <repo>] [--theme <folder>] [--yes]
For a theme with no GitHub repository: creates a private one (default name <theme folder>--theme; default owner the first of github_owners, else your gh account), adds it as origin, pushes the default branch and the current one, and requires the dump check (ci / committed-files) on the default branch. Asks first. Needs gh signed in.
deploy
taw-fleet deploy setup <site> # the form: host, details, key, test, apply
taw-fleet deploy profiles [--json] # the hosts taw-fleet knows, and where each value is
taw-fleet deploy key <site> # the deploy key's public half (made the first time)
taw-fleet deploy test <site> [target flags] # connect as the deploy will; nothing changes
taw-fleet deploy apply <site> [target flags] [--yes]
Sets up taw/core's shared deploy (taw/core 1.97+) for a theme on GitHub with no deploy yet: by SSH + rsync into the theme's folder on the server, or by git push to the host's remote. apply tests the connection again, pinning the server's host key, then (after asking) stores the settings as repository variables and the key as the secret DEPLOY_SSH_KEY, opens a pull request adding .github/workflows/deploy.yml (merging it deploys), and adds production_url to the settings. The deploy key stays in the Keychain only until then.
| Target flag | Does |
|---|---|
--profile <id> | Pre-fills the method, port and git defaults (deploy profiles) |
--method rsync|git | How the theme reaches the host |
--host, --port, --user, --path | rsync: the SSH host, port (22), user, and the theme's folder (…/wp-content/themes/<theme>) |
--git-remote, --git-branch, --git-path | git: the remote, its branch (master), and the theme's place in it (wp-content/themes/<theme>) |
--url | The production site's URL |
launch-report
taw-fleet launch-report <site> [--theme <dir>] [--open] [--json] [--no-speed]
Checks a site in production as it is now, only reading it, and saves its launch report as ~/TAW Fleet/sites/<site>/launch.html (and launch.md). The checks: production answers over HTTPS, http:// moves to https:// for good, the certificate; search engines are let in (no noindex in the page or its headers, which is what WordPress's "Discourage search engines" leaves behind, and a robots.txt that doesn't shut everyone out); the last deploy; the companion (verified, the same taw/core as the theme, plugin updates, known vulnerabilities); PageSpeed, mobile and desktop (up to a minute; --no-speed skips it); taw-fleet watch; BugSmash; and the rest of the SETUP checklist. The report starts with what's left for you, each with how. PageSpeed's picture of production's first screen is saved in production/, beside the Local build's from build/ when there is one. --json adds report, the page's path.
| Flag | Does |
|---|---|
--open | Open the report in the browser |
--json | Print the report's data as JSON |
--no-speed | Skip PageSpeed |
restore
taw-fleet restore <site> [point] [--yes] [--save] [--json]
A site's restore points, newest first. Each holds the Local database (when the site was running) and the theme's branch and commit, saved before an update, a merge (branch only) or a content import, or by hand with --save. With a point (its id, or latest) it puts it back after asking: the theme onto the point's branch, commits made since staying, and the database from its copy. How things are just before is saved as a point first, so a restore can be undone. See Restore points.
| Flag | Does |
|---|---|
--save | Save a point now (--theme picks the theme on a site with several) |
--json | Print {site, keep, folder, points} |
--yes, -y | Don't ask |
Points live in ~/Library/Application Support/taw-fleet/restore/<site>/. taw-fleet refuses to save one when that folder is inside the site, a theme or any git repository, and the step that wanted it doesn't run.
report
taw-fleet report <site> | --all [--month 2026-09] [--language en|es] [--print] [--json] [--open] [--no-speed]
Makes a site's monthly report: availability (from watch), updates and changes, BugSmash comments, PageSpeed, and the live site's security and maintenance. It saves Markdown and HTML in ~/TAW Fleet/reports/<site>/<month>.{md,html} and prints a summary, including why a section couldn't be measured. Without --month, it's this month so far. See Monthly reports.
| Flag | Does |
|---|---|
--month | The month, such as 2026-09 |
--all | Every site with a production_url |
--language | en or es for this report (default: report_language) |
--print | Print the Markdown; save nothing |
--json | Print the report's data |
--open | Open the HTML in the browser |
--no-speed | Skip PageSpeed (it takes up to a minute) |
| Subcommand | Does |
|---|---|
report list [site] | The saved reports |
report key import | Store a PageSpeed Insights API key from stdin in the Keychain |
report key show | Say where the key comes from, never the key |
chat
taw-fleet chat [site] --prompt [--theme <dir>]
The chat itself is in the dashboard: > from the list for the whole fleet, > on a site's details for that site. See Chat with Claude. --prompt prints what taw-fleet adds to Claude's instructions, for the fleet or a site, so you can read it or give it to another agent.
init
taw-fleet init
Writes the fleet folder, ~/TAW Fleet/: a CLAUDE.md made from the settings, taw-fleet's MCP server in .mcp.json, and the fleet skills. It lists what it wrote, or says it's already up to date. The dashboard does the same when it opens. Your CLAUDE.local.md, your own skills and the reports are left alone.
Settings and taw-fleet
config
| Subcommand | Does |
|---|---|
config init | Write a commented starter settings file. Never overwrites |
config show | The settings in effect and the editors and terminals found |
config path | Print the settings file's path |
config icons [symbols|nerd] | With no value, show the icon set in effect. With one, set icons in the settings file, keeping the rest of it (the file is created from the starter if it's missing). Any other value is an error |
config open-at-login [on|off] | With no value, say whether the dashboard opens at login. on sets open_at_login = true and adds the login agent; off sets it to false and removes the agent. See Open at login |
Every key is on the taw-fleet page.
self-update
taw-fleet self-update [--check] [--yes]
Downloads the newest release for this Mac from GitHub, checks it against the release's checksums.txt and replaces this binary. A Homebrew install is refused: run brew upgrade taw-fleet.
| Flag | Does |
|---|---|
--check | Only say whether a newer release exists |
-y, --yes | Don't ask |
version
taw-fleet version
Prints taw-fleet <version> (<commit>).
completion
taw-fleet completion <bash|zsh|fish|powershell> [--no-descriptions]
Prints a shell completion script. taw-fleet completion <shell> --help shows how to load it. --no-descriptions leaves out the descriptions.
Doctor finding codes
Codes are stable and dot-namespaced, so scripts can filter doctor --json on them. Severities show as ✗ error, ▲ warning and • note (info in JSON).
| Code | Severity | Means |
|---|---|---|
scan.local | warning | Local's sites couldn't be read: Local isn't installed, or has no site |
scan.github | warning | The newest versions are unknown: GitHub didn't answer and nothing is cached, or --offline with no cache |
site.read-error | warning | Part of a site couldn't be read: its Local registry entry or status, its themes folder, or a theme's git or taw/core details |
tools.php-missing | warning | Local doesn't have the PHP build the site uses. Open the site in Local once |
theme.symlink-broken | error | The theme is a symlink to a folder that no longer exists |
core.missing | error | taw/core isn't installed (no vendor/). Run composer install |
core.unreadable | error | The installed taw/core can't be read |
core.behind | warning | taw/core is older than the newest release |
core.lock-mismatch | warning | vendor/ and composer.lock have different taw/core versions |
scaffold.drift | note | The last scaffold check found Tier 1 paths that differ from taw-theme |
scaffold.check-failed | warning | The last scaffold check failed |
scaffold.behind | note | An umbrella checkout of taw-theme or taw-gutenberg is behind its own latest release |
skills.missing | note | The theme's taw/core ships site skills its .claude/skills/ doesn't have. Classic: S; block: taw skills:sync --apply |
git.none | note | The theme isn't its own git repository |
git.dirty | note | Uncommitted changes |
git.detached | warning | HEAD isn't on a branch |
git.no-upstream | warning | The branch isn't pushed (no upstream). The fix names the delivery remote: taw.json's update.remote, else origin |
git.behind | warning | Commits to pull from the upstream |
git.ahead | note | Commits not pushed |
git.foreign-upstream | warning | The checked-out branch tracks another repository (owner/name, or the remote's name), neither origin nor the delivery remote. The versions and files shown are that branch's, not the site's. Fix: D in the dashboard, or git switch <default> |
git.off-default | note | Not on the default branch. Fix: D in the dashboard, when that's what you want. Not reported when git.foreign-upstream is |
git.no-hook | warning | taw/core's pre-commit check (no dumps, .env or keys committed) isn't on, on a theme with taw/core 1.94 or newer. Fix: u (the update turns it on), or git config core.hooksPath vendor/taw/core/resources/git-hooks |
git.hook-own | note | The clone has its own git hooks (its own core.hooksPath, or hooks in .git/hooks), so the update left them alone. Fix: add the TAW check to its pre-commit (taw upgrade --explain 1.94.0/pre-commit-hook) |
git.no-remote | warning | No delivery remote: origin, or the one taw.json's update.remote names |
pr.failing | warning | A pull request's CI failed |
pr.conflict | warning | A pull request conflicts with the default branch |
pr.ready | note | A pull request is ready to merge (M) |
deploy.failed | warning | The last deploy failed |
deploy.blocked | warning | CI failed on the default branch, so it isn't deployed |
deploy.pending | note | Commits on the default branch aren't deployed, and nothing is running |
live.signature | error | A production answer's signature doesn't match the pinned key. If the site's key was rotated on purpose, pin the new one with live trust |
live.refused | warning | The site refused taw-fleet's signature: it doesn't have taw-fleet's public key |
live.unreachable | warning | The production site or its companion didn't answer |
live.untrusted | note | The site answers, but no key is pinned for it, so answers aren't verified |
live.companion-outdated | note | Production runs a companion without the inventory and vulnerability routes |
live.core-mismatch | note | Production runs a different taw/core than this Mac's theme |
live.vulnerable | warning, or error when the worst is high or critical | Known vulnerabilities on production, per the site's scanner |
live.plugin-updates | note | Plugin updates are waiting on production |
comments.no-key | note | The site has bugsmash_project, but no BugSmash API key is stored |
comments.unreachable | warning | The BugSmash project is gone, the key was refused, or BugSmash didn't answer |
comments.open | note, or warning once the oldest has waited more than two days | Open BugSmash comments |
Keychain items
taw-fleet keeps its secrets in your login Keychain, under the service taw-fleet. They're never written to a file or shown again.
| Account | Holds | Set with |
|---|---|---|
companion-signing-key | taw-fleet's Ed25519 signing key and its key id | live key new or live key import |
bugsmash-api-key | The BugSmash API key | comments key import |
wp-<folder> | One site's WordPress bot user and Application Password | wp-remote key import <site> |
Each Mac needs its own copy.
Environment variables
| Variable | Effect |
|---|---|
GITHUB_TOKEN, GH_TOKEN | GitHub token for newest versions, pull requests, deploys and merging. Without either, taw-fleet uses gh auth token when the gh CLI is signed in. The token is only sent to GitHub |
BUGSMASH_API_KEY | The BugSmash API key, used when the Keychain has none |
XDG_CONFIG_HOME | The settings folder becomes $XDG_CONFIG_HOME/taw-fleet |
TAW_FLEET_HOME | Use another home folder, for example a copy of Local's sites.json for testing |
TAW_FLEET_THEME | light or dark: the color palette. Default: from COLORFGBG, else dark; the dashboard also asks the terminal |
NO_COLOR | No colors |
Files
| Path | Holds |
|---|---|
~/.config/taw-fleet/config.toml | The settings (see Settings) |
~/.config/taw-fleet/companion-keys.json | The production sites' pinned public keys, by site folder |
~/Library/Caches/taw-fleet/github/ | The newest release tags, cached for an hour |
~/Library/Caches/taw-fleet/live/ | Production checks, cached for 5 minutes |
~/Library/Caches/taw-fleet/bugsmash/ | BugSmash comments, cached for 5 minutes |
~/Library/Caches/taw-fleet/sync/ | Each theme's last scaffold check (the SYNC column) |
~/Library/Caches/taw-fleet/content/ | Content snapshots fetched by pull |
~/Library/Application Support/taw-fleet/content/<site>/ | The site's base for publishing: base.json, production's content as Local last had it, and base.meta.json |
~/TAW Fleet/sites/<site>/publish/<time>/ | Each publish's review: review.html, plan.json (without the token), decisions.json, report.json |
~/Library/Caches/taw-fleet/handoff/ | Prompts and launchers for Claude Code windows; fleet-<time>/ for an update of every theme |
~/Library/Caches/taw-fleet/window/, work/ | Launchers for the dashboard's own window and for Vite windows |
~/TAW Fleet/reports/<site>/ | Monthly reports, <month>.md and <month>.html |
~/TAW Fleet/sites/<site>/notes.md | The site's notes, newest first (see Site notes) |
~/Library/LaunchAgents/com.relmaur.taw-fleet.login.plist | The login agent, while open_at_login is on |
~/Library/Application Support/taw-fleet/restore/ | Restore points: per site, the database copy (database.sql.gz, 0600) and point.json. Never inside a site or a repository |
~/Library/Application Support/taw-fleet/watch/ | watch's state (what it told, each production site's uptime per day) and the background agent's log |
~/Library/LaunchAgents/com.relmaur.taw-fleet.watch.plist | The background agent, while watch install is on |
With XDG_CONFIG_HOME set, the two config files live in $XDG_CONFIG_HOME/taw-fleet/. With TAW_FLEET_HOME, every path is under that folder instead of your home.