magus v0.4.2 is out. See what's new
¶ View generated markdown
7 min read

magus-diff

Read the working tree's changes in the order they deserve attention

Synopsis

magus diff [--generated] [--impact] [--no-tui] [--watch] [--rev <base>...<head>] [--patch <file>|-] [<path>...] [flags]

Description

Read the working tree's uncommitted changes, annotated and ordered.

A changeset is not a list of files, it is a set of CONSEQUENCES, and a reader's attention is scarce. Alphabetical order spends it at random: it gives a regenerated lockfile the same weight as a signature change twelve packages depend on. This orders by what a change can BREAK.

Generated files - declared target outputs - are folded away by default. Reading one is reading a machine's restatement of a change made somewhere else, so the source edit is the review. Pass --generated to see them anyway.

At a terminal this opens an interactive viewer: the same annotations, plus navigation and a way to mark what you have read. It is the same report either way - the viewer renders the identical annotation lines - so nothing is hidden behind a keypress, and ] and [ walk hunks while q leaves.

The viewer stands aside on its own wherever it cannot draw: no terminal, -o json, --watch, a patch argument, or --impact. Those are not refusals, they are the report printing instead, so a script or an agent needs no flag. --no-tui is for a person who wants the report at a terminal anyway, and "magus config set key=diff.tui,value=false" makes that the standing preference.

One rule decides what a word on the command line means: the CHANGESET is always named by a flag - --rev, --patch, or the working tree by default - and every positional is a PATH that narrows it. So "magus diff internal/ledger/" reads only that subtree, and it means the same thing whichever source it is narrowing.

The patch source moved behind --patch for that rule. A bare - still reads stdin, because it is unambiguous and it is what every pipe in the world already types.

--rev reads a committed range as base...head rather than the working tree, which is how you review a branch: a colleague's, or the one your own agent just finished. It is the half a working-tree diff cannot reach, and it keeps the viewer, the navigation and the marks, because a revision is a tree state magus can address rather than a patch somebody handed it. Three dots: the answer is what head added since it diverged, never what the base gained meanwhile.

A receipt earned against a range attests to the blob at that revision, so it survives the working tree moving underneath and does not follow the branch when somebody force-pushes it. That is the whole difference from a working-tree receipt, and it is why --ack takes --rev where it refuses a patch: magus can name what a range receipt covers, and cannot name what a patch on stdin covers.

Each file carries the evidence behind its rank: how many files reference the widest changed symbol it defines, whether any of those referents cross a project boundary or the module boundary (which is the question a version bump turns on), and the coverage a prior run observed. None of it is a verdict. magus does not claim a change is breaking - deciding that needs signature compatibility, which needs a base-side index magus does not keep and language semantics it does not model - it reports who can see the thing you changed and lets you decide.

The console's Diff surface reads the same annotations over the same session, and an agent can join that session through the magus_diff MCP tool.

--impact appends the blast radius of landing the change: which projects rebuild and which were merely edited, who has been changing them, an estimate of the rebuild from recorded run durations, what the workspace's advisors say, which human-authored notes anchor a file or symbol you touched, and what the authors asked magus while writing it. It is the same question magus affected --impact answers, asked of a changeset instead of a target. It is context and never a verdict - nothing is gated on it and the exit code is unchanged; neither the flag nor the section it prints says "preflight", because in this workspace's magusfiles a preflight target IS a gate and this must never read as one. Each section says when it could not measure something, so an empty one reads as "nobody looked" rather than as a clean bill of health.

--impact also carries a REVIEW section, which is a bookmark rather than a score. It reports the two things a reader cannot produce without reading: files that changed AFTER they were read, and files never opened, widest blast radius first. It reports no ratio and stays silent on a small change nobody has disturbed - a count with a target is a count that gets cleared instead of satisfied.

--prompt prints a review prompt for you to paste into whichever model you use, and magus stops there: it calls no model, holds no key, and sends nothing. It is the same refusal magus agent makes about your AGENTS.md - magus generates the text and a person carries it across, because a tool that crossed the boundary itself would leave bytes you did not write and cannot audit. It asks for findings rather than review prose; the words your colleague reads should be yours. Add --impact for the rationale behind each instruction.

A receipt covers a file at its CURRENT content, so editing it afterwards voids the receipt. Stepping a file through in the viewer earns one; --ack covers the changeset at once and takes an optional --reason kept with it. magus never infers a receipt from an editor or a session: a measure satisfied by scrolling would launder skimming into review. --ack refuses without a terminal, and agent hosts are denied it outright.

The count is never shown to anyone but the reader. There is no team view and no pull-request comment, because a read measure a second person can see is a performance metric, and a performance metric gets gamed rather than met.

Options

--ack
Record that you have read the changed files at their current content; --impact reports what carries no such record
--generated
Include declared target outputs, which are folded away by default
--impact
Append the blast radius of landing this: reach, ownership, an estimate from recorded run times, advisors, note anchors, and the evidence the authors consulted
--no-tui
Print the report instead of opening the interactive viewer
--patch -
Review a patch somebody handed you instead of the working tree; `-` reads stdin
--prompt
Print a review prompt to paste into your own LLM: the context magus has, never a drafted review. With --impact, also carries the rationale behind each instruction
--reason string
An optional note kept with an --ack, for the next reader of the report
--rev string
Review a committed range instead of the working tree, as base...head: a colleague's branch, or your agent's finished work
--watch
Re-read and re-render whenever the working tree changes

Exit status

0
The changeset was read and rendered. This is the status whether or not anything changed: unlike git diff --exit-code, a non-empty changeset is not a failure, and no flag makes it one.
1
The changeset could not be read - an unreadable patch file, or stdin, or a working tree the VCS would not report on.
2
Misuse: more than one patch argument, or an argument that is neither a readable patch nor -. The viewer never causes this: where it cannot draw - no terminal, -o json, --watch, a patch argument, --impact - it stands aside and the report prints instead.

Examples

Read what you are about to commit

magus diff

Review a branch somebody else pushed

magus diff --rev main...feat/audience

Narrow it to one subtree

magus diff internal/ledger/

Include the generated files too

magus diff --generated

Everything to know before landing it

magus diff --impact

Print the report instead of opening the viewer

magus diff --no-tui

Build a review prompt for the model of your choice

magus diff --prompt

Machine-readable, for a script or a Buzz advisor

magus diff -o json

See Also

magus(1), magus-ls(1), magus-describe(1), magus-run(1), magus-x(1), magus-where(1), magus-affected(1), magus-graph(1), magus-query(1), magus-explain(1), magus-path(1), magus-refs(1), magus-watch(1), magus-events(1), magus-status(1), magus-clean(1), magus-vcs(1), magus-doctor(1), magus-config(1), magus-session(1), magus-memory(1), magus-notes(1), magus-server(1), magus-mcp(1), magus-buzz(1), magus-completion(1), magus-man(1), magus-init(1), magus-agent(1), magus-self(1), magus-version(1)

generatedinternal/cli/registry.goclimagus diffdiffreviewchangesetsemver
Last updated (2b29c004)
Earlier changes on this page (7)

Full history ↗ · Blame source ↗

Glossary

Workspace

The magus root directory that owns a set of projects and shared config; the unit magus operates over. See workspace.

Project

A directory magus recognizes as a unit of work (it has a magusfile); the unit of caching, scheduling, and dependency tracking. See workspace.

Magusfile

The magusfile.buzz that declares a project's targets (as export funs) and binds its spells. See targets.

Target

A named operation (build, test, ...) you invoke with magus run <target>; it may compose a spell's tool-native operations and depend on other targets. See targets.

Op

A single tool-native command a target composes (long form: operation); the middle of the work hierarchy (Spell to Op to Target). See operations.

Ward

A coded diagnostic that inspects a resolved op and nudges or blocks an anti-pattern before it runs. See wards.

Module

A magus stdlib namespace a magusfile imports for host capabilities: filesystem, exec, vcs, and more. See the module reference.

Buzz

The language magusfiles are written in (the .buzz engine). See engines.

Affected

The set of projects touched by a change; magus affected <target> runs a target only over them. See affected.

CI

An ordinary magusfile-defined target you compose yourself with magus\needs - magus does not hardcode its stages. Magus.RunCI treats it specially only in that it strips the rw charm, it is the anchor magus affected ci keys off, and a selected scope with no project declaring it is a load error rather than a silent no-op. See targets.

Health

The at-a-glance daemon state derived from the pool: healthy when the pool is reporting, degraded when it reports an error, down when there is no pool. The dashboard color-codes each state. See daemon.

MAGUS.md

The committed routing index at a workspace root, regenerated from the knowledge graph: it lists every node and points at the exact query for a given question, so it is the entry point an agent reads first. See knowledge.

Ownership

An insight lens: author concentration - the primary author and their share, the distinct-author count (the bus factor), and abandonment. See insight.

Session

One magus process's recorded facts - the targets it finished, their outcomes, and the lease it acted as - kept in a repo-scoped store every worktree shares. magus session lists them; the store prunes itself by last-fact age.

Advisor

One read-only check from the advice suite: it reads the changeset through magus and writes one titled section of findings. The same advisors run as a pull request comment in CI and inside magus diff --impact locally.

Conventions

This page uses none of the site's convention markers. The full set is on the conventions page.