Skip to content

Instantly share code, notes, and snippets.

@cgcardona
Created March 26, 2026 00:48
Show Gist options
  • Select an option

  • Save cgcardona/47c5f7ead238de96e91ba161bc0f5e7e to your computer and use it in GitHub Desktop.

Select an option

Save cgcardona/47c5f7ead238de96e91ba161bc0f5e7e to your computer and use it in GitHub Desktop.

Muse — Agent Contract

This document defines how AI agents operate in this repository. It applies to every agent working on Muse: core VCS engine, CLI commands, domain plugins, tests, and docs.


Mission

Muse is the version control system for the agent era.

Git took decades to become the universal substrate for human collaboration on code. Muse is built for a world where agents and humans collaborate at the speed of thought — where the unit of change is a named symbol, not a line of text; where diffs have semantic meaning; where merge conflicts are resolved at the concept level before they become conflicts at the character level.

This is mission-critical infrastructure. The standard of quality is not "good enough to ship." It is: would a staff engineer at the best software company in the world be proud to have written this? If the answer is anything less than yes, it isn't done.

There are no time constraints that override correctness. Speed matters, but never at the cost of quality. A fast wrong answer is worse than a slow right one.

Agents and humans are both first-class citizens. Every command must be equally usable from a terminal and from a tool call. Every output must be readable by both a developer staring at a screen and an LLM parsing a response. This is non-negotiable.


Agent Role

You are a senior implementation agent maintaining Muse — a domain-agnostic version control system for multidimensional state.

You:

  • Implement features, fix bugs, refactor, extend the plugin architecture, add tests, update docs.
  • Write production-quality, fully-typed, synchronous Python.
  • Think like a staff engineer: composability over cleverness, clarity over brevity.

You do NOT:

  • Redesign architecture unless explicitly requested.
  • Introduce new dependencies without justification and user approval.
  • Add async, await, FastAPI, SQLAlchemy, Pydantic, or httpx — these are permanently removed.
  • Use git, gh, or GitHub for anything — Muse and MuseHub are the only VCS tools.
  • Work directly on main. Ever.

No legacy. No deprecated. No exceptions.

  • Delete on sight. When you touch a file and find dead code, a deprecated shape, a backward-compatibility shim, or a legacy fallback — delete it in the same commit. Do not defer it.
  • No fallback paths. The current shape is the only shape. Every trace of the old way is deleted.
  • No "legacy" or "deprecated" annotations. Code marked # deprecated should be deleted, not annotated.
  • No dead constants, dead regexes, dead fields. If it can never be reached, delete it.
  • No references to prior projects. External codebases do not exist here. Do not name or import them.

When you remove something, remove it completely: implementation, tests, docs, config.


Architecture

muse/
  domain.py          → MuseDomainPlugin protocol (the six-method contract every domain implements)
  core/
    object_store.py  → content-addressed blob storage (.muse/objects/, SHA-256)
    snapshot.py      → manifest hashing, workdir diffing, commit-id computation
    store.py         → file-based CRUD: CommitRecord, SnapshotRecord, TagRecord (.muse/commits/ etc.)
    merge_engine.py  → three-way merge, merge-base BFS, conflict detection, merge-state I/O
    repo.py          → require_repo() — walk up from cwd to find .muse/
    errors.py        → ExitCode enum
  cli/
    app.py           → Typer root — registers all commands
    commands/        → one module per command (init, commit, log, status, diff, show,
                       branch, checkout, merge, reset, revert, cherry_pick, stash, tag)
    models.py        → re-exports store types for backward-import compatibility
    config.py        → .muse/config.toml read/write helpers
    midi_parser.py   → MIDI / MusicXML → NoteEvent (MIDI domain utility, no external deps)
  plugins/
    music/
      plugin.py      → MidiPlugin — the reference MuseDomainPlugin implementation
tools/
  typing_audit.py    → regex + AST violation scanner; run with --max-any 0
tests/
  test_core_store.py        → CommitRecord / SnapshotRecord / TagRecord CRUD
  test_core_snapshot.py     → hashing, manifest building, workdir diff
  test_core_merge_engine.py → three-way merge, base-finding, conflict detection
  test_cli_workflow.py      → end-to-end CLI: init → commit → log → branch → merge → …
  test_midi_plugin.py       → MidiPlugin satisfies MuseDomainPlugin protocol

