fix(ai): add close-button aliases (dismiss/cancel/remove/closebutton/expand/collapse → x / maximize-2 / minimize-2)

Why: end-to-end test of "design a notification card with dismiss x
button" surfaced that MiniMax-M2.7 emits a path node named "Dismiss
Icon". Tokenisation gives "dismiss" but Lucide doesn't have a `dismiss`
key — the resolver fell through prefix/substring fallbacks and wrote
the placeholder lucide:circle, leaving the card with a hollow ring
where the X should be.

What: 5 new aliases added in lock-step to icon-dictionary.ts (client
commonAliases) + icon.ts (server NAME_ALIASES per existing comment):
  - dismiss   → x       (close button intent)
  - closebutton → x     (compacted from "Close Button Icon")
  - cancel    → x       (cancel-action close icon)
  - remove    → x       (remove-action close icon)
  - expand    → maximize-2
  - collapse  → minimize-2

NOT aliased: `cross`. Lucide already ships a `cross` icon (the
Christian-cross shape) and overriding it would lose that geometry.
"Cross" disambiguation is left to the model — if it really means a
close button, telling it to write "Dismiss Icon" / "Close Icon" via
the icon-catalog skill is enough.

Tests: 3 new it.each cases (Dismiss / Cancel / Remove Icon → /x/).
1069 / 1069 AI tests pass (was 1066; +3).
This commit is contained in:
Fini 2026-05-09 20:59:30 +08:00
parent 93543cf0b3
commit 38dcca0cfe
3 changed files with 20 additions and 0 deletions

View file

@ -80,6 +80,12 @@ const NAME_ALIASES: Record<string, string> = {
time: 'clock',
deliverytime: 'clock',
rider: 'bike',
dismiss: 'x',
closebutton: 'x',
cancel: 'x',
remove: 'x',
expand: 'maximize-2',
collapse: 'minimize-2',
icecream: 'ice-cream-cone',
donut: 'donut',
bread: 'croissant',

View file

@ -158,6 +158,14 @@ describe('applyIconPathResolution — opt-in marker gate', () => {
['Star Icon Shape', /star/],
['User Icon SVG', /user/],
['HomeIconPath', /home/], // camelCase compaction
// Notification card dismiss-button name slips MiniMax emits — must
// resolve to lucide:x via the dismiss/closebutton/cancel/remove
// aliases. ("cross" is intentionally NOT aliased — Lucide already has
// a "cross" icon for the Christian-cross shape, and overriding it
// would lose that.)
['Dismiss Icon', /x/],
['Cancel Icon', /x/],
['Remove Icon', /x/],
])('resolves multi-word path name "%s" to %s', (name, expectedIconId) => {
const node = makePath({ name });
applyIconPathResolution(node);

View file

@ -418,6 +418,12 @@ function iconifyBodyToPathD(body: string): string | null {
time: 'clock',
deliverytime: 'clock',
rider: 'bike',
dismiss: 'x',
closebutton: 'x',
cancel: 'x',
remove: 'x',
expand: 'maximize-2',
collapse: 'minimize-2',
icecream: 'ice-cream-cone',
donut: 'donut',
bread: 'croissant',