Commit graph

143 commits

Author SHA1 Message Date
flemming-it
7f59334176 fix(studio): System-AI test-connection error is copyable
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-19 01:52:52 +02:00
flemming-it
8724b19234 feat(store): point the Recl∆Im quick-add at its canonical index URL
Some checks are pending
Security / Security check (push) Waiting to run
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>
2026-06-19 01:49:09 +02:00
flemming-it
5220f19ff8 feat(studio): clearer store + channel switcher + approvals & welcome polish
Some checks failed
Security / Security check (push) Failing after 2s
- 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>
2026-06-18 21:29:39 +02:00
flemming-it
62ed3951e5 fix(studio): daemon-start probes health first + shows a readable error
Some checks failed
Security / Security check (push) Failing after 2s
'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>
2026-06-18 16:17:26 +02:00
flemming-it
57dac3d999 feat(studio): module-store manager (list / add / remove)
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-18 15:54:04 +02:00
flemming-it
cb130b2f03 fix(studio): connect to the active channel, not hard-coded :50051
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-18 13:52:05 +02:00
flemming-it
5f56abcf5f fix(studio): audit batch — debug.echo install, copyable errors, fast Diagnose
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>
2026-06-18 13:02:21 +02:00
flemming-it
ee4a0f6c62 fix(ui): window title Ch∆In Studio (was F∆I); de-dup federation add-satellite
- linux/macOS window chrome read 'F∆I Studio' (rename leftover) → 'Ch∆In Studio'.
- The federation page showed 'Add satellite' twice when empty (FAB + empty-state
  button); drop the empty-state button, the FAB carries the action.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-18 12:53:35 +02:00
