Routa.js is a workspace-first multi-agent coordination platform with two runtime surfaces:
- Web: Next.js app and API in
src/ - Desktop: Tauri app in
apps/desktop/backed by Axum incrates/routa-server/
The project is intentionally not "two separate products". Web and desktop differ in deployment model and storage, but they are expected to preserve the same domain semantics, API shape, and agent-coordination behavior.
- Workspace-first: workspaces are the top-level coordination boundary for sessions, tasks, notes, boards, codebases, worktrees, and memories.
- Dual-backend parity: Next.js and Rust expose the same product concepts and should stay aligned with
api-contract.yaml. - Protocol-oriented orchestration: REST, MCP, ACP, A2A, AG-UI, and SSE are all first-class integration surfaces.
- Local-first execution: desktop mode favors SQLite, local agent binaries, local worktrees, and trace files.
- Provider abstraction: different agent CLIs and runtimes are normalized behind adapter layers instead of leaking provider-specific protocol details through the system.
| Area | Purpose |
|---|---|
src/app/ |
Next.js App Router pages and API routes |
src/client/ |
Client components, hooks, view models, A2UI helpers |
src/core/ |
TypeScript domain logic: stores, ACP/MCP, kanban automation, workflows, notes, tools |
apps/desktop/ |
Tauri shell and desktop packaging |
crates/routa-core/ |
Shared Rust domain/runtime foundation: stores, ACP manager, sandbox, skills, events |
crates/routa-server/ |
Axum HTTP API for desktop/local server mode |
crates/routa-cli/ |
CLI entrypoints and ACP serving commands |
crates/routa-rpc/ |
RPC contract helpers |
crates/routa-scanner/ |
Codebase scanning utilities |
docs/ |
Durable architecture, design intent, plans, fitness guidance |
- Next.js serves pages under
src/app/. - API handlers in
src/app/api/use the TypeScriptRoutaSystemfromsrc/core/routa-system.ts. RoutaSystemselects storage by environment:DATABASE_URL-> Postgres-backed storesROUTA_DB_DRIVER=sqliteor local Node runtime -> SQLite-backed stores- fallback -> in-memory stores
- Real-time updates are delivered mainly through SSE endpoints and in-process event broadcasting.
- Tauri hosts the UI and starts the embedded Axum server from
crates/routa-server/src/lib.rs. - Shared application state is built in
crates/routa-core/src/state.rs. - The Rust backend owns local SQLite persistence, ACP runtime management, Docker-assisted agent execution, sandbox management, and local file/worktree operations.
- Tauri static export placeholders are a routing implementation detail, not part of the domain model.
Both runtimes follow the same layered shape even though the concrete implementation differs:
Presentation
React pages, workspace views, session detail, kanban, settings, traces
API / Transport
Next.js route handlers or Axum routers
Protocol Adapters
REST, MCP, ACP, A2A, AG-UI, SSE, JSON-RPC normalization
Domain Services
orchestration, kanban automation, workflow execution, notes, review, scheduling,
trace, harness, shared sessions, worker dispatch
Stores / Registries
workspace, task, session, note, codebase, worktree, schedule, artifact, skill
Persistence / Runtime
Postgres, SQLite, in-memory, JSONL traces, local processes, Docker, filesystem
Dependency direction should stay downward. UI and transport layers depend on domain services; stores and runtime layers should not depend on UI concerns.
Workspace is the primary user-visible scope. Users navigate by workspace first and then inspect sessions, boards, notes, tasks, codebases, or memories within that scope.
Current canonical background:
Important invariant:
- New product surfaces should require explicit workspace context unless they are deliberate bootstrap flows.
- A workspace can own multiple codebases.
- A codebase models repo identity and metadata such as path, branch, label, and default status.
- Worktrees are ephemeral or semi-persistent execution copies tied to a workspace and codebase.
- File search, sandbox resolution, and repo selection should flow through codebase/worktree context instead of hidden global repo state.
- A session represents a live or historical agent execution thread.
- Sessions are workspace-scoped and power the session detail page, trace views, and automation status.
- Session history may live in database rows and/or JSONL traces depending on runtime.
- ACP is the primary execution transport for agent CLIs, but some providers require adapter translation.
- Tasks are the durable work units.
- Kanban is not just a UI projection; it also drives lane-based automation and queueing.
- Column transitions can trigger fresh ACP sessions and enrich tasks with provider/role/session metadata.
- The TypeScript queue in
src/core/kanban/kanban-session-queue.tsenforces per-board concurrency and prevents stale auto-run entries from re-firing incorrectly.
- Background tasks model durable async work such as scheduled runs, polling-triggered actions, or workflow fan-out.
- Workflows convert a higher-level automation definition into multiple background tasks with dependency ordering.
- Schedule ticks, webhook events, and polling adapters can all enqueue background tasks instead of invoking execution inline.
- Traces record session lifecycle, messages, tool calls, file changes, and VCS context for audit and debugging (
src/core/trace/,crates/routa-core/src/trace/). - Trace data is a first-class debugging and attribution mechanism, not an incidental log stream.
- Review provides multi-phase code review with findings, severity, and validation context (
src/core/review/).
- Harness detects repository signals, script entrypoints, and spec sources to power governance and quality analysis (
src/core/harness/). crates/harness-monitoris documented as a four-layer harness loop ofContext -> Run -> Observe -> Govern; stable records remainTask / Run / Workspace / EvalSnapshot / PolicyDecision / Evidence, and CLI/TUI still consume one shared run assessment path.- Workers abstract local and Docker-based execution environments (
src/core/worker/). - Sandbox policy resolution in Rust enforces workspace-aware Docker constraints (
crates/routa-core/src/sandbox/).
- Notes support collaborative knowledge capture and use CRDT-based real-time behavior on the TypeScript side.
- Memory endpoints store workspace-scoped contextual records.
- Artifacts are structured outputs exchanged between agents, workflows, or coordination tools.
- Shared sessions enable multi-user or multi-agent coordination with event broadcasting and prompt dispatch (
src/core/shared-session/).
src/core/routa-system.ts is the central assembly point for the Next.js runtime. It wires:
- stores for agents, conversations, tasks, notes, workspaces, codebases, worktrees, schedules, kanban boards, background tasks, workflow runs, and artifacts
EventBusfor in-process coordination- MCP-facing tool surfaces such as
AgentTools,NoteTools, andWorkspaceTools - note broadcasting and CRDT document management
- permission storage used by runtime permission delegation flows
This file is the TypeScript equivalent of a service container. New domain services should usually be introduced here rather than instantiated ad hoc inside route handlers.
crates/routa-core/src/state.rs plays the same role for the Axum server. It wires:
- core stores including workspace, codebase, worktree, task, note, kanban, conversation, artifact, schedule, and ACP session stores
AcpManager, binary/runtime/warmup managers, and ACP path resolutionSkillRegistryEventBusSandboxManager- Docker detection and process management
This keeps desktop/server execution local-first while preserving the same domain vocabulary as the web runtime.
| Protocol | Primary endpoints | Role |
|---|---|---|
| REST | /api/* |
CRUD and product-facing operations |
| MCP | /api/mcp, /api/mcp/tools |
tool execution and collaborative agent capabilities |
| ACP | /api/acp and related runtime/registry/docker routes |
spawn, prompt, stream, install, warm up, and manage agent runtimes |
| A2A | /api/a2a/* |
agent-to-agent interoperability |
| AG-UI | /api/ag-ui |
UI-facing agent stream protocol |
| A2UI | /api/a2ui/* |
dashboard-oriented UI protocol surfaces |
| SSE | ACP, notes, AG-UI, and related endpoints | incremental updates to the frontend |
The product surface changes often. For endpoint inventory, use docs/product-specs/FEATURE_TREE.md rather than expanding this document into an API catalog.
ACP is the main execution protocol for coding agents, but providers do not behave identically.
The normalization pattern is:
Provider process or bridge
-> provider-specific output / notifications
-> adapter normalization
-> unified session updates
-> persistence, traces, and UI streaming
Current provider/runtime concerns include:
- standard ACP-compatible CLIs
- Claude Code style stream-json flows that must be translated into ACP-like updates
- Docker-backed OpenCode execution paths
- runtime installation, warmup, and registry discovery
The Rust ACP subsystem lives under crates/routa-core/src/acp/, while the web runtime keeps corresponding process and route logic under src/core/acp/ and src/app/api/acp/.
There are two main real-time mechanisms:
- transport-level streaming: mainly SSE for session, note, and protocol updates
- in-process eventing:
EventBusin both TypeScript and Rust runtimes
These support:
- agent lifecycle tracking
- kanban auto-run queue draining
- note change propagation
- workflow and background-task coordination
- UI refresh triggers for session and trace surfaces
- Primary persistent target is Postgres when
DATABASE_URLis configured. - SQLite is supported for local Node development.
- In-memory mode remains available for tests and lightweight runtime scenarios.
- SQLite is the normal persistent store.
- Filesystem state is also part of persistence: session JSONL traces, repos, worktrees, agent binaries, and local config.
- Session and trace history may be stored in database records, JSONL files, or both depending on runtime.
- Trace data is a first-class debugging and attribution mechanism, not an incidental log stream.
The Axum router in crates/routa-server/src/api/mod.rs shows the breadth of the desktop/server backend. In addition to the core workspace/session/task APIs, it includes:
- ACP registry, runtime, and Docker routes
- Kanban and worktree routes
- MCP server management
- clone, files, and GitHub import/search helpers
- schedules, polling, webhooks, workflows, and background tasks
- sandbox and review endpoints
This breadth is intentional: the desktop backend is not a thin transport shim. It is a full local coordination runtime.
The repository is still finishing the workspace-centric normalization. The durable status lives in docs/design-docs/workspace-centric-redesign.md, but the key architecture caveat is:
- some paths still fall back to
"default"when workspace scope is omitted - some bootstrap/runtime flows still assume a default workspace exists
- not every persistence-backed implementation is fully symmetric yet across TypeScript and Rust
- some workflow-run persistence remains in-memory even when other stores are persistent
Treat "default" as transition scaffolding, not as the target domain model.
The docs/adr/ directory captures durable architectural decisions that shape boundaries, protocols, and patterns across the codebase. ADRs are the canonical answer to "why is it built this way?"
Discover decisions via: claude -p "What ADRs exist and what do they decide?"
Current ADRs:
- Product/API index: docs/product-specs/FEATURE_TREE.md
- Architecture decisions: docs/adr/
- Design intent: docs/design-docs/
- Coding style: docs/coding-style.md
- Repository operating contract:
AGENTS.md(repo root) - MCP Spec · ACP Spec · A2A Spec
