$npx -y skills add mworldorg/markdown-memory --skill mm-save-sessionЗакрывает текущую Claude Code сессию — сохраняет лог в Obsidian/Claude/Sessions/, обновляет project note, обновляет INDEX.md, перегенерирует handoff.md (для Project Knowledge claude.ai) через /mm-handoff. Если в проекте есть GSD (.planning/ или .gsd/) — также вызывает /gsd-pause-
| 1 | # mm-save-session — End-of-Session Logger |
| 2 | |
| 3 | Оформляет финал Claude Code сессии в три места: Sessions/, Projects/, INDEX.md. Реализует правила из `~/.claude/CLAUDE.md` как skill (раньше выполнялось вручную, теперь гарантированно). |
| 4 | |
| 5 | ## Конфиг |
| 6 | |
| 7 | Загрузи `mm-config.json` по алгоритму из `<repo>/docs/CONFIG-LOADING.md`. Поддержка `mm-config.local.json` overlay обязательна. |
| 8 | |
| 9 | Понадобятся: |
| 10 | - `paths.obsidian_sessions` |
| 11 | - `paths.obsidian_projects` |
| 12 | - `paths.obsidian_index` |
| 13 | |
| 14 | ## Процесс |
| 15 | |
| 16 | ### Шаг 1. Собери контекст сессии |
| 17 | |
| 18 | **Из текущего разговора:** |
| 19 | - Что обсуждали (тема в 1-2 предложениях) |
| 20 | - Что было сделано (список фактов: что создано, изменено, исправлено) |
| 21 | - Какие решения приняты и почему |
| 22 | - Что осталось / открытые вопросы / следующие шаги |
| 23 | |
| 24 | **Из git** (если репо): |
| 25 | ```bash |
| 26 | git log --since="6 hours ago" --oneline |
| 27 | git status --short |
| 28 | git diff --stat HEAD~5 2>/dev/null || git diff --stat |
| 29 | ``` |
| 30 | Список изменённых файлов и коммитов сегодня. |
| 31 | |
| 32 | **Из cwd**: имя проекта = имя корневой папки (или из `passport.md` если есть). |
| 33 | |
| 34 | ### Шаг 1.5. Собери «Точку возврата» |
| 35 | |
| 36 | Чтобы следующее возвращение было без раскачки, на **КАЖДОМ** save фиксируй три вещи (команда остаётся одна — никаких отдельных режимов сохранения): |
| 37 | |
| 38 | 1. **Следующий конкретный шаг** — одно действие, с которого продолжить. Бери из «Открытых вопросов / следующих шагов» этой сессии. Если из разговора он неочевиден — спроси louise одной строкой: `С чего продолжить в следующий раз? (одна строка)`. |
| 39 | 2. **Недокоммиченный WIP** — из `git status --short` (уже собран в Шаге 1). Перечисли файлы или `нет, дерево чисто`. |
| 40 | 3. **Готовый, но неотправленный промпт** — если в этой сессии был собран промпт для PowerShell-Клода / claude.ai, который так и не выполнили, — запиши его текст целиком. Иначе `нет`. |
| 41 | |
| 42 | Это пойдёт в секцию «Точка возврата» файла сессии (Шаг 3) и оттуда — в handoff.md (Шаг 5.6 через `/mm-handoff`). |
| 43 | |
| 44 | ### Шаг 2. Определи целевые пути |
| 45 | |
| 46 | - **Имя проекта**: из `passport.md` (если в cwd или его родителях есть) → frontmatter `project`. Иначе — имя папки cwd. |
| 47 | - **Файл сессии**: `<obsidian_sessions>/<YYYY-MM-DD-HHMM>-<тема-slug>.md`. Время — текущее, тему-slug сгенерируй из 3-5 слов на русском в kebab-case (транслит, нижний регистр). |
| 48 | - Если файл уже существует — добавь суффикс `-2`, `-3`. |
| 49 | |
| 50 | ### Шаг 3. Создай файл сессии |
| 51 | |
| 52 | ```markdown |
| 53 | --- |
| 54 | created: <YYYY-MM-DDTHH:MM> |
| 55 | project: <project_name> |
| 56 | project_path: <abs_path> |
| 57 | tags: [claude-session, проект-<project_name>, <topical-tags>] |
| 58 | --- |
| 59 | |
| 60 | # <Заголовок-человеческий> |
| 61 | |
| 62 | **Дата:** <YYYY-MM-DD HH:MM> |
| 63 | **Проект:** [[../Projects/<project_name>|<project_name>]] |
| 64 | **Длительность:** примерно <Xм / Xч> |
| 65 | |
| 66 | ## Задача сессии |
| 67 | <1-2 предложения что собирались сделать> |
| 68 | |
| 69 | ## Что сделано |
| 70 | - <факт 1> |
| 71 | - <факт 2> |
| 72 | - <факт 3> |
| 73 | |
| 74 | ## Ключевые решения |
| 75 | - **<решение>** — <почему> |
| 76 | |
| 77 | ## Открытые вопросы / следующие шаги |
| 78 | - [ ] <q1> |
| 79 | - [ ] <q2> |
| 80 | |
| 81 | ## Точка возврата |
| 82 | - **Следующий конкретный шаг:** <одно действие, из Шага 1.5> |
| 83 | - **Если прервались посреди:** |
| 84 | - Недоделано: <что осталось / «—»> |
| 85 | - Неотправленный промпт: <текст готового, но не выполненного промпта целиком / «нет»> |
| 86 | - Недокоммиченный WIP: <файлы из git status / «нет, дерево чисто»> |
| 87 | |
| 88 | ## Затронутые файлы |
| 89 | - `<rel_path>` — <что> |
| 90 | - `<rel_path>` — <что> |
| 91 | |
| 92 | ## Git |
| 93 | <если был> |
| 94 | - Ветка: `<branch>` |
| 95 | - Коммитов сегодня: <N> |
| 96 | - `<hash> <subject>` |
| 97 | ``` |
| 98 | |
| 99 | ### Шаг 3.5. Scrub секретов ПЕРЕД записью в vault (канон config/secret-patterns.json) |
| 100 | |
| 101 | > **Заметка сессии оседает в долговременном vault** (и через Шаги 4–6 её выжимка попадает в project note / INDEX / handoff). Токен, случайно вставленный из кода или git-вывода в «Что сделано», утечёт. Поэтому собранный на Шаге 3 текст прогоняется через фильтр **до** записи. |
| 102 | |
| 103 | Переиспользуй единый механизм (как `mm-handoff` Шаг 5.9) — не дублируй список паттернов здесь. Прогони весь собранный текст заметки через паттерны из канона `<repo>/config/secret-patterns.json` (пояснение — `<repo>/docs/SECRET-PATTERNS.md`): |
| 104 | |
| 105 | 1. **Класс A** — маскируй **молча**, типизированным плейсхолдером с сохранением контекста (`TELEGRAM_TOKEN=<REDACTED:telegram-token>` и т.п. — см. doc). Не вырезай строку. |
| 106 | 2. **Класс B** (широкое `[A-Za-z0-9_\-]{32,}`) — **НЕ маскируй** (задевает git SHA-40 / UUID, которых полно в сессиях). Только добавь одну строку-warn в финальный отчёт. |
| 107 | 3. **Покажи preview перед записью**: если что-то замаскировано или есть warn — выведи одну сводную строку (`🔒 Замаскировано N (telegram-token×1, …); ⚠️ K warn`) и сами места (по 1 строке). Если находок нет — короткое `🔒 секретов не найдено`, без шума. |
| 108 | 4. В Шагах 3 (запись файла |