The module-store manager's 'Add a store' form gains an optional PEM
public-key field; when set it pins that publisher key to the store
(per-store signing trust). Localized DE/EN.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The collapsed connection dot was a static Container after the sidebar
refactor; route it through the shared ChainStatusDot with pulsing tied
to the connected state — a living live-signal, steady when down or
unknown.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The approval card only rendered the payload section when a preview
existed, so a step with no 'show:' showed nothing and the reviewer
could not tell why. Now always show the section: a present payload
scrolls inside a height-capped, copyable box; an absent one shows an
explanatory hint (the flow's approval step chooses what to surface via
its 'show:' field). Relabel 'data to be released' -> 'data to review'
(the payload is review context, accurate to its source).
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Audit sweep after the System-AI fix: the Settings dialog rendered its
two _error states as a bare Text (hub-endpoint save, default-scope
edit), and the Audit live-status bar showed the raw load failure in a
non-selectable Text (the only place that failure surfaces — the
empty-state below shows just a generic hint). Route the Settings errors
through ChainErrorBox and make the Audit disconnected text a
SelectableText. Errors must always be clipboard-copyable.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The System-AI editor rendered its failure (test connection, save, model
pull) as a bare Text(_error) — selectable-but-not-copyable, the exact
thing the operator needs to paste back. Route it through ChainErrorBox
(selectable + one-tap copy button), and show a failed test result via
ChainErrorBox too instead of a plain SelectableText.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Use the raw store-index file in the public chain-modules/reclaim repo
(git.flemming.ai/chain-modules/reclaim/raw/branch/main/store.yaml) —
stable, no release-tag churn, fetched by the hub's StoreIndex::from_url.
The availability probe flips the row to 'Add' automatically once reclaim
publishes the file.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
- store: repair the filter dialog crash (a Spacer lived directly in
AlertDialog.actions, which is an OverflowBar, not a Flex — it threw
and rendered a broken dialog). Buttons now sit in a Row.
- store: promote the module-store manager from a bare icon to a
labelled 'Add store' button, and fully localize the dialog (DE/EN).
- store: add a curated 'Suggested stores' shelf with one-click
add/remove (first entry: Recl∆Im). Each suggestion is probed for
reachability and shows 'not available yet' until its index is
published, instead of failing only on click. Fail-open on network
errors so a transient hiccup never hides a real store.
- sidebar: the channel pill is now a one-click channel switcher
(menu with per-channel running state + active check; switching
writes ~/.chain/current-channel, restarts the daemon, and Studio
repoints to the new channel).
- approvals: lead the card with the human prompt ('what am I
releasing?') and demote the flow/step id to a metadata line; clear
fallback when the step left the prompt empty.
- welcome: tidy the docs grid into equal-height paired rows with a
full-width trailing card for the odd one out.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
'Tap to start' on an already-running hub reported 'daemon could not be
started' (the start failed because it was already up) then flashed the
error away as a SnackBar — confusing next to the sidebar's 'connected'.
Now: on a failed start, probe the hub; if it answers, just connect (no
false error). If it is genuinely down, show the daemon's stderr in a
persistent, copyable dialog (showFaiProcessErrorDialog) instead of a
SnackBar that vanishes before the operator can read or copy it.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
A store icon in the Store app bar opens a dialog that lists the
configured module stores + the bundled seed (with per-source module
counts), lets the operator add a store by index URL (the hub fetches +
merges it live so its modules appear immediately), and remove a store.
Backed by the new ListStores/AddStore/RemoveStore RPCs + SDK methods.
This is how a domain app's published modules (e.g. reclaim's) become
visible in the Store without touching the CLI.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Studio defaulted its endpoint to the local channel's port (:50051), but
a curl|sh user is on the production channel (:50071) — so the sidebar
probed a different daemon than the Diagnose page reported, showing
'connected' next to 'production daemon stopped'. On first run Studio now
reads ~/.chain/current-channel (+ run/<ch>.endpoint) and follows the
active channel; an explicit Settings endpoint still wins and persists,
auto-discovery does not (re-follows the channel each launch). The
connection caption now names the channel ('Connected · production') so
it can never look contradictory again.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
From a live-test audit:
- Install via the flow-editor 'Fix' sent 'debug.echo@^0' (version
constraint included) as the install source; the hub resolves by bare
name so it missed ('no store entry for debug.echo@^0'). Strip the
@<constraint> like the Store page does — debug.echo now installs.
- Errors the operator could not copy: route the daemon-start failure
(its stderr!), the flow-editor install failure and the federation
issue failure through showFaiErrorSnack / a new showFaiProcessError
helper, so every error is selectable, one-tap copyable and logged.
- Diagnose page opened slowly because doctor() Future.wait-ed on a live
manifest fetch (8s server timeout); cap that one check at 2s so the
page no longer waits on the network.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The active-channel pill coloured 'production' with the theme error
colour — red read as 'something is broken'. Use ChainColors.success
(live & healthy) instead; still visibly distinct from beta (amber),
dev (accent) and local (grey).
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The release build aborted at the Xcode CodeSign step (no Developer-ID
identity), leaving an incomplete .app missing Contents/Frameworks —
which DYLD-crashed at launch ('Library not loaded: FlutterMacOS.framework').
Set CODE_SIGNING_ALLOWED = NO so the bundle is produced complete; the
release pipeline ad-hoc signs it afterward. Notarization is a later step.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The Studio design system, widgets and helpers carried a Fai* / fai_
prefix (FaiSpace, FaiColors, FaiTheme, FaiLog, 17 fai_*.dart files, the
faiBinary* l10n keys). Studio is the Ch∆In product, so rename them to
Chain* / chain_ — carefully preserving English fail/failure/failed.
Also fix stale references: the 'fai' binary in l10n strings -> 'chain',
FAI_* env vars (FAI_BIN/DATA_DIR/MODULES_DIR/TODAY/BOOTSTRAP_TOKEN) ->
CHAIN_*, fai_platform -> fai_chain, fai_hub -> chain_hub. Vendor
security-hook tooling (FAI_BANNED_TERMS_FILE) + the .fai bundle ext left.
flutter analyze + test: clean (20 passed).
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Studio is the Ch∆In product's GUI, not a F∆I-vendor app. Rename the
Flutter package, all package: imports, and the build identity across
platforms: linux/windows CMake BINARY_NAME + project, Windows Runner.rc
fields, macOS PRODUCT_NAME / bundle id (ai.flemming.chain.chainStudio) /
.app + scheme BuildableName. Update the client-SDK + flow-editor deps to
their renamed chain_* packages (path + git URL). Company/copyright fields
now read Flemming.AI. flutter analyze: clean.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The old 'F∆I Platform' product name and platform@flemming.ai contact
survived in docs/NOTICE/descriptions/help text; the product is Ch∆In and
the contact is chain@flemming.ai. Generic 'cross-platform/platform-native'
left untouched.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Track the platform rename: the hub spawn path is now ~/.chain/bin/chain
(was ~/.fai/bin/fai.exe on Windows — both dir and binary were stale, so
Studio could not launch the hub after the config-dir rename), the
~/.fai/* help strings become ~/.chain/*, FAI_REGISTRY_TOKEN ->
CHAIN_REGISTRY_TOKEN, and the two in-app doc URLs point at the public
fai/chain repo (fai/platform was renamed to the private fai/chain-private).
The .fai module bundle extension is left unchanged (format phase).
flutter analyze: no issues.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Studio follows the platform rename: product branding F∆I -> Ch∆In in UI
strings, command examples fai -> chain, and — critically — the spawned
hub binary path ~/.fai/bin/fai -> ~/.fai/bin/chain so Studio launches
the renamed binary. The fai_* Dart identifiers (FaiLog, widget files,
the generated SDK) stay = vendor/internal namespace. flutter analyze:
no issues.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The doc'd first install is debug.echo, but the Welcome onboarding
checklist only went green for a text.* capability — so a user
following the quickstart saw the box stay unchecked. Match any
non-system (non-built-in) capability instead.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
A new 'Föderation' destination (primary side) lists connected
satellites — name, region, version, wire version, advertised
capabilities — and adds them in one step: 'Add satellite' issues a
single-use bootstrap token bundled with the primary CA as a
ready-to-paste satellite config (the bundled CA makes the first
connect tamper-proof). Localized EN + DE, in-app help doc. Uses the
new HubService.listSatellites / issueSatelliteToken wrapping the
SDK's federation methods.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
- Strip ANSI / control characters when reading log files so daemon
logs that carry colour escape codes render clean instead of as
garbled special characters (the source side is fixed in the hub
too; this is the defensive belt for existing files).
- Generalise the file viewer (read top-down + plain mode) and add an
in-Studio "View" affordance for config.yaml / .yml / .toml on the
Doctor paths panel, so config is readable without leaving Studio.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Brightness-aware elevation tokens (FaiElevation low/medium) applied
to cards, sheets and the sidebar active item; gentle hover-lift on
Store + Doc cards; a longer, eased sidebar expand using the
under-used FaiMotion.slow; and a branded empty state carrying the
F∆I delta mark with warmer spacing. Subtle, Linear/Raycast-style —
both light and dark themes tuned.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
- Connection-aware Welcome: when the hub is down, show a hero with a
primary "Start hub" CTA + install fallback instead of a dead,
all-unchecked onboarding checklist (the first-run cliff).
- Actionable binary-not-found (file picker + install link, not a
"set FAI_BIN" dead end) and a connect-failure banner after
repeated failed health polls.
- Localize six hardcoded English error/toast clusters (DE+EN ARB).
- Bundle Inter + JetBrains Mono as assets; drop the runtime
google_fonts fetch (air-gap / KRITIS safe, no font-swap flash).
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Two operator-attention improvements:
- The sidebar's Approvals item gains a small accent-coloured
badge (e.g. '2', '9+') when there are pending approvals,
polled on the same 5 s tick the health check uses. Operators
no longer need to open the Approvals page to discover new
pending decisions; the badge surfaces them at the rail
level.
- The Settings dialog's per-category panel titles grow an
optional help icon (?) that opens the matching bundled
docs explainer via showFaiDoc. Wired for General →
architecture, Security → security, Maintenance → audit.
Other categories deliberately stay un-iced for now —
Appearance / System AI / Integrations don't yet have a
standalone bundled doc, and showing a broken help icon
would be worse than showing none.
Studio bumped to 0.69.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
When operators open a module's detail sheet from the Store,
the Permissions section now grows a small help icon next to
the section header. Tapping it opens the bundled security.md
explainer in the existing bottom-sheet reader, the same
in-app help system Approvals + Audit + Doctor already use.
Closes the zero-learning-curve gap: every operator-facing
declaration of permissions ('net: api.openai.com', 'fs.read:
…') now has a clickable affordance to learn what those
permission categories mean and how the sandbox enforces them.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
StudioFlowRunDriver gains three new methods that satisfy the
editor 0.21.0 FlowRunDriver interface:
- pendingApprovalIdForStep(flowName, stepId) — picks the
newest pending approval row matching this (flow, step)
pair from HubService.pendingApprovals().
- approveApproval(approvalId, reviewer) — delegates to
HubService.approve, same RPC the Approvals page uses.
- rejectApproval(approvalId, reviewer, reason) — delegates
to HubService.reject.
End result: when a flow run pauses on system.approval@^0,
the Run tab now renders a complete Approve / Reject form
directly under the awaiting step. Operator no longer needs
to switch tabs to make the decision; the standalone Approvals
page stays available for non-running approvals and history.
Studio bumped to 0.68.0; editor pin moves to 0.21.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Generic gRPC-code mapping was right but not specific enough.
A flow failing with an approval-timeout used to land on
'Deadline exceeded — try again later'; now it reads 'Freigabe-
Timeout abgelaufen — entweder timeout_seconds erhöhen oder
den Reviewer informieren.'
New pattern matchers in _matchHubPattern, runs before the
gRPC-code switch. Six FlowExecutionError shapes covered:
- approval rejected ("rejected by")
- approval timeout
- output too large ("exceeding the X MB cap")
- host service not declared
- missing value reference
- MCP endpoint unreachable
- capability not installed (NotFound fallback)
Every match comes with a localised hint pointing at the
concrete fix path (audit log / timeout config / Integrations
panel / Text-tab Fix button).
Five new tests pin the matchers — would catch a silent
regression when the hub renames a variant Display string.
All 11 friendly_error tests + 19 Studio tests green.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Three operator-UX gaps closed:
- Settings dialog's six-category sidebar (General / Appearance /
System AI / Integrations / Security / Maintenance) was
hardcoded English; now flows through AppLocalizations
("Allgemein" / "Darstellung" / "System-KI" / "Integrationen" /
"Sicherheit" / "Wartung"). Same for the per-panel title +
description.
- Per-channel daemon-action labels ('enable autostart' /
'disable autostart' / 'daemon restart' etc.) and the
OK / Failed result line in the toast also moved to l10n,
so the system-action feedback reads as one language.
- New 'Approvals' doc bundle (en + de) under assets/docs/,
registered as a fifth doc card on Welcome plus exposed via
the new public helper. The
Approvals, Audit and Doctor app-bars grow a Help icon button
next to Refresh that opens the matching doc in the existing
bottom-sheet reader — no extra screen, no learning curve.
Studio bumped to 0.67.0; editor path-override pulls in 0.20.1
(flow-list row polish).
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The previous Add-source dialog was English-only and
operator-hostile — answered 'where do I install from?' without
explaining what a private module *is*. New version, DE + EN:
- Title + intro + button labels routed through AppLocalizations
("Modul-Quelle hinzufügen" / "Installation fehlgeschlagen"
instead of raw English strings).
- 'How private modules work' explainer block (3 sentences):
what a module is (`module.yaml` + WASM), how to package
it (`fai pack <dir>` → .fai bundle), where to host it
(any URL: own Forgejo / GitHub / S3), what verification the
hub does (sha256 + signature against trust store).
- Honest about the Studio gap: the dialog can install URLs +
packed bundles, but unpacked source directories still
require `fai install --link <path>` on the CLI. The
example command lives in its own code-style box, selectable.
- Layout: SingleChildScrollView'd so the explainer doesn't
push the buttons off short viewports.
Studio bumped to 0.66.0; editor path-override pulls in 0.20.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Pulls in editor 0.19.0 which closes three operator-reported
gaps: persistent diagnostic strip across all three tabs,
analyzer-error block on Run, and copyable run failures.
Studio bumped to 0.65.1.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Two host-side pieces that complete the editor 0.18 quick-fix
loop:
- FlowsPage now fetches the store catalog (`searchStore` with
a 500-item ceiling) on open and hands it as `storeCapabilities`
to the FlowEditorPage. The editor's analyzer uses it to
decide whether an unknown-cap fix shows "Install …" or the
Add-source alternative.
- New `_AddModuleSourceDialog` — wired through the editor's
`onAddModuleSource` callback. Asks the operator for a URL
or local .fai bundle path; passes the value into
`HubService.installModule(source: …)`. Honest about its
limits: includes a card pointing the operator at
`fai install --link <path>` for unpacked module source
directories (which the gRPC install API doesn't currently
support — that's CLI-only).
Studio bumped to 0.65.0; editor path-override pulls in 0.18.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
FlowsPage now passes onInstallCapability to the editor — the
editor's 'Install <cap>' button on an unknown-capability
diagnostic calls HubService.installModule, refreshes the
capability list, and returns it so the editor reanalyzes and
clears the issue.
On install failure: friendly SnackBar surfaces the error. The
operator never gets stuck on the analyzer reporting a
capability they just clicked to install.
Studio bumped to 0.64.0; editor path-override pulls in 0.17.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
The Settings dialog was a single 800-line vertical scroll — Hub
endpoint, channels, System AI, MCP, n8n, registry credentials,
hub auth token, default scope, theme plugin, maintenance all
stacked. Stefan: 'inzwischen zu unübersichtlich als langes
feld, untergruppierungen wären toll, wie z.B. in den MacOS
Einstellungen'.
Splits the panel into six focused categories driven by a
left sidebar:
- **General**: Hub endpoint (host/port/TLS), channels,
default scope
- **Appearance**: theme plugin picker (applies instantly)
- **System AI**: operator-managed LLM endpoint for Studio
helpers
- **Integrations**: MCP servers + n8n endpoints
- **Security**: registry credentials + hub auth token
- **Maintenance**: reset / destructive ops
Sidebar uses macOS-style icon + label rows with a highlighted
selection pill. Content area is per-category, scrollable
within its own panel. The dialog widens from 520→820 px and
gains a fixed height (620 px) so the layout doesn't jump as
the operator switches categories.
Each panel opens with a title + one-sentence description so
the operator knows what they're looking at before scanning the
controls — same pattern Apple uses in System Settings.
Also adds the missing 'meta' dependency that FaiLog's
@visibleForTesting needed. Studio bumped to 0.63.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
FaiLog used to compute its destination directly from HOME, which
made it impossible to test without scribbling on the operator's
real ~/.fai/logs/. Adds a static testPathOverride seam tagged
@visibleForTesting so the singleton can be redirected at a per-
test temp file.
The new test/fai_log_test.dart covers:
- append() writes one JSON-shaped line per event
- context field round-trips when supplied
- tail() returns oldest-first
- tail(maxLines:) caps and keeps the newest entries
- rotation moves the previous log to .log.1 past 256 KiB
- path getter honours the override
- writes to an impossible path do not throw — best-effort
contract that protects the UI from log-write failures
Production behaviour is unchanged: when the override is null
the path getter still computes from HOME/USERPROFILE.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Two operator-visible fixes prompted by 'I picked a theme but
nothing changed':
- Theme picker tile taps now show a brief "Theme applied:
<name>" snackbar — the picker applies themes instantly, so
the operator needs a confirming cue. Slow `_pluginThemes`
loads no longer read as "click did nothing".
- `_pluginThemes` failures (plugin unreachable, manifest
drift, etc.) write to `FaiLog` so `fai admin doctor` and
Studio's inline log viewer can surface them. Previously
swallowed silently, which is what made debugging this so
miserable.
- Settings dialog's primary button relabelled to
"Connect to endpoint" (was "Save & connect") so operators
don't mistake it for "save my theme choice". The theme
selection persists at tile-tap time; the Settings dialog
has nothing left to "save".
- Theme section header gains an explicit "(applies instantly)"
cue for the same reason.
Also fixes a pre-existing curly-braces lint in the n8n add-
endpoint dialog. Studio bumped to 0.62.1, editor pinned via
path override at 0.15.1.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Bundles the error-UX overhaul and the inline log viewer:
- New `FaiLog` (`~/.fai/logs/studio-errors.log`, 256 KiB rotation,
JSON-per-line). Every operator-visible failure is appended so
`fai admin doctor` and the new viewer can show the trail
without the operator having to reproduce the failure.
- New `showFaiErrorSnack` / `showFaiErrorDialog` helpers wrap
`FaiErrorBox` in copyable surfaces; 27 ad-hoc
`SnackBar(content: Text(e.toString()))` sites swept to use
them (settings, doctor, audit, store, module sheet, system-AI
editor, flow output).
- New `FaiLogViewer` modal (`showFaiLogViewer`) renders log
files inline with line numbers, JSON-key + `[level]` token
colouring, Copy-all, Refresh, Open-externally. Doctor's
daemon-paths panel grows a "View" button next to "Open" for
every `.log` row and now also lists the Studio errors log.
- Today carousel: CTAs now actually re-run search after a
`filterCategory` / `runQuery` story is tapped (was only
flipping the chip state). Fallback story list bumped to 8.
- Editor bumped to git ref carrying 0.15.0 (type-token
colouring + analyzer diagnostics).
Studio bumped to 0.62.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Two visible UX shifts:
1. Store Today carousel.
- Three hardcoded stories rewritten to be generic:
'Modules are the building blocks',
'Flows chain modules deterministically',
'Bring your own sources' — no DeepWiki / Semgrep /
text.extract / extract-summarize.yaml mentions. The
concrete brand suggestions live in Settings → MCP
Clients where the operator goes deliberately.
- +DeepWiki / +Semgrep quick-add chips removed from
the hero footer. They felt like ads on every page
load. The standalone Suggested Sources strip below
still picks them up, but the editorial hero stays
clean.
- Auto-hide the entire carousel once installedCount
≥ 3 — the operator has demonstrably been here
before; the welcome strip stops earning its scroll
cost.
2. Editor bump to 0.13.0:
- Edge selection (click a wire to select it)
- Properties panel edge-info mode with type-compat
indicator + Disconnect button
- Canvas-wide background tap closes the panel (works
even when zoomed out so the grid doesn't fill the
viewport)
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Three changes:
1. Onboarding checklist hints no longer mention DeepWiki,
Semgrep, text.extract, or extract-summarize.yaml by
name. Brand- and file-specific copy moved to neutral
feature pointers ('add an MCP source', 'install a
module'). Brand names belong on the welcome page only
if they're load-bearing for understanding, which they
aren't.
2. Checklist rows are now clickable. Tapping a row navigates
to the page where the operator can complete it — MCP +
AI open Settings, Module opens Store, Flow opens Flows.
StudioShellState gains a public navigateTo(pageId) helper
so descendants can drive sidebar selection without
plumbing a controller through props.
3. Theme picker hint copy rewritten. Old hint suggested
'Custom' was a single-colour tweak; new copy spells out
that Material 3 derives a full palette (primary,
secondary, tertiary, surface, …) from one seed colour.
The Custom tile shows a small tune icon so its
open-the-picker semantics is visually distinct from the
apply-immediately plugin tiles.
Editor bumped to 0.12.0 (panel toggle + LabVIEW-style port
colours).
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Settings dialog's Theme Plugin section is now a grid of
swatched tiles:
- Built-in (none) — falls back to FaiTheme.light/.dark
- One tile per installed studio.theme.* plugin, each
showing the plugin's primary/secondary/tertiary as
live colour dots. Tile loads its preview lazily so a
dozen installed themes don't block the picker.
- Custom — opens a colour-picker dialog with 12 curated
Material presets + a hex input + live preview. Selecting
applies ColorScheme.fromSeed for both brightnesses.
main.dart's _pluginThemes parses a 'custom:#RRGGBB' sigil
in the same notifier slot as plugin capability ids, so the
existing persistence + restoration paths cover the custom
case with no new state.
Bumps editor to 0.11.0 (type-checked port connections +
dynamic card width fix + card-height border allowance) and
Studio to 0.58.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Picks up:
- fai_studio_flow_editor 0.9.0: per-field input + output
ports rendered from ModuleInfo, i18n tooltips, four
additional canvas patterns ported from jai_client.
- fai_client_sdk 0.18.0: regenerated ModuleField bindings
for the schema_version 3 / per-field-description proto
bump in fai/platform.
Wires StudioFlowRunDriver.moduleInfo so the editor can
fetch declared field info per step capability. The hub
maps schema_version 3 manifest fields (inputs/outputs
with description.en/de) through ModuleInfoResponse; this
patch wraps them back into the editor's ModuleSpec /
ModuleField vocabulary so the canvas paints them as
distinct anchors with hover tooltips.
ModuleDetail in hub.dart now carries the same inputs +
outputs lists (with ModuleFieldInfo type + i18n
description map), enabling other Studio surfaces — e.g.
the module-detail sheet — to render bilingual field docs
in a later pass.
Plus: store-doc nested-scroll fix. The module detail
panel's docs section sat inside its own 480px viewport
inside the outer sheet's SingleChildScrollView, producing
the double-scrollbar feel. Setting
physics: NeverScrollableScrollPhysics on the Markdown
widget and dropping the maxHeight lets the docs scroll
as part of the outer sheet — one scrollbar, predictable
mouse-wheel behaviour.
Bumps fai_studio to 0.56.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Picks up:
* FaiEditorStyle visual-effect knobs (frosted-glass panels,
canvas gradient, flow animation, node shadows) the host
can override. Studio uses the default modern preset for
now; theme-plugin integration is a follow-up.
* Properties panel rebuilt as a floating sidebar with
BackdropFilter blur over the canvas.
* Pattern + zoom controls promoted to dropdowns so
operators reach a specific level in one click.
Bumps fai_studio to 0.55.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Picks up fai_studio_flow_editor 0.7.0 (commit 7aeeae7):
- Wires take the colour of the data they carry. Inputs-
endpoint edges show their type accent (text=blue,
bytes=orange, json=purple, file=green, number=amber)
so the operator can trace flow data by colour alone.
- Edges entering a currently-running step animate as
marching dashes in the wire's accent colour. Stops
when the step completes. The canvas comes alive
during runs.
- Canvas backdrop is a subtle gradient (corners recessed,
centre lit). Nodes get layered shadows; selected nodes
wear an accent-coloured halo. 180 ms ease-out
transitions on hover / select / status changes.
Version 0.53.6 -> 0.54.0 (minor bump — first wave of the
2026-feel visual refresh).
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Picks up fai_studio_flow_editor 0.6.0 (commit 5ff7a1c):
- Edges highlight on hover (8 px hit radius around the
bezier path).
- Right-click or long-press on an edge opens a Disconnect
popup. Same on ports + step nodes — long-press is now
the trackpad-friendly alternative everywhere a context
menu lives.
- Background pattern toggle (dots / grid / blank) on the
bottom-right canvas controls.
- Live zoom indicator as a tappable % readout — tap to
snap back to 100 % without losing pan.
Version 0.53.5 -> 0.53.6.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
Picks up fai_studio_flow_editor 0.5.3 (commit 5c59f3a):
- Draft connection line now extends all the way to the
cursor (previously stopped 6 px short).
- Ports respond to hover with a soft accent glow + size
bump — clear "this is interactive" affordance before
the operator clicks.
Version 0.53.4 -> 0.53.5.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>