← Back to Mast · Docs · Overview Updated Aug 10, 2026 · v1.3.0
Documentation

Using Mast

Mast 1.3.0 sits in your menu bar and shows every git repo on your machine — branches, upstream, dirty state, open PRs, live dev-server ports — plus the full git loop, a one-click handoff to Claude Code / Codex / Cursor, and exact local AI token history. This doc covers project visibility, GitHub credential health, privacy, and the companion CLI.

Who this is for. Developers who already live in their terminal with lsof, git, and docker. Mast doesn't replace those tools — it correlates them into one row per repo.

Install

Recommended: Homebrew.

brew install --cask leonhoulier/mast/mast

Installs the signed, notarized Mast.app from the public usemast.sh release mirror.

Alternatively, download the signed Mast-1.3.0.dmg, open it, and drag Mast to Applications.

The mast companion CLI is not yet bundled into the DMG. For now, build it from the source repo: npm run build:cli && npm link.

Requirements

  • macOS 12 Monterey or later
  • Apple Silicon or Intel (universal binary)
  • ~213 MB disk, ~135 MB RAM idle

First scan

On launch, Mast performs its first scan. You'll see Waiting for first scan… for one to three seconds, then rows appear.

Scans run on a per-scanner cadence between 5 s and 30 s while the popover is open. Intervals are 5× longer when it's hidden, and scanning pauses entirely on sleep or lid-close — resumes on wake. Press ⌘R to force an immediate rescan.

The popover

The popover is 380×600. Top to bottom: header (status dot, app name, gear + info icons), search bar, Local header with repo count and refresh button, scrollable list of repos. One row per repo. No tabs.

Each row shows:

  • Status dot (gray / green / yellow / red, see FAQ)
  • Repo name with open-PR count badge when available
  • Branch → upstream, time since last commit
  • Dirty count (if any)
  • Sparkles icon → open in your AI agent
  • Primary action pill — Open :<port> when a dev server is listening, Start otherwise
  • Chevron to expand the row

Tabs were removed in v0.8. The old Ports / Repos / System tabs are gone — the Repos view is the whole popover. Ports still scan in the background and surface as Open :<port> pills on the row that owns them. System scanners (Docker, Homebrew, launchctl) still run but don't render UI in v1.3.0.

Row actions

Click a row's chevron to expand it. The expanded panel is grouped into three labeled sections: Git, Open, Info. Which verbs appear depends on repo state — a clean repo on its upstream shows fewer buttons than a dirty one with unpushed commits.

VerbSectionWhat it does
Open :<port>header pillOpens http://localhost:<port> in your default browser. Appears when a listening port correlates to this repo's cwd.
Startheader pillRuns npm / bun / pnpm / yarn run dev (fallback start) in a new Terminal at the repo. Flips to Open :<port> once the server binds.
Sparklesheader iconOpens the repo in your configured AI agent. See Open in AI agent.
StashGitgit stash push -u with a Mast-prefixed label. Recover with git stash pop.
CommitGitOpens an inline message editor (Enter submits, Escape cancels). Runs git commit -am "<msg>".
Push ↑NGitArm-fire. First click shows Confirm? Push ↑N, second click within 3s runs git push.
Pull ↓NGitAppears when behind. Arm-fire if the working tree is dirty (would otherwise fail).
FetchGitRead-only sync. No confirm.
UndoGitArm-fire. git reset --soft HEAD~1 — rewrites local history, keeps the diff staged. Only appears when ahead of upstream.
AmendGitArm-fire. git commit --amend --no-edit. Only appears when there are staged changes with no unstaged.
DiscardGit (danger)Arm-fire. git reset --hard HEAD && git clean -fd. On failure, git's stderr shows inline.
Create PRGitOpens github.com/<owner>/<repo>/compare/<base>...<branch>?expand=1 — PR form pre-opened. Appears when ahead of upstream + the remote is on GitHub.
Open in <Agent>OpenFull "Open in Claude Code / Codex / Cursor" pill. See Open in AI agent.
IDEOpenOpen the repo in your configured editor (VS Code, Cursor, Sublime, Zed, vim, etc. — whitelist-enforced).
FinderOpenReveal the repo folder in Finder.
GitHubOpenOpen the repo on github.com (when a GitHub remote is set).
Recent commitsInfoCollapsible preview of the last 5 commits via git log --pretty=format:%h%x09%s. Lazy-loaded on expand, cached 30s. Hash links to GitHub when available.

