longrun

Память и координация сессий Claude Code. Скилл нужен, чтобы сессии могли координироваться четырьмя способами: через общие документы на диске, через сообщения и задачи той сессии, у которой есть контекст, через watch, который будит сессию, когда событие наступило, и через одну сессию, которая ведет остальные к цели. Курс показывает, как работает каждый, шаг за шагом, на игрушечном проекте shop. Кому внутренности не нужны, хватит части 0.

1. Общие документы на диске

Один .longrun/ на проект с заметками, которые видят все сессии, плюс свои заметки у каждой сессии. Хуки возвращают и те и другие после каждой компакции, /clear и resume, а на каждом ходу показывают, что изменили другие сессии. Части 3, 5, 6.

2. Делегирование: сообщения и задачи

Сообщение или задача другой сессии приходит туда как ход пользователя: через сокет, если она работает, через inbox на следующем ходу, если остановлена. Сессии называются так, как видны в сайдбаре. Часть 7.

3. По событию: ожидание, которое не пропустит событие

Watch - это проверка, которую таймер запускает раз в пять минут без модели. Когда условие выполнилось, сессия просыпается с заданным текстом. Без цикла опроса, без токенов на ожидание, без паузы на заданное время, которая закончится слишком поздно или слишком рано. Часть 7.

4. Одна сессия координирует остальные - и дозванивается до вас

Одна сессия ведет доску для уже открытых сессий: раздает задачи, разблокирует, называет застрявшую и ставит диалог поверх всех окон, когда решить может только человек. Это не автономность: одну сессию к проверяемому условию ведет /goal. Часть 8.

Часть 0

Быстрый старт: поставить и просто работать

Скилл рассчитан на то, что человек работает в сессиях как обычно, а заметки, дайджесты и доставку сообщений ведут хуки и модель по инструкции. Ниже все, что нужно сделать руками.

  1. Установить один раз. Одной строкой, клон не нужен - установщик сам забирает исходники:
    curl -fsSL https://krllx.github.io/longrun/install.sh | bash
    Он ставит скилл, 12 хуков в ~/.claude/settings.json, CLI ~/.local/bin/longrun, MCP-сервер longrun, и таймер, который раз в пять минут гоняет проверки и смотрителя. Спрашивает он только про одно - про уведомления на рабочем столе, это следующий шаг. Из клона - тот же install.sh; --uninstall все это снимает.
  2. Уведомления, если они нужны. install.sh спрашивает, настраивать ли их, и этот шаг - про то, что решает ответ. longrun от них не зависит - halt и сработавший watch и так доезжают до сессии через ее сокет или инбокс, - поэтому отказ ничего больше не меняет (--no-notify отвечает заранее, brew install terminal-notifier включает потом). На macOS установщик выполняет brew install terminal-notifier, если его нет (Homebrew - то самое требование; без него он просто скажет об этом и пойдет дальше), и шлет одно тестовое уведомление; macOS может один раз спросить, разрешить ли уведомления от terminal-notifier - разрешите. Встроенными средствами macOS этот шаг не заменить: osascript -e 'display notification' отправляет уведомление от имени Script Editor, у которого нет разрешения, поэтому система кладет его в базу, не рисует ничего и выходит с нулем (25 из 25 так на macOS 15; разрешения Script Editor не получает даже после запуска). В баннере будут имя и иконка самого terminal-notifier: macOS берет и то и другое из бандла, который отправил уведомление, и переопределить их для отдельного уведомления нельзя. На Linux это notify-send (пакет libnotify), он есть в большинстве десктопов. Проверка в обоих случаях - longrun notify --test: шлет пробу, вычитывает, нарисовала ли ее система, и печатает, какая сессия откроется по клику. Сессию, которую нельзя пропустить, помечают отдельно: longrun important on (или next, или число) - после этого конец каждого ее хода приходит уведомлением независимо от notify_turn_end и от того, какое окно в фокусе, а проверка фокуса как раз этого и не умеет, пока вы печатаете в другой сессии Claude.
  3. Сделать папку проектом. Проект для longrun - это папка, которую вы открываете в Claude Code. Не обязательно корень репозитория: это может быть папка с несколькими репозиториями, подкаталог монорепозитория или пустая папка-штаб. В ней один раз выполнить longrun init: в терминале или прямо в сессии Claude Code, агент выполнит его сам, если попросить. Появится каталог .longrun/; если папка внутри репозитория, добавьте его в ignore (или longrun init --external, тогда каталог ляжет под ~/.claude/longrun/). Из каждого worktree того же проекта: longrun link <путь к проекту>. Проверка: longrun where.
  4. Настроить под себя. В сессии сказать агенту: "настрой longrun" (или /longrun onboard). Он выполнит longrun onboard, коротко расскажет, что делает скилл, и спросит про главные настройки: окно автокомпакции, пороги зависания, размеры заметок, уведомления. Ответы применит сам через longrun config set. Одно исключение: окно автокомпакции хук выставить не может, поэтому агент попросит вас ввести /autocompact 300k (или выбранное значение) в Claude Code. За 50 тысяч токенов до этого порога хук попросит сессию записать заметки перед компакцией. Подробно про ключи (см. дальше часть 9).
  5. Работать. Ничего вызывать не нужно. На старте сессия получает дайджест (общие заметки, свои, кто еще работает), после компакции все возвращается само, чужие изменения приходят на следующем ходу. Агент сам пишет заметки о тупиках и решениях. Словами можно попросить: "запиши", "что мы уже пробовали", "статус сессий", "передай другой сессии", "что осталось", "скажи, когда PR вольется".
  6. Когда сессий несколько и есть общая цель. В одной из них: "возьми роль оркестратора, цель: ...". Она заведет доску задач и будет раздавать работу; остальным сессиям задачи приходят ходом, ничего учить не надо. "Стоп всем" и "продолжаем" тоже словами, в сессии оркестратора (см. дальше часть 8).
