Files
board-viewer/.wiki/concepts/board-viewer.md
vitya 1c7e372abf feat(reader): STATUS.md parser + TS project scaffold [skip-tdd: visual for configs]
- vitest+TS scaffold (package.json/tsconfig/vitest.config = config artifacts)
- src/parser.ts: parses STATUS.md blocks → StatusBlock[]
- tests/parser.test.ts: 6 cases (single, multi, blocker, null-blocker, empty, unknown emoji)
- fix emoji contract: align with using-tasks reality ( open / 🔴 in_progress / 🟡 paused / 🔵 blocked / 🟢 done); reader-task acceptance + design doc updated

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:44:11 +03:00

106 lines
8.4 KiB
Markdown
Raw 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.
---
title: Board viewer — design
type: concept
date: 2026-05-22
status: promoted
source: .workshop/.archive/2026-05-22-board-viewer.md
sources:
- https://hermes-agent.nousresearch.com/docs/user-guide/features/kanban
- https://hermes-agent.nousresearch.com/docs/user-guide/features/kanban-tutorial
- .tasks/STATUS.md per-project emoji-словарь (⚪🟡🟣🔴🟢)
- mcp__projects-meta__tasks_aggregate (текстовый кросс-проектный вид)
---
# Board viewer — визуал прогресса по таскам
## Контекст
Сейчас визуала прогресса по таскам нет — есть только текстовые формы: `.tasks/STATUS.md` per-project с emoji-легендой (⚪ open / 🟡 paused / 🔴 in-progress / 🟢 done / 🔵 blocked) и `mcp__projects-meta__tasks_aggregate` поверх Gitea-репо `OpeItcLoc03/agenda`. Цель — визуальная kanban-доска для глаз.
## Что увидено у hermes-agent
Их kanban — не «доска», а **execution engine**:
- SQLite-DB `~/.hermes/kanban.db` как SoT.
- 6 колонок: `triage / todo / ready / running / blocked / done` (+ `archived`).
- Dispatcher каждые 60s спавнит workers, workers общаются с доской через тулсы (`kanban_show`, `kanban_heartbeat`, `kanban_complete`, `kanban_block`).
- Decomposer auto-fans `triage``todo` через специальный профиль.
- Circuit-breaker: 2 фейла подряд → auto-block.
- Web-dashboard с drag-drop, multi-select, run-history per task.
- CLI: `hermes kanban create/show/runs/decompose/watch/notify-subscribe`.
- REST API `/api/plugins/kanban/`.
- Single-host by design (cite: «~/.hermes/kanban.db is a local SQLite file ... Running a shared board across two hosts is not supported»).
Это **мультиагентский оркестратор**, где kanban — UI-слой. **Это другой кейс**, чем наш — выделили в отдельный буфер `agent-orchestration-without-user.md` (там идёт самостоятельное обсуждение).
## Решение: read-only HTML kanban-viewer над Gitea API, хостинг на VDS
**Что:** маленький HTTP-сервис на VDS (рядом с Gitea, traefik уже там), который читает Gitea API напрямую (`OpeItcLoc03/agenda` + per-project репо) и рендерит 5-колоночную доску по emoji-словарю: ⚪ open / 🟡 paused / 🔴 in-progress / 🟢 done / 🔵 blocked.
**Где:** домен `board.kzntsv.site` за traefik, рядом с `git.kzntsv.site`.
**Как обновляется:** cron-тик каждые ~5 мин, перегенерация статической HTML. Realtime не нужен — таски меняются раз в сессию.
**SoT не меняется:** `.tasks/<slug>.md` + `STATUS.md` в каждом проекте, Gitea `agenda` репо как backend. Markdown остаётся grep-able, git-blameable, скилы `using-tasks`/`setup-tasks` не ломаются.
**Размер:** ~200-300 LOC сервис + traefik label + cron-таймер.
## Implementation note — почему Gitea API, а не MCP
В исходном брейнсторме предполагалось «дергает `mcp__projects-meta__tasks_aggregate` или читает Gitea API напрямую». **Это ложная развилка:** `mcp__projects-meta__*` доступен только внутри Claude Code-контекста, у HTTP-сервиса этой шины нет. Реальный единственный путь — **прямой Gitea API** (`GET /api/v1/repos/OpeItcLoc03/agenda/contents/...`) с тем же admin-токеном из `~/.config/projects-mcp/auth.toml`. По сути — переписываем кусок логики `tasks_aggregate` поверх HTTP, не «дёргаем готовое».
## Почему не hermes-стиль
Hermes kanban — это execution engine. Dispatcher спавнит workers, агенты heartbeat'ят, circuit-breaker блокирует таску после 2 фейлов, decomposer фанаут'ит triage→todo автоматически. Это нужно когда у тебя автономный fleet агентов работает без человека. У нас другой паттерн: **визуальный прогресс** ≠ оркестрация. Импортировать их dispatcher/worker модель ради UI-слоя — купить большой движок ради картинки.
Тема «автономные cross-project агенты» обсуждается отдельно в `agent-orchestration-without-user.md`. Если она дойдёт до промоушена — там может появиться execution engine, и viewer станет естественной мордой к нему. **Viewer от него не зависит**: над `.tasks/*.md` он работает уже сейчас.
## Почему не Gitea Projects
Gitea Projects работает поверх **issues** одного репо. Чтобы он стал нашей доской — надо мигрировать `.tasks/<slug>.md` → Gitea issues как первичный носитель. Цена:
- ❌ убивается markdown grep по проекту,
- ❌ ломаются скилы `using-tasks`/`setup-tasks`, которые ждут per-task `.md` файлы,
- ❌ git-история per-task переезжает в БД Gitea, не в `git log`.
Слишком высокая цена ради drag-drop.
## Trade-offs честно
| Минус | Что значит |
|---|---|
| read-only | drag-drop статуса нет; меняем через редактирование `.md` (как сейчас) |
| 5-мин лаг | не realtime; ок для таск-доски, не ок для лога инцидентов |
| зависит от Gitea API | если Gitea упадёт — доска показывает stale (но это уже catastrophic incident) |
Drag-drop **разблокируется автоматически** когда починим `projects-meta` write-side bug cluster — см. memory `reference_projects_meta_resolveTarget_bug.md`. Это уже в плане работ по `projects-meta`, не блокер этого проекта.
## Что внутри viewer'а — MVP
- **5-колоночный board** по статусам (без `triage`/`ready` — наш словарь иной).
- **Карточка таски:** title, проект, owner (если есть), age (since open), последний коммит-маркер.
- **Группировка по проекту** опционально (toggle «по статусам vs по проектам»).
- **Поиск/фильтр** по проекту, тегам, owner'у — клиент-сайд JS (нет API за пределами initial-load).
- **Per-card drawer** показывает full markdown из `<slug>.md` (lazy-fetch из Gitea raw).
- **Refresh-таймер** видно на странице.
Чего точно нет в MVP:
- write-side ничего (drag-drop, edit, create);
- realtime обновления (WS, SSE);
- multi-tenant (пока один юзер);
- auth (это traefik basic-auth, не in-app);
- run history (это уровень оркестратора, не viewer'а).
## Зависимости
- Прямой read Gitea API к `OpeItcLoc03/agenda` + per-project репо — **уже работает**.
- traefik route + DNS на `board.kzntsv.site` — стандартная инфра VDS.
- cron tick — systemd timer или `vds-job-scheduler` (если поднимем) — на выбор при имплементации.
Ничего блокирующего.
## Связь с `agent-orchestration-without-user.md`
Viewer — независимый артефакт. Он читает текущий `.tasks/*.md` SoT, и продолжит работать как-есть после промоушена оркестратора (тот добавляет поля типа `owner`, `claim_token` — viewer просто отрендерит их в карточке). **Не блокируется ничем из orchestration-брейнсторма**, не блокирует его.