# AGENTS.md — Gitea Mail Templates ## Project Overview Theme presentation for self-hosted Gitea, driven by locked official inputs and a reusable control framework. New source architecture supports Gitea 28+; historical release tags retain their original layouts and compatibility. ## Repository Layout ``` gitea.lock.json # Generated official version, commit and file SHA-256; no vendored upstream source framework/ # Shared header/action/fallback/footer controls and structural layout presets themes// # theme.json and theme.css only; no mail data/logic/translation definitions tools/ # Go 1.24+ CLI; urfave/cli and x/net HTML validation upstream/ # Explicit sync, checksum/adapter verification and key discovery builder/ # One official-context alignment layer and theme package generation config/, data/ # Names, descriptions and mock contexts; not a template inventory preview/ # Official-compatible rendering, locale adapter and SSE dev server cli/ # list, create, delete, build, preview, dev, upstream build/themes/ # Generated installable overrides; ignored build/upstream/ # Downloaded immutable official mail/locales/assets/license; ignored preview/ # Vanilla JS UI, generated manifest and per-language scripts docs/ # English/Simplified Chinese documentation and gallery images ``` ## Source and Theme Rules - Never commit or hand-maintain official input files. `upstream prepare` downloads missing inputs to the ignored cache. `upstream sync --tag vX.Y.Z` explicitly regenerates the lock after reviewing a new version. - Build/preview bootstrap a missing cache, then verify it offline against the lock's commit and per-file SHA-256. Corruption is an error, never silently repaired. - Root `gitea.lock.json` is mandatory for prepare/verify/build/preview/dev; a cached lock is not a substitute. Restore the tracked lock for normal clones; intentional initialization uses explicit `upstream sync --tag v28.0.0`. There is no automatic latest-version selection. - Run upstream commands from `tools/`, or provide the subcommand's `--root` (default `..`). `verify` is read-only; `prepare` never rewrites the root lock; `sync` requires network and stable 28+ tags, replaces cache/lock but does not change docs or publish. See CONTRIBUTING for recovery; preserve invalid caches before rebuilding and avoid concurrent cache writers. - Changed reviewed translation/mail-renderer references require an adapter review before updating reference hashes. - Official templates own notification data, conditions, subject sections and functional URLs. The shared framework may reorganize presentation and add controls using those values and official translations; themes may not add business logic. - `theme.json` has `name`, `description`, `mode` (`shared` or `framed`) and optional `layout`. New themes default to `framed` with the `standard` framework preset. `shared` remains a minimal CSS-only mode without framework controls. - All framed themes use the same header/action/fallback/footer partials and single adapter. Structural presets live in `framework/layouts/`, not in theme directories; color/font/spacing rules live in theme CSS. - Layout fragments form balanced presentation markup. `__HEADER__` inserts the shared brand control; `__MAIL_TYPE__` expands to the discovered mail ID. Deployment logos use `{{AppUrl}}assets/img/favicon.png`; the static preview uses the downloaded icon in its generated data only. - CSS must not add text, external resources or hide official content. Use literal email-compatible CSS; browser preview is not a mail-client emulator. - All referenced translation keys must exist in the official English catalog, including keys outside `mail.*`. Other languages use official English fallback. - The reviewed Polish v28.0.0 invitation placeholder defect is reported as `[UPSTREAM-WARN]`; its exact source text is preserved. - Mail entrypoints come from the snapshot; new types need fixtures. Keep JSON fixture integers as integers for Go formatting. ## Development 1. `cd tools && go run . create `. 2. Edit only theme metadata/CSS. Shared controls or layout presets are framework changes. 3. Run `go run . upstream prepare`, `go test ./...` and `go run . preview all`. 4. Check desktop/mobile layouts and languages; update the gallery if appropriate. `build all` generates `build/themes//mail/`. `preview all` builds and renders every official language, writing `preview/rendered.js` and `preview/rendered/.js`. Static preview must work on `file://` via script loading. Keep generated output ignored. `dev` uses Go HTTP/SSE on loopback and watches theme resources, framework, lock/cache and fixture data. The preview remains vanilla JS with theme/template/language/view switching, desktop/mobile viewports, panel controls and keyboard navigation. Tests compare subjects, notification text and functional links across every language/theme and relevant branch, accounting explicitly for framework-added controls/branding. Verify button labels and identical button/fallback URLs separately. Before release, capture real mail using an isolated Gitea matching the locked version. ## Versioning - Current template release: **v28.0.0**. - The snapshot-driven source refactor is unreleased. Its baseline is Gitea v28.0.0; do not replace the existing v28.0.0 assets. - Historical compatibility is documented in `COMPATIBILITY.md`, including the incomplete v1.27.2 push fix. New source architecture does not extend support to earlier Gitea versions. - Latest upstream Gitea release: 28.1.0 [PENDING]. - Upstream discovery only adds pending documentation; it must not implicitly update snapshots or mark versions verified. - Release tags match the locked Gitea version. Review notes in `.github/release-notes/vX.Y.Z.md`, test, build and complete the matching-instance smoke test before publication. - The workflow packages generated overrides, preview language bundles, docs and upstream license/provenance. Verify Actions/write permissions on the configured Gitea host before relying on automatic upload. - Markdown managed blocks declare pairs in `DOC-TAGS`. Opening `` and closing `` delimit managed text; the first repeated pair wins. TRACKER manages pending upstream labels; RELEASE manages published labels. LATEST-TESTED and LATEST-VERIFIED remain manual-only. ## Commit Conventions Use `style(name):`, `preview:`, `tools:`, `docs:`, `fix:`, `project:`, `refactor:` or `chore:` as appropriate. Preserve unrelated user changes and keep generated files out of commits.