{"owner":"elie222","repo":"inbox-zero","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# Repository Guidelines\n\n## Build & Test Commands\n- Development: `pnpm dev`\n- Build: `pnpm build`\n- Lint: `pnpm lint`\n- Format: Biome (`pnpm check` / `pnpm fix` via ultracite)\n- Run all tests: `pnpm test`\n- Run integration tests: `pnpm test-integration`\n- Run AI tests: `pnpm --filter inbox-zero-ai test-ai`\n- Run single test: `pnpm test path/to/test-file.test.ts`\n- Run specific AI/eval test: `pnpm --filter inbox-zero-ai test-ai __tests__/eval/your-test.test.ts`\n- Evals in `apps/web/__tests__/eval/` must be run from repo root with `pnpm --filter inbox-zero-ai test-ai` (not `pnpm test`)\n- Type-check build (skips Prisma migrate): `pnpm --filter inbox-zero-ai exec next build`\n- Do not use root `tsc --noEmit`; it is not a supported validation step in this monorepo and surfaces unrelated repo-wide debt. If you need the app's CI-aligned type/build check, use `pnpm --filter inbox-zero-ai build:ci` instead, and only when explicitly asked.\n- Do not run `dev` or `build` unless explicitly asked\n- Run `pnpm install` before running tests or build if not already done\n- Before writing or updating tests, review `.claude/skills/testing/SKILL.md`.\n- For core bug-fix tasks, default to TDD when practical (red/green/refactor); AI prompt improvements should generally be backed by evals too, and TDD is often useful there as well.\n- When adding a new workspace package, add its `package.json` COPY line to `docker/Dockerfile.prod` and `docker/Dockerfile.local`.\n\n## Code Style\n- Install packages in `apps/web`, not root: `cd apps/web && pnpm add ...`\n- Lodash: import specific functions (`import groupBy from \"lodash/groupBy\"`)\n- TypeScript with strict null checks\n- Path aliases: `@/` for imports from project root\n- NextJS app router with (app) directory, tailwindcss\n- For version-sensitive or unclear Next.js behavior, check the relevant doc in `node_modules/next/dist/docs/` before changing framework code.\n- Only add comments for \"why\", not \"what\". Prefer self-documenting code.\n- Logging: avoid duplicating logger context fields from higher in the call chain. Use `logger.trace()` for PII fields (from, to, subject, etc.). Exception: the authenticated user's own email is fine to log at any level.\n- Tests should use the real logger implementation (do not mock `@/utils/logger`).\n- Avoid low-value tests that mostly restate implementation details; prefer tests that catch a real behavioral regression.\n- Helper functions go at the bottom of files, not the top\n- All imports at the top of files, no mid-file dynamic imports\n- Avoid `useEffect` for mirroring fetched props/data into local state; prefer derived values or explicit edit state.\n- Co-locate unit tests next to source files (e.g., `utils/example.test.ts`). Integration, E2E, and AI tests go in `__tests__/`.\n- Don't export types/interfaces only used within the same file\n- No re-export patterns. Import from the original source.\n- Prefer the `EmailProvider` abstraction; only use provider-type checks (`isGoogleProvider`, `isMicrosoftProvider`) at true provider boundary/integration code.\n- Infer types from Zod schemas using `z.infer<typeof schema>` instead of duplicating as separate interfaces\n- Default to inlining and co-locating logic at the call site.\n- Avoid premature abstraction. Small duplicated expressions are usually fine; extracting them often adds indirection without meaning.\n- Do not duplicate substantial logic or correctness-sensitive rules. If copied code must stay in sync to avoid bugs, extract or centralize it early.\n- Extract helpers when they make surrounding code clearer, name a meaningful domain concept, or keep shared behavior consistent across flows.\n- Don't extract helpers that just rename and forward parameters; that's a layer without meaning.\n- Avoid large/nested ternaries. Prefer straightforward control flow, a small helper, or a lookup table when it improves readability.\n- No barrel files. Import directly from source files.\n- Colocate page components next to their `page.tsx`. No nested `components/` subfolders in route directories.\n- Reusable components shared across pages go in `apps/web/components/`\n- One resource per API route file\n- Env vars: add to `.env.example`, `env.ts`, and `turbo.json`. Prefix client-side with `NEXT_PUBLIC_`.\n- Never use dynamic Prisma transactions (`prisma.$transaction(async (tx) => ...)`).\n\n## Change Philosophy\n- Prefer the simplest, most readable change; only keep backwards compatibility when explicitly requested.\n- Do not optimize for migration paths: refactor call sites directly, including larger coordinated changes when clarity improves.\n- This is a public repository. Never include non-public data or internal details from private repositories or services in repository content or GitHub metadata; describe related private work only generically (for example, “updated the marketing repository”).\n\n## LLM Features\n- Stay AI-first: fix general failure modes, not exact eval wording, and avoid brittle keyword or regex rules unless the product needs a hard guard.\n- Do not add keyword/phrase blacklists to prompts, evals, or tests just to catch a model's current bad wording. This product works across languages, so English-specific text checks are especially brittle. For LLM behavior, assert the semantic failure mode with a judge/eval criterion or structured contract instead. Example: test \"does not ask unnecessary clarification or invent payment status,\" not \"does not contain 'could you clarify' or 'specific payment'.\"\n- Never gate context injection or tool behavior on ad hoc user-text keyword matching; use structured state, metadata, or explicit events instead.\n- Tool descriptions should be self-contained: what the tool does, what its parameters mean, when to use it vs alternatives, prerequisites, and safety constraints specific to that tool.\n- Keep only cross-cutting policies (identity, write confirmation, security, formatting) in the system prompt. Per-tool guidance belongs in the tool description so it appears only when the tool is active.\n- Treat prompts, tools, and parameters as costly model-facing surface area. Every line must earn its place; do not add a tool or parameter for an edge case, and get explicit user approval before adding either.\n- Do not duplicate guidance between prompts and tool descriptions. Explicitly disclose any prompt, tool, or tool-parameter change to the user.\n- Keep model-facing schemas portable: prefer flat root objects and verify advanced constructs across providers. Use `z.strictObject()` only when dropping unknown keys is unsafe; describe refinement and transform constraints in tool fields because models may not see them.\n\n## Component Guidelines\n- Use shadcn/ui components when available\n- Use `LoadingContent` component for async data: `<LoadingContent loading={isLoading} error={error}>{data && <YourComponent data={data} />}</LoadingContent>`\n\n## Fullstack Workflow\nSee `.claude/skills/fullstack-workflow/SKILL.md` for full examples and templates.\n\n- API route middleware: `withError` (public, no auth), `withAuth` (user-level), `withEmailAccount` (email-account-level). Export response type via `Awaited<ReturnType<typeof getData>>`.\n- Mutations: use server actions with `next-safe-action`, NOT POST API routes.\n- Exception: mobile-native integrations may use POST API routes when they require a stable HTTP contract.\n- Validation: Zod schemas in `utils/actions/*.validation.ts`. Infer types with `z.infer`.\n- Data fetching: SWR on the client. Call `mutate()` after mutations.\n- Forms: React Hook Form + `useAction` hook. Use `getActionErrorMessage(error.error)` for errors.\n- Loading states: use `LoadingContent` component.\n- Cursor Cloud VM setup: see `.claude/skills/cloud-dev-environment/SKILL.md`.\n"},"files":{"AGENTS.md":"# Repository Guidelines\n\n## Build & Test Commands\n- Development: `pnpm dev`\n- Build: `pnpm build`\n- Lint: `pnpm lint`\n- Format: Biome (`pnpm check` / `pnpm fix` via ultracite)\n- Run all tests: `pnpm test`\n- Run integration tests: `pnpm test-integration`\n- Run AI tests: `pnpm --filter inbox-zero-ai test-ai`\n- Run single test: `pnpm test path/to/test-file.test.ts`\n- Run specific AI/eval test: `pnpm --filter inbox-zero-ai test-ai __tests__/eval/your-test.test.ts`\n- Evals in `apps/web/__tests__/eval/` must be run from repo root with `pnpm --filter inbox-zero-ai test-ai` (not `pnpm test`)\n- Type-check build (skips Prisma migrate): `pnpm --filter inbox-zero-ai exec next build`\n- Do not use root `tsc --noEmit`; it is not a supported validation step in this monorepo and surfaces unrelated repo-wide debt. If you need the app's CI-aligned type/build check, use `pnpm --filter inbox-zero-ai build:ci` instead, and only when explicitly asked.\n- Do not run `dev` or `build` unless explicitly asked\n- Run `pnpm install` before running tests or build if not already done\n- Before writing or updating tests, review `.claude/skills/testing/SKILL.md`.\n- For core bug-fix tasks, default to TDD when practical (red/green/refactor); AI prompt improvements should generally be backed by evals too, and TDD is often useful there as well.\n- When adding a new workspace package, add its `package.json` COPY line to `docker/Dockerfile.prod` and `docker/Dockerfile.local`.\n\n## Code Style\n- Install packages in `apps/web`, not root: `cd apps/web && pnpm add ...`\n- Lodash: import specific functions (`import groupBy from \"lodash/groupBy\"`)\n- TypeScript with strict null checks\n- Path aliases: `@/` for imports from project root\n- NextJS app router with (app) directory, tailwindcss\n- For version-sensitive or unclear Next.js behavior, check the relevant doc in `node_modules/next/dist/docs/` before changing framework code.\n- Only add comments for \"why\", not \"what\". Prefer self-documenting code.\n- Logging: avoid duplicating logger context fields from higher in the call chain. Use `logger.trace()` for PII fields (from, to, subject, etc.). Exception: the authenticated user's own email is fine to log at any level.\n- Tests should use the real logger implementation (do not mock `@/utils/logger`).\n- Avoid low-value tests that mostly restate implementation details; prefer tests that catch a real behavioral regression.\n- Helper functions go at the bottom of files, not the top\n- All imports at the top of files, no mid-file dynamic imports\n- Avoid `useEffect` for mirroring fetched props/data into local state; prefer derived values or explicit edit state.\n- Co-locate unit tests next to source files (e.g., `utils/example.test.ts`). Integration, E2E, and AI tests go in `__tests__/`.\n- Don't export types/interfaces only used within the same file\n- No re-export patterns. Import from the original source.\n- Prefer the `EmailProvider` abstraction; only use provider-type checks (`isGoogleProvider`, `isMicrosoftProvider`) at true provider boundary/integration code.\n- Infer types from Zod schemas using `z.infer<typeof schema>` instead of duplicating as separate interfaces\n- Default to inlining and co-locating logic at the call site.\n- Avoid premature abstraction. Small duplicated expressions are usually fine; extracting them often adds indirection without meaning.\n- Do not duplicate substantial logic or correctness-sensitive rules. If copied code must stay in sync to avoid bugs, extract or centralize it early.\n- Extract helpers when they make surrounding code clearer, name a meaningful domain concept, or keep shared behavior consistent across flows.\n- Don't extract helpers that just rename and forward parameters; that's a layer without meaning.\n- Avoid large/nested ternaries. Prefer straightforward control flow, a small helper, or a lookup table when it improves readability.\n- No barrel files. Import directly from source files.\n- Colocate page components next to their `page.tsx`. No nested `components/` subfolders in route directories.\n- Reusable components shared across pages go in `apps/web/components/`\n- One resource per API route file\n- Env vars: add to `.env.example`, `env.ts`, and `turbo.json`. Prefix client-side with `NEXT_PUBLIC_`.\n- Never use dynamic Prisma transactions (`prisma.$transaction(async (tx) => ...)`).\n\n## Change Philosophy\n- Prefer the simplest, most readable change; only keep backwards compatibility when explicitly requested.\n- Do not optimize for migration paths: refactor call sites directly, including larger coordinated changes when clarity improves.\n- This is a public repository. Never include non-public data or internal details from private repositories or services in repository content or GitHub metadata; describe related private work only generically (for example, “updated the marketing repository”).\n\n## LLM Features\n- Stay AI-first: fix general failure modes, not exact eval wording, and avoid brittle keyword or regex rules unless the product needs a hard guard.\n- Do not add keyword/phrase blacklists to prompts, evals, or tests just to catch a model's current bad wording. This product works across languages, so English-specific text checks are especially brittle. For LLM behavior, assert the semantic failure mode with a judge/eval criterion or structured contract instead. Example: test \"does not ask unnecessary clarification or invent payment status,\" not \"does not contain 'could you clarify' or 'specific payment'.\"\n- Never gate context injection or tool behavior on ad hoc user-text keyword matching; use structured state, metadata, or explicit events instead.\n- Tool descriptions should be self-contained: what the tool does, what its parameters mean, when to use it vs alternatives, prerequisites, and safety constraints specific to that tool.\n- Keep only cross-cutting policies (identity, write confirmation, security, formatting) in the system prompt. Per-tool guidance belongs in the tool description so it appears only when the tool is active.\n- Treat prompts, tools, and parameters as costly model-facing surface area. Every line must earn its place; do not add a tool or parameter for an edge case, and get explicit user approval before adding either.\n- Do not duplicate guidance between prompts and tool descriptions. Explicitly disclose any prompt, tool, or tool-parameter change to the user.\n- Keep model-facing schemas portable: prefer flat root objects and verify advanced constructs across providers. Use `z.strictObject()` only when dropping unknown keys is unsafe; describe refinement and transform constraints in tool fields because models may not see them.\n\n## Component Guidelines\n- Use shadcn/ui components when available\n- Use `LoadingContent` component for async data: `<LoadingContent loading={isLoading} error={error}>{data && <YourComponent data={data} />}</LoadingContent>`\n\n## Fullstack Workflow\nSee `.claude/skills/fullstack-workflow/SKILL.md` for full examples and templates.\n\n- API route middleware: `withError` (public, no auth), `withAuth` (user-level), `withEmailAccount` (email-account-level). Export response type via `Awaited<ReturnType<typeof getData>>`.\n- Mutations: use server actions with `next-safe-action`, NOT POST API routes.\n- Exception: mobile-native integrations may use POST API routes when they require a stable HTTP contract.\n- Validation: Zod schemas in `utils/actions/*.validation.ts`. Infer types with `z.infer`.\n- Data fetching: SWR on the client. Call `mutate()` after mutations.\n- Forms: React Hook Form + `useAction` hook. Use `getActionErrorMessage(error.error)` for errors.\n- Loading states: use `LoadingContent` component.\n- Cursor Cloud VM setup: see `.claude/skills/cloud-dev-environment/SKILL.md`.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Repository Guidelines\n\n## Build & Test Commands\n- Development: `pnpm dev`\n- Build: `pnpm build`\n- Lint: `pnpm lint`\n- Format: Biome (`pnpm check` / `pnpm fix` via ultracite)\n- Run all tests: `pnpm test`\n- Run integration tests: `pnpm test-integration`\n- Run AI tests: `pnpm --filter inbox-zero-ai test-ai`\n- Run single test: `pnpm test path/to/test-file.test.ts`\n- Run specific AI/eval test: `pnpm --filter inbox-zero-ai test-ai __tests__/eval/your-test.test.ts`\n- Evals in `apps/web/__tests__/eval/` must be run from repo root with `pnpm --filter inbox-zero-ai test-ai` (not `pnpm test`)\n- Type-check build (skips Prisma migrate): `pnpm --filter inbox-zero-ai exec next build`\n- Do not use root `tsc --noEmit`; it is not a supported validation step in this monorepo and surfaces unrelated repo-wide debt. If you need the app's CI-aligned type/build check, use `pnpm --filter inbox-zero-ai build:ci` instead, and only when explicitly asked.\n- Do not run `dev` or `build` unless explicitly asked\n- Run `pnpm install` before running tests or build if not already done\n- Before writing or updating tests, review `.claude/skills/testing/SKILL.md`.\n- For core bug-fix tasks, default to TDD when practical (red/green/refactor); AI prompt improvements should generally be backed by evals too, and TDD is often useful there as well.\n- When adding a new workspace package, add its `package.json` COPY line to `docker/Dockerfile.prod` and `docker/Dockerfile.local`.\n\n## Code Style\n- Install packages in `apps/web`, not root: `cd apps/web && pnpm add ...`\n- Lodash: import specific functions (`import groupBy from \"lodash/groupBy\"`)\n- TypeScript with strict null checks\n- Path aliases: `@/` for imports from project root\n- NextJS app router with (app) directory, tailwindcss\n- For version-sensitive or unclear Next.js behavior, check the relevant doc in `node_modules/next/dist/docs/` before changing framework code.\n- Only add comments for \"why\", not \"what\". Prefer self-documenting code.\n- Logging: avoid duplicating logger context fields from higher in the call chain. Use `logger.trace()` for PII fields (from, to, subject, etc.). Exception: the authenticated user's own email is fine to log at any level.\n- Tests should use the real logger implementation (do not mock `@/utils/logger`).\n- Avoid low-value tests that mostly restate implementation details; prefer tests that catch a real behavioral regression.\n- Helper functions go at the bottom of files, not the top\n- All imports at the top of files, no mid-file dynamic imports\n- Avoid `useEffect` for mirroring fetched props/data into local state; prefer derived values or explicit edit state.\n- Co-locate unit tests next to source files (e.g., `utils/example.test.ts`). Integration, E2E, and AI tests go in `__tests__/`.\n- Don't export types/interfaces only used within the same file\n- No re-export patterns. Import from the original source.\n- Prefer the `EmailProvider` abstraction; only use provider-type checks (`isGoogleProvider`, `isMicrosoftProvider`) at true provider boundary/integration code.\n- Infer types from Zod schemas using `z.infer<typeof schema>` instead of duplicating as separate interfaces\n- Default to inlining and co-locating logic at the call site.\n- Avoid premature abstraction. Small duplicated expressions are usually fine; extracting them often adds indirection without meaning.\n- Do not duplicate substantial logic or correctness-sensitive rules. If copied code must stay in sync to avoid bugs, extract or centralize it early.\n- Extract helpers when they make surrounding code clearer, name a meaningful domain concept, or keep shared behavior consistent across flows.\n- Don't extract helpers that just rename and forward parameters; that's a layer without meaning.\n- Avoid large/nested ternaries. Prefer straightforward control flow, a small helper, or a lookup table when it improves readability.\n- No barrel files. Import directly from source files.\n- Colocate page components next to their `page.tsx`. No nested `components/` subfolders in route directories.\n- Reusable components shared across pages go in `apps/web/components/`\n- One resource per API route file\n- Env vars: add to `.env.example`, `env.ts`, and `turbo.json`. Prefix client-side with `NEXT_PUBLIC_`.\n- Never use dynamic Prisma transactions (`prisma.$transaction(async (tx) => ...)`).\n\n## Change Philosophy\n- Prefer the simplest, most readable change; only keep backwards compatibility when explicitly requested.\n- Do not optimize for migration paths: refactor call sites directly, including larger coordinated changes when clarity improves.\n- This is a public repository. Never include non-public data or internal details from private repositories or services in repository content or GitHub metadata; describe related private work only generically (for example, “updated the marketing repository”).\n\n## LLM Features\n- Stay AI-first: fix general failure modes, not exact eval wording, and avoid brittle keyword or regex rules unless the product needs a hard guard.\n- Do not add keyword/phrase blacklists to prompts, evals, or tests just to catch a model's current bad wording. This product works across languages, so English-specific text checks are especially brittle. For LLM behavior, assert the semantic failure mode with a judge/eval criterion or structured contract instead. Example: test \"does not ask unnecessary clarification or invent payment status,\" not \"does not contain 'could you clarify' or 'specific payment'.\"\n- Never gate context injection or tool behavior on ad hoc user-text keyword matching; use structured state, metadata, or explicit events instead.\n- Tool descriptions should be self-contained: what the tool does, what its parameters mean, when to use it vs alternatives, prerequisites, and safety constraints specific to that tool.\n- Keep only cross-cutting policies (identity, write confirmation, security, formatting) in the system prompt. Per-tool guidance belongs in the tool description so it appears only when the tool is active.\n- Treat prompts, tools, and parameters as costly model-facing surface area. Every line must earn its place; do not add a tool or parameter for an edge case, and get explicit user approval before adding either.\n- Do not duplicate guidance between prompts and tool descriptions. Explicitly disclose any prompt, tool, or tool-parameter change to the user.\n- Keep model-facing schemas portable: prefer flat root objects and verify advanced constructs across providers. Use `z.strictObject()` only when dropping unknown keys is unsafe; describe refinement and transform constraints in tool fields because models may not see them.\n\n## Component Guidelines\n- Use shadcn/ui components when available\n- Use `LoadingContent` component for async data: `<LoadingContent loading={isLoading} error={error}>{data && <YourComponent data={data} />}</LoadingContent>`\n\n## Fullstack Workflow\nSee `.claude/skills/fullstack-workflow/SKILL.md` for full examples and templates.\n\n- API route middleware: `withError` (public, no auth), `withAuth` (user-level), `withEmailAccount` (email-account-level). Export response type via `Awaited<ReturnType<typeof getData>>`.\n- Mutations: use server actions with `next-safe-action`, NOT POST API routes.\n- Exception: mobile-native integrations may use POST API routes when they require a stable HTTP contract.\n- Validation: Zod schemas in `utils/actions/*.validation.ts`. Infer types with `z.infer`.\n- Data fetching: SWR on the client. Call `mutate()` after mutations.\n- Forms: React Hook Form + `useAction` hook. Use `getActionErrorMessage(error.error)` for errors.\n- Loading states: use `LoadingContent` component.\n- Cursor Cloud VM setup: see `.claude/skills/cloud-dev-environment/SKILL.md`.\n","category":"root","tokens":1931}]}