Gini Architecture Overview
Gini is organized around one stateful runtime gateway and many replaceable clients.
For deeper topic docs, see Gateway And Control Plane, Conversation And Runs, Memory, and Runtime Capabilities.
One Sentence
Gini’s runtime is the gateway: a single Bun process per instance owns all durable state and performs all real work. Every other surface consumes the same authenticated /api/* contract.
Picture
┌─────────────────────────────────┐
│ GATEWAY (server) │
│ │
│ Bun runtime, one per instance │
│ │
│ • agent loop │
│ • tool execution │
│ • memory.db (SQLite) │
│ • state.json │
│ • traces, audit, events │
│ • bearer-token auth │
│ │
│ /api/* (HTTP + SSE) │
└────────────────┬────────────────┘
│
┌───────────────────────────────────┼───────────────────────────────────┐
│ │ │
│ token server-side only │ paired-device token │ bearer token
│ │ │
┌───────┴───────┐ ┌────────┴────────┐ ┌───────┴────────┐
│ Next.js │ │ Expo mobile │ │ CLI │
│ BFF + UI │ │ app │ │ scripts │
│ │ │ │ │ MCP clients │
│ one per │ │ user pastes │ │ │
│ instance │ │ URL + token, │ │ direct API │
│ localhost │ │ AsyncStorage │ │ client │
└───────┬───────┘ └─────────────────┘ └────────────────┘
│
│ HTML / JS / SSE
│
┌────┴────┐
│ browser │
│ never │
│ sees │
│ token │
└─────────┘Components
Gateway
- Single source of truth for tasks, conversations, runs, jobs, memory, skills, authorizations, setup requests, audit, traces, and events.
- One process per instance.
- Authenticated HTTP API plus SSE event stream.
- JSON state for broad runtime records and SQLite for memory.
- Starts from
src/server.ts.
Next.js Control Plane
- Lives in
web/. - Browser talks to
/api/runtime/*. - Server-side BFF attaches the gateway bearer token.
- Uses the same API that CLI and future clients use.
- Can be disabled with
--no-webfor smoke and runtime-only testing.
CLI
- Entry shim:
src/cli.ts. - Command implementation:
src/cli/. - Reads instance config and calls the gateway API.
- Also owns local process management for install/start/run/stop/smoke workflows.
- The
gini import apply openclawmigrator is the one documented exception to “all writes go through the gateway.” It refuses to run while the instance’s gateway is alive (see Openclaw Migration ) and writes directly tostate.json,secrets.env, workspace files, skills, andmemory.dbthrough the in-processmutateStatepath. Single-process serialization is what makes the offline-only constraint necessary.
Future Clients
Mobile, MCP, messaging bridges, and scripts should connect through the gateway contract. Clients that can safely hold a token may call the gateway directly. Browser clients should go through a BFF.
Why This Shape
- Single source of truth. Reloading the web app, running a CLI command, and opening a future mobile app all observe the same runtime state.
- Clear token boundary. The browser never receives a bearer token. Local clients that can safely store credentials can hold their own tokens.
- Replaceable clients. New surfaces do not require a second backend or a duplicated state model.
- Parallel agent support. Instances isolate ports, state, logs, workspaces, and runtime processes.
Storage
~/.gini/
├── instances/
│ └── <instance>/
│ ├── config.json
│ ├── state.json
│ ├── memory.db
│ ├── runtime.pid
│ ├── runtime.port
│ ├── web.pid
│ ├── web.port
│ ├── traces/
│ ├── snapshots/
│ ├── skills/
│ ├── workspace/
│ ├── imports/
│ └── logs/
└── models/<instance>/imports/ holds verbatim archives of source state taken before any importer (currently only gini import apply openclaw) mutates the destination instance. The archives can contain plaintext provider keys, bot tokens, session transcripts, and memory units — they are retained as a manual restore path and never auto-purged. Treat them with the same care as the active state. See Openclaw Migration for the format.
API Surface
The current capability map is in Runtime Capabilities. Common surfaces include:
/api/status,/api/healthz,/api/state/api/version,/api/update/check,/api/update/api/tasks,/api/chat,/api/runs,/api/authorizations,/api/setup-requests/api/memory/retain,/api/memory/recall,/api/memory/reflect,/api/memory/units,/api/memory/banks,/api/embedding/*,/api/reranker/status/api/skills,/api/jobs,/api/connectors,/api/toolsets/api/pairing,/api/devices,/api/mobile/bootstrap/api/messaging,/api/mcp,/api/subagents,/api/agents/api/audit,/api/events,/api/events/stream/api/parity/hermes,/api/readiness/v1
Not Yet Built
- Production relay for off-LAN access.
- Push notification delivery.
- LaunchAgent-style auto-start.
A basic Expo mobile client lives under mobile/ — agent picker, per-agent chat list, and chat detail with task polling. It speaks the same /api/* contract directly with its own bearer token (no BFF), so it does not change the runtime/source-of-truth model.
Those should build on the existing gateway contract rather than changing the runtime/source-of-truth model.