System Design

System Design

Architecture overview of Cognova's layers, tech stack, and design principles.

System Design

Cognova is a full-stack Nuxt 4 application that combines a personal knowledge vault with AI agent capabilities. The system runs as a single Node.js process serving both the web UI and all backend services.

Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│                          Browser                                │
│  Vue 3 SPA  ·  Nuxt UI v4  ·  xterm.js  ·  CodeMirror         │
└────────┬──────────────┬──────────────┬──────────────────────────┘
         │ HTTP/REST     │ WebSocket    │ WebSocket
         ▼              ▼              ▼
┌─────────────────────────────────────────────────────────────────┐
│                     Nitro Server (H3)                           │
│                                                                 │
│  ┌──────────┐  ┌──────────────┐  ┌────────────────────────┐    │
│  │ API      │  │ WebSocket    │  │ Plugins (startup)      │    │
│  │ Routes   │  │ Routes       │  │                        │    │
│  │          │  │              │  │  00 env-validate       │    │
│  │ /api/fs  │  │ /terminal    │  │  01 api-token          │    │
│  │ /api/task│  │ /_ws/chat    │  │  02 database           │    │
│  │ /api/agen│  │ /notificatio │  │  03 file-watcher       │    │
│  │ /api/memo│  │              │  │  04 cron-agents        │    │
│  │ /api/secr│  │              │  │                        │    │
│  └────┬─────┘  └──────┬──────┘  └────────────────────────┘    │
│       │               │                                        │
│  ┌────┴───────────────┴────────────────────────────────────┐   │
│  │                    Services Layer                        │   │
│  │  agent-executor  ·  cron-scheduler  ·  memory-extractor │   │
│  └────┬──────────────────┬──────────────────┬──────────────┘   │
│       │                  │                  │                   │
│  ┌────┴────┐  ┌──────────┴───┐  ┌──────────┴──────────┐       │
│  │ Drizzle │  │ Claude Agent │  │ Utilities            │       │
│  │ ORM     │  │ SDK          │  │                      │       │
│  │         │  │              │  │ path-validator       │       │
│  │         │  │ query()      │  │ pty-manager          │       │
│  │         │  │ streaming    │  │ notification-bus     │       │
│  │         │  │              │  │ crypto               │       │
│  └────┬────┘  └──────────────┘  └──────────────────────┘       │
└───────┼─────────────────────────────────────────────────────────┘
        │
   ┌────┴────┐    ┌──────────────┐
   │PostgreSQL│    │  File System │
   │         │    │  (Vault)     │
   │ 17 tables│    │  ~/vault/    │
   └─────────┘    └──────────────┘

Tech Stack

LayerTechnologyPurpose
FrontendVue 3, Nuxt 4, Nuxt UI v4SPA with SSR-capable routing
StylingTailwind CSS 4, UnoCSS iconsUtility-first CSS
EditorCodeMirror 6Code/markdown editing with syntax highlighting
Terminalxterm.js + node-ptyFull PTY terminal in the browser
ServerNitro (H3)HTTP + WebSocket request handling
ORMDrizzle ORMType-safe PostgreSQL queries
DatabasePostgreSQLPrimary data store (local or Neon)
AuthBetterAuthEmail/password sessions with cookie-based auth
AIClaude Agent SDKStreaming chat and scheduled agent execution
Schedulingcron (npm)Cron-based agent scheduling
CLINode.js (tsx)cognova init, update, start, stop

Design Principles

Single-user, self-hosted

Cognova is designed for one person running on their own machine or VM. There is no multi-tenancy, no role-based access, and no team features. Authentication exists to protect the instance from unauthorized network access, not to separate users.

Vault-first storage

Markdown files live on the filesystem in a configurable vault directory (VAULT_PATH). The database stores metadata, search indexes, and application state -- but the files themselves are the source of truth. Deleting the database does not destroy your notes.

AI as a service layer

Claude integration runs server-side through the Agent SDK. The browser never talks to Anthropic directly. This keeps API keys off the client and lets cron agents run headlessly on a schedule.

Graceful degradation

Every major subsystem (database, vault, Claude) can be unavailable without crashing the server. The db-state utility tracks database availability, and API routes check it via requireDb() before querying. If DATABASE_URL is unset, the app still serves the file browser.

Directory Structure

cognova/
├── app/                    # Nuxt 4 frontend (Vue 3 SPA)
│   ├── components/         # UI components
│   ├── composables/        # Shared reactive logic
│   ├── layouts/            # Dashboard layout
│   ├── pages/              # File-based routing
│   └── assets/css/         # Tailwind entry
├── server/                 # Nitro backend
│   ├── api/                # REST endpoints (auto-registered)
│   ├── routes/             # WebSocket handlers
│   ├── services/           # Business logic (agents, cron, memory)
│   ├── plugins/            # Startup lifecycle (ordered 00-04)
│   ├── utils/              # Singletons and helpers
│   ├── db/                 # Schema, migrations, seed
│   └── drizzle/migrations/ # Generated SQL migrations
├── shared/                 # Types shared between app/ and server/
│   └── types/
├── cli/                    # CLI package (cognova command)
├── Claude/                 # Published Claude Code config
│   ├── CLAUDE.md           # Agent system prompt
│   ├── hooks/              # Session lifecycle hooks
│   └── skills/             # Python skill scripts
└── docs/                   # Internal planning docs

Startup Sequence

Nitro plugins run in filename order on server boot:

  1. 00.env-validate -- Checks required env vars (BETTER_AUTH_SECRET, VAULT_PATH). Warns on missing optional vars. Never crashes.
  2. 01.api-token -- Generates or loads the API token for CLI/skill access. Writes to .api-token file.
  3. 02.database -- Connects to PostgreSQL, runs migrations (production only), warms the connection pool, seeds the default admin user if the database is empty.
  4. 03.file-watcher -- Starts chokidar to watch the vault directory for file changes and sync metadata to the database.
  5. 04.cron-agents -- Cleans up orphaned agent runs from previous shutdowns, then loads all enabled cron agents into the scheduler.

Request Flow

REST API

HTTP requests hit Nitro's H3 router, which matches the file-based API route (e.g., server/api/tasks/index.get.ts). Auth middleware validates the session cookie or API token. The handler queries the database via Drizzle and returns JSON.

WebSocket (Chat)

The browser opens a WebSocket to /_ws/chat. The server creates a Claude Agent SDK query() session and streams messages back. Each message is forwarded to the client in real time. Cost and token metrics are recorded to the token_usage table.

WebSocket (Terminal)

The browser opens a WebSocket to /terminal. The server spawns a PTY process (via node-pty) rooted in the vault directory. Input/output is piped bidirectionally. Sessions auto-clean after 30 minutes of inactivity.

WebSocket (Notifications)

The browser opens a WebSocket to /notifications. The singleton NotificationBus registers the peer and broadcasts events (agent completions, file changes, reminders) to all connected clients.

Database Connection

Cognova auto-detects the database environment from DATABASE_URL:

EnvironmentSSLPool SizeIdle Timeout
Local (localhost/127.0.0.1)Off10Unlimited
Neon (*.neon.tech)Required520s
OtherOff520s

See Database Schema for the full table reference.