Commit graph

7 commits

Author SHA1 Message Date
9196251e00 refactor: FaiError -> ChainError (SDK stub rename lockstep)
Signed-off-by: flemming-it <sf@flemming.it>
2026-07-11 23:14:34 +02:00
a0a5038ad7 fix: read flows from ~/.chain after config-dir rename
The platform's operator config dir moved ~/.fai -> ~/.chain; the flow
editor read saved flows + layouts from the old path, so it found nothing
after the rename. Update the hardcoded ~/.fai/data/flows paths to
~/.chain.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-16 09:40:22 +02:00
303e318ba8 feat(editor): Fix-dialog from diagnostic strip + inline approval in Run tab
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>
2026-06-09 09:18:17 +02:00
5cd2745db5 feat(editor): localised analyzer/strip/run messages + monospace font fallback
Closes operator-reported issues around the text-tab font and
the English-only run + diagnostic surfaces.

  - **Real monospace everywhere**. The package never bundled
    JetBrains Mono as an asset (it relied on Studio's
    google_fonts pre-load), so a host that doesn't ship the
    font saw the YAML editor render in the system proportional
    default. New _monoTextStyle() pins fontFamilyFallback to a
    cross-platform monospace chain (Menlo / Consolas / Courier
    New / monospace) so the editor stays a grid in every host.
    Applied to the code field, gutter, diagnostic strip,
    issue rows, hover card, fix buttons, and the run tab's
    error box.

  - **Locale-aware analyzer messages**. New AnalyzerStrings
    adapter holds every string the analyzer emits, with an
    .english default + an .from(FlowEditorStrings) factory.
    FlowYamlCodeController.setCapabilityProviders takes the
    strings; FlowEditorPage wires them from the active locale.
    The analyzer's 'Unknown capability', 'Did you mean',
    'Not in the store — install locally with fai install
    --link', 'Unknown input/output type', YAML parse errors,
    and every quick-fix label (Install / Add source / Use /
    Change to) now flip to DE when the editor's locale is DE.

  - **Localised run + diagnostic chrome**. The bottom strip's
    'No issues', '2 errors · 1 warning', 'Copy all'; the
    issue row's L-prefix + Copy tooltip; the hover card's
    L-prefix + Copy tooltip; the run-block tooltip + inline
    message ('2 Fehler verhindern den Lauf · siehe
    Diagnose-Leiste unten'); the step-row 'awaiting approval'
    suffix; the CopyableErrorBox's Copy / Copied tooltip —
    all now flow through FlowEditorStrings.

Bumped to 0.20.0.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-09 01:36:39 +02:00
b6bb8741a9 feat(editor): persistent diagnostic strip + run-block + copyable run errors
Three connected fixes that close the loop the analyzer started:

  - **Strip lives at page level, not text-tab**. Moved
    _DiagnosticStrip out of _textTab and into _tabbedBody
    below the TabBarView, so the same error list + quick-fix
    buttons are visible on Graph + Text + Run. The Graph-tab
    operator now sees both the pulsing node AND the message
    explaining what's broken, without flipping tabs. One strip,
    one source of truth.

  - **Run button disabled when there are analyzer errors**.
    FlowEditorController.analyzerErrorCount counts `IssueType.error`
    issues; the action strip's Run button + the RunTab's Start
    button both check it. When > 0:
      · button greys out + icon flips to Icons.block
      · tooltip names the count ('2 errors prevent the run')
      · the Run tab grows an inline red explanation next to
        the disabled Start so the operator isn't left guessing
    Warnings (orange) do NOT block — they're nudges. Operators
    who want to run a half-broken flow during dev can still
    silence the analyzer via the strip.

  - **Run failures are copyable everywhere**. New
    _CopyableErrorBox replaces both the per-run failure detail
    and the per-step failure suffix in the RunTab. Selectable
    monospace + explicit Copy button with 'Copied' feedback.
    Scrollbar-capped at 220 px so the box doesn't push outputs
    off-screen. Mirrors the operator-visible contract:
    'every error is copyable, always.'

Closes the operator-reported regression where a failed run
showed 'Lauf fehlgeschlagen' as plain Text, leaving the
operator unable to paste it into a bug report.

Bumped to 0.19.0.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-09 01:13:45 +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
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