agentleFS
dewildewil/claude-toolkit/skills/redmine-snapshot/SKILL.md

redmine-snapshot

Skill9 starsChanged 3 months agoMITView on GitHub

Настроить или починить локальное зеркало открытых задач Redmine на устройстве: \"где взять api-ключ redmine\", \"падает на SSL / сертификате\", \"как узнать user_id исполнителя\".

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

Files
SKILL.md

redmine-snapshot

Скилл для первой настройки или починки локального snapshot открытых задач из Redmine через REST API. Пара скриптов держит зеркало задач команды на диске - для расчета дельт, вставки сводки в дейлики и работы без живого доступа к web-UI.

Скрипты-эталоны лежат в каноне в scripts/redmine-snapshot.py и scripts/redmine-deltas.py (top-level папка scripts/, не внутри папки скилла). .AI bootstrap типа management копирует их в scripts/ в корне проекта - оттуда же, где их ожидает запуск (python3 scripts/redmine-snapshot.py).

Архитектура повторяет telegram-snapshot: общие секреты на устройстве, проектные указатели - в репозитории проекта.

Когда применять

  • Пользователь впервые настраивает скрипты scripts/redmine-snapshot.py / redmine-deltas.py на новом устройстве.
  • Подключается новый проект - нужно создать .redmine-snapshot.json и проверить, что общая авторизация на устройстве уже есть.
  • Первый запуск падает на SSL (CERTIFICATE_VERIFY_FAILED) - Redmine за корпоративным CA.
  • Нужно узнать project_id или user_id исполнителей для проектного конфига.

Когда НЕ применять

  • Обычный регулярный pull (запуск redmine-snapshot.py за свежими задачами) - это просто Bash-команда из шаблона дейлика, отдельный скилл не нужен.
  • Анализ самих задач - они уже в _redmine-snapshot.json, читай напрямую.

Алгоритм

Шаг 1. Проверить общую авторизацию устройства

ls ~/.config/redmine-snapshot/

Должен быть auth.json (redmine_url, api_key, опционально use_curl) с правами 600. Если файла нет - идем к шагу 2.

Шаг 2. Получить API-ключ Redmine

API-ключ привязан к аккаунту пользователя:

  1. Залогиниться в Redmine в браузере.
  2. Открыть "My account" (/my/account).
  3. Справа - блок "API access key", нажать "Show". Если ключа нет - "Reset".
  4. Скопировать ключ (40 hex-символов).

Если блока "API access key" нет - REST API выключен администратором (Administration -> Settings -> API -> "Enable REST web service"). Без него скрипт работать не будет, нужен админ инстанса.

Шаг 3. Заполнить auth.json

mkdir -p ~/.config/redmine-snapshot
chmod 700 ~/.config/redmine-snapshot

Содержимое ~/.config/redmine-snapshot/auth.json (выставить права 600):

{
  "redmine_url": "https://redmine.example.com",
  "api_key": "<40-hex-ключ из шага 2>",
  "use_curl": false
}
  • redmine_url - базовый URL инстанса без хвостового слеша.
  • use_curl - оставить false. Поднять в true только если первый pull упал на SSL (см. шаг 5).
chmod 600 ~/.config/redmine-snapshot/auth.json

Шаг 4. Подключить проект (.redmine-snapshot.json)

В корне проекта создать .redmine-snapshot.json:

{
  "tasks_root": "tasks",
  "project_id": 123,
  "users": {
    "2551": "Иванов Иван",
    "2982": "Петров Петр"
  }
}
  • tasks_root - папка под снапшот относительно корня проекта (дефолт tasks/). Файлы _redmine-snapshot.json и _redmine-snapshot.prev.json лягут туда.
  • project_id - числовой id проекта. Узнать: открыть проект в web-UI, GET <redmine_url>/projects.json (с заголовком X-Redmine-API-Key), найти проект по identifier, взять его id. Идентификатор-строку из URL тоже принимает Redmine, но числовой id надежнее.
  • users - карта {user_id: "Отображаемое имя"}. Ключи - строки (JSON), значения - как удобно читать в дельтах. user_id исполнителя: открыть его профиль в Redmine, id виден в URL (/users/2551); либо GET <redmine_url>/users.json (нужны права видеть пользователей). Имя в значении - произвольная подпись, в API не уходит, только для вывода.

Этот файл - не секрет (ключа в нем нет), можно коммитить в репозиторий проекта.

Шаг 5. Первый запуск и типичные ошибки

cd <project-root>
python3 scripts/redmine-snapshot.py

Зависимостей нет - чистый stdlib (urllib). На выходе - <tasks_root>/_redmine-snapshot.json и построчный отчет по исполнителям.

ssl.SSLCertVerificationError: CERTIFICATE_VERIFY_FAILED. Redmine за корпоративным CA, которого нет в хранилище Python. На macOS системный/корпоративный CA обычно лежит в keychain, откуда его берет curl, но не urllib. Лечение - в ~/.config/redmine-snapshot/auth.json выставить "use_curl": true: скрипт пойдет через curl-subprocess, который этот CA подхватывает. Перезапустить.

401 Unauthorized / пустой ответ. Неверный или отозванный api_key - перевыпустить в "My account" (шаг 2). Проверить, что ключ скопирован целиком (40 символов).

