Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,62 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this

## [Unreleased]

## [1.0.0-alpha.0] - 2026-04-19

First v3 pre-release. ARC pivots from a collection of short-lived CLI
invocations to a **persistent local daemon** that owns every agent
runtime. The TUI, CLI, web dashboard, Electron desktop app, mobile app,
and self-hosted relay all become thin clients of one binary-mux
WebSocket protocol. Plan of record:
[`docs/plans/arc-v3-daemon.md`](./docs/plans/arc-v3-daemon.md).

### Added

- **`@axiom-labs/arc-daemon` package** — long-running local process. HTTP
`/health`, WebSocket binary-mux on `:7272`, SQLite at `~/.arc/arc.db`,
structured JSONL log at `~/.arc/daemon.log`, argon2-hashed per-client
tokens plus a root token in `~/.arc/auth.json`, PID file with
`readPid()` liveness probe, loopback-only host-header enforcement.
- **Binary-mux wire protocol (v1)** — channel byte + flags + `u32be`
length + payload. Channel `0x00` carries a Zod-validated JSON envelope;
`0x01`–`0x03` reserved for terminal, file, and audio streams. Specified
in [`docs/protocol.md`](./docs/protocol.md).
- **`@axiom-labs/arc-client` SDK** — shared client library: frame codec,
Zod envelope, typed RPC wrappers (`health`, `profiles.*`, `agents.*`),
subscription helpers, auto-reconnect with exponential backoff, terminal
channel passthrough. Re-used by every UI surface.
- **`@axiom-labs/arc-relay` placeholder** — package scaffold for the
self-hosted NaCl-box WebSocket multiplexer that lands in Phase 10.
- **`arc daemon` CLI group** — `start` (detached by default),
`start --foreground`, `stop`, `restart`, `status [--json]`, and
`logs [-n <N>] [--tail]`. `ARC_PORT` and `--port` both respected.
- **Initial SQLite schema** — `agents`, `agent_events`, `chat_rooms`,
`chat_messages`, `loops`, `handoffs`, `clients`, `meta` tables with
additive-only migrations from here on.
- **v3 user docs** — [`docs/architecture.md`](./docs/architecture.md),
[`docs/daemon.md`](./docs/daemon.md),
[`docs/protocol.md`](./docs/protocol.md), and
[`docs/v2-to-v3-migration.md`](./docs/v2-to-v3-migration.md). Getting
Started and the main ToC updated to point at the new daemon-first flow.

### Changed

- **Version scheme bumped to `1.x`.** v2 stays recoverable at the
`archive/v0.4.x` tag; new work tracks `1.0.0-alpha.0` onward.
- `packages/cli/src/version.ts` now reads `1.0.0-alpha.0`.

### Breaking

