Shad dba1eb3328
Some checks failed
build-and-publish / test (push) Has been cancelled
build-and-publish / image (push) Has been cancelled
feat(theme): promote industrial blueprint to the whole shell
Every scene now reads as the same FM doctrine: paper canvas + navy
frame + amber accent, 1px hairlines, square edges, monospace
uppercase labels, no glass, no shadows, no gradients.

WHAT CHANGED
- src/index.css rewritten end-to-end. Doctrinal hex tokens declared
  at :root, legacy --bg/--surface/--text/--primary/--border aliases
  repointed at doctrine values so existing component classes inherit
  the blueprint palette without per-component churn. Global
  * { border-radius: 0 } + box-shadow strip-out. All low-opacity
  tints via color-mix(in srgb, var(--bp-navy) X%, transparent) so no
  rgba() literals survive.
- Topbar redone as a 44px instrument strip: navy brand-lock with
  amber mark, uppercase mono tabs, amber-on-paper selected tab,
  square link buttons, mode pill with currentColor border.
- Mission Control hero + scenario tab strip + KPI cards retoken
  with amber underline on selected.
- Left rail: 1px-bordered KPI grid, queue cards stack as a single
  bordered list, agent supervision actions span the full width.
- Inspector: tabbed nav with amber selected, hairline-separated
  fields, square rule + run + evidence cards.
- Command palette: paper bg, amber-bordered selected item, mono
  caps headings.
- Live API console: paper drawer, mono call rows, amber filter chip,
  color-tokenised METHOD_COLOR map.
- Toaster: left-border accent on paper surface.
- Telemetry: navy gauges, mono row, square tick.
- Studio + Settings: shared studio-grid layout — paper panels in a
  1px navy grid with no margins between, mono inputs.
- Run History: mono table rows with amber selected filter chip.
- Landing: mono hero, square brand mark, stats strip as one
  bordered row, scenario cards in a 1px grid (no glow, no shadow,
  no gradient).
- Family accents in synthetic.ts and buildScenarios.ts retoken to
  doctrine hex. src/scenarios.json snapshot patched in place.
- Console.tsx METHOD_COLOR map → var(--bp-muted/info/amber/err).

AUDIT
- qa/palette_audit.mjs upgraded: scans 31 source files (.ts/.tsx/
  .json + index.css), catches rgb()/rgba()/hsl()/hsla() literals,
  and refuses named CSS colors (white/red/blue/...) as background/
  color/fill/stroke/border values. Hex regex uses (?![0-9a-fA-F])
  lookahead so deploy-id text like '#d3f1a' is not a false positive.
  Result: 0 non-doctrinal literals anywhere in src/.
- qa/smoke.mjs + qa/smoke_blueprint.mjs hasText matches converted
  to case-insensitive regex because the doctrine uppercases every
  user-visible label via text-transform: uppercase.
- qa/snap_all_scenes.mjs captures 9 fresh 1440x900 screenshots
  in qa/screenshots/v4/ (landing, mission procurement, mission AR
  blueprint, inspector raw, command palette, studio, settings,
  run history, mission live with console).

VERIFY
- tsc -b clean
- vite build green (CSS 41 KB / 8 KB gz, JS 851 KB / 230 KB gz)
- vitest 5 files / 24 tests green
- main smoke 27/27, 0 console errors
- blueprint smoke 15/15, 0 console errors
- palette audit clean (31 files)

ORACLE-REVIEWED
Round 1 PASS with <promise>VERIFIED</promise>. Two non-blocking
audit hardening notes landed in this same commit: scan JSON,
catch rgb/hsl/named CSS colors.

Confidence: high
Scope-risk: moderate (theme sweep, all scenes touched)
Not-tested: pixel-level visual diff vs prior theme (Oracle could
not inspect images this round; relied on programmatic checks)
2026-06-14 02:12:11 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:30:57 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00
2026-06-14 00:09:32 +04:00

FlowMaster — Mission Control demo

A polished, presenter-ready command-center for FlowMaster. Lives at shad/flowmaster-mission-control-demo on Gitea.

