Compare commits
3 Commits
5fc0ccc1d3
...
6ab4634b44
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ab4634b44 | |||
| 07e782040d | |||
| a0491e00fd |
File diff suppressed because one or more lines are too long
56
.tasks/session-inbox-monitor-pi-extension.md
Normal file
56
.tasks/session-inbox-monitor-pi-extension.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# 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, отдельная задача.
|
||||||
41
skills/browser-cdp/SKILL.md
Normal file
41
skills/browser-cdp/SKILL.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
name: browser-cdp
|
||||||
|
version: 0.1.0
|
||||||
|
description: >
|
||||||
|
Веб-автоматизация через минимальные CDP CLI-тулы в bash — вместо playwright-mcp
|
||||||
|
/ Chrome-DevTools-MCP (подход «what if you don't need MCP»). Запуск Chrome с remote
|
||||||
|
debugging, навигация, eval JS, скриншоты. Trigger: «браузер», «скрейпинг», «открой
|
||||||
|
страницу», «перейди на», «сделай скриншот», «playwright», «веб-автоматизация»,
|
||||||
|
«web scraping», «browser».
|
||||||
|
---
|
||||||
|
|
||||||
|
# browser-cdp
|
||||||
|
|
||||||
|
Минимальный набор браузерных тулов через bash + CDP, ноль зависимостей и ноль MCP-оверхеда.
|
||||||
|
|
||||||
|
## Когда использовать
|
||||||
|
|
||||||
|
Браузерная работа со страницами: открыть/навигировать, выполнить JS в контексте страницы,
|
||||||
|
снять скриншот, собрать данные (скрейпинг). Использовать **вместо** playwright-mcp или
|
||||||
|
Chrome-DevTools-MCP.
|
||||||
|
|
||||||
|
## Процесс
|
||||||
|
|
||||||
|
1. **Прочитай полную справку** (обязательно, первый шаг):
|
||||||
|
`read ~/projects/.common/scripts/browser/README.md` — там все тулы, примеры и ограничения.
|
||||||
|
2. **Старт** (если CDP ещё не поднят): `node ~/projects/.common/scripts/browser/start.js`
|
||||||
|
— идемпотентно, повторный вызов просто подтверждает.
|
||||||
|
3. Работай через bash из любой директории:
|
||||||
|
- `node ~/projects/.common/scripts/browser/nav.js <url> [--new]`
|
||||||
|
- `node ~/projects/.common/scripts/browser/eval.js '<js>'` — результат JSON в stdout
|
||||||
|
- `node ~/projects/.common/scripts/browser/screenshot.js [out.png] [--full]`
|
||||||
|
- `node ~/projects/.common/scripts/browser/list.js` — вкладки (диагностика)
|
||||||
|
4. **Композиция:** результат eval'а можно перенаправлять в файл и обрабатывать дальше
|
||||||
|
(`> /tmp/data.json`), скриншот читать через `read` (PNG как изображение).
|
||||||
|
|
||||||
|
## Правила
|
||||||
|
|
||||||
|
- Никаких `curl`-эмуляций браузера: если нужен JS/рендер/локальная сессия — только эти тулы.
|
||||||
|
- Не открывай второй Chrome поверх уже работающего: `start.js` идемпотентен, повторный вызов безвреден.
|
||||||
|
- Если `eval.js` падает с `Exception:` — исправляй выражение (часто нужно `JSON.stringify(...)` внутри, т.к. `returnByValue`).
|
||||||
|
- Один тул — одно действие. Не пиши «веб-скрейпинг-скрипт», собирай из тулов.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: session-inbox-monitor
|
name: session-inbox-monitor
|
||||||
version: 0.2.2
|
version: 0.3.0
|
||||||
description: >
|
description: >
|
||||||
Raises a persistent Monitor (Monitor tool, NOT background Bash) on the
|
Raises a persistent Monitor (Monitor tool, NOT background Bash) on the
|
||||||
project's `.claude-inbox/` at the start of an interactive session, so
|
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 «подними монитор почты»,
|
CLAUDE.md line `inbox monitor: raise on start`, or «подними монитор почты»,
|
||||||
«настрой авто-монитор инбокса», «raise inbox monitor», «auto-arm inbox
|
«настрой авто-монитор инбокса», «raise inbox monitor», «auto-arm inbox
|
||||||
watcher». Headless (`claude -p`): does NOT raise — Monitor doesn't work
|
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 the session's own project inbox
|
||||||
|
messages (own directory only, see the Pi section). NOT for how to
|
||||||
handle a received message (→ inter-session-peer-discipline) nor the
|
handle a received message (→ inter-session-peer-discipline) nor the
|
||||||
multi-machine inbox backend (→ cross-machine-inbox design).
|
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
|
- **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.
|
machine-local; only this skill (docs) and `.claude-inbox/` activity are in play.
|
||||||
|
|
||||||
|
## Pi (pi-coding-agent) support — session-scoped global extension
|
||||||
|
|
||||||
|
Same contract, pi-native, and **session-scoped**: the extension watches ONLY the
|
||||||
|
current session's project inbox (`<ctx.cwd>/.claude-inbox/`) — it never reads
|
||||||
|
other projects' inboxes (vitya's rule: an agent may only read its own
|
||||||
|
directory's inbox). Installed globally so *every* pi session has the
|
||||||
|
capability, but each session only ever touches its own project's inbox.
|
||||||
|
|
||||||
|
- **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`
|
||||||
|
(incl. decoy check — another project's inbox is never touched).
|
||||||
|
- **Opt-in per project** — same as CC: `.claude-inbox/` dir exists OR CLAUDE.md
|
||||||
|
line `inbox monitor: raise on start`.
|
||||||
|
- **PUSH:** 15s poll of the session's own inbox (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
|
## What NOT to do
|
||||||
|
|
||||||
- **Don't watch the inbox with a background Bash** (`run_in_background`) — it
|
- **Don't watch the inbox with a background Bash** (`run_in_background`) — it
|
||||||
|
|||||||
Reference in New Issue
Block a user