TL;DR
Add a new fbuild port scan CLI command that walks every visible serial port and renders two rows per port:
- Row 1 — port path + raw VID:PID + the OS descriptor string
- Row 2 — resolved vendor + product name from the FastLED/boards SQLite-over-HTTP database
The point is "what is plugged in?" answered without leaving the terminal. Today the closest thing is fbuild serial probe list (#686) which annotates each port from a tiny hardcoded BOARD_FINGERPRINTS table — useful for boards we ship support for, blank for everything else. port scan consults the full FastLED/boards aggregate instead, so an unrecognized USB device shows the actual vendor + product name (e.g. Adafruit / Feather M4 Express rather than [empty]).
Where the data comes from
The canonical lookup source moved out of fbuild's own online-data branch into the public FastLED/boards repo's published portal: https://fastled.github.io/boards/.
Endpoints (from FastLED/boards README.md):
The portal at fastled.github.io/boards/ does VID → vendor + VID:PID → product lookups client-side over site.db via sql.js (WASM). For fbuild's CLI use, we should pull the same data — either by mirroring site.db through the existing nightly data pipeline, OR by hitting site.db directly with a tiny rusqlite-over-http path.
In the meantime, the existing tiered resolver at fbuild_core::usb::resolve(vid, pid) (#712 + #717 + #719) already returns UsbInfo { vendor, product } via:
- Tier 1 — embedded vendor archive (compile-time
include_bytes!) — vendor names only
- Tier 2 — runtime overlay loaded from the daemon-managed cache — full
{vendor, product}
- Tier 3 — synthetic
Unknown vendor 0xVVVV placeholder
So the first cut of fbuild port scan can ship on the existing resolver and the tier-2 cache backing it. Pointing tier-2 at the FastLED/boards site is a follow-up wire-up question (separate issue) — this command's contract is "use whatever the resolver returns."
Proposed output shape
$ fbuild port scan
COM25 303A:1001 USB Serial Device (COM25) ser=80:F1:B2:D1:DF:B1
└─ Espressif Systems / ESP32-S3
COM20 16C0:0483 USB Serial Device (COM20) ser=15821020
└─ PJRC / Teensy 4.0
COM10 1FC9:0132 USB Serial Device (COM10) ser=0B03400A
└─ NXP / LPC-Link2 CMSIS-DAP
COM3 0000:0000 [Unknown]
└─ Unknown vendor 0x0000 / Unknown product 0x0000
3 USB ports, 1 non-USB
The └─ continuation prefix makes the second row visually subordinate to the first. Unknown VID:PID still emits the second row (with the synthetic fallback from the resolver) — every port always gets exactly two rows so the table is uniform.
Why a new command and not an extension of serial probe list
serial probe list is the small-footprint hardcoded-table fingerprint path — fast, no I/O, useful when an agent is debugging a known FastLED-ecosystem board. Keep it as-is.
port scan is the richer 'use the canonical database' path. Different intent, different data source — they're complementary.
The naming also follows the FastLED side's bash autoresearch <board> precedent: scan reads as "go look harder."
Acceptance criteria
Out of scope (follow-ups)
- Pointing tier-2 of the resolver at FastLED/boards
site.db directly (today it consumes fbuild's own online-data branch). Separate issue.
- A
--json output mode (likely a quick follow-up; not blocking the first cut).
- Filtering / sorting flags (
--vid, --vendor, --unknown-only).
Refs
Filed via Claude Code.
TL;DR
Add a new
fbuild port scanCLI command that walks every visible serial port and renders two rows per port:The point is "what is plugged in?" answered without leaving the terminal. Today the closest thing is
fbuild serial probe list(#686) which annotates each port from a tiny hardcodedBOARD_FINGERPRINTStable — useful for boards we ship support for, blank for everything else.port scanconsults the full FastLED/boards aggregate instead, so an unrecognized USB device shows the actual vendor + product name (e.g.Adafruit / Feather M4 Expressrather than[empty]).Where the data comes from
The canonical lookup source moved out of fbuild's own
online-databranch into the public FastLED/boards repo's published portal: https://fastled.github.io/boards/.Endpoints (from FastLED/boards
README.md):_meta)The portal at
fastled.github.io/boards/does VID → vendor + VID:PID → product lookups client-side oversite.dbvia sql.js (WASM). For fbuild's CLI use, we should pull the same data — either by mirroringsite.dbthrough the existing nightly data pipeline, OR by hittingsite.dbdirectly with a tiny rusqlite-over-http path.In the meantime, the existing tiered resolver at
fbuild_core::usb::resolve(vid, pid)(#712 + #717 + #719) already returnsUsbInfo { vendor, product }via:include_bytes!) — vendor names only{vendor, product}Unknown vendor 0xVVVVplaceholderSo the first cut of
fbuild port scancan ship on the existing resolver and the tier-2 cache backing it. Pointing tier-2 at the FastLED/boards site is a follow-up wire-up question (separate issue) — this command's contract is "use whatever the resolver returns."Proposed output shape
The
└─continuation prefix makes the second row visually subordinate to the first. Unknown VID:PID still emits the second row (with the synthetic fallback from the resolver) — every port always gets exactly two rows so the table is uniform.Why a new command and not an extension of
serial probe listserial probe listis the small-footprint hardcoded-table fingerprint path — fast, no I/O, useful when an agent is debugging a known FastLED-ecosystem board. Keep it as-is.port scanis the richer 'use the canonical database' path. Different intent, different data source — they're complementary.The naming also follows the FastLED side's
bash autoresearch <board>precedent:scanreads as "go look harder."Acceptance criteria
fbuild port scansubcommand exists infbuild-cli.└─ vendor / product).fbuild_core::usb::resolve(vid, pid), NOT the small hardcoded board fingerprints table.Vec<PortInfo>and emits aStringso tests can pin the row shape without hardware.Unknown vendor 0x… / Unknown product 0x…row instead of being skipped — every port always gets exactly two rows.Out of scope (follow-ups)
site.dbdirectly (today it consumes fbuild's ownonline-databranch). Separate issue.--jsonoutput mode (likely a quick follow-up; not blocking the first cut).--vid,--vendor,--unknown-only).Refs
fbuild serial probe list(the existing hardcoded-fingerprint path; not replaced).Filed via Claude Code.