Full git loop

The complete git loop remains part of the current v1.3.0 release. You can drive a repo from dirty → committed → pushed → PR without ever opening a terminal. The arm-fire pattern protects all four destructive / history-rewriting actions (Push, Discard, Undo, Amend): first click arms, second click within 3 s fires, otherwise it disarms itself. Shared with the useArmFire hook, consistent behavior across every button.

Git operations run their real commands — no wrappers, no intermediate tooling. git push uses your normal credentials. git commit uses your .gitconfig identity. Failure surfaces git's own stderr inline.

Open in AI agent

New in v1.0: every repo row has a sparkles icon (compact) and an Open in <Agent> pill (expanded) that hands the repo to your configured AI coding agent. Three agents supported:

AgentKindHow it launches
Claude CodeTerminalRuns claude in a new Terminal window at the repo's cwd.
CodexTerminalRuns codex in a new Terminal window at the repo's cwd.
CursorGUILaunches Cursor.app with the repo folder open.

Pick the default in Settings → Default AI Agent, or during the third step of first-launch onboarding. The agent's binary must be on your PATH; if it isn't, Mast returns a clear error with a link to the agent's install docs — no silent spawn failures.

Security. The agent list is a Zod enum ('none' | 'claude-code' | 'codex' | 'cursor') with a matching binary allowlist in the main process as defense-in-depth. The renderer can't pivot "Open in AI agent" into arbitrary command execution. Adding a new agent takes one enum entry + one registry row + one allowlist line.

AI usage (Mast 1.3.0)

Mast reads exact local token ledgers from Claude Code and Codex. If we say token spend, we mean exact token volume only — never a dollar cost, pricing estimate, cache savings, or API-equivalent spend. Cursor remains available for AI-agent handoff, but its token usage is unsupported because Mast has no stable local Cursor ledger.

  • Ranges: switch between 7 days, 30 days, and This year. Daily increments feed both stacked provider bars and a cumulative curve.
  • History: the GitHub-style activity heatmap reaches back as far as the local ledgers permit; missing days stay empty rather than becoming invented events.
  • Providers: each provider is labelled Exact, Updating, Unavailable, or Unsupported. Exact appears only after a complete ledger scan; Updating means an initial or continued scan is still incomplete or resuming, so cached totals are shown with that limitation.
  • Project attribution: usage is matched to repositories already discovered by Mast's Git scanner. Unmatched working directories are shown only as a numeric Unattributed bucket.
  • Agent history: active and archived Codex sessions are read together, with stable session identifiers used to deduplicate overlapping copies. Append-only Claude Code and Codex ledgers resume from verified checkpoints.

Mast persists a schema-versioned llm-usage-cache.json beside its settings in the app's Electron userData directory, so unchanged ledger files do not need to be parsed from the beginning on every scan. The cache stores numeric summaries and daily buckets, bounded identifiers and cwd attribution, file metadata, and parser checkpoints only. Prompts, responses, and tool content are never stored or surfaced.

The persisted cache is bounded at 16 MiB and 12,000 entries. On POSIX systems, Mast creates the cache directory with owner-only 0700 permissions and the cache file with owner-only 0600 permissions.

Entries are pruned only when an authoritative, complete discovery proves that a source or root has vanished or changed; unavailable or truncated scans retain the cached entries and keep the provider in Updating. To clear the local history, quit Mast, delete ~/Library/Application Support/Mast/llm-usage-cache.json, and launch Mast again; the cache rebuilds from the local ledgers.

Privacy boundary. Prompts and responses are never surfaced. Only timestamps, stable IDs, numeric counts, and Git-discovered project attribution cross the renderer boundary. This section's marketing chart uses representative example values; it is not a user's usage claim.

Repo visibility (Mast 1.3.0)

Mast keeps the active list readable without hiding data from search. Active projects are capped with See more / Show less. Repositories with a last commit older than three months move automatically under Older projects. Hidden by you is a separate manual group, and Keep shown overrides automatic aging for a repo that should stay visible.

