CodeNomad/dev-docs/UI_CONVENTIONS.md
Pascal André 7a1fc90310
docs(agents): keep AGENTS.md to universal rules and agent docs to the current state (#1082)
AGENTS.md loaded about 33,000 tokens into every agent session, subagent and reviewer, mostly per-feature contracts, and the agent documentation around it had accumulated duplicates, dated logs and history of removed designs. This PR makes AGENTS.md a short set of rules that apply everywhere plus an index of area documents, and leaves AGENTS.md, dev-docs and the repository skills describing only the current state.

Three commits, reviewable separately:

1. **Move (lossless).** Every per-area rule moved verbatim from AGENTS.md into its area document (existing ones, or six new ones: UI_CONVENTIONS, UI_SHELL, COMPOSER, TRANSCRIPT, SETTINGS, PROJECTS). A script split the old file into 208 units, required one destination for each and checked all 199 content units verbatim at their destination. AGENTS.md went from 134,000 to 16,000 characters.
2. **Trim.** A per-area ponytail review removed rules stated two or three times (keeping the more precise copy), dated validation logs, per-version qualification sections below the current minimum, abandoned designs and self-references; seven documents whose surviving rules live elsewhere were deleted. It also fixed statements the code contradicts (locale registration, the Mission play/recovery condition, plugin package updates, cleanup progress UI, timeline index persistence, automation restart/targets, stale pins and minimums).
3. **Current state only.** The new AGENTS.md rule: no history (removed features and their names, former behavior, provenance, dated logs) and no denials; correct a contradicted statement at its source. DEVELOPER_MODE.md is merged into BROWSER_AUTOMATION.md and every Developer Mode mention is gone (including the README and the browser help page in ten locales). Names that only made sense against older designs are renamed with every reference updated, MISSIONS_ENVIRONMENT_ADMISSION is folded into SESSION_ENVIRONMENT, and INDEX lists every document. The server npm README now states the real OpenCode minimum (2.1.2).

AGENTS.md is now about 14,000 characters (roughly 3,500 tokens); AGENTS.md, dev-docs and the vendor README went from about 11,200 lines to under 4,700.

Validation: every relative Markdown link and every cited dev-docs path resolves; no reference to a renamed or deleted document remains; `npm run test:help` passes for all ten locales.

Review: three independent GPT-6.1 Sol (high) reviews by area found binding rules lost in the trim and current-state passes; 25 were restored as present-tense facts or prohibitions and four contradicting statements corrected, each checked against code. A Fable 5.1 gatekeeper review of the whole PR passed; its follow-up routes session recovery from the index, points to dev-docs/INDEX.md and documents the family identity read.
2026-10-21 16:59:43 +02:00

3.8 KiB

UI conventions

Shared renderer rules for dialogs, utility windows, icon toggles, surfaces and scrollbars.

Agent conventions

  • Authentication recovery uses lib/auth-recovery.ts and components/auth-recovery-dialog.tsx: confirm CodeNomad auth status before showing an expired-login form, reconnect in place to preserve drafts, and never replay failed mutations. Its shared window styles live in styles/components/auth-recovery.css.
  • Confirmation dialogs (components/alert-dialog.tsx) keep Kobalte's initial focus on Cancel, so Enter never confirms by reflex, while the confirm button stays the filled primary action. Alert-dialog buttons show the accent focus ring on any :focus (styles/components/alert-dialog.css), including the initial focus of a mouse-opened dialog, so the ring marks the button Enter acts on. Prompts focus their input, where Enter submits. Covered by tests/browser/alert-dialog.test.ts.
  • Persistent command/search utility windows use components/dismissible-window.tsx: non-modal, no scrim, outside interactions keep them open, and explicit toggles use .icon-toggle with aria-expanded/aria-controls. Keep search state scoped to its instance/session and close it when that view becomes inactive.
  • The .icon-toggle active state (aria-pressed/aria-expanded/data-active) is one shared rule in styles/utilities.css: one uniform partial accent tint for every palette (an ink of accent leaning 20% toward --text-on-accent, then 10% toward --surface-base, at 40% opacity, 50% on hover) over the surface beneath, primary-text icon, disabled toggles excluded. It is for icon toggles only: text list rows select through --list-item-highlight-* instead (Mission past runs). The only active override is .tool-call-output-rail, which keeps its compact output-rail toggles transparent. tests/browser/icon-toggle-active.test.ts samples real active toggles on every ready-made palette over the session header (search), sessions sidebar header, right-panel tab bar, user and assistant message cards (speech button), interruption dock header and transcript canvas (overlay windows share the canvas colour): OKLab ΔE ≥ 8 from the surface on the header and ≥ 5 elsewhere, ≥ 6 from the header's idle hover, ≥ 1.4 from active to active hover, icon ≥ 3:1 on both fills.
  • Movable utility windows opt into DismissibleWindow.draggable and mark their existing top bar with data-window-drag-handle; keep drag geometry shared and controls interactive. --window-visible-height bounds their height to the visual viewport; native scrolling and a sticky existing top bar keep results, pagination and drag/close controls reachable.
  • Appearance mode and the saved light/dark selections are independent (lib/appearance-preferences.ts). Message/tool cards use the muted surface; preferences use the same secondary surface as the main panels. Show a subtle local rollover with --surface-hover-overlay over the preserved selected background, never by substituting a generic panel or the secondary surface; right-panel canvas button rollover overrides live in styles/panels/control-hover.css.
  • index.css re-anchors box-sizing: border-box on every details > :not(summary): the component library resets elements to box-sizing: inherit, so folded content would inherit content-box from the browser's own details slot and overflow full-width controls. Keep that rule rather than patching individual disclosures.
  • Keep the global scrollbar-width default at zero specificity (:where(...) in src/index.css) so component visibility rules win. The timeline shares the transcript's standard native scrollbar (geometry, rail ownership and thumb drags: dev-docs/SESSION_HISTORY_NAVIGATION.md); validate with the full stylesheet and real thumb gestures on mixed-height transcripts.