From 4a6340e83ffd01d673750d3bd0b21814676f3a5c Mon Sep 17 00:00:00 2001 From: Steven RYDELL Date: Sat, 1 Aug 2026 17:53:04 +0200 Subject: [PATCH] chore(agents): add AGENTS.md/CLAUDE.md rules for AI coding agents Any AI agent working in this repo (Claude Code, Codex, Kimi, or any other) must stay schema-driven and never hardcode object types, field names, filters, or columns as a shortcut. AGENTS.md is the index (tech stack, commands, universal rules); CLAUDE.md just points Claude Code at it so the same rules apply without duplicating content. The detailed schema-fidelity rule lives in .agents/rules/. .gitignore previously excluded *.md except README/CHANGELOG, which would have hidden these files (and SCHEMA_DEVIATIONS.md) from git. --- .agents/rules/schema-fidelity.md | 30 ++++++++++++++++++++++++++++++ .gitignore | 4 ++++ AGENTS.md | 28 ++++++++++++++++++++++++++++ CLAUDE.md | 1 + 4 files changed, 63 insertions(+) create mode 100644 .agents/rules/schema-fidelity.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.agents/rules/schema-fidelity.md b/.agents/rules/schema-fidelity.md new file mode 100644 index 0000000..0e765a4 --- /dev/null +++ b/.agents/rules/schema-fidelity.md @@ -0,0 +1,30 @@ +# Schema fidelity + +Stay schema-driven: the server's JSON schema is the single source of truth for what forms, fields, filters, and columns exist. This is why upstream (stalwartlabs/webui) rejects PRs that hardcode exceptions instead of fixing the schema/server — see [SCHEMA_DEVIATIONS.md](../../SCHEMA_DEVIATIONS.md) for the full rationale and the tracked list. + +## When this applies + +- Adding or changing anything in `DynamicList.tsx`, `FieldWidget.tsx`, `DynamicForm.tsx`, `layout.ts`, `schemaResolver.ts`, or any `src/lib/*Columns.ts` / `*Filters.ts` file. +- Adding a new list column, filter, form field, or navigation entry. +- Any change driven by a specific object/view name (`viewName === 'x:...'`, `objectName === 'x:...'`). + +## Rules + +- **NEVER** add a hardcoded `viewName === '...'` / `objectName === '...'` branch, a synthetic/computed column, or a client-side filter/sort workaround without checking first whether the schema already supports it. +- Widget-level special cases for object types the schema itself designates (e.g. `x:OtpAuth`, `x:Expression`, `x:Rate`) are fine — that pattern already exists upstream and just renders real schema data with a dedicated widget. +- **CRITICAL**: if something genuinely cannot be done through the schema because the server (`stalwartlabs/stalwart`) or upstream webui doesn't support it yet, it must become a tracked deviation, not a silent workaround: + 1. Add an entry to `SCHEMA_DEVIATIONS.md` (id, file location, what it does, why it's needed, the ideal server-side fix, status `🟡 Workaround` or `🔵 Upstream tracked`). + 2. Tag the code with `// SCHEMA-DEVIATION: ` pointing at that entry. + 3. Prefer filing (or pointing the user to file) an issue against `stalwartlabs/stalwart` or `stalwartlabs/webui` for the ideal fix. +- **CRITICAL**: `src/types/schema.ts` must **never** be edited for a deviation, not even to add an extra optional field — it must stay alignable with upstream's copy of the file. If a deviation needs to carry extra data on an official schema shape, declare the augmented type as an intersection (`OfficialType & { extra?: ... }`) in the deviation's own module, or in `src/lib/schemaDeviationTypes.ts`, and import it only where the deviation is used. +- Never remove a `SCHEMA-DEVIATION` tag or its `SCHEMA_DEVIATIONS.md` entry without confirming the underlying server/schema capability actually landed. +- Pure client-side/presentational logic (theming, dark mode, responsive layout, sidebar UX, appearance settings) is not a schema concern — no deviation tracking needed for those. + +## Example + +```ts +// SCHEMA-DEVIATION: log-client-filters (see SCHEMA_DEVIATIONS.md) +// +// The Stalwart JMAP backend rejects `level`/`event` as filter conditions on +// `x:Log/query` (`unsupportedFilter`) ... [why + ideal fix] +``` diff --git a/.gitignore b/.gitignore index 1eef4a1..e9a1b13 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,10 @@ scripts/ *.md !README.md !CHANGELOG.md +!AGENTS.md +!CLAUDE.md +!SCHEMA_DEVIATIONS.md +!.agents/rules/*.md /SPEC-* # Tool-generated artifacts during agent sessions .playwright-mcp/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..33ce16b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,28 @@ +# Stalwart WebUI Fork + +Community fork of [stalwartlabs/webui](https://github.com/stalwartlabs/webui), a schema-driven admin panel for [Stalwart](https://stalw.art). The server's JSON schema (fetched from `/api/schema`) is the single source of truth for forms, fields, filters, columns, and navigation. + +## Tech Stack + +- React 19 + Vite + TypeScript, Zustand stores, JMAP (RFC 8620) for all data operations. + +## Commands + +- `npm run dev` - Dev server +- `npm run typecheck` - `tsc --noEmit` +- `npm run lint` - ESLint +- `npm run test` - Vitest (`npm run test:watch` to watch) +- `npm run build` - `tsc -b && vite build` + +## Rules + +The detailed rules live in `.agents/rules/`. Read the relevant file before acting: + +- **Schema fidelity** - [.agents/rules/schema-fidelity.md](.agents/rules/schema-fidelity.md) - Stay schema-driven; how to handle cases the schema can't cover yet + +## Universal Rules + +- This applies to every AI coding agent working in this repo (Claude Code, Codex, Kimi, or any other) — not just one tool. +- Never hardcode object types, field names, filters, or columns as a shortcut. Read `.agents/rules/schema-fidelity.md` before adding anything that touches lists, forms, or navigation. +- **CRITICAL**: `src/types/schema.ts` mirrors the official server/webui schema contract and must never be edited to accommodate a deviation, not even to add an optional field. Deviation-only type augmentations go in `src/lib/schemaDeviationTypes.ts` (or the deviation's own module) as an intersection with the official type — see `.agents/rules/schema-fidelity.md`. +- Any client-side workaround for something the official schema doesn't support yet must be documented in `SCHEMA_DEVIATIONS.md` and tagged `// SCHEMA-DEVIATION: ` in code. Never add one silently. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..368b51a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +Read [AGENTS.md](AGENTS.md) first — it is the source of truth for this repo's rules (tech stack, commands, and the schema-fidelity rule in `.agents/rules/`). It applies to every AI agent working here, Claude Code included.