gabriel / muse public
agent-guide.md markdown
1,261 lines 62.0 KB
Raw
sha256:b636f72dcba9e190afb980bece906fa5b717fbde014b76ef023df8cb96e01eb9 docs: expand cache plan with all seven testing tiers and do… Sonnet 4.6 131 days ago

Muse Ecosystem — Agent Guide

Drop @path/to/this/file into any CLAUDE.md or agent system prompt for full ecosystem context.


Three Repos, One Platform

Repo Path What it is
muse ~/ecosystem/muse VCS engine and CLI
musehub ~/ecosystem/musehub Remote server — pushes, issues, MCP tooling. https://localhost:1337
agentception ~/ecosystem/agentception Multi-agent orchestration. http://localhost:10003

All three live under ~/ecosystem/ as a muse workspace. When you change a muse CLI command, agentception callers may need updating. When you change a musehub API shape, agentception readers may need updating.


No git. No GitHub. Ever.

  • Never run git, gh, or any git subcommand.
  • Never reference GitHub, GitHub Actions, or GitHub URLs.
  • Muse and MuseHub are the only VCS tools.
  • If you find a git or gh call anywhere — delete it in the same commit. No comment, no fallback. Delete it.

Sub-Agents Must Use Muse Too

Sub-agents start with no ecosystem knowledge. Include this in every sub-agent prompt:

IMPORTANT — this project uses Muse (not git) for version control.
- Never run git, gh, or any git subcommand.
- Repo paths: ~/ecosystem/muse, ~/ecosystem/musehub, ~/ecosystem/agentception
- Use muse code grep / symbols / cat / impact / deps / hotspots / gravity / entangle
  before reading files directly. Every command accepts --json / -j.
- Use muse -C ~/ecosystem/<repo> <command> when CWD differs from the target repo.

Muse Commands

Every command accepts --json. Always use --json for structured reads.

-C — cross-repo targeting

muse -C ~/ecosystem/muse        <command>
muse -C ~/ecosystem/musehub     <command>
muse -C ~/ecosystem/agentception <command>

-C does os.chdir() before dispatch — file paths resolve against the target repo root. Never omit it when your CWD is a different repo:

muse hub — always needs repo context

muse hub commands require a configured hub connection. Running them without -C (or from a repo without a remote) fails with "No hub connected." Always target a repo that has the hub wired up:

# ❌ Wrong — no hub context
muse hub repo list --json

# ✅ Correct
muse -C ~/ecosystem/musehub hub repo list --json
# ❌ Wrong — path resolves against CWD (wrong repo)
muse code add musehub/services/musehub_wire.py

# ✅ Correct
muse -C ~/ecosystem/musehub code add musehub/services/musehub_wire.py
muse -C ~/ecosystem/musehub commit -m "..."

muse push — check remotes exist before pushing

Before pushing to a repo for the first time, verify remotes are configured:

muse -C ~/ecosystem/<repo> remote --json

If the named remote is not found, the error now lists what is configured:

❌ Remote 'local' is not configured.
   Configured remotes: (none)
   Add one with: muse remote add local <url>

No follow-up muse remote --json call needed — the answer is in the error.

muse push — uses remote names, not --hub

--hub <url> is only valid on muse hub subcommands. muse push always takes a named remote. Never mix the two patterns:

# ❌ Wrong — --hub is not a push flag
muse -C ~/ecosystem/maestro push --hub https://staging.musehub.ai local main

# ✅ Correct — use the remote name
muse -C ~/ecosystem/maestro push staging main
muse -C ~/ecosystem/maestro push local main

To see which remotes are configured and their URLs:

muse -C ~/ecosystem/<repo> remote --json

muse push now also accepts --hub <url> as a convenience: it resolves the URL to its configured remote name automatically, so the wrong pattern is corrected rather than crashing.

muse hub — targeting staging vs local

