Commit graph

7 commits

Author SHA1 Message Date
911f368362 fix(editor): match real F∆I YAML type shape + warn on bad types
The 0.15.0 type-token coloring regex hunted for `type: <name>`,
but the F∆I YAML actually shapes types as `<fieldname>: <name>`
under `inputs:` / `outputs:` blocks. Real-world flows
(`hello.yaml`, `extract.yaml`) and module manifests (echo,
text-summarize, …) never produce the `type:` keyword unless
the operator hand-authors the long form.

Fix the regex to match an indented `KEY: VALUE` line where the
value is one of `text|json|bytes|file|number|integer`. Leading
whitespace is required so top-level keys (`name: foo`,
`version: 0.1.0`) can't false-match. This handles both
shapes — the implicit `pdf: bytes` and the explicit
`type: bytes` (used by module schema v2 inputs lists) —
because either way the pattern boils down to "key colon known
type token".

Analyzer also grows a type-token check: any inputs/outputs
field whose value isn't a known type lights up as a warning
("Unknown input type 'byes' …"), modulo `$ref` expressions
(flow outputs) and empty values (operator is mid-keystroke).

Adds `test/flow_analyzer_test.dart` with seven cases covering
empty, valid hello, unknown capability, unknown type, parse
error, version-bare matching, and the empty-installed-list
silence path.

Bumps the package to 0.15.1.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-04 02:24:29 +02:00
1e9968496e feat(editor): properties-panel toggle + LabVIEW-style type colours
Two visible UX fixes:

1. Properties-panel toggle. Tap a step → opens. Tap the
   same step again → closes (deselect via toggle). Tap the
   canvas background → also closes. selectStep now returns
   to null when called with the already-selected id; the
   editor-controller test updated for the new semantics.

2. LabVIEW-style type colours on every port + wire.
   _typeAccent now picks vibrant brightness-aware hues per
   datatype:
     text   → magenta/pink (LabVIEW string)
     json   → amber/orange (cluster feel)
     bytes  → cyan/teal (raw binary)
     file   → green (file reference)
     number → yellow/amber
   Step-input dots, step-output dots, and outputs-endpoint
   dots all switch from the generic theme.primary to the
   field's declared type accent. Operators read the
   payload from the dot alone.

Editor tests still pass (20).

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-02 11:13:01 +02:00
7b256b5e35 feat(editor): type-checked connections + card-height fix + widget tests
Three changes:

1. Type-checked port connections. Drag from an output port
   only highlights compatible-type input ports as drop
   targets; incompatible drops are silently refused. Source
   of truth: ModuleSpec for declared types. When either side
   is unknown (no manifest, implicit YAML field) the check
   degrades to 'compatible with anything' so a missing
   manifest never blocks composition.

2. NodeGeometry.heightFor now adds a 2 px allowance for the
   1 px AnimatedContainer border on top + bottom of the
   card. Without this the last port-row's Column would
   overflow by 2 px under tight layout constraints (caught
   by the new widget tests; production canvas clipped it
   silently inside InteractiveViewer).

3. Width parameter on FlowNode now actually drives the
   outer SizedBox. The dynamic _stepWidth value from the
   canvas finally reaches the card border rather than being
   shadowed by NodeGeometry.width. Long labels
   (model_endpoint, source_language) no longer ellipsis-clip.

Tests: 8 new widget + geometry tests covering width growth,
two-column body layout, port-tooltip attachment,
row-alignment between input and output sides, and the
existing kindForStep classifier. All 20 editor tests pass.

Bumps fai_studio_flow_editor to 0.11.0.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-02 01:29:00 +02:00
ad2e5b50d5 test(editor): exercise the extract-with-approval flow shape
New test mirrors the most complex shipped example —
three-step chain with a system.approval gate in the middle,
multi-line prompts containing embedded \$step.field refs,
outputs that reference multiple steps. Verifies:

 - step count + approval flagging
 - edge detection (8 edges across inputs, steps, outputs)
 - structural round-trip stability through toYaml() /
   fromYaml()