flemming-it
a8feb159ce fix(ui): production channel pill is green, not error-red
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>
2026-06-18 12:45:59 +02:00
flemming-it
891acd2ba2 refactor: rename internal Fai* design system + fai_ helpers to chain
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-16 17:53:17 +02:00
flemming-it
68d23ab7dd refactor: rename app fai_studio -> chain_studio
Some checks are pending
Security / Security check (push) Waiting to run
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>
2026-06-16 17:48:11 +02:00
flemming-it
0f93d90963 fix(studio): chain config dir + spawn path + doc URLs
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-16 09:38:30 +02:00
flemming-it
7ff4fda2a3 refactor(brand): rename F∆I -> Ch∆In + hub binary fai -> chain
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-15 16:22:22 +02:00
flemming-it
a0007b9178 fix: onboarding checklist ticks for any installed module, not just text.*
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-13 14:44:31 +02:00
flemming-it
d0cfa5df05 feat: federation panel + Dart SDK federation methods (0.70.0)
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-13 14:16:07 +02:00
flemming-it
b35bbc1b12 fix(studio): readable logs + in-app config.yaml viewer
- 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>
2026-06-11 23:52:40 +02:00
flemming-it
f0a944dce7 feat(studio): award-tier visual polish
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>
2026-06-11 23:52:31 +02:00
flemming-it
5313266cc4 feat(studio): first-run UX, recovery affordances, l10n, bundled fonts
- 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>
2026-06-11 23:52:18 +02:00
flemming-it
7511867774 feat(studio): pending-approvals sidebar badge + per-category settings help
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-09 09:41:14 +02:00
flemming-it
5aae3285df feat(studio): module sheet permissions get a help icon → security doc
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-09 09:32:37 +02:00
flemming-it
626404c5e4 feat(studio): wire inline approval driver methods
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-09 09:18:55 +02:00
flemming-it
971196518c feat(studio): friendlyError catches hub-specific patterns
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-09 02:01:36 +02:00
flemming-it
28fafce7dc feat(studio): localise Settings sidebar + add inline help docs + Approvals doc
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-09 01:57:46 +02:00
flemming-it
2be7d241bf feat(studio): localised + explainer-rich Add module source dialog
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-09 01:36:54 +02:00
flemming-it
eba7e51c7f fix(studio): bump editor pin to 0.19.0 (run-block + copyable errors)
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-09 01:13:56 +02:00
flemming-it
63985267d5 feat(studio): pass store catalog to editor + Add-module-source dialog
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-09 00:22:09 +02:00
flemming-it
0cc527b07c feat(studio): wire flow editor quick-fix install handler
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-09 00:02:28 +02:00
flemming-it
d0e15ca385 feat(studio): Settings dialog gets macOS-style sidebar categories
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-04 10:37:19 +02:00
flemming-it
d9dca60cfb test(studio): seven FaiLog cases + visibleForTesting path override
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-04 02:43:06 +02:00
flemming-it
805f1b4c1f fix(studio): theme picker confirms applied + surfaces load failures
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-04 02:25:11 +02:00
flemming-it
8f5cd2528b feat(studio): central error helpers + inline log viewer + Today CTAs
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-04 02:08:15 +02:00
flemming-it
2731062a13 feat(studio): generic Today stories + auto-hide after 3 modules + brand chips out + editor 0.13.0
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-02 15:23:23 +02:00
flemming-it
3db875c903 feat(studio): brand-agnostic onboarding hints + clickable checklist + theme-picker clarity
Some checks failed
Security / Security check (push) Failing after 2s
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>
2026-06-02 11:13:38 +02:00
flemming-it
c1c60d5434 feat(studio): rich theme picker (presets + custom colour) + editor 0.11.0
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-02 01:29:34 +02:00
flemming-it
a698be0b57 feat(studio): per-field ports in flow editor + store-doc scroll fix
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-01 22:34:08 +02:00
flemming-it
aeb71b833f feat(studio): editor 0.7.0 — typed wires + animated flow + canvas depth
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-01 17:45:47 +02:00
flemming-it
54dd957cd0 chore(studio): editor 0.6.0 — edge hover/menu + pattern + zoom
Some checks are pending
Security / Security check (push) Waiting to run
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>
2026-06-01 17:36:43 +02:00
flemming-it
f2e2433bbc chore(studio): editor 0.5.3 — draft-to-cursor + port hover
Some checks failed
Security / Security check (push) Failing after 1s
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>
2026-06-01 17:13:32 +02:00
flemming-it
36e0113fff chore(studio): editor 0.5.2 — elegant port docking
Some checks failed
Security / Security check (push) Failing after 1s
Picks up fai_studio_flow_editor 0.5.2 (commit 9afb51a):

 - Bezier endpoints now terminate at the port dot's outer
   perimeter, not its centre. Lines "dock" cleanly into
   the socket instead of vanishing under it.
 - End-cap arrow removed (the dot is the terminator).
 - Connected ports gain a tiny inner pin so they read as
   "socket with a plug seated" rather than "hollow circle".

Version 0.53.3 -> 0.53.4.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 17:03:19 +02:00
flemming-it
a8d73ebd18 chore(studio): editor 0.5.1 — 5 type colours + wired/total badge
Some checks failed
Security / Security check (push) Failing after 1s
Picks up fai_studio_flow_editor 0.5.1 (commit e4e2d45):

 - Five payload types each get a distinct hue
   (text/bytes/json/file/number).
 - Step header shows wired/total ratio when partial,
   green check when fully wired.

Version 0.53.2 -> 0.53.3.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 16:47:45 +02:00
flemming-it
251513bc54 chore(studio): editor 0.5.0 — unified port model
Some checks failed
Security / Security check (push) Failing after 1s
Picks up fai_studio_flow_editor 0.5.0 (commit 099cd18):

 - Each port is a single dot (no more inline + canvas
   duplication). Sized to match label rows.
 - Inputs endpoint dots sit on the RIGHT edge (data flows
   out), labels right-aligned. Outputs endpoint stays on
   the left. Step input dots stay on the left.
 - Filled when the port participates in an edge, outlined
   when dangling. Type-coloured for inputs-endpoint dots.
 - Right-click a wired input port to Disconnect — clears
   the with-field / output expression cleanly.

