shepherd-launcher/docs/ai/history/2025-12-26 002 initial ui.md
2025-12-29 12:38:38 -05:00

8.5 KiB
Raw Blame History

This prompt created the UI. It was run in the same conversation as the one that created shepherdd, and was also provided to Claude Opus 4.5 via VSCode Agent mode.

It was produced by ChatGPT after some back-and-forth in this conversation.

The output was committed as e2013eb694.


Now implement the UI that integrates with shepherdd as described below.


Linux / Wayland Launcher UI Specification

1. Purpose and scope

The Linux/Wayland launcher UI is the primary user-facing shell for a kiosk-style, child-friendly computing environment backed by shepherdd.

Its responsibilities are presentation and input only:

  • display what shepherdd allows right now
  • request launches and stops
  • display authoritative state (time remaining, warnings)
  • never enforce policy on its own

The launcher must not:

  • track time limits independently
  • decide availability rules
  • attempt to supervise or kill applications

If the launcher crashes or disconnects, shepherdd continues enforcement.


2. High-level architecture

The Linux UI is split into two cooperating Wayland clients:

  1. Launcher UI (main grid)
  2. HUD / Overlay UI (always visible)

Both are ordinary Wayland clients and communicate only with shepherdd over local IPC.

┌───────────────────────────────────────────┐
│ Sway (kiosk-configured compositor)        │
│                                           │
│ ┌───────────────┐   ┌──────────────────┐ │
│ │ HUD Overlay   │   │ Running App      │ │
│ │ (layer-shell) │   │ (fullscreen)     │ │
│ └───────────────┘   └──────────────────┘ │
│                                           │
│ ┌───────────────────────────────────────┐ │
│ │ Launcher UI (grid, home screen)        │ │
│ └───────────────────────────────────────┘ │
└───────────────────────────────────────────┘

3. Compositor assumptions (Sway)

3.1 Required compositor features

The launcher assumes a Wayland compositor that supports:

  • wlr-layer-shell (for always-on HUD)

  • fullscreen surfaces

  • IPC or rules to:

    • force fullscreen
    • prevent workspace switching
    • disable escape keybindings

Sway is the reference implementation.

3.2 Kiosk constraints to enforce in Sway config

The system must:

  • expose no user-visible workspaces

  • disable:

    • Alt+Tab
    • Mod+key bindings
    • exit / reload bindings
  • force launched applications fullscreen

  • ensure layer-shell overlay is always topmost

The launcher UI must not rely on Sway configuration details, but it must assume these constraints hold.


4. Process model

4.1 Launcher UI process

  • GTK4 Wayland application

  • normal Wayland surface

  • visible only when:

    • no session is running
    • or user explicitly returns to “home”

4.2 HUD / Overlay process

  • GTK4 Wayland application using layer-shell
  • always visible, regardless of running app
  • anchored to a screen edge (typically top)

4.3 Privilege

  • runs as the same user as the compositor
  • does not require elevated privileges
  • all privileged actions go through shepherdd

5. IPC contract with shepherdd

5.1 Connection

  • Unix domain socket (path configurable)
  • persistent connection
  • reconnect logic required

5.2 Commands issued by the launcher UI

  • ListEntries
  • Launch { entry_id }
  • StopCurrent
  • GetState
  • SubscribeEvents

5.3 Events consumed by launcher & HUD

  • StateChanged
  • SessionStarted
  • WarningIssued
  • SessionExpired
  • SessionEnded
  • PolicyReloaded

The UI must treat daemon state as authoritative.


6. Launcher UI (main grid)

6.1 Visual layout

  • Fullscreen window
  • Grid of large, touch-friendly icons
  • Each tile represents one EntryView from shepherdd

Each tile must show:

  • icon
  • label
  • enabled / disabled state
  • disabled reason (optional text or icon)

6.2 Availability handling

