CLI reference
commitmind is the single binary you install with the quickstart. The installer
also creates a shorter mind alias that points at the same binary, and the
examples below use it — mind <command> and commitmind <command> are
interchangeable. All commands accept --help for a concise inline summary; this
page is the prose version.
Exit codes follow the Unix convention: 0 on success, non-zero on failure.
Specific non-zero codes are noted per-command where they matter.
mind login
Pair this machine with your CommitMind account via OAuth 2.0 device flow.
mind login [--client-name NAME] [--backend-url URL]Flags
--client-name— display name for this device. Defaults touser@host.--backend-url— override the API base URL. Useful for self-hosted or staging. Defaults tohttps://api.commitmind.dev.
Example
mind login --client-name "work-laptop"Prints a short user code, opens the verification URL in your browser,
and polls until you approve. The token is stored under ~/.commitmind/auth.json
(mode 0600).
mind onboard
Run the unified onboarding wizard — install.sh execs this after
placing the binary on disk so a fresh machine flows from
curl … | bash to "ready to use" in one continuous Bubble Tea
flow.
mind onboardSteps the wizard walks you through
- Welcome — platform / arch / binary-path summary + step preview with ✓ markers next to anything already done on this machine.
- PATH — appends the binary's directory to your shell rc files (zsh / bash / fish) when missing. Idempotent + opt-in per shell. Skipped silently when the rc file already references the dir.
- Background indexer — installs the user-level launchd plist (macOS) or systemd user unit (Linux). No sudo. Skipped silently when the unit is already on disk.
- Menubar tray (macOS only) — generates the
.appwrapper + LaunchAgent so the menubar icon appears immediately. Auto-skipped on every other platform. - Sign in — OAuth 2.0 device flow (same as
mind login). Skipped silently when a PAT already lives in your token store. - Init wizard — chains into the same flow
mind initruns (project picker, editors, coaching, backfill, summary, live execute, done banner).
Every step is idempotent and gated on actual need — re-running
mind onboard after a partial flow detects done steps and
skips through them.
Non-TTY behaviour
When stdin / stdout aren't TTYs (CI, automated pipelines, headless
shells), mind onboard skips the Welcome / PATH / daemon /
tray / login screens and chains directly into mind init's
inline-prompt path. To complete setup in headless environments,
the canonical path is still:
mind login # device-code OAuth
mind init # connect this repomind init
Connect the current git repo to a CommitMind project. By default
renders a Bubble Tea wizard (Welcome → Project → Editors → Coaching
→ Backfill → Summary → live execute) when stdin AND stdout are TTYs.
Auto-disables and falls back to inline prompts when --no-tui,
CI=non-empty, NO_COLOR=non-empty, or --mcp-config-only is set.
mind init [--org SLUG] [--project ID_OR_SLUG]
[--token-name NAME] [--no-hook] [--force]
[--no-tui] [--no-mcp-config | --mcp-config-only=KEYS]
[--no-skills] [--no-coaching-hooks]
[--coaching-hooks=project|user|skip]
[--no-claude-md] [--no-copilot-instructions]
[--no-vscode-settings] [--no-gitignore]
[--no-sync-attach] [--no-backfill]
[--backend-url URL]What it does
- Picks an org and project (auto-detect by canonical git remote URL first; falls back to the picker when nothing matches or the user chooses "different").
- Mints a project-scoped agent token and stores it under
~/.commitmind/projects/. - Installs
.git/hooks/post-commit(memory capture) and.git/hooks/pre-commit(review gate, threshold=high). - Wires the
commitmindMCP server into selected editors' configs — Claude Code, Claude Desktop, Cursor, VS Code (Copilot Chat). - Installs agent-coaching hooks (project- or user-scope), routing
skills,
.claude/settings.jsondeny block,.vscode/settings.jsonterminal-tab keys,CLAUDE.mdrouting block, and.github/copilot-instructions.md. - Manages
.gitignoreso per-developer MCP configs aren't committed. - Attaches the repo to the local sync daemon's
projects.json. - Runs the auto-backfill (skip / incremental / full based on the API's view of the project) with a live progress bar.
- Auto-commits init's tracked-intent outputs as
chore(commitmind): init. - Waits up to 30s for the local symbol index to populate.
Flags
--org— org slug to connect (skips the picker if set).--project— project id orgithub_repoto connect.--token-name— display name for the new agent token. Defaults to the machine hostname.--no-hook— skip installing the git hooks.--force— overwrite an existing post-commit / pre-commit hook instead of bailing.--no-tui— use plain inline prompts instead of the wizard. Auto-on when stdin/stdout aren't TTYs, whenCIorNO_COLORis set, or when--mcp-config-onlyis passed.--no-mcp-config— skip wiring editor MCP configs entirely.--mcp-config-only=KEYS— non-interactive surgical mode: wire only the named editors (e.g.claude-code,cursor) and skip every other init step. Used by editor extensions + worktree scripts.--no-skills— skip the agent routing skills.--no-coaching-hooks/--coaching-hooks=SCOPE— skip / pre-pick the coaching-hooks scope (project/user/skip).--no-claude-md/--no-copilot-instructions/--no-vscode-settings/--no-gitignore— skip individual DX-polish steps.--no-sync-attach— skip registering the repo with the local sync daemon.--no-backfill— skip the auto-backfill + symbol-sync wait.--backend-url— override the API base URL.
Example
mind init --org acme --project acme/monolithmind status
Show the active backend, your user identity, and (if run inside a linked repo) the connected project.
mind status [--json] [--repo-dir PATH]Flags
--json— print as JSON instead of human-readable text. Useful for scripts.--repo-dir— path to the repo. Defaults to the current working directory.
Exit codes
0— user is logged in and (if inside a repo) the repo is linked.1— either not logged in, or inside an unlinked repo.
mind learn
Read this repo's own history and propose its rules, architecture and past decisions — each one citing the commits it came from. Nothing is applied.
mind learn
mind learn --window 100
mind learn --dry-run # show what it would record, write nothing
mind learn --yes # record every proposal without askingRuns entirely on your own coding agent (claude or codex). Nothing is metered, and nothing leaves your machine except what that agent already sends. The pass is tool-free: it reads the commit text you give it and cannot open other files — commit messages are written by anyone who ever contributed to the repo, so they are treated as untrusted input rather than as instructions.
Every proposal must cite a real commit from the window that was read. A candidate that cites nothing, or cites a commit that is not in that window, is dropped rather than shown with a weaker label — a proposal a reviewer cannot check is worse than no proposal.
Each run leads with what it actually looked at, before any result:
reading history on local:claude…
de-duplicating against 262 recorded decision(s)
analyzed 40 of 4057 commits
16 proposal(s): 7 rule, 4 architecture, 5 decision
The analyzed N of M line is the point: history is unbounded, so a run reads a
window and says so. 0 duplicates skipped would be meaningless without the corpus
size beside it.
What it proposes
- rules — conventions the project enforces. Compiled to a checkable pattern and dry-run against your real code where possible; where that is not possible the rule is recorded as prose with the reason, never dropped.
- architecture — structural boundaries, checked against the real import graph and reported with the violations that already exist, so you can see what accepting one would cost.
- decisions — choices made between alternatives, de-duplicated against what the project has already recorded.
Reviewing what it found
Proposals are ordered by how much judgement you have to supply yourself: a boundary that comes with a violation count first, then a rule whose pattern was dry-run against your real code, then a decision that names the alternative it rejected. Everything after that needs you to do the work, so it sorts last.
The top proposals are shown and the rest are counted, not hidden — a list
that simply stops reads as the complete answer. Raise --shortlist to see them.
Each one is shown with its commits at the decision point, and you answer y
(record), n (skip) or q (stop asking). Quitting keeps what you already
accepted; it just stops the questions.
With no terminal — in CI, or behind a pipe — the command prints the shortlist and
records nothing rather than waiting on an answer that will never come. Pass
--yes to record without being asked.
Flags
--window— how many commits to read, newest first. Default 500.--rule-budget— max rule patterns to compile. Default 12. Candidates past it are still proposed, as prose.--decision-cap— max decisions to surface in one run. Default 8.--shortlist— how many proposals to surface. Default 12. The remainder is counted, not dropped.--yes— record every proposal without asking. Everything still lands pending review; this skips the questions, not the review.--dry-run— show what would be recorded and write nothing.--timeout— total budget for the run. Default 10m; each agent call gets a third.
Nothing it records becomes active on its own. Rules land advisory and pending,
architecture as a capability-doc proposal, decisions as proposed — and each is
stamped as machine-inferred so auto-mode's background approvers skip it. A rule
derived from commit messages always waits for a person.
Requires a local coding agent. With neither claude nor codex on PATH the command stops and says so — there is no degraded mode, because without a model there is no extraction at all and a partial run would overclaim.
On a repo with no CommitMind project, it still works: rules come back as prose rather than compiled patterns, because the structural dry-run needs the local symbol index that a connected project builds. Each prose rule carries the reason it stayed prose — an unauthorable pattern kind, a pattern too broad to be a convention, or the compile budget already spent — rather than appearing as a weaker result with no explanation.
mind coverage
Show test coverage, parsed from a report your project already produces. Never runs your tests.
mind coverageCoverage is a runtime measurement — which statements actually executed during a test run — so it can only come from a report your test tooling wrote. Recognised formats, which between them cover every language CommitMind supports:
| Format | Typical producer | Looked for at |
|---|---|---|
| Go coverprofile | go test -coverprofile | coverage.out |
| LCOV | vitest, jest, nyc, llvm-cov | lcov.info, coverage/lcov.info |
| Cobertura XML | coverage.py, coverlet, phpunit, tarpaulin | coverage.xml, cobertura.xml, coverage/cobertura-coverage.xml |
| JaCoCo XML | JaCoCo (Maven / Gradle) | target/site/jacoco/jacoco.xml, build/reports/jacoco/test/jacocoTestReport.xml, jacoco.xml |
| Clover XML | PHPUnit | clover.xml, build/logs/clover.xml |
| Istanbul JSON | nyc / vitest json reporter | coverage/coverage-final.json |
When several reports exist — a polyglot repo usually has more than one — every one is listed with its own unit, and they are not combined. Go counts statements and LCOV counts lines; a blended percentage would have no unit.
When no report exists, the output says so explicitly and names the command that would produce one for your stack, inferred from the repo's language mix:
Not measured. No coverage report found in this repo.
This is NOT 0% coverage — nobody has produced a report to read.
This looks like a Go project (74% of source bytes). To produce one:
go test ./... -coverprofile=coverage.out
"No report" is never reported as 0%: an unmeasured project and an untested one are different claims.
Exit codes
0— always. This command reports; it does not gate. A missing report is an answer, not a failure.
mind flush
Drain the local buffer of commits/observations that failed to post (usually because the API was unreachable during capture).
mind flush [--all] [--repo-dir PATH] [--verbose]Flags
--all— drain every project's queue, not just the current repo's.--repo-dir— path to the repo. Defaults to the current working directory.--verbose— print progress for each buffered entry.
Exit codes
0— buffer drained cleanly (or was already empty).- Non-zero — at least one entry failed to post; remaining entries stay in the
buffer for the next
flushorcaptureto pick up.
mind backfill
Walk git history oldest-first and ingest each past commit — plus a short summary observation — into CommitMind. Useful on a freshly-linked repo so the timeline isn't empty.
mind backfill [--repo-dir PATH] [--limit N] [--since DATE]
[--quiet] [--verbose] [--no-buffer] [--dry-run]Flags
--repo-dir— path to the repo. Defaults to the current working directory.--limit— max commits to ingest.0means unlimited. Defaults to a safe cap.--since— only ingest commits after this date (YYYY-MM-DDor full RFC3339).--quiet— suppress per-commit progress; still prints the final summary.--verbose— print per-commit progress to stdout.--no-buffer— fail loud on network errors instead of buffering. Use in CI-style one-shot environments where a partial buffer is worse than a loud exit.--dry-run— count commits that would be ingested without any API calls.
Examples
# Import the last 30 days.
mind backfill --since 2026-03-24
# Fast preview: how many commits would this touch?
mind backfill --dry-runmind explain
Resolve a file path or symbol name and emit a fixed-schema envelope of
decisions, observations, and commit summaries pertinent to the target —
the why behind a piece of code. Pairs with xref (the where-lookup):
xref answers "where is this defined / called", explain answers "why
does this exist / what context shaped it" — without keyword-guessing
into search_memory.
mind explain <file|symbol> [--format=json|markdown]
[--synthesize] [--quiet] [--repo-dir PATH]Default response is fast (~100ms): full source content (decision rationales + observation bodies + commit messages) inline so the caller can read directly. The MCP tool and PreToolUse hook share this same path — agents read raw content directly, no LLM call.
Pass --synthesize to layer an LLM-produced Why paragraph plus
categorized Constraints / Risks at the top. Takes 4–8s for a hot
file (Sonnet/Haiku-tier model generation time); useful for human
reading from a terminal, not from agents.
Flags
<file|symbol>— positional. A file path (with/or recognized extension) or an exact Go/TS/Python/etc identifier.--format—markdown(default) orjson. JSON round-trips the full envelope shape for tooling.--synthesize— opt in to the LLM synthesis pass. Off by default.--quiet— suppress output when no envelope carries curated context (everyConfidence == "low"with zero decisions). Designed for the PreToolUse hook so it stays silent on files with no memory surface yet.--repo-dir— path to the repo. Defaults to cwd.
Examples
# Quick context check on a file (raw content, sub-second).
mind explain apps/cli/internal/commands/explain.go
# Symbol lookup — resolves to the indexed file(s) it lives in.
mind explain RegisterTaskAdvance
# Human-friendly synthesis for a longer reading session.
mind explain pkg/explain/queries.go --synthesize
# JSON for tooling.
mind explain pkg/explain/queries.go --format=jsonExit codes
0— envelope printed (or quietly skipped under--quiet).1— hard error (no daemon, no token, target didn't resolve).
mind doctor
Run a battery of probes against this machine's CommitMind install — daemon
health, tokenstore + auth handshake, MCP wiring per editor, and hook
installation. On macOS it also classifies any crash reports the daemon has
left behind, so a daemon that keeps dying tells you how it died rather
than just that it's gone. Pure diagnosis by default; pass --fix to apply
the safe-to-fix subset.
mind doctor [--check NAME] [--fix] [--yes] [--json]Flags
--check— run a single probe by name instead of the full battery.--fix— apply auto-fixes for fixable probes.--yes— skip the confirmation prompt when--fixis set.--json— emit JSON output for scripts and CI.
mind usage
Report what background AI has cost on this machine — the transcript harvester, the AI security scan, and the agent worker — broken down by producer and by pass. Reads the daemon's local cache only: no network, no account.
Figures are tokens charged against the agent seat this machine runs on, not dollars. That distinction matters: background AI runs on your own Claude or Codex subscription, which is a rate limit rather than a bill, so the cost of a heavy background pass shows up as your own interactive work being throttled mid-task rather than as an invoice. A dollar figure reads as trivially cheap and hides exactly the problem you are trying to find.
Results are grouped by pass as well as by call, because a pass is what the cadence settings control — one scan can fan out into dozens of batched completions, and a per-call average hides that.
mind usage [--days N]Flags
--days— how far back to report (default 7;0for all time).
A producer whose backend reports no usage is flagged rather than shown as zero: its cost is unknown, not free.
The report closes with your spend ceiling — what the last 24 hours cost against the bound you set, or a note that none is set.
mind usage limit
Bound how many tokens background AI may draw from your agent plan in a rolling
24-hour window. The ceiling is per-machine and covers every AI producer:
security review, correctness review, harvest, mind learn, and commit-message
composition.
mind usage limit light # ~2M tokens/day
mind usage limit balanced # ~8M tokens/day
mind usage limit thorough # ~30M tokens/day
mind usage limit 500000 # an exact bound
mind usage limit unlimited # remove the ceilingPresets are a starting point, not a measurement. They are anchored on a
single observed pass — one reviewed commit cost roughly 543K tokens — so treat
them as a first guess and adjust once mind usage shows your own numbers. A
raw token count is there precisely so you can.
The window is rolling, not a calendar day: there is no moment at which the number resets to zero. It decays continuously as older calls age past 24 hours, which is why the report says "in the last 24 hours" rather than "resets in N".
When the ceiling is reached, background passes are refused, not queued, and the refusal names the setting. A pass already running is never killed — enforcement happens when a pass is admitted, so no work in flight is wasted.
Unset means unlimited. So does an unrecognised value in the config file: a ceiling that cannot be read fails open rather than silently throttling the machine.
mind ui-verify
Helpers for the ui-verify blocks that mind task verify runs (headless
Playwright: navigate routes, assert console/network + visible text, capture
screenshots). By default that tier is logged-out, so it can only check public
pages. ui-verify login saves a real browser session so a block can check pages
behind a login too.
mind ui-verify login --url https://app.example.com [--login-path /signin]
mind ui-verify logout --url https://app.example.comlogin opens a browser window, waits for you to log in, and saves the
session to the CommitMind cache — one file per host, mode 0600, never inside a
repo. You type the password, so SSO, 2FA, and magic links all work; the CLI
never handles a credential itself. Re-run it when a session ages out.
A block then asks for that session by intent:
```ui-verify
{
"baseUrl": "https://app.example.com",
"auth": true,
"routes": [{ "path": "/acme/get-started", "expect": [{ "text": "Get started" }] }]
}
```The block never names the file. Blocks live in a task's review_instructions,
which sync to the cloud and render on the dashboard, so the path is resolved
locally — "auth": {"storageState": "..."} is rejected outright.
Routes stay independent: each one still gets a fresh browser context, merely seeded from the same saved session, so run order never matters.
If the saved session has expired, the app redirects to its login route and the
route is reported as session-expired rather than as a wall of failed
assertions — one run tells you to log in again. If no session has been saved for
that host, the tier skips with the exact command to run.
Flags
--url— the app origin to log in to (required).--login-path— the app's login route, if it isn't/login.
Security. The saved session is a live credential in plaintext on disk, and authenticated screenshots captured by a run contain your real pages and are uploaded with the verification record. Use this on workspaces you own.
mind update
Pull the latest CommitMind release. Fetches the manifest from
commitmind.dev/dl/latest, downloads the platform-matched binary archive,
verifies its SHA-256, and atomically replaces the running binary in place.
The daemon is reloaded (launchctl on macOS, systemctl --user on Linux) so
the new binary takes effect immediately.
mind update [--check] [--manifest-url URL]Flags
--check— print the available version and exit; don't download.--manifest-url— override the manifest URL. Useful for dev / staging.
mind prime
Print this project's CommitMind context as markdown. When stdout is a
terminal, renders a scannable human card (recent commits, observations,
open tasks). When piped or run with --hook-envelope, renders an
agent-shaped payload designed to load into an AI session via a SessionStart
hook — no manual prime_session MCP call required.
mind prime [--post-compact] [--hook-envelope]
[--quiet] [--no-color] [--repo-dir PATH]Flags
--post-compact— emit a focused post-compaction reprime (active task + contract reminder) instead of the full session-start prime.--hook-envelope— wrap output in Claude Code's SessionStarthookSpecificOutputJSON envelope and emit a one-linesystemMessagesummary.--quiet— print nothing when the repo isn't a CommitMind project.--no-color— disable ANSI color in the human card.--repo-dir— path to the repo.
Exit codes
0— printed (or quietly skipped because the repo isn't connected).1— hard error (network / token / git inspect).
mind explain
Resolve a file path or symbol name and emit a fixed-schema envelope of
decisions, observations, and commit summaries pertinent to the target —
the why behind a piece of code. Pairs with xref (the where-lookup):
xref answers "where is this defined / called", explain answers "why
does this exist / what context shaped it" — without keyword-guessing
into search_memory.
mind explain <file|symbol> [--format=json|markdown]
[--synthesize] [--quiet] [--repo-dir PATH]Default response is fast (~100ms): full source content (decision rationales + observation bodies + commit messages) inline so the caller can read directly. The MCP tool and PreToolUse hook share this same path — agents read raw content directly, no LLM call.
Pass --synthesize to layer an LLM-produced Why paragraph plus
categorized Constraints / Risks at the top. Takes 4–8s for a hot
file (Sonnet/Haiku-tier model generation time); useful for human
reading from a terminal, not from agents.
Flags
<file|symbol>— positional. A file path (with/or recognized extension) or an exact Go/TS/Python/etc identifier.--format—markdown(default) orjson. JSON round-trips the full envelope shape for tooling.--synthesize— opt in to the LLM synthesis pass. Off by default.--quiet— suppress output when no envelope carries curated context (everyConfidence == "low"with zero decisions). Designed for the PreToolUse hook so it stays silent on files with no memory surface yet.--repo-dir— path to the repo. Defaults to cwd.
Examples
# Quick context check on a file (raw content, sub-second).
mind explain apps/cli/internal/commands/explain.go
# Symbol lookup — resolves to the indexed file(s) it lives in.
mind explain RegisterTaskAdvance
# Human-friendly synthesis for a longer reading session.
mind explain pkg/explain/queries.go --synthesize
# JSON for tooling.
mind explain pkg/explain/queries.go --format=jsonExit codes
0— envelope printed (or quietly skipped under--quiet).1— hard error (no daemon, no token, target didn't resolve).
mind dashboard
Open the local project dashboard served by the running sync daemon.
Requires mind sync daemon (or the launchd / systemd unit installed
via mind sync install) to be running.
mind dashboard [--print-url]Flags
--print-url— print the dashboard URL instead of opening a browser.
mind review
Run a structured review pass over the repository and print findings — symbol-level diff for the change-scoped modes, project rule violations across all of them. Each finding is severity-tagged (info / low / medium / high / critical).
mind review [--scope working|task|staged|head|all]
[--threshold info|low|medium|high|critical]
[--format text|json|jsonl-stream]
[--limit N] [--path PATH ...]Scopes
working(default) — working tree vs HEAD; catches dirty + staged.task— only the files attributed to the agent's active task. Reach for this when another agent shares the checkout: every other scope diffs the whole working tree, so a peer's uncommitted edits get reported as yours. It refuses, naming the files, rather than silently narrowing when a changed file is not attributed — the attribution cannot see shell edits (sed,perl, apython3heredoc), and reviewing the remainder would report clean over unreviewed code.--pathwins outright and is the way past a refusal.staged— git index vs HEAD (pre-commit semantics).head— HEAD vs HEAD~1 (post-commit retrospective).all— every tracked source file vs the current rule set (full-codebase audit; structural diff suppressed, only rule violations surface). Slower than the diff scopes — pass--limit=0for unbounded.
--head-tree <sha> reviews the content of a git tree object instead of the
live working tree (--scope=working only). mind commit passes the tree it
froze for the commit, so the gate reviews exactly the bytes that will be
committed rather than a working tree a concurrent agent may still be writing to
— the diff, the changed files and lines, the file contents and the reported head
SHA all come from that tree. Rarely useful by hand.
AI review passes
Beyond the deterministic engine, review can run LLM passes on your local
coding agent:
- Judgment (
--ai/--no-ai) and security (--ai-security/--no-ai-security) run by default on an interactive review, controlled by the project'sai_defaultsetting (on unless a project opts out). The commit gate never auto-runs the judgment pass. - Maintainability (
--maintainability/--no-maintainability) — the code-smell axis (naming, duplication, missing tests for risky logic, drift from local idiom). Advisory only (never gates a commit), and off by default unless the project setsmaintainability_default. Never runs on the commit gate.
Set the project defaults from the dashboard's review-config drawer, so agents,
CI, and the review_ai MCP tool inherit them without per-run flags.
Which files are reviewed
The diff scopes review only the files in the change. --scope all
enumerates with git ls-files, so it reviews tracked files only —
anything gitignored (build output, dist/, .env, local artifacts)
is skipped automatically. You don't need to configure anything to keep
gitignored generated files out of a review.
For files that are committed but you don't want reviewed — vendored
dependencies, checked-in codegen, parser fixtures — add a
.commitmindignore at the repo root. .gitignore can't exclude these
because they're tracked on purpose. It uses gitignore-style globs matched
against repo-relative paths; matches are dropped from --scope all
entirely and marked skipped in the diff scopes (so you still see when a
commit touches an ignored path).
# .commitmindignore — paths no rule should ever fire against.
# gitignore-style globs, matched against repo-relative paths.
vendor/** # vendored third-party code
**/*.pb.go # protobuf codegen
**/*.sql.go # sqlc codegen
**/testdata/** # parser / rule fixtures
apps/web/dist/** # a committed build artifact| File kind | How it's excluded |
| --- | --- |
| Gitignored (build output, .env, local artifacts) | Automatic — git ls-files skips it; no config |
| Tracked but generated / vendored | .commitmindignore — .gitignore can't, since they're committed |
.commitmindignore means "never review this path." To silence a
specific rule on a path while keeping the others, scope it in that
rule's file_patterns instead.
Pre-commit gate
--threshold <sev> exits non-zero (code 7) when at least one finding
has severity ≥ <sev>. Pair with mind install-hook to block
commits on regressions.
Flags
--format— output renderer:text(default) — markdown to stdout, buffered until the run finishes. Good for human review.json— single JSON document, buffered. Good for CI / dashboard consumers parsing the final report.jsonl-stream— newline-delimited JSON emitted as the run progresses. Good for live UIs (the commitmind-code TUI's/scandialog) and any consumer that wants to render progress without waiting 30-60s for--scope=allto finish. See the event shape below.
--limit— max files in the report (1-200; pass0for unbounded).--path— repeatable path filter (relative to cwd).
jsonl-stream event shape
One JSON object per line. Events arrive in this order:
| event | When | Key fields |
|-------------|--------------------------------------------|---------------------------------------------------|
| progress | Stages: start once, file per file, done once | stage, done, total, path, findings, truncated |
| finding | Each deduped finding from the rule pass | severity_label, Path, Line, Message, RuleID |
| summary | Once at the end | scope, base_sha, head_sha, files_reported, truncated, counts (per-severity totals) |
| error | On orchestrator failure (mid-run) | message |
When an error event lands, no further events follow.
Examples
# Live progress for a project-wide audit
mind review --format=jsonl-stream --scope=all
# CI gate (text + threshold pair):
mind review --threshold=high
# Pipe the streaming events into jq for ad-hoc filtering:
mind review --format=jsonl-stream --scope=all \
| jq -c 'select(.event=="finding" and .severity_label=="critical")'Exit codes
0— review ran; no findings met the--threshold(when set).7— review ran; at least one finding meets the threshold. The report still printed before the exit.- non-zero (other) — orchestrator error (e.g.
--scopeinvalid, external-tool failure when not soft-skippable). For--format=jsonl-stream, the error event lands on stdout AND the exit is0so a streaming consumer parses it normally; fortext/jsonthe error returns a non-zero exit per cobra's standard.
Coverage gate
When the project enables it, mind review --scope=auto — the mode the
installed pre-commit hook runs — also checks patch coverage: whether the
lines you are staging are covered by tests. Blocks with exit code 8, distinct
from the findings gate's 7 so a caller can tell which one fired.
Patch coverage, not the project total, so a legacy repo is never blocked on code nobody touched.
Configuration
- Project-wide:
coverage_gate_enabledandcoverage_patch_thresholdin the project's review-gate config. Disabled by default. - Per-developer:
git config --local commitmind.coveragePatchThreshold <percent>. This may only raise the project's threshold — there is no local off switch, because a team gate any machine can disable is not a gate. A local value below the project floor is ignored, and the clamp is printed.
When it declines to judge
The gate warns and does not block when it cannot honestly measure:
- no coverage report exists — nothing was measured, which is not a pass and not 0%
- the report predates your staged edits, so its line numbers describe different code
- the staged diff could not be read
That last group matters more than it looks. A coverage report records positions in each file as it was when the tests ran, so lines you wrote afterwards appear in no block at all. Silently excluding them would compute "100% of nothing" and pass — precisely when the gate was most needed. It refuses instead.
AI coverage gate
When the project enables it, mind commit also blocks if the AI-judgment pass
(logic bugs, missing edge cases, breaking changes) ran but could not finish
reviewing the diff — e.g. a slow local agent under heavy machine load. Blocks
with exit code 9, distinct from the findings gate's 7 and the patch-coverage
gate's 8.
This is separate from an AI finding blocking a commit — judgment findings stay advisory. This gate fires only on a coverage gap: the pass was attempted and did not cover everything.
Configuration
- Project-wide:
ai_coverage_gate_enabledin the project's review-gate config. Disabled by default — transient AI-agent slowness should not start blocking a project that never asked for that guarantee.
When it blocks
✖ AI coverage gate: the AI-judgment pass could not fully review this diff.
Not covered:
apps/api/foo.go
Narrow the diff and try again: mind commit -- <path> ... (commit just those paths)
Or skip AI judgment for this commit (deterministic rules still gate): mind commit --no-ai
Suppressions
A suppression marks one finding on one file a false positive. A fresh match is
then kept visible as an advisory but never blocks the commit gate — the
scoped alternative to disabling a whole rule or running --no-review.
# Mark one finding on one file a false positive (reason + category required).
mind review suppress --file web/icons.ts \
--heuristic rule:lint/unused-import \
--reason "used via object shorthand two lines below" --category false-positive
# Narrower: silence ONE security finding rather than the whole analyzer.
mind review suppress --file pnpm-lock.yaml \
--finding security:osv-scanner:CVE-2026-64641 \
--reason "relocated, not introduced — verified present in the root lockfile" \
--category false-positive
# Suppress everything currently blocking the gate, in one attributed batch.
mind review suppress-gating --reason "…"
# See what is suppressed — id, reason, who, when.
mind review suppress-list
# Put a finding back in the gate.
mind review suppress-revoke <id>Pick the flag by the scope you mean. --heuristic silences that heuristic or
analyzer on that file — right for a vendored or generated file. --finding
silences one finding, identified by its id (security:<tool>:<code>) — right
when you have judged one specific CVE or check. Suppressing a single CVE with
--heuristic would stop that scanner reporting on the file at all, so a genuine
new CVE appearing there later would not gate. The _False positive?_ line printed
under each finding already names the narrower form where one exists.
Both can coexist on the same file; they are separate rows.
suppress-list reads the daemon's local mirror, so it needs no network and
works offline. Each entry prints the id that suppress-revoke takes. If the
daemon has not synced yet it says so explicitly rather than reporting "no
suppressions" — an unsynced cache and an empty project are different answers.
Suppressions recorded before attribution shipped display as unattributed:
no creator was captured for them, so none is claimed.
suppress-revoke removes the suppression so matching findings gate again on
the next review. Unlike the read path it is not best-effort — a failure is
reported, because silently failing to revoke would leave you believing a finding
is live when it is still suppressed. The local mirror may still list the revoked
row until the daemon re-syncs.
mind commit
Commit through CommitMind instead of git commit. It runs the deterministic
staged review first (fail-fast — nothing is committed if a finding meets the
project gate), composes the message, links the commit to a task, and hands off
to git so your normal pre-commit hook still runs.
mind commit [-m MSG ...] [--task ID] [--index | --only-staged]
[--no-review] [--no-ai] [--dry-run] [-- <pathspec>...]mind is the short alias for commitmind, so mind commit is the same command.
What gets committed — the part worth understanding
This is the difference from git commit, and it exists because several agents
often share one checkout and one git index.
- No pathspecs, no flags — in an agent session, the commit auto-narrows to the files this task touched, from the daemon's per-task tracking (the same set the done-gate uses). A parallel agent's staged files cannot be swept into your commit. With no attribution available (a human with a deliberately-staged index, no agent session, or the daemon down) it falls back to the whole staged index.
-- <pathspec>...— commit only those paths and leave the rest of the index untouched. Likegit commit -- <paths>, this commits the working-tree content of those paths whether or not they were staged. The review and the AI message diff are scoped to the same content, so nothing slips past unreviewed.--index— force the whole staged index, ignoring attribution.--only-staged— commit exactly what is staged: no narrowing and no automaticgit add, so files you deliberately unstaged (say after areset --soft) are never swept back in.
The attributed narrow runs git add on your task's files, which stages their
working-tree content. Any file it stages that wasn't already staged is named in
the output, so the widening is never silent.
Gates that can refuse the commit
-
Staged review — runs first and fail-fast, so a blocked commit costs no AI budget. Findings at or above the project's gate threshold abort it. Skip with
--no-review(your gitpre-commithook still runs). The reviewable alternative to skipping ismind review suppress-gating, which records an attributed, per-file false-positive rather than bypassing the gate wholesale. -
Spec gate — when you pass
--taskand that task is a feature/refactor in a project withspec_driven_mode=requiredand no human-approved spec, the commit is refused. It only applies to an explicitly named task: without--taskthe command will not guess which task a commit belongs to, so it does not gate. Both gates fail open — if the daemon is unreachable, your commit proceeds. -
Task-pin gate — with
task_pin_gate=strict, a commit is refused unless a task can be attributed to it.mind commitruns as a bare process with no session id, so on a shared checkout where several agents are pinned to different tasks CommitMind refuses to guess whose is whose — attributing your commit to a peer's task would be worse than refusing — and the commit is blocked. Pass--task <id>to name yours. That is not a bypass: every other gate still runs, unlikegit commit --no-verify, which skips the review gate too.
Use --dry-run to see the verdict over what would be committed without
staging, committing, or spending AI-message budget.
The message
With no -m and no --no-ai, the message is generated on your local coding
agent from the diff. -m (repeatable, like git) or -F FILE suppress
generation; --no-ai opens your editor instead.
The diff it reads is the commit's exact content, frozen up front as a git tree
before the review gate runs — so brand-new files are included (they used to be
invisible, because git diff cannot report an untracked path), and the gate,
this message and the printed file list all describe the same thing. If the files
change underneath a commit while it is being prepared — a concurrent agent
writing to the same paths — the commit is refused rather than landing with a
review verdict for content that was never reviewed.
Prefer -F over -m for anything multi-paragraph: -m routes the text through
the shell, where backticks and $(...) execute.
A single CommitMind: task <short-id> line links the commit to the active
session's pinned task; --task overrides it, and the line is omitted when
nothing is pinned. No Co-Authored-By trailer is added.
Flags
| flag | effect |
| --- | --- |
| -m, --message | Message paragraph, repeatable. Suppresses AI generation. |
| -F, --file | Read the message from a file. Mutually exclusive with -m. |
| --task | Task id or short id to link; overrides the session pin, and satisfies task_pin_gate=strict on a shared checkout. Also selects the task whose title is given to the message generator as intent — without it, a bare CLI process on a shared checkout can pick up a peer's pinned task. |
| --index | Commit the whole staged index instead of narrowing. |
| --only-staged | Commit exactly the index — no narrowing, no auto git add. |
| --no-review | Skip the fail-fast staged review. |
| --no-ai | Don't generate a message; open the editor. |
| --dry-run | Print the gate verdict and stop. Stages nothing, commits nothing. |
| --repo-dir | Path to the repo (defaults to cwd). |
mind rules
Print the project rules applicable to a repo-relative file path as
markdown — same payload the get_rules_for_this_file MCP tool returns.
Designed to fire from a Claude Code PreToolUse hook so an editing agent
reads the applicable rules block before every Read / Edit / Write.
mind rules <file> [--quiet] [--repo-dir PATH]Flags
<file>— positional, repo-relative path.--quiet— suppress the "no rules apply" line when the file matches no rules.--repo-dir— path to the repo.
Exit codes
0— printed (or quietly skipped because the repo isn't connected).1— hard error (no file argument, malformed git inspect).
mind rules verdicts
Report what the AI review checklist has decided about each of your rules, and the gating lifecycle state each of this project's own rules is currently in.
Every review that runs the AI checklist records one verdict per rule —
violated, clean or not_applicable. Only violated ever becomes a finding,
so this is the only place the rest of the distribution is visible: which rules
fire, which never apply, and how close each is to earning or losing a gate.
mind rules verdicts [--json]Flags
--json— emit the report as JSON, including the current threshold constants, for analysis rather than reading.
What it shows
- Total observations and how many rules have any evidence.
- When gating was activated on this cache — rules authored before that stay advisory unless explicitly promoted.
- Each active project rule's lifecycle state (
advisory_legacy,probation,gating,demoted) with the evidence behind it: evaluations, violations, suppressions. - The never-applied set — rules evaluated past the probation bar that have never once fired, and are therefore costing tokens on every review.
Only active project rules appear in the lifecycle table. Pack rules run a separate graduation pipeline, and a pending, disabled or superseded rule is never evaluated at all.
Reads the local cache only — no network, no account, and no daemon required.
Exit codes
0— reported (including when there are no verdicts yet, which is stated explicitly along with what would produce some).1— not a git repo, repo not connected, or the local cache can't be opened.
mind check
Loads each file from disk, resolves the applicable hard rules, and
evaluates them locally — file content never leaves your machine. Output
is JSON in the same shape as the server-side POST /api/v1/rules/check
response, so dashboard / CI integrations parsing the wire format keep
working unchanged.
mind check <file>... [--no-lock] [--require-lock]
[--lockfile PATH] [--quiet] [--repo-dir PATH]Rule source resolution (in order):
.commitmind/rules.lock.jsonat the repo root if present — offline-capable, deterministic, no network round-trip. Same artifactmind sync rulesproduces; CI runs identically.GET /api/v1/rules/applicableper file — automatic fallback when no lockfile exists (or when--no-lockis set).
Flags
<file>...— positional, one or more repo-relative paths.--no-lock— force the API path even when a lockfile exists.--require-lock— fail if no lockfile is present (CI gate).--lockfile— override the lockfile location.--quiet— suppress the empty-violations envelope when nothing fires.--repo-dir— path to the repo.
Exit codes
0— no violations, OR only warn/info severities fired.1— at least one error-severity violation fired.2— hard error (no file argument, file not found, lockfile integrity mismatch).
mind security audit
Run the chunked whole-repo AI security audit — the same pass the dashboard's whole-repo button runs, from the terminal.
This is the pass that resolves findings in files no current diff touches. The automatic version fires on a main/master tip change but defers execution until the machine is idle (no agent session, no edits for 20 minutes), so on a busy machine it can lag indefinitely. This is the manual escape from that lag.
mind security audit --whole-repo [--yes]Flags
--whole-repo— required. Audits every tracked file; there is no diff-scoped mode. Passing it is how you confirm the scope.--yes— skip the confirmation prompt.
Two things worth knowing before you run it
- It is metered. It spends AI quota and can run for a long time on a large
repo. The cost is stated before the prompt, so what you confirm is what you
read. This is deliberately not filed under
mind background-security, whose help promises "no AI, no quota cost". - It resumes. Already-audited file contents are skipped, so an interrupted audit is not wasted work — re-running picks up where it stopped.
Why there is no MCP tool for this
The design protects the property a human armed this, not the request came from a browser. The dashboard run is exempt from the idle-yield rule precisely because a person clicked it, and a command typed at a terminal has the same property. An agent-invoked trigger would not — so the absence of an MCP tool is an architectural fact rather than a convention. An agent that wants an audit has to ask you to run this.
mind install-hook
Render a git pre- or post-commit hook that runs mind review.
The pre-commit hook gates git commit on a mind review --scope=auto
pass, which resolves the scope from the project's review-gate config
(precommit_scope, settable in the dashboard). It defaults to diff —
"just the lines I'm committing": the same files as staged, gating
identically, but findings on lines your commit did not touch are dropped
rather than reported as pre-existing debt on every commit. Set it to
staged if you want that debt surfaced (non-blocking) at commit time.
When the gate fires, the commit is blocked and the report prints inline.
Bypass with git commit --no-verify.
mind install-hook [--threshold info|low|medium|high|critical]
[--post-commit] [--force]Flags
--threshold— severity gate for the pre-commit hook. Defaulthighso only review-blocking findings interrupt the workflow. Lower thresholds are noisier; raise as your codebase tolerates. Ignored with--post-commit.--post-commit— render a post-commit hook instead. Runsmind review --scope=allAFTER each commit lands — informational only (git ignores its exit code), so it never blocks.--force— overwrite an existing hook.
mind sync
Manage the per-machine sync daemon. The daemon keeps each project's local SQLite cache fresh from the API so rule eval, symbol lookups, and other read paths run on-laptop in under 50ms.
mind sync <subcommand>Subcommands
daemon— run the daemon foreground (used by launchd / systemd / supervisors).start— background-start the daemon (writes pidfile, returns).stop— send SIGTERM to the running daemon.status— report whether the daemon is running.attach— add the current repo to the daemon's project list.detach— remove the current repo from the daemon's project list.logs— tail the daemon's log file.rules— generate or refresh.commitmind/rules.lock.json.resync— force a freshGET /api/v1/rulesinto the daemon's cache.now— force-refresh every local cache (rules + playbooks + tasks + activity) plus the rules lockfile.install— render a launchd plist (macOS) or systemd user unit (Linux).uninstall— remove the launchd plist / systemd unit. Pass--purgeto also wipe caches + tokens.
Pass --help to any subcommand for its specific flags.
mind mcp
Run the CommitMind MCP server that Claude Code, Cursor, and other editors
spawn per session. The server reads the agent token minted by
mind init and streams JSON-RPC over stdio. You shouldn't normally
run this by hand — the Claude Code plugin wires it (or
mind init --mcp-config-only=<editor> for Cursor / VS Code).
mind mcp <subcommand>Subcommands
serve— start the tasks/memory surface (mcp__mind__*tools).serve-code— start the code-intel surface (mcp__mind-code__*tools —xref,check_rules,get_rules_for_this_file, etc).tool-snapshot— emit this build's MCP tool inventory (every tool name, description and full input/output JSON Schema) as stable, sorted JSON. The release pipeline publishes one per version so future releases can be diffed for added/removed tools and changed schemas.
# Inspect the surface this binary exposes.
mind mcp tool-snapshot | jq '.tools[].name'
# What the release pipeline runs.
mind mcp tool-snapshot --version v1.2.3 -o dist/tools.jsontool-snapshot flags
--version— version tag to stamp on the snapshot. Defaults to the running binary's version.-o,--out— write to a path instead of stdout.
mind whatsnew
Report what changed in CommitMind since a given version: the releases published after it, their notes, and a classified diff of the MCP tool surface — which tools were added or removed, which arguments changed, and which of those can break a call you already wrote.
mind whatsnew [--since vX.Y.Z]Flags
--since— version to compare from. Defaults to this binary's version, i.e. "what did I miss".
Changes are grouped by impact on an existing caller: breaking (tool removed, required argument added, argument removed or retyped), additive (tool added, optional argument added, a requirement relaxed), and cosmetic (wording).
Tool-change reporting only works backward to a release that published a schema snapshot. Releases cut before that artifact existed carry none, and for those ranges the command says so explicitly rather than reporting that nothing changed. Treat "could not be determined" as unknown, never as "unchanged".
The same report is available to agents as the whatsnew MCP tool on the
tasks surface, with an optional since argument that defaults to the running
server's version. That is the form an agent should reach for when it is unsure
whether a tool or argument exists in the installed version — the CLI command
is for humans at a terminal.
mind sweep
Compare the project's indexed files (every distinct path in
project_symbol_index) against this repo's HEAD via git ls-files, then
DELETE the index rows for any file no longer in HEAD. Companion to
mind backfill --force — --force re-queues commits for the
staleness worker; sweep cleans up symbol-index rows that no commit will
ever re-touch.
mind sweep [--dry-run] [--yes] [--verbose] [--repo-dir PATH]Flags
--dry-run— print the ghost-file list without DELETing.--yes— skip the confirmation prompt before DELETing.--verbose— print every ghost path even when there are many.--repo-dir— path to the repo.
Exit codes
0— index in sync OR sweep applied successfully.1— error (network, auth, mismatched repo, etc.).2— user declined confirmation.
mind agent
Run cheap headless workers on agent-ready tasks — the single-task dispatch
loop. agent run loads an agent-ready task, assembles its design + relevant
memory into a worker prompt, isolates a cheap claude -p worker in a throwaway
git worktree, lets it iterate to green, runs the task's acceptance verification
against the worker's diff, then surfaces the diff for human review. It runs
an escalation ladder — cheap model first, retry with feedback, then a stronger
model — and never auto-merges. The worker never sees the acceptance test (it's
orchestrator-held), and the retry feedback reports only that a check failed and
its kind — never the check command or its assertion values, so the worker can't
target the gate.
mind agent run <task-id> [--model SLUG] [--no-escalate] [--max-retries N] [--dry-run] [--repo-dir PATH]Flags
--model SLUG— cheap-tier worker model slug (default:haiku). Overrides the first rung of the escalation ladder.--no-escalate— run the cheap tier only; don't escalate to a stronger model (opus) on repeated failure.--max-retries N— attempts on the cheap tier before escalating (default2); each retry feeds back the prior failure.--dry-run— assemble and print the exact prompt the worker would receive, then exit. No worktree, no worker spawn — use it to inspect the handoff.--repo-dir PATH— repo root to dispatch from (default: current directory).
Gate. The task must be agent-ready (cleared the refinement gate: a runnable
verify block in review_instructions + a leaf task with a design_doc). A task
that isn't is rejected with a pointer to task_mark_agent_ready.
Entitlement. The coding agent (Mind Code) is a Pro feature, checked at
dispatch — a confirmed free-tier org is blocked with an upgrade pointer before
any worker spawns. The check runs after --dry-run (a dry run never spends, so
it's never gated) and fails open: if the entitlement lookup can't be reached,
dispatch proceeds with a warning rather than blocking a paying user on a
transient outage. agent queue applies the same check per task.
Outcome. On a passing verify the task advances to review with a note
summarising every attempt; the worker's diff stays in the worktree for you to
review and merge (or discard with git worktree remove). If the whole ladder
fails, the command exits non-zero and (when a salvageable diff survives) leaves
the worktree for you to inspect. Local dispatch spends your own claude login.
mind agent queue
Drain the agent-ready queue — pick up every agent-ready task in the project
(the orchestrator's queue) and dispatch each one, in turn, through the same
escalation ladder as agent run. Tasks already in review (dispatched and
awaiting a human) are skipped; nothing is ever auto-merged. This is a one-shot
drain, not a long-running poller — re-run it (or wire it to a cron) to pick up
newly refined tasks. Workers run sequentially, one worktree at a time.
mind agent queue [--limit N] [--model SLUG] [--no-escalate] [--max-retries N] [--dry-run] [--repo-dir PATH]Flags
--limit N— dispatch at mostNagent-ready tasks this run (0= all).--model SLUG— cheap-tier worker model slug (default:haiku), applied to every task's first ladder rung.--no-escalate— run the cheap tier only; don't escalate toopuson repeated failure.--max-retries N— attempts on the cheap tier before escalating (default2).--dry-run— list the agent-ready tasks that would be dispatched, then exit. No worktree, no worker spawn.--repo-dir PATH— repo root to dispatch from (default: current directory).
Outcome. Each task that passes verification advances to review in its own
worktree; each task that fails the whole ladder is left for the human (its
worktree kept) and the drain continues to the next task. The command prints a
summary — dispatched / advanced to review / left for human — and exits 0 unless
it can't list tasks or you're not inside a git repository (leaving tasks for a
human is a normal queue outcome, not a failure).
mind tray (macOS only)
Launch the menu-bar tray — a read-only status surface for the local sync daemon. Polls the daemon's pidfile for at-a-glance state and tails the recent-events log for activity.
mind tray # launch foreground
mind tray install # install LaunchAgent (.app + plist)
mind tray uninstall # remove LaunchAgentAuto-started by the LaunchAgent installed via mind tray install.
Run foreground for debugging or to test the menu without the LaunchAgent.
Quit from the menu's "Quit Tray" item — the daemon keeps running.
mind uninstall
Wipe every CommitMind artifact on this machine. Iterates every repo
recorded in ~/.config/commitmind/projects.json and removes project-scope
artifacts (hooks, MCP entries, .gitignore block, agent skills) in each.
Each per-repo wipe auto-commits ONLY the tracked files it touched, with
message "chore: remove CommitMind integration" (explicit paths only).
The commit is NOT pushed.
After per-repo cleanup, machine-scope artifacts are wiped: the sync
daemon stops, launchd/systemd units unload, the menubar tray is removed,
caches and ~/.config/commitmind (projects.json, every agent token, the
user PAT) are removed, and finally the commitmind binary itself.
mind uninstall [--scope all|project|user] [--dry-run]
[--keep-binary] [--keep-daemon] [--keep-git-hook]
[--keep-mcp-config] [--keep-tokens]Flags
--scope—all(default),project(current repo only), oruser(just user-scope hooks/MCP, no daemon, no per-repo work).--dry-run— print the plan, change nothing.--keep-binary— don'trmthecommitmindbinary itself. Useful when a distro package manager (Homebrew, etc.) owns the binary. Only meaningful with--scope=all.--keep-daemon— don't stop the sync daemon, unload its launchd / systemd unit, or remove the tray, cache dir, or~/.config/commitmind.--keep-git-hook— don't touch.git/hooks/{post,pre}-commit.--keep-mcp-config— don't touch editor MCP config files.--keep-tokens— don't delete credentials in~/.config/commitmind.
mind pack scope
Show, set, or clear the path scope of a subscribed rule pack.
A pack's rules apply to your whole repo unless its subscription carries a
path scope. In a monorepo that means a framework pack fires in apps it has
nothing to do with — a Next.js pack flagging a raw <img> in a Vite dashboard,
for example. Scoping the subscription confines it to the subtree it belongs to.
mind pack scope # list packs + current scopes
mind pack scope --pack nextjs --set 'apps/landing/**' # narrow it (repeatable)
mind pack scope --pack nextjs --clear # back to whole-repoFlags
--pack— which pack to act on: its name (substring, e.g.nextjs) or its id. Required with--set/--clear. An ambiguous name is an error, never a guess — silently scoping the wrong pack would disable rules somewhere nobody is looking.--set— a glob confining the pack to a subtree. Repeatable for several subtrees.--clear— remove the scope, returning the pack to whole-repo.
When you'd reach for it
A pack rule fires somewhere it obviously shouldn't. Check the scope before
concluding the rule is wrong — an unscoped framework pack looks exactly like a
mis-installed one. Run it with no flags: unscoped packs are listed as
(whole repo), which is the state that produces this confusion.
--set with nothing is refused rather than sent: the server rejects an empty
scope on purpose, so a forgotten flag can't silently widen a pack back across
the repo. Use --clear when that's what you mean.
Not available here: subscribe / unsubscribe
Deliberately. Unsubscribing removes an entire ruleset and nothing announces the loss — a rule that stops firing is invisible — and subscribing has billing consequences on paid packs. Both belong to a human on the dashboard.
mind task
Anchor work to a CommitMind task from the shell, without MCP. This is what you reach for when the mind MCP server is down, or when a bare CLI process needs to name a task that ambient resolution will not guess.
mind task set-active <task-id>
mind task create --title "..." [--description "..."] [--type feature|bug|chore|refactor|direct]
mind task verify [--task <id>]
mind task attribute [<sha>...] --task <id>
mind task delete <task-id> --yesset-active / create
Pin an existing task, or create one and pin it. Both register the pin on this
session so the anchor-edit gate and mind commit can see it.
Note the pin is bound to the session, so a pin set by a short-lived shell can
be reaped when that shell exits. On a shared checkout where several agents are
pinned to different tasks, prefer naming the task at the point of use —
mind commit --task <id> — over relying on ambient resolution, which
deliberately refuses to guess.
delete
Permanently removes a task, including its todos and phase groups.
mind task delete <task-id> --yesPrefer abandoning in almost every case. Abandoning is a real lifecycle state that stays in the audit trail, and it is the right answer for work that was started and then dropped — scope shifted, another task owns it, it stopped being relevant. Delete is for rows that should never have existed: a task created by mistake and caught immediately, test or scratch tasks, duplicates, or bulk junk an automated run created.
The test: would a reader of the board learn anything from seeing this task closed? If yes, abandon it. If it is just noise, delete it.
--yes is required — deletion is not a lifecycle transition and there is no
CLI undo. The cloud keeps a soft-delete record, so recovery is possible
server-side by an admin, but not from here.
Local-first like every other write: the row goes immediately and the deletion syncs to cloud in the background, so it works offline. It is also idempotent — deleting a task already gone locally still queues the cloud deletion and succeeds, because the row can be absent locally while present in cloud. The output says which of the two happened.
verify
Runs the task's verification (review_instructions commands plus any
ui-verify / api-verify blocks) and records the verdict the done-gate reads. A
deterministic review over the changed files also runs and gates on high/critical
findings.
Two flags are set only by the hosted Mind Agent dispatch runner and are inert on a normal local run:
--ai-review— also run the opt-in AI-review gate (judgment + security passes, metered) over the changes, gated at high/critical. NeedsCOMMITMIND_TOKEN+COMMITMIND_MIND_API_URLin the environment (the sandbox provides both). A couldn't-run degrades to a non-required skip, so it never false-fails a verify.--ai-grounding-file <path>— a file holding the project memory that grounds those passes, so a finding can cite the project's own decisions/rules.
attribute
Attach already-made commits to a task.
mind commit links commits automatically by writing a Task: trailer, and
mind capture can re-resolve a trailer whose
ingest failed. Neither helps a commit that has no trailer at all — a plain
git commit, or --no-verify.
That commit is not merely unlabelled. Its task ends up with no attributed commits, so the review gate falls back to "everything changed since the task started" — every peer's files included — and stops converging. Measured on a real task: 129 files for a 12-file change.
mind task attribute --task 2f09966 # HEAD
mind task attribute 637cf93 0548700 --task 2f09966This does not infer attribution — you name the task, exactly as
mind commit --task does at commit time. The rule capture states still holds:
the system never guesses which task a trailerless commit belongs to; it only
records what you assert.
- Re-running is a reported no-op, not a failure.
- A commit already attributed to a different task is refused, naming the current owner. Attribution never moves implicitly.
- Takes explicit revisions rather than a range: guessing which commits belong to a task is precisely what the widened gate gets wrong.
mind capture (hook-invoked)
Hidden from --help; documented here for operators. Reads a commit via
git show and posts it to the CommitMind API. mind init wires this
into your .git/hooks/post-commit; you shouldn't normally run it by hand.
mind capture [--sha REV] [--repo-dir PATH] [--quiet] [--verbose] [--no-buffer]Flags
--sha— the commit to capture. Any git rev works (full or short SHA,HEAD~1, a branch name). Defaults toHEAD, which is what the hook wants.--repo-dir— path to the repo. Defaults to the current working directory.--quiet— suppress all output (the default when running as a git hook).--verbose— print debug output to stdout.--no-buffer— fail loud on network errors instead of buffering to disk.
Recovering a commit whose attribution never landed
The post-commit ingest routes through the local daemon so a
CommitMind: task <short-id> trailer resolves into this machine's
task_commits. That step is best-effort by design — a commit must never
fail because the daemon is down — so a restarting or wedged daemon makes it
fall through to the cloud, which does not write local attribution.
When that happens the trailer is never resolved, and the task's review gate widens from "this task's files" to "everything changed since the task started." In a shared checkout with another agent committing, that set grows faster than the scan retires it, and the gate stops converging.
Re-ingest the commit to resolve the trailer that was in the message all along:
mind capture --sha 58381d4This cannot invent attribution. A commit with no trailer stays unattributed — the honest answer for it — so re-running is safe on anything.
When there was never a trailer
mind capture resolves a trailer that exists. A commit made with plain
git commit — or git commit --no-verify, the escape hatch agents reach for
when the task-pin gate blocks them — has no trailer to resolve, so capture
correctly leaves it alone. Name the task explicitly instead with
mind task attribute.