diff --git a/HANDOFF.md b/HANDOFF.md index 45a31ea..c30bd42 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -2,45 +2,50 @@ ## Branch / Commit State -**`main`**, working tree is **CLEAN**. +**`main`**, working tree is **CLEAN**. `origin/main` == `1f4624c` (pushed). -Both split phases are now complete. Phase 1 (view-model partials) is pushed; -Phase 2 (MainWindow.xaml → UserControls) is complete but **local-only**. +**Pushed** (reached `origin/main` == `1f4624c`, incl. tags): Phase 1 commit `0` ++ refactor commits `1..11`, **and Phase 2 commits `12..18`** (they were pushed +at the Phase-2 milestone; the old "Phase 2 local-only" claim below was written +before that push and is stale). -**Pushed** (reached `origin/main` == `14d3ed4`, incl. tags): Phase 1 commit `0` -and refactor commits `1..11` (`refactor-commit-0..11`), plus policy/HANDOFF. +**LOCAL ONLY (Phase 3 — A, B, C, D, E) + the Controls doc commit** — policy +2026-08-30: no per-commit push; `git push` only at a user-agreed milestone / +"push it". **Push pending on explicit user approval:** -**LOCAL ONLY (Phase 2 — 12, 13, 14, 15, 16, 17, 18)** — policy 2026-08-30: no -per-commit push; `git push` only at a user-agreed milestone / "push it". -**Push pending on explicit user approval:** - -| Commit | Hash | Tag | Control | From Loc | -|--------|------|-----|---------|----------| -| 12 | `bc23b64` | `refactor-commit-12` | `Controls/BottomBar` | footer | -| 13 | `6914252` | `refactor-commit-13` | `Controls/HealthBanner` | row 1 banner | -| 14 | `90f5ad5` | `refactor-commit-14` | `Controls/TopBar` | row 0 top bar | -| 15 | `c5e3466` | `refactor-commit-15` | `Controls/PreviewPane` | center preview | -| 16 | `73397cf` | `refactor-commit-16` | `Controls/SceneThumbnailStrip` | row 0 strip | -| 17 | `c9fd1bd` | `refactor-commit-17` | `Controls/LeftPanel` | row 1 col 0 | -| 18 | `544208e` | `refactor-commit-18` | `Controls/OverlayHost` | overlay dialogs | +| Commit | Hash | Tag | Payload | +|--------|------|-----|---------| +| docs | `cb54637` | — | `Controls/index.md` (missing per-directory map) | +| A | `6944db8` | `refactor-commit-A` | split `MainViewModel.cs` core → **495** | +| B | `31362d1` | `refactor-commit-B` | split `MainViewModel.Streaming.cs` → **330** | +| C | `fab2e09` | `refactor-commit-C` | split `MainViewModel.Background.cs` → **418** | +| D | `d3271a0` | `refactor-commit-D` | trim `SocialsDialogViewModel.cs` → **334** | +| E | `dcb3637` | `refactor-commit-E` | split `LayoutStore.cs` → 6 partials, **≤495** | ## What's In Flight -Nothing code-in-flight — working tree clean, **Phase 2 complete**. +Nothing code-in-flight — working tree clean, **Phase 3 complete**. -**Phase 2 result:** `MainWindow.xaml` carved 1,681 → **123 lines** (a shell over -6 UserControls under `Controls/`, namespace `ytLive.Controls`). Every change: -0-warning build, `scripts/verify.sh` (246 pass + 2 known only), explicit-file -`scripts/scope-check.sh`, `ViewModels/index.md` in the SAME commit, tagged -`refactor-commit-N`, no per-commit push. +**Phase 3 result:** every production `.cs` is now **≤ 500 lines** (checked via +`git ls-files '*.cs'` minus tests; nothing exceeds 500). The 500-line count is a +**hard ceiling, not the goal** — each file was split **grouped by functionality** +so an AI can process one concern per file. Splits were **concern-driven**: +- `MainViewModel` → `.Sources.cs`/`.Web.cs`, `Streaming.cs` + `Streaming.Operations.cs`, + `Background.cs` + `Background.Model.cs`; `SocialSlotViewModel.cs` (row VM). +- `LayoutStore` (was 1402) → `Migrations.cs`/`Load.cs`/`Save.cs`/`Settings.cs`/ + `Assets.cs` + a 47-line shell; `public partial class LayoutStore : IDisposable`. + +Every change: 0-warning build, `scripts/verify.sh` (246 pass + 2 known only), +explicit-file `scripts/scope-check.sh`, `ViewModels/index.md` tracker in the +SAME commit, tagged `refactor-commit-N`, no per-commit push. **Next:** -- If user says "push": `git push origin main && git push --tags` (7 commits 12-18 - + their tags). -- Then optional Phase 3 if queued. Nothing is queued beyond Phase 2. +- If user says "push": `git push origin main && git push --tags` (6 commits: + `cb54637` + A–E, and tags `refactor-commit-A..E`). -**Pending bus:** `ViewModels/index.md` Phase 2 tracker has rows 12–18 (closed); -Phase 1 tracker closed. `Controls/` has `index.md`-style facts only if needed. +**Pending bus:** `ViewModels/index.md` Phase 3 tracker has rows A–E (closed); +Phase 3 marked COMPLETE. Watch-list (under limit, no action): `Controls/PreviewPane.xaml.cs` +(464), `ViewModels/MainViewModel.Audio.cs` (408). ## Landmines @@ -69,31 +74,29 @@ Phase 1 tracker closed. `Controls/` has `index.md`-style facts only if needed. ## Todo state - MainViewModel refactor: **Phase 1 complete (11/11 partials)**, pushed. -- MainWindow.xaml refactor: **Phase 2 complete (6/6 controls)**, local-only. +- MainWindow.xaml refactor: **Phase 2 complete (6/6 controls)**, pushed at `1f4624c`. +- 500-line compliance: **Phase 3 complete (all 5 offenders ≤ 500)**, local-only A–E. - TASK 3: 27/30 (preview compositor 16, text source 17, alerts 20 still open). - TASK 4: ✅ shipped. TASK 9: items 1–3 shipped; 4–7 open. TASK 10: steps 1–7; Velopack pending. - TASK 18: shipped, creator verification pending. TASK 19/23, 20, 21-A: shipped. - TASK 22 (audio sync offset): not started — required for v1. -## Session summary (2026-08-30) +## Session summary (2026-08-31) -- Ran the **MainWindow.xaml split to completion** under the standing "continue +- Ran the **500-line Phase 3 split to completion** under the standing "continue without stopping" directive — no interruption prompts, no `question` tool. -- Commits 12–18 landed locally, each: cut → 0-warning build → verify (246 pass + - 2 known) → scope-check → index.md in-commit → `git tag refactor-commit-N`. No push. -- **Commit 15 (PreviewPane** the hardest: 1920×1080 canvas + drag/select/resize/ - hit-test, webcam menu handlers, social glow, audio meters. A dropped outer - `Border` (background/glow/margin) was caught and restored same-commit. -- **Commit 17 (LeftPanel)** the biggest: property editors + chat autoscroll - (moved to self-subscribe on `Loaded`), drag-to-reorder, snapshot revert/accept - family; window routes via `_leftPanel.IsClickInside` and - `_leftPanel.OnSelectionChanged(vm)`. -- **Commit 18 (OverlayHost)** the scope-decision: moved only the three dialogs; - kept `WebViewHostPanel` + `ToastArea` as window-root stubs because their - name-based lookups (WebView2 init, toast `InArea`) would break if buried in a - control — a spin-guard decision, not a guess. -- Two XAML extraction gotchas recorded: (a) a moved block losing its `xmlns` - → MC2000 "key null" (Line n col m), fixed by adding `xmlns:models` on the - control root; (b) re-deriving line numbers after each edit before `sed`/awk - deletion ranges (the edit tool shifts numbers). -- Push checkpoint reached; awaiting explicit "push" for commits 12–18 + tags. +- Commits A–E landed locally, each: cut → 0-warning build → verify (246 pass + 2 + known) → scope-check → index.md in-commit → `git tag refactor-commit-{A..E}`. +- **Re-structuring principle (user correction, 2026-08-31):** split by + **functionality**, so an AI can process one concern per file; the 500-line + count is a **ceiling**, NOT the target. Do not pad or reshape code to a + number — group by concern and only split enough to stay under the ceiling. +- **Commit E (LayoutStore)** the biggest: 1402 → 6 concern-based partials + (Migrations/Load/Save/Settings/Assets/shell), default partial split. +- **Accident caught & recovered (Commit D):** a `> ViewModels/SocialsDialogViewModel.cs` + write that read from the file it was simultaneously truncating left the file at + 1 line. Fixed IMMEDIATELY via `git checkout --` and re-ran the split. **Lesson** + (goes in `MyMistakes.md`): never `awk … > SRC` where `awk` also reads `SRC`; + stage every multi-block cut into temp files first, then assemble. All later + LayoutStore cuts did exactly that (read original once into temp files). +- Push checkpoint reached; awaiting explicit "push" for `cb54637` + A–E + tags. diff --git a/MyMistakes.md b/MyMistakes.md index dc4808d..74cdb2b 100644 --- a/MyMistakes.md +++ b/MyMistakes.md @@ -44,3 +44,26 @@ packages, high-quality downscale via `TransformedBitmap`. Screenshots compress 4. Point `README.md` at the `.jpg` (not `.png`). **Result:** 3.2MB screenshot → 1400×794 → **188KB** `ytLlive-preview.jpg` in `docs/`. + +--- + +## Splitting a large file into partials — NEVER `awk … > SRC` while awking SRC + +(2026-08-31, Commit D) Tried to split `SocialsDialogViewModel.cs` in one line: +`{ awk '…' SRC; echo ""; awk '…2…' SRC; } > SRC`. The **first write truncated +SRC to 1 line**, so the second `awk` read the already-truncated file → the whole +source was lost (1 line left). Recovered with `git checkout -- SRC`, then redid +it, but the same bug could have meant making it up from scratch. + +**Rule:** when a cut needs N blocks from one source into N files, never write a +block back onto the source that the `awk`s still read. Instead: +1. Read the source **once** at the start into temp files (`mktemp -d`, one file + per block), with a `$D` variable you carry forward. +2. Verify block sizes (`wc -l`) and brace balance (`python3 -c` counting `{`/`}`) + before touching any real file. +3. Then assemble each new file from `cat D/block …` — never truncating the source + until every read is done. + +`git status` can't save you here if you don't notice until the file is gone — +`git checkout -- ` from the last commit is the recovery. Cheap insurance: +restore-then-retry, do it atomically from temp files the first time.