What this is (and isn't)

Is:

  • A single-page React 19 app (Vite + ReactFlow + cmdk + framer-motion + zustand
    • dagre).
  • Polished command-center for any FlowMaster process: graph, queue, inspector, tour, command palette, live-mode toggle, run history.
  • Two data modes:
    • SNAPSHOT (default): bundled src/scenarios.json, captured from demo.flow-master.ai. Fast, offline, deterministic.
    • LIVE: in-browser fetch from the same backend via the API client at src/lib/api.ts (dev-login → bearer → /api/ea2/work-items/api/ea2/process-definitions/{k}/graph/api/runtime/transactions/{id}). Loading and error states are wired through src/scenes/MissionControl.tsx.

Isn't:

  • Not a replacement for the existing demo at https://demo.flow-master.ai (Next.js fm-shell). This is a separate command-center experience.
  • Not multi-tenant. No auth UI, no tenancy switcher, no settings.
  • Not wired to actually mutate state. Every action button (start runtime, dispatch agent, approve, decline, confirm) is preview-only and fires a toast naming the endpoint that would make it real.

Scenarios in the catalog

id mode source
procurement live Purchase Requisition → PO (pr_to_po_def on demo.flow-master.ai)
extra-1 live Atlas F1 Fresh (procurement variant)
extra-2 live Atlas F1 Fresh (procurement variant)
ar blueprint AR · Customer Refund Approval
hcm blueprint HCM · New Hire Onboarding
gl blueprint GL · Period-End Close
service blueprint Service Ops · Customer Incident

Live = backed by a real EA2 process definition currently in the demo backend, with real runtime transactions and a real work-item queue.

Blueprint = hand-modelled in the same typed format. Identical UI surface; the backend just doesn't have a runnable definition for it yet. Internal metadata carries isSynthetic: true for provenance audits.

How honesty is enforced in this code

This pass came out of an Oracle review that called out theatrical bits in the prior version. Safeguards now in place:

  • No invented numbers. src/components/Telemetry.tsx derives every value from the active scenarios (SLA = 1 - errored / cases, agent acceptance = fraction of agent runs not in proposed). The throughput sparkline plots the actual running rollup over time, not a sine wave. The "ui tick" dot is labelled as a UI heartbeat and tooltip-named as such.
  • No fake buttons. Every preview-only action fires a toast that names the endpoint that would make it real, and carries a preview marker.
  • No misleading tour copy. Blueprint tours frame the scenario as an industry blueprint, not "we don't have this yet".
  • Mode is always visible. Topbar has a SNAPSHOT/LIVE pill, last-fetch age, and a refresh button when live.

Live-mode mechanics (the CORS gotcha)

demo.flow-master.ai does not advertise CORS headers for arbitrary origins. src/lib/api.ts therefore uses an empty baseUrl everywhere (both dev and prod). All /api/* requests are same-origin from the browser's perspective; whatever is serving the page is responsible for proxying them to the backend.

  • Dev (pnpm dev): vite.config.ts proxies /api/* to ${VITE_FM_BASE:-https://demo.flow-master.ai}.
  • Prod (Docker image): the bundled nginx.conf reverse-proxies /api/* to https://demo.flow-master.ai. The image is intended to sit behind the mc.flow-master.ai ingress (see FM06/flowmaster-ops overlay).
  • Anywhere else: set VITE_FM_BASE=https://your-backend at build time and accept that browsers will reject the cross-origin call. Live mode then fails gracefully — setMode("live") catches the error, raises an mc-banner-err banner + error toast, and falls back to snapshot.

Run, test, build

pnpm install

# refresh the bundled snapshot from demo.flow-master.ai
pnpm fetch:scenarios

# dev (with backend proxy for live mode)
pnpm dev                                # → http://127.0.0.1:5173

# tests
pnpm test                               # vitest, 22 tests across api, live,
                                        # synthetic, layout, store

# build
pnpm build                              # tsc + vite, single chunk ~225 KB gz

# end-to-end smoke + screenshots
pnpm qa:smoke                           # playwright headless, 28 assertions

# DOM layout audit
pnpm qa:layout

File map

src/
├── data/                    # ProcessScenario domain + snapshot + blueprint catalog
├── lib/                     # API client + live-scenario builder (+ tests)
├── state/store.ts           # zustand: scene, mode, scenario, tour, recents, toasts
├── graph/layout.ts          # dagre LR auto-layout (+ tests)
├── components/              # ProcessGraph, Inspector, LeftRail, CommandBar, Tour,
│                            # Telemetry, Toaster, icons
├── scenes/                  # Landing, MissionControl, RunHistory
├── App.tsx                  # shell: topbar (mode pill / refresh / tour / ⌘K)
├── index.css                # design system (~700 lines)
├── main.tsx
└── scenarios.json           # cached snapshot of demo.flow-master.ai

qa/
├── smoke.mjs                # Playwright e2e + 9 screenshots
└── layout_audit.mjs         # programmatic clipping/overlap check

vite.config.ts               # /api → demo.flow-master.ai proxy for dev
fetch_scenarios.mjs          # Node script to refresh src/scenarios.json

Deploy

Production deployment is tracked in FM06/flowmaster-ops PR #1164, which adds three resources to manifests/overlays/demo/:

  • mc-deployment.yaml — 2-replica nginx Deployment in the demo namespace
  • mc-service.yaml — ClusterIP service on port 80
  • mc-ingress.yaml — Traefik ingress at mc.flow-master.ai with cert-manager DNS-01 cert

Status: the PR is open and mergeable. The live URL https://mc.flow-master.ai is not yet serving — two pre-merge action items remain for the trusted updater:

  1. Cloudflare A record mc.flow-master.ai → 65.21.71.186, 91.98.159.56 (same as hakeem.flow-master.ai).
  2. Gitea Actions must have published the first image tag (gitea.flow-master.ai/shad/mission-control-demo:sha-…) — mc-deployment.yaml pins that explicit SHA, not :latest.

Until the PR merges + DNS is added, the artifact is this repo + the open PR.

pnpm build
# dist/ is the static site. The Dockerfile bakes it into a tiny nginx
# image. CI in .gitea/workflows/build.yml builds + publishes on push to main.

What's intentionally not here

  • Authentication UI (dev-login is used because this is a demo lane).
  • Mutation endpoints (every action is preview-only and the toast names the endpoint).
  • Mobile layout (1440px-and-up demo surface).
  • Route persistence / deep linking (scene + scenario live in memory).
  • i18n (English only).

Small, well-scoped follow-ups — not architectural changes.

Description
FlowMaster Mission Control demo — a polished, presenter-ready command-center that runs against demo.flow-master.ai (live mode) or a bundled snapshot, with industry-blueprint scenarios for AR, HCM, GL Close, and Service Ops.
Readme 456 KiB
Languages
TypeScript 64.5%
CSS 19.1%
JavaScript 16%
Dockerfile 0.2%
HTML 0.2%