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

  1. Если проект имеет git remote → создаёт ветку forge-task-N в /tmp/forge-worktree-N
  2. Claude работает в worktree (не в оригинальном репо)
  3. После DONE — коммитит, пушит, создаёт PR
  4. Merge & Close — squash merge, удаляет ветку и worktree

VERIFY-GATE

После выполнения автоматически ищет и запускает тесты:

  • package.json scripts.testnpm test
  • pytest.ini / pyproject.tomlpytest
  • go.modgo 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'