Files
eka c49c9a480b chore: временные файлы — в tmp/ репозитория
- .gitignore: tmp/
- README: раздел «Конвенции репозитория» — tmp/ вместо /tmp,
  submodule как источник, имя агента из файла, render_listing для списков,
  идентичность коммитов
2026-09-23 13:22:51 +05:00

336 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Harness 🛠️
**Универсальный менеджер скиллов, агентов, MCP-серверов и конфигов для Hermes и OpenCode.**
Репа-каталог, где живут ссылки на полезные skills, MCP-серверы, тулзы и агенты — с единым скриптом управления.
```
dev/harness/
├── agents/ # Определения агентов OpenCode (leader, fixer, devops, admin, ...)
├── catalog/ # Скиллы: git submodule'ы на внешние репы
│ ├── jakubkrehel-skills/ # → github.com/jakubkrehel/skills (11 скиллов UI)
│ └── developer-documentation-skill/ # → NateBJones-Projects/… (доки; ставится вручную)
├── scripts/
│ └── harness # Основной CLI-скрипт
└── README.md
```
## Грамматика
**Объект — первым, действие — вторым:** `harness <объект> <действие> [аргументы]`
| Объект | Что это | Действия |
|--------|---------|----------|
| `status` | среда целиком | — |
| `skills` | скиллы из каталога | `list`, `installed`, `install`, `remove` |
| `agents` | агенты (только OpenCode) | `list`, `install`, `remove` |
| `mcp` | MCP-серверы Hermes | `list`, `add`, `rm` |
| `catalog` | внешние репозитории каталога | `list`, `init`, `update` |
| `hermes` | сам Hermes | `config`, `restart`, `update` |
| `opencode` | сам OpenCode | `install`, `restart` |
```bash
./scripts/harness status
./scripts/harness skills list
./scripts/harness skills install jakubkrehel-skills better-ui --target all
./scripts/harness agents install leader
./scripts/harness mcp list
./scripts/harness catalog update
./scripts/harness hermes restart
```
## Быстрый старт
```bash
./scripts/harness status # Обзор среды
./scripts/harness skills list # Что доступно в каталоге (+ отметки установки)
./scripts/harness skills installed # Что реально стоит у агентов
./scripts/harness agents list # Агенты: доступные в репо + установленные
./scripts/harness mcp list # MCP-серверы Hermes
./scripts/harness catalog list # Источники каталога
```
## Правила вывода списков
Все списочные команды идут через один рендерер — `render_listing()`. Новую
списочную команду нужно добавлять так же: собрать `rows` и вызвать рендерер,
а не печатать таблицу самой.
```
СКИЛЛЫ — доступно к установке ← 1. заголовок ВЕРХНИМ РЕГИСТРОМ
Каталог: /mnt/data/Agent/dev/harness/catalog ← 2. источник, dim
✓ — установлено, · — нет ← 3. легенда, если есть отметки
jakubkrehel-skills (11 скиллов, 267330e) ← 4. группа, мета в скобках
├─ better-ui hermes · opencode ✓ ← 5. имя, мета, отметки
│ Polishes and improves the UI in your… ← 6. описание, обрезка до 72
Итого: 12 скиллов, установлено 0 ← 7. итог
hermes ~/.hermes/skills/catalog ← куда ставится, dim
```
1. **Заголовок** — ВЕРХНИМ РЕГИСТРОМ, формат `<ОБЪЕКТ> — что именно`.
2. **Источник** — второй строкой, dim: `Каталог: <путь>` / `Источник: <путь>`.
3. **Легенда отметок** — `✓ — установлено, · — нет`, только если отметки есть.
4. **Группы** — жёлтым, метаданные в скобках (кол-во, sha, `⚠ сдвинут`), между
группами пустая строка. Нет групп — строки идут сразу после легенды.
5. **Элемент** — `├─ <имя>` (cyan, выравнивание по самому длинному имени), затем
мета (dim, выровнена), затем отметки `<цель> ✓` / `<цель> ·`, затем пометка (yellow).
6. **Описание** — строкой ниже, dim, обрезано до 72 символов.
7. **Итог** — `Итого: N <единица>, установлено M`, ниже dim-строками — куда ставится.
8. **Только русский.** Никаких `Available` / `Installed` вперемешку с русским.
9. **Порядок отметок** = порядок целей из `--target` / `--scope`.
10. **Числа — со склонением** через `plural()`: 1 скилл, 2 скилла, 5 скиллов.
Правила продублированы комментарием в `scripts/harness` над `render_listing()`.
## `skills` — скиллы из каталога
### `skills list` — что доступно к установке
Показывает содержимое каталога и где скилл уже стоит. `✓` — установлено, `·` — нет.
```bash
./scripts/harness skills list
./scripts/harness skills list --target opencode
```
```
СКИЛЛЫ — доступно к установке
Каталог: /mnt/data/Agent/dev/harness/catalog
✓ — установлено, · — нет
jakubkrehel-skills (11 скиллов, 267330e)
├─ better-ui hermes · opencode ✓
│ Polishes and improves the UI in your project…
├─ better-colors hermes · opencode ·
│ Helps you build a color system…
...
Итого: 12 скиллов, установлено 1
Поставить: harness skills install <источник> <скилл>|--all
hermes ~/.hermes/skills/catalog
opencode ~/.claude/skills ~/.config/opencode/skills
```
Для git-источников в скобках группы виден короткий sha; `⚠ сдвинут` — submodule
ушёл вперёд и это ещё не закоммичено.
### `skills installed` — что реально стоит
Полное дерево каталогов агента, включая скиллы не из каталога.
```bash
./scripts/harness skills installed
./scripts/harness skills installed --target hermes
```
### `skills install` / `skills remove`
```bash
# Один скилл
./scripts/harness skills install jakubkrehel-skills better-ui --target opencode
./scripts/harness skills install jakubkrehel-skills/better-ui --target all
# Все скиллы источника
./scripts/harness skills install jakubkrehel-skills --all --target opencode
# Удалить
./scripts/harness skills remove better-ui
./scripts/harness skills remove better-ui --target hermes
```
Скиллы ставятся **симлинками**:
| Агент | Куда ставится |
|-------|--------------|
| Hermes | `~/.hermes/skills/catalog/<name>/` |
| OpenCode | `~/.claude/skills/<name>/` |
| OpenCode | `~/.config/opencode/skills/<name>/` |
## `agents` — агенты (только OpenCode)
Источник — `harness/agents/*.md`. Имя агента = имя файла без `.md`.
```bash
./scripts/harness agents list
./scripts/harness agents list --scope global
./scripts/harness agents list --scope project --project ~/work/myrepo
./scripts/harness agents install leader # в ~/.config/opencode/agents/
./scripts/harness agents install --all --scope global
./scripts/harness agents install devops --scope project --project ~/work/myrepo
./scripts/harness agents remove leader
./scripts/harness agents remove leader --scope global
```
| `--scope` | Куда ставится |
|-----------|--------------|
| `global` (по умолчанию) | `~/.config/opencode/agents/<name>.md` |
| `project` | `<project>/.opencode/agents/<name>.md` (по умолчанию — cwd) |
Ставятся симлинками, так что правки в репе сразу видны OpenCode. Все агенты имеют
`mode: all` (кроме `leader` — `primary`), чтобы лидер мог вызывать их как сабагентов.
> **Hermes агентов не поддерживает** — только runtime-делегирование через
> `delegate_task`. Пользовательских определений агентов у него нет.
## `mcp` — MCP-серверы Hermes
```bash
./scripts/harness mcp list
# По URL (HTTP/SSE)
./scripts/harness mcp add my-server http://localhost:8000/mcp
# Командой (stdio)
./scripts/harness mcp add github npx \
--env GITHUB_TOKEN=ghp_xxx \
--arg -y --arg @modelcontextprotocol/server-github
./scripts/harness mcp rm my-server
```
`add` и `rm` сами перезапускают `hermes-gateway`, чтобы изменения подхватились.
## `catalog` — внешние репозитории
```bash
./scripts/harness catalog list # источники, sha, признак «сдвинут»
./scripts/harness catalog init # стянуть submodule'ы на зафиксированных коммитах
./scripts/harness catalog update # подтянуть свежие коммиты upstream (потом закоммитить)
```
### Свежий клон
Submodule'ы **не** тянутся при обычном `git clone` — каталоги `catalog/*/` окажутся
пустыми. `skills list` это распознаёт и подсказывает, что делать:
```
СКИЛЛЫ — доступно к установке
Каталог: /path/to/catalog
✓ — установлено, · — нет
⚠ submodule'ы не стянуты: jakubkrehel-skills
├─ jakubkrehel-skills не инициализирован
Итого: 0 скиллов, установлено 0
Стянуть: harness catalog init
```
Дальше — `harness catalog init`. Либо сразу клонировать с сабмодулями:
```bash
git clone --recurse-submodules git@git.itphx.loc:eka/harness.git
```
`catalog init` идемпотентен: если всё на месте, просто сообщит об этом.
`catalog update`, в отличие от него, двигает коммиты на актуальные upstream —
сначала стягивает недостающие, потом обновляет.
## `hermes` / `opencode` — сам агент
```bash
./scripts/harness hermes config # показать конфиг
./scripts/harness hermes config --set model.default=gpt-4o
./scripts/harness hermes config --set agent.max_turns=200
./scripts/harness hermes restart # systemctl --user restart hermes-gateway + webui
./scripts/harness hermes update # hermes update + рестарт сервисов
./scripts/harness opencode install # curl-установщик opencode.ai
./scripts/harness opencode restart # systemctl --user restart opencode + openchamber
```
`hermes config --set` меняет `~/.hermes/config.yaml` и перезапускает сервисы.
## Как добавить скилл в каталог
Каталог — это **git submodule'ы**: в репе фиксируется ссылка на внешний репозиторий
и точный коммит, а не копия файлов.
```bash
git submodule add https://github.com/user/skills-repo.git catalog/user-skills
git commit -m "chore: add user-skills to catalog"
```
После этого `harness skills list` покажет найденные скиллы, а
`harness catalog update` подтянет свежие коммиты во всех submodule'ах.
### Раскладка репозитория и ручная установка
CLI понимает одну раскладку — `<репа>/skills/<name>/SKILL.md`. Репозитории с другой
структурой (`SKILL.md` в корне, `.agents/skills/`, вложенные категории) он показывает
без списка скиллов, и такие скиллы ставятся вручную. Ограничение только у CLI: сам
OpenCode сканирует рекурсивно (`skills/**/SKILL.md`, а через `skills.paths` —
`**/SKILL.md` на любой глубине).
Пример — `developer-documentation-skill` держит `SKILL.md` в корне репы:
```bash
ln -s /mnt/data/Agent/dev/harness/catalog/developer-documentation-skill \
~/.agents/skills/developer-documentation
```
Альтернатива без симлинков — указать в конфиге OpenCode корень каталога:
```json
{ "skills": { "paths": ["/mnt/data/Agent/dev/harness/catalog"] } }
```
Тогда OpenCode найдёт все `SKILL.md` из каталога, в любой раскладке. Минус —
подхватывается всё содержимое разом, включая ненужное.
## Как добавить агента
Положить `.md` файл в `agents/` репозитория — и он сразу виден через `harness agents list`.
Формат — как у OpenCode:
```markdown
---
description: "Что делает агент и когда его звать"
mode: all # primary | subagent | all
temperature: 0.1
steps: 100
color: "#2563eb"
permission:
task: deny
bash: allow
edit: allow
---
# Имя агента
Тело промпта: роль, принципы, порядок работы, что НЕ делать, формат ответа.
```
- `mode: all` — можно и вызвать напрямую, и делегировать из `leader` (сабагент).
- `mode: primary` — только как основной агент (Tab в UI). Такой агент **не** появится
в `task`-инструменте лидера: OpenCode фильтрует список сабагентов по `mode !== "primary"`.
## Поддерживаемые форматы
- **Скиллы** — `SKILL.md` с YAML frontmatter (`name`, `description`); родной формат OpenCode и Hermes.
- **Агенты** — `<name>.md` с frontmatter (`description`, `mode`, ...); формат OpenCode.
## Конвенции репозитория
- **Временные файлы — только в `tmp/`** репозитория: фикстуры, логи, эксперименты,
распакованные архивы. Не в `/tmp`, не в корне. `tmp/` в `.gitignore`.
- Источники каталога — git submodule'ы, а не копии файлов.
- Агенты — `agents/<имя>.md`, имя агента = имя файла без расширения.
- Все списочные команды — через `render_listing()` (см. «Правила вывода списков»).
- Идентичность коммитов — как в остальных репах: `eka <eeeeka@itphx.loc>`.
## Совместимость
| Фича | Hermes | OpenCode |
|------|--------|----------|
| Skills (SKILL.md) | ✅ `~/.hermes/skills/` | ✅ `~/.claude/skills/`, `~/.config/opencode/skills/` |
| Agents | ❌ (только `delegate_task` в рантайме) | ✅ `~/.config/opencode/agents/`, `<project>/.opencode/agents/` |
| MCP-серверы | ✅ `config.yaml mcp_servers` | 🟡 через `opencode.json` |
| Plugins | ✅ `.hermes/plugins/` | ❌ (не поддерживает) |
| Systemd service | ✅ gateway + webui | ✅ opencode + openchamber |
| CLI install/update | `hermes update` | curl install script |