Skip to content

feat(gui): introduce product-manifest seam#150

Merged
PAMulligan merged 2 commits into
mainfrom
feat/gui-manifest-seam
Jun 22, 2026
Merged

feat(gui): introduce product-manifest seam#150
PAMulligan merged 2 commits into
mainfrom
feat/gui-manifest-seam

Conversation

@PAMulligan

Copy link
Copy Markdown
Collaborator

What & why

Step 1 of evolving packages/gui from the Flavian-only desktop app into a generic engine that
renders any PMDS product (Flavian, Aurelius, Nerva) from a typed descriptor — the unified
destination is Trajan. This PR extracts the implicit "what Flavian exposes" knowledge into an
explicit ProductManifest, with zero user-visible behaviour change.

See packages/gui/docs/GUI-PLATFORM.md for the three-layer architecture and the staged plan.

Three layers

  • Shared engine — generic core/main/renderer + the manifest interpreters. Knows no product.
  • Per-product manifestsrc/shared/product/ (pure, node-free data). Declares identity, project
    markers, and screens → steps → (command, parser, prerequisites). Reuses the engine's existing
    vocabulary (TaskKind, DockerCommand, QaScript, PipelineKind, ThemeStarter).
  • Per-product specifics — the bespoke *Panel.tsx, now reading their step catalogs from the manifest.

Changes

  • New src/shared/product/: manifest.ts (the type), flavian.ts (a faithful reproduction of
    today's catalog), index.ts (registry + activeManifest + selectors), aurelius.ts (typed
    extension-point scaffold, intentionally not wired in).
  • New src/core/product/: command-spec.ts (CommandDescriptorRunSpec) and parsers.ts
    (output-parser registry).
  • main/index.ts injects activeManifest into registerHandlers; handlers build specs, select
    parsers, and derive dialog copy from it.
  • core/{locate-root,run-prerequisites,pipeline-run,run-init} take their product specifics as
    inputs; removed the now-dead docker-commands.ts, qa-commands.ts, paths.ts.
  • renderer/App.tsx reads brand + nav from the manifest; the panels + project gate read their
    catalogs from it.

Extension point (Aurelius)

A second product is just another manifest: author src/shared/product/aurelius.ts, register it in
index.tsPRODUCTS, and flip ACTIVE_PRODUCT_ID. No engine/core/renderer change. A typed
scaffold is included, intentionally inactive.

Deferred (noted in the doc)

Panel presentation prose, the window.flavian / flavian:* bridge namespace, and build identity
(@flavian/gui, window title, installer name) stay "Flavian" for now — shared transport / build
identity, out of scope for this behaviour-preserving seam.

Test plan

  • pnpm --filter @flavian/gui typecheck ✅ (node + web)
  • pnpm --filter @flavian/gui lint
  • pnpm --filter @flavian/gui test53 passed (was 41; adds the command-spec + manifest engine tests)
  • pnpm --filter @flavian/gui build
  • pnpm --filter @flavian/gui smoke ✅ packaged app launches; shell brand renders Flavian

🤖 Generated with Claude Code

PAMulligan and others added 2 commits June 22, 2026 18:28
Extract the implicit "what Flavian exposes" knowledge into an explicit, typed
ProductManifest so the GUI engine can render any PMDS product from a descriptor —
groundwork toward the unified Trajan app. Zero user-visible behaviour change.

- Add the ProductManifest type and flavianManifest in src/shared/product (pure,
  node-free data; reuses TaskKind/DockerCommand/QaScript/PipelineKind/ThemeStarter).
- Engine reads from the active manifest: a command-spec interpreter + parser registry
  in core/product, the manifest injected into registerHandlers, and the renderer shell
  reading brand + nav from it.
- Panels read their step catalogs from the manifest; remove the now-dead
  docker-commands / qa-commands / paths modules.
- Mark the extension point with a typed Aurelius scaffold (a second product is just
  another manifest), intentionally not wired in.
- Add tests proving the engine renders commands/screens from a manifest; keep the
  packaged smoke test green.
- Brief: packages/gui/docs/GUI-PLATFORM.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The "active product is Flavian" test compared the registry's manifest to a
directly-imported flavianManifest by reference. That relies on the tsx test loader
deduping two import specifiers (the barrel's ./flavian vs the test's direct import)
to one module instance — true on case-insensitive Windows, but on Linux CI flavian.ts
is evaluated twice, so the objects are structurally equal but not reference-equal.

Compare activeManifest to PRODUCTS.flavian (same registry module — always
reference-safe) and check id/displayName by value. Production is unaffected:
electron-vite bundles main and renderer separately and the barrel dedupes per bundle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@PAMulligan PAMulligan self-assigned this Jun 22, 2026
@PAMulligan PAMulligan added pipeline Figma/Canva-to-WordPress conversion pipeline javascript Pull requests that update javascript code labels Jun 22, 2026
@PAMulligan PAMulligan merged commit 038f03b into main Jun 22, 2026
18 checks passed
@PAMulligan PAMulligan deleted the feat/gui-manifest-seam branch June 22, 2026 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

javascript Pull requests that update javascript code pipeline Figma/Canva-to-WordPress conversion pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant