Skip to content

Commit f6b948e

Browse files
committed
chore: Add agents.md file
1 parent 3a06b5e commit f6b948e

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed

AGENTS.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# Agent Guidelines for Annum
2+
3+
This document provides coding agents with essential information about the Annum codebase structure, conventions, and workflows.
4+
5+
## Project Overview
6+
7+
Annum is a SvelteKit application that visualizes Trakt.tv watch history. It uses:
8+
- **SvelteKit** (v5) with TypeScript
9+
- **Vite** for bundling
10+
- **Vitest** for testing
11+
- **pnpm** as package manager
12+
- **Auth.js** (@auth/sveltekit) for authentication
13+
- **Netlify** for deployment
14+
15+
## Build, Test & Lint Commands
16+
17+
```bash
18+
# Development
19+
pnpm dev # Start dev server on port 5173
20+
pnpm build # Create production build
21+
pnpm preview # Preview production build locally
22+
23+
# Type Checking & Linting
24+
pnpm check # Run svelte-check for type errors
25+
pnpm check:watch # Run svelte-check in watch mode
26+
pnpm typecheck # Run TypeScript compiler without emitting files
27+
pnpm lint # Run ESLint
28+
pnpm lint:fix # Run ESLint with auto-fix
29+
30+
# Testing
31+
pnpm test # Run tests in watch mode
32+
pnpm test:ci # Run tests once (for CI)
33+
pnpm test:coverage # Run tests with coverage report
34+
35+
# Run a single test file
36+
pnpm vitest src/lib/utils/__tests__/index.ts
37+
38+
# Run a single test by name pattern
39+
pnpm vitest -t "chunks"
40+
```
41+
42+
## Code Style Guidelines
43+
44+
### ESLint Configuration
45+
46+
The project uses `@antfu/eslint-config` with custom overrides:
47+
48+
- **Indentation**: Tabs (not spaces)
49+
- **Quotes**: Single quotes (avoid escape when necessary)
50+
- **Semicolons**: No semicolons
51+
- **Array Types**: Use generic syntax `Array<T>` not `T[]`
52+
53+
### TypeScript
54+
55+
- **Strict mode enabled**: All strict TypeScript checks are on
56+
- **No `{}` or `object` types**: Use `Record<string, unknown>` instead
57+
- **Unused variables**: Prefix with underscore `_` to indicate intentionally unused (e.g., `_variable`, `_arg`)
58+
- **Type imports**: Use `import type` for type-only imports
59+
- **No `any`**: Avoid using `any` type; use proper types or `unknown`
60+
61+
### Naming Conventions
62+
63+
- **Files**: Use kebab-case for files (e.g., `user-stats.ts`)
64+
- **Components**: PascalCase for Svelte components (e.g., `Primary.svelte`)
65+
- **Functions**: camelCase for functions (e.g., `normalizeItem`)
66+
- **Constants**: SCREAMING_SNAKE_CASE for top-level constants (e.g., `TRAKT_BASE_URL`)
67+
- **Types/Interfaces**: PascalCase (e.g., `TraktHistoryItem`)
68+
69+
### Imports
70+
71+
Order imports by:
72+
1. Type imports (using `import type`)
73+
2. External dependencies
74+
3. Internal modules (using SvelteKit aliases)
75+
76+
Example:
77+
78+
```typescript
79+
import type { Language, NormalizedItemResponse } from '$lib/types'
80+
import { page } from '$app/state'
81+
import { normalizeItem } from '$lib/utils'
82+
import { signIn } from '@auth/sveltekit/client'
83+
```
84+
85+
### SvelteKit Path Aliases
86+
87+
- `$lib/*``src/lib/*`
88+
- `$assets``src/assets`
89+
- `$const``src/const.ts`
90+
- `$app/*` → SvelteKit internals (state, navigation, stores, etc.)
91+
92+
### Environment Variables
93+
94+
- All private environment variables must use `PRIVATE_` prefix (configured in `svelte.config.js`)
95+
- Example: `PRIVATE_TRAKT_CLIENT_ID`, `PRIVATE_AUTH_SECRET`
96+
97+
## Function Documentation
98+
99+
All utility functions should include JSDoc comments with:
100+
- Description of what the function does
101+
- `@example` tag showing usage
102+
103+
Example:
104+
105+
```typescript
106+
/**
107+
* Split an array into chunks of a given size
108+
* @example chunks([1, 2, 3, 4, 5], 2) => [[1, 2], [3, 4], [5]]
109+
*/
110+
export function chunks<T>(array: Array<T>, number: number | string): Array<Array<T>>
111+
```
112+
113+
## Error Handling
114+
115+
- Use SvelteKit's `error()` helper for HTTP errors
116+
- Include helpful error messages with context
117+
- Log warnings to console for non-critical issues (e.g., missing TMDB IDs)
118+
119+
Example:
120+
```typescript
121+
if (!session?.user)
122+
error(401, 'You must sign in to access this route.')
123+
```
124+
125+
## Testing Patterns
126+
127+
- **Test files**: Located in `__tests__/` directories alongside source files
128+
- **Fixtures**: Store test data in `__fixtures__/` directories
129+
- **File pattern**: `src/**/__tests__/*.ts`
130+
- **Coverage**: Includes `src/lib/utils/*.ts` and `src/lib/actions.ts`
131+
132+
Test structure:
133+
134+
```typescript
135+
import { describe, expect, it } from 'vitest'
136+
137+
describe('functionName', () => {
138+
it('should describe expected behavior', () => {
139+
const result = functionName(input)
140+
expect(result).toBe(expected)
141+
})
142+
})
143+
```
144+
145+
## Svelte 5 Patterns
146+
147+
- Use Svelte 5 runes: `$state`, `$derived`, `$effect`, `$props`
148+
- Access page store with `page` from `$app/state`
149+
- Use `<script lang='ts'>` for TypeScript in Svelte files
150+
- For PostCSS in styles: `<style lang='postcss'>`
151+
152+
## API Routes
153+
154+
- API routes in `src/routes/api/`
155+
- Use `RequestHandler` type from `./$types`
156+
- Set cache headers using `setHeaders()`
157+
- Return responses with `json()` helper
158+
- Check authentication with `await locals.auth()`
159+
160+
Example structure:
161+
162+
```typescript
163+
export const GET: RequestHandler = async ({ locals, url, fetch, setHeaders }) => {
164+
const session = await locals.auth()
165+
if (!session?.user)
166+
error(401, 'You must sign in to access this route.')
167+
168+
setHeaders({ ...DEFAULT_CACHE_HEADER })
169+
170+
// Implementation
171+
return json({ data })
172+
}
173+
```
174+
175+
## Constants
176+
177+
Define all constants in `src/const.ts` using:
178+
- `as const` for literal types
179+
- `satisfies` for type checking without widening
180+
181+
Example:
182+
183+
```typescript
184+
export const TMDB_FETCH_DEFAULTS = {
185+
method: 'GET',
186+
headers: { 'user-agent': 'annum' },
187+
} satisfies RequestInit
188+
```
189+
190+
## Common Patterns
191+
192+
### Type Guards
193+
194+
```typescript
195+
function isTraktWatchedItem(item: TraktHistoryItem | TraktWatchedItem): item is TraktWatchedItem {
196+
return !('type' in item)
197+
}
198+
```
199+
200+
### Generic Utility Types
201+
202+
```typescript
203+
type Filter<T> = MapValuesToKeysIfAllowed<T>[keyof T]
204+
export function groupBy<T extends Record<PropertyKey, any>, Key extends Filter<T>>(
205+
arr: Array<T>,
206+
key: Key,
207+
): Record<T[Key], Array<T>>
208+
```
209+
210+
## Git & Deployment
211+
212+
- Deployed on Netlify (adapter: `@sveltejs/adapter-netlify`)
213+
- Redirects configured in `_redirects` file
214+
- Site manifest: `static/site.webmanifest`
215+
216+
## Additional Notes
217+
218+
- Use `enhancedImages()` from `@sveltejs/enhanced-img` for optimized images
219+
- Custom media queries defined in `src/styles/custom-media-queries.css`
220+
- CSS variables in `src/styles/variables.css`
221+
- Reset styles in `src/styles/reset.css`

0 commit comments

Comments
 (0)