@leumas/workflows-web
Leumas Workflows at workflows.leumas.tech — triggers, actions and workflows: build them in the browser, dry-run them free, run them with a key.
@leumas/workflows-web — Leumas Workflows at workflows.leumas.tech
When this happens, do that. The workflow engine inside Leumas Studio, on the web: a member-grade builder over the same eight node types, the same validator and the same stepper, with a free dry run in front and a metered, owner-scoped run lane behind.
Status: built. Blueprint: products/TODOS/workflows.leumas.tech.md (§6a records the decisions made while building).
What is where
| Piece | Lives in |
|---|---|
| The vocabulary, validator, stepper, templates | @leumas/workflows (shared/packages/workflows) — unchanged |
| The dry run (echo runner, isomorphic) | @leumas/workflows/dryrun |
| What a member's graph may reach (isomorphic) | @leumas/workflows/member-policy |
| The builder, the trace, the gallery glyph | @leumas/workflows/react (WorkflowBuilder, RunTrace, FlowGlyph) |
| The member lane | products/leumas-api/src/{controllers,routes}/workflowsSite.js → /api/workflows/{status,catalogue,templates,dryrun,mine/*} |
| The money | PLAN_CATALOG workflows $15 · policy.js workflows.* (floor: build + dryrun; plan: saves, run, monthlySteps, arm, webhook, keys, runRetentionDays) |
| The SDK | @leumas/workflows-sdk |
| This site | src/content/pages.js (the prose as data) · src/content/catalogue.generated.js (from the registries at build) · src/screens/* |
| Guards | pnpm check:workflows-public · pnpm check:workflows-metered · pnpm smoke:workflows-site |
The catalogue is generated
scripts/gen-catalogue.mjs reads createTriggerRegistry().listManifests(), createActionRegistry().listManifests(), the connectors registry and every workflow catalogue, and writes src/content/catalogue.generated.js. One page per trigger, action, app and template is derived from it; check:workflows-public holds the page table to the file both ways. Never type a count.
Three doors, one meter
A run from the browser, from a key (POST /api/workflows/mine/:id/run, Authorization: Bearer lk_… with the workflows scope) and from an armed rule (run-workflow, bound in app.js to the site's runForOwner) all pass walk() in the controller: reserve against workflows.monthlySteps, step, record a workflow_runs row. check:workflows-metered asserts the connections. The dry run is the one door that stays free, because it executes nothing.
Why this can read a visitor's session with no configuration
workflows.leumas.tech is a platform-owned Imperium site row (shared/services/index/src/workflowsSite.js), served by the Imperium worker behind the IIS *.leumas.tech wildcard. That worker forwards /api and the auth prefixes to leumas-api preserving the visitor's Host header and cookies, so every call is same-origin.
[warning] Never set VITE_API_BASE. The session cookie is httpOnly and same-origin.
Running it
pnpm dev:api # :3000
pnpm dev:workflows # :5080
pnpm --filter @leumas/workflows-web build
pnpm check:workflows-public && pnpm check:workflows-metered && pnpm smoke:workflows-site
[warning] pnpm deploy:workflows copies files but carries no release stamp. Only pnpm ship applies.