From eea4ee53dbdf158c87a65a0be6c4cd2e3c58e478 Mon Sep 17 00:00:00 2001 From: canvas-bot Date: Mon, 15 Jun 2026 01:14:33 +0400 Subject: [PATCH] docs(readme): align with shipped canvas product The previous README still described this as a 1440-px-only, no-auth-UI, preview-only-actions demo. The actual product has SSO, EA2-backed Process Studio, Hubs, Geo Attendance, internal Chat, Command Assistant + per-tenant memory, three personas, and a deterministic-or-LLM agent path. Rewrite to match what ships. --- README.md | 211 ++++++++++++++++++++---------------------------------- 1 file changed, 77 insertions(+), 134 deletions(-) diff --git a/README.md b/README.md index e152443..8fd117d 100644 --- a/README.md +++ b/README.md @@ -1,168 +1,111 @@ -# FlowMaster — Mission Control +# FlowMaster — Canvas -**Live at https://canvas.flow-master.ai** · [source on Gitea](https://gitea.flow-master.ai/shad/flowmaster-mission-control-demo) +**Live at https://canvas.flow-master.ai** · operations cockpit for every process the company runs. -The proper FlowMaster frontend: an operations cockpit for every process the -company runs. Industrial-blueprint doctrine — paper canvas, navy frame, -amber accent, 1px hairlines, square edges, monospace operational density. +Canvas is the FlowMaster operator surface. Industrial-blueprint doctrine: +paper canvas, navy frame, amber accent, 1px hairlines, square edges, +monospace operational density. People, Finance, Procurement, and IT in +one frame. -## What this is (and isn't) +## What it is -**Is:** +- React 19 single-page app (Vite + ReactFlow + cmdk + framer-motion + + zustand + dagre + leaflet). +- Connected directly to EA2 in the browser via the API client at + `src/lib/api.ts`. EA2 is the runtime source of truth. +- Microsoft SSO is the primary sign-in path. The login screen probes + `/api/v1/auth/microsoft/login` on mount and only enables the SSO + button when the redirect is wired; the dead-button state is honest + ("not configured" / "not wired") instead of silently failing. + Developer dev-login remains as a fallback for the demo lane. -- 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`. +## Scenes -**Isn't:** +- Landing — entry surface with persona switcher and recent processes. +- Mission Control — live work-items + reactflow process graph + inspector. +- Approvals — work waiting on the signed-in operator. +- Run History — recent runtime transactions and outcomes. +- Process Studio (Wizard) — the Process Creation Wizard, ported from + dev.flow-master.ai. Intake → analyze → generate → validate → publish. + Writes to EA2 at every step via `src/lib/wizardApi.ts`. +- Hubs (HR / Finance / Procurement / IT) — department lenses over the + EA2 catalog. Each hub focuses Mission Control, surfaces hub-specific + KPIs, and exposes the start-process actions the hub head can take. +- Geo Attendance — leaflet map (OpenStreetMap tiles) showing per-site + attendance status from `src/lib/attendanceApi.ts`. +- Chat — internal employee ↔ manager messaging (`src/lib/chatApi.ts`), + threaded, text-only. Replaces booting Teams for "what laptop?" type + questions. +- Command Assistant (Agent) — chat surface with deterministic tools + (`src/lib/agentTools.ts`) for navigation, process start, chat send, + retain / recall against per-tenant memory. When the LLM proxy + (`llm-proxy/`) is configured the assistant also synthesises fluent + natural-language replies; when it isn't, the deterministic path + still works. +- Documents — data shapes per process. +- Explainer — "What is FlowMaster?" recalled from the FlowMaster + explainer and rendered in-product. +- Settings — identity, theme, polling cadence, console default. +- Login / SSO callback. -- 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. +## Three view-as personas -## Scenarios in the catalog +Bundled in `src/data/personas.ts`. Switching persona re-signs in under +the persona's email so the operator UI reflects that seat. -| 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 | +| Persona | Title | Default hub | +|---------|----------------------|--------------| +| Mariana | Chief Executive | Finance | +| Aisha | Head of People (HR) | HR | +| Rohan | Head of IT | IT | -**Live** = backed by a real EA2 process definition currently in the demo -backend, with real runtime transactions and a real work-item queue. +## Agent + per-tenant memory -**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. +`src/lib/agentMemory.ts` keeps three fact kinds (world / experience / +opinion) keyed by tenant + user. The agent calls deterministic tools +defined in `src/lib/agentTools.ts`. When `OPENAI_API_KEY` or +`ANTHROPIC_API_KEY` is set on the `llm-proxy/` sidecar, the agent layers +LLM responses on top of the tool output; otherwise it falls back to the +deterministic display strings. -## 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 - `canvas.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. +The proxy lives in `llm-proxy/main.py` (FastAPI, no streaming, no tool +calls, no images). The shape mirrors `@earendil-works/pi-ai`'s +normalized completions so a forked Pi coding agent can drop in later +without changing the browser contract. ## Run, test, build ```bash 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 +pnpm test # vitest # 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 +pnpm build # tsc + vite ``` ## Deploy -Production deployment is tracked in -[FM06/flowmaster-ops PR #1164](https://gitea.flow-master.ai/FM06/flowmaster-ops/pulls/1164) -(merged), which added 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 `canvas.flow-master.ai` with cert-manager DNS-01 cert - -Cloudflare A record `canvas.flow-master.ai → 65.21.71.186` was added at the -same time. The cluster certifies with cert-manager (Let's Encrypt DNS-01) -and Traefik fronts the nginx pods. nginx reverse-proxies `/api/*` to -`https://demo.flow-master.ai` so the SPA is same-origin (no CORS). +Deployment is tracked in `FM06/flowmaster-ops`, overlay +`manifests/overlays/demo/`. nginx in the image reverse-proxies `/api/*` +to the EA2 backend so the SPA is same-origin (no CORS). ```bash -pnpm build # builds dist/ -docker build -t gitea.flow-master.ai/shad/mission-control-demo:sha- . -docker push gitea.flow-master.ai/shad/mission-control-demo:sha- +pnpm build +docker buildx build --platform linux/amd64 \ + -f Dockerfile.runtime \ + -t gitea.flow-master.ai/shad/canvas-frontend:sha- \ + --load . +docker push gitea.flow-master.ai/shad/canvas-frontend:sha- # Then bump the image pin in manifests/overlays/demo/mc-deployment.yaml. ``` -## What's intentionally not here +## Source -- 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. +`gitea.flow-master.ai/shad/canvas-frontend` is the authoritative source +for canvas.flow-master.ai. The earlier `flowmaster-mission-control-demo` +repository is retained for history but no longer deployed.