Files
brain/tools/secretary-sessions.mjs
T
Дмитрий 90f1360065 feat(secretary): устойчивость к обрывам — источник=транскрипт, склейка продолжений, догон сессий
Секретарь перестал терять промпт владельца при обрыве (сбой API / ручной стоп /
жёсткий крах). Источник правды — транскрипт на диске: сырьё (Слой 1) пересобирается
из всего транскрипта на каждом завершении, а не дописывается по последнему обмену.

- classifyEntry/assembleExchanges: распознавание машинных меток (isApiErrorMessage,
  [Request interrupted by user] обе формы, isCompactSummary, isMeta) — метка не считается
  настоящим промптом; промпт после обрыва помечается продолжением (cont=1), хвост — tail=1.
- realBoundariesFromRaw: продолжение не открывает новый спан (одна работа не дробится).
- честные пометки спана: «(связь прерывалась — продолжено)» / «(прервана, не завершена)».
- stop-хук: пересборка сырья из транскрипта + догон недоразобранного хвоста прошлых
  (умерших) сессий дела при «включи секретаря <дело>» (_sessions.json, secretary-sessions).
- parseLastExchange → тонкая обёртка над assembleExchanges (без дубля логики).

Свод секретаря зелёный: 172 теста / 12 файлов.
Спека: docs/superpowers/specs/2026-06-23-secretary-interruption-resilience-spec.md
План: docs/superpowers/plans/2026-06-23-secretary-interruption-resilience.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 04:19:16 +03:00

17 lines
1.0 KiB
JavaScript

// Учёт «какие сессии вели дело» — для догона недоразобранного хвоста умершей сессии после краха.
// Хранится в папке дела (docs/secretary/<work>/_sessions.json), НЕ коммитится.
/** Добавить/обновить указатель сессии {session, cursor}. cursor — последний разобранный spanCursor. */
export function upsertSessionPointer(list, { session, cursor }) {
const out = (Array.isArray(list) ? list : []).map((e) => ({ ...e }));
const i = out.findIndex((e) => e.session === session);
if (i >= 0) out[i].cursor = cursor;
else out.push({ session, cursor });
return out;
}
/** Прошлые сессии дела (кроме текущей) — кандидаты на догон хвоста. */
export function prevSessionsForCatchUp(list, currentSession) {
return (Array.isArray(list) ? list : []).filter((e) => e && e.session && e.session !== currentSession);
}