Диагностика в одну команду: longrun where (какой проект и сессия), longrun status (кто из сессий что делает), longrun watch status (жив ли таймер), longrun notify --test (доходят ли уведомления до экрана), longrun config (действующие настройки).
Часть 1

Зачем

Контекст модели конечен. На длинной дистанции компакция случается всегда: автоматически, когда окно заполнено, или вручную через /compact. Claude Code сообщает об этом хукам до и после (PreCompact, PostCompact), и longrun ловит оба момента. Но саму потерю компакция не отменяет: история сжимается в резюме, следующая компакция сжимает резюме.

Проблема 1: компакцияПервым из резюме пропадает "что пробовали и почему не вышло". Через полчаса агент предлагает фикс, который сам же откатил.
Проблема 2: несколько сессийКаждая живет в своем окне. Одна открыла PR, другая об этом не знает и говорит "PR еще не создан". Тупик, пройденный одной, вторая проходит заново.
Проблема 3: ожидание"Скажи, когда PR вольется" превращается в цикл опроса, который тратит токены на каждом пробуждении, или в паузу на заданное время (sleep), после которой событие уже давно произошло или еще не наступило.
Проблема 4: много сессий, одна цельПять сессий на одном проекте, и только человек знает, что сделано, что застряло и что дальше. Каждая передача идет через него.
Лечение 1: документы на дискеЗаметка на диске не деградирует. Хуки возвращают заметки после каждой компакции, /clear и resume, а резюме компакций архивируют дословно.
Лечение 2: сообщения и задачиОдин .longrun/ на проект: общие заметки, которые видит каждая сессия, список сессий с их статусом, сообщения и задачи, доставленные ходом пользователя.
Лечение 3: watchтаймер проверяет условие раз в пять минут без модели и будит сессию, когда оно выполнилось. Надежно, реактивно, бесплатно.
Лечение 4: оркестраторОдна сессия ведет доску, раздает задачи, называет застрявшую и спрашивает человека диалогом только когда без него нельзя.

Картинка ниже про проблему 1. Верхняя строка: что модель держит в контексте, слева направо во времени: сначала полная история, после компакции только резюме, и агент, который читает это резюме. Нижняя строка: файл на диске, куда агент в самом начале записал одну заметку. Пунктирные стрелки: заметка попадает в контекст при старте и снова после компакции.

Контекст модели во времени 1. история: пробовали X, упало, откатили, взяли Y... 2. резюме: "делали Y" 3. агент: "попробуем X!" Файл заметок сессии на диске (longrun) [s1] dead: X fails: it needs a real Redis, use REDIS_URL=fake:// одна заметка: [s1] ее номер (s = своя, n = общая), dead = тег "тупик", дальше сам факт одной строкой по-английски
Резюме теряет причины. Строка на диске стоит 26 токенов и приходит обратно после каждой компакции, поэтому на шаге 3 агент видит, что X уже пробовали.

Из чего состоит скилл

Механика: хуки, CLI, таймер

