Forge — Mobile Dev Station
Что это
Node.js оркестратор задач с Telegram ботом и MiniApp. Запускает Claude Code для выполнения задач с PLAN-GATE, git worktree изоляцией и PR flow.
Доступ
- MiniApp: https://forge.08317.ru
- Сервис:
systemctl --user status forge - Логи:
journalctl --user -u forge -f - Код:
/home/claude/forge/
Стек
- Node.js + Fastify (порт 3000)
- Telegraf (Telegram бот)
- SQLite (better-sqlite3) —
/home/claude/forge/forge.db - React MiniApp (Vite) —
/home/claude/forge/miniapp/ - Traefik → forge.08317.ru → host.docker.internal:3000
Переменные окружения (/home/claude/forge/.env)
BOT_TOKEN=8935029336:AAHKjbC4aihtYGW2O2jji_zssylJewLxxdY
ALLOWED_TG_ID=30777924
PROJECTS_DIR=/home/claude
Статусы задач
QUEUED → PLANNING → PLAN_GATE → RUNNING → VERIFY_GATE/DONE/FAILED
↘ VERIFY_FAILED → (merge anyway / cancel)
CANCELLED, MERGED
Уровни автономии
- L2 (default) — строит план → PLAN_GATE (ждёт OK) → выполняет → VERIFY-GATE
- L4 — сразу выполняет без планирования
Git Worktree flow
- Если проект имеет git remote → создаёт ветку
forge-task-Nв/tmp/forge-worktree-N - Claude работает в worktree (не в оригинальном репо)
- После DONE — коммитит, пушит, создаёт PR
- Merge & Close — squash merge, удаляет ветку и worktree
VERIFY-GATE
После выполнения автоматически ищет и запускает тесты:
package.json scripts.test→npm testpytest.ini/pyproject.toml→pytestgo.mod→go test ./...- Нет тестов → пропускает, сразу DONE
HMAC
Validate Telegram initData для write-эндпоинтов. В браузере (без initData) — пропускает.
Файловая структура
forge/
├── bot.js # Telegraf бот + запуск server.js
├── server.js # Fastify HTTP + WebSocket
├── supervisor.js # Claude CLI runner, worktree, PR, тесты
├── db.js # SQLite schema
├── events.js # EventEmitter для WS
└── miniapp/
├── src/App.jsx
├── src/index.css
└── dist/ # собранный фронт, отдаётся Fastify
WebSocket
wss://forge.08317.ru/ws/tasks/:id — live stream событий задачи.
Важные баги которые были и исправлены
- WS path
/ws/tasksне матчил/ws/tasks/123→ regex match forge/task-Nсо слэшем ломал git refs →forge-task-N- Claude писал файлы в оригинальный репо вместо worktree → явно указывать cwd в промпте
- Кавычки в описании ломали
git commit -m "..."→ spawnSync с args[] - Cancel → FAILED (SIGTERM перезаписывал CANCELLED) → проверка статуса перед FAILED
chat_id NOT NULLпри создании через MiniApp → подставлять ‘web’- NaNд в timeAgo → SQLite формат
2026-07-01 18:01:51не парсится Date() →.replace(' ','T')+'Z'