@giladbarnea/pi-user-agents
Run, view, and control background Pi agents.
Package details
Install @giladbarnea/pi-user-agents from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@giladbarnea/pi-user-agents- Package
@giladbarnea/pi-user-agents- Version
0.0.8- Published
- Sep 9, 2026
- Downloads
- 1,278/mo · 504/wk
- Author
- giladbarnea
- License
- MIT
- Types
- extension
- Size
- 486.9 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-user-agents
You deserve your own agents, too. It's only fair.
No token tax. No derailed turns. No trace — unless you say so.
Pi extensions give your agent subagents. This one gives you — the user — your own: background agents you dispatch mid-turn, watch live, steer, and whose results stay out of the main agent's context until you decide otherwise.
Why
You're watching your agent grind through phase 1, and you already know what phase 2 needs.
You have two options, and both are bad. Steer — and derail the work in progress with an errand. Wait — and carry the thought in your head for twenty more minutes.
Now there's a third:
/agent plan the next phase and write it to phase-2.md
The instant you press Enter, a background agent forks off with a snapshot of the current conversation and gets to work — while your main agent keeps going, none the wiser.
A second pair of hands with the same memory — and a separate token budget.
Install
pi install npm:@giladbarnea/pi-user-agents
The loop
1. Dispatch
/agent <task> starts a background agent with the current conversation as its starting context — it knows everything the main agent knows up to that moment. /agent -i <task> starts one with a blank slate instead. Dispatch as many as you like; they run concurrently.
Classic dispatches:
/agent write a handoff document for the work currently in progress
/agent -i -m flash summarize what PARSER_SPEC.md guarantees
/agent -s --thinking high find the root cause of the flaky widget test
The first preserves the session's knowledge before the context window fills, without interrupting the main agent to do it. The second is a cheap, isolated errand. The third auto-squashes: its findings are delivered into the main conversation when it finishes.
2. Watch
Every agent gets a row in a widget under the editor: status, task, model, turn count, tool uses, elapsed time, a one-cell context meter, and the last line of live activity.
Press ← or ↓ from the editor to focus the widget. The selected row shows a short session ID and offers the same agent actions as the overlay. Press Enter to open the full conversation, streaming live and following the tail as it grows. Tool calls render as proper views — read, edit, write, grep, find, ls, and bash each get a dedicated format, everything else a readable generic one.
3. Steer
A background agent is not fire-and-forget — it's a session you can talk to.
Press Enter in the overlay to open the steer composer. Mid-turn, your message queues in after the current tool batch, before the next model call — exactly like steering the main agent. After the turn completes, the same composer starts another turn on the same live session. Follow up as many times as you need. Read each response in the agent overlay.
Ctrl+x interrupts only the current turn — the agent goes idle and stays available for steering, squashing, or detaching. In fact, nothing ends an agent except you: pressing d twice, squashing or rebasing it, or ending the Pi session.
4. Detach
When a row has served its purpose, press d twice: the agent stops, its row leaves the widget, and its session file is left untouched. The transcript records which one it was:
Detached session 0199c4f2-8b1a-7c3d-9e05-6a2f18d7b4ce
Pick it back up whenever you like — /resume 0199c4f2, or pi -r and choose it from the list. It resumes as an ordinary Pi session with its full history, its model, and its thinking level, and from there it is a normal agent you talk to directly.
Or take it back as a background agent instead: /agent-attach 0199c4f2 puts the session back in the widget — parked idle, restored as dispatched down to its --tools and the rest of its options — and offers to open it. A unique id prefix is enough, only this conversation's own agents qualify, and the transcript records the return: Attached session 0199c4f2-….
5. Squash — or don't
This is what makes user agents different from subagents: by default, the main agent never learns any of this happened.
Completed responses stay in the agent overlay, accessible through the widget below the editor. Completion adds no transcript card. Ask an agent ten questions and your main agent's token budget does not move.
When a result does belong in the main conversation, squash it in:
- Dispatch with
-s/--squashand the result is delivered automatically on completion. - Or press
sin the overlay of any completed agent, whenever you decide it earned its place.
A squash delivers a compact record, not a transcript dump: every message you sent the agent and the final answer to each — no thinking, no tool traffic. The record is rebuilt from the agent's full history at squash time, so early turns survive even after the agent compacts its own context. If the main agent is mid-turn, the record is steered in; if idle, it triggers a turn. Squash adds no transcript card. A squashed agent retires; its overlay stays readable.
6. Or rebase — rewrite history
Squash has a raw sibling. Press r in the overlay and the agent's whole conversation — prompts, replies, tool calls and their results — is appended to the main session as ordinary messages, exactly as if you had prompted the main agent all along. The dispatch preamble is stripped, nothing is wrapped or summarized, and no trace remains that a background agent ever existed.
Everything the agent lived through rides along untouched. If it compacted its own context mid-run, the compaction rides along too, and the main conversation's context picks up exactly where the agent's left off. The transcript redraws with the conversation inline, plus one dim provenance line:
Rebased session 01a0534e-9fa7-7d6f-bd44-b85fba1f5e05 into this conversation (added 32 messages, ~135K tokens, 1 compaction event)
Rebase is a fast-forward, in the git sense: the agent forked from the main conversation's tip, and its history can graft back only while that tip hasn't moved. Send the main agent anything after the dispatch and r disappears, leaving s — which always works — as the way in. Press r anyway and the footer tells you why not.
Delivering the rebase switches the session in place — same file, same session id, transcript redrawn — so r is withheld while any agent is mid-turn, and parked agents are detached first, each leaving its Detached session … line to /resume from. When siblings would be detached, the first r warns with the count and a second r confirms.
The mechanics
🎛️ Per-dispatch configuration
Each agent takes its own configuration, using the same flags as the pi CLI:
/agent -m opus --thinking high design the caching layer
/agent --tools read,grep,find audit the error handling in src/
/agent -i --system-prompt "be terse" what does the session-format doc guarantee?
Options come first; everything after them is your task, verbatim. The full grammar lives in PARSER_SPEC.md — not that you'll need it.
✨ The fanciest autocomplete in the Pi universe
You'll rarely type any of this by hand. The moment you type -, a completion menu opens — no Tab needed. Anywhere the set of valid values is finite, the editor hands it to you: models, providers, thinking levels, the session's tools, even skill and prompt-template paths. You pick from what actually exists instead of typing and hoping.
And what you do type by hand is checked live, as you type. Valid options and values light up in your theme's syntax colors; anything that won't parse — a blocked option, a model that doesn't resolve, an option stranded after the task began — shows in the error color before you ever press Enter. A /agent line that looks right is right.
🧱 Agents are durable Pi sessions
Every dispatch writes a real session file, exactly like the one you're sitting in, so dispatched agents show up in /resume and pi -r alongside your own sessions.
The widget does not survive a session reload. Each agent's session remains on disk, accessible through /resume or /agent-attach. Completion cards from older versions stay hidden.
🌡️ A context meter in one cell
Each row carries the agent's own footer gauge: it fills ▁▂▃▄▅▆▇█ against that agent's model context window and shifts color through the same stages as Pi's footer — dim, then muted at 40%, warning at 65%, error at 85%. You see an agent approaching its limit before it becomes a problem.
Reference
Everything goes through one command: /agent [options] <task>. Its one companion, /agent-attach <session-id>, brings a detached session back into the widget.
| Flag | Effect |
|---|---|
-i, --isolate |
Start without the conversation snapshot |
-s, --squash |
Deliver the result into the main context on completion |
-m MODEL |
Model for this agent (alias of Pi's --model) |
| pi CLI options | Forwarded to the agent — --thinking, --tools, --system-prompt, … |
| Where | Key | Action |
|---|---|---|
| Editor | ← / ↓ |
Focus the agents widget |
| Widget | ↑ ↓ · Enter |
Select an agent · open its overlay |
| Widget / overlay | Ctrl+x |
Interrupt the current turn (agent stays alive) |
| Widget / overlay | d d |
Detach the agent, keeping its session (twice to confirm) |
| Widget / overlay | Esc |
Back |
| Overlay | Enter |
Steer mid-turn, or start another turn when idle |
| Widget / overlay | s |
Squash the conversation into the main context |
| Widget / overlay | r |
Rebase the raw conversation into the main context (fast-forward only) |
| Widget / overlay | c |
Copy the latest response |
| Widget / overlay | i |
Copy the agent's full session ID |
| Overlay | scroll · End |
Pause tail-following · resume it |
Good to know
- Some accepted
pioptions have no effect on a background run (the session, approval, offline, and API-key families). They parse; they just don't do anything yet. candicopy viapbcopy, so they are macOS-only for now.- The overlay caps very large tool outputs and omits thinking entries.
Roadmap
- Agents stay alive until you end them — steer, interrupt, resume, across turns.
- Squash: a compact record of the exchange, delivered into the main context.
- Rebase: the raw conversation grafted onto the main session — fast-forward only, compaction-faithful.
- Attach: a detached session returns to the widget, restored as dispatched.
- Live syntax coloring and eager autocomplete for the
/agentline. - Render an agent's compaction event in the overlay.
- Wire the accepted-but-inert
pioptions. - Clipboard support beyond macOS.
Under the hood
Design notes — result delivery through the Pi SDK, the squashed-message format, the rebase and attach mechanisms, runtime sharing, model resolution, and editor internals — live in INTERNALS.md. The complete command grammar lives in PARSER_SPEC.md.
Heavily inspired by tintinweb/pi-subagents.