pi-graphite
v0.6.1
Published
Opinionated pi tools + skill for stacked PR workflows with the Graphite (gt) CLI.
Maintainers
Readme
pi-graphite
Opinionated pi tools + skill that wrap the Graphite
gt CLI for stacked PR workflows. A small set of tools, one correct path.
graphite_status → (graphite_setup if needed) → graphite_sync → graphite_navigate
→ graphite_change → graphite_submit (dry-run) → graphite_submit (apply)The extension wraps gt for stack operations. Submit also uses explicit,
non-interactive gh pr view/edit --body-file calls to enforce PR descriptions.
It deliberately does not edit PR titles, fetch review comments, or expose
interactive stack surgery (split / fold / squash / reorder). Reparenting a
tracked branch IS supported via graphite_move (gt move --source --onto,
non-interactive). For the remaining surgery flows, run the underlying gt or
gh command yourself in your own terminal; the agent should not invoke them
from bash, as their defaults open interactive prompts, hunk pickers, or editors
that will hang non-interactive sessions.
Requirements
gtCLI installed and authenticated (gt auth).ghCLI installed and authenticated for PR body inspection/editing.- A pi runtime that loads npm or local pi packages.
Install
# global
pi install npm:pi-graphite
# project-local
pi install -l npm:pi-graphite
# from a local checkout
pi install /path/to/pi-graphite
# or, for one session
pi -e /path/to/pi-graphiteThe package also ships a graphite skill (skills/graphite/SKILL.md) that pi
auto-discovers. It describes the golden path and per-recipe tool calls; the
agent loads it on demand.
Registered tools
| Tool | Purpose | Wraps |
| ------------------------ | ----------------------------------------------------------------------- | ---------------------------------------------- |
| graphite_status | Read-only snapshot: current stack, or targeted branches + bounded topology snippets | gt log --stack, gt info, gt info <branch>, filtered gt log |
| graphite_setup | Initialize Graphite or track an existing Git branch with explicit parent | gt init --trunk, gt track --parent |
| graphite_sync | Start-of-day / after-merge cleanup + restack | gt sync |
| graphite_get | Pull a branch / stack from the remote | gt get <branch> |
| graphite_navigate | Move around the stack | gt checkout, gt up/down/top/bottom |
| graphite_move | Reparent a tracked branch + restack descendants (dry-run by default) | gt move --source --onto |
| graphite_change | Create / amend a stacked branch | gt create -am, gt modify -am, gt modify --into, gt absorb |
| graphite_submit | Push the entire stack, open/update PRs, and enforce descriptions (dry-run by default) | gt submit --stack --no-edit --no-ai + gh pr edit --body-file |
| graphite_recover | Continue / abort / undo / restack | gt continue, gt abort, gt undo, gt restack |
Targeted status
Default status shows the current stack only:
graphite_status cwd=/repoFor cross-stack checks, pass explicit branches. This runs gt info <branch>
for each branch and, with includeTopology:true, returns bounded snippets
from gt log around those names instead of dumping every tracked branch.
graphite_status cwd=/repo branches=[feature-a,feature-b] includeTopology=trueGolden path
graphite_status
graphite_setup # only if repo not initialized or branch untracked
graphite_sync # at session start, or after merges
graphite_navigate action=checkout branch=… # move to the target PR / parent
# user edits files
graphite_change action=create message="…" # or action=amend
graphite_submit apply=false # review plan + required descriptions
graphite_submit apply=true confirmRemote=true descriptions=[{branch:"feature", body:"..."}]Conflict path:
# resolve files, then: git add -- <paths>
graphite_recover action=continueNever run git rebase --continue after a gt command — use
graphite_recover action=continue so Graphite propagates the resolution to
dependent branches.
Conventions and guardrails
- Every tool requires absolute
cwd. gtis invoked with--cwd <cwd> --no-interactive, no shell strings. Tools that support AI metadata pass--no-ai.- Editor / pager / browser env is forced safe (
GT_EDITOR=true,GT_PAGER=,BROWSER=true, …). Commands have a hard timeout.GRAPHITE_INTERACTIVEis deliberately not set — somegtbuilds treat it as "running inside Graphite Interactive" and silently return empty output for read commands. - Interactive editor / hunk / browser / reorder paths are not exposed.
- Commands echoed in tool output are safe to copy-paste back into a shell.
graphite_setup action=track_branchrequires explicitbranch, explicitparent, andconfirmParent:true; do not guess parent if unclear.graphite_setup action=init_repo reset:trueneedsconfirmDestructive:true.graphite_submitdefaults to--dry-run;apply:truealso needsconfirmRemote:true.--forcepush also requiresconfirmRemote:true. Before remote mutation, apply mode inspects the current stack withgh pr viewand refuses if any new PR branch (or existing empty PR body) lacks a non-emptydescriptions:[{branch, body}]entry. Aftergt submit, it writes supplied bodies withgh pr edit --body-fileand verifies the body is non-empty.graphite_syncwithforceordeleteAllneedsconfirmDestructive:true.graphite_recover action=continuerefuses to proceed if tracked files still contain<<<<<<<markers, unlessallowConflictMarkers:true.- Output is ANSI-stripped, branded ("Graphite" not "Charcoal"), and truncated to ~50 KB / 2000 lines.
- Failure output is parsed into structured
hints(notInitialized,conflictHalted,restackNeeded,trunkOutOfSync,branchNotTracked,noChangesStaged,checkedOutElsewhere,operatingOnTrunk,emptyOutput, …). - Read commands that must produce output (
graphite_status) treat an exit-0 empty stdout as a failure (emptyOutputhint) instead of a misleading "ok". - Output is also scanned (on success and failure) for non-fatal
warnings(skippedBranches,remoteChanged,alreadyMerged,needsRestack).skippedBranchesonly detects skipped branch work; prompt skip messages from non-interactive submit are ignored. A result with warnings is reported asok (with warnings)so agt sync/gt submitthat silently skipped work is not mistaken for a clean success. - A mutating command that fails appends a "partial side effects possible"
note, prompting a follow-up
graphite_status.
Git hooks
Git hooks in the target repository run as normal; this extension does not bypass them. Treat them as part of your repo's trust boundary.
License
MIT
