# Session Orchestrator

> Session orchestrator on top of the recall index of all Claude Code sessions: finds a past session by task description, dives in (context, project, skill, artifacts) and acts in one of three modes — finish here, hand off the resume command, or open the session in a new terminal window. Use when user asks: "find the session where I did X", "we already did this", "do it again like back then", "resume/open that session", "what did we decide about…" / «найди сессию где я делал X», «мы же это уже делали», «сделай ещё раз как тогда», «восстанови проект Z», «открой сессию про…», «что мы решили насчёт…» / "找到我做过X的会话", "继续那个会话", "打开那个项目". Not for brand-new tasks with no past session.

- Skill: `rocketmandrey/session-orchestrator` (Agent Skill)
- Install (CLI): `npx skillmds@latest add rocketmandrey/session-orchestrator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rocketmandrey/session-orchestrator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: rocketmandrey (https://skillmd.com/u/rocketmandrey)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/rocketmandrey/session-orchestrator

---


# session-orchestrator — найти сессию, погрузиться, продолжить

CLI: `recall` (см. `recall help`). Данные: `~/.claude/session-recaps/` —
карточка на сессию + единый `INDEX.md` (строка на сессию). Это первичная точка
касания; запасной полнотекст — `recall grep`.

## Шаг 1 — Поиск по индексу (ВСЕГДА сначала здесь)

```bash
recall find <основа1> <основа2> ...
```

- Ищи по ОСНОВЕ слова, не по словоформе: «Ивановой» → `иванов`, «выгрузку» → `выгрузк`.
- Несколько вариантов сразу: `recall find иванов выгрузк постоянн`. Выдача уже
  отранжирована: совпадение в задаче > в #тегах/{сущностях} > в проекте, свежее выше.
- Строка индекса: `<id8> <дата>T<чч:мм> <проект> [status] <задача> #теги {сущности}`.
- `[new]` = сессия ещё без LLM-рекапа (свежая или умершая грязно; строка = её первый
  запрос). Это НОРМАЛЬНЫЙ кандидат — часто именно та самая последняя сессия.
- `⚡LIVE` в конце строки = сессия ОТКРЫТА ПРЯМО СЕЙЧАС. НЕ resume и НЕ `recall open`
  (раздвоит контекст) — работай адресно: `recall ps` → `recall peek/send <tty>`.
- `(meta)` / `#meta` = сессия-искатель (сама искала другие сессии) — почти никогда
  не то, что нужно; ранжируется вниз автоматически.
- Можно искать прямо по тегу: `recall find #rosperevozki` (словарь: `recall tags`).
- Текущую сессию игнорируй. Если индекс молчит — fallback: `recall grep <основы...>`
  (полнотекст по сырым транскриптам; строка: `<id8> <дата> <проект> … сниппет …`),
  затем шаг 2 по найденному id.
- При «подними последнюю/вчерашнюю сессию» сверяй ВРЕМЯ в строке: одинаковых сессий
  одного проекта много, нужна самая свежая по `<дата>T<чч:мм>`, не первая попавшаяся.

### Несколько кандидатов → селектор

Если уверенного победителя нет (2+ правдоподобных строки) — НЕ выбирай сам.
Построй селектор через AskUserQuestion: один вопрос «Какая сессия?», вариант на
кандидата (максимум 4 самых свежих/релевантных):

- **label** — папка проекта + дата (`my-crm · 11.06`);
- **description** — контекст из строки индекса: задача, статус, ключевые сущности;
- последним вариантом всегда — **«Копнуть глубже»**: по выбору открой карточки
  (`recall show`) всех кандидатов, при нужде `recall grep` или сырые transcripts
  (`~/.claude/projects/`), и покажи расширенное сравнение.

## Шаг 2 — Погружение

```bash
recall show <id8>        # карточка: task, status, method, entities, artifacts, next
```

Карточки часто достаточно: в `artifacts` лежат URL готовых таблиц/страниц, в `method` —
какой скилл/скрипт использовался, в `next` — на чём остановились. Если нужна полная
глубина — сырой transcript: `~/.claude/projects/<папка>/<session-id>.jsonl`
(полный id есть в карточке). Оттуда вытаскивай параметры, пути, чем кончилось.

## Шаг 3 — Действие: ТРИ режима

1. **finish — доделать здесь.** «Сделай ещё раз как тогда, но по Z» / «доделай»:
   из карточки возьми проект (cwd) и метод (скилл + параметры), выполни задачу в
   ТЕКУЩЕЙ сессии с новыми параметрами, работая из папки того проекта. Если там
   вызывался скилл — вызови его же через Skill с новым аргументом.
