The Run tab asked the operator to type an absolute path into a text
field — with no file dialog anywhere. FlowEditorPage now accepts an
onPickFile callback (PickedFileData: name + bytes) that hosts wire
to their native picker; the path-entry dialog remains only as the
no-host fallback. 0.23.0.
Signed-off-by: flemming-it <sf@flemming.it>
Two big operator-UX wins that the previous batch missed:
1. Diagnostic-strip header gets a 'Beheben' (Fix) button next
to 'Copy all'. Clicking opens a focused modal listing every
issue with its quick-fix actions plus an 'apply every quick
fix' master button. Replaces the cramped expand-strip flow
for operators who want a deliberate dialog instead of
scrolling in a 200-px footer.
2. Run tab inlines the Approve / Reject form right under any
step that the hub paused on system.approval@^0. The
FlowRunDriver gains three new methods (host-implements
them; defaults throw with a clear message):
- pendingApprovalIdForStep(flowName, stepId) → String?
- approveApproval(approvalId, reviewer) → Future<void>
- rejectApproval(approvalId, reviewer, reason)
The _InlineApprovalCard polls the driver for ~3s waiting for
the hub to materialise the approval row (event-stream race
against the hub's create), then renders the same form the
Approvals page does — reviewer + optional reason + Approve /
Reject buttons. After submit the hub picks up the decision
on its next poll and emits step.approved / step.rejected,
which the existing event stream already maps to the right
step status.
Closes the operator question 'wie soll das gehen dass da
Freigaben landen?': they land in the Approvals page AND
inline in the Run tab; the inline path is now the natural
workflow.
All 36 editor tests + 24 Studio tests green. Bumped to 0.21.0.
Signed-off-by: flemming-it <sf@flemming.it>
Phase A of the per-field-output-ports roadmap.
FlowRunDriver gains optional moduleInfo(capability) hook
that returns a ModuleSpec carrying declared inputs +
outputs (each ModuleField has name, type, locale->
description map). Default returns null so legacy hosts
that didn't implement the hook keep compiling — the editor
falls back to YAML-reference-derived ports.
FlowCanvas caches ModuleSpec per step capability, kicked
off lazily on each build. When the spec lands, the canvas
rebuilds with:
- Per-field input ports on the LEFT (declared input names,
in stable manifest order) — replaces the with_-keys-as-
port-labels shape.
- Per-field output ports on the RIGHT — one anchor per
declared output field. A flow like summarize that
declares response/model_endpoint/model_name/model_digest
now exposes four distinct anchors instead of fanning
every downstream reference out of one collapsed point.
- Tooltips on each port label, picked from the field's
description.<locale> with English fallback.
NodeGeometry refactored: heightFor(inputs, outputs) takes
max(inputs, outputs); outputPortY(index) for the new
multi-port output side; outputAnchorY() preserves the
legacy single-anchor fallback so edges still draw before
the spec resolves.
Edges + hit-tester now use _outputPortPosition(stepId,
fieldName: edge.fromField). Field index lookup falls
through to outputAnchorY when the spec isn't loaded yet.
Patterns: ported modern, classic, blueprint, minimal from
jai_client's CanvasPatternPainter. Dropdown now has seven
choices (dots, grid, modern, classic, blueprint, minimal,
blank).
Bumps fai_studio_flow_editor to 0.9.0.
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>