For each entry:

  • If disabled:

    • tile is visually muted
    • tapping does nothing
    • optional “why” tooltip (e.g. “Not available until 3pm”)
  • If enabled:

    • tapping sends Launch(entry_id)
    • UI transitions to “launching” state

6.3 Launch feedback

When a launch is requested:

  • grid input is disabled

  • show:

    • “Starting…” indicator
  • wait for:

    • SessionStarted → transition away
    • or error → restore grid

6.4 Return to home

The launcher UI must be able to re-appear when:

  • session ends
  • user presses “close” in HUD (if allowed)
  • daemon requests shell visibility

7. HUD / Overlay UI (always visible)

7.1 Placement and layer

  • Wayland layer-shell
  • layer: overlay
  • exclusive zone: minimal (or none)
  • must not be obscured by fullscreen apps

7.2 Required elements

The HUD must display, at minimum:

  1. Time remaining

    • authoritative countdown from daemon
    • format: MM:SS or H:MM:SS
    • visually emphasized when below warning thresholds
  2. Battery level

    • via UPower (local system API)
    • percent + icon
    • daemon does not own battery state
  3. Volume

    • current output volume

    • mute state

    • controls may:

      • send SetVolume via daemon
      • or adjust locally (implementation choice)
  4. Close / End session button

    • sends StopCurrent
    • availability depends on daemon state
    • may be hidden or disabled for certain entries
  5. Power button

    • opens a small modal:

      • Suspend
      • Shutdown
      • Restart
    • actions are forwarded to daemon (daemon decides if allowed)

7.3 Warning presentation

On WarningIssued:

  • show banner or modal in HUD
  • severity reflected visually
  • optional sound cue
  • must not block rendering of underlying app

On SessionExpired:

  • show “Times up” overlay
  • remain visible until session ends and home returns

7.4 Failure handling

If daemon disconnects:

  • HUD must:

    • show “Disconnected” indicator
    • attempt reconnect
    • not fabricate time remaining

8. Interaction between launcher and HUD

  • Launcher and HUD do not communicate directly
  • Both reflect the same daemon state
  • HUD remains visible while launcher is hidden
  • Launcher must ignore input while a session is running

9. Input and accessibility considerations

9.1 Input

  • Touch-friendly sizing
  • Mouse and keyboard supported
  • No reliance on keyboard shortcuts for core actions

9.2 Accessibility

  • High contrast mode recommended
  • Large fonts
  • Minimal text; icon-first design
  • Avoid hover-only affordances

10. Error states and recovery

10.1 Daemon unavailable at startup

  • Show blocking error screen:

    • “System not ready”
    • retry button
  • Do not allow launching without daemon

10.2 App fails to launch

  • Daemon emits failure
  • Launcher returns to grid
  • Optional error message

10.3 Session ends unexpectedly

  • HUD updates immediately
  • Launcher reappears automatically

11. Non-functional requirements

11.1 Robustness

  • UI must tolerate daemon restarts
  • UI must tolerate compositor restarts (best effort)

11.2 Determinism

  • Countdown is driven only by daemon events/state
  • UI must never infer remaining time independently

11.3 Maintainability

  • No daemon logic embedded in UI
  • All policy logic treated as opaque

12. Implementation constraints and recommendations

  • Toolkit: GTK4
  • Language: Rust (gtk-rs) preferred
  • Layer-shell: gtk4-layer-shell (or equivalent)
  • IPC client: reuse shepherd-api and shepherd-ipc types

13. Explicit non-goals

  • Embedding third-party apps inside the launcher
  • Replacing the compositor
  • Managing system accounts or users
  • Performing enforcement locally in UI

14. Success criteria

The launcher UI is considered correct if:

  • It can fully drive the system using only daemon IPC.
  • It remains usable while arbitrary fullscreen apps (VMs, emulators) run underneath.
  • Time warnings and expiry are always visible and accurate.
  • Replacing the launcher UI with another client would not weaken enforcement.