{"slug": "a-3d-office-where-real-claude-code-sessions-work-as-employees", "title": "A 3D office where real Claude Code sessions work as employees", "summary": "A developer tool called Orchestrator presents a 3D office environment in which each employee at a desk is a real `claude` process running in a real tmux session and git worktree on a shared server, with tasks marked done only after tests run and both a colleague and the owner approve a conflict-free merge. The office runs on one server that stays open, with owners, colleagues and visitors joining via desktop app or browser, and a colleague's own computer becomes a separate room on the floor. The project's README claims one employee of the office built 21 interactive 3D website previews for real businesses in a single day, and a live demo at office-demo.sparkcan.com uses scripted stand-in employees so it costs no Claude usage.", "body_md": "## orchestrator-promo-readme.mp4\n\n<sub>▶ The office in 50 seconds (sound on). The real app, recorded in a demo office whose employees are scripted stand-ins, so no Claude usage was spent. Music: “Funkorama” by Kevin MacLeod ([incompetech.com](https://incompetech.com)), licensed under [Creative Commons: By Attribution 4.0](https://creativecommons.org/licenses/by/4.0/).</sub>\n\n**Real Claude Code agents. Real colleagues. One server. Played like a game — shipped like a company.**\n\n[**In 30 seconds**](#-in-30-seconds) ·\n  [**How it fits together**](#-how-it-fits-together) ·\n  [**Built in one day**](#-built-in-one-day) ·\n  [**Screenshots**](#-screenshots) ·\n  [**Features**](#-everything-it-does) ·\n  [**Quick start**](#-quick-start) ·\n  [**FAQ**](#-faq) ·\n  **Docs**\n\n| Every person at a desk is a **real `claude` process** in a real tmux session, in a real git worktree, on a real machine.**Done** means your tests ran, a colleague and you reviewed it, and it merged — not that an agent said so.Nothing moves unless a hook, a tool call or the terminal says it happened. Unknown is shown as `UNKNOWN` . | Walk the floor with `W A S D` .`F` talks to whoever you stand next to;`Space` sits you at their terminal.They act out what their session is doing: chin in hand while it thinks, typing while it codes, **a hand up** when it needs you.Quests, XP, employee of the month, an arcade, a city to parachute into — and a whip for the sleepers. | The office runs on **one server** and stays open. Your colleagues walk in with the desktop app, from their own computers.Shared agents work on the server; a colleague's own computer becomes **a room** on the floor, and what runs there stays theirs.Owners, colleagues, visitors. Chat, voice, two-player arcade. | \n\n**👀 Don't take our word for it — [walk into the live demo](https://office-demo.sparkcan.com).** No sign-up: you're the boss for the day. Talk to the team (`F`), hand out tasks, answer their questions, look at the machines and the colleagues' rooms, chat with whoever else is there. <sub>(Its employees are scripted stand-ins, so it costs nothing to keep open; the office around them is the real one. Use a computer.)</sub>\n\n**One server, the whole team.** Agents on the server are shared by everyone invited; a colleague's own computer joins while they are in.\n\n```\nflowchart LR\n  subgraph People[\"👥 People — desktop app or browser\"]\n    you[\"🧑‍💼 You (owner)\"]\n    mila[\"👩‍💻 Mila (colleague)\"]\n    guest[\"👀 A visitor\"]\n  end\n  subgraph Server[\"🖥️ One server — the office, always on\"]\n    office[\"🏢 Orchestrator<br/>tasks · approvals · reviews · merges<br/>events · memory · audit\"]\n    subgraph Shared[\"Shared machine\"]\n      a1[\"🤖 claude · Alex<br/>tmux + worktree\"]\n      a2[\"🤖 claude · Sarah<br/>tmux + worktree\"]\n      a3[\"🤖 claude · Mike<br/>tmux + worktree\"]\n    end\n  end\n  subgraph Laptop[\"💻 Mila's own computer — a room on the floor\"]\n    m1[\"🤖 claude · Mi-1\"]\n    m2[\"🤖 claude · Mi-2\"]\n  end\n  you & mila & guest <-->|\"TLS · one office\"| office\n  office <--> Shared\n  office <-->|\"while Mila is in\"| Laptop\n```\n\n**What \"done\" really means.** Every step below is measured by the office, not reported by the agent.\n\n``` php\nflowchart LR\n  T[\"📋 You hand out a task\"] --> W[\"🌿 Worktree + branch<br/>made for it\"]\n  W --> C[\"🤖 The agent works<br/>in its real Claude Code\"]\n  C -->|\"needs a decision\"| H[\"✋ A hand goes up<br/>held until you answer\"]\n  H --> C\n  C --> V[\"🧪 Your tests run<br/>on the machine\"]\n  V -->|\"fail\"| C\n  V -->|\"pass\"| R[\"👀 A colleague reviews,<br/>then you\"]\n  R -->|\"send back\"| C\n  R -->|\"approve\"| M[\"✅ Merged without conflict<br/>= DONE\"]\n```\n\n**Twenty-one interactive 3D website previews for real businesses — each its own idea, not a template — built in a single day by *one* employee of the office.** The rest of the team spent that day on other projects. All live; open any of them.\n\n| [**vanas.rs**](https://vanas-preview.sparkcan.com)<sub>Real catalogue tiles in a 3D bathroom</sub> | [** energoglobal.com**](https://energoglobal-preview.sparkcan.com)<sub>A generator that comes apart as you scroll</sub> | [** josipovic.rs**](https://josipovic-preview.sparkcan.com)<sub>A camera lens, and focusing</sub> | \n| [**mocbilja.rs**](https://mocbilja-preview.sparkcan.com)<sub>Herbs that grow, and a map of the body</sub> | [** sax.rs**](https://sax-preview.sparkcan.com)<sub>Fabric in the wind</sub> | [** casagrande.rs**](https://casagrande-preview.sparkcan.com)<sub>A furniture configurator</sub> | \n| [**dar.rs**](https://dar-preview.sparkcan.com)<sub>An X-ray of a tractor</sub> | [** skuteribeograd.com**](https://skuteri-preview.sparkcan.com)<sub>Ride a scooter as you scroll</sub> | [** tehnoalat.com**](https://tehnoalat-preview.sparkcan.com)<sub>A wall of swinging tools</sub> | \n| [**borikplus.rs**](https://borikplus-preview.sparkcan.com)<sub>UPS & solar calculator, live gauges</sub> | [** kupidobro.rs**](https://kupidobro-preview.sparkcan.com)<sub>Shelving where every shelf is a category</sub> | [** astyle.rs**](https://astyle-preview.sparkcan.com)<sub>An order pallet and a B2B price list</sub> | \n| [**demkatrade.com**](https://demkatrade-preview.sparkcan.com)<sub>From log to pallet: a production line</sub> | [** bioline.rs**](https://bioline-preview.sparkcan.com)<sub>A scale for loose tea</sub> | [** cfsport.rs**](https://cfsport-preview.sparkcan.com)<sub>A shaker that fills with supplements</sub> | \n| [**beautydoo.rs**](https://beautydoo-preview.sparkcan.com)<sub>A pipeline with valves that open</sub> | [** vodoterm.co.rs**](https://vodoterm-preview.sparkcan.com)<sub>A house in thermal vision</sub> | [** agrosanmitrovic.rs**](https://agrosan-preview.sparkcan.com)<sub>A greenhouse through the seasons</sub> | \n| [**europaint.rs**](https://europaint-preview.sparkcan.com)<sub>A car door repaired in a paint booth</sub> | [** bajkolino.rs**](https://bajkolino-preview.sparkcan.com)<sub>A toy town with a little car</sub> | [** fravero-prophoto.com**](https://fravero-preview.sparkcan.com)<sub>A 3D photo album with gold foil</sub> | \n\n<sub>Every picture is the real app, taken from a demo office whose employees are scripted stand-ins (so no Claude usage was spent on looking good). Only the frames and the shouting were added — `scripts/readme-shots.cjs` and `scripts/readme-art.cjs` make them again.</sub>\n\n| With a terminal per agent | In the office | \n|---|---|\n| You tab through a dozen terminals to find out who is stuck | Every tag says what that session is really doing; the **Inbox** and the**Command center** list who needs you, across every machine | \n| A permission prompt waits unseen in a tab you are not looking at | A hand goes up. The request is held open — through restarts — until you answer it | \n| \"Done\" means the agent says so | *Done* means a worktree and a branch, your tests run on the machine, a review by a colleague and then by you, and a clean merge | \n| An agent on another machine means SSH and `tmux attach` | Every machine's sessions sit in the same office; `Space` puts you at any terminal,**Take control** gives you the keyboard | \n| You carry context between agents by hand | They ask each other, wait for each other, hand work over and review each other — on the record | \n| One Claude account runs out and the work stops | Several accounts per machine; when one is spent its people move on by themselves | \n| Keeping everyone busy is your job | The foreman answers operational questions; a `/goal` keeps one going until it holds; routines repeat the checks | \n| You work alone | Your colleagues are in the same office, on the same server, with their own agents in their own rooms | \n\n**For the work**\n\n| 🧑💻 **Hire** | A name, a role, a folder, a desk — and the **Claude account** ,**model** (Fable, Opus, Sonnet, Haiku) and**effort** for each; change them for one or a dozen at once | \n| ✋ **Answer** | A raised hand is a real question or permission request, held open until you decide | \n| 📋 **Quests** | Tasks with worktrees and branches; each a conversation (questions with answers to click, pictures, send back). Done = tested, reviewed, merged | \n| 🤝 **Teamwork** | Agents ask, wait for, hand over to, review, unblock and wake each other | \n| 🎯 **Goals** | `/goal every test in packages/api passes` — they keep going, turn after turn, until it holds | \n| 🧢 **The foreman** | A supervisor that walks the floor, answers operational questions and keeps people moving — you are asked only about direction | \n| 🔋 **Claude accounts** | Several per machine, signed in **from the office** ; Z.AI's GLM plan too. Out of quota → people move on; out of Fable → they go on with Opus | \n| 🧠 **Long memory** | The record kept word for word ( [MemPalace](https://github.com/brstic/orchestrator/blob/main/docs/MEMORY.md) ); agents`recall` and`remember` across sessions | \n| 🔁 **Routines** | \"Every 30 minutes, check the error log\" — repeated by itself | \n| ⏳ **Background commands** | A long test run or a dev server shows as **⏳ COMMAND RUNNING** ; nobody nudges them meanwhile | \n| 📎 **Files & eyes** | Pictures and files on tasks and messages; screenshots as evidence; a browser of their own ( [docs/ATTACHMENTS.md](https://github.com/brstic/orchestrator/blob/main/docs/ATTACHMENTS.md) ) | \n| 🔐 **A vault** | Keys and passwords used by name, never typed into a prompt | \n| 😴 **Sleep & wake** | Idle sessions sleep after 30 minutes; a message, a task or the whip wakes them — same conversation | \n\n**Because it is an office**\n\n| 🎭 **Zero NPCs** | Everybody acts out what their session is really doing, and the tag says it in words | \n| 👥 **People** | Invite with a link; owners, colleagues, visitors; a room per colleague's computer; chat, voice ( `V` ), gestures | \n| 🕹️ **Arcade** | A Mega Drive in the corner — bring your own cartridges; a colleague presses **Join** and plays player 2 from their own computer | \n| 🛋️ **Break room** | Internet radio for the whole office, a TV with a real browser, sofas you can sit on | \n| 🌆 **A view** | The top floor of a tower at dusk, a park, an island, the northern lights or orbit — one click, for everybody | \n| 🪂 **The city below** | Walk out on the terrace, jump off the edge, parachute down, take a car out of the traffic and drive a city without end | \n| 🏆 **Employee of the month** | Whoever really **worked** the longest this month, counted by the office | \n| 🪢 **The whip** | `R` . A crack, a flinch, a \"jao!\". It wakes the sleepers; it sends nothing to anybody's session | \n| 🚪 **The front door** | The office's address has an entrance page: members sign in, anyone else knocks | \n\nRequirements: **Node.js 22.18+**, **tmux**, **git**, the **Claude Code CLI** (`claude`) logged in, and pnpm.\n\n```\npnpm install\npnpm build          # bundles the server + agent and builds the office UI\npnpm start --open   # server + local host agent; opens the office in your browser\n```\n\nor as a desktop app: `pnpm desktop`. Then **Menu → Team → Hire**, walk to the desk and press `F`.\n\n**For the team:** run the office on a server (ideally Linux) so it stays open, and invite people from **Menu → Access** — they paste the link into the desktop app. `pnpm package` builds a portable tarball and a macOS app; [docs/INSTALL.md](https://github.com/brstic/orchestrator/blob/main/docs/INSTALL.md) covers servers, TLS, services and Windows/WSL.\n\n## **Step by step: your first hire, and a whole team**\n\n**Talk to an employee directly (the \"cubicle\" model).** Every employee can live in a folder and own the project in it.\n\n1. **Menu → Team → Hire** — a name, a role and a**folder** (use*Browse…* ;**New folder** makes one on that machine). That folder becomes their project, and they work in it in place. There are three levels:**Standard** (edits and routine commands; everything else asks you),**Auto** (Claude Code's auto mode decides; you are asked only for decisions) and**Unrestricted** (Claude Code's bypass-permissions mode: nothing is asked; high-risk commands are still held for you unless you switch that off). An owner's new hires are Unrestricted, a colleague's are on Auto; choose under*More options* . Claude Code's own first questions —*trust this folder?* , the bypass warning — are answered by the office, on the record (Settings → Employees switches that off).\n2. Walk to their desk (`W` /`S` to walk,`A` /`D` to turn,`Q` /`E` to sidestep) and press`F` to**talk** : tell them what to do in plain words. Your message goes into their real Claude Code session; their reply comes back in the conversation. Paste a screenshot or drop a file into it and they get the file; ask them to show you something and the picture appears there, to look at or download. Tick*Track as a task* when you want the work verified before it counts as done.\n3. Press `Space` instead to sit at their terminal and watch it, and**Take control** if you want the keyboard. The folders on their desk are the Markdown files in their folder — click them to read.\n\n**Extras.** The **hi-fi** in the break room (or **Menu → Hi-fi**) plays internet radio for the whole office: pick a station, or add any direct stream address; a small player in the top bar shows what is on and stops it. `R` next to an employee cracks a whip — a sound, a flinch and a “jao!”, and nothing else: it sends nothing to their session. The **arcade cabinet** (it arrives after ten delivered tasks) plays Mega Drive cartridge files you bring: *Add games…* and *Play*; a running game shows up for everybody else in the office with **Join** and **Watch** ([docs/ARCADE.md](https://github.com/brstic/orchestrator/blob/main/docs/ARCADE.md)). `Space` at a sofa or a chair sits you down; `Space` on open floor is a jump.\n\n**Let Orchestrator manage a team on a shared project.**\n\n1. **Projects → New project** — point it at a git repository and give it a verification command (e.g.`npm test` ). Shared projects give each employee an isolated worktree and merge finished work for you.\n2. **Team → Hire** several roles into that project.\n3. **Tasks → New task** , or press`G` and type*“Assign Alex to fix the authentication bug”* /*“Build the customer system. Split the work between backend, frontend, QA and security.”*\n\nTo set up a whole example team in one go:\n\n```\npnpm apply-config examples/team.json --repo ~/code/your-repo --plan\n```\n\n## **Is this a game?**\n\nIt is a real development environment that you operate like a game. Everything that moves stands for something that really happened in a real Claude Code session; the 3D office is the interface, not the point.\n\n## **Does it spend my Claude usage?**\n\nYour employees are your Claude Code sessions, on your accounts — they use what Claude Code would use. Walking around, the whip, the arcade and the city spend nothing. The live demo spends nothing at all: its employees are scripted stand-ins.\n\n## **Do my colleagues need their own server?**\n\nNo. One server runs the office; everybody walks in with the desktop app. Agents on the server are shared by the people invited; a colleague who wants agents of their own runs them on their own computer, which becomes their room while they are in.\n\n## **How much may an agent do on its own?**\n\nThree levels per employee — Standard, Auto, Unrestricted — mapped to Claude Code's own permission modes. High-risk commands are held for the owner, and a project's deny rules and the fence around the office's own files stand in front of every level. [docs/SECURITY.md](https://github.com/brstic/orchestrator/blob/main/docs/SECURITY.md) says what that does and does not protect.\n\n## **Which systems?**\n\nVerified on macOS (Apple silicon) and Linux; in daily use as an always-on office on Ubuntu, with people coming in from macOS and Windows. Details below, under *Status and limits*.\n\n## **What you press, and what really happens**\n\n| In the office | What really happens | \n|---|---|\n| Walk up to a desk, press `F` and say what you need | Your words are pasted into that employee's real session; the reply shown is the final message of the turn, as reported by Claude Code's `Stop` hook | \n| Walk up to a desk, press `Space` | Your client subscribes to that pane's output through tmux control mode; you see the live terminal, read-only | \n| **Take control** | The server grants you exclusive input ownership; your keystrokes go to that same tmux session with `send-keys` . The Claude process is never replaced | \n| **Return control** | Ownership is released; anything Orchestrator held back while you typed is delivered | \n| Assign a task | A worktree and task branch are created, the session is started if needed, the prompt is pasted into the terminal, and delivery is confirmed by Claude Code's `UserPromptSubmit` hook | \n| An employee raises a hand | The agent called `ask_boss` , or Claude Code raised a`PermissionRequest` /`AskUserQuestion` — the real request is held open until you answer | \n| Answer from the office | The answer is returned as the tool result or hook decision; it is marked confirmed only when the runtime acts on it | \n| A task turns DONE | Orchestrator itself checked a clean tree, real commits, ran your verification command on the host, got review approval if required, and merged without conflict | \n| An employee walks to a colleague | A real `request_collaboration` was sent through the MCP server and delivered into the colleague's session | \n| The start screen: **Connect to an office** /**An office on this computer** | Connecting needs an invitation link (or the office's address, to ask at the door): the app talks only to a computer whose certificate it can check, and sends nothing before checking it. An office on this computer starts a server and agent here | \n| Menu → **Access** →**Open** ,**Invite** | You get a short link that works once ( `https://your.office/join/K7QF-M2XP-9TRD` ); the person pastes it into the app, and the app exchanges the code at the office's door for a credential of its own. A second, TLS listener forwards the page, the API, the client socket, and what a member's own computer needs (agent socket for personal hosts only, worker endpoint). Each member has a role — visitor, colleague, owner — enforced by the office for every request and terminal message ([docs/ACCESS.md](https://github.com/brstic/orchestrator/blob/main/docs/ACCESS.md) ) | \n| A room with someone's name on it | That member is connected and their computer is one of the office's machines right now; the employees in it run on that computer. The room is gone when they leave; the sessions stay in tmux there | \n| Other people walking around | Each person's app reports where their character is; the office relays it. What they say (Enter) is heard by the people present — never typed into an employee's session | \n| Team → **Hire for several projects** | One employee per folder you tick, named after the folder; each folder becomes that employee's own project. Nobody's session is started by hiring: it starts when you first talk to them or give them work | \n| An empty chair → `Space` ; right-click →**Move to another desk…** ; Office →**Who sits where** | Only the employee's desk changes (a swap if someone sits there). Their session, project and work are untouched | \n| The TV in the break room | A real browser inside the window (desktop app): its own storage, no access to the office or your files, camera and microphone refused. Put away, it keeps playing; the screen on the wall shows its real picture | \n| Machines → Add a machine → A server over SSH | The office runs `ssh` as you (keys only), copies the host agent to the server and keeps a reverse tunnel open; the server enrols with a single-use token and its Claude Code sessions become employees. No port is opened anywhere | \n| A card on the Tasks board that says **Your review** or**Asks you** | Something really waits for you: finished work to approve or send back (a colleague may have approved it first), a question an employee asked on the ticket and cannot go on without, or a proposal to release. Click the card: your answer in the task's box is delivered into that employee's session | \n| An employee asks on a ticket, with **A / B / C** to click | Its session called `comment_on_task` with a question: the task is parked on that question and the employee takes no new work until it is answered. Your click is delivered into the session as the answer | \n| **Send back** on a finished task | The task is reopened with your note, on a fresh branch from where it stood; the same employee picks it up again | \n| A task with parts | Its assignee divided it ( `split_task` ): each part is a ticket of its own that a colleague's session really works on; the ticket waits for them and comes back to its lead | \n| An employee hands a task to a colleague | The agent called `hand_off_task` : its work had to be committed, the task branch moves to the colleague's worktree, and the notes travel with the task | \n| Projects → Integration | After each merge your verification command also runs on the integration branch; **Bring in main** merges the base branch in,**Promote to main** fast-forwards the base branch to it — refused while tests fail, when it is not a fast-forward, or over uncommitted changes. Nothing is ever pushed | \n| Terminals → Operations | Build results are the office's own verification runs; deployments are commands that really ran in a terminal, with their exit status; git activity is commits and merges measured on the machines | \n| A security notification | Claude Code refused an action, a known credential format went through a session (it is redacted in the records), a machine was refused a connection, or someone presented wrong owner tokens | \n| The **Foreman** stands at someone's desk during a round | The foreman's own session looked at that employee ( `look_at` : the last lines of their real terminal, their task, their open question), answered them, gave them work or told them what to do next. Between rounds it walks the office from desk to desk; that walk is only a walk — nothing is read or sent | \n| An employee's question is answered without you | The foreman's session called `answer_question` ; the employee gets the answer as usual and the record says the foreman gave it. Approving or denying an action is never the foreman's | \n| Hire → **Account** ,**Model** ,**Effort** | That employee's sessions are started with `CLAUDE_CONFIG_DIR=<that account's folder> claude --model … --effort …` . The effort levels offered are the ones the Claude Code on that machine says it has | \n| Company → Claude → **Add an account… → A Claude account** | The office makes a config folder on that machine and runs Claude Code's own sign-in ( `claude auth login` ) there, in a terminal of its own; the window shows its link and passes on the code you paste. The login token stays in that folder on that machine; the office keeps neither the code nor the token ([docs/ACCOUNTS.md](https://github.com/brstic/orchestrator/blob/main/docs/ACCOUNTS.md) ) | \n| Company → Claude → **Z.AI — GLM Coding Plan** | Your API key is written into that account's own `settings.json` on the machine (`ANTHROPIC_BASE_URL` ,`ANTHROPIC_AUTH_TOKEN` ); Claude Code started there talks to Z.AI's models. The office does not keep the key, and never moves anybody onto that account or off it by itself | \n| Company → Claude → **Who is on what** →*Apply* | Each changed employee is updated; a running session is started again with `--resume` (the same conversation) on its new account, model or effort — at once when it is between turns, otherwise when its turn ends | \n| *“You've hit your Fable limit · resets Nov 19, 1pm”* | Read from Claude Code's `StopFailure` hook and from the screen: Fable counts as used up**on that account** until then, and everybody there who thinks with Fable is started again with`--model opus --resume` . Only when no model has room is anybody moved to another account. Claude Code's own menu after a refusal is answered*Stop and wait* — never*Switch to usage credits* | \n| An employee changes a colleague's model | Their session called `set_model` with a reason: the colleague's setting changes, their session is started again with the same conversation, and the change, the reason and who made it are in the feed and the audit log. The level and the account are not theirs to change | \n| The **Employee of the month** board | Every half minute the office adds the time each running session spends in a working state (thinking, reading, coding, testing, running a command…) for its employee; the board shows whoever has the most this calendar month. Waiting for you does not count | \n| Profile → **Routines** | A routine is an instruction the office types into that employee's session every *N* minutes, when they are between turns; a run that finds them busy is skipped | \n| `/goal <what has to be true>` in Talk (or Profile →**Goal** ) | The goal is typed into their session with its rules. Each time their turn ends and it does not hold, the office's `Stop` hook sends them on with it. It ends when their session calls`goal_met` with its evidence — and your check command passes, if you gave one — or when three turns in a row used no tool, or after a hundred. It waits while they wait for you, for a colleague or for a background command. Only a person can give a check command ([docs/CLAUDE-CODE-INTEGRATION.md](https://github.com/brstic/orchestrator/blob/main/docs/CLAUDE-CODE-INTEGRATION.md) ) | \n| **⏳ COMMAND RUNNING** over someone, the command under their name | Every two seconds their machine's agent reads the process table for the shells Claude Code started under that session; the hooks tell the office which Bash call is in front, so the others are the background ones. Their description (or the command, credentials redacted) is what the tag says | \n| Somebody asleep at their desk | No session is running: none was ever started, or it was stopped after 30 minutes without work (Settings → Employees). A message, a task, a meeting or the whip starts it — after a sleep with `--resume` : the same conversation, in the same folder | \n| Signing in at the office's address | The name and password belong to a member; signing in gives that member a credential for 30 days, the same kind an invitation gives. Guessing is slowed down per name and per address; the office's own owner token is never accepted from the network ( [docs/SIGN-IN.md](https://github.com/brstic/orchestrator/blob/main/docs/SIGN-IN.md) ) | \n| An employee recalls something from last month | Its session called `recall` ; the office searched MemPalace on its own machine, by meaning, in what was said and done, and returned what bears on it ([docs/MEMORY.md](https://github.com/brstic/orchestrator/blob/main/docs/MEMORY.md) ) | \n| An employee releases, unblocks, assigns or reviews a task, or wakes a colleague | Their session called `release_task` ,`unblock_task` ,`give_task` ,`submit_review` or`wake_colleague` ; it is on the record under their name. They cannot approve a permission request, mark work done unverified, or delete anything. Settings → Employees takes the board back | \n| The arcade → **Add games…** | The cartridge file goes to the office in pieces and is kept on its shelf; everyone in the office gets it from there. The emulator runs in a sandboxed frame of your own window that can reach nothing of the office | \n| A game at the arcade, and somebody else's **Join** | Your console keeps running the game; your window packs its picture and sound (the browser's own encoders) and the office passes them to whoever sat down. Their keys come back as the second pad — from the one who holds it and from nobody else. The office keeps nothing of the game | \n| `Space` at a sofa;`Space` on open floor | Your character sits there, or jumps. Your app tells the office, the office tells the others: nothing else happens anywhere | \n| The **vault** in the server room | Credentials are stored encrypted with the office; an employee's command gets one by name through a helper in its session's folder, and what goes through a terminal is redacted in the records ( [docs/VAULT.md](https://github.com/brstic/orchestrator/blob/main/docs/VAULT.md) ) | \n| Menu → **My work** →*Hire a team lead* | One more session on your own computer with tools held to your own employees: you tell it what you want, it hands it to the one whose it is and asks you what is yours to decide ( [docs/TEAM-LEAD.md](https://github.com/brstic/orchestrator/blob/main/docs/TEAM-LEAD.md) ) | \n| Projects → **Delete project…** | The project and its tasks are removed from the office, work in progress is interrupted first, its people stay. Nothing on disk is touched | \n| Meeting room | Each participant's session writes a proposal and a response; the facilitator's session writes the decision document and follow-up tasks | \n| Growth | Workers record lessons after real friction; Orchestrator proposes policy and process changes from its own history | \n\n## **Honesty rules the code enforces**\n\n- **Backend is the source of truth.** The 3D layer receives view models and callbacks; it cannot reach sessions or tasks.\n- **Unknown is shown as unknown.** A session without hooks, or on a host that is offline, is`UNKNOWN` — never “working”.\n- **Delivered ≠ confirmed.** Messages, tasks and answers move`queued → sent → confirmed` , and*confirmed* requires a signal from Claude Code.\n- **Measured, reported, unavailable.** Verification results are measured on the host; an agent's summary is “reported”; token usage is read from the real transcript or shown as “not available”. Cost is never invented.**How much Claude is left** on each account (5-hour and weekly percentages, exactly as Claude Code reports them, and a model's own limit once Claude refused a turn for it) is shown in Company → Claude; employees can be put on different Claude accounts.\n- **Autonomy is Claude Code's own permission modes, chosen per employee.** The three levels — Standard, Auto, Unrestricted — map to its modes and allow-rules; high-risk commands (pushes,`sudo` , deploys, broad deletions, reading credential files) go to the owner first. The top level,**Unrestricted** , is Claude Code's bypass-permissions mode — nothing is checked or asked there — and only an owner can give it; the owner can also switch the high-risk hold off for it. What stays in front of every level: a project's deny rules and the fence around the office's own files.`docs/SECURITY.md` says what that does and does not protect.\n\n## **The foreman**\n\nHire the **Foreman** (Team → Hire, role *Foreman*; give it any folder — that is only where its Claude Code session runs). There is one for the whole office, it runs on the office's own machine, and it has **no desk**: it walks the office — the shared floor and every member's room that is open — and keeps the work going. Hiring it switches its rounds on; **Settings → Foreman** pauses them.\n\n- **The office decides when, without any model.** Every few seconds it works out from its own records what needs attention: an employee's question nobody has answered, a blocked task, someone idle for five minutes with a task in progress, ready work that nobody has while somebody is free, and someone whose session has done nothing for ten minutes with no task at all. Only when that list holds something*new* — and the previous round is over, and the gap you set has passed — is**one** prompt delivered to the foreman's session. The prompt carries the digest itself, so a simple round needs a handful of tool calls. A quiet office starts no round and costs nothing.\n- **The foreman acts through its own tools** :`office_overview` ,`look_at` (an employee's real terminal screen, task and recent events),`answer_question` ,`assign_task` ,`create_task` ,`tell_employee` (carry on, how a blocker is resolved, what to pick up),`escalate_to_owner` ,`finish_round` . Everything it does is on the record under its name, and its character walks to whoever it is dealing with.\n- **Everyone is its business, members' own employees too** — while their member's computer is in the office. Work does not cross: a shared project's task never goes to someone's own computer, nor the other way round. Because the foreman sees what an owner sees, its own terminal is for owners only, and only owners can talk to it (see`docs/SECURITY.md` ).\n- **You are asked only about direction.** The foreman answers operational questions itself and escalates what is yours: direction, product or policy, anything destructive or irreversible, anything it is not sure about. An escalated question stays open in your inbox. You can always answer first — whoever answers first counts.\n- **It never approves anything.** Permission requests stay with you and with each employee's level; the foreman has no tool that could decide one, and cannot edit files or type into anybody's terminal.\n- **Cost.** Each round is a real turn in the foreman's Claude Code session and uses the Claude usage of the account that session runs on. An item the foreman has already seen does not start another round; an employee the foreman itself told to carry on, and who stops again, is left alone for twice as long each time. Optionally, with nothing waiting, it takes one look around every*N* minutes if tasks or sessions changed since its last round (default 15; 0 = never).\n\n*Settings → Foreman* shows who the foreman is, who it is with, the last round and its summary, and what currently needs attention (`GET /api/foreman`).\n\n## **Self-improvement**\n\n- **Workers** : after a task that hit real friction (failed verification, rejected review, merge conflict, a question, a denial), the employee's own session is shown the recorded facts and asked what it would do differently. Lessons are stored with their evidence, fed back into that employee's future prompts, and counted. Your answers to questions become project knowledge so nobody asks twice.\n- **Orchestrator** : routes unassigned work using measured first-pass rates per employee and task kind, and proposes changes from its record — pre-approve a command you keep approving, require review where work keeps failing, sequence tasks that keep colliding. Anything that widens what agents may do waits for you.\n\n## **How it is built**\n\n```\n ┌──────────────── 3D office (Electron / browser) ────────────────┐\n │  React Three Fiber scene · HUD panels · xterm.js terminals     │\n └───────────────▲───────────────────────────────▲────────────────┘\n        entities, events, monitor frames      terminal stream + input\n                 │            WebSocket + REST  │\n ┌───────────────┴────────── Orchestrator server ─────────────────┐\n │ hosts · sessions · employees · terminal gateway (ownership)    │\n │ hook receiver · tasks/scheduler · approvals · collaboration    │\n │ meetings · progression · self-improvement · MCP endpoint       │\n │ SQLite or PostgreSQL: entities, events, credentials, audit     │\n └───────────────▲────────────────────────────────────────────────┘\n                 │ one outbound, authenticated WebSocket per machine\n ┌───────────────┴──── orchestrator-agent (per machine) ───────────┐\n │ tmux control mode · Claude Code launcher · hook socket          │\n │ git worktrees · verification runner · resource sampling         │\n └───────────────▲─────────────────────────────────────────────────┘\n                 │ tmux panes\n        claude   claude   claude   …   (real interactive sessions,\n                                        or SDK-managed workers)\n```\n\n## **Repository**\n\n```\napps/\n  server/        HTTP + WebSocket server, MCP endpoint\n  host-agent/    orchestrator-agent CLI and daemon\n  desktop/       Electron shell + React app\npackages/\n  contracts/     shared types, event schema, protocol\n  execution/     tmux control client, Claude Code launcher, git, verification\n  orchestration/ engine: registries, hooks, tasks, approvals, meetings, commands, self-improvement\n  terminal/      terminal gateway and input ownership\n  integrations/  hook normalisation, MCP protocol + tool catalogue\n  database/      SQLite store, event store, credentials, audit\n  game-systems/  XP, levels, milestones\n  office-3d/     the 3D scene (pure view)\n  ui/            UI primitives\ntests/\n  e2e/           end-to-end tests against real tmux, hooks, MCP and git\n  fixtures/      scripted stand-ins for the CLI and the Agent SDK, used only by tests\n  real/          checks against the real Claude Code CLI and the real Agent SDK\n  ui/            the built UI driven in Electron with real clicks against a live office\n  linux/         the agent on Debian in a container, enrolled over TLS\ndocs/            architecture, install, security, Claude Code integration, and a page per larger feature (docs/README.md is the map)\n```\n\n## **Tests**\n\n```\npnpm test                  # unit tests\npnpm test:e2e              # about 370 end-to-end scenarios: real server, real agents, real tmux, real git; scripted worker\npnpm check:changed         # while working: typecheck and the tests beside what you touched (not instead of the above)\npnpm test:ui               # the UI used for real in Electron (clicks, typing, keys) against a live development office\npnpm package && pnpm package:smoke   # build the tarball and macOS app, then run them (incl. the connect screen)\npnpm package:linux         # .deb and Linux desktop bundles;  pnpm test:linux:deb / test:linux:desktop run them (Docker)\npnpm package:windows       # Windows desktop bundles, with the app's icon in Orchestrator.exe (not runnable here)\npnpm package:notarize      # sign with your Developer ID and notarize the macOS app (--check lists what is missing)\npnpm test:linux            # the agent on Debian in a container (needs Docker)\npnpm test:ssh              # a server reachable only over SSH is linked, used, disconnected, reconnected and removed (needs Docker)\npnpm test:machines         # three machines, three operating systems, one office; includes a real network partition (needs Docker)\npnpm test:real             # the acceptance scenario against the real Claude Code CLI (uses a little of your usage)\npnpm test:real:approvals   # real permission approval / denial / AskUserQuestion answered from the office\npnpm test:real:talk        # hire into a folder, say something, get the real reply\npnpm test:real:team        # two real sessions: implement, review by the second one, merge, then a meeting (…:team:sdk for SDK workers)\npnpm test:real:flows       # unanswered approval, Stop-hook delivery, retrospective, merge conflict — with the real model\npnpm test:real:flows2      # dependent task, nudge, request between employees, rejected review → rework, restarts mid-work\npnpm test:real:sdk         # an SDK-managed worker with the real Agent SDK (needs `orchestrator-agent sdk install`)\n```\n\n`tests/fixtures/fake-claude.mjs` behaves like Claude Code at the protocol level (runs the configured hooks, calls the MCP endpoint, edits files, commits) and `tests/fixtures/fake-agent-sdk` does the same for the Agent SDK's `query()`, so the whole system can be tested deterministically without tokens. Neither is ever used by the product.\n\n## **Status and limits**\n\nWorking and verified on macOS (Apple silicon) with Claude Code 2.1.321–2.1.323 and tmux 3.8; the host agent, the `.deb` and the desktop bundle are also verified on Linux (Debian 12, Ubuntu 24.04). It is in daily use as an always-on office on a Linux server (Ubuntu 22.04), with people coming in from macOS and Windows. See [docs/ARCHITECTURE.md](https://github.com/brstic/orchestrator/blob/main/docs/ARCHITECTURE.md#status) for exactly what was and was not validated. In short: both worker runtimes; reviews, rework, meetings, retrospectives, merge conflicts, nudges and restarts with real sessions; three machines on three operating systems with a real network partition; PostgreSQL; and every package except the Windows one were run for real. Two things could not be done on the development machine: starting the packaged Windows app (the app from the repository is used on Windows every day; the bundle itself has never been started) and notarizing the macOS app. What is in use and what is not yet verified, day by day, is in [docs/STATUS.md](https://github.com/brstic/orchestrator/blob/main/docs/STATUS.md).\n\n**Not ours:** the arcade runs RetroArch with the Genesis Plus GX core (in the repository, packed, with its source and checksums in `apps/desktop/src/arcade/core/NOTICE.md`). Genesis Plus GX may be used and passed on free of charge and **may not be sold or be part of something sold**. No game is in the repository, and none may be added: you bring your own.\n\n**Questions, ideas, what your office built, help with setting one up — it all happens in the [Orchestrator community](https://www.facebook.com/groups/orchestrator).**\n\nCome in and say hello.\n\n**ORCHESTRATOR** — the baton conducts, the prompt plays.\n\nNo employees were harmed by the whip. It only wakes the sleepers.\n\n<sub>Made by Branko · [LinkedIn](https://www.linkedin.com/in/bste/)</sub>", "url": "https://wpnews.pro/news/a-3d-office-where-real-claude-code-sessions-work-as-employees", "canonical_source": "https://github.com/brstic/orchestrator", "published_at": "2026-11-14 21:46:31+00:00", "updated_at": "2026-11-14 22:24:10.419475+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-products"], "entities": ["Orchestrator", "Claude Code", "Anthropic", "sparkcan.com", "tmux", "vanas.rs"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/a-3d-office-where-real-claude-code-sessions-work-as-employees", "markdown": "https://wpnews.pro/news/a-3d-office-where-real-claude-code-sessions-work-as-employees.md", "text": "https://wpnews.pro/news/a-3d-office-where-real-claude-code-sessions-work-as-employees.txt", "jsonld": "https://wpnews.pro/news/a-3d-office-where-real-claude-code-sessions-work-as-employees.jsonld"}}