Version 0.53.1 -> 0.53.2.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 16:45:18 +02:00
flemming-it
acdb54ae52 chore(studio): editor 0.4.0 — port geometry + endpoint editor + unsaved badge
Some checks failed
Security / Security check (push) Failing after 1s
Picks up fai_studio_flow_editor 0.4.0 (commit fb88926):

 - Connection dots now line up with their inline port-row
   labels (header geometry rewrite so subtitle space is
   always reserved).
 - Inputs endpoint colours its output ports by declared
   type (text / bytes / json / file / number).
 - Selecting the inputs or outputs endpoint opens a
   dedicated editor in the properties panel — add /
   rename / retype / remove without touching YAML.
 - "Unsaved" badge replaces the easy-to-miss 8-px dot;
   filename also colours primary when dirty.

Version 0.53.0 -> 0.53.1.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 16:31:51 +02:00
flemming-it
f252487c92 feat(studio): editor 0.3 — endpoints stay put + node context menu
Some checks failed
Security / Security check (push) Failing after 1s
Picks up fai_studio_flow_editor 0.3.0 (commit 296e5bf):

 - inputs/outputs endpoints now live in the layout sidecar
   like every other node — they stop drifting when the
   operator drags a step. The "outputs panel jumps when I
   touch anything" pain Stefan flagged is gone by
   construction.
 - Right-click on any step in the graph tab opens a popup
   menu: Duplicate (with unique id + offset), Disconnect
   all inputs (clears with-field values but keeps keys),
   Delete.
 - Floating Reset Layout button on the canvas next to
   Fit-to-screen — wipes the sidecar and re-runs
   AutoLayout from scratch + auto-fits, for when manual
   drags have drifted into spaghetti.

Version 0.52.4 -> 0.53.0 (minor bump — first new
operator-visible editor feature surface since 0.52).

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 16:16:37 +02:00
flemming-it
696541e5b3 fix(studio): narrow default window to 1280x900
Some checks failed
Security / Security check (push) Failing after 1s
The 1440x900 default felt too wide for first-run: the
Welcome page's 960 px content column left visible slack on
either side even after the centring fix, and the editor's
sidebar plus canvas plus properties panel still didn't
need that much horizontal room on a fresh open.

1280x900 matches the most common laptop effective
resolution, keeps every Studio surface comfortable, and
the operator can resize larger any time. Same value
across all three host platforms (macOS NSWindow setContentSize,
Linux gtk_window_set_default_size, Windows Win32Window::Size).

Version 0.52.3 -> 0.52.4.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 16:06:50 +02:00
flemming-it
f1b0f65c86 fix(studio): centre Welcome page content on wide windows
Some checks failed
Security / Security check (push) Failing after 2s
Welcome page used ConstrainedBox(maxWidth: 960) inside a
left-aligned Column, so on the 1440x900 default window
the content hugged the left edge and left ~370 px of
empty space on the right. With Stefan's M4 sidebar
collapsed to 72 px the asymmetry was the dominant visual
in the first thing every operator sees.

Wrap the ConstrainedBox in a Center widget. 960 px stays
an opinionated reading width — long-form prose gets
uncomfortable past ~1100 px — but the slack now splits
evenly so the content sits with ~190 px breathing room
on both sides instead of all on one.

Bumps the editor-package lock pointer to ad2e5b5 (same
0.2.2 version, picks up the extract-with-approval test
commit on top of f8138f3) as a side-effect of the
flutter pub upgrade run during verification.

Version 0.52.2 -> 0.52.3.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 10:52:38 +02:00
flemming-it
36ddac2017 chore(studio): bump editor lock to 0.2.2 (save snackbar + drop highlight)
Some checks failed
Security / Security check (push) Failing after 2s
Picks up:
 - Brief green-check snackbar after every successful save
   (Cmd+S keystroke now has visible confirmation).
 - During a connection drag, every input port lights up
   and the closest one within snap distance gets a halo
   glow so the operator sees which port the drop will
   snap to.

