diff --git a/frontend/src/__tests__/new-project-starter-sections.test.ts b/frontend/src/__tests__/new-project-starter-sections.test.ts index ddd0568b..9cfe9418 100644 --- a/frontend/src/__tests__/new-project-starter-sections.test.ts +++ b/frontend/src/__tests__/new-project-starter-sections.test.ts @@ -2,10 +2,11 @@ * NewProjectDialog starter sections — display order and overlay cards. * * The dialog hardcodes its sections; overlay-registered kinds (M5Stack, - * the partner sections, XIAO C6, XIAO RP2040) surface only when the private - * overlay registered them. Guards the operator's requested order: the - * partner sections (M5Stack, Seeed Studio, DFRobot, Pimoroni, Espressif) - * sit between ESP32 and STM32, and an OSS build shows none of them empty. + * the partner sections, the XIAO overlay variants) surface only when the + * private overlay registered them. Guards the operator's requested order: + * the partner sections (M5Stack, DFRobot, Pimoroni, Espressif) sit between + * ESP32 and STM32, Seeed boards live inside the chip-family sections, and + * an OSS build shows no empty partner block. */ import { describe, it, expect } from 'vitest'; import { buildStarterSections } from '../components/editor/NewProjectDialog'; @@ -46,6 +47,16 @@ describe('NewProjectDialog starter sections', () => { expect(m5.entries[0].blurb).toBe('ESP32-S3 card computer'); }); + it('the S3 Sense joins the ESP32 section, not a section of its own', () => { + const secs = buildStarterSections([def('xiao-esp32s3-sense', 'XIAO ESP32-S3 Sense', 'x')]); + expect(secs.map((s) => s.title)).not.toContain('Seeed Studio'); + const esp32 = secs.find((s) => s.title === 'ESP32')!; + expect(esp32.entries.map((e) => e.kind)).toContain('xiao-esp32s3-sense'); + // Right after its sibling XIAO S3. + const kinds = esp32.entries.map((e) => e.kind); + expect(kinds.indexOf('xiao-esp32s3-sense')).toBe(kinds.indexOf('xiao-esp32-s3') + 1); + }); + it('full partner overlay: sections sit between M5Stack and STM32, catalog order', () => { const defs = [ def('cardputer-adv', 'M5 Cardputer ADV', 'x'), @@ -61,7 +72,6 @@ describe('NewProjectDialog starter sections', () => { 'Arduino', 'ESP32', 'M5Stack', - 'Seeed Studio', 'DFRobot', 'Pimoroni', 'Espressif', diff --git a/frontend/src/components/editor/NewProjectDialog.tsx b/frontend/src/components/editor/NewProjectDialog.tsx index 98289a30..dbb36371 100644 --- a/frontend/src/components/editor/NewProjectDialog.tsx +++ b/frontend/src/components/editor/NewProjectDialog.tsx @@ -256,12 +256,16 @@ export function buildStarterSections(defs: ProBoardDef[]): StarterSection[] { }, // One card per ESP32 chip generation, XIAO variant preferred where // Seeed makes one: classic → DevKit V1, S3/C3 → XIAO, C6 → XIAO (overlay). + // The S3 Sense sits here next to its sibling — a separate Seeed section + // would repeat a brand this section already carries (operator call, + // 2026-08-28). { title: 'ESP32', entries: [ oss('esp32'), oss('esp32-cam'), oss('xiao-esp32-s3'), + ...pro('xiao-esp32s3-sense'), oss('xiao-esp32-c3'), ...pro('xiao-esp32c6'), ], @@ -272,10 +276,8 @@ export function buildStarterSections(defs: ProBoardDef[]): StarterSection[] { { title: 'M5Stack', entries: [...pro('cardputer-adv'), ...pro('m5stack-core')] }, // Hardware partners (overlay kinds, same shape as M5Stack): each section // lists only the boards the overlay actually registered, so an OSS build - // and launch-embargoed items (e.g. the Espressif devkits pre-launch) - // simply render nothing. The XIAO S3/C3/C6 and XIAO RP2040 stay in the - // chip-family sections above as the generation representatives. - { title: 'Seeed Studio', entries: [...pro('xiao-esp32s3-sense')] }, + // and launch-embargoed items simply render nothing. Seeed gets no section + // of its own — its boards live in the chip-family sections above. { title: 'DFRobot', entries: [...pro('unihiker-m10')] }, { title: 'Pimoroni',