chore(site): enforce sentence-case UI labels in AgentsPage via Biome plugin

Add a Biome GritQL plugin scoped to src/pages/AgentsPage non-test files that flags Title Case in label-bearing JSX attributes (label/title/sectionLabel/aria-label) and label:/title: object properties. Fix the residual violations it surfaces (API key, Custom headers, User OIDC identity, Force on, Default on, Default off) and document the convention in site/AGENTS.md.
This commit is contained in:
Atif Ali
2026-06-02 20:22:03 +00:00
parent 887ea21237
commit 9153c4e22a
5 changed files with 63 additions and 8 deletions
+9
View File
@@ -117,6 +117,15 @@ Debug logs and pprof dumps use the same job name and commit SHA convention.
- For JSX boolean props that are `true`, use the shorthand form
(`<Foo prop />`) instead of `<Foo prop={true} />`. The two are
equivalent; the shorthand is the React convention and reduces noise.
- Use **sentence case** for user-facing UI labels: capitalize only the
first word and proper nouns (`Personal instructions`, `API key`), not
Title Case (`Personal Instructions`, `API Key`). Under
`src/pages/AgentsPage`, a Biome GritQL plugin
(`biome-rules/use-sentence-case-labels.grit`) enforces this for
`label`/`title`/`sectionLabel`/`aria-label` attributes and `label:`/
`title:` object properties. It cannot see labels rendered as JSX text
or built from variables, so those still need a human eye. Add genuine
proper nouns to the allowlist in that file.
- **Avoid unnecessary indirection.** Inline single-use module-level
constants, single-use aliases, and one-line helpers that just return a
single field at the call site. Do not create wrapper hooks that only
@@ -0,0 +1,35 @@
// Enforce sentence case for user-facing UI labels.
//
// Flags Title Case in label-bearing JSX attributes (label, title,
// sectionLabel, aria-label) and object-property labels (label:, title:,
// sectionLabel:). Sentence case capitalizes only the first word and
// proper nouns: "Personal instructions", not "Personal Instructions".
//
// Heuristic: a space followed by a capitalized word ([A-Z][a-z]). This
// also catches acronym-prefixed Title Case like "MCP Servers". Genuine
// multi-word proper nouns (e.g. "VS Code") are false positives and must
// be added to the allowlist below.
//
// Diagnostic-only: Biome GritQL plugins cannot autofix yet.
language js
or {
JsxAttribute(name = $name) as $node where {
$name <: r"^(?:label|title|sectionLabel|aria-label)$",
$node <: contains JsxString() as $value
},
JsPropertyObjectMember() as $node where {
$node <: contains JsLiteralMemberName() as $key,
$key <: r"^(?:label|title|sectionLabel)$",
$node <: contains JsStringLiteralExpression() as $value
}
} where {
$value <: r".* [A-Z][a-z].*",
// Allowlist: proper nouns / product names that are correctly multi-cap.
not $value <: r".*(?:VS Code|Coder Agents|GitHub Actions|JetBrains Fleet|Cmd/Ctrl).*",
register_diagnostic(
span = $value,
message = "Use sentence case for UI labels (e.g. \"Personal instructions\"), not Title Case. If this is a proper noun, add it to the allowlist in use-sentence-case-labels.grit.",
severity = "warn"
)
}
+11
View File
@@ -3,5 +3,16 @@
"files": {
"includes": ["!e2e/**/*Generated.ts", "!scripts/*.mjs"]
},
"overrides": [
{
"includes": [
"src/pages/AgentsPage/**/*.ts",
"src/pages/AgentsPage/**/*.tsx",
"!**/*.stories.tsx",
"!**/*.test.tsx"
],
"plugins": ["./biome-rules/use-sentence-case-labels.grit"]
}
],
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json"
}
@@ -256,7 +256,7 @@ export const ProviderForm: FC<ProviderFormProps> = ({
>
<div className="space-y-5">
<ProviderField
label="API Key"
label="API key"
htmlFor={apiKeyInputId}
required={requiresAPIKey}
description={apiKeyDescription}
@@ -67,25 +67,25 @@ const TRANSPORT_OPTIONS = [
const AUTH_TYPE_OPTIONS = [
{ value: "none", label: "None" },
{ value: "oauth2", label: "OAuth2" },
{ value: "api_key", label: "API Key" },
{ value: "custom_headers", label: "Custom Headers" },
{ value: "user_oidc", label: "User OIDC Identity" },
{ value: "api_key", label: "API key" },
{ value: "custom_headers", label: "Custom headers" },
{ value: "user_oidc", label: "User OIDC identity" },
] as const;
const AVAILABILITY_OPTIONS = [
{
value: "force_on",
label: "Force On",
label: "Force on",
description: "Always injected into every conversation.",
},
{
value: "default_on",
label: "Default On",
label: "Default on",
description: "Pre-selected but users can opt out.",
},
{
value: "default_off",
label: "Default Off",
label: "Default off",
description: "Available but users must opt in.",
},
] as const;
@@ -784,7 +784,7 @@ const ServerForm: FC<ServerFormProps> = ({
disabled={isDisabled}
/>
</Field>
<Field label="API Key" htmlFor={`${formId}-apikey-value`}>
<Field label="API key" htmlFor={`${formId}-apikey-value`}>
<Input
id={`${formId}-apikey-value`}
className="h-9 font-mono text-[13px] [-webkit-text-security:disc]"