Code Domain — Complete Reference
Engine:
muse/plugins/code/· No external deps for core analysis Scope: Every command, module, type, and protocol in the code domain plugin
Overview
The code domain plugin treats a codebase as a typed, content-addressed symbol graph — not as a bag of text lines. Every function, class, method, variable, and import becomes a SymbolRecord with a stable content-addressed identity (SHA-256). This unlocks operations that are structurally impossible in Git:
- Track a function through renames and cross-file moves with perfect identity.
- Cherry-pick a single named function out of a historical commit.
- Detect exact and near-duplicate code across an entire snapshot in O(1).
- Predict merge conflicts before writing a single byte.
- Enforce architectural invariants as committed rules.
- Assign semantic version bumps automatically at commit time.
- Coordinate thousands of parallel agents without a central lock server.
Contents
- Selective Staging (
muse code add) - Symbol Identity Model
- Provenance & Topology Commands
- Query & Temporal Search
- Index Infrastructure
- Symbol Identity Detail
- Multi-Agent Coordination Layer
- Merge Engine & Architectural Enforcement
- Semantic Versioning
- Call-Graph Tier Commands
- Architecture Internals
- Type Reference
1. Selective Staging (muse code add)
The code domain adds a Git-style staging index to Muse. By default,
muse commit snapshots the entire working tree. Once you run muse code add,
the next commit includes only what you have explicitly staged — everything
else carries forward from the previous commit unchanged.
This lets you commit a coherent, working subset of your in-progress changes without committing half-finished code.
Stage index location
.muse/code/stage.json — a JSON file that maps workspace-relative paths to
their staged object IDs and mode (A added / M modified / D deleted`).
muse code add
muse code add <file> [<file> …] # stage one or more files
muse code add <dir> # stage every file under a directory
muse code add . # stage everything in the working tree
muse code add -A / --all # stage all changes, including new files
muse code add -u / --update # stage only tracked (already-committed) files
# modified or deleted on disk — no new files
muse code add -p / --patch <file> # interactive hunk-by-hunk staging
muse code add -n / --dry-run … # show what would be staged without staging
muse code add -v / --verbose … # print each file as it is staged
Patch mode (-p)
Interactive hunk-by-hunk staging, mirroring git add -p. For each diff
hunk you are prompted:
| Key | Action |
|---|---|
y |
Stage this hunk |
n |
Skip this hunk |
q |
Quit; commit hunks accepted so far |
a |
Stage this and all remaining hunks in this file |
d |
Skip the rest of this file |
? |
Show help |
The partial file (accepted hunks only) is hashed, written to the object store, and recorded in the stage index. The working tree is never modified.
Agents should use explicit file paths (muse code add <file>) and avoid
--patch, which requires an interactive terminal.
muse code reset
muse code reset # unstage everything
muse code reset <file> # unstage a specific file
muse code reset HEAD <file> # same — mirrors Git syntax
Removes files from the stage index without touching the working tree. The working tree copy is always preserved.
muse commit with an active stage
When .muse/code/stage.json exists and is non-empty:
- Staged files → committed at their staged object ID.
- Tracked-but-unstaged files → carried forward at their committed (HEAD) object ID.
- Untracked files → not included in the commit.
After a successful commit the stage index is cleared automatically.
muse status with an active stage
When a stage is active, muse status renders a three-bucket view:
On branch main
Changes staged for commit:
(use "muse code reset HEAD <file>" to unstage)
new file: src/auth.py
modified: src/models.py
Changes not staged for commit:
(use "muse code add <file>" to update what will be committed)
modified: src/broken_wip.py
Untracked files:
(use "muse code add <file>" to include in what will be committed)
tmp_experiment.py
With --format json:
{
"branch": "main",
"clean": false,
"staged": {
"src/auth.py": {"mode": "A", "object_id": "<sha256>"}
},
"unstaged": {
"src/broken_wip.py": "modified"
},
"untracked": ["tmp_experiment.py"]
}
Workflow example
# Edit freely — nothing is committed until you stage.
vim src/auth.py src/models.py src/wip.py
# Stage only the production-ready files.
muse code add src/auth.py src/models.py
# Verify what will be committed.
muse status
# Commit exactly what was staged.
muse commit -m "feat: add auth + models"
# The working-tree copy of wip.py is untouched.
2. Symbol Identity Model
Every symbol carries four content-addressed hashes and two stable keys:
| Field | Description |
|---|---|
content_id |
SHA-256 of the full normalized AST (signature + body + metadata). Two symbols are identical iff their content_id matches. |
body_hash |
SHA-256 of the function/class body only (excluding signature and decorators). Matches across renames and decorator changes. |
signature_id |
SHA-256 of the normalized parameter list and return annotation. Matches across implementation-only changes. |
metadata_id (v2) |
SHA-256 of decorator list + async flag + base classes. Matches when only the implementation or signature changed. |
canonical_key (v2) |
{file}#{scope}#{kind}#{name}#{lineno} — stable machine handle for agent-to-agent symbol handoff. |
qualified_name |
Dotted path within the file (e.g. MyClass.my_method). |
Exact Refactor Classification
Two symbols are classified by comparing their four hashes:
| Classification | Condition |
|---|---|
unchanged |
content_id matches |
rename |
body_hash matches, name differs, same file |
move |
content_id matches, different file, same name |
rename+move |
body_hash matches, different file, different name |
signature_only |
body_hash matches, signature_id differs |
impl_only |
signature_id matches, body_hash differs |
metadata_only |
body_hash + signature_id match, metadata_id differs |
full_rewrite |
Both signature and body changed |
3. Provenance & Topology Commands
muse code lineage ADDRESS
Full provenance chain of a named symbol from its first appearance to the present.
muse code lineage src/billing.py::compute_total
muse code lineage src/billing.py::compute_total --commit HEAD~10
muse code lineage src/billing.py::compute_total --json
How it works: Walks all commits in chronological order, scanning InsertOp/DeleteOp/ReplaceOp entries in each structured_delta. Rename detection uses content_id matching across Insert+Delete pairs within a single commit.
Output events: created, modified, renamed_from, moved_from, deleted.
Flags:
--commit REF— stop history walk at this commit (default: HEAD)--json— emit a JSON array of event objects
JSON schema:
[
{
"event": "created",
"commit_id": "a1b2c3d4...",
"committed_at": "2026-01-01T00:00:00+00:00",
"message": "Initial commit",
"address": "src/billing.py::compute_total",
"content_id": "sha256..."
}
]
muse code api-surface
Public API surface of a snapshot — every non-underscore function, class, and method.
muse code api-surface
muse code api-surface --commit v1.0
muse code api-surface --diff v1.0
muse code api-surface --json
With --diff REF: Shows three sections — Added (new public symbols), Removed (deleted public symbols), Changed (same address, different content_id).
Public means: kind in {function, class, method, async_function} and name not starting with _.
muse code codemap
Semantic topology of the entire codebase at a snapshot.
muse code codemap
muse code codemap --top 10
muse code codemap --commit HEAD~5
muse code codemap --json
What it shows:
- Modules by size — ranked by symbol count
- Import graph — in-degree (how many modules import this one)
- Cycles — import cycles detected via DFS (a hard architectural smell)
- High-centrality symbols — functions called from many places (blast-radius risk)
- Boundary files — high fan-out (imports many), zero fan-in (nothing imports them)
Flags:
--top N— show top N entries per section (default: 5)--commit REF— snapshot to analyse--json— structured output
muse code clones
Find exact and near-duplicate symbol clusters across the snapshot.
muse code clones
muse code clones --tier exact
muse code clones --tier near
muse code clones --tier both
muse code clones --commit HEAD~3 --json
Exact clones: Same body_hash at different addresses. These are literal copy-paste duplicates — same implementation, possibly different name.
Near-clones: Same signature_id, different body_hash. Same public contract (parameters + return type), diverged implementation — a maintainability risk.
Output: Clusters, one per group, listing all member addresses.
muse code checkout-symbol ADDRESS --commit REF
Restore a single named symbol from a historical commit into the current working tree. Only the target symbol's lines change; everything else is untouched.
muse code checkout-symbol src/billing.py::compute_total --commit v1.0
muse code checkout-symbol src/billing.py::compute_total --commit abc123 --dry-run
muse code checkout-symbol src/billing.py::compute_total --commit v1.0 --json
Flags:
--commit REF(required) — source commit--dry-run— print the unified diff without writing--json— emit result as JSON for agent consumption
JSON output:
{
"address": "src/billing.py::compute_total",
"file": "src/billing.py",
"restored_from": "abc12345",
"dry_run": false
}
Safety: Rejects the operation if the target file cannot be parsed (syntax error) or if the symbol no longer exists at the destination location and the file cannot be safely patched.
Security: The file path component of ADDRESS is validated via contain_path() before any disk access. Paths that escape the repo root (e.g. ../../etc/passwd::foo) are rejected with exit 1.
muse code semantic-cherry-pick ADDRESS... --from REF
Cherry-pick one or more named symbols from a historical commit. Applies each symbol patch to the working tree at the symbol's current location; appends at the end of the file if the symbol is not present in the current tree.
muse code semantic-cherry-pick src/billing.py::compute_total --from v1.0
muse code semantic-cherry-pick src/billing.py::f1 src/billing.py::f2 --from abc123
muse code semantic-cherry-pick src/billing.py::compute_total --from v1.0 --dry-run --json
Flags:
--from REF(required) — source commit--dry-run— show what would change without writing--json— structured output with per-symbol patch results
JSON output:
{
"from_commit": "abc12345",
"dry_run": false,
"results": [
{"address": "src/billing.py::compute_total", "status": "applied",
"detail": "lines 10–25 → 12 lines", "old_lines": 16, "new_lines": 12}
],
"applied": 1,
"failed": 0,
"already_current": 0
}
Security: Every file path extracted from ADDRESS arguments is validated via contain_path() before any disk I/O or directory creation. Paths that escape the repo root are recorded as not_found and the remaining symbols continue to be processed.
4. Query & Temporal Search
muse code query PREDICATE...
Symbol graph predicate DSL — SQL for your codebase.
muse code query kind=function language=Python
muse code query "(kind=function OR kind=method) name^=_"
muse code query "NOT kind=import file~=billing"
muse code query kind=function name~=validate --all-commits
muse code query hash=a3f2c9 --all-commits --first
muse code query --commit v1.0 kind=class
muse code query kind=function --json
Predicate Grammar (v2)
expr = or_expr
or_expr = and_expr ( "OR" and_expr )*
and_expr = not_expr ( and_expr )* # implicit AND
not_expr = "NOT" primary | primary
primary = "(" expr ")" | atom
atom = KEY OP VALUE
Operators
| Operator | Meaning |
|---|---|
= |
Exact match (case-insensitive for strings) |
~= |
Contains substring |
^= |
Starts with |
$= |
Ends with |
!= |
Not equal |
>= |
Greater than or equal (lineno keys only) |
<= |
Less than or equal (lineno keys only) |
Keys
| Key | Type | Description |
|---|---|---|
kind |
string | function, class, method, variable, import, … |
language |
string | Python, Go, Rust, TypeScript, … |
name |
string | Bare symbol name |
qualified_name |
string | Dotted qualified name (e.g. MyClass.save) |
file |
string | File path (relative to repo root) |
hash |
string | content_id prefix (hex) |
body_hash |
string | body_hash prefix |
signature_id |
string | signature_id prefix |
lineno_gt |
integer | Symbol starts after this line number |
lineno_lt |
integer | Symbol starts before this line number |
Flags
| Flag | Description |
|---|---|
--commit REF |
Query a specific commit (mutually exclusive with --all-commits) |
--all-commits |
Walk all commits, deduplicate by content_id, annotate first-seen commit |
--first |
With --all-commits: keep only the first appearance of each unique body |
--json |
JSON output with schema_version: 2 wrapper |
muse code query-history PREDICATE... [--from REF] [--to REF]
Temporal symbol search — track matching symbols across a commit range.
muse code query-history kind=function language=Python
muse code query-history name~=validate --from v1.0 --to HEAD
muse code query-history kind=class --json
Output: For each matching symbol address, reports first_seen, last_seen, commit_count (how many commits touched it), and change_count (how many times its content_id changed).
JSON schema:
{
"schema_version": 2,
"query": "kind=function language=Python",
"from_ref": "v1.0",
"to_ref": "HEAD",
"results": [
{
"address": "src/billing.py::compute_total",
"first_seen": "commit_id...",
"last_seen": "commit_id...",
"commit_count": 12,
"change_count": 3
}
]
}
5. Index Infrastructure
muse code index status
Show present/absent/corrupt status and entry counts for all local indexes.
muse code index status
muse code index status --json
Flags:
--json— emit status array as JSON
JSON output:
[
{"name": "symbol_history", "status": "present", "entries": 1024, "updated_at": "2026-03-21T12:00:00"},
{"name": "hash_occurrence", "status": "absent", "entries": 0, "updated_at": null}
]
muse code index rebuild
Rebuild one or all indexes by walking the full commit history.
muse code index rebuild
muse code index rebuild --json
muse code index rebuild --index symbol_history
muse code index rebuild --index hash_occurrence --verbose
Flags:
--index NAME— rebuild only this index (default: all)--verbose, -v— show progress while building--json— emit rebuild summary as JSON
JSON output:
{
"rebuilt": ["symbol_history", "hash_occurrence"],
"symbol_history_addresses": 512,
"symbol_history_events": 2048,
"hash_occurrence_clusters": 31,
"hash_occurrence_addresses": 87
}
Index Design
Indexes live under .muse/indices/ and are:
- Derived — computed entirely from the commit history.
- Optional — no command requires them for correctness; they only provide speed.
- Fully rebuildable —
muse code index rebuildreconstructs them from scratch in one pass. - Versioned —
schema_versionfield for forward compatibility.
symbol_history index
Maps symbol_address → list[HistoryEntry] (chronological). Enables O(1) lineage lookups instead of O(commits × files) scans.
hash_occurrence index
Maps body_hash → list[symbol_address]. Enables O(1) clone detection and muse code find-symbol hash= queries.
6. Symbol Identity Detail
New SymbolRecord fields
SymbolRecord gains two backward-compatible fields (empty string "" for pre-v2 records):
metadata_id
: SHA-256 of the symbol's metadata wrapper — decorators + async flag for Python functions, decorator list + base classes for Python classes. Allows distinguishing a decorator change from a body change.
canonical_key
: {file}#{scope}#{kind}#{name}#{lineno} — a stable, unique machine handle for a symbol within a snapshot. Enables agent-to-agent symbol handoff without re-querying. Disambiguates overloaded names and nested scopes.
muse code detect-refactor (v2 output)
With --json, emits schema_version: 2 with a richer classification:
{
"schema_version": 2,
"from_commit": "abc...",
"to_commit": "def...",
"total": 3,
"events": [
{
"old_address": "src/billing.py::compute_total",
"new_address": "src/billing.py::compute_invoice_total",
"old_kind": "function",
"new_kind": "function",
"exact_classification": "rename",
"inferred_refactor": "none",
"confidence": 1.0,
"evidence": ["body_hash matches a1b2c3d4"],
"old_content_id": "ab12cd34",
"new_content_id": "ef56gh78",
"old_body_hash": "a1b2c3d4",
"new_body_hash": "a1b2c3d4"
}
]
}
exact_classification values: rename, move, rename+move, signature_only, impl_only, metadata_only, full_rewrite, unchanged.
inferred_refactor values: extract, inline, split, merge, none.
7. Multi-Agent Coordination Layer
The coordination layer enables thousands of agents to work on the same codebase simultaneously without stepping on each other. It is purely advisory — the VCS engine never reads coordination data for correctness decisions. Agents that ignore it still produce correct commits.
Storage Layout
.muse/coordination/
reservations/<id>.json advisory symbol lease
intents/<id>.json declared operation before edit
All records are write-once (never mutated) and use TTL-based expiry. Expired records are kept for audit purposes but ignored by all commands.
muse coord reserve ADDRESS... [OPTIONS]
Announce intent to edit one or more symbol addresses.
muse coord reserve src/billing.py::compute_total
muse coord reserve src/billing.py::f1 src/billing.py::f2 --run-id agent-007 --ttl 7200
muse coord reserve src/billing.py::compute_total --op rename
muse coord reserve src/billing.py::compute_total --json
Flags:
--run-id ID— identifier for this agent/run (default: random hex string)--ttl SECONDS— reservation expiry in seconds (default: 3600)--op OPERATION— declared operation:rename,move,extract,modify,delete--json— JSON output
Conflict detection: Warns (but never blocks) if any of the requested addresses are already reserved by another active reservation.
Reservation schema (v1):
{
"schema_version": 1,
"reservation_id": "sha256:<hex>",
"run_id": "<agent-supplied ID>",
"branch": "<current branch>",
"addresses": ["src/billing.py::compute_total"],
"created_at": "2026-03-18T12:00:00+00:00",
"expires_at": "2026-03-18T13:00:00+00:00",
"operation": "rename"
}
muse coord intent ADDRESS... --op OPERATION [OPTIONS]
Declare a specific operation before executing it. More precise than a reservation; enables muse coord forecast to produce accurate conflict predictions.
muse coord intent src/billing.py::compute_total --op rename --detail "rename to compute_invoice_total"
muse coord intent src/billing.py::compute_total --op modify --reservation-id <id>
Flags:
--op OPERATION(required) —rename,move,extract,modify,delete,refactor--detail TEXT— free-text description of the planned change--reservation-id ID— link to an existing reservation--run-id ID— agent identifier--json— JSON output
Intent schema (v1):
{
"schema_version": 1,
"intent_id": "sha256:<hex>",
"reservation_id": "sha256:<hex> or empty",
"run_id": "<agent ID>",
"branch": "<current branch>",
"addresses": ["src/billing.py::compute_total"],
"operation": "rename",
"created_at": "2026-03-18T12:00:00+00:00",
"detail": "rename to compute_invoice_total"
}
muse coord forecast [OPTIONS]
Predict merge conflicts from active reservations and intents — before writing any code.
muse coord forecast
muse coord forecast --branch feature-x
muse coord forecast --json
Conflict types detected:
| Type | Confidence | Condition |
|---|---|---|
address_overlap |
1.0 | Two reservations on the same symbol address |
blast_radius_overlap |
0.75 | Reservations on symbols that call each other (via call graph) |
operation_conflict |
0.9 | Two reservations declare incompatible operations (e.g. both rename) |
Flags:
--branch BRANCH— restrict to reservations on this branch--json— structured conflict list
muse coord plan-merge OURS THEIRS [OPTIONS]
Dry-run semantic merge plan — classify all symbol conflicts without writing anything.
muse coord plan-merge main feature-x
muse coord plan-merge HEAD~5 HEAD --json
Output: Classifies each diverging symbol into one of:
no_conflict— diverged in disjoint symbolssymbol_edit_overlap— both sides modified the same symbolrename_edit— one side renamed, the other modifieddelete_use— one side deleted a symbol still used by the other
Flags:
--json— structured output with full classification details
muse coord shard --agents N [OPTIONS]
Partition the codebase into N low-coupling work zones for parallel agent assignment.
muse coord shard --agents 4
muse coord shard --agents 8 --language Python
muse coord shard --agents 4 --json
Algorithm: Builds the import graph, finds connected components, greedily merges small components into N balanced shards (by symbol count). Reports cross-shard edges as a coupling score (lower is better).
Flags:
--agents N(required) — number of shards--language LANG— restrict to files of this language--json— shard assignments as JSON
muse coord reconcile [OPTIONS]
Recommend merge ordering and integration strategy from the current coordination state.
muse coord reconcile
muse coord reconcile --json
Output: For each active branch with reservations, recommends:
- Merge order — branches with fewer predicted conflicts should merge first
- Integration strategy —
fast-forward,rebase, ormanual(when conflicts are predicted) - Conflict hotspots — addresses that appear in the most reservations
8. Merge Engine & Architectural Enforcement
ConflictRecord — Structured Conflict Taxonomy
MergeResult now carries conflict_records: list[ConflictRecord] alongside the existing conflicts: list[str]. Each ConflictRecord provides structured metadata for programmatic conflict handling:
@dataclass
class ConflictRecord:
path: str
conflict_type: str = "file_level" # see taxonomy below
ours_summary: str = ""
theirs_summary: str = ""
addresses: list[str] = field(default_factory=list)
conflict_type taxonomy:
| Value | Meaning |
|---|---|
symbol_edit_overlap |
Both branches modified the same symbol |
rename_edit |
One branch renamed, the other modified |
move_edit |
One branch moved, the other modified |
delete_use |
One branch deleted a symbol still used by the other |
dependency_conflict |
Conflicting changes to interdependent symbols |
file_level |
Legacy — no symbol-level information available |
muse code breakage
Detect symbol-level structural breakage in the current working tree vs HEAD.
muse code breakage
muse code breakage --language Python
muse code breakage --json
Checks performed:
stale_import— afrom X import YwhereYno longer exists in the committed version ofX(detected via symbol graph, not execution).missing_interface_method— a class body is missing a method that exists in the HEAD snapshot's version of that class.
What it does NOT do: Execute code, install packages, run mypy or a type checker, or access the network. Pure structural analysis.
JSON output:
{
"breakage_count": 2,
"issues": [
{
"issue_type": "stale_import",
"file": "src/billing.py",
"description": "imports compute_total from src/utils.py but compute_total was removed"
}
]
}
muse code invariants
Enforce architectural rules declared in .muse/invariants.toml.
muse code invariants
muse code invariants --commit HEAD~5
muse code invariants --json
Rule types:
no_cycles
[[rules]]
type = "no_cycles"
name = "no import cycles"
The import graph must be a DAG. Reports every cycle as a violation.
forbidden_dependency
[[rules]]
type = "forbidden_dependency"
name = "core must not import cli"
source_pattern = "muse/core/"
forbidden_pattern = "muse/cli/"
Files matching source_pattern must not import from files matching forbidden_pattern.
layer_boundary
[[rules]]
type = "layer_boundary"
name = "plugins must not import from cli"
lower = "muse/plugins/"
upper = "muse/cli/"
Files in lower must not import from files in upper (enforces layered architecture).
required_test
[[rules]]
type = "required_test"
name = "all billing functions must have tests"
source_pattern = "src/billing.py"
test_pattern = "tests/test_billing.py"
Every public function in source_pattern must have a corresponding test function in test_pattern (matched by bare name).
Bootstrapping: If .muse/invariants.toml does not exist, muse code invariants creates it with a commented template and exits with a guided onboarding message.
9. Semantic Versioning
Muse automatically assigns semantic version bumps at commit time based on the StructuredDelta.
SemVerBump
SemVerBump = Literal["major", "minor", "patch", "none"]
Inference rules (infer_sem_ver_bump)
| Change type | Bump | Breaking? |
|---|---|---|
| Delete a public symbol | major |
yes — address added to breaking_changes |
| Rename a public symbol | major |
yes — old address added to breaking_changes |
signature_only change |
major |
yes — callers may break |
| Insert a new public symbol | minor |
no |
impl_only change (body only) |
patch |
no |
metadata_only change |
none |
no |
| Formatting-only change | none |
no |
| Non-public symbol changes | patch or none |
no |
Public = name does not start with _ and kind is function, class, method, or async_function.
Storage
Both StructuredDelta and CommitRecord carry:
sem_ver_bump: SemVerBump(default"none")breaking_changes: list[str](default[])
These fields are backward-compatible — pre-v2 commits read as "none" / [].
muse log display
When a commit's sem_ver_bump is non-none, long-form muse log output appends:
SemVer: MAJOR
Breaking: src/billing.py::compute_total, src/billing.py::Invoice (+2 more)
10. Call-Graph Tier Commands
muse code impact ADDRESS [OPTIONS]
Transitive blast-radius analysis — what else breaks if this function changes?
muse code impact src/billing.py::compute_total
muse code impact src/billing.py::compute_total --commit HEAD~5
muse code impact src/billing.py::compute_total --json
Algorithm: BFS over the reverse call graph (Python only via ast). Traverses until the transitive closure is exhausted, annotating each affected symbol with its depth.
Risk levels: 🟢 (0–2 callers), 🟡 (3–9 callers), 🔴 (10+ callers).
muse code dead [OPTIONS]
Dead code detection — symbols with no callers and no importers.
muse code dead
muse code dead --kind function
muse code dead --exclude-tests
muse code dead --json
Detection logic: A symbol is a dead-code candidate when:
- Its bare name appears in no
ast.Callnode in the snapshot and - Its module is not imported anywhere in the snapshot.
Distinction: definite_dead (module never imported) vs soft_dead (module imported but function never called directly).
muse code coverage CLASS_ADDRESS [OPTIONS]
Class interface call-coverage — which methods of a class are actually called?
muse code coverage src/billing.py::Invoice
muse code coverage src/billing.py::Invoice --show-callers
muse code coverage src/billing.py::Invoice --json
Output: Lists every method of the class, marks which ones appear in ast.Call nodes anywhere in the snapshot, and prints a coverage percentage. No test suite required.
muse code deps ADDRESS_OR_FILE [OPTIONS]
Import graph + call-graph analysis.
muse code deps src/billing.py
muse code deps src/billing.py --reverse
muse code deps src/billing.py::compute_total
muse code deps src/billing.py::compute_total --reverse
muse code deps src/billing.py --commit v1.0 --json
File mode: Lists all import-kind symbols from the file (what does it import?). With --reverse: which other files import this one.
Symbol mode (address contains ::): Python-only call extraction — which functions does this function call? With --reverse: which functions call this one.
muse code find-symbol [OPTIONS]
Cross-commit, cross-branch symbol search by hash, name, or kind.
muse code find-symbol --hash a3f2c9
muse code find-symbol --name compute_total
muse code find-symbol --name compute_* --kind function
muse code find-symbol --hash a3f2c9 --all-branches --first
muse code find-symbol --name validate --json
Flags:
--hash HEX— matchcontent_idprefix (exact body match across history)--name NAME— exact name or prefix glob with*--kind KIND— restrict to symbol kind--all-branches— also scan all branch tips in.muse/refs/heads/--first— deduplicate oncontent_id, keeping only the first appearance--json— structured output
muse code patch ADDRESS SOURCE [OPTIONS]
Surgical semantic patch — replace exactly one named symbol in the working tree.
muse code patch src/billing.py::compute_total new_impl.py
echo "def compute_total(x): return x * 2" | muse code patch src/billing.py::compute_total -
muse code patch src/billing.py::compute_total new_impl.py --dry-run
muse code patch src/billing.py::compute_total new_impl.py --json
Syntax validation: Before writing, validates the replacement source with:
ast.parsefor Pythontree-sitterCST error-node check for all 11 supported languages
Rejects the patch and exits non-zero if the source has syntax errors.
Flags:
--body, -b FILE(required) — file containing the replacement source (-for stdin)--dry-run, -n— print what would change without writing--json— emit result as JSON for agent consumption
JSON output:
{
"address": "src/billing.py::compute_total",
"file": "src/billing.py",
"lines_replaced": 12,
"new_lines": 9,
"dry_run": false
}
Security: The file path component of ADDRESS is validated via contain_path() before any disk access. Paths that escape the repo root (e.g. ../../etc/passwd::foo) are rejected with exit 1.
muse grep PATTERN [OPTIONS]
Search the typed symbol graph by name — not file text. Every result is a real symbol declaration; no false positives from comments, string literals, or call sites.
muse grep validate
muse grep "^handle" --regex
muse grep Invoice --kind class
muse grep compute --language Go
muse grep total --commit HEAD~5
muse grep validate --json
Flags:
| Flag | Short | Description |
|---|---|---|
--regex, -e |
Treat PATTERN as a Python regex (default: substring match) | |
--kind KIND, -k |
Restrict to symbols of this kind (function, class, method, …) | |
--language LANG, -l |
Restrict to files of this language (Python, Go, …) | |
--commit REF, -c |
Search a historical commit instead of HEAD | |
--hashes |
Include 8-char content-ID prefix in output | |
--json |
Emit results as JSON |
JSON output:
[
{
"address": "src/auth.py::validate_token",
"kind": "function",
"name": "validate_token",
"qualified_name": "validate_token",
"file": "src/auth.py",
"lineno": 14,
"language": "Python",
"content_id": "cb4afa1234567890..."
}
]
Security: Patterns are capped at 512 characters to prevent ReDoS. Invalid regex syntax is caught and reported as exit 1 rather than crashing.
muse code-check [COMMIT] [OPTIONS]
Enforce semantic code invariants against a commit snapshot.
muse code-check # check HEAD
muse code-check abc1234 # check specific commit
muse code-check --strict # exit 1 on any error-severity violation
muse code-check --json # machine-readable JSON output
muse code-check --rules my_rules.toml # custom rules file inside the repo
Flags:
| Flag | Description |
|---|---|
COMMIT |
Commit ID to check (default: HEAD) |
--strict |
Exit 1 when any error-severity violation is found |
--json |
Emit machine-readable JSON |
--rules FILE |
Path to a TOML invariants file inside the repo (default: .muse/code_invariants.toml) |
Security: --rules FILE is validated via contain_path() — paths that escape the repo root are rejected with exit 1.
11. Architecture Internals
Module Map
muse/
plugins/code/
plugin.py MidiPlugin → CodePlugin (MuseDomainPlugin + StructuredMergePlugin)
ast_parser.py Python AST → SymbolRecord; validate_syntax() for all 11 languages
symbol_diff.py diff_symbol_trees() — O(n) diffing, rename/move annotation
_query.py symbols_for_snapshot(), walk_commits(), language_of()
_predicate.py Predicate DSL parser — tokenise → recursive descent → Predicate callable
_callgraph.py ForwardGraph, ReverseGraph, build_*, transitive_callers BFS
_refactor_classify.py classify_exact(), classify_composite(), RefactorClassification
core/
coordination.py Reservation, Intent, create/load helpers, .muse/coordination/
indices.py SymbolHistoryIndex, HashOccurrenceIndex, save/load/rebuild
Language Support
| Language | Extension(s) | Parser | Symbol types |
|---|---|---|---|
| Python | .py |
ast (stdlib) |
function, async_function, class, method, variable, import |
| JavaScript | .js .jsx .mjs .cjs |
tree-sitter | function, class, method |
| TypeScript | .ts .tsx |
tree-sitter | function, class, method, interface, type_alias, enum |
| Go | .go |
tree-sitter | function (method qualified as Type.Method) |
| Rust | .rs |
tree-sitter | function (impl method qualified as Type.method) |
| Java | .java |
tree-sitter | class, interface, method, constructor, enum |
| C | .c .h |
tree-sitter | function_definition |
| C++ | .cpp .cc .cxx .hpp |
tree-sitter | function, class, struct |
| C# | .cs |
tree-sitter | class, interface, struct, method, constructor, enum |
| Ruby | .rb |
tree-sitter | class, module, method, singleton_method |
| Kotlin | .kt .kts |
tree-sitter | function, class, method |
| Markdown / RST | .md .rst .txt |
tree-sitter-markdown | section (ATX headings) |
| HTML | .html .htm |
tree-sitter-html | section (semantic elements, id-bearing elements) |
| CSS / SCSS | .css .scss |
tree-sitter-css | rule (rule-sets, @keyframes, @media) |
| TOML | .toml |
tomllib (stdlib, zero deps) |
section ([table], [[array]]), variable (scalar key-value) |
Layer Rules
muse/core/*is domain-agnostic — never imports frommuse/plugins/*muse/cli/commands/*are thin — delegate all logic tomuse/core/*or plugin helpersmuse/plugins/code/*is the only layer that imports domain-specific AST logicmuse/core/coordination.pyandmuse/core/indices.pyare domain-agnostic helpers
12. Type Reference
SymbolRecord (TypedDict)
class SymbolRecord(TypedDict):
kind: str # function | class | method | variable | import | …
name: str # bare name
qualified_name: str # dotted path (e.g. MyClass.save)
lineno: int
end_lineno: int
content_id: str # SHA-256 of full normalized AST
body_hash: str # SHA-256 of body only
signature_id: str # SHA-256 of signature only
metadata_id: str # SHA-256 of decorators + async + bases (v2, "" for pre-v2)
canonical_key: str # {file}#{scope}#{kind}#{name}#{lineno} (v2, "" for pre-v2)
StructuredDelta
class StructuredDelta(TypedDict):
domain: str
ops: list[DomainOp]
summary: str
sem_ver_bump: SemVerBump # default "none"
breaking_changes: list[str] # default []
DomainOp union
DomainOp = InsertOp | DeleteOp | ReplaceOp | MoveOp | PatchOp
Each op is a TypedDict discriminated by a Literal "op" field.
ConflictRecord (dataclass)
@dataclass
class ConflictRecord:
path: str
conflict_type: str = "file_level"
ours_summary: str = ""
theirs_summary: str = ""
addresses: list[str] = field(default_factory=list)
Reservation
class Reservation:
reservation_id: str
run_id: str
branch: str
addresses: list[str]
created_at: datetime
expires_at: datetime
operation: str | None
def is_active(self) -> bool: ...
def to_dict(self) -> dict[str, str | int | list[str] | None]: ...
@classmethod
def from_dict(cls, d) -> Reservation: ...
Intent
class Intent:
intent_id: str
reservation_id: str
run_id: str
branch: str
addresses: list[str]
operation: str
created_at: datetime
detail: str
def to_dict(self) -> dict[str, str | int | list[str]]: ...
@classmethod
def from_dict(cls, d) -> Intent: ...
SemVerBump
SemVerBump = Literal["major", "minor", "patch", "none"]
Predicate
Predicate = Callable[[str, SymbolRecord], bool]
# first arg: file_path
# second arg: SymbolRecord
# returns: True if the symbol matches the predicate
ExactClassification
ExactClassification = Literal[
"rename", "move", "rename+move",
"signature_only", "impl_only", "metadata_only",
"full_rewrite", "unchanged",
]
InferredRefactor
InferredRefactor = Literal["extract", "inline", "split", "merge", "none"]
Further Reading
- Plugin Authoring Guide — implementing
MuseDomainPlugin - Type Contracts — strict typing rules and enforcement
- CRDT Reference — CRDT and OT merge primitives
- Demo — Code — full narrative walkthrough of all code commands
- Demo — MIDI — MIDI domain demo walkthrough