Commit graph

9 commits

Author SHA1 Message Date
flemming-it
060c8003d5 feat(studio): operator-mode pass — Store + audit detail + channel switcher (v0.10.0)
Turns Studio from read-only dashboard into operator console.
Pieces:

  * **New Store page** (sidebar destination #3): browses the
    hub's bundled store-index with query + category + status
    filters. Each card has an Install button that prompts for
    the `.fai` bundle source (URL or local path), ships it to
    HubAdmin.InstallModule, shows success / error in a progress
    dialog, refreshes the list.

  * **Audit drill-down**: every event row is now tappable;
    opens a modal with all LoggedEvent fields including the
    new `detail` JSON pretty-printed in a code block. KRITIS
    forensic story: every audit row → full structured detail
    in two clicks.

  * **Approvals payload preview**: shipped already; now
    pretty-prints JSON when the preview parses as such, plus
    a clearer `PAYLOAD PREVIEW` label. Reviewer identity
    defaults to `$USER@studio` instead of the hard-coded
    `studio-mvp` so the audit trail records who acted.

  * **Channel switcher in Settings dialog**: the dialog now
    pulls HubAdmin.ChannelStatus and renders one row per
    channel (local / dev / beta / production) with port,
    running indicator, active marker. A "Connect" button
    on a running channel sets Studio's endpoint to that
    channel's port and reconnects in one click.

Cmd+1..6 keyboard shortcuts updated for the six destinations.
Widget test asserts every destination renders.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-07 11:54:31 +02:00
flemming-it
18db6ff164 feat(doctor): update banner via HubAdmin.CheckUpdate (v0.9.0)
Doctor page now opens with a slim banner above the summary strip
in two cases: an actually newer version on the channel ("Update
available — v0.x.y", success-tone "new" pill, release-notes URL
when present) or the release host being unreachable
("Release host unreachable", neutral "offline" pill, with the
network reason). When local matches latest the banner stays
hidden — quiet UI is the right default.

Hooks into the existing parallel-fetch in `HubService.doctor` so
the new RPC adds zero latency to the page load.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-06 15:53:52 +02:00
flemming-it
753db4fc60 feat(ui): Flows page (5th destination) + keyboard shortcuts
Two operator-DX additions:

1. **Flows** is the new third destination in the sidebar.
   Lists saved flows from the hub via the new HubAdmin
   ListFlows RPC. Each row has a Run button that opens an
   input dialog (key=value pairs, one per line, all values
   sent as text payloads — the binary-input case stays in
   `fai run` CLI). Flow runs in a non-dismissable progress
   dialog; output is shown per-key with monospace
   selectable text. Errors render with the exception detail
   for diagnosis.

2. **Keyboard shortcuts** at the shell level:
   - Cmd+1 / Cmd+2 / Cmd+3 / Cmd+4 / Cmd+5 jump to the
     matching destination (Doctor / Modules / Flows / Audit
     / Approvals).
   - Cmd+, opens the Settings dialog (macOS convention).

   Implemented via Flutter's Shortcuts/Actions/Intent triple
   so the bindings are discoverable in IDE devtools and
   composable with platform-specific overrides later.

Bumps fai_studio 0.7.3 -> 0.8.0.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 23:35:48 +02:00
flemming-it
2f32023322 fix(ui): theme toggle is now actually reactive
The toggle changed _mode and called setState on StudioAppState,
but the sidebar that hosts the toggle button never rebuilt:
StudioApp returns `MaterialApp(home: const StudioShell())`, and
the const child's element doesn't get a didUpdateWidget on
parent rebuild. So the toggle's icon would only flip on the
next health-poll tick (up to 5s later) when the sidebar's own
setState fired for an unrelated reason.

Switch to a ValueNotifier-based pattern:
- StudioAppState exposes `modeNotifier` (ValueNotifier<...>)
  instead of a getter.
- StudioApp wraps MaterialApp in a ValueListenableBuilder
  bound to the notifier so themeMode flips immediately.
- _ThemeToggle is itself a ValueListenableBuilder against the
  same notifier — its icon and onPressed always reflect the
  current value without depending on parent rebuild timing.

Bumps fai_studio 0.7.2 -> 0.7.3.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 23:00:45 +02:00
flemming-it
20230684a9 fix(ui): visible ∆ pulse + drop internal codename from version line
Two issues from live feedback:

1. The version label said "v0.7.1 · warm-minimalism". The
   suffix is an internal design-direction codename, not
   user-facing. Drop it — the line now just reads "v0.7.2".

2. The ∆ pulse in live mode used only alpha + blur, which is
   too subtle to register at first glance. Replace with a real
   scale-pulse: the whole mark grows from 0.85x → 1.15x → 0.85x
   over 1.6s. Glow halo blur range expanded (8→22) and alpha
   range widened. The triangle also gets a soft fill on the
   up-beat. Easy to spot from across the room.

Bumps fai_studio 0.7.1 -> 0.7.2.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 22:51:19 +02:00
flemming-it
d5631177e0 fix(ui): stat-tile overflow + visible build version
Two issues:

1. _StatTile in the Doctor page overflowed by ~6px on narrow
   widths because the Row containing the icon + label "AUDIT
   CHAIN" with letterSpacing=0.6 didn't fit in the ~90px
   constraint per tile (4 tiles in a Row sharing the page
   width). Fix: smaller icon (16→14), tighter gap, label wrapped
   in Flexible with TextOverflow.ellipsis, and the longest label
   shortened "AUDIT CHAIN" → "AUDIT" with the chain count moved
   to the subtitle.

2. The new redesign was easy to mistake for the previous build
   from the outside. Add a small monospaced version line right
   under "F∆I Studio" in the sidebar header:

       F∆I Studio
       v0.7.1 · warm-minimalism

   Self-identifying — "wrong build" is now visible without
   reading the about dialog.

Bumps fai_studio 0.7.0 -> 0.7.1.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 22:41:26 +02:00
flemming-it
521a8baab8 feat(ui): hub-endpoint settings dialog with persistence
Studio is no longer hardcoded to localhost:50051. A gear icon
in the sidebar footer opens a small settings dialog where the
operator picks host / port / TLS-on-or-off. Saved values
persist via shared_preferences and Studio reconnects to the
new endpoint immediately.

- data/hub.dart: HubService.loadPersistedEndpoint() called once
  before the first frame; reconnect() persists on every change.
- widgets/fai_settings_dialog.dart: typed form with port range
  validation, live URL preview pill, error surfacing if the
  reconnect fails.
- main.dart: gear icon at the sidebar bottom, replaces the
  static "platform v0.10.42" footer.

shared_preferences added as dependency. flutter analyze clean,
flutter test 2/2, macOS debug build succeeds.

Bumps fai_studio 0.4.0 -> 0.5.0.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 22:12:47 +02:00
flemming-it
c94504247f feat(ui): warm-minimalism redesign — design tokens + 6 primitives + animated ∆
Replaces the Material-default look with a deliberate visual
language. Single accent (sky-cyan), Inter + JetBrains Mono via
google_fonts, dense rows over puffy cards, micro-interactions
under 250ms. Dark-first, light reaches parity.

New foundation under lib/theme/:
- tokens.dart   FaiColors / FaiSpace / FaiRadius / FaiMotion
- theme.dart    ColorScheme + typography + component themes for
                light and dark, plus FaiTheme.mono helper for
                technical strings (IDs, paths, capability refs).

Six primitives under lib/widgets/:
- FaiCard            flat card, optional accent stripe (top or
                     left). No shadows.
- FaiPill            small inline label with five tones
                     (neutral / accent / success / warning /
                     danger), optional mono and leading icon.
- FaiStatusDot       breathing dot, used as a "live" indicator.
- FaiDataRow         Linear-style dense row for the audit
                     stream — hover-elevation, mono leading,
                     coloured leading stripe.
- FaiEmptyState      gracious icon + title + hint + action,
                     replaces "(no data)" everywhere.
- FaiDeltaMark       the ∆ signature element. Three modes —
                     idle (still), live (gentle pulse), busy
                     (slow rotation). Drawn from primitives,
                     not a font glyph. Lives in the sidebar
                     header so the brand is always visible.

Page-level changes:
- main.dart        custom 220px sidebar replaces the Material
                   NavigationRail. ∆ on top, hub-connection
                   pill below it, hover-animated destinations,
                   page transitions are 200ms slide+fade.
- modules.dart     FaiCard rows with capability pills.
- audit.dart       FaiDataRow stream, segmented filter chips,
                   live status bar with hash-chain badge.
- approvals.dart   FaiCard with accent-top stripe, structured
                   action footer, toast on approve/reject,
                   themed reject-reason dialog.

google_fonts added as dep. flutter analyze clean. flutter test
2/2. flutter build macos --debug succeeds.

Bumps fai_studio 0.2.0 -> 0.3.0.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 21:49:37 +02:00
flemming-it
a173eec1d0 feat: F∆I Studio MVP scaffold (Tier-2 desktop GUI)
Initial scaffold for the F∆I Platform Tier-2 generic GUI client.
Flutter Desktop (macOS, Linux, Windows). Three MVP pages with
mock data, sharing one navigation shell:

- Modules — installed modules with capabilities, declared
  permissions and required services.
- Audit — event-stream view with type filter and tone-coded
  rows (started / completed / failed).
- Approvals — pending system.approval@^0 reviews with prompt,
  payload preview, and approve/reject buttons.

Live gRPC connection arrives in the next iteration via
fai_dart_sdk (sibling repo, currently a typed stub).

Future Forgejo path: fai/studio. Local layout matches existing
fai_platform/ convention.

Background: see docs/architecture/client.md in the platform
repo. The tier-2 client was previously called "Stage" — renamed
to "Studio" on 2026-05-05 to avoid confusion with
"staging environment".

flutter analyze: clean. flutter test: 2/2.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 14:19:39 +02:00