System Design
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
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Vue 3, Nuxt 4, Nuxt UI v4 | SPA with SSR-capable routing |
| Styling | Tailwind CSS 4, UnoCSS icons | Utility-first CSS |
| Editor | CodeMirror 6 | Code/markdown editing with syntax highlighting |
| Terminal | xterm.js + node-pty | Full PTY terminal in the browser |
| Server | Nitro (H3) | HTTP + WebSocket request handling |
| ORM | Drizzle ORM | Type-safe PostgreSQL queries |
| Database | PostgreSQL | Primary data store (local or Neon) |
| Auth | BetterAuth | Email/password sessions with cookie-based auth |
| AI | Claude Agent SDK | Streaming chat and scheduled agent execution |
| Scheduling | cron (npm) | Cron-based agent scheduling |
| CLI | Node.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:
- 00.env-validate -- Checks required env vars (
BETTER_AUTH_SECRET,VAULT_PATH). Warns on missing optional vars. Never crashes. - 01.api-token -- Generates or loads the API token for CLI/skill access. Writes to
.api-tokenfile. - 02.database -- Connects to PostgreSQL, runs migrations (production only), warms the connection pool, seeds the default admin user if the database is empty.
- 03.file-watcher -- Starts chokidar to watch the vault directory for file changes and sync metadata to the database.
- 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:
| Environment | SSL | Pool Size | Idle Timeout |
|---|---|---|---|
| Local (localhost/127.0.0.1) | Off | 10 | Unlimited |
| Neon (*.neon.tech) | Required | 5 | 20s |
| Other | Off | 5 | 20s |
See Database Schema for the full table reference.