Search runs across every discovered match, including collapsed groups and manually hidden projects. The visibility state changes presentation only; it does not delete or stop scanning a repository.

Keyboard shortcuts

ActionKeys
Open popover (default global hotkey)CommandOrControl+Shift+Ctrl+D ⌘ ⇧ ⌃ D
Focus search⌘ F
Navigate rows↑ ↓
Open row in IDE⌘ ↵
Refresh now⌘ R
Dismiss popoveresc

GitHub integration

Connecting Mast to GitHub unlocks three things: open-PR counts per repo, CI status (pass / fail / pending), and the Create PR button in the expanded row. It's optional — without a token, those slots just stay empty.

Create a personal access token

Mast works with either GitHub token type. Pick based on how much scope you want to grant:

Token typeRecommended scopesWhere
Fine-grained (recommended) Repository access: All repositories or select. Permissions: Pull requests: Read, Contents: Read, Metadata: Read (auto-included). github.com/settings/personal-access-tokens/new
Classic repo (single scope covers private + public read access). No other scopes needed. github.com/settings/tokens/new

Add the token to Mast

Two ways:

  • GUI: Settings → GitHub → paste the token. Mast saves it, immediately checks GET /user, and reports the result in the connection-health label.
  • CLI: mast setup github writes the token to the same settings file. Mast checks it on the next GitHub scan.

The connection health label is explicit: Connected when the check succeeds, Rejected when GitHub refuses the credential, and Rate limited when the API asks Mast to wait. Replacing a token triggers an immediate recheck, so a stale status does not linger.

How the token is stored. The token is encrypted on disk via Apple's safeStorage API (Keychain-backed). The renderer process never sees the raw string — IPC redacts the settings payload to githubTokenPresent: boolean before it crosses the bridge.

What Mast queries

For each auto-discovered repo with a GitHub remote, Mast periodically runs:

  • GET /repos/<owner>/<repo>/pulls?state=open — open PR list
  • GET /repos/<owner>/<repo>/commits/<sha>/check-runs — CI status for HEAD

The GitHub scanner runs every 60 seconds. If GitHub returns 403 / 429, Mast surfaces the Rate limited state in Settings and retries on its normal scan cadence.

Revoking access

Either delete the token on GitHub (it stops working immediately but the stale record stays in Mast) OR clear it from Settings → GitHub → Remove token. Both are safe.

Companion CLI

The mast CLI renders the Repos list as ANSI and drives git actions from the terminal — same state store, same per-repo mutex as the GUI, no duplicated code.

Install

Not yet bundled in the DMG. Build from the private source repo:

git clone https://github.com/leonhoulier/mast.git
cd mast
npm install
npm run build:cli    # → dist/cli/mast.js
npm link             # puts `mast` on PATH

Default output

$ mast
LOCAL                                          9 repos
  ● devdash              feat/v1.3.0          1 dirty   :8765
  ● GA boss              main → origin/main · 2w  15 dirty
  ● leonhoulier-site     feat/LEO-8-india-tra  1 dirty   :3000
  ● watchatlas           main → origin/main · 1w  13 dirty
  ● Leonhoulier paperclip  main · 2w ago       clean

Verbs

CommandWhat it does
mastRepos list (default, matches the GUI).
mast overviewFull firehose: ports + processes + repos + services.
mast portsPort → process → repo chains.
mast processesProcesses grouped by project with memory.
mast servicesDocker, Homebrew, Launch Agents.
mast githubGitHub PRs and CI per repo.
mast watchLive-refresh every 10 s in place.
mast --jsonMachine-readable snapshot (pipe to jq).
mast stash <repo>git stash push -u
mast discard <repo> [--force]git reset --hard + git clean -fd — --force skips the confirm prompt.
mast commit <repo> "message"Stages + commits. Stages all changes (git add -A) if nothing is staged.
mast push <repo>git push
mast log <repo> [-n N]Recent commits (default 10).
mast refreshForce an immediate git scan.
mast setupInteractive wizard (dev roots, editor, AI agent, GitHub token).
mast setup githubSet GitHub PAT only.
mast setup editor <name>Set default editor (whitelist).
mast configShow current settings (JSON).
mast config set K VSet a single config value.