2. **handoff — дать команду.** Пользователь хочет сам: `recall cmd <id8>` → выдай ему
   готовую строку `cd "<проект>" && claude --resume <id>`.
3. **spawn — открыть окно самому.** «Открой её», «переключи меня», «дай окошко»:
   `recall open <id8>` — откроется новое окно терминала с восстановленной сессией
   (iTerm: `RECALL_TERMINAL=iTerm recall open <id8>`; «открой табом» → `--tab`,
   при `RECALL_TAB=1` табы и так по умолчанию, разово окном — `--window`).
   Это живой контекст той сессии —
   пользователь продолжает там, ты в своём окне свободен. Восстановленная сессия
   автоматически получает свой handoff (SessionStart-хук): последнее состояние,
   что в полёте, следующие шаги. Если у старой сессии карточки нет — `recall open`
   сам сгенерит её перед открытием (~30 сек, один вызов haiku); предупреди
   пользователя об этой паузе, торопится — `--fast`.

Режим выбирай по формулировке: задача → finish; «дай команду» → handoff;
«открой/переключи/восстанови окно» → spawn. Вопрос «как/что было» — просто ответь из
карточки (с артефактами и id сессии). Непонятно — покажи топ-кандидатов одной строкой
каждый и спроси.

## Живые сессии — адресная работа (iTerm2 bridge)

Помимо ПРОШЛЫХ сессий (`find`/`open`) recall адресно рулит ЖИВЫМИ открытыми
Claude-сессиями через мост к iTerm2 Python API (демон в AutoLaunch держит
соединение, CLI общается с ним через очередь `0700` — без проблем с авторизацией).
Установка один раз: `recall iterm-install` → iTerm2 Settings → General → Magic →
✅ Enable Python API → перезапустить iTerm2.

- `recall ps` — открытые сессии: tty (`s034`), бежит ли `claude`, его session-id, папка, тайтл.
- `recall peek s034 [строк]` — прочитать текущий экран сессии (что она сейчас делает).
- `recall send s034 "текст"` — промпт В ОДНУ сессию. Гарантии: **никогда не broadcast**,
  адрес однозначен, `claude` на tty реально бежит, сессия открыта; каждая отправка → audit-лог
  (`~/.claude/recall/iterm-audit.log`).
- `recall wait s034 [сек]` — заблокироваться, пока сессия не «утихнет» (экран стабилизировался).

Петля оркестрации: `ps` → нужный tty → `send` задачу → `wait` → `peek` результат.
Адрес сессии `s0NN` виден в статус-строке каждого таба. Демона нет / API выключен →
команды честно скажут «bridge not responding» (не молча висят).

## Codex-сессии

recall индексирует не только Claude Code — интерактивные сессии Codex CLI
(`originator: codex-tui`) попадают в тот же индекс. Механика и живые правила
(pgrep/tty/инжект) — подробно в `docs/CODEX.md`, здесь только то, что нужно
оркестратору по ходу дела.

**Находить**: `recall find #codex` (или просто по словам задачи — Codex-строки
ранжируются вместе с Claude-строками). Строка индекса такая же, как у Claude,
но id длиннее — `id13` (первые 13 символов uuid, например `019f2adc-c5cc`) —
это и есть сигнал «это Codex, не Claude». `⚡LIVE` значит то же самое: живой
`codex`-процесс + свежий mtime роллаута.

**Поднимать**: `recall cmd <id13>` → `cd <cwd> && codex resume <полный-id>`.
Важно (контр-интуитивно для тех, кто привык к Claude): `codex resume`
дописывает В ТОТ ЖЕ файл тем же id — новой сессии не создаётся, «цепочек»
файлов нет. Резюмить нужно всегда тот же id, что и был.

**Батчи `codex_exec`** (аналог субагента, разовый вызов без TUI) в реестр не
попадают — это норма, не пропущенная сессия.

### Транзишн-ритуал: «собери контекст → передай Codex»

Когда оркестратор (текущая Claude-сессия) должен передать задачу в Codex —
например, юзер просит «дальше пусть доделывает codex» — по шагам:

1. **Написать бриф-файл** по шаблону recap-карточки: Задача / Сделано /
   В работе / Дальше / Гочи, плюс пути к репозиторию и ключевым файлам
   (шаблон `CODEX_HANDOFF.md` — в `docs/CODEX.md`).
2. **Передать его командой**:
   ```bash
   recall to-codex <dir> --brief <файл-брифа> --spawn
   ```
   Она пишет `<dir>/CODEX_HANDOFF.md`, при отсутствии `AGENTS.md` создаёт
   минимальный (существующий не трогает), и поднимает `codex` новым окном.
