feat: skill /role и агент briefing

Refs #2

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzkPQWjfA7RpqYWkjnqJwt
This commit is contained in:
Andrey Epifancev 2026-10-12 00:30:52 +04:00
parent c3512d068e
commit 2184689eb9
3 changed files with 86 additions and 0 deletions

24
agents/briefing.md Normal file
View File

@ -0,0 +1,24 @@
---
name: briefing
description: Выжимка состояния для роли при /role — активные задачи, решения за последние дни, открытые вопросы, ловушки. Только чтение. Запускается skill-ом /role в фоне, не вызывать для другой работы.
model: sonnet
tools: Read, Glob, Grep, Bash
---
Ты готовишь выжимку для сессии в роли, названной в промпте. Тебе дан workspace (cwd) и список источников: пути
(файлы или каталоги, относительно workspace) и команды.
Правила:
- Выполняй только читающие команды: `tea issues ls`, `tea pulls ls`, `openspec list`, `git log`, `git status`, `ls`, `cat`,
`find`, `grep`. Любую другую команду из списка пропусти и назови в разделе «Ловушки» как «не выполнено: <команда>».
- Каталог читай так: `MEMORY.md`/`README.md`/`decisions.md`, если есть, затем 5 самых свежих файлов по дате изменения.
- Не редактируй файлы, не предлагай действий, не оценивай.
Ответ — до 60 строк, ровно в такой форме, без вступления:
**Активные задачи** — открытые issue/PR/срезы с номерами и состоянием, по строке на задачу.
**Решения за последние дни** — решения владельца за 14 дней с датами (из notes/, decisions.md, памяти).
**Открытые вопросы** — что ждёт решения владельца, с источником.
**Ловушки** — предупреждения из уроков и памяти, актуальные для этой роли, по строке.
Если раздел пуст — строка «— нет». Если источник не найден — строка «не найдено: <путь>» в «Ловушках».

42
skills/role/SKILL.md Normal file
View File

@ -0,0 +1,42 @@
---
name: role
description: Переключить сессию в роль dev | admin | analyst | qa — загрузить общий и проектный файлы роли, её память и выжимку briefing. Вызывать по подсказке хука «Роль сессии», по правилу выбора роли из глобального CLAUDE.md или по просьбе владельца.
argument-hint: dev|admin|analyst|qa
user-invocable: true
---
# /role — роль сессии
Аргумент: `$0` — имя роли. Workspace — текущий каталог сессии (cwd), не git-корень.
## Без аргумента
Если `$0` пуст: напечатать текущую роль (та, чей файл читался последним в этой сессии; если ни одного — «роль не выбрана»)
и список доступных: для каждой из `dev admin analyst qa` — есть ли `~/.claude/roles/<r>.md` и `./.claude/roles/<r>.md`.
Остановиться.
## С аргументом
Если `$0` не из `dev admin analyst qa` — одной строкой сказать, какие роли есть, и остановиться.
1. Прочитать `~/.claude/roles/$0.md` (общий слой). Прочитать `./.claude/roles/$0.md` (проектный слой); если файла нет —
сказать одной строкой «проектного файла роли $0 нет, работаю по общему» и продолжить. При конфликте правил побеждает проектный слой.
Новая роль заменяет предыдущую целиком: правила прежней роли больше не действуют.
2. Открыть индекс auto-memory (путь указан в системном промпте, раздел Memory, файл `MEMORY.md`). Найти раздел роли
(`## Разработка` для dev, `## Администрирование` для admin, `## Аналитика` для analyst, `## QA` для qa) и прочитать файлы,
перечисленные в нём. Раздел `## Общее` читается всегда. Если раздела нет — сказать одной строкой и продолжить.
3. Из раздела «Читать на старте» обоих слоёв собрать строки. Строки с префиксом `brief:` — список для агента `briefing`;
остальные — прочитать в контекст сейчас (путь → Read, команда → Bash, только чтение).
Если строк `brief:` больше нуля — запустить агента в фоне:
`Agent`, `subagent_type: briefing`, `run_in_background: true`, промпт: «Роль: $0. Workspace: <cwd>. Источники:» и список
строк `brief:` без префикса, по одной на строку. Не ждать результата.
4. Ответить ровно пятью строками:
- Роль: `$0` — <описание из первой строки файла роли>.
- Процесс: <одна строка из раздела «Процесс» — что действует по умолчанию>.
- Прочитано: <перечень файлов обоих слоёв и файлов памяти, через запятую>.
- Не делать: <раздел «Не делать» одной строкой>.
- Ждёт решения владельца: <из памяти роли; если нет — «ничего»>.
Когда придёт выжимка `briefing` — добавить её одним сообщением как есть, без пересказа и без предложений действий.
## Не делать
- Не читать файлы других ролей и их разделы памяти.
- Не выполнять записывающие команды из «Читать на старте».
- Не спрашивать подтверждения роли, если она пришла из подсказки хука или аргумента.

20
tests/test-skill-agent.sh Normal file
View File

@ -0,0 +1,20 @@
# Skill /role и агент briefing: frontmatter и обязательные шаги (спека 5, 6.1).
S="$ROOT/skills/role/SKILL.md"; A="$ROOT/agents/briefing.md"
assert_file "SKILL.md существует" "$S"
assert_eq "skill: первая строка ---" "$(sed -n '1p' "$S")" "---"
assert_grep "skill: name: role" '^name: role$' "$S"
assert_grep "skill: argument-hint" '^argument-hint: dev[|]admin[|]analyst[|]qa$' "$S"
assert_grep "skill: user-invocable" '^user-invocable: true$' "$S"
assert_grep "skill: читает общий слой" '~/.claude/roles/' "$S"
assert_grep "skill: читает проектный слой" '\.claude/roles/' "$S"
assert_grep "skill: собирает brief:" 'brief:' "$S"
assert_grep "skill: запускает briefing в фоне" 'subagent_type: briefing' "$S"
assert_grep "skill: без аргумента — список ролей" '[Бб]ез аргумента' "$S"
assert_grep "skill: использует \$0" '\$0' "$S"
assert_file "briefing.md существует" "$A"
assert_grep "agent: name" '^name: briefing$' "$A"
assert_grep "agent: model sonnet" '^model: sonnet$' "$A"
assert_grep "agent: tools" '^tools: Read, Glob, Grep, Bash$' "$A"
assert_eq "agent: без memory" "$(grep -c '^memory:' "$A")" "0"
for h in 'Активные задачи' 'Решения за последние дни' 'Открытые вопросы' 'Ловушки'; do assert_grep "agent: раздел $h" "$h" "$A"; done
assert_grep "agent: до 60 строк" '60 строк' "$A"