Skip to content

Consolidate the icon-color palette onto one shared module - #961

Merged
selfcontained merged 1 commit into
mainfrom
agt_394016a2d732/job-debt-collector-90583005
Aug 15, 2026
Merged

Consolidate the icon-color palette onto one shared module#961
selfcontained merged 1 commit into
mainfrom
agt_394016a2d732/job-debt-collector-90583005

Conversation

@selfcontained

Copy link
Copy Markdown
Owner

What

The eight-colour brand icon palette lived in three places, with the hexes duplicated a fourth time. Adding a colour meant editing three files across two TS programs and hoping the lists stayed in sync.

Copy What it held
apps/server/src/server/static-theme.ts:7 VALID_ICON_COLORS id tuple + IconColor type
apps/web/src/hooks/use-icon-color.ts:4,22 ICON_COLORS id tuple (byte-identical) and ICON_COLOR_OPTIONS re-listing the same hexes as swatch
scripts/generate-icon-colors.ts:25 the same ids again with primary / dark hexes

All three now derive from a new dependency-free apps/server/src/shared/icon-colors.ts holding the ids and both hex channels in one ordered table — the same #844/#849 shared-module pattern already used for agent types, IDE types, media file types, and errorMessage.

  • static-theme.ts keeps exporting VALID_ICON_COLORS / IconColor as aliases, so server.ts and static-theme.test.ts are untouched.
  • use-icon-color.ts keeps exporting IconColorId / ICON_COLOR_OPTIONS, so settings-pane.tsx and appearance-settings.tsx are untouched. Display labels stay web-side, mirroring AGENT_TYPE_LABELS in lib/agent-types.ts.
  • generate-icon-colors.ts imports the palette directly.

Why it's tech debt

Four copies of one table, spread across the server, the web app, and a root-level build script — pure maintenance drag with a real drift risk (the web swatch hexes and the generator's primary hexes have to agree or the settings preview stops matching the icon that actually ships).

No behaviour change

  • Order preserved exactly (teal, blue, purple, red, orange, amber, pink, cyan). It drives both the rendered swatch order in Appearance settings and the server's iconColor must be one of: ... error string; both verified identical against the live dev stack.
  • Icon generator re-run end-to-end after the change: all 8 variants regenerated with zero git diff on apps/web/public/icons/.
  • Verified live: swatches render in order, selecting Purple round-trips through the API, POST /api/v1/agents/settings still rejects an unknown colour with the same message.

Deliberately left alone

  • scripts/ is not covered by any TS program. tsconfig.scripts.json includes bin/**/*.ts only, so generate-icon-colors.ts is never type-checked by pnpm run check. The new import was validated by running the script under tsx rather than by type-checking it. Widening the include is a separate change and out of scope here.
  • ICON_COLORS (web) was deleted, not aliased. It had zero importers repo-wide — its only use was deriving IconColorId inside its own file, which now comes from the shared module. VALID_ICON_COLORS does have importers, so it kept its alias.
  • Labels stayed in web. ICON_COLOR_LABELS is a Record<IconColorId, string>, so TS still enforces exhaustiveness when a colour is added, but a UI string doesn't move into a server module.
  • DEFAULT_ICON_COLOR stays in static-theme.ts — it's a server runtime default, not part of the palette table.

Next run

Queued: the server↔web wire-type duplication cluster, largest being apps/web/src/hooks/use-service-resources.ts (~180 lines mirroring observability/service-resources.ts).

Checks

pnpm run check · pnpm run finalize:web · pnpm run test:e2e (180 passed) · server vitest (2733 passed) · web vitest (898 passed) — all green.

🤖 Generated with Claude Code

The eight-colour brand palette existed in three places, with the hexes
duplicated a fourth time:

  1. apps/server/src/server/static-theme.ts — VALID_ICON_COLORS id tuple
  2. apps/web/src/hooks/use-icon-color.ts — ICON_COLORS id tuple, plus
     ICON_COLOR_OPTIONS re-listing the same hexes as `swatch`
  3. scripts/generate-icon-colors.ts — the same ids with primary/dark hexes

Adding a colour meant editing three files in two TS programs. All three now
derive from a new dependency-free apps/server/src/shared/icon-colors.ts
(the #844/#849 shared-module pattern), which holds the ids and both hex
channels in one ordered table.

Behaviour is unchanged: the tuple order (teal, blue, purple, red, orange,
amber, pink, cyan) is preserved exactly, so the Appearance settings swatch
order and the server's `iconColor must be one of: ...` error string are
byte-identical. Re-running the icon generator produces zero git diff.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@selfcontained
selfcontained merged commit 8fe8057 into main Aug 15, 2026
1 check passed
@selfcontained
selfcontained deleted the agt_394016a2d732/job-debt-collector-90583005 branch August 15, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant