pi-regraft
Vendor and update upstream code as plain files, with a dedicated Pi agent for resumable conflict resolution.
Package details
Install pi-regraft from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-regraft- Package
pi-regraft- Version
0.4.0- Published
- Aug 2, 2026
- Downloads
- 551/mo · 551/wk
- Author
- osolmaz
- License
- MIT
- Types
- extension
- Size
- 401.7 KB
- Dependencies
- 3 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./src/extension.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-regraft
pi-regraft is a Pi extension for vendoring code from Git repositories. It lets
you change the copied code in place and pull later upstream changes without
losing your work.
The vendored code stays in your repository as ordinary files. Regraft stores pristine upstream copies in normal commits on your branch and uses them as three-way merge bases during updates. It fetches only the new upstream commit.
The package also includes Regrafter, a dedicated Pi agent for resolving update conflicts, running checks, and pausing when an update needs a product decision.
Install
Install from npm:
pi install npm:pi-regraft
You can also run the GitHub version without installing it:
pi -e git:github.com/osolmaz/pi-regraft
First graft
Run Pi at the root of the repository that will receive the files. Add an upstream repository, tracked ref, optional subdirectory, and destination:
/regraft add https://github.com/example/tool.git@main#extensions/foo vendor/foo
The npm package also installs a regraft executable for scripts and coding
agents:
regraft add https://github.com/example/tool.git@main#extensions/foo vendor/foo
The destination must be empty. Regraft copies the selected upstream tree into
vendor/foo and writes regraft.json before creating a commit named
chore(regraft): import upstream base.
Edit the copied files after that commit and commit your changes normally. If a local change has a reason that may matter during conflict resolution, record it in the manifest:
/regraft note foo "log every failed request"
Commit the updated manifest before pulling from upstream.
Updates
Check whether any tracked ref has advanced:
/regraft status
Update one graft by name:
/regraft update foo
Regraft reads the old pristine tree from your branch and fetches the new upstream commit before merging these trees:
- the old pristine upstream tree
- your committed local tree
- the new upstream tree
It commits the new pristine tree before restoring the merged local version in your worktree. If you made no local changes, the worktree stays clean. If local changes remain, run your project checks and commit the restored local version.
Text conflicts use normal Git conflict markers. Pi receives the affected file
paths and the notes from regraft.json, so the agent can help resolve them.
Regraft also preserves executable bits, symlinks, binary files, and
file-versus-directory changes.
Commands
/regraft add <url>[@ref][#subdir] [dest] copy and commit an upstream tree
/regraft update <name> pull upstream and restore local edits
/regraft status show local bases and upstream status
/regraft note <name> <text> record why a local edit exists
The executable provides the same operations without the leading slash. Add
--json to receive one versioned JSON result on stdout. Expected merge
conflicts return a successful needs_resolution result so an agent can inspect
and resolve them before running project checks.
Regrafter
Regrafter keeps one Pi session and one repository lease for each update run. It can pause for several decisions and resume without losing the conversation or the exact repository state.
Install the commands and Pi Factory, then install the app bundle:
npm install -g pi-regraft @osolmaz/pi-factory
pi-factory install osolmaz/pi-regraft --ref v0.4.0 --yes
Work with Regrafter directly in a repository:
pi-factory run regrafter --cwd /path/to/repository
A main agent or script can drive the same app through bounded controller commands:
regrafter start --repo /path/to/repository --request-file task.md --json
regrafter send <run-id> --decision <decision-id> --message-file answer.md --json
regrafter inspect <run-id> --json
regrafter list --repo /path/to/repository --json
regrafter attach <run-id>
regrafter abort <run-id> --json
The baseline command grants no authority to create overlay commits, push, or
open pull requests. Grant only the actions the run needs with
--allow commits,push,pull-requests. A later send may add authority, but it
cannot remove authority already granted.
Regrafter never drops a lease because it is old and never silently chooses
between competing local and upstream behavior. abort does not reset files; it
releases the lease only after verifying the repository handoff state.
The bundled app defaults to an OpenAI-compatible model named regrafter at
http://127.0.0.1:1234/v1. It does not install or start a model server. Edit
the installed pi-factory.toml when the endpoint or model differs.
Repository requirements
add and update require an attached Git branch, a clean worktree and index,
and a configured Git author. Git credentials must come from a credential helper
or SSH key. Regraft rejects credentials embedded in source URLs.
An update also refuses to run when ignored, uncommitted files exist inside the graft. Move or remove those files first so they cannot be erased by the update.
Keep every chore(regraft): import upstream base commit in branch history.
Rebasing those commits is safe. Squashing or dropping them removes the merge
bases and blocks future updates.
Regraft fails when a required local base is missing. It never recovers the old base by fetching the previously pinned commit from upstream.
The full commit model and merge rules are in the design document.