Conventions for this repository, read by DevAsign's own review agent. Each rule is a single checkable sentence. Newly introduced violations are flagged as nits — they don't block the merge. See README.md for how this file is used and scoped.
- Imports use explicit
.jsextensions on relative paths (TypeScript NodeNext ESM). - All Claude / LLM calls go through
complete()inbackend/src/llm.ts; passcacheSystem: truewhen the system prompt is static. The documented exceptions are callscomplete()can't express: PDF/image reads that need adocument/imagecontent block (summarizeLinearFile,extractGuidanceFromPdf) and non-Anthropic provider calls (summarizeVideo, which uses Gemini) — these call the SDK/provider directly. - GitHub REST calls go through the
gh()helper inbackend/src/github/app.ts; the documented exceptions are raw blob reads viainstallationToken, the OAuth user-token identity calls (/user,/user/emails) inbackend/src/github/oauth.ts(which need the user's OAuth token rather than an installation token), and the App-JWT/app/installationscalls — minting installation tokens, listing installs, anduninstallApp's install delete — which need the App JWT (an installation token can't delete or enumerate installations). - Persistence goes through the
dbhelper (db.insert/update/find/filter); do not write raw SQL in feature code. - A review finding only blocks a merge when its severity is
blocker; advisory findings usewarnornit. - Always read, always write tests for all the changes made.
- The browser talks to the backend only through the typed client in
frontend/src/api.ts— no ad-hocfetchto API routes from components. - Styling uses the shared design tokens in
frontend/src/styles.css(CSS variables like--accent,--fg-dim), not hard-coded hex values.