The Example chip used to come from a client-side content-marker
scan that had drifted from the hub's renamed sample header — no
current sample matched it. The host now passes the hub-reported
sample set (FlowSummary.sample) and the editor renders truth only:
no host info, no chips.
Samples collapse under one 'Examples (N)' group below the
operator's own flows (expanded only when nothing else exists), and
an optional onImportSamples action on the empty list is the
deliberate way to pull the bundled examples into a sealed area's
empty hub. Guard: flow_list_samples_test pins chips-from-host-only,
the grouping, and the import round trip.
Signed-off-by: flemming-it <sf@flemming.it>
Full rewrite of the editor surface, layered on top of the
FlowGraph foundation. One in-memory flow drives three tabs
that the operator can flip between freely:
- Graph: a drag-and-drop canvas. Nodes are step cards with
port dots on their left (one per `with:` field) and a
combined output port on the right. Pinned inputs and
outputs pseudo-nodes sit at the left and right edges so
every flow has a visually obvious source and sink. Pan +
zoom via InteractiveViewer; drag a node by its body to
reposition it (positions persisted to a sidecar JSON file
under ~/.fai/data/flows/.layout/<name>.json — kept OUT of
the YAML so `fai run` stays byte-stable).
- Text: the existing YAML CodeField with expands:true so
line 1 anchors at the top edge. YAML-aware syntax
highlighting picks up the theme's primary / secondary /
tertiary palette for keys / strings / numbers.
- Run: an inputs form (text fields + file-pick), a Start
button that calls the host's FlowRunDriver, a live step
list driven by the driver's event stream (matches the
`fai run` CLI rendering — ◻ pending, · running, ✔ done +
duration, ✗ failed, ⏸ awaiting approval), and the typed
outputs once the run resolves.
Source of truth = the YAML text. Graph edits emit fresh YAML
into the shared CodeController; text edits re-parse the
graph on a 350 ms debounce. Layout sidecar persists drag
positions only.
New public API (lib/fai_studio_flow_editor.dart):
FlowEditorPage(
initialFlowName: ...,
locale: ...,
runDriver: FlowRunDriver?, // NEW — host bridge
availableCapabilities: List<String>, // NEW — for the
// capability picker
// dialog when adding
// a step
)
The host (Studio) implements FlowRunDriver to bridge the
hub's gRPC SDK into the editor's event vocabulary. The
StepStarted/Completed/Failed/AwaitingApproval events are
shared verbatim with the CLI's run_progress renderer so
both surfaces speak the same visual language.
Files in this commit:
- lib/src/editor_controller.dart — shared state +
debounced reparse loop
- lib/src/run_driver.dart — host bridge
interface + event types
- lib/src/widgets/flow_canvas.dart — pan / zoom / drag /
port-to-port connection drawing
- lib/src/widgets/flow_node.dart — node card primitive
(module / approval / inputs / outputs variants)
- lib/src/widgets/edge_painter.dart — single CustomPainter
for every edge + draft drag line, cubic bezier with
arrow-head caps
- lib/src/widgets/properties_panel.dart — right-side editor
when a step is selected (rename id, change capability, add
/ remove / rename with-fields, delete step)
- lib/src/widgets/capability_picker.dart — searchable list
dialog used by Add-step
- lib/src/widgets/run_tab.dart — inputs form +
live step progress + outputs renderer
- lib/src/flow_editor_page.dart — host scaffolding,
toolbar, file list, three-tab body, keyboard shortcuts
- lib/src/l10n.dart — EN + DE strings for
every new label
- lib/fai_studio_flow_editor.dart — exports the new
public types (FlowRunDriver, FlowRunEvent variants,
FlowOutputValue variants)
flutter analyze: 0 issues. flutter test: 7/7 green.
Signed-off-by: flemming-it <sf@flemming.it>
Extracted from fai/studio's lib/pages/flow_editor.dart so the
editor can be swapped out independently of the host.
Public surface kept minimal — a single FlowEditorPage widget
with three named parameters (initialFlowName, locale, onRun).
The package brings its own design tokens, empty/error
widgets, l10n table; no host-internal types leak through.
Studio depends on this repo via pubspec.yaml git reference.
Forks point Studio at a different URL and rebuild.
See README.md for the swap recipe.
Signed-off-by: F∆I Platform <platform@flemming.ai>