Files
Sprimo/docs/FRONTEND_REQUIREMENTS.md
2026-02-13 11:22:46 +08:00

493 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Frontend Requirements Document — **sprimo-frontend**
**Document type:** Product + Engineering requirements (frontend scope only)
**Version:** v0.1
**Date:** 2026-02-12
**Scope:** Bevy-based overlay renderer + local control server + minimal UI.
**Out of scope:** Backend detection/rules engine (assumed external), cloud services.
---
# 1. Overview
The frontend is a **desktop overlay pet renderer** implemented in Rust (Bevy). It presents an animated character in a **transparent, borderless window** that can be **always-on-top**. It receives control instructions from a local backend process via **localhost REST API**, applies them to its animation/state machine, and persists user preferences locally.
The frontend must be able to run standalone (idle animation) even if the backend is not running.
---
# 2. Goals
> Note: Windows and Linux should be first-hand support, macOS support is optional.
1. **Render a cute animated character overlay** with smooth sprite animation.
2. Provide a **stable command interface** (REST) for backend control.
3. Offer **essential user controls** (tray/menu + hotkeys optional) to keep the pet recoverable and visible.
4. Persist **window position, scale, sprite pack choice, and flags**.
5. Be **cross-platform** (Windows/macOS/Linux) with documented degradations, especially on Linux Wayland.
---
# 3. Non-Goals (Frontend v0.1)
* Tool activity detection (backend responsibility).
* Online sprite gallery, accounts, telemetry.
* Complex rigged animation (Live2D/3D). Sprite atlas only.
* Full settings UI panel (tray + config file is enough for v0.1).
---
# 4. User Stories
## Core
* As a user, I can see the pet on my desktop immediately after launch.
* As a user, I can drag the pet to a preferred location.
* As a user, I can toggle always-on-top so the pet stays visible.
* As a user, I can change the character (sprite pack).
## Backend control
* As a backend process, I can instruct the frontend to play specific animations and switch states via REST.
* As a backend process, I can update position/scale/visibility.
* As a backend process, I can query frontend health/version.
## Safety
* As a user, I can always recover the pet visibility/interaction state via hotkey or tray item.
---
# 5. Functional Requirements
## 5.1 Window & Overlay Behavior
### FR-FW-1 Borderless + transparent
* Window must be **borderless** and **no title bar**.
* Background must be **transparent** so only the pet is visible.
**Acceptance**
* Screenshot shows only pet pixels; underlying desktop visible.
* No OS window chrome visible.
### FR-FW-2 Always-on-top
* Support always-on-top toggle.
* Default: ON (configurable).
**Acceptance**
* When ON, window stays above normal windows.
### FR-FW-3 Interaction model
* Click-through is not required.
* Pet remains interactive while visible.
* Must provide a **failsafe** mechanism to recover visibility and interaction state.
**Acceptance**
* Recovery hotkey/tray action restores visible, interactive pet state reliably.
### FR-FW-4 Dragging & anchoring
* User can drag the pet.
* Dragging updates persisted position in config.
* Optional: snapping to screen edges.
**Acceptance**
* Drag works smoothly, without major jitter.
* Relaunch restores position.
### FR-FW-5 Multi-monitor + DPI
* Window positioning must respect:
* multiple monitors
* per-monitor DPI scaling
* Position stored in a device-independent way where possible.
**Acceptance**
* Pet stays at expected corner after moving between monitors.
### FR-FW-6 Taskbar/Dock visibility
* Prefer not showing a taskbar entry for the overlay window (where supported).
* If not feasible cross-platform, document behavior.
**Acceptance**
* On Windows/macOS: overlay window ideally hidden from taskbar/dock.
* If not implemented, doesnt break core usage.
### Platform notes (requirements)
* **Windows:** always-on-top via SetWindowPos.
* **macOS:** NSWindow level + ignoresMouseEvents.
* **Linux:** best effort:
* X11: possible with shape/input region.
* Wayland: overlay behavior limitations may apply; document limitation.
---
## 5.2 Rendering & Animation
### FR-ANI-1 Sprite pack format
Frontend must load sprite packs from local disk with:
* `manifest.json` (required)
* atlas image(s) (PNG; required)
* optional metadata (author, license, preview)
**Manifest must define:**
* sprite sheet dimensions and frame rects (or grid)
* animations: name → ordered frame list + fps
* anchor point (pivot) for positioning
* optional hitbox (for drag region)
* optional offsets per frame (advanced)
**Acceptance**
* Default bundled pack loads with no config.
* Invalid packs fail gracefully with error message/log and fallback to default pack.
### FR-ANI-2 Animation playback
* Play loop animations (idle/dance).
* Support one-shot animations (celebrate/error) with:
* duration or “until frames complete”
* return-to-previous-state behavior
**Acceptance**
* Switching animations is immediate and consistent.
### FR-ANI-3 FPS control
* Configurable target FPS for animation updates (e.g., 30/60).
* Rendering should remain stable.
**Acceptance**
* Low CPU usage when idle animation running.
### FR-ANI-4 Layering
* Single character is mandatory for v0.1.
* Optional: accessory layers (future).
---
## 5.3 State Machine & Command Application
### FR-STM-1 Core states
Frontend supports at minimum:
* `Idle`
* `Active`
* `Success`
* `Error`
* `Dragging` (internal)
* `Hidden` (window hidden but process alive)
Each state maps to a default animation (configurable by sprite pack):
* Idle → idle animation
* Active → typing/dance
* Success → celebrate then return to Active/Idle
* Error → upset then return
### FR-STM-2 Transition rules
* Backend commands can:
* set state directly
* request specific animation with priority
* Frontend must implement:
* debouncing/cooldown (avoid flicker)
* priority arbitration (e.g., Error overrides Active)
**Acceptance**
* Repeated Active commands dont restart animation constantly.
* Error state overrides Active for N seconds.
### FR-STM-3 Local autonomy (no backend)
* If backend is absent:
* frontend stays in Idle with periodic idle animation
* user controls still function
* If backend connects later, commands apply immediately.
---
## 5.4 REST Control Server (Frontend-hosted)
### FR-API-1 Local binding only
* HTTP server must bind to `127.0.0.1` by default.
* Port configurable; recommended default fixed port (e.g., 32145).
### FR-API-2 Authentication token
* Frontend generates a random token on first run.
* Stored in local config directory.
* Backend must provide `Authorization: Bearer <token>` for all non-health endpoints.
* Health endpoint may be unauthenticated (optional).
### FR-API-3 Endpoints (v0.1)
**Required:**
* `GET /v1/health`
* returns: version, build, uptime, active_sprite_pack
* `POST /v1/command`
* accept a single command
* `POST /v1/commands`
* accept batch of commands
* `GET /v1/state` (debug)
* current state, current animation, flags, position/scale
**Command types required:**
* `SetState { state, ttl_ms? }`
* `PlayAnimation { name, priority, duration_ms?, interrupt? }`
* `SetSpritePack { pack_id_or_path }`
* `SetTransform { x?, y?, anchor?, scale?, opacity? }`
* `SetFlags { click_through?, always_on_top?, visible? }` (`click_through` is deprecated/ignored)
* `Toast { text, ttl_ms? }` (optional but recommended)
### FR-API-4 Idempotency & dedupe
* Commands include:
* `id` (ULID/UUID)
* `ts_ms`
* Frontend must ignore duplicate command IDs for a short window (e.g., last 5k IDs or last 10 minutes).
### FR-API-5 Error handling
* Invalid commands return 400 with error details.
* Auth failure returns 401.
* Server never crashes due to malformed input.
**Acceptance**
* Fuzzing basic JSON payload does not crash.
---
## 5.5 User Controls
### FR-CTL-1 Tray/menu bar controls (preferred)
Provide tray/menu bar items:
* Show/Hide
* Toggle Always-on-top
* Sprite Pack selection (at least “Default” + “Open sprite folder…”)
* Reload sprite packs
* Quit
If tray is too hard on Linux in v0.1, provide a fallback (hotkey + config).
### FR-CTL-2 Hotkeys (failsafe)
At minimum one global hotkey:
* Force visible + interactive recovery mode
Example default:
* `Ctrl+Alt+P` (Windows/Linux), `Cmd+Option+P` (macOS)
**Acceptance**
* User can recover visibility and interaction state even when the pet was hidden or misplaced.
### FR-CTL-3 Context menu (optional)
Right click pet (when interactive) to open a minimal menu.
---
## 5.6 Persistence & Configuration
### FR-CFG-1 Config storage
* Store config in OS-appropriate directory:
* Windows: `%APPDATA%/sprimo/config.toml`
* macOS: `~/Library/Application Support/sprimo/config.toml`
* Linux: `~/.config/sprimo/config.toml`
### FR-CFG-2 Config fields
* window:
* position (x,y) + monitor id (best-effort)
* scale
* always_on_top
* click_through (deprecated/ignored; always false)
* visible
* animation:
* fps
* idle_timeout_ms
* sprite:
* selected_pack
* sprite_packs_dir
* api:
* port
* auth_token
* logging:
* level
### FR-CFG-3 Live reload (nice-to-have)
* v0.1: reload on tray action (“Reload config”).
* v0.2+: auto reload.
---
## 5.7 Logging & Diagnostics
### FR-LOG-1 Logging
* Log to file + console (configurable).
* Include:
* API requests summary
* command application
* sprite pack load errors
* platform overlay operations outcomes
### FR-LOG-2 Diagnostics endpoint (optional)
* `GET /v1/diag` returns recent errors and platform capability flags.
---
# 6. Non-Functional Requirements
## Performance
* Idle: < 2% CPU on typical dev laptop (target).
* Memory: should not grow unbounded; texture caching bounded.
## Reliability
* Should run for 8 hours without crash under command load.
* If REST server fails to bind port, show clear error and fallback behavior.
## Security
* Localhost only binding.
* Token auth by default.
* No file system access beyond sprite/config/log directories.
## Compatibility
* Windows 10/11
* macOS 12+ recommended
* Linux:
* X11 supported
* Wayland: documented limitations, still runs
---
# 7. Platform Capability Matrix (deliverable)
Frontend must expose in logs (and optionally `/v1/health`) capability flags:
* `supports_click_through`
* `supports_transparency`
* `supports_tray`
* `supports_global_hotkey`
* `supports_skip_taskbar`
Example:
* Windows: click-through false; others vary by implementation status
* macOS: click-through false; others vary by implementation status
* Linux X11: most true
* Linux Wayland: skip-taskbar variable and overlay behavior limitations
---
# 8. Acceptance Test Plan (v0.1)
## Window
1. Launch: window appears borderless & transparent.
2. Drag: drag updates position; restart restores.
3. Recovery: hotkey restores visible + always-on-top behavior reliably.
4. Always-on-top: verify staying above typical apps.
## Animation
1. Default pack: idle animation loops.
2. Command: `PlayAnimation("dance")` plays immediately.
3. One-shot: `Success` plays then returns to previous.
## API
1. Health returns correct version/build.
2. Auth required for commands; invalid token rejected.
3. Batch endpoint applies multiple commands in order.
4. Malformed JSON returns 400, app remains running.
## Persistence
1. Settings persist across restart.
2. Missing sprite pack falls back to default.
---
# 9. Implementation Constraints / Suggested Stack (not mandatory but recommended)
* Renderer/engine: **Bevy 2D**
* REST server: **axum + tokio** in background thread
* Shared protocol: `protocol` crate with `serde` structs
* Platform overlay: separate crate/module with per-OS implementations:
* Windows: `windows` crate (Win32 APIs)
* macOS: `objc2`/`cocoa` bindings
* Linux X11: `x11rb` (best effort)
* Config: `toml`
* IDs: `ulid` or `uuid`
---
# 10. Open Questions (Frontend)
1. Do we require Linux Wayland support beyond “runs but limited overlay features”?
2. Do we want multiple pets (multiple windows) in v0.1 or later?
3. Do we embed a default sprite pack (license?), or ship an empty skeleton?
---
If you want, I can turn this into:
* a `docs/FRONTEND_REQUIREMENTS.md`
* plus a concrete **REST API spec** (OpenAPI-like) and a **sprite-pack manifest schema** with examples (JSON).