Files
skills/.tasks/2026-08-10-00942-session-inbox-monitor-pi-extension.md

4.4 KiB
Raw Blame History

session-inbox-monitor-pi-extension — working context

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 аналог.

Решения

  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 по своему инбоксу (интерактив только).
    • PULL: agent_settled sweep — pi-эквивалент Stop-хука.
    • 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] <имя-файла> + тело инлайн, потом move в .read/. Пустые файлы (частичная запись) пропускаются и ретраятся.
  5. Source of truth: .common/lib/pi-extensions/inbox-monitor.ts (Node built-ins only, без npm deps — авто-дискавери без package.json). Деплой: копия в ~/.pi/agent/extensions/inbox-monitor.ts (global → все pi, все директории). Hot-reload /reload. Тест: inbox-monitor.test.mjs (node --experimental-strip-types, Node ≥22.6).

Verified

  • Функциональный тест 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).

Open questions / failure modes

  • Кросс-харнессный двойной пикап: 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-доставка не реализована (сознательно): при необходимости — внешний Notify/ntfy, отдельная задача.