- None yet in this pre-release. The v3 wire-protocol version is `1`;
any future breaking protocol change will bump it. Within `1.x` the
additive-only rules documented in [protocol.md](./docs/protocol.md#versioning-and-backward-compat)
apply.

### Removed

- Nothing. The v2 JSON stores stay in place and are read-for-read by the
daemon until later phases migrate them into SQLite.

## [0.4.0] - 2026-04-18

### Added
Expand Down Expand Up @@ -223,7 +279,8 @@ All 25 phases of the [v2.0 spec](./docs/spec/SPEC.md) are now implemented. ARC h
- **Light mode contrast** — WCAG AA compliant dimmed/border colors, explicit `colors.text` on import hint
- **React hooks violation** — `useScreenSize()` moved above conditional returns in DashView

[Unreleased]: https://github.com/Codename-11/ARC/compare/v0.4.0...HEAD
[Unreleased]: https://github.com/Codename-11/ARC/compare/v1.0.0-alpha.0...HEAD
[1.0.0-alpha.0]: https://github.com/Codename-11/ARC/compare/v0.4.0...v1.0.0-alpha.0
[0.4.0]: https://github.com/Codename-11/ARC/compare/v0.2.0...v0.4.0
[0.2.0]: https://github.com/Codename-11/ARC/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/Codename-11/ARC/releases/tag/v0.1.0
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,31 @@

---

> ### 🚧 ARC v3 in progress (`1.0.0-alpha.0`)
>
> ARC is pivoting to a **daemon-first architecture**. A single long-running
> local process now owns every agent runtime; the TUI, CLI, web dashboard,
> and future Electron / mobile / relay clients are thin consumers of one
> binary-mux WebSocket protocol.
>
> - Plan of record: [`docs/plans/arc-v3-daemon.md`](./docs/plans/arc-v3-daemon.md)
> - New-in-v3: [daemon operator guide](./docs/daemon.md) · [architecture](./docs/architecture.md) · [wire protocol](./docs/protocol.md) · [v2 → v3 migration](./docs/v2-to-v3-migration.md)
> - v2 (`0.4.x`) stays recoverable at the `archive/v0.4.x` tag.

<p align="center">
<img src="assets/screenshots/dash-dark.png" alt="ARC Dashboard" width="700">
</p>

## What is ARC?

ARC started as a profile manager for agent CLIs (v0.1). It has since absorbed the [Axiom-Supervisor](https://github.com/Codename-11/axiom-supervisor) project and implements all 25 phases of the [v2.0 spec](./docs/spec/SPEC.md) — becoming a unified control plane for the full lifecycle of AI coding agents.
ARC started as a profile manager for agent CLIs (v0.1), absorbed the
[Axiom-Supervisor](https://github.com/Codename-11/axiom-supervisor) project
to implement all 25 phases of the v2.0 spec, and is now (v3) pivoting to a
**daemon-first** architecture — a persistent local process that owns every
agent runtime and exposes a single binary-mux WebSocket protocol to every
UI surface.

One binary. One config directory (`~/.arc/`). Every agent runtime — Claude Code, Codex CLI, Gemini CLI, OpenClaw, or anything that speaks MCP/HTTP/stdio.
One daemon. One config directory (`~/.arc/`). Every agent runtime — Claude Code, Codex CLI, Gemini CLI, OpenClaw, or anything that speaks MCP/HTTP/stdio.

## Features

Expand Down
144 changes: 144 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# ARC v3 Architecture

ARC v3 is **one daemon, many mouths**. A persistent local process owns
every agent runtime, every piece of state, and the single wire protocol
everything else speaks. The CLI, TUI, web dashboard, Electron desktop app,
mobile app, and self-hosted relay are all thin clients.

> **Source of truth:** [`docs/plans/arc-v3-daemon.md`](./plans/arc-v3-daemon.md).
> This document summarises the architecture that plan puts in motion.

```
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ TUI │ │ CLI │ │ Dashboard│ │ Electron │ │ Mobile │
│ (Ink) │ │ (short) │ │ (SPA) │ │ (desktop)│ │ (Expo) │
└────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │ │ │
└─────────────┴──────┬──────┴─────────────┴─────────────┘
@axiom-labs/arc-client (SDK)
▼ WebSocket binary-mux @ :7272 (local)
│ or NaCl-box through the relay (remote)
┌────────┴────────┐
│ ARC Daemon │
│ │
│ HTTP /health ──┤
│ WS binary-mux │
│ │
│ ┌───────────┐ │
│ │ Router │ │
│ │ Hub (subs)│ │
│ │ RPC │ │
│ │ Agent Mgr │──┼──► adapters spawn CLIs
│ │ Chat │ │ (claude / codex / gemini / ...)
│ │ Orchestr. │ │
│ │ Hook bus │ │
│ │ Profile │ │
│ │ registry │ │
│ └────┬──────┘ │
└───────┼─────────┘
┌─────────┴──────────┐
│ ~/.arc/ │
│ arc.db (SQLite)│
│ auth.json │
│ daemon.log │
│ daemon.pid │
│ profiles/… │
│ shared/… │
└────────────────────┘
```

## Package responsibilities

| Package | Role |
|----------------------------------|-------------------------------------------------------------------------------------------|
| `@axiom-labs/arc-core` | Agent adapters, agent-client, orchestration, hooks, knowledge, tool registry. **Unchanged from v2**: daemonising is purely a shell around it. |
| `@axiom-labs/arc-daemon` | Long-running process. HTTP + WS bind, router, RPC handlers, Hub (subscriptions), SQLite, structured logger, auth. Owns every agent lifecycle. |
| `@axiom-labs/arc-client` | Wire-protocol SDK — frame codec, Zod envelope, typed RPC wrappers, subscription helpers, auto-reconnect. Shared by every UI surface. |
| `@axiom-labs/arc-cli` | Commander.js CLI. `arc daemon …` lifecycle commands, typed client wrappers around remote ops, legacy passthrough for v2-only commands. |
| `@axiom-labs/arc-dashboard` | Web SPA. Reads from the daemon over WebSocket; no direct adapter spawn any more. |
| `@axiom-labs/arc-relay` | Stateless, zero-knowledge WebSocket multiplexer for remote daemon access. Placeholder in Phase 1 — ships in Phase 10. |
| `@axiom-labs/arc-adapter-claude` | Claude Code adapter — SDK bridge, auth, detect, import, shared. |
| `@axiom-labs/arc-adapter-openclaw` | OpenClaw adapter — plugin manifest, hooks, tools. |
| `@axiom-labs/arc-mcp` | ARC as an MCP server + host manager. |

## Data flow: client → daemon → adapter → agent

A typical `agents.run` request follows this path:

```
┌─ client (TUI / CLI / dashboard / mobile)
│ 1. client.connect() → WS open → auth.login request
│ ← auth.login response { sessionId, ... }
│ 2. client.agents.run({ profile, prompt, cwd, ... })
│ └─ encodes Envelope { type: "request", method: "agent.run", params }
│ as a Control frame (channel 0x00)
│ sends over the WebSocket binary message
┌─ daemon
│ 3. ws/connection.ts reads the binary message,
│ frame.ts decodes channel 0x00 → envelope JSON
│ Zod parses Envelope → { id, type, method, params }
│ 4. router.ts dispatches:
│ - auth gate (requires authenticated session)
│ - rpc/agent.ts → agentRun handler
│ - handler validates AgentRunParams, writes `agents` row in SQLite,
│ tells the Agent Mgr to spawn via the profile's adapter
│ 5. Agent Mgr (Phase 4) spawns the adapter process in worker mode,
│ attaches stdout/stderr/tool-call streams, records agent_events rows.
│ 6. Hub fan-out:
│ - `agents` topic: list-churn event (agent started)
│ - `agent:<id>` topic: stream of stdout / status / tool-call events
│ - responses for future `agent.send` calls go back on the same sock
┌─ subscribers
│ 7. Any client holding a `subscribe(topic: "agent:<id>")` receives `event`
│ envelopes carrying the recorded payload — terminal frames on channel
│ 0x01 bypass JSON entirely and land raw in the client's renderer.
└─ Client also receives the `response` envelope for request (2) with
{ agentId } as soon as the agent is registered.
```

Agent lifecycle state, event history, chat messages, and paired-client
tokens all live in `arc.db`. Restarting the daemon (or reconnecting a
client) replays state from SQLite rather than memory.

## Key properties

- **Agent survival across UI disconnect.** The daemon owns the child
process, not the UI. Closing the TUI leaves the agent running.
- **Single protocol, many clients.** Every surface uses the same
`@axiom-labs/arc-client` SDK. Local vs. remote is a URL difference
only.
- **Additive-only schema.** Wire protocol rules (see
[protocol.md](./protocol.md#versioning-and-backward-compat)) and SQLite
migrations are additive-only inside a major version. Clients pinned to
`v: 1` keep working as methods and topics accrete.
- **No polling.** UIs receive change events through subscriptions. There
is no "refresh" endpoint; the daemon pushes.
- **Loopback-first security.** The daemon refuses non-loopback hosts;
every paired client carries an argon2-hashed bearer token; remote
access goes through the relay with NaCl-box on every frame.

## Further reading

- [Daemon operator guide](./daemon.md) — lifecycle, env vars, filesystem,
troubleshooting.
- [Wire protocol spec](./protocol.md) — frame format, envelopes, method
catalog, error codes, backward-compat rules.
- [v2 → v3 migration](./v2-to-v3-migration.md) — moving from the
pre-daemon layout.
- Plan of record: [`docs/plans/arc-v3-daemon.md`](./plans/arc-v3-daemon.md).
Loading
Loading