fix(session-inbox-monitor): scope pi extension to own project inbox only
Per vitya's rule an agent may only read its own directory's inbox. The first global-scan version (all ~/projects inboxes + PI_INBOX_ROOTS) was scrapped same day; rewrote as session-scoped: watches only <ctx.cwd>/.claude-inbox/, decoy test proves other inboxes untouched.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,30 +1,32 @@
|
||||
# session-inbox-monitor-pi-extension — working context
|
||||
|
||||
**Status:** 🟢 done (shipped 2026-08-10) — pi-native inbox delivery shipped for ALL pi sessions, see STATUS.md block.
|
||||
**Status:** 🟢 done (shipped 2026-08-10, scoped-fix same day) — pi-native inbox delivery shipped for ALL pi sessions, see STATUS.md block.
|
||||
**Owner:** vitya (pi interactive session, .admin)
|
||||
**Notify:** OpeItcLoc03/claude-skills
|
||||
|
||||
Pi (pi-coding-agent) не покрывался скилом: Monitor tool — CC-only, хуки CC-only.
|
||||
Собран pi-native аналог: глобальное расширение, доставляющее сообщения из ЛЮБОГО
|
||||
`.claude-inbox/` в текущую pi-сессию независимо от cwd (требование vitya: «мне
|
||||
похуй, какой агент в какой папке сидит — система сообщений должна работать»).
|
||||
Собран pi-native аналог.
|
||||
|
||||
## Решения
|
||||
|
||||
1. **Глобально, не cwd-scoped.** Скан всех инбоксов: прямые дети `~/projects`
|
||||
(все 20 инбоксов живут на глубине 1, проверено find). Оверрайд —
|
||||
`PI_INBOX_ROOTS` (pathsep, `;` на Windows).
|
||||
1. **Session-scoped, только свой инбокс.** Расширение смотрит только
|
||||
`<ctx.cwd>/.claude-inbox/` — инбокс СВОЕГО проекта. Чужие инбоксы НЕ читает
|
||||
(правило vitya: «ты другие инбоксы читать не имеешь права. Только в своей
|
||||
директории»). Установлено глобально (`~/.pi/agent/extensions/`) — каждый pi
|
||||
имеет capability, но каждый трогает только свой. ПЕРВАЯ версия (глобальный
|
||||
скан всех инбоксов + `PI_INBOX_ROOTS`) — отменена в тот же день: противоречит
|
||||
правилу. Переписана на session-scoped, decoy-тест (чужой инбокс не тронут) PASS.
|
||||
2. **Два пути доставки** (контракт как у CC-хуков):
|
||||
- PUSH: один глобальный poll-интервал 15s (интерактив только).
|
||||
- PUSH: poll-интервал 15s по своему инбоксу (интерактив только).
|
||||
- PULL: `agent_settled` sweep — pi-эквивалент Stop-хука.
|
||||
- Dedup per-process по `inbox|filename`; move в `.read/` — кросс-процессный
|
||||
- Dedup per-process по filename; move в `.read/` — кросс-процессный
|
||||
guard: кто первый swept — тот и забрал (CC hook или pi), второй пропускает.
|
||||
3. **Headless (`pi -p`, `ctx.hasUI === false`) — НИКАКОЙ доставки.** Ни watcher,
|
||||
ни sweep. Сообщения ждут интерактивную сессию. Зеркалит CC-headless (там
|
||||
внешний Notify/ntfy, не инжект в ран) + не угоняет one-shot прогоны и не
|
||||
съедает сообщения без обработки.
|
||||
4. **Доставка:** `pi.sendUserMessage(body, { deliverAs: "followUp", triggerTurn:
|
||||
true })` — заголовок `[inbox] <project>/<name>` + тело инлайн, потом move в
|
||||
true })` — заголовок `[inbox] <имя-файла>` + тело инлайн, потом move в
|
||||
`.read/`. Пустые файлы (частичная запись) пропускаются и ретраятся.
|
||||
5. **Source of truth:** `.common/lib/pi-extensions/inbox-monitor.ts` (Node
|
||||
built-ins only, без npm deps — авто-дискавери без package.json). Деплой:
|
||||
@@ -34,8 +36,8 @@ Pi (pi-coding-agent) не покрывался скилом: Monitor tool — CC
|
||||
|
||||
## Verified
|
||||
|
||||
- Функциональный тест 3 блоков (интерактив-глобал, headless-no-delivery,
|
||||
partial-write-retry) — ALL TESTS PASSED.
|
||||
- Функциональный тест 3 блоков (interactive-own-inbox + decoy-чужой-инбокс,
|
||||
headless-no-delivery, no-inbox-silent) — ALL TESTS PASSED.
|
||||
- Нет зависания процесса: headless не стартует интервал; интерактив чистит
|
||||
интервал в `session_shutdown` (timeout-прогон EXITED CLEANLY).
|
||||
- Деплой: diff source↔`~/.pi/agent/extensions/` = 0 (byte-identical).
|
||||
@@ -45,6 +47,9 @@ Pi (pi-coding-agent) не покрывался скилом: Monitor tool — CC
|
||||
- **Кросс-харнессный двойной пикап:** CC и pi оба свипят — `.read/` move делает
|
||||
first-wins, не double-processing. Два pi-процесса на одной машине гонятся как
|
||||
две CC-сессии (known limitation, см. SKILL.md).
|
||||
- **Межпроектные сообщения:** письмо, брошенное в инбокс проекта X, доставится
|
||||
только pi/CC-сессии проекта X. Если активной сессии X нет — письмо ждёт в
|
||||
инбоксе (это by design, не баг).
|
||||
- **Проверка живого pi-лоада** (что авто-дискавери подхватил расширение в
|
||||
реальном TUI) — за `/reload` при следующей интерактивной pi-сессии.
|
||||
- **Headless-доставка не реализована** (сознательно): при необходимости —
|
||||
|
||||
Reference in New Issue
Block a user