403 Forbidden на конкретном исполнителе. У аккаунта-владельца ключа нет прав видеть задачи этого пользователя в проекте. Скрипт сообщает об ошибке (!! <имя> в stderr), проверяет остальных и завершает сбор с кодом 1 без изменения снимка и prev. Сетевая ошибка дозапроса задачи по id не прерывает сбор: задача остается в новом снимке с пометкой "статус неизвестен". HTTP 403/404 при дозапросе задачи дает отдельную пометку "выбыла из доступа": задача не переносится в снимок и повторно не дозапрашивается. Некорректный ответ API прерывает сбор с кодом 1 без изменения пары.

Нет total_count в ответе выборки. Сбор прерывается с кодом 1: пустой список задач без общего числа не считается доказательством пустой выборки.

0 задач у всех. Чаще всего неверный project_id или фильтр status_id=open не совпадает с настройкой статусов инстанса. Проверь, что в проекте действительно есть открытые задачи на этих исполнителей, и что project_id числовой и верный.

Шаг 6. Дельты

После второго и последующих запусков рядом появляется _redmine-snapshot.prev.json (архив предыдущего сбора). Блок изменений для дейлика:

python3 scripts/redmine-deltas.py

Выведет markdown "Дельты с прошлого сбора": закрытые / новые задачи, "Ушла из наблюдения", "Выбыли вместе с исполнителем", "Статус неизвестен", смена статуса, смена исполнителя. Интервал - от предыдущего успешного сбора до текущего, а не календарные сутки. При нескольких сборах за день сравниваются два последних успешных сбора.

Коды сборщика: 0 - снимок записан, 1 - загрузка или запись не удалась, 2 - нет обязательного конфига. Коды дельт: 0 - сравнение выполнено, 2 - нет текущего снимка, 3 - нет _redmine-snapshot.prev.json. При коде 2 дельты выводят "снимка нет: <путь>"; при коде 3 - "база для сравнения отсутствует, дельты не посчитаны", без списка новых задач. "Изменений нет" означает, что оба снимка есть и различий нет.

Сборщик дозапрашивает по id задачи из прежнего снимка, пропавшие из выборки открытых задач исполнителей. Они остаются в users -> issues с текущими status, is_closed (признак закрытого статуса из API) и assigned_to_id. Если status.is_closed отсутствует, is_closed записывается как null, а задача идет в "Статус неизвестен (нет признака закрытия)". При сетевой ошибке дозапроса задача сохраняется с status: "статус неизвестен" и status_unknown: true, а дельты показывают ее только в группе "Статус неизвестен (дозапрос не удался)". Закрытие по явному признаку имеет приоритет; открытая задача, переназначенная за пределы users конфига, попадает в "Ушла из наблюдения". Если исполнитель удален из users конфига, его прежние задачи выводятся строками "выбыли вместе с исполнителем <имя>". Исполнитель определяется по assigned_to_id, а не по ключу группы в снимке.

При ошибке записи сохраняется прежняя пара снимков, поэтому дельты можно считать по последнему успешному сбору. Ссылки на issue берутся из redmine_url снимка; auth.json для дельт не нужен.

Шаг 7. Апгрейд скриптов в существующем проекте

Скрипты эволюционируют (новые поля, фиксы). Для обновления клиента с .AI используй /canon и canon-sync: pinned-процедура показывает изменения и сохраняет проектные правки/исключения. Для legacy-only клиента переход в .AI сначала нужно запросить отдельно через migrate. Не копируй скрипты вручную из других проектов - версии могут расходиться.

Жесткие правила

  1. auth.json - НЕ кладем в проектную папку. Если проектная папка синхронизируется через облако (Yandex.Disk, Dropbox, iCloud), утечка api_key в облако недопустима. Только в ~/.config/redmine-snapshot/ (локально на каждом устройстве отдельно).
  2. api_key - секрет. В .redmine-snapshot.json, который коммитится, ключа быть не должно - только project_id, users, tasks_root.
  3. use_curl - крайняя мера. Дефолт - urllib. Поднимать use_curl только при реальной SSL-ошибке корпоративного CA, не "на всякий случай".
  4. Снапшот - технический артефакт: его место вне синкаемой папки. tasks_root принимает абсолютный путь - им снимок и уводится из проекта; скрипт предупреждает на каждом прогоне, если путь ведет внутрь. Исключение из синка после создания файла не спасает - только защищает следующий (rules/docs-maintenance.md, раздел "Технические артефакты в синкаемой папке").

Связанные файлы

  • scripts/redmine-snapshot.py в корне проекта - сбор открытых задач команды в _redmine-snapshot.json (urllib по умолчанию, curl-фолбэк для корпоративного CA, пейджинг по 100).
  • scripts/redmine-deltas.py в корне проекта - расчет дельт между текущим и предыдущим snapshot для блока в дейликах.
  • ~/.config/redmine-snapshot/auth.json - локальные credentials на устройство (redmine_url, api_key, use_curl). Не в проекте.
  • .redmine-snapshot.json в корне проекта - проектные указатели {tasks_root, project_id, users}. Не секрет.

Модель и текущие назначения

Перед новым заданием и запуском применяй маршрутизацию моделей: свежий MODELS выше канонического дефолта. Границы данных и полномочий этого навыка сохраняются.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.