3. **Верифицировать по окну**: найти tty поднятого codex-процесса
   (`ps -eo pid,tty,command | grep codex`), `peek` это окно — убедиться, что
   codex реально стартовал и читает handoff (а не завис/не упал на старте).
4. **Дальше** — юзер работает прямо в окне codex; оркестратор туда не пишет
   вслепую, а действует по правилам `docs/CODEX.md` (живость только через
   `pgrep`, окно ищется по tty процесса, инжект текста в TUI не сабмитится
   сам — нужен настоящий key-event или руки юзера).

## Защита от потери транскриптов

Транскрипты `~/.claude/projects/**/<id>.jsonl` бывают удаляются извне. Защита:
Stop-хук (бэкап после КАЖДОГО хода — грязная смерть теряет максимум последний ход),
SessionEnd/PreCompact-хуки и `recall sweep` (LaunchAgent, 30 мин) копируют каждый в
`~/backups/claude-transcripts` (append-only). `recall open` на удалённой сессии не
открывает пустой resume — рапортует выжившие артефакты и архивную копию; на ЖИВОЙ
сессии отказывается (не раздваивать контекст; `--force` — осознанный override). Плюс
`cleanupPeriodDays: 999999` в settings.json глушит возрастную чистку Claude Code.

## Пример (реальный)

«Сделайте ещё выгрузку по постоянным Светланы Ивановой»:
1. `recall find иванов выгрузк` →
   `c2631a96 2026-06-11 my-crm [done] Выгрузка сделок уволенного логиста Ивановой…`
2. `recall show c2631a96` → method: скилл export-dismissed,
   artifacts: URL готовой таблицы, project: `~/Documents/Cursor/my-crm`.
3. finish: вызвать тот же скилл с новым аргументом из папки проекта.
   (Или просто отдать ссылку на готовую таблицу, если она уже отвечает на запрос.)

## Удаление из индекса

«Убери эту сессию из индекса», «забудь её», «стереть тему»:
`recall remove <id8>` — удаляет карточку, строку индекса и ставит tombstone
(хук/backfill её больше не воскресят; вернуть: `recall recap <transcript> --force`).
Перед удалением покажи строку индекса и подтверди, что это та самая сессия.

## Как наполняется индекс

Два контура, потому что сессии обычно умирают ГРЯЗНО (ноут вырубили — SessionEnd
не сработал):
1. SessionEnd-хук (`recall hook`) рекапит каждую чисто завершённую сессию ≥15
   событий через haiku.
2. `recall sweep` (LaunchAgent, каждые 30 мин) — страховка от грязных смертей:
   бэкапит транскрипты, даёт КАЖДОЙ неучтённой сессии дешёвую `[new]`-строку в
   индексе без LLM (сессия находима через ≤30 мин после появления, даже если
   никогда не завершится), и докарточивает/дохэндоффивает устаревшие (кап 8
   haiku-вызовов за проход).

Старые сессии: `recall backfill`. Пересборка индекса из карточек (после правки
тегов/карточек, без LLM): `recall reindex`. Словарь тегов: `recall tags`
(`~/.claude/session-recaps/TAGS.md` — recap-промпт сам предпочитает эти теги).
Диагностика: `recall doctor` (в т.ч. покрытие индекса за 7 дней и живость
LaunchAgent; permissions: установщик прописывает `Bash(recall *)` в allow —
recall работает в любой сессии без промптов).

Заодно сессии **называют себя сами**: каждый recap/handoff даёт сессии имя
`папка/проект · задача` (механизмом `/rename`) — пикер `claude --resume` читаем.
Ручные имена не перезаписываются; «назови ту сессию X» → `recall rename <id8> X`.

## Handoff-слой (непрерывность; опционален)

Петля включается при установке (`./install.sh --with-handoff`; `recall doctor`
покажет её статус). Если включена: перед каждым автокомпактом PreCompact-хук
пишет **handoff-карточку** сессии
(`~/.claude/session-recaps/handoffs/<id>.md`: task now / done / in flight / next /
gotchas), а SessionStart-хук (compact|resume) вливает её обратно в контекст. Значит:
после компакта и при `recall open` сессия сама знает, на чём остановилась — не
пересказывай ей контекст вручную. Карточка свежее компакта быть не может — если
видишь handoff в начале контекста, доверяй ему как ground truth. Посмотреть руками:
`cat ~/.claude/session-recaps/handoffs/<полный-id>.md`.

Старые сессии (закончились до установки петли) карточек не имеют. Точечно карточку
сгенерит сам `recall open`; если пользователь хочет переобход («сделай handoff'ы
всем недавним»), предложи `recall handoff --all --days 14` — честно назови цену
(один вызов haiku на сессию) и запусти в фоне.

