AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
Cubicle: Paperclip, Claude Code 등 AI 에이전트 작업 실시간 관찰
Watch Paperclip, Claude Code, Codex or Gemini CLI agents work in a live office: desks, raised hands, errors, a KPI board and Telegram alerts. Open source, zero dependencies.
개발 도구JavaScript · HTMLGitHub @caglarutkuguler온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Cubicle: a live pixel-art office for your AI agents (Paperclip, Claude Code, Codex, Gemini CLI). See who works, who needs you, who failed; KPI board, Telegram alerts, HD themes. Zero dependencies, read-only.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A live pixel-art office for your AI agents. Works with Paperclip, Claude Code, or any tool that can write a small JSON file.
Your agents get a desk. When one starts working it walks over, sits down and starts typing, with its current task floating above its head. When it needs you, it raises a hand. When it finishes it goes back to the lounge for a coffee. If it hits an error, its screen flashes red.README 전문 보기 ↗A live pixel-art office for your AI agents. Works with Paperclip, Claude Code, or any tool that can write a small JSON file.
Your agents get a desk. When one starts working it walks over, sits down and starts typing, with its current task floating above its head. When it needs you, it raises a hand. When it finishes it goes back to the lounge for a coffee. If it hits an error, its screen flashes red.
GET requests, and only to a short allowlist. It cannot change anything in your agent system.npx, a clone, a systemd unit, or a browser tab pointed at the hosted demo.?lang=xx; words on the walls of the HD themes follow it.Requires Node.js 18+.
Paperclip (default; expects Paperclip at http://127.0.0.1:3100):
npx @caglarutkuguler/cubicle
Inside Paperclip — as a plugin, with its own menu entry and no separate server:
npx paperclipai plugin install @caglarutkuguler/cubicle
Open Cubicle in Paperclip's sidebar. Details in Inside Paperclip.
Claude Code, as a Claude plugin (easiest; in a terminal or the Claude desktop app's Code tab):
/plugin marketplace add caglarutkuguler/cubicle
/plugin install cubicle@cubicle
/cubicle
No terminal? In the Claude desktop app's Code tab, ask Claude: Install the Cubicle plugin from caglarutkuguler/cubicle, and click Allow when it asks to run the command. Then start a new session and say Open Cubicle. Node.js 18 or newer is needed.
The plugin brings the hooks (every session, subagent and background task becomes a character) and a /cubicle skill that starts the office if it is not running, gives you its address and changes its settings when you ask: turn on autostart starts Cubicle by itself whenever a Claude session starts, kept up to date with --auto-update. Each release also carries the plugin as cubicle.plugin. Details in plugin/.
Claude Code, by hand (one character per session, driven by Claude Code's own hooks; details in examples/claude-code/):
npx @caglarutkuguler/cubicle install-hooks # once; backs up ~/.claude/settings.json first
npx @caglarutkuguler/cubicle --source claude-code
Each session is named after its folder. When the editor is open on one project but the session edits files in (or cds into) a sibling one, as with a portfolio of modules or packages under one folder, the card takes that project's name instead: the nearest folder with .git, package.json, composer.json, config.xml or a <folder>.php, else the first folder below the one they share. A window opened on the folder that holds the projects (one with no project file of its own, not home) is named after the project inside it being worked on. Reading another project, temporary folders and the home folder do not count, and work back in its own folder brings the name back. No Paperclip needed. Scripts that run Claude Code unattended (cron, CI, issue bots) can name their character and link it to a ticket with CUBICLE_NAME, CUBICLE_TASK_URL and CUBICLE_LINGER; see Headless workers.
Both in one office — Paperclip agents on the first rows, Claude Code sessions after them:
npx @caglarutkuguler/cubicle --source paperclip,claude-code
Anything else — a JSON file or URL in the feed format:
npx @caglarutkuguler/cubicle --source ./agents.json
npx @caglarutkuguler/cubicle --source http://localhost:8080/agents
Then open http://127.0.0.1:3200. Nothing running yet? Open http://127.0.0.1:3200/?demo, or the hosted demo.
Or from a clone:
git clone https://github.com/caglarutkuguler/cubicle.git
cd cubicle
node bin/cubicle.js # add --source … as above
| Flag | Environment variable | Default |
|---|---|---|
--port | CUBICLE_PORT | 3200 |
--host | CUBICLE_HOST | 127.0.0.1 |
--source | CUBICLE_SOURCE | paperclip — or claude-code, codex, gemini, replay:FILE.jsonl, a .json file, an http(s):// URL, or several of these comma-separated |
--paperclip | PAPERCLIP_URL | http://127.0.0.1:3100 |
--token-file | PAPERCLIP_TOKEN / PAPERCLIP_TOKEN_FILE | none — API key for an authenticated Paperclip |
--redact | CUBICLE_REDACT=1 | off — strip task titles, commands and error text on the server; the office shows only ids, tool names and statuses |
--record FILE.jsonl | off — append everything the office shows to a file, only when it changes | |
--appearance FILE | CUBICLE_APPEARANCE | ~/.cubicle/appearance.json — where agent looks, photo heads and the logo are saved |
--speed N | CUBICLE_SPEED | 60 — replay speed for --source replay:FILE.jsonl (60 = an hour a minute) |
URL parameters:
?company=PREFIX opens a specific Paperclip company (for example ?company=MEG). With several companies, a picker also appears in the header.?layout=auto (default), side or stack: auto makes the whole office as large as fits both the page's width and the window's height, with the cards below it; side fits the office to the window's height and puts the cards beside it; stack is the classic narrower page. Also in the ⚙ menu. A big office on a wide screen grows sideways, adding desk wings instead of rows, so it keeps the window's shape.?demo=20 shows a bigger demo office (up to 48 agents).?lang=en, tr, de, es, fr, zh or ar sets the language (the ⚙ menu's Language does the same and is remembered per browser).?demo shows fake agents.?theme=military&branch=land picks a theme and its options (listed in public/themes/index.json). The same choices are in the ⚙ menu, which remembers them per browser and copies a link that carries them, so a kiosk always opens the same way.?kiosk fills the screen with the office for a TV or a second monitor (run the server with --redact if that screen is shared): cards and footer hidden, names and bubbles scale with the screen, cursor hidden. Combined with the auto-updater, a wall display picks up new versions by itself.| Status | In the office |
|---|---|
running | Sits at its desk, monitor on, typing; bubble shows the task |
waiting | Sits at its desk with a hand up, amber screen — it needs your input or approval. With Paperclip this comes from issues whose review is waiting on the board (for example pending ask-user questions); a busy agent keeps typing but its bubble flashes the issue id, and the header counts how many need you |
idle | Wanders the lounge; says "✓ done" right after finishing a run |
error | Slumped at its desk, red screen, error text on its card |
paused | "zZ" |
| Theme | What you get |
|---|---|
pixel (default) | The classic 16-px pixel-art office |
holding | Walnut-panelled headquarters with the company name on the wall, a boardroom and a city or sea view; suits, skirts and heels |
plaza | A high floor of a glass tower: window wall with a skyline or sea view, white desks, a coffee bar and sofa in the lounge; smart casual, some in skirts and heels |
warehouse | Loading-bay doors, a conveyor that runs faster the more agents work, pallet racks and a forklift; hi-vis vests and hard hats |
factory | A production line (car bodies with robot arms, or bottling) that runs while agents work, an andon tower that shows the office state, coveralls |
space | A base in orbit or on Mars: viewports, holographic consoles, mission clock, a hydroponics garden; mission jumpsuits |
military | HD operations room drawn at 4× resolution. Land: olive walls, tactical map with a marker per working agent. Air: hangar windows with a passing jet, radar scope, runway safety line. Naval: riveted steel deck, portholes, sonar. Joint: video wall with all three plus local and UTC clocks, and every agent in the uniform of one service. Rank follows the agent's role (a star for CEO/lead/director, chevrons otherwise); a red beacon turns on while any agent is in error. |
Themes change only how the office is drawn; movement, bubbles, cards and the data the server sends are the same for every theme. A theme is one file in public/themes/ plus a line in index.json, loaded only when chosen; a shared kit draws people, desks, windows and furniture, so a new room is mostly a palette and an outfit. How to write one: docs/THEMES.md.
Each card below the office links to the agent's current task when the source provides a link (Paperclip issues do), and shows the agent's spend this month when Paperclip reports one (amber from 80 % of the budget, red at 100 %).
When a Paperclip issue moves from one agent to another, both walk to the lounge table for a few seconds and the one handing over says which issue it passes on.
--redact, only the code). Issue ids open in the same dialog over the office.qa-agent-2); the card shows the original next to it, and Paperclip keeps its own. Inside Paperclip, a link opens the agent's page to rename it there for real.📊 KPI in the header opens a board of the tasks a person created in Paperclip (not the ones agents open for each other):
how many are open, their average progress, how many were finished in the last 7 days (with a 14-day bar chart), the usual time a task takes here, and how many are blocked;
for each task: who has it, its progress and when it should be done. Progress comes from its subtasks (a task an agent split into five subtasks, three done, is about 60%), or from its status when it has none. The expected time follows the pace so far, or, without subtasks, the usual time a task takes in this company; a task past that time says so.
when each task started and how long it took, or how long it has been running so far (long ones stand out);
▸ opens a task into its subtasks, and each subtask into its own, as a tree with the same columns.
An agent working at its desk shows its task code and when the task should be done (⏱), and the same on its card; hovering the code shows the task's name. The time comes from the task's subtasks (the pace so far) or from how long this agent's finished tasks took.
💡 Speed-up advice. The bulb next to an open task reads that task's tree, Paperclip's last thousand runs and its cost summary, and lists what is measurably slowing it down, most pressing first: tasks waiting for your answer or approval, failed runs grouped by cause (the AI provider's usage limit, prompts too large for the system (E2BIG), turns that broke off, lost processes), blockers that have themselves stopped, open work nobody is on or nothing has happened to for a day, one agent holding the queue while others are free, subtasks open far longer than similar ones, tasks with many runs that are still open, and a queue in review. Each line names the tasks it is about and what to do.
Turning advice into a task. With Let Cubicle create these tasks in Paperclip switched on (under the advice; off by default, and switched on only from the computer Cubicle runs on), each piece of advice, or all of it together, can be made into a subtask of the slow task in Paperclip: you pick the agent and priority and can edit the title and text first. It is the second thing Cubicle can write to Paperclip, after Telegram replies, and only when you ask for it. Advice already made into a task shows that task instead of the button while it is open; once the task is done its result (the task's last comment) is shown, and if the problem still shows in the data it can be made into a task again. Advice tasks whose problem no longer shows are listed under Earlier advice with their result.
It reads the issues Paperclip already has (every page of them, so a company with more than a thousand issues is counted in full); ?kpi in a link opens the board directly.
Without Paperclip. When Cubicle does not read Paperclip and the CEO task box is on, the board shows the tasks you gave the CEO instead, kept in ~/.cubicle/kpi.json: each task, and under it the GitHub issues its run opened, with their state from gh (queued, a worker on it, a PR in review, waiting for you, closed). A task is done when its issues are closed. Paperclip's tasks can be copied in once, so the history stays: npx @caglarutkuguler/cubicle kpi-import (Paperclip running at http://127.0.0.1:3100, or give its address).
⚙ Your desk (?human=1) puts you in the office, at the first desk. An agent that needs you no longer raises its hand at its own desk: it walks over and joins the line in front of yours, so the length of the line is how much is waiting for you. Click yourself to open the first one in line, or, when nobody is waiting, to change your own look (a photo works too).
Every card has a ✎ button. It opens the appearance dialog for that agent:
Pets (optional, off by default). ⚙ → Pets adds a cat 🐈, a dog 🐕, a rabbit 🐇 and/or a robot vacuum 🤖 to the office, one of each you pick, in every theme. They walk around the desks like the agents do and keep to their habits: the cat naps (more at night) or sits by someone who is working, the dog goes and sits by an agent who needs you or trots after one who walks by, the rabbit hops about and nibbles, the robot vacuum cleans its rounds and stops to charge. Click one to say hello. The choice is kept per browser; ?pets=cat,dog sets it in a link (a kiosk or TV link, or Copy link in the ⚙ menu).
The ⚙ menu uploads a company logo, which each theme hangs where its wall has room, and exports or imports all of it as one file.
Where it is kept: with the standalone server, in ~/.cubicle/appearance.json on the machine running Cubicle, so every screen of the office (a TV, a laptop) shows the same faces. Only a browser on that machine can change it. Inside Paperclip, in the browser. Photos are resized to 160 px and never sent anywhere else; ask people before putting their face on a shared screen.
The ⚙ menu also has:
?voice=wait,start,done,err,chat (or ?voice=all) sets it in a kiosk link. Some browsers speak only after one click on the page.?fps=15 sets it in a kiosk link. Drawing an HD office takes about 1.3 to 2.2 ms of script per frame on a laptop; hidden tabs draw nothing.The standalone server can run a Telegram bot for your office. It tells you when an agent starts needing you, a run fails or work completes, with a link that opens Cubicle on that agent and one to the issue in Paperclip when available, and it answers /status, /waiting, /kpi and /office. A finished message says what was done: the task with its link, how long the run took, what it said last (its summary or answer), the main task it is part of and how far that has come (e.g. 1 of 3 pieces done, 1 working, 1 queued), and who else is working or waiting.
Setting it up takes three steps, all on the page (⚙ → 📨 Telegram…, on the computer Cubicle runs on):
bot. BotFather sends you a token, a long line like 123456789:AAH….~/.cubicle/telegram-settings.json (readable only by you) and starts the bot right away./start 123456, works too. That chat is now linked; the page shows it. Only linked chats get messages or answers. The code stays the same across restarts.Choose who can use the bot. In ⚙ → 📨 Telegram…, Allow everyone is checked by default: anyone with the pairing code can link a chat, just as before. Uncheck it to add or remove people by their numeric Telegram user ID (not their @username). Previously linked private chats are also available to add. Only listed users can pair, use commands or receive notifications, and only in private chats; groups are blocked in this mode. An empty list blocks everyone. Changes apply immediately and survive restarts, including when the bot token comes from the environment. Checking Allow everyone again keeps the list for later. These settings can only be managed from the computer running Cubicle.
On your phone. Links in the messages open on the computer Cubicle runs on until it has an address your phone can reach. Step 5 of the dialog sets that up with Tailscale (free), which keeps the office private to your own devices:
tailscale serve --bg --http 3200 http://127.0.0.1:3200 once, and from then on the links use http://<computer>.<tailnet>.ts.net:3200. The dialog shows the address and a QR code to try it.Cubicle stays bound to 127.0.0.1. Requests that come through such a proxy are never treated as "this machine": the phone sees the office, not the settings or the pairing code. While Paperclip runs on 127.0.0.1 only, it cannot open on the phone: messages and the office page there leave out the Paperclip links and buttons (instead of opening blank pages), and you answer by replying in Telegram. To open Paperclip on the phone too, it must accept the Tailscale name (npx paperclipai allowed-hostname <computer>.<tailnet>.ts.net) and be served the same way; Cubicle then takes its address from --paperclip-public-url. In Paperclip's default local_trusted mode anyone who can reach it acts as the board, so do this only on a tailnet with your own devices. --public-url sets the address from the command line instead. For a server without a browser, the token can also come from the environment: CUBICLE_TELEGRAM_TOKEN=…; Cubicle then prints a /start 123456 line to send to the bot.
Turn notifications off and on. ⚙ → 🛠 Cubicle settings → Telegram → Send notifications to Telegram (telegram.notify: false in ~/.cubicle/settings.json) stops everything the bot sends by itself: agents waiting for you, failures, completed work, decisions from the task box and GitHub, new versions. The linked chats get one message saying so, and another when it is turned back on; nothing missed meanwhile is replayed (/waiting shows who is waiting). The bot keeps answering commands, and /status says notifications are off.
Choose what reaches you. /mute WebDev stops alerts for one agent (/unmute WebDev brings them back, /mute lists who is muted); /alerts questions sends only agents that need you, /alerts failures only failed runs and errors, /alerts all includes both plus completed work (or just /questions, /errors, /all). Each linked chat keeps its own choice; new chats default to all alerts.
Completed work. Successful Paperclip runs and new feed completedAt timestamps produce one completion alert. Feeds without that field use an observed running-to-idle transition. Existing completions are not announced at startup, and changing a chat's filter or unmuting an agent does not replay completions it skipped. Completion alerts follow the same per-chat filters, muted agents and access restrictions as other alerts.
One at a time. With replies on, agents waiting for you come one by one: only the first is sent, and each of its questions arrives as its own message. Just write your answer (the option's number or your own words); when the issue's last question is answered, all answers go to Paperclip as one comment and the next agent comes. /skip moves on, /waiting lines up everyone waiting now. The queue survives restarts, and something answered in Paperclip meanwhile drops out of it.
Questions in the message. When the agent asks questions, the message carries them with numbered options; reply with a number to pick that option, or write your own answer. An approval the agent asks for comes with its summary, its risks and a link to approve or reject it in Paperclip.
Answering from Telegram. With the last switch in the dialog (or --telegram-replies), replying to a "needs you" message (or /answer MEG-12 your text) posts your text as a comment on that Paperclip issue, with the Paperclip key or as the board in Paperclip's local mode. It is the one thing Cubicle can write to Paperclip, and it is off unless you turn it on. For full conversations and Paperclip's own question forms on Telegram, Paperclip has a Telegram connection of its own (Connectors → Chat); give it a separate bot, because a bot's messages can be read by one program only.
Paperclip. Cubicle proxies a few read-only endpoints (/api/health, /api/companies, /api/companies/:id/agents|issues|heartbeat-runs; for runs only the latest 60, and only their status, error code, error text and the end of stderr) and maps Paperclip's agent status and open issues onto the office. Any adapter Paperclip supports — Claude Code, Codex, Cursor, HTTP agents — shows up, because the status comes from Paperclip itself.
The default local_trusted mode needs no key. For an authenticated or remote Paperclip, give Cubicle an API key; it is sent as Authorization: Bearer … on the forwarded requests only:
PAPERCLIP_URL=https://paperclip.example.com PAPERCLIP_TOKEN=pcp_… npx @caglarutkuguler/cubicle
# or keep it in a file only you can read
npx @caglarutkuguler/cubicle --paperclip https://paperclip.example.com --token-file ~/.config/cubicle/paperclip-token
Use a board API key with the narrowest read-only scope Paperclip lets you create; an agent key also works but only sees that agent's company. There is no --token flag on purpose, because command-line flags are visible in the process list. With systemd, put PAPERCLIP_TOKEN=… in a chmod 600 file and point EnvironmentFile= at it (see examples/systemd/cubicle.service).
Claude Code. A hook script (bin/cubicle-hook.js) runs on Claude Code's own hook events and rewrites ~/.cubicle/claude-code.json. Tool calls put the character at its desk, permission prompts raise its hand, Stop sends it to the lounge. Subagents started with the Agent (Task) tool get their own character next to the session (thanks @omeruyanik03). Setup and privacy notes: examples/claude-code/README.md.
Codex CLI and Gemini CLI. The same hook, installed with install-hooks codex or install-hooks gemini, writes ~/.cubicle/codex.json or ~/.cubicle/gemini.json; read them with --source codex or --source gemini. Codex uses Claude Code's hook events (trust them once with /hooks in Codex); Gemini's are mapped onto them. Both were checked end to end with the real CLIs (Codex 0.159, Gemini CLI 0.61). See examples/codex/ and examples/gemini/.
GitHub Copilot. examples/github-copilot/ includes a read-only Desktop session exporter (github-copilot-desktop.json) and a terminal CLI hook (github-copilot.json). Both write under ~/.cubicle/, one character per local session. Point --source at the appropriate file, or include its full path alongside other sources. Existing offices must also add that source to their running service or feed collector. See the example README for setup and limitations.
Replay. --record day.jsonl saves what the office shows whenever it changes. --source replay:day.jsonl --speed 60 plays it back an hour a minute, looping, with the replayed time in the header: a whole working day in a few minutes, for a demo or a wall screen.
Codex Desktop and existing CLI sessions. The optional session-file observer exports local JSONL histories without installing hooks. It labels Desktop and CLI separately; see its README for the limits of inferring status from logs.
Several at once. --source paperclip,claude-code,./other.json puts every source in the same office. Each source keeps its own block of desks, so agents don't shuffle when a session starts or ends, and if one source goes down the others keep showing while the header names the one that is unreachable.
Grok CLI. A passive hook example handles Grok's event fields, cancellations and
permission notifications. Setup and limitations: examples/grok/.
Feed. Any process can write { "company": "…", "agents": [{ "id", "name", "role", "status", "task", "error" }] } to a file or serve it over HTTP. Full spec with status aliases: docs/FEED.md. A sample is in examples/feed.json.
Antigravity Desktop and CLI (agy). A passive hook example writes a shared local feed, labels Desktop and CLI conversations separately, and tracks invocation, stop, failure and background-work events. See its README for setup, privacy and permission-detection limits.
The same npm package is also a Paperclip plugin. Install it once and every company gets a Cubicle entry in the sidebar:
npx paperclipai plugin install @caglarutkuguler/cubicle
GET requests. The plugin asks Paperclip for three capabilities, all UI only (ui.sidebar.register, ui.page.register, ui.dashboardWidget.register); its worker answers Paperclip's lifecycle calls and nothing else.local_trusted mode): curl -X POST http://127.0.0.1:3100/api/plugins/caglarutkuguler.cubicle/upgrade. When a version asks for a new capability (0.11 adds the dashboard widget), Paperclip refuses the upgrade; install it again instead, which keeps the plugin's id and your kiosk links: npx paperclipai plugin uninstall caglarutkuguler.cubicle && npx paperclipai plugin install @caglarutkuguler/cubicle. Remove with npx paperclipai plugin uninstall caglarutkuguler.cubicle.npx paperclipai plugin install /path/to/your/cubicle/clone installs from a checkout.Differences from the standalone server: --redact and the proxy's field filtering don't apply (the page talks to Paperclip directly, as the signed-in user, who can already see everything it shows), and Claude Code sessions or feeds are not mixed in; run the standalone server for those.
Cubicle is one of several pixel offices for AI agents, all inspired by Pixel Agents. They optimise for different things:
| Cubicle | Pixel Agents | Agent Pixels | agents-in-the-office | |
|---|---|---|---|---|
| Works with | Paperclip, Claude Code, Codex CLI, Gemini CLI, any JSON feed | Claude Code | Paperclip | Claude Code, Gemini CLI |
| Runs as | Paperclip plugin, or standalone page (npx, systemd, kiosk) | VS Code extension or npx browser app | Paperclip plugin | Standalone app |
| Setup | One command, nothing to build (also as a plugin) | Marketplace install; build from source to hack on it | Build against the Paperclip plugin SDK | See its README |
| Access to your agents | Read-only by design (GET allowlist) | Watches local Claude Code sessions | Inside Paperclip | Watches local sessions |
| Shows "needs you" | Yes: permission prompts, board questions | Yes: waiting for approval | Not listed | Yes: approval alerts |
| Office editor, art | Fixed room, programmer art | Layout editor, furniture and character assets, pets | 80+ characters, multi-room views | Tile map editor, sound packs |
Pick Cubicle if you want something you can trust to run next to production agents (it can only read), that starts in seconds with no build, or that shows Paperclip and Claude Code in one place. Pick another one if you want to design your office, richer art, or tighter editor integration.
npx @caglarutkuguler/cubicle@latest, npm install -g @caglarutkuguler/cubicle@latest, or git pull for a clone), and a linked Telegram chat gets one message per version. After an update the page and Telegram say so once. The request is a plain GET of the package's version from registry.npmjs.org, carrying nothing about your office; --no-update-check (or CUBICLE_UPDATE_CHECK=0) turns it off.git pull in a clone, npm install -g for a global install, or npx otherwise), lets go of its port and starts again on it, and the page reloads. Run as a service (systemd, launchd), it steps aside and the service starts the new version. From Telegram, send /update. If it cannot update from here, it shows the command instead.--auto-update (e.g. npx @caglarutkuguler/cubicle --auto-update): Cubicle then runs under a small supervisor that, when a new version is out, starts it (through npx, or after a fast-forward git pull in a clone) in place of the old one; open pages reload themselves. If the new version cannot start, it goes back to the one that ran before. A clone with local edits is left alone.npx paperclipai plugin upgrade caglarutkuguler.cubicle.⚙ → 🛠 Cubicle settings, on the computer Cubicle runs on, changes ~/.cubicle/settings.json (or CUBICLE_SETTINGS): the language of alerts and messages, starting Cubicle with every Claude session (autostart, with the port and sources it starts on), the Paperclip links, agents and advice tasks, and the CEO task box (dispatch: folder, model, budget, allowed tools, instructions). With the task box on, the CEO is also the first responder: an agent that stops with an error is handed to it with the error, its task and last steps; it retries, relaunches or fixes the work, and only when it cannot does it ask you (a decision on the page and in Telegram, whose failure message says the CEO is on it). Each failure goes to it once, at most twice per agent in 6 hours and 6 times an hour; the CEO's own failures come to you. Turn it off with When an agent fails, the CEO tries to fix it first (dispatch.fixFailures: false). It also shows what this Cubicle runs with: version, address, sources and how it updates. Changes apply at once; autostart applies from the next Claude session. The address, the sources it watches now and the update mode come from its command line or service. Telegram notifications are switched off and on here (Send notifications to Telegram, telegram.notify); setting up the bot has its own dialog (⚙ → 📨 Telegram…); looks, theme, layout, language and sounds are per browser in the ⚙ menu.
If your agents work from GitHub issues labelled agent:ready, agent:working, agent:review, agent:blocked-human and agent:failed (as the worker scripts in ~/agents do), Cubicle reads them with the gh CLI signed in on this computer, from the repos in ⚙ → 🛠 Cubicle settings → GitHub (github.repos, or by default those in ~/agents/repos.conf). The header shows 📥 n: the work that waits for you (a decision, a failure, a PR to review); when no agent is working while work waits for you it turns into 💤 n waiting for you, and Telegram says so too, at most every 4 hours. A click lists everything, grouped, with links to the issues and PRs and their CI. Telegram also tells you when an issue becomes blocked on you or fails.
With The CEO reviews PRs whose CI passed and merges them (github.autoMerge, needs the task box), each PR in review goes to the CEO once per commit: a green one to review (with the code- and security-review subagents) and merge, a red or conflicting one to send back to a worker with what to fix. Anything risky or unclear comes to you as a decision; a PR without CI stays with you.
A decision waiting on GitHub (agent:blocked-human) need not send you to GitHub: with the task box on, the CEO reads the issue and prepares it (what it is about, what to do step by step, with any command in a code block, its recommendation, and the question with its options). In the 📥 list the item gets ✋ Decide, which opens it in Cubicle; your answer goes back to the CEO, which carries it out on GitHub (github.briefs: false turns this off).
systemd user units are in examples/systemd/: cubicle.service (Paperclip, port 3200), cubicle-claude.service (Claude Code, port 3201), and an optional updater.
git clone https://github.com/caglarutkuguler/cubicle.git ~/cubicle
mkdir -p ~/.config/systemd/user
cp ~/cubicle/examples/systemd/*.service ~/cubicle/examples/systemd/*.timer ~/.config/systemd/user/
# edit ExecStart in cubicle*.service to point at your node binary (`command -v node`)
systemctl --user daemon-reload
systemctl --user enable --now cubicle.service cubicle-claude.service
Stay up to date automatically. cubicle-update.timer fast-forwards the clone every 10 minutes and restarts the running Cubicle services when something changed; open browser tabs reload themselves within a minute. It never touches a clone with local edits.
# link instead of copying, so updates to these two units arrive with the clone
systemctl --user link ~/cubicle/examples/systemd/cubicle-update.service ~/cubicle/examples/systemd/cubicle-update.timer
systemctl --user enable --now cubicle-update.timer
journalctl --user -u cubicle-update.service # what it did
For automatic startup at macOS login, see the LaunchAgent example.
127.0.0.1 by default. Keep it that way unless you put it behind your own authentication, because anyone who can reach it can see your agent names, statuses and task titles.--telegram-replies, a reply from a linked chat becomes a comment on a Paperclip issue, only when asked for.~/.cubicle/settings.json). Then POST /api/cubicle/tasks creates one subtask under an existing issue, for an agent of the same company, and nothing else; it takes JSON with the Cubicle header and no foreign Origin only, and is refused with --redact. These two (Telegram replies and advice tasks) are the only writes to Paperclip Cubicle can make.GET and HEAD are accepted, with one more exception: PUT /api/appearance saves the office's own appearance file (looks, photo heads, logo). It is accepted only from the machine Cubicle runs on, only as JSON with a Cubicle header and no foreign Origin, so another website or another computer on the network cannot change it. Everything else gets 405; nothing ever writes to your agent system. The ✋ Answer dialog is Paperclip's own issue page in a frame, loaded with your own Paperclip sign-in: an answer written there is sent by Paperclip's page, exactly as in a separate tab, never by Cubicle or its proxy. In Paperclip mode only the endpoints above are forwarded and any other /api/ path gets 403. In feed mode the only upstream request is a GET to the configured file or URL.--redact, task titles, commands, error text and stderr are dropped too, so a kiosk on a shared screen (or anyone who can reach its port) sees issue ids, tool names and statuses only.Authorization header are never forwarded upstream. If you bind to anything other than loopback while a key is set, Cubicle prints a warning at startup: everyone who can reach the port can read what the key can read.GET to registry.npmjs.org for Cubicle's latest version (off with --no-update-check). As a Paperclip plugin, ⬆ Update now calls Paperclip's plugin upgrade, only when clicked and only for an instance admin.bin/cubicle.js serves public/index.html and either proxies the allowed Paperclip endpoints or serves the feed at /api/feed. The page polls every 4 seconds and draws everything, including characters, furniture and the day/night windows, on a canvas 22 tiles wide (352 office pixels, taller when there are more agents) with plain shapes. HD themes draw the same office on a canvas 4× larger.
Issues and pull requests are welcome; see CONTRIBUTING.md for the few ground rules (zero dependencies, read-only). Look for issues labelled good first issue. Ideas: new themes (one file each; see docs/THEMES.md), more UI languages, adapters for other agent runtimes (write a feed, send a PR with an example), optional sound cues, a company logo on the wall, and per-agent appearance.
Versions are published to npm by .github/workflows/release.yml with npm trusted publishing, so no npm token exists anywhere and every version carries a provenance attestation.
npm version patch # or minor / major: bumps package.json, commits, tags vX.Y.Z
node scripts/sync-plugin.js # the Claude plugin gets the same hook and version (the tests check it)
git push --follow-tags # CI tests, publishes to npm, creates the GitHub release with cubicle.plugin
Inspired by the idea behind Pixel Agents by Pablo De Lucca. Cubicle is an independent implementation and uses no code or assets from it.
Cubicle is a community project and is not affiliated with or endorsed by Paperclip Labs or Anthropic.
▶ Canlı demoyu deneyin: kurulum gerekmez, tarayıcıda sahte ajanlarla çalışır.
Cubicle, AI ajanlarınızı canlı bir pixel ofiste gösterir: Paperclip ve Claude Code hazır gelir; başka sistemler küçük bir JSON feed ile bağlanır. Çalışan ajan masasına oturup yazar ve başının üstünde görevi görünür; sizi bekleyen ajan elini kaldırır; işi biten ajan dinlenme alanına döner; hata alan ajanın ekranı kırmızı yanar.
Paperclip içinde eklenti olarak: npx paperclipai plugin install @caglarutkuguler/cubicle komutundan sonra Paperclip menüsünde Cubicle sayfası açılır; ayrı bir sunucu gerekmez. Bağımsız kurulum: npx @caglarutkuguler/cubicle (Paperclip) veya npx @caglarutkuguler/cubicle --source claude-code (Claude Code) çalıştırın ve http://127.0.0.1:3200 adresini açın. Kurmadan denemek için: canlı demo. Ofis varsayılan olarak hem sayfa genişliğine hem pencere yüksekliğine sığacak en büyük boyutta görünür, kartlar altında durur (⚙ menüsünde Yerleşim: otomatik, yan yana ya da kartlar altta); çok ajanlı ofis geniş ekranda yana doğru büyür, sıra eklemek yerine yeni masa kanatları açar. Arayüz tarayıcı diline göre Türkçe açılır; dil ⚙ menüsündeki Dil seçeneğinden ya da ?lang=tr ile değiştirilir, HD temalardaki duvar yazıları da bu dile uyar. ⚙ menüsünden klasik piksel ofis ya da HD temalar seçilebilir: holding, plaza ofisi, depo, fabrika, uzay üssü ve askerî (Kara, Hava, Deniz veya Müşterek Kuvvetler); aynı seçim ?theme=military&branch=land gibi bir linkle de yapılır. Her ajan kartındaki ✎ düğmesiyle ajana bir fotoğraftan kesilen gerçek bir yüz, saç modeli, etek ya da topuklu ayakkabı verilebilir; ⚙ menüsünden şirket logosu yüklenir, bir ajan sizi beklediğinde masaüstü bildirimi ve ses açılabilir, ofisin 30 saniyelik videosu kaydedilebilir. Claude Code için en kolay kurulum Claude eklentisi: Claude Code'da (terminal ya da Claude masaüstü uygulamasının Code sekmesi) /plugin marketplace add caglarutkuguler/cubicle, ardından /plugin install cubicle@cubicle yazılır (terminal kullanmadan: Code sekmesinde Claude'a caglarutkuguler/cubicle adresindeki Cubicle eklentisini kur deyip komuta izin verin, yeni bir oturumda Cubicle'ı aç deyin; Node.js 18+ gerekir); /cubicle ofisi açar, çalışmıyorsa başlatır, istenirse her Claude oturumunda kendiliğinden başlamasını (autostart) açar. Yeni sürüm çıkınca sayfanın köşesinde ve Telegram'da haber verilir, bu kurulumu güncelleyen komutla birlikte; Cubicle'ın çalıştığı bilgisayarda kutudaki ⬆ Şimdi güncelle yeni sürümü tek tıkla kurup Cubicle'ı yeniden başlatır, Telegram'dan /update da aynısını yapar; --auto-update ile başlatılan Cubicle yeni sürüme kendisi geçer (--no-update-check kontrolü kapatır), Paperclip eklentisinde ⬆ Şimdi güncelle Paperclip'in kendi eklenti güncellemesini çalıştırır. Takılan işler de görünür: Paperclip'in engellenen işler kutusundaki bir iş (beklediği zincir durmuş, engelleyen işin sahibi yok, iş beklemede ya da iptal edilmiş, inceleyen yok, yönetimin kararı bekleniyor) ajanın elini ⛔ ile kaldırır; kartında neyi beklediği yazar, tıklayınca ne zamandır durduğu, bakılacak iş (⛔ onu Paperclip'te açar) ve ajanın takılı diğer işleri görünür; Telegram da aynısını bağlantısıyla gönderir. Sizi bekleyen ya da yönetime soru soran bir Paperclip ajanının kartında ✋ düğmesi çıkar: Paperclip'in kendi iş sayfası ofisin üstünde bir pencerede açılır, yanıt oradan verilir; Cubicle kendisi hiçbir şey göndermez. Ajan yönetimden onay istiyorsa (bağlı onay) ajana tıklayınca istenen şey ve riskleri bir pencerede görünür; ✋ düğmesi Paperclip'in kendi onay sayfasını açar. Telegram mesajı da onayın özetini, risklerini ve onay sayfasının bağlantısını içerir. Bir ajana tıklayınca açılan panel ajanın hep yanında durur; yapılabilecekler düğme olarak görünür (Yanıtla, İşi aç, Çalıştırma kaydını aç, Görünüm ve ad). Son çalıştırması başarısız olan ajanın kartında hata mesajı, kodu ve çıktının sonu gösterilir. ✎ penceresinden ajana yalnızca Cubicle'da görünen bir ad verilebilir. Panelin 💬 düğmesi, görev vermeden ajanla konuşmak için Paperclip'in Agent Chat'ini ofisin üstünde açar (Paperclip → Instance settings → Experimental'dan bir kez açılmalı). Başlıktaki Paperclip'i kendi sekmesinde açar; , bir kişinin verdiği görevlerin ilerlemesini (alt görevlerden), başlangıç tarihlerini, ne kadar sürdüklerini ya da ne zamandır sürdüklerini, tahmini bitiş zamanlarını, 7 günde bitenleri ve tipik bitirme süresini gösterir; ▸ ile her görev alt görevlerine ağaç olarak açılır. Açık görevin yanındaki 💡 görevi yavaşlatan ölçülebilir nedenleri sıralar (sizi bekleyen onay ve sorular, sağlayıcı kullanım sınırı ya da çok büyük istem (E2BIG) gibi tekrar eden hatalar, durmuş blokajlar, sahipsiz ya da hareketsiz işler, tek ajana yığılan iş, uzun süren ve çok çalıştırılan alt görevler) ve ne yapılacağını yazar. Tavsiyenin altındaki seçeneği (varsayılan kapalı, yalnızca Cubicle’ın çalıştığı bilgisayardan açılır) açılınca her tavsiye ya da hepsi birlikte, ajanı ve önceliği seçilerek yavaş görevin alt görevi olarak Paperclip’te açılabilir; açık görevi olan tavsiyede düğme yerine o görev görünür, görev tamamlanınca sonucu (son yorumu) yazılır, sorunu kalmayan tavsiyeler altına iner. Masasında çalışan ajanın üzerinde görev kodu ve tahmini bitiş saati (⏱) görünür; kodun üzerine gelince görevin adı çıkar. ⚙ menüsündeki ile ajanlar olanları sesli söyler, her biri kendi sesi ve tonuyla; , , , ve ayrı ayrı açılır. Kadın ajanlar kadın, erkek ajanlar erkek sesiyle konuşur (ofisteki görünüşe göre ya da ✎ → ile seçilir; ⚙ → ile karışık ya da herkes aynı da yapılabilir, / ile ses seçilir, ▶ ile dinlenir; Chrome'da Türkçe kadın sesi yoktur, menüdeki ofisi aynı ayarlarla Edge'de açar, orada Emel vardır). Tarayıcının kendi ses motoru (Web Speech API) kullanılır: ücretsizdir, kurulum gerektirmez, Cubicle hiçbir yere bir şey göndermez. Doğal Türkçe sesler Microsoft Edge'de var; Windows'ta Türkçe dil paketi de bir ses ekler. Linkte ya da ile de açılır. ⚙ menüsündeki satırından ofise isteğe bağlı bir kedi 🐈, köpek 🐕, tavşan 🐇 ya da robot süpürge 🤖 eklenir (her temada): kedi uyuklar ya da çalışan birinin yanına oturur, köpek sizi bekleyen ajanın yanına gidip oturur ya da yürüyen birinin peşine takılır, tavşan zıplayıp ot kemirir, robot süpürge tur atıp şarja girer; üstlerine tıklayınca selam verirler. Seçim tarayıcıda saklanır, ile linke de yazılır. Paperclip kullanılmıyorsa ve görev kutusu açıksa , CEO'ya verdiğiniz görevleri ve her birinin GitHub'da açtığı işleri (durumlarıyla) gösterir; dosyasında tutulur, Paperclip'teki eski görevler ile bir kez aktarılır. ⚙ menüsündeki açılırsa siz ilk masada oturursunuz ve sizi bekleyen ajanlar el kaldırmak yerine masanızın önünde sıraya girer. İsteğe bağlı Telegram botu ⚙ → penceresinden üç adımda kurulur: @BotFather'da ile bot oluşturulur, verdiği token pencereye yapıştırılır, penceredeki QR kodu telefonla okutulur (ya da bot Telegram uygulamasında veya Telegram Web'de açılır) ve 'a basılır; olmazsa bota penceredeki mesajı gönderilir. Bağlantıların telefonda da açılması için bilgisayara (tailscale.com/download) ve telefona (App Store / Google Play) ücretsiz Tailscale kurulup aynı hesapla girilir; pencerenin 5. adımındaki düğmesi bilgisayarın Tailscale adresini kendisi bulur ve bağlantıları o adrese çevirir. Bot bir ajan sizi beklediğinde ya da çalıştırma hata verdiğinde Cubicle ve Paperclip bağlantılarıyla mesaj atar, , , komutlarını yanıtlar; açıksa mesaja verdiğiniz yanıt Paperclip'teki işe yorum olarak yazılır. Bildirimler ⚙ → 🛠 → bölümündeki ile kapatılıp açılır: kapalıyken bot kendiliğinden mesaj göndermez (bekleyen ajanlar, hatalar, biten işler, kararlar, yeni sürümler), bağlı sohbetlere bir kez haber verilir; komutlar (, ) çalışmaya devam eder, yeniden açılınca kaçanlar tekrar gönderilmez. GitHub'daki iş kuyruğu ( etiketleri, ile okunur) başlıkta olarak görünür: sizi bekleyen kararlar, hatalar ve incelenecek PR'lar; hiçbir ajan çalışmazken iş sizi bekliyorsa olur ve Telegram'dan da haber verilir. açıksa yeşil PR'ları CEO inceleyip birleştirir, kırmızı ya da çakışanları düzeltilmek üzere bir işçiye geri gönderir. Karar bekleyen bir iş () için CEO işi okuyup kararı hazırlar: ne olduğu, adım adım yapılacaklar, önerisi ve seçenekleriyle soru. 📥 listesindeki bunu Cubicle'da açar; cevabınızı CEO GitHub'da uygular. ⚙ → 🛠 (yalnızca Cubicle'ın çalıştığı bilgisayarda) dosyasını sayfadan değiştirir: bildirim ve mesajların dili, her Claude oturumuyla otomatik başlatma (port ve izlenecek kaynaklarla), Paperclip bağlantıları, ajanları ve tavsiye görevleri, CEO görev kutusu (klasör, model, bütçe, izinli araçlar, talimatlar; görev kutusu açıkken hata verip duran bir ajan önce CEO'ya gider, CEO işi yeniden dener ya da düzeltir, çözemezse karar size sorulur, Telegram'daki hata mesajı da CEO'nun müdahale ettiğini söyler); çalışan Cubicle'ın sürümünü, adresini, kaynaklarını ve güncelleme biçimini de gösterir. ⚙ menüsündeki ve seçenekleriyle iki bölümden biri kapatılabilir; animasyon kapalıyken kartlar, her ajanı temaya uygun masasında oturur hâlde gösteren sabit masa kartlarına dönüşür.
?anim=0, ?cards=0 in a link). With the animation off, nothing moves and the cards become desks: each agent sits at its desk in the current theme, drawn once per update, with the card's details below. Handy on a slow machine or a busy screen.?voice=wait,start,done?voice=all?pets=cat,dog~/.cubicle/kpi.jsonnpx @caglarutkuguler/cubicle kpi-import/start 123456/status/waiting/kpi--telegram-replies/status/waitingagent:ready/working/review/blocked-human/failedghagent:blocked-human~/.cubicle/settings.json