How baiganio/aperio works
1. Aperio is a self-hosted Node.js memory layer for agents, not a standalone chat product. The core runtime exposes three faces over the same backend: a browser UI, a terminal chat client, and an MCP server for external tools and IDE agents.
2. server.js is the main app entrypoint. It ties together the HTTP API, WebSocket streaming, the agent loop, and the web UI in public/. The MCP server lives separately in mcp/index.js, so remote agents can use the same memory and code tools without going through the UI.
3. Persistence is centralized in db/. db/index.js auto-selects SQLite or Postgres, with SQLite as the default single-file store and Postgres used when Docker/production mode is available. Both backends share the same logical schema via migrations, and the store holds memories, wiki articles, code graph data, and embeddings metadata.
4. The memory subsystem is the main semantic store. lib/handlers/memory/ implements remember/recall/update/forget flows, while lib/helpers/embeddings.js, lib/helpers/embedding-queue.js, and lib/workers/deduplicate.js handle vectorization, backfilling, and near-duplicate cleanup. Semantic search is paired with full-text search in the database.
5. The wiki subsystem is a second knowledge layer, distinct from raw memories. lib/handlers/wiki/ supports article creation, search, retrieval, and regeneration, so the agent can maintain longer-form, cited synthesis rather than only short memory records. It uses the same backing store but a different retrieval and authoring path.
6. Aperio’s code graph is a pre-indexed source knowledge system. lib/codegraph/ extracts symbols, calls, imports, and inheritance edges from code, using tree-sitter-based extractors for JS/TS/JSX/TSX and watcher-driven incremental reindexing. The code_* MCP tools query this graph for callers, callees, outlines, and symbol context.
7. The document graph complements the code graph for non-code files. lib/docgraph/ and lib/handlers/docgraph/ ingest PDFs, DOCX, PPTX, XLSX, HTML, EML, and Markdown, chunk them, extract references, and store them for search. Attachment preprocessing workers normalize PDFs and images before they are handed to local vision or extraction steps.
8. Agent behavior is orchestrated in lib/agent/, lib/workers/, and lib/tools/. Model providers are pluggable: Ollama is the local default, with Anthropic, DeepSeek, and Gemini supported as cloud alternatives. The agent layer also manages tool hooks, tool profiles, reasoning/roundtable workers, and context trimming via lib/context/.
9. The UI layer is a static frontend in public/ with panels for sessions, settings, wiki, code graph, database status, and streaming activity. It talks to the backend through API calls and WebSocket events, and the same stream is also surfaced in the terminal client through emitter abstractions in lib/emitters/.
10. Security is enforced at the path boundary, not inside the model. lib/routes/paths.js validates read/write locations against allow-lists, and shell execution is heavily gated in mcp/tools/shell.js. The default execution model is conservative: file access is scoped, writes are restricted, and shell commands are opt-in and allow-listed.
11. There is an optional two-agent “roundtable” path. When configured, a primary and verifier persona from id/whoami-primary.md and id/whoami-verifier.md can cross-review a turn before the result is returned, with the UI exposing a Discuss toggle and the backend running the revise/re-review loop in lib/workers/roundtable.js.
12. The skills/ directory is not a runtime service; it is a library of task-specific playbooks and assets that shape how agents behave and how certain document/code generation workflows are performed. In architecture terms, it is an instruction and tooling layer wrapped around the same core memory/graph backend.
Main entry points: db/index.js Database · mcp/index.js MCP Server · agent/index.js Agent Core · server.js Server
Components 29
Runtime
Entrypoints and service surfaces
- Server · HTTP API, WebSocket streaming, agent loop, and web UI host
server.js - MCP Server · Separate Model Context Protocol entrypoint for external tools and IDE agents
mcp/index.js - API Routes · Backend request surface for UI and clients
lib/routes/api.js
Storage
Persistence and schema management
- Database · Auto-selects SQLite or Postgres and exposes the shared store
db/index.js - SQLite · Single-file default store and SQLite-specific migrations
db/sqlite.js - Postgres · Production/Docker database backend for the same schema
db/postgres.js - Migrations · Shared logical schema for memories, wiki, code graph, and embeddings metadata
db/migrations
Knowledge
Memory, wiki, and graph indexes
- Memory API · Remember, recall, update, and forget handlers
lib/handlers/memory/memoryHandlers.js - Embeddings · Vectorization helpers for semantic retrieval
lib/helpers/embeddings.js - Embedding Queue · Queues and backfills embedding work
lib/helpers/embedding-queue.js - Dedup Worker · Finds and removes near-duplicate memories
lib/workers/deduplicate.js - Wiki API · Article create, search, retrieve, and regenerate paths
lib/handlers/wiki/wikiHandlers.js - Code Graph · Extracts symbols, calls, imports, and inheritance edges
lib/codegraph/indexer.js - Code Watcher · Watcher-driven updates for source graph indexing
lib/codegraph/watcher.js - Doc Graph · Ingests and chunks PDFs, Office docs, HTML, email, and Markdown
lib/docgraph/indexer.js - Doc Watcher · Watches and refreshes non-code document graph content
lib/docgraph/watcher.js - Attachments · Normalizes PDFs, images, and Office attachments before extraction
lib/handlers/attachments/index.js
Agent
Model orchestration and tool use
- Agent Core · Coordinates turns, tools, provider calls, and context management
lib/agent/index.js - Providers · Pluggable model backends including Ollama, Anthropic, DeepSeek, Gemini, and Claude Code
lib/agent/providers - Tool Hooks · Tool profiles, hook logic, and activity tracking
lib/agent/tool-hooks.js - Context Trim · Builds and trims agent context from the RAG store
lib/context/trim.js - Reasoning · Inference, reasoning, and roundtable execution workers
lib/workers/reasoning.js - Roundtable · Primary/verifier revise-and-review loop for optional cross-checking
lib/workers/roundtable.js
UI
Web and terminal surfaces
Safety
Boundary checks and execution controls
- Path Guard · Allow-list validation for read/write file paths
lib/routes/paths.js - Shell Tool · Restricted shell execution for MCP tool use
mcp/tools/shell.js
Skills
Instruction and workflow assets
- Skills · Task playbooks and workflow assets that shape agent behavior
skills
Connections 33
- Server → API Routes: serves · Hosts HTTP endpoints for clients and UI
- Server → Emitters: streams · Pushes events over WebSocket-backed emitters
- Server → Agent Core: runs · Main app drives the agent loop
- Server → Web UI: hosts · Serves the browser frontend
- MCP Server → Memory API: tools · Exposes memory actions through MCP
- MCP Server → Code Graph: tools · Exposes code graph queries through MCP
- MCP Server → Doc Graph: tools · Exposes document graph queries through MCP
- MCP Server → Wiki API: tools · Exposes wiki operations through MCP
- MCP Server → Shell Tool: uses · Gated shell execution for remote tool runs
- Database → SQLite: selects · Uses SQLite by default when not in production/Docker mode
- Database → Postgres: selects · Uses Postgres when available
- Database → Migrations: applies · Initializes the shared schema
- Memory API → Database: stores · Reads and writes memories through the persistence layer
- Memory API → Embeddings: vectorizes · Computes embeddings for semantic recall
- Memory API → Embedding Queue: queues · Schedules backfill and embedding work
- Embedding Queue → Dedup Worker: feeds · Supports cleanup and backfill maintenance
- Wiki API → Database: stores · Persists article content and retrieval metadata
- Code Graph → Database: stores · Writes graph data and symbol metadata
- Code Graph → Code Watcher: refreshes · Watcher keeps source graph incrementally current
- Doc Graph → Database: stores · Writes document chunks, refs, and search metadata
- Doc Graph → Doc Watcher: refreshes · Watcher keeps document graph current
- Attachments → Doc Graph: prepares · Normalizes attachments before document ingestion
- Agent Core → Providers: calls · Delegates model requests to pluggable providers
- Agent Core → Tool Hooks: controls · Applies tool policies and activity tracking
- Agent Core → Context Trim: trims · Builds bounded context for each turn
- Agent Core → Reasoning: delegates · Uses workers for inference and orchestration tasks
- Reasoning → Roundtable: optionally · Can route through dual-review revise/re-check flow
- Web UI → Emitters: subscribes · Receives live streaming events
- Terminal → Emitters: subscribes · Shares the same event stream as the browser UI
- API Routes → Path Guard: validates · Checks file access boundaries at the route layer
- Shell Tool → Path Guard: constrains · Restricts command-side file access and execution scope
- Skills → Agent Core: informs · Task playbooks shape agent behavior and workflows
- Skills → MCP Server: informs · Some skills support tool and protocol workflows