fr1: DulyNotes — очередь книг (pubctl.mjs), настройки на книгу

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gilfanovr
2026-10-18 15:18:34 +03:00
co-authored by Claude Opus 5.5
parent 3f5f9664e7
commit bb5b2c46cd
+1 -1
View File
@@ -177,7 +177,7 @@ backend=systemd banaction=ufw
- Мост `ask-astra` в контейнере (`/root/agent-bridge/bin/ask-astra`) по умолчанию работал в `/vault` — переключён на `/root/astra-work` (пустой git-репозиторий; `ask-astra` требует git). Бэкапы — `ask-astra.bak-20261011`, `astra-section.md.bak-20261011`.
- Gmail MCP — без OAuth-кредов (gmail-инструменты не работают, на бот не влияет).
- **MCP `books` с 2026-10-18** (книги читалки, только чтение): `claude mcp add --scope user --transport http books https://books.ruzzy.dev/mcp` с Bearer-токеном `bot:iluha_rabobot` (токен — только в `/root/.claude.json` тома и хешем в `books.db`). В `/root/CLAUDE.md` бота дописан раздел «Книги владельца» (без бэкапа: `cp` в `/root` не прошёл — нет прав; раздел — в конце файла, удаляется целиком): ответы по книгам, публикация в Telegram-канал только по команде владельца, без дословных глав. Контейнер перезапущен (ушёл в новую сессию: прежняя была >5 МБ и заархивирована entrypoint-ом). ⚠️ Текст книг — чужие PDF, теперь он попадает к агенту с SSH-ключами к fr1/gitea и `--dangerously-skip-permissions`: защита от внедрённых инструкций — только правило в CLAUDE.md. Канал для публикаций бот подключает сам по команде владельца «подключи канал @имя» (раздел «Подключение канала» в его CLAUDE.md): `getChat`/`getChatMember` по Bot API → id в `groups` в `/root/.claude/channels/telegram/access.json` (без этого `reply` в канал отклоняется) → строка в «Подключённые каналы» в конце CLAUDE.md. Подключён канал **DulyNotes** (приватный, без @username, id `-1004305290483`, бот — админ с правом публикации) 2026-10-18; бэкап access.json до правки — `/tmp/access.json.bak` в контейнере. ⚠️ У приватного канала `getChat` по имени не работает — id узнавали `getUpdates` при приостановленном (`kill -STOP`) плагине, без `offset`, потом вернули `allowed_updates=[]` (параметр `getUpdates` запоминается Telegram и действует на плагин).
- **DulyNotes: разбор книги по расписанию** (с 2026-10-18). `/root/publisher/` в томе (создан от root: `/root` в контейнере — root:claude 755, бот сам туда не пишет): `publish.mjs` — в 9:00 и 21:00 по Никосии по 2 главы «Learning Go» (book_id=2, 16 глав → 4 дня) в канал `-1004305290483`, с 2026-10-18 каждая отдельным сообщением как самостоятельная техническая заметка о Go: заголовок по теме, без упоминания книги, автора и глав, связный рассказ с переходом от прошлой заметки (её текст — `log/ch<idx>.html`), 2800–3500 символов; длиннее 3800 — второй проход «сократи», с 2026-10-18 вечера статьи 6000–8500 символов с 5–7 примерами кода (`<pre>` → `<pre><code class="language-go">` — подсветка в Telegram; режется по абзацам, не разрывая код): начало — постом, продолжение — **в комментариях** (группа обсуждений DulyNotesChat `-1004373354142`, бот — админ). Bot API не отдаёт id копии поста в группе, а апдейты держит плагин, поэтому копию ищем перебором: проба-сообщение даёт верхнюю границу id, затем ответ на кандидатов с проверкой `reply_to_message.is_automatic_forward` и `forward_origin.message_id` == id поста, промахи сразу удаляются; копия появляется с задержкой — до 5 попыток с паузой. Не вышло — продолжение ответом в канале. ⚠️ Если в группе удалить копию поста, комментарии под ним пропадают. Ручные режимы: `--fix-comments` (перенести продолжение из канала в комментарии), `--edit-last`, `--repost`; id сообщений — `posted` в `learning-go.json`; `claude -p` запускается из пустого `/tmp/publisher-run`, иначе подхватывает `/root/CLAUDE.md` бота; очередь и сделанные слоты — `learning-go.json`, лог и тексты глав — `log/`. Пост пишет `claude -p` (sonnet, по той же подписке) в **изолированном конфиге** `.claude-config` (только `.credentials.json` — симлинк на основной, пустые settings): без плагинов/хуков/встроенных инструментов, только MCP `books` (`books-mcp.json`, 600, токен `bot:iluha_rabobot`); ⚠️ `MCP_CONNECTION_NONBLOCKING=false` обязателен — иначе MCP «pending» и модель пишет вызов инструмента текстом. ⚠️ Основной конфиг для `claude -p` не годится: поднимется второй telegram-плагин, а он при старте убивает чужой опрос (`server.ts`, «Kill any stale holder»). Отправка — Bot API напрямую; HTML чистится от «<» не по делу, при отказе Telegram — текстом; ошибки — владельцу в личку. Ручные режимы: `--now`, `--preview`.
- **DulyNotes: разбор книг по расписанию** (с 2026-10-18; с того же дня — **очередь книг**: `books/<slug>.json` — главы, прогресс, `posted`, настройки per_slot/slots/topic/lang; `queue.json` — `{active, queue}`; ставит бот по разговору с владельцем через `pubctl.mjs` (status | add <book_id> [--dry] [--skip] | set | remove | activate); закончилась книга — со следующего слота следующая; неподготовленная читалкой глава — слот пропускается, владельцу уведомление; тексты заметок — `log/<slug>/ch<idx>.html`; прежний `learning-go.json` перенесён, бэкап `learning-go.json.bak-queue`). `/root/publisher/` в томе (создан от root: `/root` в контейнере — root:claude 755, бот сам туда не пишет): `publish.mjs` — в 9:00 и 21:00 по Никосии по 2 главы «Learning Go» (book_id=2, 16 глав → 4 дня) в канал `-1004305290483`, с 2026-10-18 каждая отдельным сообщением как самостоятельная техническая заметка о Go: заголовок по теме, без упоминания книги, автора и глав, связный рассказ с переходом от прошлой заметки (её текст — `log/ch<idx>.html`), 2800–3500 символов; длиннее 3800 — второй проход «сократи», с 2026-10-18 вечера статьи 6000–8500 символов с 5–7 примерами кода (`<pre>` → `<pre><code class="language-go">` — подсветка в Telegram; режется по абзацам, не разрывая код): начало — постом, продолжение — **в комментариях** (группа обсуждений DulyNotesChat `-1004373354142`, бот — админ). Bot API не отдаёт id копии поста в группе, а апдейты держит плагин, поэтому копию ищем перебором: проба-сообщение даёт верхнюю границу id, затем ответ на кандидатов с проверкой `reply_to_message.is_automatic_forward` и `forward_origin.message_id` == id поста, промахи сразу удаляются; копия появляется с задержкой — до 5 попыток с паузой. Не вышло — продолжение ответом в канале. ⚠️ Если в группе удалить копию поста, комментарии под ним пропадают. Ручные режимы: `--fix-comments` (перенести продолжение из канала в комментарии), `--edit-last`, `--repost`; id сообщений — `posted` в `learning-go.json`; `claude -p` запускается из пустого `/tmp/publisher-run`, иначе подхватывает `/root/CLAUDE.md` бота; очередь и сделанные слоты — `learning-go.json`, лог и тексты глав — `log/`. Пост пишет `claude -p` (sonnet, по той же подписке) в **изолированном конфиге** `.claude-config` (только `.credentials.json` — симлинк на основной, пустые settings): без плагинов/хуков/встроенных инструментов, только MCP `books` (`books-mcp.json`, 600, токен `bot:iluha_rabobot`); ⚠️ `MCP_CONNECTION_NONBLOCKING=false` обязателен — иначе MCP «pending» и модель пишет вызов инструмента текстом. ⚠️ Основной конфиг для `claude -p` не годится: поднимется второй telegram-плагин, а он при старте убивает чужой опрос (`server.ts`, «Kill any stale holder»). Отправка — Bot API напрямую; HTML чистится от «<» не по делу, при отказе Telegram — текстом; ошибки — владельцу в личку. Ручные режимы: `--now`, `--preview`.
- **Комментарии DulyNotes — ограниченный режим** (с 2026-10-18). Хук `PreToolUse` `/root/.claude/hooks/restricted_guard.js` (в `/root/.claude/settings.json`, бэкап `settings.json.bak-20261018`): если последнее входящее из чата из `/root/.claude/hooks/restricted_chats.json` (`chats`) не от `trusted_users` (607015), разрешены только WebSearch/WebFetch, `mcp__books__*`, reply/react/edit в тот же чат (файлы — только `draw/out` и inbox), Read/Write своей истории, Write `draw/*.txt` и Bash ровно `astra-draw <draw/*.txt>`. Проверено: 24 сценария на поддельных транскриптах + живой `claude -p --dangerously-skip-permissions` (deny соблюдается в bypass). ⚠️ Без транскрипта на диске хук пропускает (у бота он есть всегда; в тестах с `--no-session-persistence` — нет). Группа комментариев DulyNotesChat (`-1004373354142`) подключена 2026-10-18: в `restricted_chats.json` и в `access.json` (`requireMention:false`); бэкап access.json до правки — `/tmp/access.json.bak2` в контейнере. Новые группы подключает бот по команде «подключи комментарии» (раздел в CLAUDE.md; `requireMention:false`, id → `restricted_chats.json`). Privacy mode у бота выключен (`can_read_all_group_messages`), админство в группе не нужно.
- **`/root/agent-bridge/bin/astra-draw`** (с 2026-10-18) — Astra только для картинок: `codex exec --sandbox read-only` в пустом temp-каталоге с выключенными shell_tool, unified_exec, apps, plugins, browser_use*, computer_use, multi_agent, goals и `mcp_servers={}`; `code_mode_host` оставлен — через него идёт image_gen. Проверено: прочитать `/etc/hostname` не может (JS без ФС, apply_patch запрещён режимом), дочерний агент тоже без shell, внедрённая в описание просьба прочитать `~/.ssh` проигнорирована. Остаётся `web__run`. Картинки → `/root/agent-bridge/draw/out/`. Бэкап CLAUDE.md бота до этих правок — `/root/agent-bridge/CLAUDE.md.bak-20261018`.