Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ DerivedData/
Output/
Output.nosync/
*.xcuserstate

.build/
Output/
.claude/worktrees/
.DS_Store
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
target: Sources/Lively/UI/ScreenCardView.swift
total_score: 31
p0_count: 0
p1_count: 3
timestamp: 2026-07-12T01-52-59Z
slug: sources-lively-ui-screencardview-swift
---
# Design Critique: Sources/Lively/UI/ScreenCardView.swift

## Design Health Score

| # | Heuristic | Score | Key Issue |
|---|-----------|-------|-----------|
| 1 | Visibility of System Status | 3.5 | Success/error toasts use hardcoded timeouts (3s and 5s) with no manual dismissal, making them difficult for slow readers. |
| 2 | Match System / Real World | 4.0 | Terminology matches macOS conventions; vertical hierarchy flows logically from identification to selection. |
| 3 | User Control and Freedom | 2.0 | Accidental clicks on the "Remove wallpaper" trash button immediately delete config without confirmation or undo capability. |
| 4 | Consistency and Standards | 2.5 | Hardcoded literals (`.black.opacity(0.55)`, `.red.opacity(0.85)`, specific paddings) bypass unified `LivelyBrand` token system. |
| 5 | Error Prevention | 3.0 | Programmatic checks (HEVC/H.264 video format, security bookmarks) prevent broken playback, but destructive buttons lack safety alerts. |
| 6 | Recognition Rather Than Recall | 4.0 | Persistent thumbnails and clear filenames show active wallpapers without forcing memorization. |
| 7 | Flexibility and Efficiency | 2.5 | Drag-and-drop works well, but active preview cards rely on `.onTapGesture` instead of a keyboard-focusable `Button`. |
| 8 | Aesthetic and Minimalist Design | 3.0 | Elegant "Mist Reef" styling, but cards crowd up to 7 distinct action items simultaneously when active, exceeding optimal memory limits. |
| 9 | Error Recovery | 3.5 | Toast alerts are descriptive, but the 5-second automatic dismissal window makes them easy to miss. |
| 10 | Help and Documentation | 3.0 | Static placeholder provides onboarding guidance, but browse hints are hidden in appearance mode. |
| **Total** | | **31.0/40** | **Good** |

---

## Anti-Patterns Verdict

* **LLM Assessment**: The implementation shows traces of AI-generated "magic-number" styling and redundant paths:
- **Token Neglect (Magic Numbers)**: Hardcoded padding parameters (`12`, `6`, `8`, `3`) and specific inline font sizes (`9pt`, `20pt`) bypass established layout constraints in `LivelyBrand`.
- **Redundant Actions**: Implementing two distinct delete paths (header trash and thumbnail 'X') suggests composite code generation that was not simplified during final refactoring.
- **Layout Density**: Stacking two drop zones beside scale, mute, and volume controls makes the 480×560pt popover card feel crowded.
* **Deterministic Scan**: Zero violations. The automated detector returned `[]` because it is built for web-based formats (HTML/CSS/Tailwind) and Swift/SwiftUI abstractions naturally bypass these signatures.

---

## Cognitive Load Assessment

