# AGENTS.md - Agentic Coding Guidelines

This file provides guidelines for AI coding agents working in this repository.

## Project Overview

- **Type**: Astro web application (static site generator)
- **Language**: TypeScript
- **Framework**: Astro 5.x
- **Package Manager**: pnpm
- **Module System**: ES Modules (`"type": "module"`)
- **Shell**: Either use `bash` when in `direnv` or `fish` when used on my personal devices. Do not use `zsh`

## Project Structure

```
src/
├── assets/        # Image assets (SVGs, images)
├── components/    # Reusable Astro components (.astro files)
├── layouts/       # Layout components wrapping pages
└── pages/         # File-based routing (each file = a route)
public/            # Static assets served at root (favicons, etc.)
dist/              # Build output (gitignored)
```

## Build/Lint/Test Commands

### Development

```bash
pnpm install          # Install dependencies
pnpm dev              # Start dev server at localhost:4321
pnpm build            # Build production site to ./dist/
pnpm preview          # Preview production build locally
```

### Type Checking

```bash
pnpm astro check      # Run Astro + TypeScript type checking
```

### Formatting

Use prettier for formatting

### Testing

No testing framework is currently configured. When tests are added:

```bash
# Future: Run all tests
pnpm test

# Future: Run a single test file
pnpm test path/to/file.test.ts

# Future: Run tests matching a pattern
pnpm test -t "pattern"
```

## Code Style Guidelines

### Formatting (Biome)

- **Indentation**: Tabs (not spaces)
- **Quotes**: Double quotes for strings
- **Semicolons**: Required (Biome default)
- **Trailing commas**: Use trailing commas in multiline structures
- **Line width**: 80 characters (Biome default)

### Imports

- Imports are auto-organized by Biome
- Order: External packages first, then internal modules
- Use named imports when possible
- Prefer explicit imports over namespace imports

```typescript
// Good
import { useState, useEffect } from "react";
import { Button } from "../components/Button";

// Avoid
import * as React from "react";
```

### TypeScript

- **Strict mode enabled** via `astro/tsconfigs/strict`
- Always provide explicit types for function parameters
- Use `interface` for object shapes, `type` for unions/intersections
- Avoid `any` - use `unknown` if type is truly unknown
- Use optional chaining (`?.`) and nullish coalescing (`??`)

```typescript
// Good
interface Props {
  title: string;
  description?: string;
}

function greet(name: string): string {
  return `Hello, ${name}`;
}

// Avoid
function greet(name): any {
  return "Hello, " + name;
}
```

### Naming Conventions

- **Files**: kebab-case for utilities (`format-date.ts`), PascalCase for components (`Button.astro`)
- **Components**: PascalCase (`WelcomeBanner`, `NavBar`)
- **Functions/Variables**: camelCase (`getUserData`, `isLoading`)
- **Constants**: UPPER_SNAKE_CASE for true constants (`MAX_RETRIES`, `API_BASE_URL`)
- **Types/Interfaces**: PascalCase (`UserProfile`, `ApiResponse`)
- **Boolean variables**: Prefix with `is`, `has`, `should`, `can` (`isVisible`, `hasError`)

### Astro Components

- Use `.astro` extension for Astro components
- Frontmatter goes between `---` fences at the top
- Props interface defined in frontmatter
- Scoped styles with `<style>` tag (scoped by default)

```astro
---
interface Props {
  title: string;
  class?: string;
}

const { title, class: className } = Astro.props;
---

<h1 class={className}>{title}</h1>

<style>
  h1 {
    color: var(--text-color);
  }
</style>
```

### Error Handling

- Use try/catch for async operations
- Provide meaningful error messages
- Log errors appropriately for debugging
- Handle edge cases explicitly

```typescript
try {
  const data = await fetchData();
  return data;
} catch (error) {
  console.error("Failed to fetch data:", error);
  throw new Error(`Data fetch failed: ${error.message}`);
}
```

### Comments

- Use JSDoc for public functions and complex types
- Keep comments concise and meaningful
- Prefer self-documenting code over comments
- Use `// TODO:` for planned improvements
- Use `// FIXME:` for known issues

```typescript
/**
 * Formats a date for display in the UI.
 * @param date - The date to format
 * @param locale - Optional locale string (defaults to 'en-US')
 * @returns Formatted date string
 */
function formatDate(date: Date, locale = "en-US"): string {
  return date.toLocaleDateString(locale);
}
```

## Development Environment

This project uses Nix Flakes for reproducible development environments:

```bash
# If using direnv (recommended)
direnv allow

# Or manually enter the dev shell
nix develop
```

The Nix shell provides: Node.js, pnpm, PostgreSQL, and language servers.

## Before Committing

1. Run type checking: `pnpm astro check`
2. Run formatting: `pnpm format` (prettier)
3. Build successfully: `pnpm build`
4. Test locally if applicable: `pnpm preview`
