8.0 KiB
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 ofif (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()andref()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-subtleIf you need to add new color variables, they are located inapp/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 forapp/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.tsand pushed usingbunx 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
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.
// 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",
});
}
});
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;
});