From 9673f15c11523072cdd5d42013a9b9e6900e2f8b Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 15 Aug 2026 22:13:17 -0700 Subject: [PATCH] fix(dashboard): repair undefined spacing tokens, settings-search gaps, and census/browser-lane test drift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dashboard bare-run repair, census/token cluster. Real product bugs: the Command Center activity panel (FN-8866) and structural-mail badge (FN-8872) referenced undefined --space-* tokens, zeroing their gaps/padding — mapped to the defined named scale; the settings search index lagged FN-8829/FN-9021 additions and FN-8855's requiredChecks entry had no scroll anchor (now a SettingsTextRow). Test-side: the theme census learns FN-8730's intentional midnight theme, and the Chromium touch-resize suite self-gates with describe.runIf per the sibling browser-lane convention (CI/FUSION_BROWSER_SMOKE_REQUIRE still fail loudly; all 62 tests still run where Chromium exists). Co-Authored-By: Claude Fable 5 --- .../fix-cc-spacing-and-settings-search.md | 7 +++++ .../app/components/MailboxStructuralItem.css | 3 +- .../__tests__/ThemeSelector.test.tsx | 3 +- .../command-center/AgentActivityPanel.css | 17 +++++----- .../__tests__/CommandCenterControls.test.tsx | 3 +- .../sections/GeneralSection.search.ts | 29 ++++++++++++++++++ .../settings/sections/MergeSection.tsx | 28 +++++++++++------ .../fn-8602/phone-fullscreen.png | Bin 43987 -> 44063 bytes .../__screenshots__/fn-8602/tablet-after.png | Bin 52549 -> 50718 bytes .../__screenshots__/fn-8602/tablet-before.png | Bin 11500 -> 11508 bytes .../fn-8607/phone-fullscreen-sheet.png | Bin 17823 -> 18577 bytes .../fn-8607/tablet-agent-list-after.png | Bin 21489 -> 21510 bytes .../fn-8607/tablet-setup-wizard-after.png | Bin 81964 -> 80720 bytes .../task-modal-touch-resize-browser.test.ts | 14 +++++++-- 14 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 .changeset/fix-cc-spacing-and-settings-search.md diff --git a/.changeset/fix-cc-spacing-and-settings-search.md b/.changeset/fix-cc-spacing-and-settings-search.md new file mode 100644 index 0000000000..3f0b2f93c1 --- /dev/null +++ b/.changeset/fix-cc-spacing-and-settings-search.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Fix collapsed Command Center activity spacing and mailbox badge padding; make recommendation and required-checks settings searchable. +category: fix +dev: AgentActivityPanel.css used an undefined numeric `--space-1/2/3` scale (FN-8866) and MailboxStructuralItem.css referenced undefined `--space-2xs` (FN-8872), zeroing gaps/padding — mapped to the defined named token scale. Settings search index gains `maxRecommendationsPerTask` (FN-8829) and `recommendationMailboxNoticeEnabled` (FN-9021); MergeSection's `requiredChecks` row now uses the `SettingsTextRow` primitive so the FN-8855 search entry actually scroll-anchors. diff --git a/packages/dashboard/app/components/MailboxStructuralItem.css b/packages/dashboard/app/components/MailboxStructuralItem.css index 349f1d6da5..313d758931 100644 --- a/packages/dashboard/app/components/MailboxStructuralItem.css +++ b/packages/dashboard/app/components/MailboxStructuralItem.css @@ -1,11 +1,12 @@ /* FNXC:StructuralMail 2026-08-09-09:09: Reports and approval references need a compact structural treatment without changing ordinary mail. */ +/* FNXC:StructuralMail 2026-08-16-05:07: FN-8872 referenced undefined --space-2xs, which invalidated the badge padding to 0. --space-2xs is intentionally undefined (see space-token-defined.test.ts); use the established calc(var(--space-xs) / 2) half-step for the compact block padding instead. */ .mailbox-kind-badge { border-radius: var(--radius-sm); display: inline-flex; font-size: var(--font-size-xs); font-weight: var(--font-weight-medium); margin-inline-start: var(--space-xs); - padding: var(--space-2xs) var(--space-xs); + padding: calc(var(--space-xs) / 2) var(--space-xs); } .mailbox-kind-badge--report { diff --git a/packages/dashboard/app/components/__tests__/ThemeSelector.test.tsx b/packages/dashboard/app/components/__tests__/ThemeSelector.test.tsx index c66cf57b5d..9b52a64f40 100644 --- a/packages/dashboard/app/components/__tests__/ThemeSelector.test.tsx +++ b/packages/dashboard/app/components/__tests__/ThemeSelector.test.tsx @@ -4,7 +4,8 @@ import type { ColorTheme } from "@fusion/core"; import { ThemeSelector } from "../ThemeSelector"; // FNXC:Theme 2026-07-16-14:30: FN-8146 pins the historical Settings-grid set, including restored shadcn-mono, so a removal from COLOR_THEMES cannot make the all-themes checks pass circularly. -const EXPECTED_THEME_IDS = ['default', 'ocean', 'forest', 'sunset', 'zen', 'berry', 'high-contrast', 'industrial', 'monochrome', 'slate', 'ash', 'air', 'graphite', 'silver', 'solarized', 'factory', 'factory-mono', 'ayu', 'one-dark', 'nord', 'dracula', 'gruvbox', 'tokyo-night', 'catppuccin-mocha', 'github-dark', 'everforest', 'rose-pine', 'kanagawa', 'night-owl', 'palenight', 'monokai-pro', 'slime', 'brutalist', 'neon-city', 'parchment', 'terminal', 'glass', 'glass-silver', 'horizon', 'vitesse', 'outrun', 'snazzy', 'porple', 'espresso', 'mars', 'poimandres', 'ember', 'rust', 'copper', 'foundry', 'carbon', 'sandstone', 'lagoon', 'frost', 'lavender', 'neon-bloom', 'sepia', 'cobalt', 'clay', 'moss', 'aurora', 'calm', 'dawn', 'sage', 'factory-dark', 'factory-light', 'shadcn', 'shadcn-ember', 'shadcn-custom', 'shadcn-blue', 'shadcn-green', 'shadcn-red', 'shadcn-purple', 'shadcn-pink', 'shadcn-orange', 'shadcn-yellow', 'shadcn-mono', 'shadcn-mono-red', 'shadcn-mono-blue', 'shadcn-mono-green', 'shadcn-mono-purple', 'shadcn-mono-pink', 'shadcn-mono-orange', 'shadcn-mono-yellow', 'shadcn-black', 'shadcn-gray', 'shadcn-gray-blue'] as const; +// FNXC:Theme 2026-08-16-05:07: FN-8730 (5931e10345) added the Midnight preset; the census gains "midnight" between sage and factory-dark to match COLOR_THEMES order. +const EXPECTED_THEME_IDS = ['default', 'ocean', 'forest', 'sunset', 'zen', 'berry', 'high-contrast', 'industrial', 'monochrome', 'slate', 'ash', 'air', 'graphite', 'silver', 'solarized', 'factory', 'factory-mono', 'ayu', 'one-dark', 'nord', 'dracula', 'gruvbox', 'tokyo-night', 'catppuccin-mocha', 'github-dark', 'everforest', 'rose-pine', 'kanagawa', 'night-owl', 'palenight', 'monokai-pro', 'slime', 'brutalist', 'neon-city', 'parchment', 'terminal', 'glass', 'glass-silver', 'horizon', 'vitesse', 'outrun', 'snazzy', 'porple', 'espresso', 'mars', 'poimandres', 'ember', 'rust', 'copper', 'foundry', 'carbon', 'sandstone', 'lagoon', 'frost', 'lavender', 'neon-bloom', 'sepia', 'cobalt', 'clay', 'moss', 'aurora', 'calm', 'dawn', 'sage', 'midnight', 'factory-dark', 'factory-light', 'shadcn', 'shadcn-ember', 'shadcn-custom', 'shadcn-blue', 'shadcn-green', 'shadcn-red', 'shadcn-purple', 'shadcn-pink', 'shadcn-orange', 'shadcn-yellow', 'shadcn-mono', 'shadcn-mono-red', 'shadcn-mono-blue', 'shadcn-mono-green', 'shadcn-mono-purple', 'shadcn-mono-pink', 'shadcn-mono-orange', 'shadcn-mono-yellow', 'shadcn-black', 'shadcn-gray', 'shadcn-gray-blue'] as const; function renderedThemeIds(listbox: HTMLElement) { return within(listbox).getAllByRole("option").map((option) => { diff --git a/packages/dashboard/app/components/command-center/AgentActivityPanel.css b/packages/dashboard/app/components/command-center/AgentActivityPanel.css index 7adcf6e2f1..42db239ed6 100644 --- a/packages/dashboard/app/components/command-center/AgentActivityPanel.css +++ b/packages/dashboard/app/components/command-center/AgentActivityPanel.css @@ -1,10 +1,13 @@ /* FNXC:CommandCenterAgentActivity 2026-08-10-01:54: The activity panel keeps live and timeline controls touch-usable at desktop and mobile widths with existing design tokens. Timeline rows are manual windows, so this stylesheet deliberately adds no nested scroll owner. + +FNXC:CommandCenterAgentActivity 2026-08-16-05:07: +FN-8866 shipped with the undefined numeric --space-1/2/3 scale, which invalidated every gap/padding to 0 and collapsed the panel's spacing. This design system defines only the named --space-xs/sm/md/lg/xl/2xl scale (styles.css), so the numeric references map to xs=4px, sm=8px, md=12px per CommandCenter.token-validity.css.test.ts. */ .cc-agent-activity { display: grid; - gap: var(--space-3); + gap: var(--space-md); min-inline-size: 0; } @@ -13,7 +16,7 @@ The activity panel keeps live and timeline controls touch-usable at desktop and .cc-agent-activity-target { display: flex; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); min-inline-size: 0; } @@ -35,15 +38,15 @@ The activity panel keeps live and timeline controls touch-usable at desktop and .cc-agent-activity-list { display: grid; - gap: var(--space-2); + gap: var(--space-sm); } .cc-agent-activity-row { display: flex; align-items: center; - gap: var(--space-2); + gap: var(--space-sm); min-inline-size: 0; - padding: var(--space-2); + padding: var(--space-sm); border: 0; border-radius: var(--radius-sm); background: transparent; @@ -63,7 +66,7 @@ button.cc-agent-activity-row:focus-visible { .cc-agent-activity-copy { display: grid; - gap: var(--space-1); + gap: var(--space-xs); min-inline-size: 0; overflow-wrap: anywhere; } @@ -93,6 +96,6 @@ button.cc-agent-activity-row:focus-visible { @media (max-height: 480px) and (max-width: 768px) { .cc-agent-activity { - gap: var(--space-2); + gap: var(--space-sm); } } diff --git a/packages/dashboard/app/components/command-center/__tests__/CommandCenterControls.test.tsx b/packages/dashboard/app/components/command-center/__tests__/CommandCenterControls.test.tsx index a6646eef6e..05717bd333 100644 --- a/packages/dashboard/app/components/command-center/__tests__/CommandCenterControls.test.tsx +++ b/packages/dashboard/app/components/command-center/__tests__/CommandCenterControls.test.tsx @@ -76,7 +76,8 @@ function cssRule(css: string, selector: string) { } // FNXC:Theme 2026-07-16-14:30: FN-8146 pins the historical Settings-grid set, including restored shadcn-mono, so a removal from COLOR_THEMES cannot make the all-themes checks pass circularly. -const EXPECTED_THEME_IDS = ['default', 'ocean', 'forest', 'sunset', 'zen', 'berry', 'high-contrast', 'industrial', 'monochrome', 'slate', 'ash', 'air', 'graphite', 'silver', 'solarized', 'factory', 'factory-mono', 'ayu', 'one-dark', 'nord', 'dracula', 'gruvbox', 'tokyo-night', 'catppuccin-mocha', 'github-dark', 'everforest', 'rose-pine', 'kanagawa', 'night-owl', 'palenight', 'monokai-pro', 'slime', 'brutalist', 'neon-city', 'parchment', 'terminal', 'glass', 'glass-silver', 'horizon', 'vitesse', 'outrun', 'snazzy', 'porple', 'espresso', 'mars', 'poimandres', 'ember', 'rust', 'copper', 'foundry', 'carbon', 'sandstone', 'lagoon', 'frost', 'lavender', 'neon-bloom', 'sepia', 'cobalt', 'clay', 'moss', 'aurora', 'calm', 'dawn', 'sage', 'factory-dark', 'factory-light', 'shadcn', 'shadcn-ember', 'shadcn-custom', 'shadcn-blue', 'shadcn-green', 'shadcn-red', 'shadcn-purple', 'shadcn-pink', 'shadcn-orange', 'shadcn-yellow', 'shadcn-mono', 'shadcn-mono-red', 'shadcn-mono-blue', 'shadcn-mono-green', 'shadcn-mono-purple', 'shadcn-mono-pink', 'shadcn-mono-orange', 'shadcn-mono-yellow', 'shadcn-black', 'shadcn-gray', 'shadcn-gray-blue'] as const; +// FNXC:Theme 2026-08-16-05:07: FN-8730 (5931e10345) added the Midnight preset; the census gains "midnight" between sage and factory-dark to match COLOR_THEMES order. +const EXPECTED_THEME_IDS = ['default', 'ocean', 'forest', 'sunset', 'zen', 'berry', 'high-contrast', 'industrial', 'monochrome', 'slate', 'ash', 'air', 'graphite', 'silver', 'solarized', 'factory', 'factory-mono', 'ayu', 'one-dark', 'nord', 'dracula', 'gruvbox', 'tokyo-night', 'catppuccin-mocha', 'github-dark', 'everforest', 'rose-pine', 'kanagawa', 'night-owl', 'palenight', 'monokai-pro', 'slime', 'brutalist', 'neon-city', 'parchment', 'terminal', 'glass', 'glass-silver', 'horizon', 'vitesse', 'outrun', 'snazzy', 'porple', 'espresso', 'mars', 'poimandres', 'ember', 'rust', 'copper', 'foundry', 'carbon', 'sandstone', 'lagoon', 'frost', 'lavender', 'neon-bloom', 'sepia', 'cobalt', 'clay', 'moss', 'aurora', 'calm', 'dawn', 'sage', 'midnight', 'factory-dark', 'factory-light', 'shadcn', 'shadcn-ember', 'shadcn-custom', 'shadcn-blue', 'shadcn-green', 'shadcn-red', 'shadcn-purple', 'shadcn-pink', 'shadcn-orange', 'shadcn-yellow', 'shadcn-mono', 'shadcn-mono-red', 'shadcn-mono-blue', 'shadcn-mono-green', 'shadcn-mono-purple', 'shadcn-mono-pink', 'shadcn-mono-orange', 'shadcn-mono-yellow', 'shadcn-black', 'shadcn-gray', 'shadcn-gray-blue'] as const; function renderedThemeIds(listbox: HTMLElement) { return within(listbox).getAllByRole("option").map((option) => { diff --git a/packages/dashboard/app/components/settings/sections/GeneralSection.search.ts b/packages/dashboard/app/components/settings/sections/GeneralSection.search.ts index 832052d295..c8e0a9341f 100644 --- a/packages/dashboard/app/components/settings/sections/GeneralSection.search.ts +++ b/packages/dashboard/app/components/settings/sections/GeneralSection.search.ts @@ -23,6 +23,35 @@ export const generalSearchEntries: SettingsSearchEntry[] = [ helpFallback: "Report a bug, send feedback, share an idea, or get help from Fusion.", keywords: ["bug", "feedback", "idea", "help", "support"], }, + { + /* + FNXC:SettingsSearch 2026-08-16-05:07: + FN-8829 (d450dbe971) added the recommendations cap descriptor row without an + index entry; the search-index drift guard caught the gap. Labels/help mirror + the section's t() copy verbatim. + */ + sectionId: "general", + key: "maxRecommendationsPerTask", + labelKey: "settings.general.maxRecommendationsPerTask", + labelFallback: "Maximum recommendations per task", + helpKey: "settings.general.maxRecommendationsPerTaskHelp", + helpFallback: "Default: 3. Set 0 to disable recommendations; choose a whole number from 1 to 20 to cap each completed task.", + keywords: ["suggestions", "follow-up", "cap", "limit"], + }, + { + /* + FNXC:SettingsSearch 2026-08-16-05:07: + FN-9021 (ea53cbd4ff) added the mailbox-notice toggle without an index entry; + same drift-guard gap as above. + */ + sectionId: "general", + key: "recommendationMailboxNoticeEnabled", + labelKey: "settings.general.recommendationMailboxNoticeEnabled", + labelFallback: "Recommendation mailbox notices", + helpKey: "settings.general.recommendationMailboxNoticeEnabledHelp", + helpFallback: "Default: enabled. When a completed task captures recommendations, send a summary to your mailbox. Turning this off does not change whether recommendations are captured.", + keywords: ["notifications", "mail", "inbox", "suggestions"], + }, { sectionId: "general", key: "taskPrefix", diff --git a/packages/dashboard/app/components/settings/sections/MergeSection.tsx b/packages/dashboard/app/components/settings/sections/MergeSection.tsx index 21501438eb..dbde9d4304 100644 --- a/packages/dashboard/app/components/settings/sections/MergeSection.tsx +++ b/packages/dashboard/app/components/settings/sections/MergeSection.tsx @@ -5,6 +5,7 @@ import { fetchGitRemoteBranches } from "../../../api"; import { MovedSettingsStub } from "./MovedSettingsStub"; import { SettingsSelectRow } from "../SettingsSelectRow"; import { SettingsNumberRow } from "../SettingsNumberRow"; +import { SettingsTextRow } from "../SettingsTextRow"; import { SettingsHelpTip } from "../SettingsHelpTip"; import type { SectionBaseProps } from "./context"; /* @@ -279,19 +280,28 @@ export function MergeSection({ form, setForm, integrationBranchOptions, integrat {form.mergeStrategy === "pull-request" && <> -
-
- - {t("settings.merge.requiredChecksHelp", "No default — unset. Comma-separated check names match GitHub exactly (case-sensitive). Leaving this empty uses GitHub required-status checks only; a named check that never reports blocks the merge.")} -
- { - const rawValue = event.target.value; + {/* + FNXC:SettingsSearch 2026-08-16-05:07: + FN-8855 (d59c1b162f) indexed requiredChecks in MergeSection.search.ts but rendered it as a + bespoke label/input, so the search result had no `data-settings-key` anchor to scroll to and + the drift guard flagged the entry as stale. The row composes the typed SettingsTextRow like + its descriptor-row neighbors: same label/help copy, same comma-list parsing on change. + */} + { + const rawValue = nextValue ?? ""; setRequiredChecksInput(rawValue); const requiredChecks = resolveRequiredCheckNames({ requiredChecks: rawValue.split(",") }); emittedRequiredCheckNames.current = requiredChecks; setForm((current) => ({ ...current, requiredChecks: requiredChecks.length > 0 ? requiredChecks : undefined })); - }}/> -
+ }} + />