If this test stays green, the editor is safe on every flow
currently shipped under flows/. 12/12 pass.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-01 02:01:46 +02:00
6b70ba65fd feat(editor): live step status on the graph during runs
Step run events were previously visible only on the run tab.
Operators who triggered a run there and then switched to
the graph tab saw a static graph — the canvas had no idea
something was executing.

Wire the run events through the FlowEditorController so all
three tabs share the same status snapshot:

 - New StepRunStatus enum on the controller
   (idle / running / done / failed / awaiting).
 - controller.stepStatuses exposes the live map.
 - controller.updateStepStatus is called from the run tab's
   event handler — one source of truth, both views read it.
 - FlowCanvas drops its own stepStatuses parameter and
   pulls from the controller instead, so the canvas now
   shows the running pulse + done check + error cross + pause
   icon in each step's header live, in lockstep with the
   step list on the run tab.

When a fresh run starts (controller.running = true) the
status map is cleared so stale events from a previous run
don't paint the new one.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-01 01:47:30 +02:00
e7cd9ca13c test(editor): controller tests for graph<->text round-trip
Four behaviour tests guarding the controller's contract with
the rest of the editor:

 - openFlow seeds the graph + clears the dirty flag against
   the freshly-captured baseline.
 - graph edits re-emit YAML into the shared CodeController
   so the text tab stays in lockstep.
 - graph edits mark the buffer dirty against the baseline;
   markSaved snaps it back to clean.
 - selectStep is idempotent: re-selecting the same step
   doesn't notify listeners (cheap rebuild guard for the
   properties panel).

11/11 tests pass.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-01 00:53:35 +02:00
dbd9a0004f feat(model): FlowGraph + LayoutStore foundation for WYSIWYG editor
First piece of the v0.2.0 rewrite. The graph view, text view,
and run view will all share a single source of truth: the
YAML text. This commit introduces the parsing layer + the
sidecar that keeps layout metadata OUT of the YAML.

FlowGraph (lib/src/model/flow_graph.dart):
 - Parses + emits the F-Delta-I flow YAML shape (inputs +
   steps + outputs + leading comment block).
 - Recognises both inputs shorthand (`name: text`) and the
   expanded form (`name: { type: text, default: ..., hint: ... }`).
 - Detects edges by scanning step.with + outputs for
   $source.field references; understands both the short
   $x.y form (canonical) and the long ${{ x.y }} form (legacy).
 - Flags system.approval@ steps via FlowStep.isApproval so
   the graph can paint them with the human-gate styling.
 - Immutable update helpers (withStepUpdated, withStepAdded,
   withStepRemoved) used by the property panel + add-step
   button.
 - tryParse returns null on YAML syntax errors so the text
   tab can keep the last valid graph while the operator
   types.

LayoutStore + FlowLayout (lib/src/model/layout_store.dart):
 - Per-flow JSON sidecar at
   ~/.fai/data/flows/.layout/<name>.json. Atomic write via
   tmp + rename so a crash mid-save leaves the previous
   copy intact.
 - The YAML stays byte-identical to what `fai run` consumes
   — positions never bleed into the flow file.

AutoLayout (lib/src/model/auto_layout.dart):
 - Deterministic topological column layout for flows that
   have never been opened in the graph view before.
 - Steps with no $step refs sit in column 0; steps whose
   refs all point at column-0 steps sit in column 1; etc.
 - Cycles + dangling refs collapse to column 0 so nothing
   is ever invisible.

Tests (test/flow_graph_test.dart): 7 cases cover canonical
parsing, edge detection across both ref forms, approval-step
flagging, leading-comment round-trip, structural round-trip,
parser robustness on broken YAML, immutability invariant.
All pass.

Version 0.1.4 -> 0.2.0 (minor bump — significant new module
graph; public FlowEditorPage constructor API unchanged).

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-01 00:37:19 +02:00