Archived
3.6 KiB
3.6 KiB
Iteration 01 Request
- Task: 20260831-105824-plan-code-ui-audit
- Requested by: build
- Owner: coder
- Status: changes-requested
Confirmed Defects To Fix
MediaAPI.postdecodes every successful JSON object response asData.self; JSONDecoder only accepts a JSON-encoded Data representation, so/play,/control,/report, and/streamsmutate the server and then throwdecodeFailed. Make no-response POSTs validate HTTP success without decoding a body.MediaPlayerController.reconcilenever assignsdesired, so the UI always says Stopped, the transport icon is wrong, and interruption resume cannot work. Keep published desired state synchronized with server state.- Play/pause/stop/seek do not fully satisfy the documented reporting protocol. Ensure local transport changes promptly report actual playback and publish
media_statewhere required, while avoiding obviously stale room/session callbacks. endConversationstops media polling but retains a non-nil room, soMediaPanelView.startDefaultPolling()cannot restart it. Preserve coherent post-conversation polling/resume behavior.- Persisted text mode is not synchronized on join:
agentReadyReceivedalways enables the microphone and never sendsset_mode:text. Join must honor persisted mode, keep the mic disabled in text mode, and synchronize agent mode. - The Settings text-mode toggle writes only UserDefaults. During a ready session it changes the visible composer mode without muting/unmuting or notifying the agent. Route it through the same live mode application behavior as ConversationView.
- A
.failedsession renders a Start button, butconnect()accepts only.idle, making retry a no-op. Allow a user retry from failed state while preserving the one-time agent-timeout retry guard. - Persisted model preference can be overwritten by an early server
models.selectedmessage becauseselectedModelstarts nil and sync prefers it oversettings.modelID. Make persisted preference deterministic and do not let event timing silently replace it before sync. - Transcript primary and secondary finals are not deduplicated.
receiveDataTranscriptmarks partial rows final and appends another final, and identical primary/data finals can both persist to history. Implement role/text-aware cross-source final dedupe and replace the appropriate open partial rather than creating duplicates. - Add focused automated tests for pure/testable regressions above. Create the smallest viable unit-test target in
project.ymlif none exists, regenerate the Xcode project, and cover at least MediaAPI successful object responses, transcript dedupe/replacement, failed-state retry behavior where dependency seams permit, and media desired-state reconciliation where feasible. Do not contort production architecture solely for tests; document anything requiring integration coverage.
Constraints
- Product/source/config/test changes must be made only by coder.
- Keep fixes minimal and avoid the broader UI redesign in this iteration.
- Do not modify hope-voice-api or hope_companion.
- Preserve unrelated worktree changes and do not commit.
- Use XcodeBuildMCP per repository instructions for build/test verification; load its skill and show defaults first.
- Write the durable report to
implementation.md, naming actual fixed model, files changed, exact commands/tools and outcomes, and residual risks.
Acceptance
- Simulator build succeeds with zero new warnings.
- New tests pass.
- Each defect above is fixed or explicitly reported blocked with evidence.
- Existing server/device limitations are not misrepresented as client fixes.