By default muse hub targets the hub configured for the repo (usually https://localhost:1337). To target staging, pass --hub https://staging.musehub.ai:

# local (default)
muse -C ~/ecosystem/musehub hub repo list --json

# staging
muse -C ~/ecosystem/musehub hub repo list --hub https://staging.musehub.ai --json

muse hub repo list — exact flags

hub repo list lists repos for the authenticated user only. It has NO --owner flag. Valid flags: --limit N, --cursor CURSOR, --hub URL, --json. Filter by owner or name in Python after fetching:

muse -C ~/ecosystem/musehub hub repo list --limit 100 --json \
  | python3 -c "import sys,json; [print(r['slug']) for r in json.load(sys.stdin)['repos'] if r['owner']=='gabriel']"

Never pipe 2>&1 into a JSON parser

2>&1 | redirects stderr into the pipe. If the muse command fails, the error text lands in stdin and Python raises JSONDecodeError: Expecting value — hiding the real error.

# ❌ Wrong — error text swallowed as fake JSON
muse hub repo list --owner gabriel --json 2>&1 | python3 -c "json.load(sys.stdin)..."

# ✅ Correct — check exit code first, or let stderr print to terminal
muse -C ~/ecosystem/musehub hub repo list --json \
  | python3 -c "import sys,json; [print(r['name']) for r in json.load(sys.stdin)['repos']]"

Core commands

Task Command
Status muse status --json
Diff working tree muse diff
Diff staged muse diff --staged
Stage additions/modifications muse code add <file> / muse code add .
Unstage muse code reset <file>
Remove file (disk + stage deletion) muse rm <file>
Untrack file (keep on disk) muse rm --cached <file>
Commit (agent — standard) muse commit -m "msg" --agent-id <id> --model-id <id> --sign
Commit (human — manual only) muse commit -m "message"
History muse log --json
Inspect commit muse read --json
Inspect commit + full manifest muse read --json --manifest
Branches muse branch --json
Create / switch muse checkout -b <name> [--intent "..." --resumable] / muse checkout <branch>
Delete branch muse branch -d <name>
Merge muse merge <branch>
Dry-run merge muse merge --dry-run <branch> --json
Push muse push local dev
Pull muse pull <remote> <branch>
Shelf / pop muse shelf save [-m "msg"] / muse shelf pop
Workspace status muse workspace status --json
Tag muse tag add "label" [<ref>]
Release muse release add <semver>

muse content-grep — regex gotchas

Uses Python re (ERE). Metacharacters ( ) . [ * + ? { } ^ $ must be escaped for literal matches:

muse content-grep "session\.add\(obj_row\)"   # ✅ escaped
muse content-grep "session.add(obj_row)"       # ❌ fails — ( opens a group

OR syntax: muse content-grep "TODO|FIXME"


Branch Flow

main          ← production; tagged releases; never direct-pushed
  ↑
dev           ← integration; latest deliverable state
  ↑    ↑    ↑
feat/* task/* bugfix/*   ← short-lived; one atomic task; hours not days

hotfix/*      ← from main; merges into main AND dev
experiment/*  ← exploratory; time-boxed; promoted or deleted

Never work directly on dev or main. Branch first, always.

Branch semantic flags

Every agent branch should carry intent and resumability metadata. --intent and --resumable are accepted by both muse checkout -b (create + switch atomically) and muse branch (create or annotate only):

# Create, annotate, and switch in one command — the canonical agent pattern
muse -C ~/ecosystem/<repo> checkout -b task/my-thing \
  --intent "implement OAuth token rotation" \
  --resumable

# Annotate an existing branch (no switch)
muse -C ~/ecosystem/<repo> branch task/my-thing \
  --intent "implement OAuth token rotation" \
  --resumable

# Discover all resumable branches (handoff discovery)
muse -C ~/ecosystem/<repo> branch --resumable --json

# JSON listing always includes intent, resumable, created_by on every entry
muse -C ~/ecosystem/<repo> branch --json
# → [{"name": "task/my-thing", "intent": "...", "resumable": true, "created_by": "claude-code", ...}]

Why: --intent lets any agent reading branch --json understand what each branch is for without inspecting commit history. --resumable marks branches as safe for another agent to pick up — use it for any task that may be interrupted.

Standard cycle

# Start — create, annotate, and switch in one command
muse -C ~/ecosystem/<repo> checkout dev
muse -C ~/ecosystem/<repo> checkout -b task/my-thing \
  --intent "describe what this task does" \
  --resumable

# Work — always commit with full agent provenance
muse code add .    # stages new + modified + deleted tracked files
muse commit -m "feat: ..." --agent-id claude-code --model-id claude-sonnet-4-6 --sign

# Merge back
muse -C ~/ecosystem/<repo> checkout dev
muse -C ~/ecosystem/<repo> merge task/my-thing
muse -C ~/ecosystem/<repo> branch -d task/my-thing
muse -C ~/ecosystem/<repo> push local dev

# When dev is ready for main
muse -C ~/ecosystem/<repo> checkout main
muse -C ~/ecosystem/<repo> merge dev
muse -C ~/ecosystem/<repo> push local main
muse -C ~/ecosystem/<repo> push local dev
muse -C ~/ecosystem/<repo> checkout dev

Harmony — Resolution Intelligence

Harmony is Muse's conflict-resolution memory system. Where Git's rerere is a mechanical exact-match cache, Harmony is a three-tier intelligence layer:

Tier 1 — Policy       declarative rule fires automatically on pattern match
Tier 2 — Exact replay blob fingerprint matches a saved resolution
Tier 3 — Semantic     domain plugin similarity score ≥ threshold
Tier 4 — Escalate     create hub issue; flag for human or specialist agent

How Harmony learns

The learning loop is automatic when --harmony-autoupdate is on (the default):

muse merge <branch>          ← harmony auto-applies any saved resolutions
                               conflicts that have no resolution → patterns recorded
                               (future merges will try to replay them)

# Resolve conflicts manually, then:
muse commit -m "merge: ..."  ← harmony records the outcome as a human-verified
                               resolution (confidence=1.0) for every conflict path

Idiomatic harmony workflow

# 1. Merge — harmony tries to auto-resolve using saved resolutions
muse merge feature-x --json
# ✔ [harmony] auto-resolved: config.py::MAX_CONNECTIONS   ← replayed
# CONFLICT: src/server.py::timeout                         ← new, no prior resolution

# 2. Inspect what harmony knows
muse harmony patterns --json          # all saved conflict patterns
muse harmony resolutions --json       # all saved resolutions
muse harmony audit --json             # full tamper-evident action log

# 3. Resolve remaining conflicts manually
muse checkout --ours src/server.py    # or --theirs, or edit manually
muse code add src/server.py

# 4. Commit — harmony automatically records the resolution
muse commit -m "merge: resolve timeout conflict" \
  --agent-id claude-code --model-id claude-sonnet-4-6 --sign
# ✅ harmony: recorded resolution for 'src/server.py::timeout'

# 5. Next time the same conflict recurs → auto-resolved without human input
muse merge feature-y --json
# ✔ [harmony] auto-resolved: src/server.py::timeout

Harmony storage layout

.muse/harmony/
  patterns/
    <pattern_id>/
      pattern.json              ← ConflictPattern (blob + semantic fingerprint)
      resolutions/
        <resolution_id>.json   ← Resolution (outcome_blob, confidence, strategy)
  policies/
    <policy_id>.json           ← declarative Policy rules
  audit/
    <YYYYMMDD>-<uuid>.json     ← append-only tamper-evident log
  escalations/
    <escalation_id>.json       ← Tier 4 escalation records

Harmony CLI reference

Task Command
List all patterns muse harmony patterns --json
List resolutions for a pattern muse harmony resolutions --pattern-id <id> --json
Show best resolution muse harmony best --pattern-id <id> --json
Add a policy muse harmony policy-add --id <id> --action prefer-ours --path-pattern "*.mid"
List policies muse harmony policies --json
View audit log muse harmony audit --json
Run the engine on a conflict muse harmony engine <path> <ours-id> <theirs-id> --json
GC stale unresolved patterns muse harmony gc --age-days 90 --json
Clear all patterns muse harmony clear --json
View escalations muse harmony escalations --json

Pattern fingerprinting

Two fingerprints identify each conflict:

  • Blob fingerprintSHA-256(sorted(ours_id, theirs_id)). Exact-replay only; different content never matches.
  • Semantic fingerprint — provided by a HarmonyPlugin implementation. Enables cross-content replay: two conflicts with different blob IDs but the same semantic shape (e.g. the same musical phrase at different tempo) share one pattern and replay the same resolution.

When a HarmonyPlugin is active and returns semantic_fp != blob_fp, the pattern_id is keyed on semantic_fp alone — enabling cross-content replay. Without a plugin, semantic_fp == blob_fp and the system degenerates to exact replay (identical to Git rerere, but richer in storage and provenance).

Key behaviours to remember

  • Idempotent learning: calling record_resolutions twice with the same outcome_blob produces exactly one resolution — no duplicates.
  • Symbol-path aware: conflict paths like config.py::MAX_CONNECTIONS are handled correctly — file portion used for manifest lookups, full address stored in the pattern.
  • Original conflict paths preserved: checkout --ours/--theirs clears conflict_paths in MERGE_STATE, but original_conflict_paths is preserved through all writes so commit always has the full list to learn from.
  • Path traversal guard: auto_apply resolves .. before any filesystem access — tampered MERGE_STATE cannot escape the repo root.
  • Human-verified wins: best_resolution ranks by (human_verified, confidence, applied_count) descending — a human-verified resolution always beats an unverified one regardless of confidence score.

Bundle — Off-Network Transfer

Bundles are self-contained msgpack files carrying commits, snapshots, and objects. Use them to transfer repo slices over SSH, USB, or email — no network connection required.

Agent decision chain

Always follow this sequence before applying a bundle:

# 1. What's in it?
muse bundle inspect bundle.muse --json
# → total_commits, branches map, per-commit message + agent_id

# 2. Is it clean?
muse bundle verify bundle.muse -q
# → exit 0 = clean; exit 1 = corrupt; no output in -q mode

# 3. What's new relative to my local repo?
muse bundle diff bundle.muse --json
# → new_commits, known_commits, refs_to_advance

# 4. Apply safely (verify before any write)
muse bundle unbundle bundle.muse --verify --json
# → verified=true in JSON if integrity passed before writes

Skip step 4 if new_commits == 0 — the repo is already up-to-date. Abort if step 2 exits 1 — the bundle is corrupt.

Create

muse bundle create repo.bundle --json                      # all of HEAD
muse bundle create out.bundle feat/audio --json            # specific branch
muse bundle create out.bundle HEAD --have <old-id> --json  # incremental

Subcommand reference

Subcommand Needs repo? Purpose
inspect No Show commits + branch heads — no writes
verify No Hash-check every object — no writes
list-heads No Print branch → commit_id map
diff Yes Show commits not yet in local repo
unbundle Yes Apply bundle; --verify guards writes
create Yes Pack commits into a bundle file

Deploy (MuseHub)

Docker + ECR + AWS SSM. Always staging first.

bash ~/ecosystem/musehub/deploy/push.sh staging
bash ~/ecosystem/musehub/deploy/push.sh prod
bash ~/ecosystem/musehub/deploy/push.sh staging prod          # both in sequence
IMAGE_TAG=<prev-tag> bash ~/ecosystem/musehub/deploy/push.sh staging  # rollback

Full details: musehub/docs/infrastructure.md.


Auth — MSign (Ed25519)

No passwords, no JWTs. Ed25519 key pairs. Keys in ~/.muse/identity.toml.

muse auth keygen --hub https://localhost:1337
muse auth register --hub https://localhost:1337 --handle <handle>
muse auth whoami
muse auth logout --hub https://localhost:1337   # decommission / key rotation

Push returns 404 ("Repository not found on remote")? The repo doesn't exist on MuseHub yet — create it via the API, then retry muse push local.

Agentception injects keys into spawned agents via MUSE_AGENT_KEY_FD (pipe fd carrying 64-byte sub-seed) and MUSE_AGENT_HANDLE env vars. get_signing_identity() reads MUSE_AGENT_KEY_FD first, derives the Ed25519 key via SLIP-0010, then falls back to ~/.muse/identity.toml.


Cryptographic Value Codec — muse.core._types

Every cryptographic value is always canonically prefixed — never a bare hex string or bare base64 blob. The prefix embeds the algorithm so the value is self-describing across storage, wire, and log output.

Wire format

sha256:<64-hex>         — content-addressed object / commit / snapshot ID
ed25519:<base64url>     — Ed25519 signature or public key (no padding)
mldsa65:<base64url>     — future post-quantum signature (reserved)

Utility functions (all in muse.core._types)

Need Function Returns
Object ID → (algo, hex_str) split_id(id) ("sha256", "<64-hex>")
Signature string → (algo, b64_str) split_sig(value) ("ed25519", "<base64url>")
Public key string → (algo, b64_str) split_pubkey(value) ("ed25519", "<base64url>")
Signature string → (algo, raw_bytes) decode_sig(value) ("ed25519", b"...")
Public key string → (algo, raw_bytes) decode_pubkey(value) ("ed25519", b"...")
Raw bytes → prefixed sig string encode_sig(algo, raw) "ed25519:<base64url>"
Raw bytes → prefixed pubkey string encode_pubkey(algo, raw) "ed25519:<base64url>"
Just the algo name sig_algo(value) "ed25519" or ""

Rules

  • Never strip prefixes manually — no removeprefix("ed25519:"), no [10:], no partition(":") inline. Use split_sig / split_pubkey / split_id.
  • Never store or transmit bare bytes — always encode with encode_sig / encode_pubkey before serialisation.
  • split_sig vs decode_sig: use split_sig when you need the base64 string (e.g. to pass to another API, embed in JSON, or validate format); use decode_sig only when you need raw bytes for cryptographic operations.
  • split_sig vs split_pubkey: semantically distinct — never pass a signature where a public key is expected.

Agent Config

One canonical source per level. IDE adapter files are derived outputs — never edit them by hand.

<repo>/.muse/agent.md          — repo-specific rules
<workspace>/.muse/agent.md     — shared rules inherited by all members

First-time setup

# At the workspace root (if inside a workspace)
muse -C ~/ecosystem agent-config init

# At each member repo
muse -C ~/ecosystem/<repo> agent-config init

# Choose which adapters you need (persists to .muse/config.toml)
muse -C ~/ecosystem/<repo> agent-config set --adapters claude,codex

# Generate adapter files
muse -C ~/ecosystem/<repo> agent-config sync

Keeping adapters in sync

After editing .muse/agent.md:

muse agent-config sync --force   # regenerate from updated source
muse agent-config status         # verify all adapters are in sync

Adapter files generated

Adapter File Style
claude CLAUDE.md @include reference
codex AGENTS.md embedded content
cursor .cursorrules embedded content
windsurf .windsurfrules embedded content

Claude's adapter uses @path include syntax — it stays minimal and Claude resolves the content at read time. All others embed the full content inline.

Inside a workspace, Claude's CLAUDE.md includes both levels:

@../.muse/agent.md   ← workspace rules
@.muse/agent.md      ← repo-specific rules

Commands

Task Command
Create agent.md muse agent-config init [--force]
Generate adapters muse agent-config sync [--force] [--adapters a,b]
Set default adapters muse agent-config set --adapters claude,codex
Read content muse agent-config read [--scope repo\|workspace\|merged]
Check sync state muse agent-config status [--json]

No Legacy. No Deprecated. No Exceptions.

  • Delete on sight. Dead code, deprecated shapes, backward-compat shims — delete in the same commit.
  • No fallback paths. The current shape is the only shape.
  • No # deprecated annotations. Delete it, don't annotate it.
  • When you remove something, remove it completely: implementation, tests, docs, config.

Code Intelligence — Replace Your Reflexes

Before you grep or read a file, ask: which muse code command answers this?

Layered intel — three altitudes, one repo

Micro  (symbol-level)   grep · symbols · cat · find-symbol · symbol-log
Meso   (file-level)     deps · impact · coverage · breakage
Macro  (repo-level)     gravity · hotspots · entangle · dead · detect-refactor · velocity

Start at the altitude that matches the question. Never reach for a file read when a Micro command answers it. Never reach for Micro when a Macro command gives you the full picture in one call.

Reflex replacement table

Old reflex Muse command
git ls-files / ls / find . — list tracked files muse ls-files --json
git ls-files src/ — list tracked files under a path muse ls-files --path-prefix src/ --json
rg "FunctionName" to find a declaration muse code grep "FunctionName" --json
Read raw file bytes muse cat file.py --json
Read file to find one function muse code cat "file.py::FunctionName" --json
muse code cat "file.py" (no ::) ❌ always errors — use muse cat file.py (file-level) or muse code symbols --file file.py (symbol list)
Understand a file's structure muse code symbols --file path/to/file.py --json
Find a symbol across all branches muse code find-symbol "Name" --json
Map scope before a refactor muse code impact "file.py::Symbol" --json
Find all callers of a function muse code impact "file.py::Symbol" --json
Understand imports muse code deps "path/to/file.py" --json
Update one function body muse code patch "file.py::Symbol" --body /tmp/new.py
Dead-code hunt muse code dead --high-confidence-only --json
Check refactor safety muse code breakage --json
Run tests for what changed muse code test --json
Find the most unstable symbols muse code hotspots --json
Rank symbols by downstream blast radius muse code gravity --json
Find files that always change together muse code entangle --json
Detect latent refactor opportunities muse code detect-refactor --json
Measure test coverage at symbol level muse code semantic-test-coverage --json
Summarise repo activity over time muse code velocity --json
How much of a symbol's original code survives? muse code age --json
When was a symbol last fundamentally rewritten? muse code age --explain file.py::Fn --json
Generate an agent keypair muse agent keygen --json
List registered agents muse agent list --json
Register an agent identity muse agent register --handle <name> --json
Create agent.md config muse agent-config init [--force] --json
Generate adapter files muse agent-config sync [--force] --json
Read merged agent config muse agent-config read --scope merged --json
Check adapter sync state muse agent-config status --json
Add inline annotation to a symbol muse annotate "file.py::Fn" --note "..." --json
List all annotations muse annotate list --json
Show API surface (public symbols) muse api-surface --json
API surface diff between refs muse api-surface --from v1.0 --to HEAD --json
Apply a unified diff .patch file muse apply my.patch --json
Apply a Muse .mpatch file muse apply-patch patch.mpatch --json
Export snapshot as tar.gz / zip muse archive --json
List .museattributes merge rules muse attributes list --json
Resolve strategy for a path muse attributes check src/foo.py --json
Validate .museattributes file muse attributes validate --json
Generate Ed25519 keypair muse auth keygen --hub <url> --json
Register key with hub muse auth register --hub <url> --handle <name> --json
Show current identity muse auth whoami --json
Remove stored credentials muse auth logout --json
Recover key from mnemonic muse auth recover --hub <url> --json
Rotate key to next HD index muse auth rotate --hub <url> --json
Show full HD identity details muse auth show --json
Start a regression bisect muse bisect start --bad HEAD --good v1.0.0 --json
Automate bisect with a test command muse bisect run "pytest -x" --json
Mark current commit bad/good/skip muse bisect bad --json / muse bisect good --json
Show bisect session state muse bisect status --json
End bisect session muse bisect reset --json
Blame a symbol's change history muse blame "file.py::Symbol" --json
Rank symbols by blast-risk score muse code blast-risk --json
List / create / delete branches muse branch --json / muse branch -b feat/x --json / muse branch -d feat/x --json
Detect working-tree structural breakage muse code breakage --json
Create a portable bundle muse bundle create repo.bundle --json
Inspect bundle contents muse bundle inspect repo.bundle --json
Verify bundle integrity muse bundle verify repo.bundle --json
Show new commits in bundle muse bundle diff repo.bundle --json
Apply a bundle muse bundle unbundle repo.bundle --verify --json
List bundle branch heads muse bundle list-heads repo.bundle --json
Print one symbol's source muse code cat "file.py::Symbol" --json
Print all symbols in a file muse code cat "file.py" --all --json
Read a raw object by ID muse cat-object sha256:<id> --json
Run domain invariant checks muse check --json / muse check --base HEAD~1 --json
Query merge-strategy attributes muse check-attr tracks/drums.mid --json
Test paths against ignore rules muse check-ignore build/ --json
Validate branch names muse check-ref-format feat/my-thing --json
Switch / create branch muse checkout dev --json / muse checkout -b task/x --intent "..." --resumable --json
Restore a symbol from history muse checkout-symbol "file.py::Fn" --commit HEAD~5 --json
Cherry-pick a commit muse cherry-pick <ref> --json
Remove untracked files muse clean --dry-run --json / muse clean --force --json
Clone a remote repository muse clone <url> --json
Find duplicate symbols muse code clones --json
Enforce code invariant rules muse code check --json
Query commit history by predicate muse code query "symbol == 'X'" --json
Stage files for commit muse code add . --json / muse code reset --json
Repo semantic topology map muse code codemap --json
Create a commit muse commit -m "feat: X" --agent-id claude-code --model-id claude-sonnet-4-6 --sign --json
Walk commit DAG muse commit-graph --tip dev --stop-at main --json
Create commit from snapshot ID muse commit-tree sha256:<id> -m "msg" --json
Symbol-level diff between refs muse code compare HEAD~10 HEAD --json
Read / get / set config muse config read --json / muse config get user.handle --json / muse config set user.type agent --json
List merge conflicts muse conflicts --json
Search file content muse content-grep "TODO\|FIXME" --json
Validate smart contract invariants muse contract check --json / muse contract list --json
GC expired coordination records muse coord gc --json
Recommend merge order / conflict hotspots muse coord reconcile --json
Release a reservation (mark done) muse coord release <id> --run-id agent-42 --json
Release all reservations for a run muse coord release --all-for-run agent-42 --run-id agent-42 --json
Sync coordination state from remote muse coord sync --json
Enqueue a work item for agents muse coord enqueue "title" --run-id orch --json
Claim the next pending task muse coord claim --run-id agent-1 --json / muse coord claim --queue hotfix --run-id agent-1 --json
Mark a task completed muse coord complete <task-id> --run-id agent-1 --json
Mark a task failed muse coord fail-task <task-id> --run-id agent-1 --error "msg" --json
Cancel a pending or claimed task muse coord cancel-task <task-id> --run-id orch --json
List tasks with filtering muse coord tasks --json / muse coord tasks --status pending --json
Line-level blame for any text file muse blame README.md --json / muse blame src/main.py --range 10-20 --json
Print raw file content muse cat file.py --json / muse cat file.py --at HEAD~5 --json
Count objects in the object store muse count-objects --json / muse count-objects --unreachable --json
Find co-changing file pairs muse code coupling --json / muse code coupling --file src/billing.py --json
Measure symbol-level test coverage muse code coverage --json / muse code coverage --symbol "file.py::Fn" --json
Inspect coordination DAG muse coord dag --json / muse coord dag --active-only --json
Find dead code candidates muse code dead --high-confidence-only --json
Show import / call graph muse code deps src/billing.py --json / muse code deps "file.py::Fn" --transitive --json
Label commit by nearest tag muse describe --json / muse describe --exact-match --json
Detect semantic refactoring events muse code detect-refactor --json / muse code detect-refactor --from v1.0.0 --to v2.0.0 --json
Show working-tree diff muse diff --json / muse diff --staged --json / muse diff HEAD~3 HEAD --json
Render / gate symbol documentation muse docs --json / muse docs --ci --json / muse docs --diff v1 v2 --json
Inspect active domain plugin muse domain-info --json / muse domain-info --all-domains --json
List registered domain plugins muse domains --json
Find entangled symbol pairs muse code entangle --json / muse code entangle --min-rate 0.8 --json
Download commits from a remote muse fetch local --json / muse fetch --all --json
Search all branches for a symbol muse code find-symbol --name validate_amount --json / muse code find-symbol --hash a3f2c9 --json
Iterate all branch refs muse for-each-ref --format json / muse for-each-ref --pattern "feat/*" --format json
Predict merge conflicts muse coord forecast --format json / muse coord forecast --branch feat/x --format json
Export commit as patch file muse format-patch --json / muse format-patch HEAD~3 --json
GC unreachable objects muse gc --json / muse gc --dry-run --json / muse gc --full --json
Compute structural gravity scores muse code gravity --json / muse code gravity --explain "file.py::Fn" --json
Search symbols by name muse code grep "validate" --json / muse code grep "compute.*" --regex --json
Manage harmony conflict patterns muse harmony patterns --format json / muse harmony audit --format json
Hash file or stdin content muse hash-object file.py --format json / echo x \| muse hash-object --stdin --format json
Refresh coordination heartbeat muse coord heartbeat <uuid> --run-id agent-42 --format json
Show symbol churn leaderboard muse code hotspots --json / muse code hotspots --top 20 --json
Map blast radius for a symbol muse code impact "file.py::Symbol" --json / muse code impact "file.py::Fn" --reverse --json
Initialise a new Muse repository muse init --json / muse init --domain audio --json
Check architectural invariants muse code invariants --json / muse code invariants --strict --json
Show language breakdown by commit muse languages --json / muse languages HEAD~5 HEAD --json
Trace symbol lineage across commits muse code lineage "file.py::Symbol" --json
List active coordination sessions muse coord list --json / muse coord list --active-only --json
Walk commit history muse log --json / muse log -n 20 --branch feat/x --json
Inspect ref movement history muse reflog --json / muse reflog --branch dev --json
List all refs with a reflog muse reflog --all --json
List tracked files in snapshot muse ls-files --json / muse ls-files --path-prefix src/ --json
List branch heads on a remote muse ls-remote --json / muse ls-remote local --json
Inspect snapshot tree structure muse ls-tree --json / muse ls-tree -r HEAD --json
Run scheduled store maintenance muse maintenance run --all --json / muse maintenance status --json
Merge a branch into current muse merge feat/x --format json / muse merge feat/x --dry-run --format json
Find common ancestor of two commits muse merge-base dev feat/x --json / muse merge-base HEAD sha256:<id> --json
Three-way merge without touching workdir muse merge-tree dev feat/x --json / muse merge-tree dev feat/x --write-objects --json
Migrate a Git repo to Muse muse code migrate --source /path/to/repo --json / muse code migrate --source /repo --dry-run --json
Rename a tracked file muse mv src/old.py src/new.py --json / muse mv src/old.py src/new.py --dry-run --json
Map commit IDs to branch-relative names muse name-rev sha256:<id> --json
Render a symbol's life story muse code narrative "file.py::Symbol" --json
Build a pack bundle (dry-run) muse pack-objects HEAD --dry-run --json
Surgical symbol replacement muse code patch "file.py::Symbol" --body /tmp/new.py --json
Compute patch fingerprint muse patch-id --json / muse patch-id HEAD~3 --json
Dry-run plan a merge (conflict prediction) muse plan-merge feat/x --json
Predict merge risk between branches muse predict feat/x dev --json
GC dangling objects muse prune --json / muse prune --dry-run --json
Fetch from a remote muse pull local dev --json
Push branch to remote muse push local dev --json
Query commit history with predicates muse query "author == 'gabriel'" --json
Query symbol change history muse query-history "file.py::Fn" --json
Show diffs between two commit ranges muse range-diff main..feat/a main..feat/b --json
Inspect HEAD commit muse read --json
Inspect HEAD commit + full file list muse read --json --manifest
Inspect a specific commit muse read sha256:<id> --json
Read a commit record by ID muse read-commit sha256:<id> --json
Read a snapshot manifest muse read-snapshot sha256:<id> --json
Replay commits onto a new base muse rebase main --json / muse rebase --squash main --json
Preview rebase commits muse rebase --dry-run main --json
Resume a paused rebase muse rebase --continue --json / muse rebase --abort --json
Inspect in-progress rebase muse rebase --status --json
Create a local release muse release add v1.2.0 --json / muse release add v1.3.0-beta.1 --channel beta --draft --json
List releases muse release list --json / muse release list --channel stable --json
Read a single release muse release read v1.2.0 --json
Infer next version from commit graph muse release suggest --json / muse release suggest --base v1.1.0 --json
Push a release to remote muse release push v1.2.0 --json / muse release push v1.2.0 --dry-run --json
Delete a release label muse release delete v1.2.0 --yes --json / muse release delete v1.2.0 --dry-run --json
List configured remotes muse remote --json
Add a remote muse remote add origin https://musehub.ai/user/repo --json
Get a remote's URL muse remote get-url origin --json
Update a remote's URL muse remote set-url origin https://... --json
Rename a remote muse remote rename origin upstream --json
Remove a remote muse remote remove origin --json
Check remote reachability muse remote status origin --json
AST-level symbol rename muse code rename billing.py::compute_total compute_invoice_total --json --yes
Preview rename without writing muse code rename billing.py::compute_total new_name --dry-run --json
Rename only the definition muse code rename billing.py::compute_total new_name --scope definition --json --yes
Reserve symbol addresses (advisory) muse coord reserve "billing.py::compute_total" --run-id agent-42 --json
Reserve with operation and TTL muse coord reserve "auth.py::validate" --run-id agent-42 --op modify --ttl 7200 --json
Reserve with dependency ordering muse coord reserve "billing.py::Fn" --run-id agent-B --depends-on <uuid> --json
Soft reset (branch pointer only) muse reset HEAD~1 --json
Hard reset (branch + working tree) muse reset HEAD~1 --hard --json
Preview reset without writing muse reset HEAD~3 --dry-run --json
Restore working-tree file from HEAD muse restore a.py --json
Unstage a file (reset stage to HEAD) muse restore --staged a.py --json
Full restore: stage + working tree muse restore --staged --worktree a.py --json
Restore from an arbitrary ref muse restore --source HEAD~3 a.py b.py --json
Stream filtered commit IDs muse rev-list HEAD --json / muse rev-list -n 10 HEAD --json
Count commits in a range muse rev-list --count main..feat --json
Filter by author or date muse rev-list --author alice --after 2026-01-01 HEAD --json
Resolve ref to full commit ID muse rev-parse HEAD --json / muse rev-parse main --json
Get current branch name muse rev-parse --abbrev-ref HEAD --json
Revert a commit (creates new commit) muse revert HEAD --json
Revert to working tree only (no commit) muse revert HEAD --no-commit --json
Preview revert without writing muse revert HEAD --dry-run --json
Remove file from tracking + disk muse rm song.txt --json
Untrack file (keep on disk) muse rm --cached compiled/app.css --json
Recursive untrack of directory muse rm -r --cached build/ --json
Cherry-pick a symbol from a commit muse code semantic-cherry-pick "src/billing.py::compute_total" --from abc123 --json
Cherry-pick multiple symbols muse code semantic-cherry-pick "src/auth.py::validate_token" "src/auth.py::refresh_token" --from feat --json
Preview semantic cherry-pick muse code semantic-cherry-pick "src/core.py::Fn" --from HEAD~5 --dry-run --json
Static symbol-level test coverage muse code semantic-test-coverage --json
Coverage for one file muse code semantic-test-coverage --file billing.py --json
Show only uncovered symbols muse code semantic-test-coverage --uncovered-only --json
CI coverage gate muse code semantic-test-coverage --min-coverage 80 --json
Partition codebase into work zones muse coord shard --agents 4 --json
Shard for a specific language muse coord shard --agents 4 --language Python --json
Shard at a historical commit muse coord shard --agents 8 --commit HEAD~10 --json
Save working-tree checkpoint muse shelf save --json / muse shelf save name --intent-type handoff -m "desc" --json
List all shelf entries muse shelf list --json / muse shelf list --resumable --json
Inspect a shelf entry muse shelf read --json / muse shelf read name --json
Preview what a shelf apply would change muse shelf diff --json / muse shelf diff name --json
Restore shelf entry (keep entry) muse shelf apply --json / muse shelf apply name --json
Restore shelf entry and remove it muse shelf pop --json / muse shelf pop name --json
Discard a shelf entry muse shelf drop --json / muse shelf drop name --json
Commit summary by author muse shortlog --json / muse shortlog --numbered --json
Commit summary by agent muse shortlog --group-by agent --json
Commit summary by model muse shortlog --group-by model --numbered --json
List all branch refs muse show-ref --json / muse show-ref --pattern 'refs/heads/task/*' --json
Check if a ref exists muse show-ref --verify refs/heads/feat/my-task --json
Show HEAD ref muse show-ref --head --json
Count all branches muse show-ref --count --json
Produce an MSign Authorization header muse sign header --method POST --path /owner/repo/push --hub URL --json
Verify an MSign header muse sign verify --header 'MSign ...' --method POST --url URL --public-key-b64 KEY --json
Sign and execute an HTTP request muse sign request --method POST --url URL --body-file payload.json --json
Sign an MPay micropayment muse sign payment --from alice --to bob --amount 1000000 --nonce HEX --json
Capture working-tree checkpoint muse snapshot create --json / muse snapshot create -m "before refactor" --json
List all snapshots muse snapshot list --json / muse snapshot list -n 5 --json
Inspect a snapshot manifest muse snapshot read sha256:abc123 --json
Export snapshot as archive muse snapshot export sha256:abc123 --json / muse snapshot export sha256:abc123 -f zip -o out.zip --json
Diff two snapshots muse snapshot-diff main dev --json / muse snapshot-diff sha256:abc sha256:def --json
Diff — only added files muse snapshot-diff main dev --only added --json
Diff — scope to subdirectory muse snapshot-diff main dev --path-prefix src/ --json
Attach a tag to a commit muse tag add emotion:joyful --json / muse tag add section:chorus HEAD --json
List all tags muse tag list --json / muse tag list --match 'emotion:*' --json
Remove a tag muse tag remove emotion:joyful --json
List all symbols in a file muse code symbols --file src/utils.py --json
List symbols by kind muse code symbols --kind function --json
Read HEAD symbolic ref muse symbolic-ref HEAD --json
Point HEAD at a branch muse symbolic-ref HEAD --set main --json
Track a symbol's full lifecycle muse code symbol-log "file.py::Fn" --json
Symbol log since a tag muse code symbol-log "file.py::Fn" --from v1.0.0 --json
Switch to existing branch muse switch feat --json
Create and switch (with intent) muse switch -c task/x --intent "implement X" --resumable --json
Return to previous branch muse switch - --json
Working-tree status muse status --json / muse status --exit-code --json
Branch + upstream info only muse status --branch --json
Find most stable (unchanged) symbols muse code stable --json / muse code stable --top 20 --json
Stable symbols since a release muse code stable --since v2.0.0 --json
Enable sparse-checkout (cone mode) muse sparse-checkout init --json
Enable sparse-checkout (glob mode) muse sparse-checkout init --no-cone --json
Replace active pattern list muse sparse-checkout set 'src/' 'tests/' --json
Append patterns to sparse config muse sparse-checkout add 'docs/' --json
List active patterns muse sparse-checkout list --json
Count matching vs. excluded files muse sparse-checkout stats --json
Disable sparse-checkout muse sparse-checkout disable --json
Type-health report for HEAD muse code type --json
Trace Any-annotation blast radius muse code type --any-blast-radius billing.py::compute --json
Type coverage trend over commits muse code type --drift --json
Rank untyped symbols by typing ROI muse code type --migration-targets --top 10 --json
Type-signature diff since a ref muse code type --diff HEAD~5 --json
Run tests for changed files muse code test --json
Run one test file python3 -m pytest tests/test_foo.py -q --tb=short
List trusted paths muse trust list --json
Add a trusted path muse trust add /path/to/repo --json
Remove a trusted path muse trust remove /path/to/repo --json
List trusted hub fingerprints muse trust hub-list --json
Reset a hub fingerprint muse trust hub-reset hostname --json
Unpack a MPackBundle from stdin muse unpack-objects --json
Move a branch HEAD (low-level) muse update-ref main sha256:<id> --json
Compare-and-swap branch update muse update-ref main sha256:<new> --old-value sha256:<expected> --json
Symbol growth rate by module muse code velocity --json
Whole-repo integrity check muse verify --json / muse verify --no-objects --json
Verify Ed25519 commit signatures muse verify-commit HEAD --json
Verify stored object integrity muse verify-object --all --json
Verify a MPackBundle muse verify-pack --file bundle.muse --json
Verify tag signatures muse verify-tag v1.0 --json
Stream coordination events muse coord watch --json / muse coord watch --once --json
Add workspace member muse workspace add core https://musehub.ai/acme/core --json
List workspace members muse workspace list --json
Workspace member status muse workspace status --json
Remove workspace member muse workspace remove core --json
Sync workspace members muse workspace sync --workers 8 --json
List worktrees muse worktree list --json
Create linked worktree muse worktree add feat-x feat/x --json
Worktree status muse worktree status feat-x --json
Remove a worktree muse worktree remove feat-x --json
Prune stale worktree records muse worktree prune --json
Repair worktree paths muse worktree repair --json
Rebuild code intelligence indexes muse code index rebuild --json
Index rebuild dry-run muse code index rebuild --dry-run --json
Index status muse code index status --json
Purge indexes muse code index purge --json

Trigger phrases → commands

When you find yourself thinking this… run this instead.

Thought Command
"Let me read the whole file to understand it" muse code symbols --file f.py --json → then muse code cat "f.py::X" --json for the symbol you need
"Where is this function defined?" muse code grep "FunctionName" --json
"I wonder which branch has the latest version" muse code find-symbol "Name" --json
"What would break if I change this?" muse code impact "file.py::Symbol" --json
"What does this file import?" muse code deps "file.py" --json
"Which functions change most often?" muse code hotspots --top 10 --json
"What is the most dangerous symbol to touch?" muse code gravity --top 1 --json
"Are these two files suspiciously coupled?" muse code entangle --json
"Is there dead code I can delete?" muse code dead --high-confidence-only --json
"What tests cover this symbol?" muse code semantic-test-coverage --json
"Is it safe to commit?" muse code breakage --json && muse code test --json

Eight questions, eight commands — do not confuse them

  • muse code grep "X" — find symbols whose name matches X (declarations only)
  • muse code find-symbol "X" — same, but searches across all branches (multi-branch discovery)
  • muse code impact "file.py::X" — find everything that calls or imports X (blast radius)
  • muse code deps "file.py" — find what file.py imports (outbound dependency graph)
  • muse code hotspots — find symbols that change most often (churn leaderboard)
  • muse code gravity — find symbols with the largest downstream blast radius (change risk)
  • muse code entangle — find file pairs that always change together (hidden coupling)
  • muse code dead — find symbols that are never called (safe to delete)

Task-typed rituals

Before modifying a symbol

muse code grep "SymbolName" --json              # confirm declaration location
muse code cat "file.py::Symbol" --json          # read the current body
muse code impact "file.py::Symbol" --json       # map blast radius
muse code semantic-test-coverage --json         # what tests already cover it?

Before a refactor

muse code gravity --top 20 --json               # which symbols carry the most risk?
muse code hotspots --top 20 --json              # which symbols are most volatile?
muse code entangle --json                       # which files move together?
muse code deps "file.py" --json                 # outbound dependency map
muse code breakage --json                       # current structural health

Before deleting a symbol or file

muse code impact "file.py::Symbol" --json       # blast radius — anything still calls it?
muse code dead --high-confidence-only --json    # confirm dead-code classification

Before merging / releasing

muse code breakage --json                       # structural safety gate
muse code test --json                           # tests for what changed
muse code hotspots --top 5 --json               # flag high-churn symbols for review

muse read --json — what the output contains

muse read --json gives commit metadata and a file-level diff (files_added, files_modified, files_removed). It does not include the full snapshot manifest by default.

To get the complete path → object_id map for every tracked file at that commit, add --manifest:

muse read --json --manifest          # HEAD
muse read <ref> --json --manifest    # any commit or branch tip

The manifest key is absent unless --manifest is given — default JSON stays compact.

muse cat vs muse code cat — two different commands

Command Level Use for
muse cat file.py --json File-level Raw file bytes — any domain
muse code cat "file.py::Symbol" --json Symbol-level One function/class body
muse code cat "file.py" --all --json Symbol-level All symbols in a file

muse cat accepts --at <branch|sha> for historical reads. muse code cat accepts --at too.


Gitism Glossary

Every wrong pattern on the left is burned into agent training data from Git.

JSON key names

Git term / wrong key Muse JSON key Location
sha / hash / id commit_id everywhere
msg / commit_message message muse log, muse read
date / timestamp / time committed_at muse log, muse read
parent parent_commit_id muse log, muse read
entries / log / data commits muse log
active / checked_out current muse branch
branch_name name muse branch list entries
index as integer string keys "1", "2" muse code impact blast_radius
callers / caller_list blast_radius["1"] muse code impact
coverage coverage_pct muse code semantic-test-coverage
churn changes muse code hotspots
score / risk_score gravity_pct muse code gravity
files (combined) added + modified + deleted muse diff, muse status
muse log top-level { "truncated": bool, "commits": [...] } muse log --json
muse branch top-level a list — no wrapper key muse branch --json
muse hub repo list top-level { "total": N, "next_cursor": null, "repos": [...] } muse hub repo list --json
blast_radius key type strings "1" "2" — not integers muse code impact

Deletion muscle memory — git rmmuse rm

Git has two patterns for staging a file deletion. Both have exact Muse equivalents:

Git reflex Muse equivalent Effect
git rm <file> muse rm <file> delete from disk and stage deletion
git rm --cached <file> muse rm --cached <file> stage deletion only (keep on disk)
git rm -r <dir> muse rm -r <dir> recursive — required for directories
git add <deleted-path> muse code add <deleted-path> stage deletion of already-deleted file
git add -u muse code add -u stage all tracked changes incl. deletions
git add . muse code add . stage all tracked changes incl. deletions

The wrong reflex that burns agents: reaching for muse code add --deleted (flag doesn't exist) or muse code reset <file> (that unstages — the opposite of what you want).

Rule: deleting a file in a task? Use muse rm <file> — it does the rm and stages the deletion in one step. muse code add <path> also works if the file is already gone from disk, but muse rm is clearer intent.

muse status --json — always the same shape

The schema is identical regardless of domain or staging state. Every key is always present — no dict.get guards needed.

{
  "branch":             "dev",
  "head_commit":        "sha256:abc…",
  "upstream":           null,
  "ahead":              null,
  "behind":             null,
  "clean":              true,
  "dirty":              false,
  "total_changes":      0,
  "added":              [],
  "modified":           [],
  "deleted":            [],
  "renamed":            {},
  "staged":             {"added": [], "modified": [], "deleted": []},
  "unstaged":           {"added": [], "modified": [], "deleted": []},
  "untracked":          [],
  "conflict_paths":     [],
  "merge_in_progress":  false,
  "merge_from":         null,
  "conflict_count":     0,
  "checkout_interrupted": false,
  "checkout_target":    null
}

Key rules:

  • added / modified / deleted — flat union of staged + unstaged. Primary interface for "what changed".
  • staged / unstaged{added, modified, deleted} sub-objects for staging detail. null for domains with no staging concept (non-code domains).
  • untracked — files on disk not tracked by Muse. Non-empty list makes clean=false.
  • cleantrue only when no staged changes, no unstaged changes, and no untracked files. Matches git: "untracked files present" is not a clean working tree.
  • dirty — always not clean.

Git muscle-memory traps for muse status --json:

Git reflex What Muse actually has
data["index"] or data["worktree"] (git status --porcelain=v2) data["staged"] / data["unstaged"]
"untracked" in data as a flag data["untracked"] is always a list
data["staged"] is a path→object map data["staged"] is {added, modified, deleted} lists
dirty means only tracked-content changes dirty is also true when untracked files exist

Hub command shape — noun then verb, not verb-noun

Git flattens everything to git <verb> or gh <verb>-<noun>. Muse uses muse hub <noun> <verb>. The wrong reflex produces commands that don't exist.

Wrong reflex (git/gh pattern) Correct Muse command
muse hub delete-repo muse hub repo delete
muse hub create-repo muse hub repo create
muse hub list-repos muse hub repo list
muse hub show-repo muse hub repo read
muse hub get-repo muse hub repo read
muse hub update-repo muse hub repo update
muse hub transfer-repo muse hub repo transfer-ownership
muse hub create-issue muse hub issue create
muse hub list-issues muse hub issue list
muse hub show-issue muse hub issue read
muse hub get-issue muse hub issue read
muse hub close-issue muse hub issue update <n> --status closed
muse hub reopen-issue muse hub issue update <n> --status open
muse hub comment-issue muse hub issue comment <n> --body "..."
muse hub assign-issue muse hub issue assign <n> --assignee <handle>
muse hub label-issue muse hub issue label <n> --set <label>
muse hub create-proposal muse hub proposal create
muse hub merge-proposal muse hub proposal merge
muse hub list-proposals muse hub proposal list
muse hub show-proposal muse hub proposal read
muse hub get-proposal muse hub proposal read
muse hub review-proposal muse hub proposal review submit --verdict approve
muse hub request-reviewer muse hub proposal reviewer request <id> <handle>
muse hub add-label muse hub label create
muse hub list-labels muse hub label list
muse hub delete-label muse hub label delete --name <name>
muse hub add-collaborator muse hub collaborator invite <handle>
muse hub list-collaborators muse hub collaborator list
muse hub remove-collaborator muse hub collaborator remove <handle>
muse hub create-webhook muse hub webhook create --url <url> --events push
muse hub list-webhooks muse hub webhook list
muse hub delete-webhook muse hub webhook delete <webhook-id>
muse hub create-release muse hub release create --tag v1.0.0
muse hub list-releases muse hub release list
muse hub get-release muse hub release read <tag>
muse hub delete-release muse hub release delete <tag>
muse hub fork-repo muse hub fork create --repo owner/repo
muse hub list-forks muse hub fork list --repo owner/repo
muse hub get-user muse hub user read <handle>
muse hub update-user muse hub user update <handle> --bio "..."
muse hub list-topics muse hub topic list
muse hub set-topics muse hub topic set --topic jazz --topic midi

Always check muse hub <noun> --help when unsure — the subcommand tree is the canonical reference, not any git/gh mental model.

muse hub — full command reference

Every command returns a JSON envelope with muse_version, schema, exit_code, duration_ms, timestamp, warnings plus domain fields. Always pipe --json output through jq or Python — never parse text.

Connection

muse hub connect --hub https://localhost:1337 --json
muse hub status --json
muse hub ping --json
muse hub disconnect --json

Repos

muse hub repo create --name muse --visibility public --json
muse hub repo list --json | jq '.repos[].slug'
muse hub repo read --json                          # reads current repo
muse hub repo update --description "new desc" --json
muse hub repo delete --json
muse hub repo transfer-ownership --to carol --json

Proposals (= pull requests)

muse hub proposal create --title "feat: x" --from-branch feat/x --json
muse hub proposal list --state open --json | jq '.proposals[].proposalId'
muse hub proposal read af54753d --json
muse hub proposal merge af54753d --strategy squash --json
muse hub proposal comment create af54753d --body "LGTM" --json
muse hub proposal comment list af54753d --json
muse hub proposal reviewer request af54753d alice --json
muse hub proposal reviewer remove af54753d alice --json
muse hub proposal review list af54753d --json
muse hub proposal review submit af54753d --verdict approve --json

Issues

muse hub issue create --title "bug: crash" --label bug --json
muse hub issue list --state open --json | jq '.issues[].number'
muse hub issue read 42 --json
muse hub issue update 42 --status closed --json
muse hub issue close 42 --json
muse hub issue reopen 42 --json
muse hub issue comment 42 --body "Fixed in abc" --json
muse hub issue comment-list 42 --json
muse hub issue comment-delete 42 --comment-id <uuid> --json
muse hub issue assign 42 --assignee gabriel --json
muse hub issue label 42 --set bug enhancement --json

Labels

muse hub label create --name bug --color '#d73a4a' --json
muse hub label list --json | jq '.labels[].name'
muse hub label update --name bug --new-color '#b60205' --json
muse hub label delete --name obsolete --json

Collaborators

muse hub collaborator list --json
muse hub collaborator invite carol --permission write --json
muse hub collaborator update-permission carol --permission admin --json
muse hub collaborator remove carol --json

Webhooks

muse hub webhook create --url https://ci.example.com/hook --events push --json
muse hub webhook list --json
muse hub webhook delete <webhook-id> --json
muse hub webhook delivery-list --webhook-id <uuid> --json
muse hub webhook redeliver --webhook-id <uuid> --delivery-id <uuid> --json

Releases

muse hub release create --tag v1.0.0 --title "First release" --json
muse hub release list --json | jq '.releases[].tag'
muse hub release read v1.0.0 --json
muse hub release delete v1.0.0 --json
muse hub release asset-list v1.0.0 --json
muse hub release asset-attach v1.0.0 --name track.mid --url <url> --json
muse hub release asset-delete v1.0.0 --asset-id <uuid> --json

Users, topics, forks

muse hub user read gabriel --json
muse hub user update gabriel --bio "Composer" --json
muse hub topic list --query jazz --json
muse hub topic set --topic jazz --topic midi --json
muse hub fork create --repo gabriel/muse --json
muse hub fork list --repo gabriel/muse --json

git stashmuse shelf

Git's stash is delta-based and unnamed. Muse shelf is snapshot-based, content-addressed, and optionally named. Every subcommand maps directly:

Git reflex Muse equivalent Notes
git stash muse shelf save Shelves all tracked changes
git stash push -m "msg" muse shelf save -m "msg" Named shelf entry
git stash pop muse shelf pop Restore + drop most recent entry
git stash list muse shelf list --json All entries; structured output
git stash drop muse shelf drop Delete most recent without restoring
git stash show muse shelf show --json Inspect the top entry
git stash apply stash@{n} muse shelf pop --index <n> Restore by index

Rule: never reach for stash as a verb or concept — it is a Gitism. Use shelf / shelve / shelved in all code, comments, and docs.

File History 4 commits
sha256:b636f72dcba9e190afb980bece906fa5b717fbde014b76ef023df8cb96e01eb9 docs: expand cache plan with all seven testing tiers and do… Sonnet 4.6 131 days ago
sha256:7f9e2ef5286aedad9c1e6011b4c46ca27f39dbdad6e3409357e36b26e46b3b7c docs: docstring sprint for-each-ref→hotspots — idiomatic ru… Sonnet 4.6 patch 137 days ago
sha256:88ac91129873e6a496e9189515aa690eb893ae25d69c8f72af141a2be5068eb3 docs: docstring sprint contract→find-symbol — idiomatic run… Sonnet 4.6 patch 137 days ago
sha256:a09b1b4f6838754495547f200aa0ce88e2f56ffc5b20b900f6f0cff2c3cdede9 fix(cursorignore): remove git-ism (.git/worktrees) Human minor 140 days ago