Commit graph

9 commits

Author SHA1 Message Date
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
671194c105 feat(ui): theme-mode toggle (system / light / dark) with persistence
Three-way switch in the sidebar footer next to the settings
gear. Cycles system → light → dark → system. Choice persists
via shared_preferences across app launches; restored before the
first frame so there's no theme flicker on startup.

The icon changes per state (auto / sun / moon) and the tooltip
spells it out so the cycling behaviour is discoverable.

- StudioApp is now stateful; exposes StudioApp.of(context) to
  let descendants flip the theme without prop-drilling.
- ThemeModeValue enum lives in data/hub.dart so the persistence
  layer stays free of flutter/material imports.

Bumps fai_studio 0.6.0 -> 0.7.0.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 22:19:13 +02:00
flemming-it
b3fdd69139 feat(ui): module-detail bottom sheet on tap
Tapping a module card on the Modules page slides up a detail
sheet showing the full manifest data: directory path
(monospaced + selectable), every capability with version, and
every declared permission with a semantic icon (net = globe,
fs.read = folder, fs.write = edit, env = terminal, hub =
shield).

Empty permission list shows "(none — pure-computation module)"
explicitly — the operator should see *why* a module needed
zero perms, not be left guessing.

Backed by HubAdmin.ModuleInfo. New widget FaiModuleSheet with a
small drag-handle, FutureBuilder for the load state, error
surfacing if the RPC fails.

Bumps fai_studio 0.5.0 -> 0.6.0.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 22:15:41 +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
4352ecc28c feat(ui): add Doctor page (4th destination) — full health snapshot
Composes the platform's health picture in one view:
- Summary strip: 4 stat tiles for modules / approvals / audit
  chain / services with semantic accent colour.
- Event-log panel: WORM-1 badge + chain status, points to the
  first tampered event id when integrity fails.
- Modules & approvals panel: counts plus an "attention" pill
  when approvals are pending.
- Services panel: declared services from operator config or a
  helpful empty-state pointing at ~/.fai/config.yaml.

Backed by the new HubAdmin RPCs (VerifyEventChain, ListServices)
plus the existing ListCapabilities and ListApprovals. One
HubService.doctor() call fans out to all four in parallel.

Doctor is the new first destination in the sidebar — that's the
page an operator wants to land on after starting the app.

Bumps fai_studio 0.3.0 -> 0.4.0.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 22:09:49 +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
127c497f73 feat: live gRPC pages — drop mock data, talk to the real hub
Studio's three MVP pages now pull live data from a running hub
via fai_dart_sdk. Mock fixture removed.

- data/hub.dart: HubService singleton wraps fai_dart_sdk's
  HubClient and exposes UI-friendly types (ModuleSummary,
  AuditEvent, PendingApproval) so pages don't import protobuf.
- pages/modules.dart: FutureBuilder against listModules,
  groups CapabilityEntry rows by module, retry-on-error UI.
- pages/audit.dart: 2s polling Timer, status bar shows
  "live (polling 2s)" or "disconnected — <error>".
- pages/approvals.dart: live listApprovals, Approve sends
  DecideApproval(APPROVE), Reject opens a reason dialog and
  sends DecideApproval(REJECT). Both refresh after success.
- Connection-error states across all pages: cloud_off icon +
  hint to start `fai serve` + Retry button.

When no hub is running the pages render their disconnected
state instead of crashing. When a hub is running, the data is
real — no more mock fixture.

Bumps fai_studio 0.1.0 -> 0.2.0.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-05 16:27:54 +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