- Created AGENTS.md with quick start, architecture, content schema, styling, Prettier, caching, Docker deployment, constraints, common tasks, and gotchas - Merged content authoring guidelines from AGENT.md (blog post style, tag system with vocabulary and rules) - Removed redundant AGENT.md file; AGENTS.md is the single source of truth for agent instructions
9.1 KiB
9.1 KiB
Agent Instructions
Compact guidance for OpenCode sessions working on this repository.
Quick Start
npm install
npm run dev # dev server at http://localhost:4321
npm run build # production build to ./dist/
npm run preview # serve production build locally
npm run format # Prettier across entire codebase
Never skip npm install after checkout. Dependencies are not vendored.
Architecture
- Framework: Astro 5 with Tailwind CSS v4 (Vite plugin)
- Content: Astro Content Collections — markdown files in
src/content/blog/ - Schema:
src/content.config.ts— posts requiretitle,description,date; optionaldraft,tags - Build output:
dist/(gitignored). Never commit built files. - Deployment: Docker multi-stage build →
static-web-serverbehind Traefik.compose.ymldefines production service.
Content
Blog posts live in src/content/blog/. Frontmatter must match the schema in src/content.config.ts.
Blog Post Style
- Voice: First-person, direct, opinionated. No preamble, no "Hope this helps" closings.
- Opening: Hook into a specific frustration or observation. Skip the generic intro.
- Headings:
##— lede/subtitle (one per post, immediately after the title, punchy)###— main sections---— horizontal rule between sections- No
#(H1) anywhere in the post body
- Closing: End decisively. A statement, not a sendoff.
- Grammar: Correct. No "Do you ever wondering", no "Let's get started!"
- Tone reference: See the three most recent posts by date.
Tag System
Current Vocabulary
| Tag | Description |
|---|---|
linux |
Linux-specific content — distros, tools, fixes |
flutter |
Flutter framework, mobile development |
android |
Android-specific content, ADB, AVD |
windows |
Windows-specific content, PowerShell, Win tooling |
git |
Git commands, workflows, hosting |
hardware |
Physical hardware, drivers, firmware quirks |
ai |
AI-assisted development, LLM tools, agents |
dev-setup |
Developer environment, tooling, workflow, DX |
dart |
Dart language, Dart-specific libraries |
go |
Go language |
craftsmanship |
Software design, architecture, TDD, DDD, Clean Architecture, code quality |
self-hosting |
Self-hosted services, VPS, infrastructure |
distributed-systems |
Distributed data, sync, CRDTs, consensus |
misc |
Catch-all for posts that don't fit elsewhere |
Per-Post Tags (current state)
| Post | Tags |
|---|---|
| stop-stashing-use-git-worktree | git, dev-setup |
| vibe-coding-still-needs-a-craftsman | ai, craftsmanship |
| building-my-own-self-hosted-music-library | linux, self-hosting |
| building-load-testing-script-with-claude | go, ai |
| crdt-conflict-free-replicated-data-types | dart, distributed-systems |
| fix-adb-unsufficient-permission-linux | linux, android |
| fix-infinix-air-pro-plus-quad-speakers-linux | linux, hardware |
| fix-infinix-air-pro-plus-screen-color | windows, linux, hardware |
| flutter-android-emulator-not-showing | flutter, android |
| flutter-clean-architecture | flutter, craftsmanship |
| immutable-workstation-fedora-kinoite | linux, dev-setup |
| kuwot (draft) | flutter, dart |
| remap-copilot-key-infinix-air-pro-plus | linux, hardware |
| sign-github-commit-on-windows | git, windows |
| using-direnv-in-powershell-on-windows | windows, dev-setup |
| welcome | misc |
Rules for Tags
When tagging a post:
- Use 2–4 tags per post. More than 4 is a sign you're being too specific.
- Prefer tags from the existing vocabulary above.
- A tag should describe what the post is about, not every concept it mentions.
When adding a new tag:
- Ask: will this tag apply to at least one other existing post, or is it clearly a category this blog will write about again?
- If yes: add it to the vocabulary table above and apply it.
- If no: fold into an existing tag or leave it out.
- Do not add tags for topics covered once and unlikely to recur (e.g.
music,testing,open-source). - Document new tags in this file.
Styling
- Tailwind v4 via
@tailwindcss/vite. Global styles insrc/styles/global.css. - Custom theme: Fira Code font, neutral-900 background, neutral-300 text.
- Expressive Code (
ec.config.mjs) — code blocks usedark-plustheme, no border radius, transparent shadows. - Pagefind integration provides search index built at
npm run build.
Prettier
Format before committing. The config (.prettierrc) uses:
prettier-plugin-astro— parses.astrofilesprettier-plugin-organize-imports— sorts imports automatically
npm run format writes changes in place. No separate lint step exists.
Production Caching
sws.config.toml (mounted into Docker container) defines cache headers:
- HTML:
no-cache, must-revalidate— always revalidate - Astro assets (
/_astro/*):max-age=31536000, immutable— fingerprinted, cache forever - Images/fonts:
max-age=604800— 1 week
Do not change without understanding fingerprinting behavior.
Docker & Deployment
- Build:
docker build -t site .(multi-stage: node:24-alpine → static-web-server) - Run:
docker compose up -d(uses externaltraefik-proxynetwork) - Port: Container serves on port 80; Traefik routes
fiatcode.devandwww.fiatcode.dev - Config:
sws.config.tomlmounted at/config.toml;SERVER_CONFIG_FILEenv var points to it. - No build args or secrets — site is fully static.
Important Constraints
- No test suite — no
vitest,jest, or similar configured. - No CI/CD — no GitHub Actions workflows in repo.
- No ESLint — only Prettier for formatting.
- Single package — not a monorepo; all code lives under
src/. - Node version — Docker uses Node 24; local dev should match (nvm recommended).
- Generated files —
.astro/directory is generated; never edit files there. - Content assets — images in
public/images/; reference with absolute paths like/images/piko-1.webp.
Common Tasks
Add a blog post
- Create
src/content/blog/<slug>.mdwith required frontmatter (title, description, date, draft: false, tags) - Run
npm run devto verify rendering - Run
npm run format - Commit with conventional commit:
feat: add post <title>
Update tag vocabulary
Edit the "Current Vocabulary" table and "Per-Post Tags" matrix in this file. Keep both in sync.
Change site metadata
- Site URL:
astro.config.mjs→sitefield - Title/description per-page: in the page/layout component frontmatter
- Favicon/manifest: replace files in
public/
Modify Tailwind theme
Edit src/styles/global.css — @theme block and @layer base utilities.
Gotchas
- Port conflict: Astro dev defaults to port 4321. Change via
npm run dev -- --port <n>if needed. - Content cache: Astro caches content collections in
.astro/data-store.json(large, gitignored). Delete if content changes aren't reflected. - Image paths: In markdown, use absolute paths starting with
/(e.g.,). Relative paths break in production. - Date format: Use ISO 8601 with timezone offset (e.g.,
2024-03-18T14:16:19+07:00). Astro's date parser is strict. - Draft posts: Set
draft: trueto exclude from builds.draftfield is optional in schema but recommended for clarity. - Prettier on Astro files: Must have the plugin installed; otherwise formatting corrupts
.astrosyntax. Verified indevDependencies.
References
astro.config.mjs— integrations (sitemap, pagefind, expressive-code)src/content.config.ts— content collection schema and loadersws.config.toml— production server and cache headerscompose.yml— Docker Compose production serviceREADME.md— basic commands and tech stack