Repo arguments accept an absolute path, a path relative to CWD, or a bare basename (e.g. mast stash devdash). Ambiguous bare names exit 2 with a list of matches.

MAST_SETTINGS=/custom/dir overrides the settings directory — the CLI and the app read the same JSON file, so GUI changes are visible in the CLI and vice versa.

Changelog

Condensed per-release history. Full notes: the Mast changelog.

v1.3.0 — AI usage + clearer project surfaces Released · 2026-08-10

  • Exact local Claude Code + Codex token history with 7-day, 30-day, and This year views.
  • Daily stacked provider bars, cumulative curve, provider breakdown, Git-project attribution, and a history heatmap reaching back as far as local ledgers permit.
  • Persistent incremental ledger cache in Mast's user-data directory; unchanged files are reused and append-only Claude Code and Codex ledgers resume from checkpoints without storing prompt, response, or tool content.
  • Provider cards say Updating while an initial or continued scan is incomplete or resuming, and Exact only after a complete scan.
  • Archived Codex sessions are included and stable-deduped; prompts and responses never enter the renderer.
  • Active repos are capped with See more / Show less, older repos move under Older projects after three months, and manual Hidden by you supports Keep shown overrides while search still finds every match.
  • GitHub status labels are Connected / Rejected / Rate limited, with an immediate recheck after token replacement and no raw token in the renderer.
  • Optional anonymous telemetry is off by default; the signed download is the v1.3.0 universal DMG.

Earlier release — Full git loop + arm-fire everywhere 2026-04-23

  • New git actions inline: Pull, Fetch, Undo commit (soft-reset), Amend, Create PR (opens GitHub compare).
  • Arm-fire on Push: first-click confirm, second-click fires within 3 s. Matches Discard.
  • Discard migrated to the new shared useArmFire hook (no more inline setTimeout juggling).
  • Expanded row now groups actions into labeled sections: Git, Open, Info.
  • First-launch onboarding gains an AI-agent step (Claude Code / Codex / Cursor / None).

v1.0 — Open in AI Agent 2026-04-22

  • New Open in <Agent> button on every repo row. Three agents: Claude Code (Terminal), Codex (Terminal), Cursor (GUI). PATH preflight with install-doc fallback on missing binary.
  • Settings → Default AI Agent (Zod enum + binary allowlist as defense-in-depth).
  • Settings schema v5 → v6 migration: adds defaultAgent: 'none' to existing installs.

v0.9 — Installable CLI with git actions 2026-04-22

  • mast is now a standalone binary: npm run build:cli bundles to dist/cli/mast.js, npm link puts it on PATH.
  • New CLI git verbs: mast stash / discard / commit / push / log / refresh. All go through the same per-repo mutex as the GUI.
  • mast (no args) now prints the Repos list instead of the firehose — matches the GUI. Use mast overview for the old behavior.
  • Removed mast vps and mast setup vps * (ssh-vps scanner was unwired in v0.8).

v0.8 — Repos-only layout + Commit / Push inline 2026-04-22

  • Tab bar hidden. Popover is now a single scrollable Repos list. Ports still scan in the background and surface as Open :<port> pills; System scanners still run but don't render UI.
  • New Commit action with inline message editor, Push ↑N action on ahead repos.
  • Ahead/behind badge on repos with a GitHub remote is now clickable — opens the GitHub compare page.
  • Recent commits preview collapsible under each row (last 5 via git log, cached 30 s).
  • SSH VPS scanner unwired from the scheduler; no remote SSH processes spawn.

v0.6 — Start / Open pill, power-aware scanning 2026-04-22

  • Local repo rows get the Open :<port> / Start primary action pill.
  • Scanners pause on powerMonitor suspend / lid-close, resume on wake.
  • Minimum macOS 12 (Monterey). Drops Catalina + Big Sur.
  • LSUIElement=true — no dock icon flash, no cmd-tab entry.

Privacy & data