Двенадцать хуков Claude Code (см. дальше часть 4), команда longrun и таймер (агент launchd на macOS, systemd-таймер пользователя или cron на Linux). Механика работает без участия модели:

  • печатает дайджест на старте сессии и после каждой компакции;
  • архивирует каждое резюме компакции дословно;
  • пишет упавшие команды в журнал;
  • перед компакцией снимает HANDOFF: последние просьбы человека и правленые файлы, чтобы после компакции продолжить с того же места;
  • доставляет сообщения между сессиями;
  • гоняет отложенные проверки без модели: PR влит, URL отвечает, файл появился;
  • следит за сессиями для оркестратора, сессии, которая ведет проект к цели (см. дальше часть 8).

Инструкция модели: SKILL.md

Что делает модель, потому что ее так попросили: пишет заметку одной строкой, когда наткнулась на тупик, приняла решение или узнала факт об окружении; зовет recall, когда чего-то не хватает в контексте; передает работу той сессии, у которой больше контекста. Про то, что писать (см. дальше часть 5).

Часть 2

Три сущности, больше ничего

Проект

Общая память группы сессий: каталог .longrun/, который longrun init создает в папке проекта (или вне дерева с --external). Внутри:

  • общие заметки [n1], [n2]: одна строка = один факт, видят все сессии;
  • inbox: сообщения сессиям, которые сейчас не работают;
  • доска задач оркестратора;
  • архив резюме компакций и снимков.

Подробнее (см. дальше часть 3).

Сессия

Один разговор Claude Code, в приложении одна строка в сайдбаре. Свое у нее:

  • свои заметки [s1]: то же самое, но видит только эта сессия;
  • журнал: хронология, вехи, падения, компакции;
  • meta: счетчики и последний статус.

Лежат под ~/.claude/longrun/, не в репозитории.

Каталог

Папка, где сессия стартовала: корень, worktree, подкаталог. Ничего не хранит. Только говорит, к какому проекту относится сессия.

Слово "проект" значит только каталог .longrun/: не проект в монорепозитории и не папка транскриптов Claude Code. Worktree привязывается к проекту командой longrun link, своих заметок у него нет. Сессия принадлежит одному проекту. При resume приложение выдает сессии новый CLI id; longrun идет по цепочке priorCliSessionIds, и свои заметки продолжаются.

Часть 3

Файлы на диске

Каждый файл появился из конкретной задачи:

  • notes.md сессии: проблема 1. Тупики и решения этой сессии, которые должны пережить компакцию.
  • NOTES.md проекта: проблема 2. Факты, которые нужны любой сессии: номер PR, решение, особенность окружения.
  • journal.md: хронология без токенов. Вехи от агента, а механика дописывает старт, конец, упавшие команды, компакции. По нему видно, что сессия делала, не читая транскрипт.
  • archive/compact/ и archive/precompact/: резюме каждой компакции дословно и снимок перед ней (HANDOFF). Первое находит recall, второе возвращается в дайджест после компакции.
  • inbox/: сообщение сессии, которая сейчас не работает, ждет ее следующего хода.
  • meta.json: счетчики, последний ответ, идущий инструмент. Из него строки SESSIONS и флаги для оркестратора.
  • board.json, stale.json, watch/, halt.json: доска оркестратора, пометки "перестало быть правдой", отложенные проверки, стоп всем. Про них в частях 7 и 8.

Все общее лежит в проекте. Все свое лежит вне дерева репозитория и вне синхронизируемых папок, потому что переписывается на каждом вызове инструмента. Нажмите на файл.

