circuitforge-core/docs/developer/display-package.md
pyr0ball 6d82f3561f
Some checks failed
CI / test (pull_request) Has been cancelled
feat(display): add @circuitforge/display strip-display Vue package
New packages/display/ — Vue 3 primitives for products running a secondary
1920x480 landscape / 480x1920 portrait kiosk display, per the strip display
spec. First non-Python module in this repo; published as its own npm
package (not part of the Python circuitforge-core distribution) so products
that don't use a strip display never pull in Vue as a dependency.

- DisplayLayout — root wrapper: identity zone, orientation-aware grid
  (landscape/portrait), dark-default theme, #metrics/#alerts/#macros slots.
- DisplayMetric — value/label tile with optional unit, severity colour,
  sparkline.
- DisplayAlert — timestamped, severity-coloured alert row.
- DisplayMacroButton — touch target (44px+ min) emitting a
  shell/url/api/display_switch action payload; execution stays product-side.
- theme.ts — central theme file: CSS custom properties (dark/light) plus
  UnoCSS theme/shortcut fragments for products that already run UnoCSS
  (Turnstone, Robin) to spread into their own uno.config.ts.
- launcher/launcher.html — static, framework-free product switcher reading
  a sibling launcher.config.json.

37 Vitest tests across all four components; vue-tsc type-checks clean;
vite build produces ESM/CJS bundles + CSS + .d.ts.

First consumer: Turnstone's sysadmin profile (turnstone#25, currently
blocked on this ticket).

Closes: #69
2026-07-10 18:29:21 -07:00

2.2 KiB
Raw Permalink Blame History

@circuitforge/display — Vue package

packages/display/ is the first non-Python module in circuitforge-core: Vue 3 primitives for CircuitForge products running a secondary strip display (1920×480 landscape / 480×1920 portrait kiosk). Design spec: circuitforge-plans/circuitforge-core/superpowers/specs/2026-05-17-strip-display-spec.md.

Why a separate npm package, not circuitforge_core

Most products in the menagerie are Python-only and never touch Vue. Publishing @circuitforge/display as its own npm package — rather than bundling it into the Python circuitforge-core distribution — means:

  • Products that don't use a strip display (most of them) never pull in Vue as a transitive dependency.
  • Versioning follows npm semver independently of the Python package's release cadence — a Vue component API change doesn't force a circuitforge-core PyPI bump, and vice versa.
  • The build tooling (Vite, vue-tsc, Vitest) stays isolated in packages/display/, not mixed into the Python pyproject.toml/pytest setup.

This mirrors the reasoning behind keeping the BSL resources module split into the separate circuitforge-orch package — different consumers, different release cycles, kept apart even though both live in adjacent repos/directories.

Location and consumers

  • Package root: packages/display/
  • First consumer: Turnstone's sysadmin profile (turnstone#25) — CPU/RAM/disk/network metrics, live alert feed, service macro buttons
  • Planned: Robin's proactive assistant overlay

Working on it

cd packages/display
npm install
npm test          # Vitest — 37 tests across the four components
npm run build     # vue-tsc --emitDeclarationOnly && vite build → dist/

Gotcha to watch for: Vite's build.emptyOutDir defaults to true and will silently wipe the .d.ts files vue-tsc --emitDeclarationOnly just wrote, since both commands target the same dist/. vite.config.ts sets emptyOutDir: false to prevent this — don't remove it without changing the build order.

See packages/display/README.md for the component API, theming (src/theme.ts is the central theme file — CSS custom properties + UnoCSS fragments for products that already run UnoCSS), and the launcher page.