All checks were successful
continuous-integration/drone/push Build is passing
- Root AGENTS.md: add build pipeline, Makefile targets, full directory listing - Backend AGENTS.md: add architecture layout, API routes table, streaming/store patterns, missing deps (jsonschema-go, values pkg, types pkg) - Frontend AGENTS.md: add architecture layout, missing deps (marked, highlight.js), Alpine component pattern, build pipeline details - README.md: add env var config table, Docker/Make workflows, dev setup, thinking support, token stats, structured output, llama.cpp timings
2.5 KiB
2.5 KiB
Frontend Agent Instructions
Stack
- Bun (bundler + package manager — no npm)
- TypeScript (strict mode, ES2020 target)
- Alpine.js (reactivity, bundled via
main.ts— not CDN) - Tailwind CSS 4 (no config file, just
styles.csswith@import) - marked + marked-highlight + highlight.js (Markdown rendering)
Commands
bun run build # Production build → public/dist/
bun run dev # Watch mode (JS + CSS)
bun run lint # ESLint
Architecture
Directory Layout
src/
main.ts # Entry point — imports components, starts Alpine
client.ts # All API calls (fetch-based, centralized)
types/index.ts # Shared TypeScript interfaces
utils.ts # Shared utility functions
theme.ts # Theme toggle logic
components/
chatManager.ts # Chat UI — message list, streaming, Markdown
imageManager.ts # Image generation/gallery UI
settingsManager.ts # Settings form UI
themeManager.ts # Theme Alpine component
navigationManager.ts # Page navigation Alpine component
public/
index.html # SPA shell
pages/
chats.html # Chat page template
images.html # Images page template
settings.html # Settings page template
styles.css # Tailwind entry point
Key Patterns
- Alpine.js components: each
*Manager.tsregisters anAlpine.data(...)component. State lives in Alpine's reactive scope + localStorage for persistence. - API client: all backend calls go through
src/client.ts. Streaming uses NDJSON viaReadableStreamreader. - Build pipeline: Bun bundles
src/main.ts→public/dist/main.js; Tailwind CLI compilesstyles.css→public/dist/styles.css. Output is copied tobackend/web/static/by the rootMakefile. - No SPA router: navigation is handled by Alpine component visibility toggling.
Non-Negotiables
- ❌ No
anytype — useunknownand narrow - ❌ No
astype assertions - ❌ No
@ts-ignoreor@ts-expect-error - ❌ Fix all TypeScript and ESLint errors — don't ignore them
- ❌ No Alpine.js via CDN (it's bundled)
- ❌ Don't commit
public/dist/
Code Style
- 2 spaces, single quotes, semicolons required
- camelCase for variables/functions
- PascalCase for types/interfaces
- UPPER_SNAKE_CASE for constants
- Explicit error handling with try/catch
- User-friendly error messages in UI (not just console.log)