Virtual Company OS

A staff of AI agents on your Mac, run from your phone.

Shiioo turns the coding agents you already pay for, Claude Code on your Claude plan and Codex on your OpenAI plan, into employees of a small company whose only human is you. You hand out work from Telegram, they work in their own branches, your rules decide what they may do alone, the rest comes to your phone as a question, and everything they did is on the record.

You need a Mac that stays on · Claude Code or Codex · a Telegram bot · Tailscale

Five ideas, one binary.

Employees are harnesses

Claude Code and Codex run headless in a git worktree of your repository, on your subscriptions. Local models through Ollama, LM Studio or an MLX server serve Shiioo's own loop. Each is one [[employees]] entry; a task goes to the first whose subscription window isn't used up.

The office is one binary

shiioo is the server (the record, the rules, the API and dashboard, the Telegram bot, the workers) and the node that runs the agents, in one process on your machine. Its data is one directory with an embedded database. No Postgres, no containers.

The record is the only state

Every run is an append-only, hash-chained event log: each model message, tool call, result, rule verdict and approval. Workers hold fenced leases, so a crash, a sleeping laptop or a lost connection means the run resumes from its log, and a side effect never silently happens twice.

Rules first, you second

rules.toml says what agents may do without asking: allow, ask or deny per tool, command, path and repo. Before every tool call the harness asks Shiioo. Most calls are decided at once; the rest wait for your tap. A dead server means deny, never an unguarded agent.

Your phone is the interface

Telegram to delegate, approve and be told when something finished or needs you. A mobile dashboard over Tailscale for the live log, the diff and the buttons. No public address anywhere: the bot long-polls, the dashboard sits on your tailnet.

On the record

Everything an agent did, in order, provably.

A run's log is the thing itself, not a report about it. The worker writes what it is about to do before it does it, so a crash at any point leaves a log that says exactly what did and didn't happen. Each event carries its position, the lease epoch it was written under, and the hash of the event before it; change a byte anywhere and verification fails.

  • Fenced leases. Only the current lease holder can append. A stalled worker that wakes up after a takeover is refused, and so is the late tool call it tries to send.
  • Write before acting. The model's response is recorded before any tool runs; a tool call is recorded as an intent before it is dispatched and as a result after.
  • No blind retries. Pure and idempotent calls are re-run after a crash; a side-effecting call whose outcome is unknown stops the run and asks you.
#0  run created: Append a line to README.md and commit it
#1  lease acquired by local-70065 (epoch 1)
#2  claude-code session 91ccb674… (claude-haiku-5-5)
#4  → Bash {"command":"tail -c 200 README.md | od -c | tail -5 && git status --short"}
#5  capacity claude-code: 5h 19%, 7d 5% used
#6  rules: ask Bash (segment "od -c": default: ask)
#7  waiting for approval: Bash: tail -c 200 README.md | od -c | …
#8  allow by owner
#9  ← /Users/me/shiioo-office/.shiioo/worktrees/db2426e0-…
#12 → Bash {"command":"printf 'Dashboard check.\n' >> README.md && git commit -qam …"}
#13 rules: allow Bash (rule 59 (Bash|shell `printf *`): allow)
#14 ← 5702552 docs: dashboard check  1 file changed, 1 insertion(+)
#16 harness result: success, cost $0.0027, 0 permission denial(s)
#17 completed: Appended the line to README.md, committed as 5702552

The staff

Hire the agents you already have.

Sixteen pixel-art portraits of the Shiioo mascot in different moods

Claude Code

Driven in its headless print mode, in a worktree of your repo, with the same login you use in the terminal. Every message and tool call is recorded; a crashed worker resumes the very same session. Its five-hour and seven-day windows are read from its output and shown on your phone.

Codex

Driven through codex exec --json with the same approval hook: before each command Codex asks Shiioo, and your rules or your tap decide. Its own OS sandbox is off, because headless Codex can't ask you and its sandbox would block every commit; the hook is the sandbox.

Local models

Shiioo's own agent loop against anything that speaks the OpenAI chat API: Ollama, LM Studio, an MLX server. Name a model ollama/qwen3:32b and it runs on your hardware, for planning, triage and bulk work that shouldn't spend a subscription.

Tasks go to the first employee whose windows are under their limits; /capacity shows what is left this week.

Status

What works today, and what doesn't yet.

Kernel: event log, hash chain, leases with fencing, crash recovery, embedded storebuilt, conformance-tested, plus a seeded crash simulation
Claude Code and Codex as employees, worktree per run, resume after a crashbuilt, verified with the real binaries
Rules, approvals through the harness hook, cancellationbuilt, verified live
Telegram bot and mobile dashboardbuilt; bot tested against a fake server, dashboard in a browser
shiioo install: login service, keep-awakebuilt on macOS; Linux unit untested
Capacity broker, local models, GitHub-issue intakebuilt; untested against a live Ollama
OS isolation levels, secrets injection, egress rulesplanned, phase 4
Planner and routines, remote nodes, asset and mail work, fork and replayplanned

Today an agent runs with your user's permissions and no OS sandbox; the rules and your approvals are what stand between it and your machine. Use it on repositories you don't mind it changing until phase 4 lands.

Quick start

Three commands on the Mac, then your phone.

Log in once to claude and/or codex, create a bot with @BotFather, then:

cargo install --path crates/shiioo
export SHIIOO_TELEGRAM_TOKEN=...
shiioo --workspace ~/shiioo-office install

install prints the dashboard link and the Tailscale steps. Put your Telegram id and your repositories in .shiioo/config.toml, restart, and send the bot /run myproject fix the flaky test. The full walkthrough →

Your work, delegated. Your record, intact.