Files
LlamaCasty/HANDOFF.md
T

75 lines
7.1 KiB
Markdown
Raw 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.
# HANDOFF — Session State
## Branch
**`main`** @ `67baac6`, committed LOCALLY, working tree clean. **NOT pushed — user rule: never
push without explicit instruction (2026-08-24).** No feature branches pre-1.0: all work lands on
`main` per work unit.
## Shipped (this session, all on main)
- TASK 26 — webcam (+) menu gates on the app-wide identity (test `WebcamMenuGateTests`).
- TASK 27 — YouTube Chat one-per-layout gate + legacy label heal (test `ChatLayerGateTests`).
- TASK 19/23 status flip — Control Surface UX verified shipped; map corrected.
- TASK 20 step 1 — global hotkeys F1-F9 (`Services/GlobalHotkeys.cs`, test `GlobalHotkeyTests`). Validated by creator.
- ON-AIR sign right of REC — gray offline / red public / green private (`OnAirBrush`), shared `StatusSignText` style. Test `OnAirSignTests`.
- **Broadcast metadata pull-out + launch geometry** (`b988e6d`) — white "Text" tab on preview's right edge slides out the broadcast form: Title, Description, Tags csv, Visibility, Made-for-Kids, read-only Scheduled Start. Edits persist to Settings `Broadcast.*` immediately; Update Broadcast PUTs `liveBroadcasts?part=snippet,status` via new `YouTubeStreamService.UpdateBroadcast`. Go Live prefills from the form + captures back what was inserted. Old Default Stream Title/Description removed from App Settings (properties deleted). Window: default 1920×1040, MinWidth 1366, MinHeight 768, Manual startup, size+position persisted on close and restored clamped. Test `BroadcastPullOutTests`.
- **Bug-fix pass 1** (`e6baa55` + `d9e352f`): Text tab **always visible** (creator revised the Live-only gating same day); tab **toggles** the drawer; **click-away collapses it** (`Window_PreviewMouseLeftButtonDown` checks `TextPullOutHost` ancestry); avatar initial-letter fallback added.
- **Bug-fix pass 2** (`1009800`): real crash fix + avatar root cause.
- **Update Broadcast button** (`89ab83b`): diff-before-push, offline=local only, live=API; Go Live empty-field prompt opens Text drawer.
- **TASK 20 step 2** (this session): hotkey config UI + persistence:
- `Services/HotkeyChord.cs` — modifier+key chord record with display/parse/FromWpf helpers
- `Services/GlobalHotkeys.cs` — modifier param on `IHotkeyRegistrar`, custom bindings dict, `Reattach()` for hot-swap
- `Services/LayoutStore.cs` — `LoadHotkeyBindings()` / `SaveHotkeyBindings()` (Settings table, no migration)
- `ViewModels/HotkeyConfigViewModel.cs` — working copy, capture mode, conflict detection, unbind, reset
- `HotkeyConfigDialog.xaml` + `.cs` — click-to-capture, Unbind per row, Reset/Save/Cancel
- `ViewModels/MainViewModel.cs` — loads bindings, `OpenHotkeyConfigCommand`, `HotkeyBindingsChanged` callback
- `MainWindow.xaml.cs` — passes bindings to manager, re-attaches on dialog save
- Tests: `HotkeyConfigTests` (round-trip, display string, storage serialization)
- **Thumbnail strip hotkey labels** (`d4aa5e1`): each scene shows its current binding (e.g. "Starting F1").
- **Pull-out tab renamed** to "Stream Settings"; **right-click Start Stream** → Change Account / Logout context menu (`67baac6`).
- **Scope Lock rules** (`AGENTS.md` + `scripts/scope-check.sh`): pre-task scope declaration, git history scan before editing, pre-commit audit script that validates `git diff` against declared file list. Born from the `d2114c7` incident.
- Suite: 231 total, 230 pass — only failure is the known pre-existing `AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback`. Build 0 warnings.
## ⚠️ Landmines
- **User verdict (2026-08-23):** "The AI wrote fucked up code after repeatedly and intentionally misunderstanding instructions." Trust nothing from those sessions without manual verification. Session 2026-08-24 reinforced it: shipped a "fix" that couldn't work (see Run-crash above) and a UX guess that missed — verify behavior, don't pattern-match.
- **USER RULE: never `git push` without explicit instruction.**
- **Pre-existing test failure is ONE** (`AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback`) — unrelated to this session.
- **Real-MainWindow tests MUST set `LayoutPathOverride`** (ai.md) — DB pollution wiped real data once.
- **WPF handle forcing:** `WindowInteropHelper.Handle` pre-show returns Zero and does NOT raise `SourceInitialized`; use `EnsureHandle()` (does both).
- **Two MainWindows alive at once double-register hotkeys** — second window's RegisterHotKey fails silently-by-log. Tests close windows before opening the next.
- **Closing a MainWindow OVERWRITES saved window geometry** (Closing → SaveWindowGeometry). In tests that assert restore-from-DB, save state AFTER closing prior windows.
- **liveBroadcasts.update replaces the whole snippet part** — `UpdateBroadcast` echoes scheduledStartTime or YouTube clears the schedule.
- **contentDetails lock in created/ready** — latency/DVR/embed etc. cannot be edited while live; deliberately absent from the pull-out form.
- **Text Runs are not Visuals** — ANY new hit-testing code must type-guard before `VisualTreeHelper.GetParent` (it throws on non-Visuals).
- **Avatar images: never decode via BitmapImage.UriSource on this box** — use the HttpClient→StreamSource pattern in `MainWindow.LoadAvatarImage`.
- **App running locks ytLive.exe** — build fails MSB3027 until creator exits the app (or ask before killing PID).
- **`Source.Type` setter derives `IsBackground`** (Models/Source.cs:40) — any Type change must re-set IsBackground after.
- **vstest quirk:** only one `--tests:` param allowed; plain substrings work, alternation regexes silently match nothing.
- Notification.Wpf gotchas (ai.md/TASKS.md): area routing by XAML `Name`; unknown AreaName silently drops; `NeverExpires()` = `TimeSpan.MaxValue`; `ToHex()` = `#AARRGGBB`.
- **Dead code flagged, not touched:** `ShowWebcamCommand` / `CanShowWebcamInStagedScene` wired but unbound — audit item.
## Next steps
1. Verify unpushed fixes on next launch: logo click opens About (no crash); avatar shows the real profile image (startup.log free of `Avatar load failed`); then PUSH pending creator go-ahead.
2. Continue queue: TASK 17 web source, TASK 18 local recording, TASK 21 media source, TASK 22 audio sync offset.
3. Loose ends: dead `ShowWebcamCommand`, AudioPipelineTests failure, Velopack update URL.
## Build
```bash
"/mnt/c/Program Files/dotnet/dotnet.exe" build "C:\Users\gramp\Documents\Code\projects\ytLive\ytLive.csproj"
"/mnt/c/Program Files/dotnet/dotnet.exe" vstest "C:\Users\gramp\Documents\Code\projects\ytLive\ytLive.Tests\bin\Debug\net8.0-windows10.0.19041.0\ytLive.Tests.dll"
```
## Polar.sh resources
| Resource | ID |
|---|---|
| Org ID | `c05fb364-b967-4f6c-adf2-8a144e46d085` |
| Product | `d105dfa1-497e-423b-8cd4-e0ee2e3abbc0` |
| Price | `7c1b6f70-cf8c-46df-9bc8-6703f9fa64d0` |
| Benefit | `80f66bc1-d5a3-44a1-b9ea-1709ae508535` |
| Checkout URL | `https://buy.polar.sh/polar_cl_ueMy8AyAClO0o0yo19IroZwKTbD587gzUsjEW3bFapw` |
| Validate endpoint | `POST https://api.polar.sh/v1/customer-portal/license-keys/validate` |
| Key prefix | `LCYT-` |
## v1 vision
> A streaming tool so intuitive it needs no manual — go live or record in minutes, OBS-free.