Files
veridian/AGENTS.md
T

241 lines
8.0 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 Triplit with
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
- `bunx triplit schema push` - Push schema changes to database
## Tech Stack & Dependencies
- **Framework**: Nuxt 4 (SSR enabled)
- **Language**: TypeScript with strict configuration
- **Database**: Triplit (next generation fullstack syncing database, sort of
like convex)
- **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 Triplit for database operations
- Export all schemas from `triplit/schema.ts`
- Use environment variables for database credentials
- Triplit schemas are defined in `triplit/schema.ts` and pushed using `bunx triplit schema push`
### 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)
- Triplit adapter for authentication
- 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
|-- triplit/ # Database related files
│ |-- schema.ts # Database schema
│ |-- client.ts # Interacts with the database on the client
│ \-- server.ts # Interacts with the database on the server
\-- lib/ # Shared utilities
```
## Testing
Currently no test framework is configured, and tests are not currently a
requirement.
## Environment Variables
Key environment variables:
- `TRIPLIT_SERVICE_TOKEN` - Triplit service token (admin token. **SECRET**)
- `NUXT_TRIPLIT_ANON_TOKEN` - Triplit anonymous token (for anonymous access)
- `BETTER_AUTH_SECRET` - Authentication secret (for better-auth)
- `EXTERNAL_JWT_SECRET` - Will always be BETTER_AUTH_SECRET (used for
verifying JWT tokens from better-auth)
- `NUXT_PUBLIC_TRIPLIT_URL` - Triplit server URL
## 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;
});
```