feat(session-inbox-monitor): pi support — global extension section, v0.3.0

Pi (pi-coding-agent) sessions get inbox delivery via global extension
(.common/lib/pi-extensions/inbox-monitor.ts → ~/.pi/agent/extensions/).
Not cwd-scoped: any .claude-inbox/ message pages the current session with
project name in header. Headless = no delivery. SKILL.md v0.2.2→v0.3.0.
This commit is contained in:
2026-08-10 22:43:18 +03:00
parent 5fc0ccc1d3
commit a0491e00fd
3 changed files with 95 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
---
name: session-inbox-monitor
version: 0.2.2
version: 0.3.0
description: >
Raises a persistent Monitor (Monitor tool, NOT background Bash) on the
project's `.claude-inbox/` at the start of an interactive session, so
@@ -11,7 +11,9 @@ description: >
CLAUDE.md line `inbox monitor: raise on start`, or «подними монитор почты»,
«настрой авто-монитор инбокса», «raise inbox monitor», «auto-arm inbox
watcher». Headless (`claude -p`): does NOT raise — Monitor doesn't work
there; rely on the Stop-hook inbox pickup + Notify/ntfy. NOT for how to
there; rely on the Stop-hook inbox pickup + Notify/ntfy. Pi (pi-coding-agent)
sessions: a global extension delivers any `.claude-inbox/` message to the
current session regardless of cwd (see the Pi section). NOT for how to
handle a received message (→ inter-session-peer-discipline) nor the
multi-machine inbox backend (→ cross-machine-inbox design).
---
@@ -127,6 +129,39 @@ for free on session end. Headless sessions skip it and rely on the pull-model
- **No repo writes.** The hook and its `~/.claude/settings.json` registration are
machine-local; only this skill (docs) and `.claude-inbox/` activity are in play.
## Pi (pi-coding-agent) support — global extension
Same contract, pi-native, and **not cwd-scoped**: which folder the pi session
sits in is irrelevant — every `.claude-inbox/` under the configured roots is
watched and swept; a message pages the *current* pi session with the project
name in the header (`[inbox] <project>/<name>` + body inline, then moved to
`.read/`).
- **Source of truth:** `.common/lib/pi-extensions/inbox-monitor.ts` (Node
built-ins only, no npm deps). Deploy: copy to
`~/.pi/agent/extensions/inbox-monitor.ts` (global → every pi, every
directory), hot-reload with `/reload`. Test:
`node --experimental-strip-types .common/lib/pi-extensions/inbox-monitor.test.mjs`.
- **Roots:** direct children of `~/projects` by default (all inboxes live there,
depth 1); override with `PI_INBOX_ROOTS` (pathsep-separated, `;` on Windows).
- **PUSH:** one 15s global poll while a session is live (interactive only).
**PULL:** `agent_settled` sweep — the pi equivalent of the CC Stop-hook
pickup. Both share one dedup set per process; the `.read/` move is the
cross-process guard — first sweeper (CC hook or pi) claims the message, the
other skips it.
- **Headless (`pi -p`, `ctx.hasUI === false`):** NO delivery — no watcher, no
sweep. Messages sit in the inbox until an interactive session picks them up.
Mirrors CC headless (external Notify there, nothing in-run) and avoids
hijacking one-shot scripted runs or consuming messages nobody processes.
- **Delivery:** `pi.sendUserMessage(body, { deliverAs: "followUp", triggerTurn:
true })` — paged into the transcript as a user message; the agent handles it
per `inter-session-peer-discipline`. Partial writes (empty file) are skipped
and retried next poll.
- **Failure mode — cross-harness double-pickup:** CC and pi both sweep; the
`.read/` move makes it first-wins, not double-processing. Two live pi sessions
in one process tree share the dedup set; two pi *processes* on one machine
race like two CC sessions (known limitation, see Failure modes above).
## What NOT to do
- **Don't watch the inbox with a background Bash** (`run_in_background`) — it