Files
veridian/AGENTS.md
T
2026-01-11 05:04:29 -06:00

245 lines
8.1 KiB
Markdown

# AGENTS.md
This file contains guidelines and commands for agentic coding agents working in
the Veridian repository.
## Project Overview
Veridian is a Nuxt 4 application built with TypeScript, using PostgreSQL with
Drizzle ORM, better-auth for authentication, and UnoCSS for styling. The app is
an agnetic chat platform that is meant to provide a well rounded experience for
interacting with LLMs as well as providing a way to manage agents and provide
helpful tools like RAG (retrieval augmented generation) and web scraping/search.
You should be connected to the Nuxt docs MCP server, if you need to reference
the documentation or are unsure on how to implement something, consult the
docs.
## Core Commands
As an agentic agent, never run the development server yourself.
Instead, once you have completed your task, end generation and inform me that
you are done and request a review of your changes. You are allowed to use
database commands.
### Database Commands
- `tsx db/migrate.ts` - Run database migrations
- `bun x @better-auth/cli@latest generate --output db/auth/auth.schema.ts` -
Generate authentication schema based on `lib/auth.ts`
- `bun x drizzle-kit generate` - Generate migration files
- `bun x drizzle-kit push` - Push schema changes to database
- `bun x drizzle-kit studio` - Open Drizzle Studio for database inspection
## Tech Stack & Dependencies
- **Framework**: Nuxt 4 (SSR enabled)
- **Language**: TypeScript with strict configuration
- **Database**: PostgreSQL with Drizzle ORM
- **Auth**: better-auth with email/password and social providers
- **Styling**: UnoCSS with presetMini
- **Icons**: @nuxt/icon with Iconify, use Myna UI Icons
## Code Style Guidelines
**Follow the LLVM golden rule: If you are extending, enhancing, or bug fixing
already implemented code, use the style that is already being used so that
the source is uniform and easy to follow.**
- **Always end lines with a semicolon regardless of surrounding code**
- Use 4 spaces for indentation
- Use consistent naming conventions for variables, functions, and constants
- Always use strict equality checks (`===` and `!==`) instead of loose equality
checks (`==` and `!=`)
- Prefer using explicity equality checks over truthy/falsy checks
e.g., prefer `if (value !== null)` instead of `if (value)`
- Always check existing code patterns before implementing new features
- Follow existing component and composable structures
- Use proper TypeScript types for all function parameters and returns
- Implement proper cleanup in composables (e.g., useClickOutside)
- Prefer reactive state management over direct DOM manipulation
- Keep components focused and single-purpose
- Use semantic HTML elements where appropriate
### General Structure
- Use Nuxt's app directory structure (`app/`, `server/`, `lib/`)
- Auth configuration in `lib/auth.ts`
- Server API routes go in `server/api/`
- Composables go in `app/composables/`
- Database schema in `db/schema.ts`
- Database migrations in `db/migrations/`
### TypeScript Guidelines
- Use strict TypeScript with no implicit any
- Export types and interfaces explicitly
- Use `computed()` and `ref()` from Vue 3 reactivity system
- Type API responses and database models
### Vue Components
- **Never use self-closing tags, excluding images, br, hr, and input**
- Use `<script setup lang="ts">` syntax
- Strongly prefer composition API over options API
- Prefer composables for shared state management
- Maintain consistent 4-space indentation
- Use PascalCase for component file names
### CSS/Styling
- Use UnoCSS utility classes exclusively
- Never use margin for spacing, always prefer flexbox or grid
- Prefer inline utility classes over custom CSS
- Use semantic color variables: `--color-base`, `--color-neutral`, `--color-accent`, `--color-subtle`
If you need to add new color variables, they are located in `app/assets/css/base.css`,
along with a general CSS reset.
- Apply consistent spacing and layout patterns
- Use responsive prefixes only when necessary
### Imports
- Order imports: Vue/Nuxt imports first, then local files, then dependencies
- `~/` is an alias for `app/` and `~~/` is an alias for the root of the project
- Avoid wildcard imports
- Keep imports sorted alphabetically within groups
### Naming Conventions
- **Page**: camelCase
- **Composables**: camelCase
- **Components**: PascalCase when referenced in templates
- **Functions/Variables**: camelCase
- **Constants**: UPPER_SNAKE_CASE for environment variables only
- **Database tables**: snake_case
- **API routes**: kebab-case path segments
### Database Patterns
- Use Drizzle ORM with PostgreSQL
- Export all schemas from `db/schema.ts`
- Use environment variables for database credentials
- `db/auth/auth.schema.ts` is a generated file, do not touch it. If you need to
change the authentication schema, edit `lib/auth.ts` and run the generation
script.
### Error Handling
- Use proper TypeScript error types
- Implement try-catch blocks for database operations
- Provide user-friendly error messages in API responses
- Log errors appropriately without exposing sensitive data
### Performance Guidelines
- Leverage Nuxt's auto-imports and code splitting
- Use `useState()` for shared state across components
- Implement proper loading states with async operations
- Optimize database queries and use indexes where needed
## Authentication Implementation
The app uses better-auth with:
- Email/password authentication (configurable via env vars)
- Drizzle adapter for PostgreSQL
- Session management through cookies
- Auth plugins in `app/plugins/` for client/server initialization
- Global auth middleware in `app/middleware/auth.global.ts`
All users must be signed in to view pages aside from authentication pages.
(located in `app/pages/auth/`), you do not need to check if session or user
objects are null or undefined, use the non-null assertion operator (`!`) where
necessary. In API routes, you can use `protectRoute` to guarantee that the
user must be authenticated.
## File Organization
```
|-- app/ # Application code
│ |-- components/ # Vue components
│ |-- composables/ # Reuseable composition functions
│ |-- layouts/ # Layout components
│ |-- middleware/ # Route middleware
│ |-- pages/ # File-based routing
│ \-- plugins/ # Vue/Nuxt plugins
|-- server/ # Server-side code
│ \-- api/ # API routes
|-- db/ # Database related files
│ |-- schema.ts # Database schema
│ |-- migrate.ts # Migration runner
│ \-- migrations/ # Migration files
\-- lib/ # Shared utilities
```
## Testing
Currently no test framework is configured, and tests are not currently a
requirement.
## Environment Variables
Key environment variables:
- `DATABASE_URL` - PostgreSQL connection string
- `BETTER_AUTH_SECRET` - Authentication secret
- `DISABLE_LOCAL_AUTH` - Disable email/password auth
- `DISABLE_SIGNUP` - Disable user registration
## Common Patterns
### Composables Pattern
```typescript
export const useFeature = () => {
const state = useState<Type>('feature:state', () => defaultValue)
const computed = computed(() => /* logic */)
const actions = {
// methods
}
return { state, computed, ...actions }
}
```
### API Route Pattern
API routes are defined in `server/api/` and are exported as a single object.
File names contain information about the route, e.g. `user.get.ts` specifies a
GET route to `/user`. This applies for all HTTP methods.
```typescript
// an example GET route to /user
export default defineEventHandler(async (event) => {
try {
// implementation
return { success: true, data: result };
} catch (error) {
throw createError({
statusCode: 500,
statusMessage: "Error description",
});
}
});
```
```typescript
import { users } from "~~/db/schema";
// an example POST route to /user
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { email, name, password } = body;
const [user] = await db
.insert(users)
.values({ email, name, password })
.returning();
return user;
});
```