@manuelstolze/pi-git-integration
Pi extension for guided Git commits, pushes, and GitHub or GitLab review requests.
Package details
Install @manuelstolze/pi-git-integration from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@manuelstolze/pi-git-integration- Package
@manuelstolze/pi-git-integration- Version
1.2.2- Published
- Nov 10, 2026
- Downloads
- 966/mo · 211/wk
- Author
- manuelstolze
- License
- MIT
- Types
- extension
- Size
- 241.2 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./dist/index.js"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@manuelstolze/pi-git-integration
A Pi extension for guided Git commits, pushes, and GitHub pull requests or GitLab merge requests. It collects Git context, creates a commit plan, and asks for approval before it performs permanent Git actions.
Compatibility
Requires Node.js 22.19.0 or later and Pi API 1.5.0 or later in the 1.x line. Pi API versions below 1.5.0 are not supported by this package. Other Pi integrations in this repository keep their own compatibility ranges.
Installation
pi install npm:@manuelstolze/pi-git-integration
The extension detects the hosting provider from the origin remote. It uses
gh for GitHub and glab for GitLab. For self-hosted GitLab, the extension
probes glab against the current repository.
Install and authenticate the matching CLI if you want to use the request flow.
Usage
Run the following commands inside a Pi session:
/herald # full mode: commits, push, and review requests
/herald commit # commit mode: commits only
/herald request # request mode: push and review requests for existing commits
/herald cancel # leave an unfinished Herald workflow
Commit mode permits commits only. Request mode permits pushes and review requests for existing commits. Full mode uses a separate approval for the commit stage and the later request stage. Each approval belongs to one proposal in one run and session.
A stage is the commit work or the push and review-request work in one Herald run. Herald displays the complete proposal and exact commands in a chat message from the extension. The model reports the meaning of a later interactive or RPC (remote procedure call) reply. An RPC reply comes from a remote client connected to Pi. A clear, unconditional reply can approve the current proposal. A denial, condition, unclear reply, extension-generated input, or input queued before the proposal is displayed does not approve it. A model report reflects the model's interpretation. It is not independent proof that the reply was unconditional.
Herald does not show its own command approval dialog. You approve in chat, in your own words. Herald never needs a fixed phrase or the proposal ID. After approval, Herald runs each approved command itself, exactly as shown in the proposal. Before each command, it checks the relevant file, index, branch, remote, title, and description inputs. The index is Git's staging area. A missing approval, a changed input, or no user interface stops the command.
The extension reads CONTRIBUTING.md before it plans commits or a review
request. Request and full modes require a usable origin remote and a working,
authenticated hosting CLI. Commit mode works without either.
Approval stages and supported commands
For the commit stage, Herald shows each commit's files, complete message, and exact command. It supports only the command forms generated by Herald. These forms stage only approved literal paths and then commit the approved message:
git add -- ':(literal)<path>' && git commit -m '<message>'
Herald checks the staged and unstaged state, file contents, file mode, and untracked file contents again before the command runs. A multi-commit plan uses ordered commands and a separate checked input record for each commit. Herald does not support multi-line commit messages or other command forms. A revised plan must not repeat a completed command. A changed or unreadable input blocks the command.
For the request stage, Herald shows the source and target branches, full title, full description, exact push command, and exact request command. The source branch must be the current branch. The push uses explicit branch names:
git push origin '<source-branch>:<source-branch>'
GitHub request creation uses gh pr create with explicit --base, --head,
--title, and --body-file values. GitLab request creation uses glab mr create
with explicit --source-branch, --target-branch, --title, and
--description-file values. GitLab also uses --remove-source-branch and --yes.
A single-line description can use GitHub's --body or GitLab's --description
option instead. Herald checks the exact description file path and bytes before
request creation. Herald builds these commands; it does not accept other
command forms.
Herald keeps the existing duplicate-request check. If an open request exists for the same source and target branches, it does not create another request.
Running approved commands
After you approve a stage, the model calls herald_run_command with the
proposal ID and the command number, starting at 0, for each command in order.
Herald then checks the approval, run, session, order, single attempt, mode, user
interface, and inputs. It runs the stored command with sh -c in the
repository, with a 300-second timeout, and returns the exit code and the last
4,000 characters of standard output and standard error. A timeout counts as a
failed attempt.
During a Herald run, Herald blocks commits, pushes, and review-request creation
sent through the Bash tool. If the mode allows the action, the block reason
tells the model to use herald_run_command. If the mode does not allow it, the
reason names the mode. A wrapper prefix, such as rtk git commit, does not
hide the action. Read-only commands, such as git status, git log,
git diff, and git status && printf 'Latest commit:', still run through Bash.
Other extensions' Bash rewrites and Bash checks do not apply to approved Herald
commands, because Herald runs them through Pi's process API, not the Bash tool.
For example, rtk does not rewrite them or compress their output, and Pi Permission
Gate does not prompt for them. If you rely on a permission-gate rule for
git push, Herald's chat approval is the only check for an approved Herald
push.
Herald checks each Bash command segment separately. Segments are separated by
&&, ||, ;, |, or a newline. Words in another program's arguments, such
as printf 'Latest commit', do not count as an action. This is a text check,
not a sandbox. It does not find every indirect way to run Git or a hosting CLI,
such as a script file or an alias.
Each approved command allows one attempt. A failed commit needs a new proposal and chat approval before a retry. A failed push or request creation ends the current workflow; retry it in a new workflow. A user revision replaces unused commands but does not undo completed actions. Approval expires when its stage ends, a new proposal replaces it, Herald is cancelled or completes, or the session changes. Reload and session replacement do not resume an unfinished run.
Command checks happen before execution. Another process or Git hook can still change inputs after a check.
After git init, use /herald commit to prepare the first commit. Herald
reports that no commits exist and retains available branch and change information.
This works regardless of the language of Git error messages. Other Git failures
remain errors. Full mode also supports the first commit when its remote and
hosting-access requirements are met. The same approval rules still apply.
Workflow lifetime and cancellation
Herald stays active while it waits for an approval or a revision in chat. A proposal and a later reply belong to the same workflow, run, and session. The Herald model, thinking level, instructions, and mode checks remain active while it waits. Each stage needs its own proposal and approval.
After it shows a proposal, the model ends its turn and waits for your reply.
Herald's proposal message is not your reply. The model reports your reply with
herald_report_reply; Herald binds that report to your latest reply and shows
the bound text in the result. After approval, the model runs the approved
commands with herald_run_command. The herald_run_command,
herald_report_reply, and proposal tools are active only during a Herald run.
An active-workflow status shows the current mode and /herald cancel. The model
calls herald_finish, an operation that reports completion, terminal failure,
or cancellation. It must not call this operation while waiting for approval or
revisions. In full mode, completion includes both commits and the review request.
Herald restores the previous chat selections after the final answer finishes.
The finish report does not itself prove that Git actions succeeded.
If the model does not call herald_finish, Herald stays active. Run
/herald cancel to leave it. This also works while Herald waits for your reply.
Cancellation stops active Herald model work before cleanup and clears unused
approval. It also sends a stop signal to an approved command that is still
running.
Cancellation does not reverse completed commands, reset commits, or delete
branches. Use /herald cancel before changing to unrelated chat work. Messages
sent before Herald ends remain inside its workflow.
A terminal model error, an aborted run, reload, or session change also clears Herald. Reload and session replacement do not resume an unfinished workflow. You can start another Herald command after cleanup completes.
Herald model settings
By default, Herald uses the current chat model and thinking level. A thinking level controls how much reasoning a model performs before it answers.
To use different values during Herald, add this object to your Pi agent
settings.json or your project's .pi/settings.json:
{
"herald": {
"model": "provider/modelId",
"thinkingLevel": "high"
}
}
provider/modelId is a placeholder. Open /model to find an available model,
then use its exact provider and model ID. For example, a model ID that contains
/ stays intact after the first / separator. Partial model names are not
supported.
Both fields are optional. Accepted thinking-level names are off, minimal,
low, medium, high, xhigh, and max. A model may support only some of
these levels. Use /thinking to see its supported choices.
The user settings file is normally ~/.pi/agent/settings.json. Herald honors
PI_CODING_AGENT_DIR when that environment variable selects another agent
directory. Custom agent directories passed only by applications that embed Pi
are not discovered by this extension.
Project settings apply only when Pi trusts the project. They override user
settings per field. For example, a project can replace herald.model while
keeping the user's herald.thinkingLevel. An invalid project value does not
reactivate the user value it replaced.
Herald reads these settings at the start of every /herald, /herald commit,
or /herald request command. No /reload is needed. Edits during a run affect
only the next run. An absent field keeps the current chat value where the model
supports it. Switching models does not substitute that model's startup thinking
level for the chat level.
The selected values apply only during Herald. When the run ends or is cancelled, Herald restores the previous chat values. It also restores them before an extension reload or session change. It does not write startup defaults or edit settings files.
A model or thinking level you select manually during Herald remains selected
afterward where supported. If Herald restores the previous model and that
model cannot support your manual thinking choice, Herald restores the model,
uses a supported thinking level, and warns. Use /thinking or /model to
adjust that result. Starting another Herald command while one is active is
not supported.
Fixing settings warnings
Warnings identify the setting, its source file, the value used instead, and correction steps:
- Invalid or unknown model: Open
/model. Setherald.modelto an exact availableprovider/modelId, or remove the field. Herald uses the chat model until the setting is fixed. - Missing model authentication: Run
/loginfor the named provider, or configure that provider's credentials. You can also removeherald.model. Herald uses the chat model instead. A configured credential does not prove that a remote service will accept it; remote request failures still end the run under Pi's normal rules. - Invalid thinking level: Set
herald.thinkingLevelto an accepted name, or remove the field. Herald requests the chat thinking level instead. - Unsupported thinking level: Open
/thinkingto find a supported level, then update or removeherald.thinkingLevel. Herald keeps a usable selected model and uses a supported thinking level. - Unreadable settings or invalid JSON: Fix access or syntax in the named file before the next command. Herald ignores that file and keeps valid settings from the other source where available. It does not repair files.
- Restoration failure: Use
/modeland/thinkingto restore your choices. Check/loginif the previous model has become unavailable.
Normal shutdown and cancellation run cleanup. A forced process termination
cannot run cleanup. Temporary choices can remain in that session's transcript;
check /model and /thinking when resuming after a forced termination.
Development
From the repository root:
npm install
npm run build --workspace @manuelstolze/pi-git-integration
npm run typecheck
The extension source is in src/. The compiled entry point is
dist/index.js.
The package follows the repository's hexagonal package structure. See
../../docs/hexagonal-packages.md for the
layer and testing rules.