feat: consolidate iOS with API and web preserving history
Rebuild & Deploy / rebuild (push) Failing after 23s

This commit is contained in:
snowspeeder committed 2026-10-04 07:23:49 -04:00
commit d735ee72fa
102 files changed
+13077 -258

No files matched your search

@@ -0,0 +1,121 @@
# UI Research Implementation Report
- Task: 20260831-105824-plan-code-ui-audit
- Agent: coder (UI/UX research pass)
- Model: litellm-lan/qwen3.8-27b (the fixed model this agent runs on; note the user asked for a "cheap local qwen3.8-27b" — this is exactly that model, routed via LiteLLM LAN)
- Date: 2026-08-31
- Status: complete
## Summary
Research-only pass: located and analyzed the square Hope visual element in the reference
projects, audited every SwiftUI source file in `voice-ios`, extracted the web design-token
system, and produced a full redesign specification. **No product code was modified** —
the only files written are this report and `ui-ux-spec.md`.
### The square Hope element (resolved)
The square Hope element is the **LED-wall avatar** in the web UI: a 320×320 px square
(`border-radius: 26px`) containing a 21×21 dot matrix that blooms with audio.
Evidence:
- `hope-voice-api/web/style.css` L331–346 — `.led-wall { width: 320px; height: 320px;
display: grid; grid-template-columns: repeat(21, 1fr); border-radius: 26px }`
- `hope-voice-api/web/style.css` L349–359 — glass panel backing (radial iris gradient + border)
- `hope-voice-api/web/style.css` L361–372 — `.led-dot` (base 5 px, 90 ms linear transitions)
- `hope-voice-api/web/style.css` L376–392 — state palette: idle `#56739E`, connecting/thinking
`#D99A6C`, listening `#6F8FF7`, speaking `#9DC2FF` + drop-shadow
- `hope-voice-api/web/app.js` L265–341 — build (21×21, per-dot radial + phase) and per-frame
render (gaussian falloff, ripple, audio-reactive sizing, listening dimmed to 0.55×)
- `hope-voice-api/web/index.html` L61–62 — wall is `aria-hidden`, separate `aria-live="polite"` label
Two related marks documented for the redesign:
- **Favicon glyph** (`hope-voice-api/web/favicon.svg`): 64×64 rounded square, plate `#08111F`,
iris circle + tilted orbit ellipse + warm dot — compact identity mark.
- **Companion icon** (`hope_companion/resources/icon.png`, generated by
`scripts/gen-icons.mjs`): 1024² rounded square (r≈22.3%), indigo→violet diagonal gradient,
white two-node + arc + ring mark. Verified 1024×1024 RGBA via `sips`.
The current iOS app uses **none** of these: `OrbView.swift` L45–47 is a plain 120 pt system-color
`Circle()`, and `Resources/Assets.xcassets/AppIcon.appiconset/Contents.json` has no images.
## Files Changed
Product code: **none** (research-only mandate).
Artifacts written:
- `.artifacts/20260831-105824-plan-code-ui-audit/ui-ux-spec.md` — full audit + redesign spec
(asset provenance, current-state findings N1–N3/C1–C11, navigation hierarchy, color/shape/
motion tokens with exact values, per-component specs incl. LED-wall formulas, accessibility,
app-icon plan, 4-phase rollout, acceptance criteria, risks)
- `.artifacts/20260831-105824-plan-code-ui-audit/ui-research-implementation.md` — this report
## Paths Inspected
### voice-ios (all SwiftUI sources read in full)
- `Sources/App/VoiceApp.swift`, `Voices.swift`, `SettingsStore.swift`
- `Sources/Features/Conversation/ConversationView.swift`, `OrbView.swift` (incl. TranscriptListView)
- `Sources/Features/Settings/SettingsView.swift`, `ConnectionTestView.swift`
- `Sources/Features/Tasks/TaskPanelView.swift`
- `Sources/Features/Media/MediaPanelView.swift`
- `Sources/LiveKit/VoiceSession.swift`, `ConversationState.swift`, `TranscriptHandler.swift`,
`TranscriptHistory.swift`, `ControlChannel.swift`, `TaskStore.swift`, `AgentMonitor.swift`
- `Sources/Media/MediaPlayerController.swift`, `PinnedMediaResourceLoader.swift`, `MediaAPI.swift`
- `Sources/Networking/TokenClient.swift`, `ServerConfig.swift`, `TLSPinning.swift`
- `project.yml`, `Resources/Info.plist`, `Resources/Assets.xcassets/AppIcon.appiconset/Contents.json`
- `PLAN.md`, `UPDATE_PATH.md`, `AGENTS.md`
### hope-voice-api (reference)
- `web/style.css` — token block L1–26, brand glyph L125–166, LED wall L316–429, buttons L431+,
message bubbles L702–764, task dots L1120–1150, keyframes L427/L709/L1133
- `web/app.js` — LED wall build/render L265–341, mic level smoothing L343–354, state setter L389
- `web/index.html` — ARIA structure (L18–107)
- `web/favicon.svg` — full file (square Hope glyph)
### hope_companion (reference)
- `scripts/gen-icons.mjs` — full SDF icon generator (plate, gradient, mark geometry)
- `resources/icon.png` — metadata via `sips` (1024×1024 RGBA)
- `package.json`, `electron-builder.yml` — icon usage
## Verification
Commands run (research-only; no build performed since no code changed):
- `sips -g all hope_companion/resources/icon.png` → 1024×1024, RGBA, hasAlpha: yes ✓
- `rg "led-wall|led-dot|orb" hope-voice-api/web/style.css` → located all LED-wall rules (L317–1563) ✓
- `rg "square" voice-ios/` → no hits; confirmed the term maps to the LED-wall container, not a literal "square" identifier ✓
- Read-based verification of every cited line range above.
No build/test commands were run because the brief restricts this pass to research and
specification; the spec's Phase A–D implementation will carry its own verification per
`ui-ux-spec.md` §11 (XcodeBuildMCP simulator build + the PLAN.md Phase 8 reconnect matrix).
## Design Decisions (recorded for the implementer)
1. LED wall is procedural (Canvas + TimelineView ≤30 fps), not a raster asset — matches web
implementation and keeps the asset catalog clean.
2. Exact port of app.js formulas (falloff/ripple/sizing) rather than an approximation — the
spec includes the verbatim math so behavior matches the reference pixel-for-pixel in intent.
3. System colors fully replaced by a `HopeColor` token enum derived from web `:root`;
semantic mapping (mint=success, danger=error, warm=thinking) documented in spec §5.1.
4. Accessibility mirrors web ARIA: wall hidden from VO, separate live status element,
announcements throttled to meaningful transitions only.
5. Four-phase rollout (tokens/assets → LED wall → transcript/composer → polish) so each
phase is independently reviewable and revertible.
## Risks And Limitations
- Simulator mic is dead (-4010, PLAN.md Phase 2): listening-side wall reactivity is
device-only; speaking-side verifiable in sim via agent TTS. Recorded as R1 in the spec.
- No automated tests exist in the repo (also noted in manifest Open Risks); verification
for the implementation phases will be simulator-based + Instruments profiling for the wall.
- `Color(hex:)` helper does not exist yet — required prerequisite for Phase A (spec R3).
## Follow-up For Reviewer
1. Confirm the "square Hope element" identification (LED wall) matches the user's intent;
if they meant the favicon glyph or companion icon instead, spec §9 already covers both as
secondary assets and only §6.1/§10-B would need re-scoping.
2. Review spec §5.1 token table for any brand values that should differ from web (e.g., if a
lighter iOS-native surface treatment is preferred over the dark canvas).
3. Approve Phase A–D sequencing before coder implementation begins; each phase has exit
criteria in §10 and global acceptance criteria in §11.