Кто пишет, когда создается, что внутри.
ФайлКто пишетКогда удаляется
NOTES.md проектаагент: add --shared, rm, replace, pruneзаписи старше 14 дней в архив (кроме pin); rm уносит строку в archive/notes.md
notes.md сессииагент: add, rm, replace, pruneвместе с сессией, молчавшей 7 дней (в archive/sessions/)
journal.mdхукихвост старше 200 строк в архив
meta.jsonхуки на каждом событиис сессией
archive/compact/*.mdхук PostCompactстарше 30 дней или больше 40 штук
inbox/*.mdsend, watch, board, askпри доставке в .archive/, оттуда через 30 дней
watch/w*.jsonwatch add, тик таймерачерез неделю после срабатывания
Часть 4

Хуки: где живет механика

Claude Code зовет внешнюю команду на каждое событие сессии. longrun ставит двенадцать таких команд, все это один python-скрипт. Хук это отдельный процесс на событие, поэтому после установки новый код работает во всех сессиях сразу. Нажмите на хук в цикле.

Цикл одной сессии

Старт, потом ходы: запрос человека, вызовы инструментов, ответ. Когда контекст переполнен, компакция и снова SessionStart. Хуки на каждом узле.
Единственное, что попадает в контекст модели из хуков: дайджест на SessionStart, дельта общих заметок и сообщения на UserPromptSubmit, редкое напоминание записать заметку, предупреждение о контексте и отказ при halt. Остальное пишется в файлы молча.
Часть 5

Заметки: что писать и куда

Одна строка, по-английски, до 400 символов (тот же факт по-русски стоит в полтора раза больше токенов, а бюджеты жесткие). Тест один: вернет ли это одна команда, Read или grep? Если да, не писать.

ТегЧтоКуда обычно
deadподход не сработал, и почемусвои; общие, если в тот же тупик может зайти другая сессия
decisionвыбор и причинаобщие, если касается других
factфакт об окружении, который стоил усилийобщие
ctxрамки задачи от человекасвои
pinфакт без срока давности: номер PR, ветка, хостобщие
docуказатель на файл, который в строку не влезаетобщие

Заметка по умолчанию идет в общие заметки проекта; --own оставляет ее внутри этого разговора. Не влезает в строку - значит это файл: longrun doc add research/plan.md "план раскатки и что открыто" кладет в общие заметки одну строку-указатель, а сам файл каждая сессия открывает, только когда он ей нужен. Прогресс ("запушил", "тесты зеленые") не пишется никуда: хроника и так лежит в журнале, ее ведут хуки. То, что переживет задачу (кто пользователь, как он работает), в автопамять Claude Code, не сюда.

Проверьте себя: куда это?

Часть 6, сценарий

Одна сессия переживает компакцию

Проект shop, сессия A. Кнопки "Дальше" и "Назад" или стрелки на клавиатуре. Слева, кто с кем говорит на этом шаге; справа, команда и что она печатает; внизу, что изменилось на диске.

человек, диалогсессияпроект .longrunсвое сессиитаймерглобальное
Что запомнить: тупики и решения пишутся сразу, вехи в журнал, после компакции все возвращается само, потерянную деталь ищет recall.
Часть 7, два сценария

Две сессии: общая память

В той же папке открывается сессия B.

Передать работу и ждать событие

Сообщение другой сессии приходит к ней как ход пользователя. Ожидание события стоит ноль токенов: проверку гонит таймер.

Проверка cmd идет от таймера, у которого окружение почти пустое: только абсолютные пути, никакого Touch ID, ssh и алиасов. Сначала longrun watch test -- cmd '...'.
Часть 8, сценарий

Оркестратор: одна сессия координирует остальные

Слой поверх заметок и сообщений. Одна сессия держит цель и доску, остальные учат три команды: board take, board done, board block. Все, что нужно оркестратору, лежит в файлах состояния, транскрипты он не читает. Это координация нескольких окон плюс линия к человеку, а не автономная езда: одну сессию к условию, которое умеет проверить оценщик, ведет встроенный /goal.

Кто что может

Смотритель и оркестратор только предлагают. Идущий инструмент здесь никто не убивает: застрявшее окно останавливает человек, клавишей Esc. Остановить всех (halt) и снять стоп (resume) можно только по слову человека в этом разговоре, не по просьбе другой сессии.

Диалог или доска

Диалог поверх окон для того, что не может ждать: подтверждение, доступ, действие только человека. Вопросы о цели и приоритетах идут на доску через board block, оркестратор разберет.

Часть 9

Настройки

Два уровня: глобальный файл ~/.claude/longrun/config.json и файл проекта .longrun/config.json; значение проекта перекрывает глобальное. Смотреть и менять руками JSON не нужно:

longrun config                                  # действующие значения и откуда каждое: default / global / project
longrun config set stuck_tool_min 60 --global   # для всех проектов
longrun config set notes_max_bytes 8000         # для этого проекта
longrun config unset notes_max_bytes            # обратно к умолчанию

Ключей около сорока (полный список в docs/REFERENCE.md, раздел 6). Сразу после установки имеет смысл посмотреть на эти:

КлючПо умолчаниюКогда и как менять
notes_max_bytes, session_notes_max_bytes5000, 3000Бюджеты общих и своих заметок. Читаются на каждом старте, поэтому больше не значит лучше. Проект с четырьмя и более сессиями, где дайджест постоянно просит PRUNE: 8000 и 4000.
notes_max_age_days14Записи старше уходят в архив (кроме pin). Проект с редкими сессиями: 30.
nudge_tools, nudge_turns40, 8Через сколько вызовов или ходов без заметки напомнить (и только если были правки или падения). Раздражает: 80 и 16.
ctx_warn_before50000За сколько токенов до окна автокомпакции просить записать заметки. Работает в паре с /autocompact 300k в Claude Code; 50k хватает.
stuck_tool_min, stuck_wait_min30, 10Два порога смотрителя для оркестратора: инструмент все еще идет, запрос разрешения остался без ответа (минуты). Сборки по 40 минут в порядке вещей: stuck_tool_min 60.
ask_wait_sec, ask_expire_min90, 360Сколько секунд диалог ждет ответ инлайн; через сколько минут закрывается сам. Обычно оставить.
watch_ttl_days7Срок проверки по умолчанию (только глобально). Ждете релиз неделями: 30, или --for 30d у конкретной проверки.
autocompact_window0Где Claude Code делает автокомпакцию, как задано /autocompact N; принимает 300k, 1M. 0 = следовать за Claude Code. Хук не может выполнить /autocompact, поэтому это намерение: onboard сравнивает его с настройкой Claude Code и просит ввести команду вас. Рекомендация для моделей с окном 1M: 300k.
pr_toolautoЧем проверки pr-merged спрашивают статус PR: gh (GitHub CLI) или arc (Arcadia). auto смотрит на папку, из которой зарегистрирован watch.
watch_timerautoЧем гоняется тик watch: launchd (macOS), systemd (таймер пользователя), cron, none. auto берет то, что есть на этой машине.
notify_turn_endoffУведомление, когда сессия закончила ход: off, unfocused (только пока окно Claude не в фокусе), always. Только глобально. Для одной сессии, которую нельзя пропустить, есть longrun important on - она обходит оба условия.
Проще всего не запоминать ключи, а сказать агенту "настрой longrun": longrun onboard печатает ему бриф с текущими значениями и смыслом каждого ключа, он спросит вас по одному и применит ответы. Минимальный набор: окно автокомпакции 300k (ввести /autocompact 300k самому), stuck_tool_min 60, если у вас долгие сборки, notify_turn_end unfocused, если хотите узнавать, что сессия закончила. Остальное трогать, когда дайджест или смотритель начнут мешать.
Часть 10

Шпаргалка и границы

# установка
curl -fsSL https://krllx.github.io/longrun/install.sh | bash
                        # скилл, 12 хуков, CLI, MCP-сервер, таймер на 5 минут, уведомления
longrun watch install   # только таймер (установщик уже это сделал)
longrun notify --test   # по желанию: доходит ли уведомление до экрана
longrun init [--external]  # в папке проекта
longrun link <проект>   # из каждого worktree
longrun where           # какой проект, какая сессия
# заметки
longrun add [--own] -t TAG "..."
longrun doc add путь "что внутри" | doc ls
longrun rm s3 n12 | replace n12 "..."
longrun stale n12 "почему" | mute n12
longrun notes | prune [--auto] [--shared]
longrun recall слово
# сессии
longrun status
longrun send [--list] [--resume] КТО "текст"
longrun important on|next|N|off [--to КТО]
longrun watch add --to КТО --then "..." -- pr-merged ID
longrun watch ls | test -- CHECK | sessions
# оркестратор
longrun orchestrate start --goal "..."
longrun board | board add|assign|take|done|block T7
longrun board add --fact "..." --task T7 | board ls --facts | board ack F1
longrun halt "почему" | resume
longrun ask "вопрос" --options "Да,Нет"
# настройки
longrun onboard [done]
longrun config
longrun config set KEY VALUE [--global]
longrun config unset KEY [--global]

Что гарантирует механика, а что зависит от модели

Гарантирует механикаЗависит от модели и инструкции
архив каждого резюме компакции, журнал падений, снимок HANDOFF, возврат заметок в контекст, доставка сообщений, дельта общих заметок, отказ инструментов при halt, проверки watchчто заметка будет написана и написана по делу, что перед повторным исследованием будет recall, что сообщение от коллеги не будет принято за слово человека

Границы

  • Дайджест не больше 9000 байт. Вытесняются по порядку: watch, хвост журнала, обязанности оркестратора, список сессий, доска, HANDOFF. Заметки уступают последними и не хвостом, а по одной самой старой записи без pin: обрезать конец значило бы выкинуть как раз последние.
  • Resume в приложении связывается по priorCliSessionIds; /clear в CLI по эвристике "та же папка, конец с причиной clear не позднее трех минут назад".
  • Формат сокета и транскриптов не задокументирован: при смене версии Claude Code первым сломается send в работающую сессию, очередь через inbox продолжит работать.
  • Под таймером macOS у python может не быть доступа к ~/Documents (TCC). Проверки от этого не зависят; сообщение тогда ложится в каталог сессии под ~/.claude.
  • Сабагенты дайджест не получают. /rewind заметки не откатывает.

Подробности: README.md, docs/REFERENCE.md, docs/ORCHESTRATOR.md в репозитории, и longrun help.