docs: обновлён WebSocket протокол, убраны адаптеры, capabilities на агентах
This commit is contained in:
parent
5061c60b9a
commit
7849a1fddb
374
IDEAS.md
374
IDEAS.md
@ -61,9 +61,9 @@
|
|||||||
|
|
||||||
| Компонент | Описание |
|
| Компонент | Описание |
|
||||||
|-----------|----------|
|
|-----------|----------|
|
||||||
| **Tracker** | Ядро: проекты, задачи, чаты, события. Внутренний, WebSocket сервер |
|
| **Tracker** | Ядро: проекты, задачи, чаты, события. Внутренний, WebSocket сервер. Роутинг событий агентам |
|
||||||
| **Web Client** | Next.js + BFF (Python). Авторизация через Authentik. Единственное что торчит наружу |
|
| **Web Client** | Next.js + BFF (Python). Авторизация через Authentik. Единственное что торчит наружу |
|
||||||
| **Агенты** | Отдельные сервисы. Подключаются к трекеру по WebSocket |
|
| **Агенты** | Независимые приложения (любой язык). Подключаются к Tracker по WebSocket |
|
||||||
|
|
||||||
### Репозитории
|
### Репозитории
|
||||||
|
|
||||||
@ -221,48 +221,15 @@ Task A ──depends_on──→ Task B
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Агенты и адаптеры
|
## Агенты
|
||||||
|
|
||||||
### Адаптер (провайдер)
|
### Принцип
|
||||||
|
|
||||||
Адаптер — это подключение к конкретной нейросети. Один адаптер может использоваться несколькими агентами.
|
**Агент = независимое приложение.** Написано на чём угодно (Python, Go, Rust, JS — без разницы). Подключается к Tracker по WebSocket. Может быть даже человек с WebSocket-клиентом.
|
||||||
|
|
||||||
```yaml
|
Tracker не знает и не заботится, что внутри агента — нейросеть, скрипт или человек.
|
||||||
Адаптер:
|
|
||||||
id: uuid
|
|
||||||
название: "Claude Opus"
|
|
||||||
провайдер: anthropic | openai | google | openclaw | cli
|
|
||||||
|
|
||||||
# Конфиг — JSON поле, разное для каждого провайдера
|
### Структура агента
|
||||||
config:
|
|
||||||
# Anthropic
|
|
||||||
api_key: "sk-ant-..."
|
|
||||||
model: "claude-opus-4-5"
|
|
||||||
max_tokens: 8192
|
|
||||||
|
|
||||||
# Или OpenAI
|
|
||||||
api_key: "sk-..."
|
|
||||||
model: "gpt-4"
|
|
||||||
organization: "org-..."
|
|
||||||
|
|
||||||
# Или OpenClaw
|
|
||||||
gateway_url: "http://localhost:18789"
|
|
||||||
gateway_token: "..."
|
|
||||||
agent_id: "main"
|
|
||||||
|
|
||||||
# Или CLI
|
|
||||||
command: "claude"
|
|
||||||
working_dir: "/workspace"
|
|
||||||
|
|
||||||
# Возможности адаптера (что умеет эта нейросеть)
|
|
||||||
capabilities: ["coding", "analytics", "review", "design", "docs", "testing"]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Важно:** Capabilities привязаны к адаптеру, не к агенту. Потому что возможности определяются нейросетью.
|
|
||||||
|
|
||||||
### Агент
|
|
||||||
|
|
||||||
Агент — это "личность" с ролью, которая использует адаптер.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Агент:
|
Агент:
|
||||||
@ -270,20 +237,21 @@ Task A ──depends_on──→ Task B
|
|||||||
имя: "Кодер"
|
имя: "Кодер"
|
||||||
slug: "coder"
|
slug: "coder"
|
||||||
|
|
||||||
# Привязка к адаптеру
|
# Capabilities — что умеет этот агент
|
||||||
адаптер_id: uuid
|
capabilities: ["coding", "backend", "testing"]
|
||||||
|
|
||||||
# Роль
|
|
||||||
системный_промпт: "Ты — backend разработчик..."
|
|
||||||
|
|
||||||
# Подписка
|
# Подписка
|
||||||
подписка:
|
подписка:
|
||||||
режим: mentions # all | mentions | assigned
|
режим: assigned # all | mentions | assigned
|
||||||
проекты: ["*"] # или конкретные
|
проекты: ["*"] # или конкретные
|
||||||
|
|
||||||
# Ограничения
|
# Ограничения
|
||||||
макс_параллельных: 2
|
макс_параллельных: 2
|
||||||
таймаут: 600 # секунд
|
таймаут: 600 # секунд
|
||||||
|
|
||||||
|
# Статус (управляется Tracker)
|
||||||
|
status: online | offline | busy
|
||||||
|
last_heartbeat: timestamp
|
||||||
```
|
```
|
||||||
|
|
||||||
### Лейблы
|
### Лейблы
|
||||||
@ -301,30 +269,20 @@ CREATE TABLE labels (
|
|||||||
|
|
||||||
Примеры: `coding`, `design`, `analytics`, `testing`, `docs`, `backend`, `frontend`, `urgent`, `bug`
|
Примеры: `coding`, `design`, `analytics`, `testing`, `docs`, `backend`, `frontend`, `urgent`, `bug`
|
||||||
|
|
||||||
### Связка: лейблы задач ↔ capabilities адаптеров
|
### Связка: лейблы задач ↔ capabilities агентов
|
||||||
|
|
||||||
```
|
```
|
||||||
Задача с лейблом "coding" → только агенты с адаптером, у которого capability "coding"
|
Задача с лейблом "coding" → только агенты с capability "coding"
|
||||||
Задача с лейблом "design" → только агенты с адаптером, у которого capability "design"
|
Задача с лейблом "design" → только агенты с capability "design"
|
||||||
```
|
```
|
||||||
|
|
||||||
Агент-дизайнер НЕ возьмёт задачу с лейблом `coding` — у его адаптера нет такой capability.
|
Агент-дизайнер НЕ возьмёт задачу с лейблом `coding` — у него нет такой capability.
|
||||||
|
|
||||||
### Типы провайдеров
|
|
||||||
|
|
||||||
| Провайдер | Описание | Конфиг |
|
|
||||||
|-----------|----------|--------|
|
|
||||||
| `anthropic` | Claude API | api_key, model, max_tokens |
|
|
||||||
| `openai` | GPT, Codex | api_key, model, organization |
|
|
||||||
| `google` | Gemini | api_key, model |
|
|
||||||
| `openclaw` | OpenClaw Gateway | gateway_url, gateway_token, agent_id |
|
|
||||||
| `cli` | Claude Code CLI | command, working_dir |
|
|
||||||
|
|
||||||
### Подписка на события
|
### Подписка на события
|
||||||
|
|
||||||
| Режим | Агент получает |
|
| Режим | Агент получает |
|
||||||
|-------|---------------|
|
|-------|---------------|
|
||||||
| `all` | Все сообщения в подписанных проектах |
|
| `all` | Все события в подписанных проектах |
|
||||||
| `mentions` | Только когда @упомянут |
|
| `mentions` | Только когда @упомянут |
|
||||||
| `assigned` | Назначенные задачи + mentions |
|
| `assigned` | Назначенные задачи + mentions |
|
||||||
|
|
||||||
@ -332,30 +290,108 @@ CREATE TABLE labels (
|
|||||||
|
|
||||||
## WebSocket протокол
|
## WebSocket протокол
|
||||||
|
|
||||||
### Трекер → Клиент
|
### Подключение и Init Handshake
|
||||||
|
|
||||||
|
При подключении агент проходит аутентификацию и получает начальный контекст:
|
||||||
|
|
||||||
```
|
```
|
||||||
task.created — задача создана
|
1. Агент подключается: ws://tracker:8100/ws
|
||||||
task.updated — задача обновлена
|
2. Агент → Tracker: auth
|
||||||
task.ready — задача готова к выполнению (перенесена из Backlog)
|
{
|
||||||
|
"type": "auth",
|
||||||
|
"token": "agent-token-xxx"
|
||||||
|
}
|
||||||
|
|
||||||
|
3. Tracker → Агент: auth.ok + init (начальный контекст)
|
||||||
|
{
|
||||||
|
"type": "auth.ok",
|
||||||
|
"agent": {
|
||||||
|
"id": "uuid",
|
||||||
|
"name": "Кодер",
|
||||||
|
"capabilities": ["coding", "backend"]
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"projects": [
|
||||||
|
{"id": "uuid", "name": "Team Board", "slug": "team-board"}
|
||||||
|
],
|
||||||
|
"assigned_tasks": [
|
||||||
|
{"id": "uuid", "title": "...", "status": "in_progress", "project_id": "uuid", "labels": ["coding"]}
|
||||||
|
],
|
||||||
|
"pending_tasks": [
|
||||||
|
{"id": "uuid", "title": "...", "status": "ready", "project_id": "uuid", "labels": ["coding"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
4. При ошибке:
|
||||||
|
{
|
||||||
|
"type": "auth.error",
|
||||||
|
"message": "Invalid token"
|
||||||
|
}
|
||||||
|
→ соединение закрывается
|
||||||
|
```
|
||||||
|
|
||||||
|
**init** содержит:
|
||||||
|
- **projects** — проекты, в которых участвует агент
|
||||||
|
- **assigned_tasks** — задачи, назначенные на этого агента (in_progress, review)
|
||||||
|
- **pending_tasks** — задачи, подходящие по capabilities и готовые к взятию (ready)
|
||||||
|
|
||||||
|
### Роутинг событий (Tracker → Агент)
|
||||||
|
|
||||||
|
Tracker фильтрует события по трём критериям:
|
||||||
|
|
||||||
|
**1. Capabilities** — лейблы задачи ∩ capabilities агента
|
||||||
|
- Задача с лейблом `coding` → только агентам с capability `coding`
|
||||||
|
- Нет совпадения → событие не отправляется
|
||||||
|
|
||||||
|
**2. Подписка агента** (subscription mode)
|
||||||
|
- `assigned` → только свои задачи + @mentions
|
||||||
|
- `mentions` → @mentions в чатах и комментариях
|
||||||
|
- `all` → все события (фильтруются по capabilities)
|
||||||
|
|
||||||
|
**3. Чаты** — отдельная логика:
|
||||||
|
- **Чат задачи** → assignee + участники обсуждения
|
||||||
|
- **Чат проекта** → все агенты проекта (без фильтра по capabilities — обсуждение для всех)
|
||||||
|
- **Лобби** → все подключённые агенты
|
||||||
|
|
||||||
|
### Трекер → Клиент (события)
|
||||||
|
|
||||||
|
```
|
||||||
|
task.created — задача создана (с учётом роутинга)
|
||||||
|
task.updated — задача обновлена (статус, описание, лейблы)
|
||||||
|
task.ready — задача готова к выполнению
|
||||||
task.assigned — задача назначена агенту
|
task.assigned — задача назначена агенту
|
||||||
task.blocked — задача заблокирована зависимостью
|
task.blocked — задача заблокирована зависимостью
|
||||||
task.unblocked — зависимость выполнена, задача разблокирована
|
task.unblocked — зависимость выполнена, задача разблокирована
|
||||||
chat.message — новое сообщение в чате
|
chat.message — новое сообщение в чате (с учётом роутинга)
|
||||||
agent.status — статус агента изменился
|
agent.status — статус агента изменился (online/offline/busy)
|
||||||
file.attached — файл прикреплён к задаче
|
file.attached — файл прикреплён к задаче
|
||||||
```
|
```
|
||||||
|
|
||||||
### Клиент → Трекер
|
### Клиент → Трекер (команды)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
auth — аутентификация (первое сообщение)
|
||||||
task.take — агент берёт задачу
|
task.take — агент берёт задачу
|
||||||
task.complete — агент завершил задачу
|
task.complete — агент завершил задачу
|
||||||
|
task.update — агент обновляет задачу (статус, описание)
|
||||||
task.comment — комментарий к задаче
|
task.comment — комментарий к задаче
|
||||||
task.attach — прикрепить файл
|
task.attach — прикрепить файл
|
||||||
chat.send — отправить сообщение в чат
|
chat.send — отправить сообщение в чат
|
||||||
agent.register — регистрация агента
|
agent.heartbeat — пульс (каждые 30 сек)
|
||||||
agent.heartbeat — пульс
|
```
|
||||||
|
|
||||||
|
### Heartbeat
|
||||||
|
|
||||||
|
```
|
||||||
|
Агент → Tracker (каждые 30 сек):
|
||||||
|
{
|
||||||
|
"type": "agent.heartbeat",
|
||||||
|
"status": "idle" | "busy",
|
||||||
|
"current_tasks": ["task-uuid-1"]
|
||||||
|
}
|
||||||
|
|
||||||
|
Если heartbeat не пришёл 90 секунд → agent.status = offline
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -463,27 +499,18 @@ review_history:
|
|||||||
## База данных (ключевые таблицы)
|
## База данных (ключевые таблицы)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- Адаптеры (подключения к нейросетям)
|
-- Агенты (независимые приложения)
|
||||||
CREATE TABLE adapters (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
provider TEXT NOT NULL, -- anthropic, openai, google, openclaw, cli
|
|
||||||
config JSONB NOT NULL, -- всё специфичное для провайдера
|
|
||||||
capabilities TEXT[] NOT NULL, -- ["coding", "analytics", "review", ...]
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Агенты (личности с ролями)
|
|
||||||
CREATE TABLE agents (
|
CREATE TABLE agents (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
slug TEXT UNIQUE NOT NULL,
|
slug TEXT UNIQUE NOT NULL,
|
||||||
adapter_id UUID REFERENCES adapters(id),
|
token TEXT UNIQUE NOT NULL, -- токен для WebSocket auth
|
||||||
system_prompt TEXT,
|
capabilities TEXT[] NOT NULL DEFAULT '{}', -- ["coding", "analytics", ...]
|
||||||
subscription_mode TEXT DEFAULT 'mentions', -- all, mentions, assigned
|
subscription_mode TEXT DEFAULT 'assigned', -- all, mentions, assigned
|
||||||
max_concurrent INT DEFAULT 1,
|
max_concurrent INT DEFAULT 1,
|
||||||
timeout_seconds INT DEFAULT 600,
|
timeout_seconds INT DEFAULT 600,
|
||||||
status TEXT DEFAULT 'idle',
|
status TEXT DEFAULT 'offline', -- online, offline, busy
|
||||||
|
last_heartbeat TIMESTAMPTZ,
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -544,176 +571,59 @@ CREATE TABLE task_files (
|
|||||||
|
|
||||||
### Принцип
|
### Принцип
|
||||||
|
|
||||||
**Агент = отдельный процесс.** Не привязан к OpenClaw или конкретному серверу. Может быть запущен локально, на другом сервере, в Docker — где угодно. Подключается к Tracker по WebSocket.
|
**Агент = независимое приложение.** Написано на чём угодно. Подключается к Tracker по WebSocket. Tracker не управляет запуском — агент сам стартует и подключается.
|
||||||
|
|
||||||
### Архитектура
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────┐
|
|
||||||
│ Agent Process │
|
|
||||||
│ ┌───────────────────┐ │
|
|
||||||
│ │ Agent SDK │ │ ← общая Python-библиотека
|
|
||||||
│ │ ┌──────────────┐ │ │
|
|
||||||
│ │ │ Adapter │ │ │ ← OpenClaw / OpenAI / Ollama / CLI
|
|
||||||
│ │ └──────────────┘ │ │
|
|
||||||
│ └─────────┬─────────┘ │
|
|
||||||
└────────────┼────────────┘
|
|
||||||
│ WebSocket (локально или через интернет)
|
|
||||||
┌──────┴──────┐
|
|
||||||
│ Tracker │
|
|
||||||
│ AgentManager │
|
|
||||||
└─────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### Agent SDK (Python-пакет)
|
|
||||||
|
|
||||||
Общая библиотека для всех агентов:
|
|
||||||
|
|
||||||
```python
|
|
||||||
from team_board.agent import Agent
|
|
||||||
from team_board.adapters import OpenClawAdapter
|
|
||||||
|
|
||||||
adapter = OpenClawAdapter(
|
|
||||||
gateway_url="http://localhost:18789",
|
|
||||||
gateway_token="...",
|
|
||||||
)
|
|
||||||
|
|
||||||
agent = Agent(
|
|
||||||
name="Кодер",
|
|
||||||
tracker_url="ws://localhost:8100",
|
|
||||||
adapter=adapter,
|
|
||||||
system_prompt="Ты — backend разработчик...",
|
|
||||||
)
|
|
||||||
|
|
||||||
agent.run() # подключается к Tracker, слушает задачи
|
|
||||||
```
|
|
||||||
|
|
||||||
Что делает SDK:
|
|
||||||
- **WebSocket клиент** → подключение к Tracker, переподключение при разрыве
|
|
||||||
- **Heartbeat** → автоматический пинг каждые N секунд
|
|
||||||
- **Обработка задач** → получил задачу → передал адаптеру → вернул результат
|
|
||||||
- **Файловые операции** → загрузка/скачивание файлов задачи
|
|
||||||
|
|
||||||
### Адаптеры (BaseAdapter)
|
|
||||||
|
|
||||||
```python
|
|
||||||
class BaseAdapter(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
async def send(self, messages: list[Message]) -> Response:
|
|
||||||
"""Отправить сообщения нейросети и получить ответ."""
|
|
||||||
...
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def capabilities(self) -> list[str]:
|
|
||||||
"""Возвращает capabilities адаптера."""
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
Реализации:
|
|
||||||
| Адаптер | Подключение | Особенности |
|
|
||||||
|---------|-------------|-------------|
|
|
||||||
| `OpenClawAdapter` | Webhooks / sessions_spawn | Доступ к инструментам OpenClaw |
|
|
||||||
| `AnthropicAdapter` | Claude API напрямую | Чистый API, без инструментов |
|
|
||||||
| `OpenAIAdapter` | GPT / Codex API | |
|
|
||||||
| `OllamaAdapter` | Локальная модель | Бесплатно, офлайн |
|
|
||||||
| `CLIAdapter` | Claude Code CLI | Доступ к файловой системе |
|
|
||||||
|
|
||||||
### AgentManager (в Tracker)
|
### AgentManager (в Tracker)
|
||||||
|
|
||||||
Tracker управляет жизненным циклом агентов:
|
Tracker отслеживает подключённых агентов:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Реестр агентов:
|
Реестр агентов:
|
||||||
- id: uuid
|
- id: uuid
|
||||||
name: "Кодер"
|
name: "Кодер"
|
||||||
adapter: "Claude Opus"
|
status: online | offline | busy
|
||||||
status: online | offline | busy | dead
|
capabilities: ["coding", "backend"]
|
||||||
host: "localhost" # где запущен
|
|
||||||
pid: 12345 # PID процесса (если локальный)
|
|
||||||
last_heartbeat: timestamp
|
last_heartbeat: timestamp
|
||||||
current_tasks: [task_id]
|
current_tasks: [task_id]
|
||||||
```
|
```
|
||||||
|
|
||||||
Функции AgentManager:
|
Функции AgentManager:
|
||||||
1. **Запуск** — поднимает агента как отдельный процесс (локально: subprocess/systemd)
|
1. **Регистрация** — агент подключился → auth → попал в реестр
|
||||||
2. **Мониторинг** — следит за heartbeat, помечает dead если пропал
|
2. **Мониторинг** — следит за heartbeat, помечает offline если пропал
|
||||||
3. **Перезапуск** — dead агент → повторный запуск (макс 3 попытки)
|
3. **Назначение задач** — матчит задачу → подходящего агента по capabilities + загрузке
|
||||||
4. **Назначение задач** — матчит задачу → подходящего агента по capabilities + загрузке
|
4. **Роутинг событий** — фильтрация по capabilities + подписке + чатам
|
||||||
5. **Остановка** — graceful shutdown через WebSocket команду
|
|
||||||
|
|
||||||
### Запуск агентов
|
|
||||||
|
|
||||||
**Локально (MVP):**
|
|
||||||
```bash
|
|
||||||
# Tracker запускает как subprocess
|
|
||||||
python -m team_board.agent --name coder --tracker ws://localhost:8100
|
|
||||||
```
|
|
||||||
|
|
||||||
**Через systemd (production):**
|
|
||||||
```ini
|
|
||||||
[Unit]
|
|
||||||
Description=Team Board Agent: Coder
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/opt/team-board/venv/bin/python -m team_board.agent --name coder
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
```
|
|
||||||
|
|
||||||
**Удалённо (будущее):**
|
|
||||||
- SSH: `ssh remote-host 'python -m team_board.agent --tracker ws://tracker:8100'`
|
|
||||||
- Docker: `docker run team-board-agent --tracker ws://tracker:8100`
|
|
||||||
- HTTP API на удалённом хосте
|
|
||||||
|
|
||||||
### Heartbeat и мониторинг
|
|
||||||
|
|
||||||
```
|
|
||||||
Агент → Tracker: agent.heartbeat (каждые 30 сек)
|
|
||||||
{
|
|
||||||
status: "idle" | "busy",
|
|
||||||
current_tasks: [...],
|
|
||||||
uptime: 3600,
|
|
||||||
memory_mb: 150
|
|
||||||
}
|
|
||||||
|
|
||||||
Если heartbeat не пришёл 90 секунд → статус = dead → перезапуск
|
|
||||||
```
|
|
||||||
|
|
||||||
### Таблица БД
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Расширение таблицы agents
|
|
||||||
ALTER TABLE agents ADD COLUMN host TEXT DEFAULT 'localhost';
|
|
||||||
ALTER TABLE agents ADD COLUMN pid INT;
|
|
||||||
ALTER TABLE agents ADD COLUMN last_heartbeat TIMESTAMPTZ;
|
|
||||||
ALTER TABLE agents ADD COLUMN restart_count INT DEFAULT 0;
|
|
||||||
ALTER TABLE agents ADD COLUMN max_restarts INT DEFAULT 3;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Открытые вопросы
|
## Открытые вопросы
|
||||||
|
|
||||||
1. Как интегрировать CLI-агентов (Claude Code, Cline)?
|
1. Workspace для агентов — общий или изолированный?
|
||||||
2. Workspace для агентов — общий или изолированный?
|
2. Прогресс работы агента в реалтайме?
|
||||||
3. Прогресс работы агента в реалтайме?
|
3. Биллинг/учёт использования API?
|
||||||
4. Биллинг/учёт использования API?
|
|
||||||
5. Шаблоны агентов — как быстро создать нового?
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Приоритеты реализации
|
## Приоритеты реализации
|
||||||
|
|
||||||
1. [ ] Tracker: базовый WebSocket сервер
|
### Сделано ✅
|
||||||
2. [ ] Tracker: проекты, задачи, подзадачи
|
1. [x] Tracker: REST API (проекты, задачи, агенты, лейблы)
|
||||||
3. [ ] Tracker: зависимости задач
|
2. [x] Tracker: базовый WebSocket (connection manager, heartbeat)
|
||||||
4. [ ] Tracker: чаты (лобби + проект)
|
3. [x] Tracker: Docker Compose (postgres + redis + tracker)
|
||||||
5. [ ] Tracker: файлы в задачах
|
4. [x] Web Client: канбан-доска с drag-and-drop
|
||||||
6. [ ] Web Client: авторизация (Authentik)
|
5. [x] Web Client: BFF с JWT авторизацией
|
||||||
7. [ ] Web Client: канбан-доска
|
6. [x] CI/CD: Gitea Actions auto-deploy
|
||||||
8. [ ] Web Client: чат
|
|
||||||
9. [ ] Шаблон агента
|
### В работе 🔧
|
||||||
10. [ ] Подключение первого агента (OpenClaw)
|
7. [ ] Web Client: детальный вид задачи (описание, комменты, assignee)
|
||||||
|
8. [ ] Tracker: WebSocket протокол v2 (init handshake, роутинг событий)
|
||||||
|
|
||||||
|
### Следующее 📋
|
||||||
|
9. [ ] Tracker: чаты (лобби + проект + задача)
|
||||||
|
10. [ ] Tracker: файлы в задачах
|
||||||
|
11. [ ] Web Client: чат
|
||||||
|
12. [ ] Web Client: управление агентами
|
||||||
|
13. [ ] Первый агент (OpenClaw → Tracker)
|
||||||
|
14. [ ] Web Client: Authentik OAuth
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user