# AGENTS.md — Atalaya ## Architecture pnpm workspace: Cloudflare Worker (`src/`) + Astro 6 SSR app (`status-page/`). - **Worker entrypoint**: `src/index.ts` — `fetch` + `scheduled` handlers, `RegionalChecker` Durable Object - **Astro entrypoint**: `status-page/src/pages/index.astro` — single-page SSR app - **Static assets**: `status-page/dist/client/` served via `ASSETS` binding (`run_worker_first = true`) - **Shared types**: `src/types.ts` imported via `@worker/types` alias in `status-page/tsconfig.json` - **Auth**: `status-page/src/lib/auth.ts`, configured via `STATUS_PUBLIC`, `STATUS_USERNAME`, `STATUS_PASSWORD` env vars - **Monitor config**: YAML inline in `wrangler.toml` `MONITORS_CONFIG` env var. Secrets interpolated via `${ENV_VAR}` syntax (`src/utils/interpolate.ts`). ## Commands ### Root (Worker) ```bash pnpm dev # wrangler dev pnpm test # vitest (20 test files) pnpm typecheck # tsc --noEmit pnpm check # typecheck + lint + format:check pnpm check:fix # auto-fix lint + format pnpm deploy # build:pages + wrangler deploy pnpm lint:strict # oxlint --deny warnings + eslint --max-warnings=0 vitest run src/path/to.test.ts # single test (no npx needed) ``` ### Pages workspace ```bash pnpm dev:pages # astro dev pnpm build:pages # astro build → status-page/dist/ pnpm test:pages # vitest (3 test files) pnpm check:pages # astro check + tsc --noEmit + eslint pnpm lint:pages # eslint (astro plugin) ``` ### Verification order Before commit: `pnpm check && pnpm test && pnpm build:pages && pnpm check:pages` ## Gotchas - **`.js` extensions in imports**: All worker imports use `.js` extensions (`import { foo } from './bar.js'`). Required for ESM resolution with `moduleResolution: "bundler"`. - **D1 requires bind parameters**: Use `WHERE 1=?` with `.bind(1)` for queries that would otherwise have no parameters. - **Database naming**: D1 columns are `snake_case`, TypeScript properties are `camelCase`. Map at query boundary. - **`--legacy-peer-deps`**: Not needed with pnpm. If peer issues arise, configure `peerDependencyRules` in `pnpm-workspace.yaml`. - **Pages `dist/` and `.astro/`**: Build artifacts, gitignored. - **Astro SSR build artifact**: Worker dynamically imports `../status-page/dist/server/index.mjs` at runtime — uses `@ts-expect-error`. - **Astro 6 + @astrojs/cloudflare v13 workarounds**: `status-page/astro.config.mjs` includes `fixBuildRollupInput` plugin and `prerenderEnvironment: 'node'`. ## Code Style - **Formatting**: Prettier — single quotes, semicolons, 100 char width, trailing commas ES5, no arrow parens. - **Linting**: Oxlint (worker) + ESLint with `eslint-plugin-oxlint` dedup. Pages uses `eslint-plugin-astro`. - **Types**: `type` for aliases, `interface` for object shapes. Explicit return types. - **Naming**: files `kebab-case.ts`, types `PascalCase`, variables `camelCase`, DB fields `snake_case`. - **Tests**: `*.test.ts` colocated with source. Vitest with `vi` for mocks.