Aricode is a coding agent. Aridesk is the second mode: a personal-agent runtime that lives in the same app but works for you — browsing the web, triaging email, running shell tasks, drafting messages — every sensitive call gated through your phone.
Aridesk is actively being built. The runtime, cron, broker, tools, templates, skills, MCP bridge and phone chat land as of v0.6; the desktop dashboard ships in the current Aricode app under the Desk tab. The isolation model is a host process pinned to the agent's workspace/ directory plus a multi-tier approval broker; container-grade sandboxing is on the long-horizon roadmap, not the next folio.
The aricode desktop already knows how to hold a conversation, stream a model, invoke tools, and pair with your phone over end-to-end encryption. Aridesk reuses all of that, but points the agent at a different kind of work.
Instead of a repo on your disk, each Aridesk agent gets its own persona, its own pinned workspace, its own browser profile with persistent cookies, and its own toolset. You create them the way you'd create folders: give them a name, drop in a soul.md, pick a template, start chatting.
Every agent is a directory: soul.md persona, instructions.md task scope, agent.md YAML config, memory.md rolling context. Version-control them, sync between machines, diff persona changes like code.
Run a research agent, an inbox triager, a shopping assistant, and a calendar secretary at the same time. Each gets its own pinned workspace, model selection, browser profile, and memory. Switch between them as tabs on the phone.
Three tiers of gating before any tool call fires. Workspace pin — every shell, file, and browser call is rooted at the agent's workspace/; paths outside it are rejected outright. Exec policy — shell calls pre-classify into auto (safe reads), gate (asks once, can be remembered), or deny (foot-guns, never run). Approval petition — gated calls stall as a card on your phone with full preview, Approve / Deny / Always-allow scoped to the target.
Chromium + Playwright driven over CDP on the host, with a per-agent browser-profile/ directory as its user-data-dir. Cookies, local storage, and session tabs survive restarts — the agent stays logged into the sites you gave it access to. The browser context spins up lazily on first navigate and closes after idle, so a sleeping agent costs nothing.
A shell pinned to the agent's workspace/ directory. Ripgrep, curl, node, python, git inherited from the host. Timeouts per call, stdout/stderr streamed back as tool output. The exec policy classifies each command before it runs — safe reads (ls, git status) skip the prompt; mutating commands gate to your phone; foot-guns hard-deny.
Read, write, edit, and search files inside the agent's workspace/ directory. Paths are pinned — anything outside the workspace stalls for phone approval. Drop documents in from the host to give the agent material, export artifacts back when it's done.
Brave Search API, wired on the host side and exposed as a single web.search tool. Configured per-agent or globally, so scoped keys are trivial.
A host-side broker exposes macOS automation to the agent. Every AppleScript call routes to the phone for approval, with an optional always-allow rule scoped to a specific target. Nothing runs unreviewed. The broker is in-process today — the runtime, the broker, and the relay are co-located in the Aricode app, so latency is zero and there's no socket to lock down.
A dedicated tool emits a desk.agent.notify frame up the relay. Long jobs can finish and tap you on the shoulder. Cron-style runs can report their summary unsolicited.
Declare toolsets: [browser, terminal, files, web] in agent.md. Add fine-grained allow/deny lists for specific tool names. Deny always wins over allow — same semantics as OpenClaw.
Each agent gets a memory.md that it can rewrite through a memory.update tool, plus a recall database for incremental facts. Loaded whole into the system prompt; you can edit it by hand too. A nightly dreaming pass that consolidates transcripts back into the notebook is scheduled for v0.2.
A dedicated Desk tab in AriCompanion lists agents as cards and opens each into a messaging-style chat. Tool calls render as inline cards, approvals as blocking prompts, images attach via the composer. No desk, no laptop needed.
Before AppleScript runs or any gated tool fires, the broker emits a desk.approval.required frame. The chat surface stalls on a card with the full script preview, Approve / Deny buttons, and an always-allow for this target row that writes a scoped rule.
X25519 handshake, ChaCha20-Poly1305 on every frame, HKDF-SHA256 session keys, fingerprint verified on both ends. The relay sees ciphertext; agents on the same Mac register as peers on the same encrypted channel.
Agents load on first message, stay warm while conversations are live, and close their browser context after idle. No always-on daemon unless you want one. The runtime is co-hosted inside the Aricode desktop app — quit the app, the agents quit with it.
The desktop's hello frame declares capabilities.desk: true only when aricode desk init has run. The phone hides the Desk tab until it sees that flag, so pre-Aridesk installs look the same as before.
A full aricode desk subcommand group: init, new, list, edit, logs, start, stop, doctor. And a /desk <agent> slash in the aricode REPL for local prompts.
Each agent's agent.md declares model: provider:name. Mix and match: one agent on ChatGPT, one on Copilot, one on local Ollama, one on Anthropic — running concurrently, each with its own keys.
The agent runs as a host process pinned to its own workspace/ and browser profile. The Mac's native integrations (AppleScript, Keychain, the phone channel) sit behind an approval broker: anything outside the pin stalls as a petition on the phone before it fires. Three tiers gate every call — the workspace pin, the exec-policy classifier, and the phone approval card — and every decision is appended to a JSONL audit log on disk.
Toolsets are the primary unit of capability. Declare them in agent.md; narrow further with tools.deny. Deny always wins.
browser-profile/ directory used as Chromium's user-data-dir.workspace/ directory with a per-call timeout. The exec policy classifies each command as auto, gate, or deny before it runs, so safe reads skip the approval prompt and foot-guns never reach the shell.workspace/. Paths outside the pin stall for phone approval.memory.update — for conversational personas that need nothing but context and reply.
No database, no binary blobs (except the browser profile, which you probably want to keep uncommitted). Every agent is a directory you can read with ls.
agents/
research/
soul.md # persona / system prompt
instructions.md # task scope
agent.md # YAML: model, toolsets, image, limits
memory.md # rolling memory, agent-curated
history.jsonl # conversation transcript
workspace/ # pinned cwd for shell + files
browser-profile/ # used as Chromium user-data-dir
inbox/
calendar/
shopper/
templates/ # seeded by `aricode desk init`
research/
inbox/
calendar/
shopper/
broker.sock # host AppleScript broker (0600)
approvals.jsonl # audit log of every approve/deny
rules.json # "always allow" whitelist entries
Aridesk extends the existing AriCompanion relay with a desk.* frame family. No new transport, no new crypto. The phone and desktop mirror these cases in TS and Swift.
desk.agent.listPhone pulls the agent roster from the paired desktop.desk.agent.createCreate a new agent from a template on-device.desk.session.openOpen a chat with an agent; returns the last N messages.desk.messageUser message (text + optional base64 attachments) to the agent.desk.deltaA streaming chunk of the agent's reply, back to the phone.desk.tool.callRender a tool-call card on the phone as the agent invokes a tool.desk.tool.resultCompletion marker for a tool call — ok plus a short summary.desk.approval.requiredThe broker is blocking on a sensitive op and needs user decision.desk.approval.decisionPhone returns approve / deny, with optional "always allow" rule.desk.agent.notifyUnsolicited agent message — "I'm done, here's the summary".The agent emits, say, applescript.run with a script that texts your partner.
The host broker compares the call to rules.json. Exact match on script kind + target? Run it. No match? Hold the call.
A desk.approval.required frame travels the relay. The chat surface stalls on a card that renders the script verbatim.
Approve once, deny, or check always allow for this target to write a scoped rule that applies next time.
The script runs via osascript on the host. The decision and call are appended to approvals.jsonl.
The tool returns either the script output or a denial error, and the agent continues its turn.
// Per-agent whitelist. Deny always wins.
[
{
"kind": "imessage.send",
"target": "+44…0001",
"reason": "partner"
},
{
"kind": "calendar.add_event",
"target": "*@work.example"
}
]
Each template is a valid-on-its-own directory you can copy into agents/ by hand. aricode desk new is sugar on top.
Browser + web search + files. Opens tabs, extracts, summarises. Good for market scans, literature reviews, "what happened this week".
Host + files + memory. Reads Mail.app via AppleScript, drafts replies, flags what needs your attention.
Host + memory. Understands your week, adds events, texts people to reschedule, surfaces conflicts before you hit them.
Browser + memory. Keeps logged into your accounts, compares prices, tracks orders, reminds you when things are about to renew.
~/.aricode/desk/workspace/approvals.jsonl with timestamp + decision sourcecron.jsonl)aricode desk CLI subcommand group for scriptingmemory.mdagent.mdA personal agent you can actually trust,
because nothing sensitive happens
without a nod from your phone.