Version 0.52.1 -> 0.52.2.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 02:00:45 +02:00
flemming-it
8a220d9c6e chore(studio): bump editor lock to 0.2.1 (live status + fit-to-screen)
Some checks failed
Security / Security check (push) Failing after 1s
Pulls in:
 - Live step status on the graph during runs (the graph
   highlights running / done / failed / awaiting nodes
   alongside the run-tab list).
 - Empty-graph call-to-action overlay with an Add step
   button so the first opened-but-empty flow points the
   operator at the right action.
 - Fit-to-screen button + auto-fit on first open of each
   flow so wide flows aren't cut off in the default
   viewport.

Version 0.52.0 -> 0.52.1.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 01:54:08 +02:00
flemming-it
634fd52635 feat(studio): Flows page IS the editor — three-tab graph+text+run
Some checks failed
Security / Security check (push) Failing after 1s
Studio's Flows destination is now the swappable
fai_studio_flow_editor's full surface: a drag-and-drop
graph view, the raw YAML text editor, and the run tab
with inputs form + live step progress + outputs.

What's gone:
 - The old saved-flows list + per-row run dialog.
 - The separate "flow-editor" navigation destination (one
   icon, not two — operators reach the editor by clicking
   Flows, period).
 - _FlowEditorAdapter (no longer needed; FlowsPage hands
   the runDriver to the editor directly).

What's new:
 - lib/data/flow_run_driver.dart — StudioFlowRunDriver:
   adapter implementing the editor's FlowRunDriver. Maps
   runFlow() to HubService.runSavedFlow and events() to
   HubService.streamEvents filtered to step.* event types.
   Converts proto-shaped FlowOutput variants to the editor's
   host-agnostic FlowOutputValue family.
 - lib/pages/flows.dart — replaced with a 50-line wrapper
   that loads capabilities into the editor's picker dropdown
   and forwards the active locale.

Editor pinned to fai_studio_flow_editor 0.2.0 (commit
870cbc2). All editor state — file list, dirty tracking, tab
selection, graph layout sidecar, properties panel — lives in
the editor package now; Studio just supplies the hub bridge.

Version 0.51.10 -> 0.52.0 (minor bump — Flows-page contract
changed, separate flow-editor destination removed).

flutter analyze: 0 issues. flutter test: 12/12 green.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 00:52:23 +02:00
flemming-it
fe2ee0a323 chore(studio): bump editor lock to 0.1.4 (top-align + refresh move)
Some checks failed
Security / Security check (push) Failing after 2s
Stefan reported the editor still centered short files vertically
and the reload icon was still between New and Save — but his
pubspec.lock pinned fai_studio_flow_editor to resolved-ref
7655e0d (0.1.2), which predates both fixes:

 - a7485ca (0.1.3) stretch attempt
 - daf6732 (0.1.4) actual fix via CodeField expands:true +
   refresh moved into the FileList header

Force lock to daf6732 so `flutter pub get` during `fai studio`
build picks up the current state of the editor's main branch
without needing a manual `flutter pub upgrade` step.

Version 0.51.9 -> 0.51.10.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 00:12:03 +02:00
flemming-it
3097a30428 fix(studio): larger default window — 1440x900 across all platforms
Some checks failed
Security / Security check (push) Failing after 1s
Stefan observed the default Studio window opened smaller
than comfortable when launched fresh (no persisted size).
On macOS specifically the xib-stored default was around
800x600 — too tight to read the sidebar + content + run
panel side-by-side.

Set 1440x900 as the initial content size across all three
host platforms:

 - macOS: MainFlutterWindow.swift sets contentSize via
   NSWindow.setContentSize after the FlutterViewController
   attaches, and centers on the active NSScreen. Clamped to
   the screen's visibleFrame so we never open larger than
   the display (matters for non-Retina external monitors).
 - Linux: gtk_window_set_default_size 1280x720 -> 1440x900
 - Windows: Win32Window::Size 1280x720 -> 1440x900

1440x900 is the effective Retina resolution of a 13" MacBook
(Stefan's dev machine) and the smallest "modern desktop"
footprint that lets the sidebar + content + tool panel
breathe.

Version 0.51.8 -> 0.51.9.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-06-01 00:06:04 +02:00