* **Checklist Status**:
- [x] **Single focus**: Pass
- [x] **Chunking**: Pass
- [x] **Grouping**: Pass
- [x] **Visual hierarchy**: Pass
- [ ] **One thing at a time**: Fail. Active states display scale, mute, volume, deletion, and tabs concurrently.
- [ ] **Minimal choices**: Fail. Stacks 7 choices when a wallpaper is assigned (violates Cowan's ≤4 limit).
- [x] **Working memory**: Pass
- [x] **Progressive disclosure**: Pass. Settings collapse when configuration is empty.
* **Verdict**: **Moderate Cognitive Load (2/8 failures)**.

---

## Overall Impression
A highly defensive, clean-rendering macOS settings card with beautiful adaptive transitions. However, the UX is visually crowded, lacks safety confirmation overlays for destructive commands, and relies on non-focusable gesture views that break accessibility.

---

## What's Working
1. **Asynchronous Validation**: Checking H.264/HEVC support and security-scoped access prevents crashing.
2. **Screen Reader announcements**: Correct use of `AccessibilityNotification.Announcement` alerts VoiceOver users of state changes.
3. **Adaptive layout transitions**: Responsive mode changes are gated on `reduceMotion`.

---

## Priority Issues

### [P1] Inaccessible Video Thumbnail Affordance
* **Why**: The thumbnail uses `.onTapGesture` instead of a SwiftUI `Button`, making it impossible for keyboard-only/VoiceOver users to select or change a video.
* **Fix**: Wrap `VideoThumbnailView` in a standard button style, or apply `.accessibilityElement()` with appropriate traits and double-tap actions.
* **Suggested Command**: `$impeccable audit`

### [P1] Missing Deletion Safety Confirmation
* **Why**: The header trash button executes `configStore.remove` instantly. One misclick on a mouse or trackpad wipes a user's setup immediately.
* **Fix**: Bind the trash button to show a `.confirmationDialog` or `.alert` modal before deletion.
* **Suggested Command**: `$impeccable harden`

### [P1] Hidden Action Instructions in Appearance Mode
* **Why**: In Light/Dark mode, the browse hint "Drop a video, or click to browse" is hidden. First-time users won't know the mode card is interactive.
* **Fix**: Show a shortened secondary prompt (e.g. "Click to add video") under the mode title.
* **Suggested Command**: `$impeccable onboard`

### [P2] Hardcoded Values & Token Violations
* **Why**: Inline constants like `.system(size: 9)`, `.red.opacity(0.85)`, and padding integers bypass the `LivelyBrand` design system.
* **Fix**: Map inline values to `LivelyBrand.Typography`, `LivelyBrand.destructive`, and `LivelyBrand.Spacing` tokens.
* **Suggested Command**: `$impeccable typeset`

---

## Persona Red Flags

* **Sam (Accessibility)**:
- Cannot tab to or focus the interactive video preview card using a keyboard.
- Clear button lacks a VoiceOver accessibility label (defaults to reading system icon names).
- "Click to change" visual overlay text is only `9pt`, violating low-vision visibility guidelines.
* **Jordan (First-Timer)**:
- Does not know how to interact with appearance-mode boxes since text instructions are hidden.
- Confronted with unpolished technical jargon when validations fail: "Only H.264 and HEVC are supported. Re-encode this file."
* **Riley (Stress Tester)**:
- Accidentally deletes configuration with a single off-target click in the header.
- Network-stored video files will freeze the main thread inside `onAppear` because `resolveBookmark` runs synchronously.

---

## Minor Observations
- Success toast text instructions ("Switch Spaces...") could be enhanced with a macOS-specific helper (e.g., Mission Control tip).
- Volume slider could be completely hidden unless the user toggles mute off to keep choices under Cowan's limit.

---

## Questions to Consider
1. *Why do we have two separate paths to clear wallpapers (header trash vs. thumbnail cross)? If we remove the global header trash, does the layout breathe more and protect users from accidental wipes?*
2. *Should volume be muted by default, and should the slider stay hidden until explicitly unmuted?*
Binary file added assets/lively-app-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/lively-setting-design.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/lively-wallpaper.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
188 changes: 188 additions & 0 deletions docs/Lively-task-list-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Lively — Agent task list & implementation plan

> **Give this entire file to one agent (or one session). Work only on this product until ship criteria are met.**

| Field | Value |
|-------|--------|
| **Product** | Lively |
| **Priority** | P2 — ship + craft proof |
| **GitHub** | https://github.com/harshabala/Lively |
| **Local clone (preferred)** | `~/Documents/Projects/Lively` |
| **If missing, clone to** | `~/Documents/Projects/Lively` via `gh repo clone harshabala/Lively` |
| **Default branch** | `master` |
| **Work branch** | `feat/flow-metrics-2026-07` (create from latest default if needed) |
| **Stack** | Swift Package macOS menu-bar video wallpaper app |
| **Task IDs** | LV-1, LV-2, LV-3 |
| **Fable plan status** | Fable plan FAILED — reconstructed below from task list |
| **Work already done** | None for this initiative |

## Agent instructions (start here)

1. **Read this whole file** before editing.
2. **cd** to the local clone path above. If the path does not exist, clone the GitHub repo there.
3. `git fetch origin && git checkout -B feat/flow-metrics-2026-07 origin/master` (or continue existing feature branch if present).
4. Implement tasks in the **recommended commit sequence** at the bottom of the plan section.
5. After each commit: run the **verify commands** listed below.
6. Create/update **`docs/TASKS.md`** with every task ID and status.
7. Complete the **README dual-section rewrite**.
8. Run design + code + security self-review on the diff; fix critical/high issues.
9. Push branch and open a PR against `master`. Do **not** force-push. Do **not** merge unless the user asked for auto-merge.
10. Do **not** touch other portfolio repos in this session.

## What “done” means for this product

All task IDs listed above are implemented **or** explicitly documented as infeasible with a narrow alternative. Metrics are local-first, activation is a named constant, scoreboard is user-visible with method + privacy copy, README is dual-section, `docs/TASKS.md` is accurate, tests/build green, PR open.


## Global constraints (apply to ALL work)

Source: `~/Desktop/portfolio-implementation-plan-2026-07-10.md` and `~/Desktop/product-flow-metrics-task-list.md`.

1. **Local-first metrics** — counters/estimates on device or extension storage only. Nothing leaves unless user explicitly exports or opts in. **No cloud analytics in v1.**
2. **One activation event** — named constant in code (e.g. `ACTIVATION_EVENT = '...'`).
3. **User-visible scoreboard** on the natural success screen (ParseKit token-savings pattern), with **method + caveat microcopy**. Honest estimates; never fake precision.
4. **Privacy line on every stats surface:** e.g. *"Stored only on this device. Never uploaded."* (wording may adapt slightly per product).
5. **Zero-AI default** where relevant — core loop works without API keys; AI is optional upgrade.
6. **README rewrite required** in every repo (see below).
7. **`docs/TASKS.md`** committed checklist; update checkboxes as you finish task IDs.
8. **Ship path:** branch `feat/flow-metrics-2026-07` → push → open PR → (if user requested auto-merge and reviews pass) squash-merge to default branch and delete feature branch.

### README overhaul (mandatory for every product)

Rewrite `README.md` with **two top sections**:

#### Start here (novice)
Plain everyday words, zero jargon:
- What it is
- What problems it solves
- Step-by-step install and first use
- Edge cases and how to still use it when you hit them

#### For technical users
- Mermaid architecture diagram (GitHub-native render)
- How it works under the hood
- Metrics / activation definition
- Dev install, test commands, storage/privacy notes

### Ship checklist per repo

- [ ] All task IDs for this product implemented or honestly deferred with reason in PR
- [ ] `docs/TASKS.md` updated (checkboxes match reality)
- [ ] README novice + technical sections done
- [ ] Build/tests pass (commands in this file)
- [ ] Design pass (hierarchy, motion, empty states, reduced-motion)
- [ ] Code pass (edge cases, no regressions)
- [ ] Security pass (secrets, XSS, storage, permissions, no accidental egress)
- [ ] Branch pushed; PR opened with body mapping commits → task IDs → metrics
- [ ] Merge only if user wants auto-merge **or** explicitly asks

### Related docs (read if needed)

| File | Why |
|------|-----|
| `~/Desktop/product-flow-metrics-task-list.md` | Original product task specs + metrics definitions |
| `~/Desktop/pm-portfolio-analysis-lenny.md` | Why these metrics matter (senior PM framing) |
| `~/Desktop/portfolio-implementation-plan-2026-07-10.md` | Multi-repo orchestration notes |
| `~/Desktop/fable-portfolio-handoff/STATUS.md` | What Fable completed (mostly plans only) |



## Work already completed

None for flow-metrics.

## Original product task spec

# P2 — Lively

## Product in one line

macOS menu-bar video wallpapers per Space / display, offline.

## Current gap

Activation is “set a wallpaper once.” Retention is “still set weeks later.” Less business narrative — keep metrics light and local.

---

### Task LV-1 — First-run: pick video → apply → confirm Space

| Field | Detail |
|-------|--------|
| **Flow change** | On first launch: pick sample or file → Apply to current Space → toast *“Playing on this Space. Switch Spaces to set another.”* |
| **How it helps** | Activation in one minute. |
| **Metric: Activation** | `activated = wallpaper successfully applied ≥1` |
| **Privacy** | Paths local only; never upload video. |
| **Acceptance** | Sample video works without Finder hunt. |

### Task LV-2 — Menu bar: “Now playing” + days active

| Field | Detail |
|-------|--------|
| **Flow change** | Menu: current display/Space mapping; *“Active X days”* (days app applied a wallpaper for ≥1 hour — local). |
| **How it helps** | Lightweight retention signal for user and portfolio. |
| **Metric** | `days_with_wallpaper_active` |
| **User understanding** | *“Counts days Lively was actively rendering on at least one display.”* |
| **Acceptance** | Zero network dependency. |

### Task LV-3 — Performance honesty

| Field | Detail |
|-------|--------|
| **Flow change** | If thermal/CPU throttle: gentle notice *“Reduced quality to save power”* — builds trust. |
| **How it helps** | Nuance; support burden. |
| **Metric** | Optional local `throttle_events` count for your debugging only (not user-facing required). |

**Lively north star:** still active at day 7 among activated.
**User-facing:** now playing + days active.

---

## Implementation plan for agent


## Implementation plan (Fable never produced a plan — reconstructed from task list)

### Repo orientation
- Swift Package macOS app: `Package.swift`, `Sources/`, `Tests/`.
- Menu-bar video wallpaper; per Space / display; offline.

### LV-1 — First-run: pick video → apply → confirm Space
- First launch flow with sample video if needed.
- Activation: `ACTIVATION_EVENT = 'wallpaper_applied_once'` when apply succeeds.
- Local flag / date of first apply.

### LV-2 — Menu bar “Now playing” + days active
- Show current Space/display mapping.
- `days_with_wallpaper_active` local counter (days app rendered ≥1 hour optional; if hard, “days app applied wallpaper” is OK with honest copy).
- Privacy: paths local; never upload video.

### LV-3 — Performance honesty
- If thermal/CPU throttle: gentle notice reduced quality.

### Metrics
- Activation: wallpaper applied ≥1
- User-facing: now playing + days active
- Privacy line on stats surfaces

### Verify
```bash
swift build
swift test # if tests exist
```

### Commit sequence
1. feat: activation + first-run apply flow (LV-1)
2. feat: menu bar now-playing + days active (LV-2)
3. feat: throttle/performance honesty notice (LV-3)
4. docs: README dual sections + docs/TASKS.md


## Agent completion checklist

- [ ] LV-1 … LV-3
- [ ] README dual sections
- [ ] docs/TASKS.md
- [ ] swift build (+ tests if present)
- [ ] Security: no network for wallpapers; local paths only
- [ ] PR against master
Loading
Loading