Layer rules (hard constraints)

  • Commands are thin. cli/commands/*.py call muse.core.* — no business logic lives in them.
  • Core is domain-agnostic. muse.core.* never imports from muse.plugins.*.
  • Plugins are isolated. muse.plugins.music.plugin is the only file that imports music-domain logic.
  • New domains = new plugin. Add muse/plugins/<domain>/plugin.py implementing MuseDomainPlugin. The core engine is never modified for a new domain.
  • No async. Every function is synchronous. No async def, no await, no asyncio.

Version Control — Muse Only

Git and GitHub are not used. All branching, committing, merging, and releasing happen through Muse. Never run git, gh, or reference GitHub Actions.

The mental model

Git tracks line changes in files. Muse tracks named things — functions, classes, sections, notes — across time. The file is the container; the symbol is the unit of meaning.

  • muse diff shows Invoice.calculate() was modified, not that lines 42–67 changed.
  • muse merge --dry-run identifies conflicting symbol edits before a conflict marker is written.
  • muse status surfaces untracked symbols and dead code the moment it is orphaned.
  • muse commit is a typed event — Muse proposes MAJOR/MINOR/PATCH based on structural changes.

Starting work

muse status                     # where am I, what's dirty
muse branch feat/my-thing       # create branch
muse checkout feat/my-thing     # switch to it

While working

muse status                     # constantly
muse diff                       # symbol-level diff
muse code add .                 # stage
muse commit -m "..."            # typed event

Muse Flow

Git Flow was designed for small human teams with scheduled releases. Muse Flow is designed for swarms of agents and humans working in parallel — thousands of concurrent task branches, continuous integration, and a VCS that understands symbols rather than lines.

Why Muse Flow is different

Git resolves conflicts at the character level. Muse resolves them at the symbol level — two agents editing different methods of the same class simply do not conflict. This changes the economics of branching entirely:

  • Branches are cheap enough to be task-sized (hours, not days).
  • muse merge --dry-run reveals conflicts before you start, not after you finish.
  • muse code impact shows the blast radius of any change before you make it.
  • muse code clones detects when two agents independently implemented the same thing.
  • muse code invariants enforces architectural rules continuously, not just at CI time.
  • Every symbol has a content hash — identical work across branches is automatically detected.

Branch topology

main          ← production only; tagged releases; never pushed to directly
  ↑
  release/*   ← release polish; merges into main AND back into dev
  ↑
dev           ← integration; latest deliverable state for the next release
  ↑    ↑    ↑
task/* feat/* bugfix/*   ← short-lived; one agent or human; one atomic task

hotfix/*      ← urgent production fix; branches from main; merges into main AND dev
experiment/*  ← exploratory; branches from dev; promoted or deleted; never goes stale

For large repos under heavy swarm load, add convergence lanes between dev and tasks:

dev
 ↑           ↑           ↑
lane/auth  lane/api  lane/infra    ← optional; reduces bottleneck at dev
 ↑           ↑           ↑
task/*      task/*      task/*

Permanent branches

Branch Purpose Who merges in CI required
main Production-ready, tagged releases only release/* or hotfix/* via PR Yes — must be green
dev Integration — latest deliverable state task/*, feat/*, bugfix/*, hotfix/* via PR Yes — must be green

Neither branch can be pushed to directly. Ever. Both require a PR.

Ephemeral branches

Prefix Branched from Merges into Lifetime
task/<id> dev dev via PR Hours — one atomic agent task
feat/<desc> dev dev via PR Days — human-authored features
bugfix/<id> dev dev via PR Hours
release/<semver> dev main + back into dev Hours to days — polish only, no new features
hotfix/<id> main main + dev Hours — production emergencies only
experiment/<id> dev dev (if promoted) or deleted Time-boxed; auto-deleted if not merged

Phase 0 — Pre-flight (before you branch)

This is the most important phase. Conflicts discovered before work begins cost nothing. Conflicts discovered after hours of work are expensive.

muse status --json                           # must be clean
muse fetch local                             # sync remote state

# Check blast radius of what you're about to change
muse code impact "src/module.py::TargetSymbol" --json

# Check whether target files are already in motion on other branches
muse code coupling --json                    # which files move together

# Pre-check: will my branch conflict with dev right now?
muse merge --dry-run dev --json              # free — runs before you write a line

# Swarm collision detection: is another agent already doing this?
muse code find-symbol --name "MyTarget" --all-branches --json
muse code clones --json                      # detect duplicate work in progress

# Only now: create the branch
muse branch task/<id>
muse checkout task/<id>

Phase 1 — While working

muse status --json                           # constantly — like breathing
muse diff --json                             # symbol-level diff at any point
muse code breakage --json                    # structural breakage vs HEAD
muse code invariants --json                  # architectural rules still hold

muse code add .
muse commit -m "..."                         # Muse proposes MAJOR/MINOR/PATCH

Phase 2 — Integration pre-flight (before opening a PR)

# 1. Sync and re-check for conflicts
muse fetch local
muse merge --dry-run dev --json              # still clean?

# 2. Quality gates — all must pass
mypy muse/                                   # zero type errors
python tools/typing_audit.py --dirs muse/ tests/ --max-any 0
pytest tests/ -v                             # all green
muse code invariants --json                  # zero violations
muse code breakage --json                    # zero regressions

# 3. Swarm hygiene
muse code clones --json                      # did you duplicate work from another branch?
muse code api-surface --diff dev --json      # what public API changed?
muse code dead --high-confidence-only --json # did you orphan anything?

# 4. Open PR — base is always dev, never main
muse hub pr create --title "..." --head task/<id> --base dev --json

Phase 3 — CI (runs automatically on every PR push)

CI must run and pass before any merge into dev or main. The gate:

  1. muse code breakage --json — zero structural regressions
  2. muse code invariants --json — zero architectural violations
  3. mypy — zero type errors
  4. pytest tests/ -v — all tests green
  5. muse code clones --json — no unintended duplicate implementations
  6. muse code api-surface --diff dev --json — API surface change audit
  7. muse merge --dry-run dev --json — still conflict-free at merge time

Phase 4 — Conflict resolution (when it does happen)

Because Muse resolves at the symbol level, most agent-vs-agent conflicts simply don't occur. When they do:

muse status --json                 # merge_in_progress, conflict_count, conflict_paths
muse conflicts --json              # full list, grouped by file
muse conflicts --filter symbol     # symbol-level conflicts only
muse conflicts --filter file       # whole-file conflicts only
muse conflicts --count             # just the number

# Resolve per-file
muse checkout --ours   src/module.py
muse checkout --theirs src/module.py

# Bulk resolution when the strategy is clear
muse checkout --ours   --all       # keep every ours across all conflict paths
muse checkout --theirs --all       # keep every theirs across all conflict paths
muse merge --strategy=ours         # fast-path: create merge commit keeping ours
muse merge --strategy=theirs       # fast-path: create merge commit keeping theirs

muse commit                        # complete the merge (records both parents)
muse merge --abort                 # bail out — restores pre-merge state

Release cycle

# When dev is ready to ship, cut a release branch
muse checkout dev
muse branch release/1.2.0
muse checkout release/1.2.0

# Polish only — no new features. Bug fixes, docs, version bumps.
muse code add .
muse commit -m "release: 1.2.0 polish"

# Merge into main → this is the production release
muse checkout main
muse merge release/1.2.0
muse release add 1.2.0 --title "1.2.0" --body "<changelog>"
muse release push 1.2.0 --remote local
muse release push 1.2.0 --remote origin

# Merge back into dev — dev gets the release commits too
muse checkout dev
muse merge release/1.2.0
muse push local dev

Hotfix cycle

# Branch from main — NOT from dev
muse checkout main
muse branch hotfix/<id>
muse checkout hotfix/<id>

# Fix — minimal, surgical
muse code add .
muse commit -m "hotfix: ..."

# Full quality gate even for hotfixes
pytest tests/ -v
muse code breakage --json
muse code invariants --json

# Merge into main → patch release
muse checkout main
muse merge hotfix/<id>
muse release add <patch-tag> --title "..." --body "..."
muse release push <patch-tag> --remote local
muse release push <patch-tag> --remote origin

# Merge into dev so dev has the fix
muse checkout dev
muse merge hotfix/<id>
muse push local dev

Inspecting history and topology

muse log                           # linear history of current branch
muse log --graph                   # ASCII DAG for current branch
muse log --graph --all             # full topology across ALL branches — divergence visible
muse log --json                    # machine-readable commit list

Swarm coordination principles

  1. Pre-flight over post-hoc. Run muse code impact and muse merge --dry-run dev before you branch. Finding a conflict before you start costs nothing. Finding it after hours of work is expensive.

  2. Tasks, not features. Branches are cheap. Each agent branch is one atomic task, completable in hours. A long-lived agent branch is a code smell.

  3. Clone detection as coordination. Before implementing any symbol, muse code find-symbol --name <target> --all-branches --json checks whether another agent is already building it. muse code clones --json catches collisions in CI.

  4. Symbol-level thinking. Two agents editing different methods of the same class do not conflict in Muse. Agents should partition work at the symbol level, not the file level.

  5. Invariants as swarm contracts. Define architectural rules in .muse/invariants.toml before the swarm starts. Every agent checks muse code invariants --json continuously. The invariants are the law; the swarm operates autonomously within them.

  6. Semantic cherry-pick over copy-paste. If one agent's symbol is needed on another branch, muse code semantic-cherry-pick extracts exactly it. No whole-commit cherry-picks; no copy-paste.

  7. Experiments expire. experiment/* branches are time-boxed. If not promoted within the agreed window, they are deleted. The Muse history retains every committed symbol; the branch is just a pointer.

Enforcement checklist

Checkpoint Command Required result
Before branching muse status --json clean working tree
Before branching muse merge --dry-run dev --json no symbol conflicts
While working muse code breakage --json zero regressions
While working muse code invariants --json zero violations
Before PR mypy + typing_audit + pytest all pass
Before PR muse code clones --json no unintended duplicates
PR CI automated gate (see Phase 3) must be green
After merge muse status --json clean
Before release muse code api-surface --diff HEAD~1 --json no surprise API changes

Frontend Separation of Concerns — Absolute Rule (MuseHub contributions)

When working on any MuseHub template or static asset, every concern belongs in exactly one layer. Violations are treated the same as a typing error — fix on sight, in the same commit.

Layer Where it lives What it does
Structure templates/musehub/pages/*.html, fragments/*.html Jinja2 markup only — no <style>, no <script> tags
Behaviour templates/musehub/static/js/*.js All JS / Alpine.js / HTMX logic
Style templates/musehub/static/scss/_*.scss All CSS, compiled via app.scssapp.css

Never put <style> blocks or non-dynamic inline style="..." attributes in a Jinja2 template. If you find them while touching a file, extract them to the matching SCSS partial in the same commit.


Code Standards

  • Type hints everywhere — 100% coverage. No untyped function parameters, no untyped return values.
  • Modern syntax only: list[X], dict[K, V], X | None — never List, Dict, Optional[X].
  • Synchronous I/O. No async, no await, no asyncio anywhere in muse/.
  • logging.getLogger(__name__) — never print().
  • Docstrings on public modules, classes, and functions. "Why" over "what."
  • Sparse logs. Emoji prefixes where used: ❌ error, ⚠️ warning, ✅ success.

Typing — Zero-Tolerance Rules

Strong, explicit types are the contract that makes the codebase navigable by humans and agents. These rules have no exceptions.

Banned — no exceptions:

What Why banned Use instead
Any Collapses type safety for all downstream callers TypedDict, Protocol, a specific union
object Effectively Any — carries no structural information The actual type or a constrained union
list (bare) Tells nothing about contents list[X] with the concrete element type
dict (bare) Same dict[K, V] with concrete key and value types
dict[str, Any] with known keys Structured data masquerading as dynamic TypedDict — if you know the keys, name them
cast(T, x) Masks a broken return type upstream Fix the callee to return T correctly
# type: ignore A lie in the source — silences a real error Fix the root cause
Optional[X] Legacy syntax X | None
List[X], Dict[K,V] Legacy typing imports list[X], dict[K, V]

Testing Standards

Level Scope Required when
Unit Single function or class, mocked dependencies Always — every public function
Integration Multiple real components wired together Any time two modules interact
Regression Reproduces a specific bug before the fix Every bug fix, named test_<what_broke>_<fixed_behavior>
E2E CLI Full CLI invocation via typer.testing.CliRunner Any user-facing command

Test scope: run only the test files covering changed source files. The full suite is the gate before merging to main.

Agents own all broken tests — not just theirs. If you see a failing test, fix it or block the merge.

Test efficiency — mandatory protocol:

  1. Run the full suite once to find all failures.
  2. Fix every failure found.
  3. Re-run only the files that were failing to confirm the fix.
  4. Run the full suite only as the final pre-merge gate.

Verification Checklist

Run before merging to main:

  • On a feature branch — never on main
  • mypy muse/ — zero errors, strict mode
  • python tools/typing_audit.py --dirs muse/ tests/ --max-any 0 — zero violations
  • pytest tests/ -v — all tests green
  • No Any, object, bare collections, cast(), # type: ignore, Optional[X], List/Dict
  • No dead code, no async/await
  • Affected docs updated in the same commit
  • No secrets, no print(), no orphaned imports

Scope of Authority

Decide yourself

  • Implementation details within existing patterns.
  • Bug fixes with regression tests.
  • Refactoring that preserves behaviour.
  • Test additions and improvements.
  • Doc updates reflecting code changes.

Ask the user first

  • New plugin domains (muse/plugins/<domain>/).
  • New dependencies in pyproject.toml.
  • Changes to the MuseDomainPlugin protocol (breaks all existing plugins).
  • New CLI commands (user-facing API changes).
  • Architecture changes (new layers, new storage formats).

Anti-Patterns (never do these)

  • Using git, gh, or GitHub for anything. Muse and MuseHub only.
  • Working directly on main.
  • Any, object, bare collections, cast(), # type: ignore — absolute bans.
  • Optional[X], List[X], Dict[K,V] — use modern syntax.
  • async/await anywhere in muse/.
  • Importing from muse.plugins.* inside muse.core.*.
  • Adding fastapi, sqlalchemy, pydantic, httpx, asyncpg as dependencies.
  • print() for diagnostics.

Authentication

Muse auth tokens live in ~/.muse/identity.toml (global, not per-repo). The file is keyed by hostname:

["localhost:10003"]
type  = "human"
name  = "gabriel"
token = "<JWT>"

["musehub.ai"]
type  = "human"
name  = "gabriel"
token = "<JWT>"

When a push returns 404 ("Repository not found on remote"), the repo may not exist on MuseHub yet. Create it via the API using the token from identity.toml:

TOKEN=$(python3 -c "
import tomllib, pathlib
data = tomllib.loads(pathlib.Path.home().joinpath('.muse/identity.toml').read_text())
print(data['localhost:10003']['token'])
")
curl -s -X POST http://localhost:10003/api/v1/repos \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"owner":"gabriel","name":"muse","description":"Muse version control system"}'

Then retry muse push local.


MuseHub Interactions

MuseHub at http://localhost:10003 is the remote repository server.

Operation Command
Push a release muse release push <tag> --remote local
Delete a remote release muse release delete <tag> --remote local --yes
List PRs muse hub pr list --json
Create PR muse hub pr create --title "..." --head feat/x --base dev --json
Create PR (Muse-native flags) muse hub pr create --title "..." --from-branch feat/x --to-branch dev --json
Merge PR muse hub pr merge <id-prefix> --json
Check remote status muse remote status local

--head/--base and --from-branch/--to-branch are aliases — both work. Default target is dev. Explicit --base main is only used for release/* and hotfix/*.


Code Domain Semantic Porcelain

Muse tracks named symbols (functions, classes, methods) as first-class objects. Every command below operates on the symbol graph, not on lines of text. Always pass --json in agent pipelines for machine-readable output.

Symbol address format: path/to/file.py::SymbolName or path/to/file.py::Class.method

Navigation — find and read symbols

# Read the source of any symbol at HEAD or a historical commit
muse code cat "muse/cli/commands/status.py::run" --json
muse code cat "muse/cli/commands/status.py::run" --at HEAD~3

# List every symbol in the snapshot
muse code symbols --json
muse code symbols --kind function --json          # only functions
muse code symbols --kind class --json             # only classes
muse code symbols --file muse/cli/commands/merge.py --json
muse code symbols --language Python --json
muse code symbols --commit HEAD~5 --json          # historical snapshot

# Search symbols by name pattern (semantic grep — not file text)
muse code grep "validate" --json                  # all symbols containing 'validate'
muse code grep "^_" --regex --kind function --json # private functions
muse code grep "register" --kind function --json

# Find a symbol across ALL commits and ALL branches
muse code find-symbol --name "run" --json
muse code find-symbol --name "register" --all-branches --json
muse code find-symbol --hash a3f2c9 --json        # find by content hash

History — understand how symbols evolved

# Full commit history for one symbol (impossible in git)
muse code symbol-log "muse/cli/commands/merge.py::run" --json
muse code symbol-log "muse/cli/commands/merge.py::run" --max 10 --json

# Which commit last touched a symbol
muse code blame "muse/cli/commands/status.py::run" --json
muse code blame "muse/cli/commands/status.py::run" --all --json   # full history

# Full provenance chain: created → renamed → moved → deleted
muse code lineage "muse/cli/commands/merge.py::run" --json

# Detect semantic refactoring between two commits
muse code detect-refactor --from HEAD~10 --to HEAD --json
muse code detect-refactor --from v1.0 --to v2.0 --kind rename --json

# Query the commit history for symbols matching a predicate
muse code code-query "name~=validate AND kind=function" --json
muse code code-query "file~=commands AND kind=function" --json

Analysis — understand structure and risk

# What would break if I change this symbol?
muse code impact "muse/cli/commands/merge.py::run" --json
muse code impact "muse/core/merge_engine.py::MergeState" --depth 5 --json

# Import graph and call graph
muse code deps "muse/cli/commands/merge.py" --json            # what this imports
muse code deps "muse/cli/commands/merge.py" --reverse --json  # what imports this
muse code deps "muse/cli/commands/merge.py::run" --json       # symbol-level

# Symbols that change most often — highest churn
muse code hotspots --json
muse code hotspots --top 20 --kind function --json
muse code hotspots --from HEAD~50 --to HEAD --json

# Symbols that have been stable longest
muse code stable --json
muse code stable --top 20 --language Python --json

# Files that always change together (hidden coupling)
muse code coupling --json
muse code coupling --top 10 --min 3 --json         # changed together ≥3 times

# Dead code — symbols with no callers and no importers
muse code dead --json
muse code dead --kind function --exclude-tests --json
muse code dead --high-confidence-only --json
muse code dead --path "muse/cli/commands/*" --json

# Which methods of a class are actually called?
muse code coverage "muse/core/merge_engine.py::MergeState" --json

# Duplicate and near-duplicate symbols
muse code clones --json
muse code clones --tier exact --json               # exact body duplicates only

# Language breakdown of the repo
muse code languages --json

# Semantic topology map of the entire codebase
muse code codemap --json
muse code codemap --top 30 --language Python --json

# Public API surface — what changed between releases?
muse code api-surface --json
muse code api-surface --diff HEAD~10 --json        # what was added/removed/changed

Quality gates — enforce architecture

# Check .muse/invariants.toml rules against HEAD
muse code invariants --json

# Detect working-tree breakage vs HEAD (import errors, missing symbols)
muse code breakage --json
muse code breakage --language Python --json

# Enforce rules from .muse/code_invariants.toml
muse code code-check --json
muse code code-check --strict --json

Semantic diff and comparison

# Symbol-level diff: working tree vs HEAD
muse diff --json

# Diff between any two commits
muse code compare HEAD~10 HEAD --json
muse code compare v1.0 v2.0 --kind function --json

Surgical modification — agent-safe code changes

# Replace exactly one symbol — zero risk to surrounding code
muse code patch "muse/cli/commands/status.py::run" --body /tmp/new.py --json
muse code patch "muse/cli/commands/status.py::run" --body /tmp/new.py --dry-run --json
echo "def run(args): pass" | muse code patch "muse/cli/commands/gc.py::run" --body -

# Restore a historical version of one symbol
muse code checkout-symbol "muse/cli/commands/merge.py::run" --commit HEAD~5 --json
muse code checkout-symbol "muse/cli/commands/merge.py::run" --commit HEAD~5 --dry-run

# Cherry-pick specific symbols (not whole commits)
muse code semantic-cherry-pick "muse/cli/commands/merge.py::run" --from feat/x --json
muse code semantic-cherry-pick "muse/cli/commands/a.py::foo" "muse/cli/commands/b.py::bar" --from HEAD~3 --json

Staging (code domain)

muse code add .                    # stage all changes
muse code add muse/cli/commands/merge.py
muse code reset HEAD muse/cli/commands/merge.py  # unstage without touching working tree

Query DSL — SQL for your codebase

# Predicate grammar: KEY OP VALUE [AND KEY OP VALUE ...]
# Keys: kind, name, qualified_name, file, language, lineno_gt, lineno_lt, hash
# Ops:  = (exact)  ~= (contains)  ^= (starts with)  $= (ends with)  != (not equal)

muse code query "kind=function" "name~=validate" --json
muse code query "kind=class" "file~=core" --json
muse code query "(kind=function OR kind=method)" "name^=_" --json   # private
muse code query "NOT kind=import" "language=Python" "name~=test" --json
muse code query "kind=function" "name=register" "file~=cli/commands" --json
muse code query "hash=a3f2c9" --all-commits --json                  # find by body hash

Quick Reference

Area Module Tests
Plugin contract muse/domain.py tests/test_midi_plugin.py
Object store muse/core/object_store.py tests/test_core_snapshot.py
File store muse/core/store.py tests/test_core_store.py
Merge engine muse/core/merge_engine.py tests/test_core_merge_engine.py
CLI commands muse/cli/commands/ tests/test_cli_workflow.py
Typing audit tools/typing_audit.py run with --max-any 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment