claude-office
v1.0.1
Published
Pixel-art isometric office that shows your live Claude Code sessions and sub-agents as employees at their desks. Unofficial, not affiliated with Anthropic.
Maintainers
Readme
Claude Office
A pixel-art isometric office where your live Claude Code sessions and sub-agents show up as employees: they walk in, type, read, print, chill on the couch or smoke when idle, raise their hands when they need you, and go home when the session ends. Runs locally, reads
~/.claudeonly. Unofficial project, not affiliated with Anthropic. Support: Boostynpx claude-office
Изометрический офис в духе Game Dev Tycoon, в котором живут ваши агенты Claude Code. Комната с двумя стенами, окнами, дверью и декором (доска, постеры, книжный шкаф, картотека, кулер, растения, пуфики, принтер); столы с мониторами, клавиатурами и стульями; сотрудники с причёсками и лицами, которые:
- заходят в дверь, когда появляется сессия или субагент, и садятся за первый свободный стол (свободные столы всегда есть — офис сам растёт целыми рядами, число колонок не уменьшается, а лишний пустой ряд убирается только через 5 минут, чтобы картинка не прыгала при каждом приходе/уходе);
- за столом изображают реальную работу агента: печатают, стучат по терминалу, читают код, пишут, гуглят, планируют, думают; экран монитора горит цветом статуса, на нём бегут строки кода;
- при делегировании (
Task) встают, берут бумажку и несут её к столу коллеги; - иногда сами ходят к принтеру или кулеру;
- без работы уходят отдыхать: худи и рыжая — на диван в лаунж с приставкой, курильщики (случайная половина) — в стеклянную курилку за лаунжем;
- засыпают за столом, если работы нет (голова набок, «Zzz»); трясут руками, если ждут вашего ответа; уходят в дверь, когда сессия завершена.
Запуск одной кнопкой
Нужен только Node.js 18+ (https://nodejs.org или brew install node).
Сборки нет — клиент это обычные ES-модули, зависимость одна (ws).
- macOS, Finder: двойной клик по
Claude Office.command— при первом запуске сам поставит зависимости, поднимет сервер и откроет браузер. Закрыть окно Терминала = остановить. - Терминал:
./start.sh(то же самое;./start.sh --simulate 10— выдуманная команда из 10 агентов,./start.sh --port 5000— другой порт). - Всегда включён:
npm run service:install— регистрирует сервер как login item (launchd), он стартует при входе в систему и живёт в фоне на http://localhost:4173;npm run service:status,npm run service:uninstall. Лог:~/Library/Logs/claude-office.log. - Windows: двойной клик по
start.cmd; автозапуск при входе —scripts\service.cmd install(Планировщик заданий),status,uninstall. - npm:
npm install && npm start(илиnpx .из папки — естьbin).
Сервер сам открывает браузер (отключить: --no-open или NO_OPEN=1) и,
если порт занят, берёт следующий свободный. Если сейчас нет запущенных
сессий Claude Code, увидите демо-команду (она сама крутит состояния и
периодически «отправляет домой» одного сотрудника, чтобы показать, как офис
сжимается и растёт).
Графика
Столы, стулья, реквизит, доска, дверь, город за окнами и четыре модели
сотрудников — сгенерированные в Midjourney пиксель-арт спрайты в public/assets/ (ТЗ и промпты — в
docs/sprites-spec.md). Фон каждой картинки вырезается при загрузке по
цвету углов, листы персонажей нарезаются на кадры автоматически. Стены, пол,
рамы окон и дверной проём рисуются кодом, чтобы комната могла расти; плоские
фронтальные картинки (доска, дверь, панорама города) натягиваются на стены
аффинным сдвигом.
Если какого-то файла нет — для него остаётся процедурная отрисовка.
Каждому агенту при появлении случайно назначается модель. Направление спрайта при ходьбе берётся из вектора движения: лист «лицом» смотрит вниз-влево, «со спины» — вверх-вправо, зеркалирование даёт два остальных.
Структура
server.js — следит за ~/.claude и шлёт состояние по WebSocket
start.sh / start.cmd — запуск одной командой (ставит зависимости при первом запуске, печатает --doctor)
Claude Office.command — то же для двойного клика в Finder
scripts/service.sh — установка/удаление launchd-службы (автозапуск при входе)
public/
index.html — оболочка: шапка, canvas, боковая панель
styles.css
src/
main.js — точка входа: WebSocket, игровой цикл, клики, панель деталей
simulation.js — состояние: столы, сотрудники, приход/уход, походы, поручения
render.js — кадр: пол/стены, сортировка по глубине, подписи
scene.js — планировка комнаты и статический декор
sprites.js — как рисовать стол, монитор, стул, сотрудника, реквизит; позы
iso.js — изометрическая проекция и примитивы (тайл, бокс, стена)Отладка в консоли браузера: office.frozen = true замораживает живые
обновления, после чего можно скормить свою сцену:
office.syncEntities(office.flattenEntities({desks:[...]})).
DEV_SNAP=/tmp/snap.png npm start включает POST /__snap, куда страница
может отправить canvas как data-URL — удобно снимать сцену целиком.
SIMULATE=7 npm start — 7 выдуманных агентов, живущих своей жизнью.
Кнопка «💡 свет» в шапке (или клавиша L) выключает свет: сцена умножается на карту освещения (тёмно-синяя база + аддитивные источники: мониторы цветом статуса, торшеры в лаунже и у принтера, телевизор во время игры, принтер во время печати, табличка EXIT, отсвет из окон), поверх — свечение стекла мониторов; всё обрезается силуэтом комнаты. Отдельных «ночных» спрайтов нет. Выбор запоминается в localStorage.
Производительность: пол и стены рендерятся один раз в offscreen-слой при
смене планировки, спрайты кэшируются в предмасштабированном виде под
реальный размер на экране, размер холста ограничен ~12 МП (MAX_CANVAS_PIXELS
в render.js). Кадр рисуется не чаще 30 fps, пока кто-то идёт или едет
дверь/свет, и 12 fps в покое (main.js, frame governor); в скрытой вкладке
rAF стоит. Ночной проход держит статичные источники света в кэше и рисует
свечения готовыми тайлами. Сервер читает транскрипт только если изменились
mtime/size, флаг сайдчейна и листинг папки кэширует, а по WebSocket шлёт
состояние только при изменении (плюс heartbeat раз в 5 с).
Статусы и как они выглядят
Боковая панель показывает те же пузыри, что висят над головами (они рендерятся из того же кода), поэтому легенда и сцена не расходятся:
- работает — сидит за монитором, экран горит зелёным; пузырь говорит, что именно делает (печатает / терминал / пишет / гуглит / планирует / думает); «читает» — сидит с листом в руках.
- нет работы — спит за столом (экран тусклый, «Zzz»), либо ушёл на диван с приставкой или в курилку.
- нужен ваш ответ — руки вверх, красный пузырь «?», экран красный.
- завершено — сессия закончилась: сотрудник выходит в дверь, стол гаснет и через минуту пропадает.
Где лежат данные агентов — определяется само
При запуске сервер определяет систему и папку Claude Code, из которой
читаются сессии и транскрипты (npm run doctor или node server.js --doctor
печатает результат; лаунчеры делают это при первом запуске):
| система | где ищет (по порядку) |
|---|---|
| любая | $CLAUDE_CONFIG_DIR — если задана, Claude Code хранит всё там |
| macOS / Linux | ~/.claude, затем ~/.config/claude |
| Windows | %USERPROFILE%\.claude, %APPDATA%\claude |
| Linux под WSL | дополнительно /mnt/c/Users/<имя>/.claude (Claude Code, установленный на Windows-стороне) |
Берётся первая папка, в которой есть sessions или projects. Внутри:
sessions/<pid>.json — живые сессии, projects/<cwd-с-разделителями-→->/*.jsonl
— транскрипты (на Windows C:\Users\me\app кодируется как C--Users-me-app;
имя папки ищется и без учёта регистра/точек). Если папка нашлась не там —
CLAUDE_CONFIG_DIR=/путь ./start.sh.
--doctor также проверяет, что файлы сессий содержат sessionId/cwd и что
для каждой сессии есть папка проекта, и считает транскрипты субагентов
("isSidechain":true).
Как это работает
server.js каждую секунду читает:
~/.claude/sessions/<pid>.json— по файлу на каждую живую сессию (pid,cwd,sessionId,status,waitingFor)~/.claude/projects/<cwd-с-заменёнными-/->/<sessionId>.jsonl— транскрипт этой сессии; сервер читает только хвост файла и смотрит, какой инструмент вызвал агент последним (Bash→ терминал,Read/Grep→ чтение,Write/Edit→ правки,WebSearch/браузер-тулы → гуглит,Task→ раздаёт задачи субагентам, и т.д.) — это и становится занятием сотрудника- остальные
.jsonlв той же папке проекта — эвристический поиск сайдчейнов ("isSidechain":true) для отображения субагентов
Важное предупреждение
Формат ~/.claude/sessions/*.json и ~/.claude/projects/**/*.jsonl
нигде официально не задокументирован как публичный API — Anthropic может
поменять его в любой момент. Сервер читает поля защищённо (ничего не падает,
если что-то не найдено), но если после обновления Claude Code офис вдруг
опустеет или разучится показывать активность — значит, формат изменился и
парсинг в server.js (readRealOffice / lastActivity / readSubagents)
нужно поправить под новую структуру. Проверить реальный формат проще всего
так:
cat ~/.claude/sessions/*.json
find ~/.claude/projects -name "*.jsonl" | head -1 | xargs tail -5Настройка
- Порт:
PORT=5000 npm startили./start.sh --port 5000 - Стол считается «рабочим», если файл менялся последние 15 секунд —
ACTIVE_MSвserver.js. - Стол пропадает, если файл не менялся 10 минут (
STALE_MS). - Планировка комнаты (ширина, шаг между рядами столов, где стоит декор) —
константы в начале
public/src/scene.js.
Поддержать
Проект бесплатный и открытый. Если офис вам пригодился — можно угостить автора кофе: boosty.to/remirovich/donate.
Made by @remirovich
