Expose theme-aware status widget integration

This commit is contained in:
jb
2026-08-30 13:00:14 -04:00
parent 9a8169523b
commit bc3e3d6049
4 changed files with 871 additions and 146 deletions
+20 -5
View File
@@ -11,10 +11,9 @@ The backend is selected automatically: Herdr is used when Pi runs in a Herdr-man
`subagent()` returns immediately. In Herdr, the sub-agent runs in a new unfocused tab in the current workspace. In tmux, it runs in a right split off the parent Pi pane. A live widget above the input tracks every running sub-agent, and when one finishes, its result is steered into the main session as a notification that triggers a new turn.
```
╭─ Subagents ──────────────────────────── 2 running ─╮
│ 00:23 scout active · bash 7m │
│ 00:45 scout-2 waiting 2m │
╰────────────────────────────────────────────────────╯
Subagents 2 running
⟳ 00:23 scout active · bash 7m
○ 00:45 scout-2 waiting 2m
```
Spawn several in parallel — they run concurrently and steer results back independently as each finishes.
@@ -148,7 +147,23 @@ Access is **whitelist-only**. Every sub-agent process is launched with `--no-ext
Spawns must name a known agent at **every** depth. A top-level session may spawn anything discoverable; a sub-agent may only spawn the agents in its `subagent_agents` list (enforced via `PI_SUBAGENT_ALLOWED`). There is no agentless spawn route, so a child can never escalate to a full-toolset profile by omitting its agent.
Extensions can register additional tools for sub-agents at runtime via `registerToolExtension(name, path)` on the `__pi_interactive_subagents` process global.
Extensions can register additional tools for sub-agents at runtime via `registerToolExtension(name, path)` on the `__pi_interactive_subagents` process global. Hosts that compose widgets can optionally use its reload-safe `statusWidget` surface:
```typescript
const { statusWidget } = globalThis.__pi_interactive_subagents;
const onChange = () => rerender();
const release = statusWidget.claim(onChange);
statusWidget.hasContent(); // whether any subagent rows exist
statusWidget.getBodyRowCount(); // uncapped number of running agents
statusWidget.render(width, maxBodyRows, ctx.ui.theme); // compact unboxed lines; cap includes an overflow row
statusWidget.isClaimed(onChange); // true only for the current provider claim
release(); // restore the standalone subagent-status widget
```
`render(width, maxBodyRows?, theme?)` accepts Pi's current theme as an optional structural value. The standalone widget receives and uses its own Pi theme automatically. When no theme is passed, a legacy ANSI fallback keeps status colors usable. The header is a compact unboxed `Subagents <count> running` row; body rows remain width-safe, and `maxBodyRows` counts body rows including the overflow summary, not the header. Semantic row colors match Pi's Todo conventions: accent header, muted count, warning active/running, error stalled, dim starting/provider tags/elapsed time, and accent waiting.
`claim()` replaces any prior claim, and an old release function cannot release a newer claim. Standalone-widget clearing/restoration is deferred to a microtask, so hosts may release and immediately re-claim without a transient fallback widget. `isClaimed(onChange)` checks both callback identity and the current runtime ownership, so hosts can detect invalidation after reload/session rebind. Claims are cleared during session shutdown, including `/reload`, so a fresh host runtime must claim again rather than retaining a stale callback. Calling `render()` directly does not claim or change the standalone widget.
## Role folders