@senomas/pi-git-hat
Pi extension for role-based Git branch workflows — wear different hats by switching branches
Package details
Install @senomas/pi-git-hat from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@senomas/pi-git-hat- Package
@senomas/pi-git-hat- Version
1.0.0- Published
- Jul 13, 2026
- Downloads
- 3,158/mo · 286/wk
- Author
- senomas
- License
- MIT
- Types
- extension
- Size
- 1.1 MB
- Dependencies
- 1 dependency · 2 peers
Pi manifest JSON
{
"extensions": [
"./git-hat.ts",
"./extensions/hat-host-tools/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
git-hat 🧢
Wear different hats by switching git branches.
A pi extension that maps git branches to roles (researcher, planner, implementor, reviewer, admin) and enforces role-based permissions.
Install
pi install npm:@senomas/pi-git-hat
No other dependencies needed. Role prompts and roles.json are loaded from a three-tier priority chain (see Role Configuration).
Workflow
The typical workflow moves through five roles in a cycle. Use /hat to switch roles at each stage.
0. 🔬 Research — researcher branch
Before planning, use a research/* branch to explore ideas, brainstorm approaches, or gather context. This is where you remove ambiguity before writing tasks.
Interact with the AI across multiple turns: propose an approach, let the AI challenge it, refine, repeat. The output is a design doc in docs/ that captures decisions, tradeoffs, and rationale. Only once the design feels solid do you move on.
> /hat # Switch to a research branch
1. 🎨 Plan — planner branch
Write a design doc in docs/ first. Discuss it with the AI across multiple turns — expose edge cases, surface risks, clarify scope — until there's no ambiguity left.
Then ask the AI to create a todo. The AI will use the built-in tools to produce a todo/NN-name.json with properly scoped tasks.
> /hat # Switch to planner branch
> /hatt # See all pending tasks across todo files
2. ⚙️ Implement — implementor branch
Switch to an implementor branch. Run /hatt — it picks up the next task that needs work and starts implementation. The AI works through tasks, recording progress as it goes.
> /hat # Switch to implementor branch
> /hatt # Start implementing — picks next task automatically
/hatt on the implementor role shows tasks that need attention: fresh tasks, partially implemented ones, or tasks flagged with a review gap (⚠️).
3. 🔍 Review — reviewer branch
Switch to a reviewer branch. Run /hatt — it shows the review queue of fully implemented tasks waiting for sign-off. The AI reviews each task, flags gaps, and marks them done.
> /hat # Switch to reviewer branch
> /hatt # Start reviewing — shows tasks waiting for sign-off
4. 🔄 Stay in sync — /hatr anywhere
Keep your branch chain clean. /hatr auto-detects your current role and rebases onto the correct upstream branches.
> /hatr # Auto-rebase through the role chain
| Your role | Rebase targets (in order) |
|---|---|
| implementor | reviewer → planner |
| reviewer | implementor |
| planner | admin (main/master) → reviewer |
| admin | reviewer |
No confirmation prompts — invoking /hatr is itself consent. Shows the commit graph after each successful rebase.
Commands
| Command | Description |
|---|---|
/hat |
TUI branch selector — switch roles by switching branches |
/hat info |
Show current role, branch, and config info |
/hatt |
Role-aware task launcher — shows implementor or review queue |
/hatt f |
TUI filter interface — toggle filters (not started, unreviewed, blocked, signoff, done) for role-agnostic task browsing |
/hatt fn |
Next page of /hatt f results (pagination) |
/hatt impl |
Force show implementation queue (any role) |
/hatt all |
Show all tasks including done ones |
/hatt list |
Force text-only display (no TUI picker) |
/hatt summary |
Compact status bar |
/hatt regen_md |
Regenerate .md from .json for role-relevant files |
/hatt backfill |
Generate .json from orphan .md files |
/hatt migrate |
Migrate todo files to latest format (ID backfill + regen) |
/hatr |
Auto-rebase through the role chain based on current role |
/hatl [N] |
Colored git log (default 10 lines) |
/hatp |
Push current branch (+ tags) to all remotes |
/hatpo |
Push all role-matching local branches to origin |
/hatd |
Generate docs/index.md from all docs — /hatd dry-run for preview |
/hat kill |
Force-remove all podman containers for the current project |
/hat prep |
Rebuild container image from Containerfile + recreate containers |
/hatn |
Toggle network on/off for the current podman container |
/hatweb |
Toggle the webview companion UI server (dashboard + markdown rendering) — /hatweb off to stop |
/hat — Branch & Role Switching
Opens a searchable TUI listing all local branches grouped by their role. Shows "← current" and "← last used" indicators. After switching, shows a colored git log automatically.
Subcommands:
| Subcommand | Description |
|---|---|
/hat info |
Show current role, branch, and config info |
/hat prep |
Rebuild container image from Containerfile + recreate containers |
/hat kill |
Force-remove all podman containers for the current project |
WebUI — Companion Dashboard & Markdown Server
The /hatweb command starts a browser-based companion UI on localhost:
> /hatweb # Start server (random port >10000)
> /hatweb off # Stop server
> /hatweb open # Start + open in default browser
Dashboard
A real-time view of your pi session: prompt history, turn status (thinking/running/done), expandable message detail, message input, and an abort button. Updated live via Server-Sent Events. Designed as a companion, not a replacement — all input also goes through the terminal.
Markdown Viewer
Browse and view any .md file in your project rendered as styled HTML with Catppuccin theming and Mermaid diagram support. Available at /md/* routes on the same port.
Auto-Start
Add a webui section to .pi-project.json and the server starts automatically on every session:
{
"webui": {
"host": "127.0.0.1",
"port": 9876
}
}
See docs/webview-tui-design.md for full design.
/hatt — Role-Aware Task Launcher
The central command for the implement ↔ review loop:
| Role | Shows | Action |
|---|---|---|
| implementor | Tasks needing work: fresh, partial, or gap-fix | TUI picker → auto-starts task, creates phased sub-tasks for complex items |
| reviewer | Tasks fully implemented, waiting for sign-off | Flat list → review queue |
| other | All undone tasks with state | General status overview |
On the implementor role, /hatt also runs an ancestry check to verify the current branch is based on the correct ancestor branches. If not, it blocks with a warning until you rebase.
/hatt f — TUI Filter Interface
/hatt f opens a role-agnostic task browser with toggleable filter checkboxes, decoupled from the role-aware /hatt queue. It replaces the need to switch roles just to see what's happening in the project.
Five filters (OR logic — a task matches if it satisfies any active filter):
| Filter | Matches tasks that… |
|---|---|
| not started | Have no implementation or all impl blocks are incomplete |
| unreviewed | Have implemented work that hasn't been reviewed yet |
| blocked | Have an unresolved review gap (⚠️) |
| signoff | Are fully reviewed without gaps but not yet marked done |
| done | Are marked done: true |
Role presets — when opened without flags, the TUI pre-toggles filters matching your role (planner → not started; implementor → unreviewed + blocked; reviewer → unreviewed + signoff). Toggling any filter manually overrides the preset.
Keyboard shortcuts within the TUI:
| Key | Action |
|---|---|
↑ ↓ / j k |
Navigate |
Space |
Toggle selected filter checkbox |
Tab |
Switch between filter panel and task list |
1–5 |
Toggle filter by number |
t |
Toggle "show done tasks" |
Enter |
Apply filters and display results |
Esc / q |
Cancel |
Pagination — results are limited to 10 tasks per page. Use /hatt fn to load the next page.
> /hatt f # Open TUI with role-preset filters
> /hatt f --done # Pre-select done filter
> /hatt fn # Next page of results
See docs/hatt-f-tui.md for the full design.
Todo File Format
JSON is the source of truth. Each todo/NN-name.json is automatically rendered to a human-friendly todo/NN-name.md.
{
"meta": {
"nn": 42,
"name": "my-feature",
"goal": "Implement my feature"
},
"tasks": [
{
"title": "Build the widget",
"done": false,
"detail": "Create the main widget component with these sub-steps:\n- Design the API\n- Implement the logic\n- Write tests",
"impl": [
{
"checked": true,
"note": "Implemented widget API in src/widget.ts",
"reviews": []
}
]
}
]
}
The .md file is auto-generated and should never be edited manually.
Role-Branch Mapping
Branch names determine the active role. The mapping is defined in roles/roles.json via an ordered patternRouting array — first match wins:
| Branch pattern | Role |
|---|---|
.*\.plan$ |
planner (override: any *.plan suffix) |
.*\.review$ |
reviewer (override: any *.review suffix) |
plan/*, plan-*, plan |
planner |
feat/*, feat-*, feat |
implementor |
feature/*, feature-* |
implementor |
impl/*, impl-*, impl |
implementor |
work/*, work-* |
implementor |
implementor |
implementor (exact match only) |
review/*, review-*, review |
reviewer |
main, master |
admin |
research/*, research-*, research |
researcher |
The first two entries (.*\.plan$, .*\.review$) are override patterns — they let any branch take on the planner or reviewer role by suffix, regardless of prefix. For example, feat/my-feature.plan is detected as planner, not implementor.
The mapping is fully configurable — add, reorder, or replace entries in patternRouting. See docs/role-branch-mapping.md for the full design.
Role Configuration
Roles are defined in roles/roles.json with optional descriptions, path permissions, and the patternRouting array:
{
"roles": {
"planner": { "description": "Plan work by creating todo files" },
"implementor": { "description": "Implement features from todo files" },
"reviewer": { "description": "Review implementations" },
"admin": { "description": "Configuration and docs" },
"researcher": { "description": "Research topics and document findings" }
},
"patternRouting": [
{ "pattern": ".*\\.plan$", "role": "planner" },
{ "pattern": "^plan(-|/|$)", "role": "planner" },
{ "pattern": "^feat(-|/|$)", "role": "implementor" },
{ "pattern": "^review(-|/|$)", "role": "reviewer" },
{ "pattern": "^(main|master)$", "role": "admin" }
]
}
Loaded from a three-tier priority chain:
.pi/roles.json(project-local, highest priority)roles/roles.json(project-level)- Extension-bundled (fallback)
Role-specific system prompts follow the same chain: .pi/{role}.md > roles/{role}.md > extension-bundled > built-in fallback.
Per-Project Environment Config (.pi/config)
.pi/config is a simple key=value file for per-project environment overrides.
It's read by podman-bash.ts (when running inside Podman containers),
lib/config.ts (for hat tools), and can be consumed by Makefiles and shell scripts.
Format
# Comments start with #
# Blank lines are ignored
# Tool-specific key: <tool>.<setting>=<value>
go.gomodcache=./.go/pkg/mod
# Direct env var: env.<VARNAME>=<value>
env.GOMODCACHE=./.go/pkg/mod
Path resolution: ./ → relative to project root, / → absolute, other → literal.
Tool Key → Env Var Mapping
Tool keys auto-derive env vars. Explicit env.* entries take precedence.
| Tool key | Derived env var | Purpose |
|---|---|---|
go.gomodcache |
GOMODCACHE |
Go module cache dir |
go.gopath |
GOPATH |
Go workspace path |
rust.target-dir |
CARGO_TARGET_DIR |
Cargo build artifacts |
rust.cargo-home |
CARGO_HOME |
Cargo home cache |
node.registry |
npm_config_registry |
npm registry URL |
node.cache |
npm_config_cache |
npm cache dir |
python.venv |
VIRTUAL_ENV |
Python virtual env path |
python.cache-dir |
PIP_CACHE_DIR |
pip cache dir |
See docs/pi-config-format.md and
docs/usage-in-other-projects.md for full details.
Permission Enforcement
Each role has write boundaries enforced via tool call interception:
| Role | Can Write To | Blocked From |
|---|---|---|
| Planner | todo/, plan/, docs/*.md |
Everything else |
| Implementor | Source files | todo/, plan/, .pi/ |
| Reviewer | todo/ (review notes, mark done) |
Everything else |
| Admin | .pi/, root *.md |
Everything else |
| No match | Nothing (strict read-only) | Writes + destructive bash |
Security
- Podman sandbox — Bash commands execute inside a Podman container, not on the host. Role-based volume mounts (
rw/ro) are enforced at the kernel level. - Role-based write permissions — Each role's write boundaries are enforced via tool call interception (see Permission Enforcement above).
- Network off by default — Containers start with
--network=none. Network access requires explicit user consent via thehat_enable_networktool or/hatncommand. - Host tools with user consent —
hat_make,hat_python, andhat_podmanrun on the host, guarded by a trust registry and user confirmation dialogs. - Full security architecture — See
docs/developer.mdfor the complete security design, including sandbox internals, escape hatches, OCI hooks, and the network firewall model.
For Contributors
git-hat is self-hosted — it is developed using itself. The four role branches (planner → implementor → reviewer → admin) form the development pipeline, driven by AI through the git-hat toolchain.
For architecture, project structure, build instructions, and contributing workflow, see docs/developer.md.
License
MIT