Every command runs without prompts, is safe to run twice, and has --help with examples. Every command except update can output versioned JSON. Fetching uses your own git.
regraft add — create a named GraftCopies files in and creates a durable relationship between the Source and one exclusively owned local destination. Use --name to give a single Graft a stable name.
# A named Graft from a directory regraft add owner/repo/tree/main/src/components lib/components --name components # A single file regraft add owner/repo/blob/main/src/utils.ts --name utils # Track an existing copy without overwriting your edits regraft add owner/repo/tree/main/src/utils lib/utils --name utils --adopt
--adopt keeps existing differing files and marks them as needing Intent. --force overwrites them instead; the two flags are mutually exclusive. --dry-run reports the plan without changing files or state.
Anything your git can clone, plus named Grafts published in a repository's regraft.yaml.
A bare fragment first resolves as a Git ref, then falls back to a published Graft. Use #graft=<name> when the distinction matters. Branch names containing / need the #<ref>:<subpath> syntax.
regraft note — say why you changed thingsOne plain-English sentence: what changed and why. regraft snapshots the current state of the files, saves the note, and updates PATCH.md.
# By default the note covers every edited file that doesn't have one yet regraft note "Swapped the default tokens for our brand palette" # Or name the files it applies to regraft note "Removed the telemetry hooks" --files lib/components/analytics.ts
Notes aren't optional: regraft status flags any edited file that doesn't have one, and fails until it does. That's what keeps PATCH.md trustworthy over time.
regraft diff — see both directionsSee what you changed or what upstream changed. It never writes anything. Use --graft to select exact Graft names or IDs.
# What you changed since copying the code in regraft diff # What upstream changed since then, for one Graft regraft diff --upstream --graft components
Exits 1 when there are differences, 0 when there are none (like git diff). Binary files are flagged and not diffed.
regraft status — anything need attention?Checks each source for new upstream commits and reports the state of every tracked file.
regraft status # exits 1 if anything is stale, unrecorded, missing, or unresolved regraft status --offline # skip the upstream checks entirely (no network)
clean Unchanged since regraft last wrote it modified+intent You edited it and left a note modified-unrecorded You edited it but haven't left a note. Fails the exit code missing A tracked file is no longer on disk conflict-unresolved A previous pull left conflict markers waiting for resolve reconciliation-pending An Update still needs deliberate judgment Run it in CI to catch drift before it compounds.
regraft pull — update selected GraftsPass exact Graft names or IDs, or omit them to update everything. Straightforward changes apply automatically; anything needing judgment remains durable, retryable pending state.
regraft pull components # update one named Graft regraft pull components --dry-run # report the plan, write nothing regraft pull components --force # take upstream for every pending file
On conflict, regraft writes Git-style markers and a Brief with the Graft, revision transition, conflicts, warnings, relevant upstream commits, and Intent. Binary changes, deletions, and destination collisions also persist as pending judgment. Inspect that state with regraft inspect <name> --json.
regraft resolve — close the loopRun after you or your agent deliberately reconciles pending files. Select Grafts with --graft; add --note to record the resolution Intent in the same step.
# Resolve a Graft and leave a note in one step regraft resolve --graft components --note "Re-applied our palette on the new token system" # Or resolve specific files first, note later regraft resolve lib/components/theme.ts
regraft inspect — canonical Graft contextReturns provenance, Intent, local and upstream status, pending Updates, and Briefs for exact Graft names or IDs. This is the preferred context entry point for coding agents.
regraft inspect components --json regraft inspect components --offline --json
Machine output includes schemaVersion: 1. All JSON success and error envelopes use the same schema version.
regraft validate — publish named GraftsMaintainers publish stable source surfaces by committing regraft.yaml at the repository root. There is no publish command or hosted registry.
version: 1 grafts: session: path: packages/auth/src/session description: Session management implementation regraft validate regraft add owner/repo#graft=session src/session
# Stop tracking by exact Graft name or ID; --hard also deletes the files regraft remove components regraft remove components --hard # Update regraft itself (latest, or a specific tag) regraft update regraft update v0.1.0 # Tab completion echo 'eval "$(regraft completion bash)"' >> ~/.bashrc regraft completion zsh > ~/.zfunc/_regraft regraft completion fish > ~/.config/fish/completions/regraft.fish
Removed Grafts keep their Intent as history, marked orphaned in PATCH.md.
regraft.json Format v2 stores named Grafts, stable IDs, Sources, destinations, separate upstream/local hashes, scoped Intent, exclusions, and pending Updates.
PATCH.md A readable, Graft-scoped projection of Intent history. Regenerated from regraft.json; do not edit it directly.
.regraft/ Cached clones and conflict briefs. regraft writes .regraft/.gitignore containing * so you never have to think about it.
regraft.yaml Names stable source surfaces that others can consume directly from the Git repository.
0 Everything is fine, clean, succeeded, or already done 1 Something needs attention — status: anything stale, missing a note, missing, or unresolved; pull: any conflict or warning; resolve: markers remain or the note is missing; add: any file skipped; diff: any difference found
Every command except update accepts --json. Every success and error envelope includes schemaVersion: 1.