Architecture
Clew is a terminal-based AI coding assistant — a React/Ink TUI, Commander.js CLI, multi-provider AI engine, and extensible tool/plugin runtime all in one process.
Layered Design
The application is structured as four cooperative layers:
1. Terminal UI (React 19 + Ink 6)
Renders the interactive REPL: prompt input, streaming markdown output, status bar with context meter, arc spinner, permission dialogs, file explorer, inline images, buddy (duck) companion, and fullscreen mode. Components live in src/components/, state management in src/state/, and React context in src/context/.
2. CLI & Command Layer (Commander.js 13)
Entry point at src/main.tsx — parses CLI flags (--model, --print, --permission-mode, --mcp-config, etc.), loads config, initializes providers and telemetry, then launches the REPL or print-mode query. Slash commands are registered in src/commands.ts and implemented under src/commands/. Commands are categorized as local (runs in-terminal), prompt (skills that expand to text), or local-jsx (Ink UI panels).
3. AI Provider & Adapter Layer
ProviderManager (src/services/ai/ProviderManager.ts) resolves API keys, selects models, and manages provider config. Provider metadata is declared in src/services/ai/providers.json — currently 32 providers (9 dedicated classes + 23 OpenAI-compatible) with model listings, capabilities, base URLs, and env key mappings. Non-Anthropic providers are wrapped by the AnthropicAdapter or GoogleAdapter, which normalize content blocks (contentBlockUtils.ts), tool calls (toolCallParser.ts), errors (errorNormalizer.ts), and usage (usageNormalizer.ts) to a uniform format.
4. Tool Execution & Query Loop
Tools use Zod schemas and are executed by the StreamingToolExecutor (src/services/tools/StreamingToolExecutor.ts). Permission gating via hooks in src/utils/permissions/permissions.ts. The query loop in src/query.ts + src/QueryEngine.ts orchestrates message building, context management, streaming, and tool call cycling. MCP tools (src/services/mcp/) are discovered at runtime and merged into the tool pool.
Data Flow
Terminal input
|
v
+ Query Engine (query.ts + QueryEngine.ts)
| Message building and context assembly
| Tool call loop (model tool results)
| Streaming response handling
|
+ Provider Manager Adapter AI Model API
| 27 providers via providers.json
| AnthropicAdapter / GoogleAdapter normalization
|
+ Tool Executor (StreamingToolExecutor)
| Permission check (permissions.ts)
| Pre/Post tool hooks (plugins)
| Tool execution result
|
+ Terminal UI (React/Ink)
Streaming text and tool renders
Status bar, spinner, context meter
Permission dialogs
Key Subsystems
MCP (Model Context Protocol)
src/services/mcp/ — manages external MCP server connections, tool discovery, resource access, and paginated tools/list responses. Servers configured via --mcp-config or /mcp command. See MCP for detailed setup and configuration.
Plugins & Hooks
src/services/plugins/ — plugin loading, installation, marketplace reconciliation, and hook dispatch. Hook points: PreToolUse, PostToolUse, PreBash, PostPrompt, PreAcceptEdit. Plugins can provide commands, agents, skills, MCP servers, and LSP integrations.
LSP (Language Server Protocol)
src/services/lsp/ — language-aware code intelligence via LSP servers. Diagnostics, completions, and symbol navigation. Enable with ENABLE_LSP_TOOL=1.
Bridge Mode
src/bridge/bridgeMain.ts — WebSocket remote control and collaboration. Gated behind BRIDGE_MODE=1. Remote clients can send commands and receive responses.
Session System
src/services/SessionLifecycle/ — cross-session context persistence. src/services/SessionMemory/ — persistent knowledge with cross-lingual semantic search and auto-memory capture.
GrowthBook Feature Flags
src/services/analytics/growthbook.js — A/B testing and feature flag platform. Initialized at startup, evaluates flags locally with caching.
Agent Runtime
src/agentRuntime/ — manages multi-agent orchestration. The orchestrator coordinates agent sessions, runStore persists agent run data, toolGateway routes tools between agents, and workflowRegistry / agentRegistry declare named workflows and agent configurations.
Autonomous / Daemon
src/services/autonomous/ — enables 24/7 background execution. The taskQueue is a file-backed queue with priorities, leases, and dead-letter handling. agentLoop runs the continuous dequeue spawn worker monitor retry cycle. daemonMode provides the supervisor-managed background process entry point, and supervisorIntegration handles health checks and auto-respawn. See Daemon Mode for detailed configuration and usage.
Coordinator (Multi-Agent)
src/coordinator/ — supports multi-agent collaboration. coordinatorMode delegates tasks to sub-agents, and workerAgent provides standalone workers for delegated subtasks.
Memory
src/memory/ — local embedding-free memory with SQLite FTS5 full-text search. Token-aware chunking (3000 tokens), truth priority scoring, secret redaction, and auto-ingest from .claude/memory/. See Memory for detailed usage.
Voice Mode
src/voice/ — compile-time gated voice input support (VOICE_MODE=1). Provides speech-to-text and voice command processing for hands-free operation.
State Management
The app uses a lightweight observable store pattern (createStore<T> in src/state/store.ts). Stores are plain functions with getState, setState, and subscribe. React components subscribe via the AppState React context (src/state/AppState.tsx).
Important Source Paths
| Path | Role |
|---|---|
src/main.tsx | CLI entry, Commander program, option parsing, REPL launch |
src/query.ts | Core query processing, message building, tool call loop |
src/QueryEngine.ts | Query orchestration, caching, deduplication, rate limiting |
src/commands.ts | Slash command registry (80+ commands) |
src/tools.ts | Tool registry (40+ built-in tools) |
src/Tool.ts | Base tool types, schemas, buildTool() helper |
src/services/ai/ProviderManager.ts | Provider selection, API key resolution |
src/services/ai/providers.json | Declarative provider config (27 providers) |
src/services/ai/adapter/ | AnthropicAdapter, GoogleAdapter |
src/services/tools/StreamingToolExecutor.ts | Streaming tool execution |
src/utils/permissions/permissions.ts | Permission evaluation logic |
src/services/mcp/ | MCP server management |
src/services/plugins/ | Plugin loader and hook dispatch |
src/state/store.ts | Lightweight observable store (createStore<T>) |
src/state/AppState.tsx | Root app state (React context) |
src/state/AppStateStore.ts | App state store implementation |
src/state/selectors.ts | State selectors |
src/agentRuntime/ | Agent orchestration, run store, tool gateway |
src/services/autonomous/ | Task queue, agent loop, daemon mode, supervisor |
src/coordinator/ | Multi-agent coordinator and worker agents |
src/research/ | Deep research, dossier generation, truth checking |
src/memory/ | SQLite FTS5 memory search (14 files) |
src/voice/ | Voice mode support (compile-time gated) |
src/entrypoints/init.ts | Startup initialization (Sentry, configs, telemetry) |
src/entrypoints/cli.tsx | Alternative CLI entry point (Commander-based) |
src/entrypoints/mcp.ts | MCP server entry point |
Build System
Built with Bun bundler — bun run build outputs a single binary to dist/. TypeScript with strict mode and ESM/NodeNext module resolution. External dependencies include Electron, chromium-bidi, AWS SDK, Google Auth, and platform-specific native modules. Lint/format via Biome 2.4.