Commit graph

57 commits

Author SHA1 Message Date
flemming-it
88c5f2da1f fix(studio): Cmd+; opens Settings (Cmd+, is reserved by macOS) (v0.12.1)
Operator reported Cmd+, doing nothing. macOS reserves Cmd+,
for the native app-Preferences menu item which Flutter Desktop
doesn't wire up — the keystroke is captured by the OS before
the Shortcuts widget sees it.

Adds Cmd+; as the working alternative; keeps Cmd+, registered
too so a future Flutter version (or a native-menu setup) can
light it up. Tooltip on the sidebar gear icon now reads
"Settings (⌘;)" so the discoverable affordance also tells you
the shortcut.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-07 13:49:21 +02:00
flemming-it
4c4e2bb1eb feat(studio): "Explain this" + System AI in Settings (v0.11.0)
Two new operator affordances powered by `HubAdmin.AskAi`:

  * **Audit drill-down → "Explain" button.** Tappable on every
    failed event when System AI is configured; greyed out with
    a "Configure in Settings" tooltip otherwise. Shows an
    inline panel under the event fields with the LLM's plain-
    language explanation, a "FIX" suggestion, the privacy-mode
    badge (`redacted` / `full`), and round-trip latency. Errors
    map to actionable fix hints (`env_missing` → "set $VAR in
    your shell, then fai daemon restart"; `network` → "is your
    provider running?"; etc.) — no raw HTTP errors surfaced.

  * **Settings dialog → System AI panel.** Renders the live
    HubAdmin.SystemAiStatus (provider, endpoint, model,
    api_key_env name, privacy mode). When disabled, shows a
    one-line explainer + pointer to docs/architecture/system-ai.md.
    Read-only for now; editing the config still requires
    ~/.fai/config.yaml (Phase-1+ adds in-place editing).

Both surfaces follow the new zero-learning-curve UX rule:
the user never has to look up what the configurable means or
how to fix an error — every state self-explains in place.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-07 13:18:22 +02:00
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
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