Project Structure
Cognova is a monorepo with a Nuxt 4 app and a CLI workspace package, managed by pnpm.
Top-Level Layout
cognova/
app/ # Nuxt 4 frontend source root
server/ # Nitro server (API, plugins, middleware)
shared/ # Code shared between app and server
cli/ # CLI package (workspace)
Claude/ # Claude Code config (published, installed to ~/.claude/)
.claude/ # Claude Code config (dev-only, not published)
.output/ # Nuxt build output
nuxt.config.ts # Nuxt configuration
drizzle.config.ts # Drizzle ORM configuration
docker-compose.yml # Docker Compose for local dev and deployment
Dockerfile # Production container image
package.json # Root package with scripts and dependencies
pnpm-workspace.yaml # Workspace definition
app/ -- Frontend
Nuxt 4 uses app/ as the source root (different from Nuxt 3).
app/
components/ # Vue components (auto-imported)
composables/ # Vue composables (auto-imported)
layouts/ # Page layouts
middleware/ # Route middleware
pages/ # File-based routing
assets/ # CSS and static assets
app.vue # Root component
Import alias: ~/ and @/ resolve to app/.
server/ -- Backend
The Nitro server handles API routes, database access, and WebSocket connections.
server/
api/ # REST API endpoints
db/ # Drizzle schema and database connection
drizzle/ # Generated migration files
middleware/ # Server middleware (auth, etc.)
plugins/ # Server startup plugins (database init, migrations)
routes/ # Non-API routes (WebSocket handlers under _ws/)
services/ # Business logic
utils/ # Server utilities
Import alias: ~~/ resolves to the project root. Server code uses ~~/server/ paths (e.g., import { getDb } from '~~/server/db').
WebSocket handlers live under server/routes/_ws/ to avoid collisions with Nuxt page routes. A WebSocket handler at server/routes/chat.ts would intercept the /chat page.
shared/ -- Shared Code
shared/
types/ # TypeScript types used by both app and server
utils/ # Utility functions shared across boundaries
Types are defined here once and imported everywhere. Never duplicate type definitions.
cli/ -- CLI Package
The CLI is a workspace package built with tsup. It is not published separately -- it is bundled into the root npm package.
cli/
src/
index.ts # Entry point, command dispatch
commands/ # One file per command (init, start, stop, update, doctor, reset)
lib/ # Shared logic (prerequisites, install, database, vault, config)
templates/ # String generators for .env, CLAUDE.md, ecosystem.config.cjs
tsup.config.ts # Builds to dist/cli/
Build output goes to dist/cli/index.js, which is the bin entry in package.json.
Claude/ -- Published Claude Config
Files in Claude/ are installed to ~/.claude/ during cognova init:
Claude/
CLAUDE.md # Agent identity and instructions
settings.json # Claude Code settings
rules/ # Pattern-matched rules for file types
skills/ # Custom skills (task, project, memory, environment)
hooks/ # Lifecycle hooks (session-start, pre-compact, etc.)
See Claude Integration for details on each component.
Key Scripts
Defined in the root package.json:
| Script | Description |
|---|---|
pnpm dev | Start Nuxt dev server |
pnpm build | Build for production |
pnpm lint | Run ESLint |
pnpm db:generate | Generate Drizzle migrations |
pnpm db:migrate | Run pending migrations |
pnpm db:push | Push schema to database (dev) |
pnpm db:studio | Open Drizzle Studio |
pnpm db:up | Start local PostgreSQL container |
pnpm db:down | Stop local PostgreSQL container |
pnpm cli:build | Build the CLI |
pnpm cli:dev | Watch-build the CLI |
Workspace Structure
pnpm-workspace.yaml defines a single workspace package:
packages:
- "cli"
The root package and the CLI share a lockfile. The CLI's build dependencies (tsup, @clack/prompts, picocolors) are inlined at build time, so the published npm package has no CLI-specific runtime dependencies.