Mast's product scans run locally and the app does not require an account. Optional anonymous telemetry is off by default and only starts after an explicit opt-in in Settings.

  • Ports + processes come from lsof, ps, launchctl.
  • Git data comes from shelling out to git in each repo.
  • GitHub PR + CI data, if enabled, uses a personal access token encrypted on disk via Apple's safeStorage. The renderer never reads the raw token — IPC redacts it to githubTokenPresent: boolean. See GitHub integration for how to create and revoke tokens.
  • AI agents and usage history launch via execFile or read local ledgers with an enforced provider/parser boundary. Prompts, responses, and tool content are never surfaced or persisted in the ledger cache; only timestamps, stable IDs, numeric counts, cwd attribution, file metadata, and parser checkpoints are used.
  • Telemetry, when explicitly enabled, is anonymous usage/crash reporting. It does not include prompts, responses, raw repository paths, or GitHub tokens. Turning it off clears queued events.
  • Marketing site (usemast.sh) uses Google Analytics 4 with Consent Mode v2 — only if you accept the banner. Read the full usemast.sh privacy policy.

FAQ

Why not just use Activity Monitor?

Activity Monitor sees processes. It doesn't see ports, repos, PRs, or the AI agent you'd want to hand the repo off to. It can't tell you that the server on :4100 has drifted from the branch you thought you were on, or that you've got 3 unpushed commits while you're still refactoring.

Does Mast require root?

No. Everything Mast reads is readable by your user.

Will it drain my battery?

Scans are cheap and infrequent. When the popover is hidden, intervals stretch 5×. Power-aware pause suspends all scanners on sleep / lid-close and resumes them on wake, so there's no timer backlog firing at once.

How do I configure which directories get scanned for repos?

Settings → Repos → Scan roots. Default roots are ~/Developer, ~/Projects, ~/Code, ~/src, ~/repos, ~/work, ~/dev. Accepts globs.

What AI agents can I use with "Open in <Agent>"?

v1.3.0 ships with Claude Code, Codex, and Cursor for agent handoff. Adding a new one is intentionally cheap (one enum entry + one binary on the allowlist) — if you want a different agent supported, open an issue with the CLI name and install doc URL. Cursor token usage is not counted because it has no stable local ledger.

Can Mast commit and push for me?

Yes. Expand a dirty repo → Commit (inline message editor) → Push ↑N. Both use your normal git credentials. Push is arm-fire (click twice within 3 s to fire). If you're ahead of a GitHub remote, Create PR appears and opens the compare page with the form pre-opened.

Can I run Mast on Linux?

Not yet. The menu bar app is macOS-only. The CLI is node-based and should run anywhere node does, but it hasn't been tested outside macOS.

Troubleshooting

Popover is stuck on "Waiting for first scan…"

Quit Mast, relaunch. If it persists, check ~/Library/Logs/Mast/main.log — the most common cause is a missing lsof binary in your PATH.

"Open in <Agent>" shows "<agent> not found"

The agent's CLI binary isn't on Mast's PATH. Two common fixes:

  • Install the agent. The error popover links to the agent's install docs. For Claude Code: curl -fsSL https://claude.ai/install.sh | sh. For Codex: npm install -g @openai/codex. For Cursor: install Cursor.app first.
  • Confirm PATH. Open Terminal and run which claude / which codex. If it works there but Mast still complains, the binary is in a shell-rc-only PATH (~/.zshrc, ~/.bashrc) that isn't exposed to GUI-launched apps. Symlink it into /usr/local/bin or /opt/homebrew/bin.

GitHub PR counts aren't showing up

Three checks:

  • Settings → GitHub confirms a token is set (shows ● next to "Connected").
  • The repo has a GitHub remote (git remote -v shows github.com).
  • You haven't hit the GitHub rate limit — Mast surfaces Rate limited in Settings if you have. Wait and retry after GitHub's limit resets.

Commit / Push / Pull failed with "git: command not found"

Mast shells out to git. It inherits PATH from the user's launch environment. If git --version fails in a fresh Terminal, install git (Xcode Command Line Tools: xcode-select --install) and relaunch Mast.

Push failed with "Permission denied (publickey)"

Mast doesn't manage credentials — it uses yours. The most common fix is SSH-agent not having your key loaded. Run ssh-add --apple-use-keychain ~/.ssh/id_ed25519 (or your key path) and retry.

Still stuck? Open an issue at github.com/leonhoulier/mast/issues with the contents of ~/Library/Logs/Mast/main.log.