From 231c65186879ef19a60da09e0ca93cbaf0804777 Mon Sep 17 00:00:00 2001 From: max Date: Fri, 7 Aug 2026 18:08:10 +0300 Subject: [PATCH] hub: push after every turn so teammates see a session as it happens The client only pushed on SessionStart, so a long session stayed invisible to the team until the next one began. Add UserPromptSubmit and Stop hooks that run an incremental `hub push` in the background (2.4s for 87KB, measured), guarded by a hub.json check so machines outside a team hub do nothing. Paired with the server timer dropping from 10 minutes to 1, work shows up in team search about a minute after it happens. Co-Authored-By: Claude Opus 5 --- .../2026-08-07-realtime-hub-visibility.md | 63 +++++++++++++++++++ docs/team-hub.ru.md | 17 +++-- hooks/hooks.json | 24 ++++++- 3 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 docs/decisions/2026-08-07-realtime-hub-visibility.md diff --git a/docs/decisions/2026-08-07-realtime-hub-visibility.md b/docs/decisions/2026-08-07-realtime-hub-visibility.md new file mode 100644 index 0000000..3686f61 --- /dev/null +++ b/docs/decisions/2026-08-07-realtime-hub-visibility.md @@ -0,0 +1,63 @@ +# Работа коллеги видна в общем поиске почти сразу + +## Контекст + +Командный хаб отдавал историю с задержкой в часы. Два разных лага складывались: + +1. **Клиент отправлял транскрипты только на `SessionStart`.** Пока человек не + закроет текущую сессию и не откроет следующую, ничего из его работы на хаб не + уезжало вообще. Для долгой сессии это полдня. +2. **Сервер индексировал загруженное раз в 10 минут** (`OnUnitActiveSec=10min`). + +Требование, из-за которого это стало проблемой: вечерний дайджест работы команды +собирается из хаба, а «видеть, что делает команда» хочется в момент работы, а не +на следующий день. Формулировка задачи — «написал сообщение, оно видно; агент +ответил, ответ виден». + +## Решение + +- Плагин пушит после каждого хода: хуки `UserPromptSubmit` и `Stop` дополнительно + к существующему `SessionStart`. Оба вызывают `session-recall hub push` в фоне. +- Серверный таймер индексации — раз в минуту вместо десяти. + +Итоговая задержка: секунды на отправку плюс до минуты на индексацию. + +## Почему + +**Почему push после каждого хода, а не по таймеру на клиенте.** Ход — это ровно +то событие, после которого появились новые байты. Таймер либо будит машину +впустую, либо просыпается не тогда. + +**Почему это дёшево.** Отправка инкрементальная — уезжает только хвост файла. +Замер на реальной сессии: 2.4 секунды на 87 KB, и это в фоне (`&`), сессия его не +ждёт. `pgrep` не даёт запуститься второму пушу поверх идущего. + +**Почему хук молчит у тех, кто не в команде.** Первой строкой — проверка +`hub.json`; нет файла, значит машина не подключена к хабу, и хук выходит с нулём. +Плагин ставят и вне нашей команды, у них не должно появляться ни ошибок, ни +лишних запусков. + +**Почему минута, а не 10 секунд.** Прогон индексации — это эмбеддинги новых +чанков; десятисекундный цикл начал бы наслаиваться сам на себя без выигрыша, +который человек способен заметить. + +## Что протестировали + +- `session-recall hub push` на живой сессии: 2 файла, 89 161 байт, 2.4 с. +- `/v1/recent` за день с ключом участника: сессии приходят с полем владельца — + видно, чья работа, без ручной сверки. +- Прогон индексации на сервере при 10 накопленных файлах: 34 с CPU. За минуту + накапливается заметно меньше, в цикл укладывается. + +## Отвергли + +- **Индексация по событию из `/v1/ingest`** — честный realtime, но это очередь и + разделяемое состояние между сервисом и индексатором; минутный таймер даёт почти + тот же результат без нового кода. +- **Пуш на `PostToolUse`** — срабатывает по десятку раз за ход, а новых байтов + добавляет столько же, сколько один пуш в конце. +- **Ускорить только серверный таймер** — не помогло бы: главный лаг был на + клиенте, где данные лежали до следующего запуска сессии. + +--- +07.08.2026 · PR: hooks + docs + timer на сервере (`claude-recall-index.timer`) diff --git a/docs/team-hub.ru.md b/docs/team-hub.ru.md index e56ab82..821670f 100644 --- a/docs/team-hub.ru.md +++ b/docs/team-hub.ru.md @@ -72,8 +72,13 @@ session-recall hub push session-recall hub status ``` -Дальше ничего делать не нужно: при старте каждой сессии агента новые -транскрипты уходят на сервер сами. +Дальше ничего делать не нужно: транскрипты уходят на сервер сами — при старте +сессии, а потом после каждого хода (твоё сообщение, ответ агента). Отправка +инкрементальная, это доли секунды в фоне и она не задерживает сессию. + +Сервер переиндексирует загруженное раз в минуту, так что работа коллеги видна +в общем поиске примерно через минуту после того, как она произошла, — не нужно +ждать, пока он закроет сессию. ### Как этим пользоваться @@ -163,9 +168,11 @@ session-recall hub secrets status # сколько секретов маск session-recall hub index ``` -Запускается по таймеру. Идёт тем же кодом, что и локальная индексация, — по -одному проходу на владельца. Один сбойный транскрипт не останавливает -остальных. +Запускается таймером `claude-recall-index.timer` раз в минуту — это то, что +делает общий поиск почти realtime. Идёт тем же кодом, что и локальная +индексация, — по одному проходу на владельца. Один сбойный транскрипт не +останавливает остальных. Прогон занимает секунды: за минуту накапливается +несколько файлов, а не сотни. --- diff --git a/hooks/hooks.json b/hooks/hooks.json index 0385243..a685e9d 100644 --- a/hooks/hooks.json +++ b/hooks/hooks.json @@ -1,5 +1,5 @@ { - "description": "Keep the session-recall index fresh — incremental re-index in the background at session start.", + "description": "Keep the index fresh: a full incremental re-index at session start, plus a lightweight hub push after every turn so teammates see the session as it happens.", "hooks": { "SessionStart": [ { @@ -11,6 +11,28 @@ } ] } + ], + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "timeout": 5, + "command": "[ -f \"$HOME/.local/share/session-recall/hub.json\" ] || exit 0; export PATH=\"$HOME/.local/bin:$HOME/bin:$PATH\"; sr=session-recall; command -v \"$sr\" >/dev/null 2>&1 || exit 0; pgrep -f \"$sr hub push\" >/dev/null 2>&1 || (\"$sr\" hub push >>/tmp/session-recall-push.log 2>&1 &)" + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "timeout": 5, + "command": "[ -f \"$HOME/.local/share/session-recall/hub.json\" ] || exit 0; export PATH=\"$HOME/.local/bin:$HOME/bin:$PATH\"; sr=session-recall; command -v \"$sr\" >/dev/null 2>&1 || exit 0; pgrep -f \"$sr hub push\" >/dev/null 2>&1 || (\"$sr\" hub push >>/tmp/session-recall-push.log 2>&1 &)" + } + ] + } ] } }