CoreLayer Docs
Architecture

System Overview

How CoreLayer fits together: the Tauri shell, the Node.js daemon, the registered runtimes, and the execution pipeline.

CoreLayer is a local-first desktop Agent OS. A Tauri shell hosts the UI and supervises a Node.js daemon; the daemon owns every runtime, every tool call, and every piece of persisted state.

This page describes what the running system actually contains. For the long-term direction, see Multi-Runtime Direction.

Topology

┌──────────────────────────────────────────────────────────────┐
│ Tauri Desktop Shell (Rust)                                   │
│   ├─ Webview UI (React 19 + Vite + Tailwind)                 │
│   ├─ Daemon supervisor: spawn / health / restart / shutdown  │
│   └─ HTTP proxy → localhost daemon                           │
└───────────────────────────┬──────────────────────────────────┘
                            │ HTTP (loopback, port 3001 by default)
┌───────────────────────────┴──────────────────────────────────┐
│ Node.js Daemon (TypeScript + Hono)                           │
│                                                              │
│  Runtime host (registry · lifecycle · status)                │
│   ├─ agent        — conversation loop, tool calling          │
│   ├─ tool         — registry, routing, native tools          │
│   ├─ coding       — executor adapters, worktrees, gates      │
│   ├─ memory       — long-term memory + snapshots             │
│   ├─ voice        — wake word, ASR, TTS, barge-in            │
│   └─ scheduler    — cron-driven autonomous work              │
│                                                              │
│  Workflow plane                                              │
│   ├─ run dispatcher / queue / slot manager                   │
│   ├─ delegation (monotonic narrowing)                        │
│   ├─ task graph DAG executor                                 │
│   └─ adjudication (adversarial judge)                        │
│                                                              │
│  Cross-cutting                                               │
│   ├─ Permission guard + approvals (HITL)                     │
│   ├─ Audit + event log                                       │
│   └─ Persistence (SQLite by default; Supabase / PostgreSQL)  │
└──────────────────────────────────────────────────────────────┘

Layers

Frontend (React)

Renders conversations, workspaces, runs, approvals, and settings. Talks to the daemon only through the Tauri bridge; it never opens a database or a provider connection itself.

Tauri bridge (Rust)

Spawns and supervises the daemon sidecar, forwards HTTP calls, and provides native capabilities (paths, window, tray). All IPC commands are explicitly registered.

Daemon (Node.js)

The only component with authority. It holds the runtime registry, assembles context, calls models through the Model Gateway, executes tools behind the Permission Guard, and persists everything through the repository layer.

Shared packages

The daemon composes eight workspace packages rather than duplicating their logic:

PackageRole
@jarvis/typesShared TypeScript types
@jarvis/model-gatewayProvider resolution and model routing
@jarvis/mcp-clientMCP server connections (stdio, HTTP, SSE)
@jarvis/tool-registryTool catalog and resolution
@jarvis/permission-guardRisk classification, policy, audit
@jarvis/runtime-coreRuntime lifecycle primitives
@jarvis/runtime-protocolRuntime contract definitions
@jarvis/execution-environmentExecution abstraction (worktree-backed)

What is registered

Runtime registration lives in daemon/src/runtimes/index.ts. Six runtimes are registered with the runtime host and report status through GET /api/runtime/components:

agent, tool, coding, memory, voice, scheduler.

Computer control is not registered. Its risk, permission, and audit layers exist and its tools are defined, but the execute path still returns without touching the OS and no Rust-side capability backs it. Registering it would advertise a runtime that silently does nothing, so it stays out of the host until a real implementation lands. Treat any documentation that lists it as a live runtime as incorrect.

Communication

User input
  → React frontend
  → Tauri IPC
  → Rust daemon supervisor (HTTP proxy)
  → Hono route (/api/conversations/:id/messages/stream, /api/chat/stream, …)
  → agent runtime: context assembly → model → tool calls → completion policy
  → SSE / JSON response back along the same path

Long-running work does not block a chat turn: the run dispatcher persists an agent_run, the queue holds a slot for it, and events are written to the event log as it progresses. Clients read them through GET /api/events and GET /api/runs/:id/events.

Next Steps

On this page