Commit graph

5 commits

Author SHA1 Message Date
f43c1ac6cf feat(editor): copyable diagnostics + hover tooltip + quick fixes
Three operator-UX gaps closed in one pass — the diagnostic
strip stayed plain Text (no copy), the wavy underline gave no
hover tooltip (had to read the strip), and there was no way to
act on an issue without leaving the editor.

  - **Selectable + copyable strip**. Both the header summary
    and the per-row issue message are now SelectableText. Per-
    row Copy button (compact icon) lives next to the message;
    header carries a 'Copy all' that copies every issue as
    'L7: <message>' lines. Trackpad-only operators no longer
    have to use the system selection gesture.

  - **Hover tooltip on the wavy underline**. The controller
    attaches TextSpan.onEnter / onExit handlers to every
    issue-overlapping leaf and publishes IssueHoverRequest via
    a ValueNotifier. FlowEditorPage listens and inserts an
    OverlayEntry tooltip card near the cursor. Card carries
    its own MouseRegion that cancels the dismiss timer so the
    operator can slide INTO it to click the action buttons.

  - **Quick fixes for the two most common issues**:
      · 'Unknown capability X' → InstallCapabilityFix (delegated
        to host via the new onInstallCapability callback). On
        success, controller.setAvailableCapabilities + reanalyze
        clear the issue automatically.
      · 'Unknown type Y' with a Levenshtein-distance-≤2 match
        → ReplaceLineValueFix. Applied by the editor itself:
        line is mutated, key + indent preserved, comment
        preserved, then reanalyze.
    Distance > 2 stays unfixed — pushing 'zonglefax' to 'bytes'
    would be worse than no suggestion.

New public surface (exported from the package):

  - QuickFix sealed base + InstallCapabilityFix + ReplaceLineValueFix
  - InstallCapabilityCallback typedef
  - IssueHoverRequest + IssueHoverSeverity
  - FlowEditorPage.onInstallCapability prop

Tests:
  - FlowAnalyzer attaches InstallCapabilityFix to capability
    issues
  - FlowAnalyzer suggests the closest valid type for typos
  - FlowAnalyzer emits no fix when the typo is too far

All 33 editor tests green. Bumped to 0.17.0.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-09 00:01:51 +02:00
b1fe765468 feat(editor): per-field input/output ports + i18n tooltips + 4 jai_client patterns
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>
2026-06-01 22:32:26 +02:00
1f5601a461 feat(editor): FaiEditorStyle + frosted glass panel + pattern/zoom dropdowns
Visual-effect knobs (FaiEditorStyle) the host can override —
distinct from ColorScheme, which stays orthogonal. Today
Studio passes it through FlowEditorPage's new style:
parameter; tomorrow a theme plugin can ship both colours and
effects in one move.

Two presets ship today: modern (frosted glass, gradient
backdrop, animated flow, shadowed nodes — the default) and
minimal (everything off, flat surfaces — accessibility /
reduce-motion / low-spec).

Properties panel rebuilt as a floating sidebar with
BackdropFilter blur when glass-style is on; falls back to
the pre-0.7 flush-divider layout under solid style.

Pattern + zoom controls promoted to PopupMenuButton dropdowns
so operators reach a specific zoom level / pattern in one
click instead of cycling.

Bumps fai_studio_flow_editor to 0.8.0.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-01 18:10:51 +02:00
870cbc29f7 feat(editor): three-tab WYSIWYG editor — graph / text / run
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>
2026-06-01 00:48:35 +02:00
F∆I Platform
51f9a1d2b1 feat: initial scaffold — swappable flow editor
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>
2026-05-30 14:33:03 +02:00