Skip to content

fix(RAN-68): land RAN-15 capture-target exclusion + cut v0.1.1#9

Merged
aksOps merged 3 commits intomainfrom
fix/RAN-68-capture-target-exclusion-v011
Apr 26, 2026
Merged

fix(RAN-68): land RAN-15 capture-target exclusion + cut v0.1.1#9
aksOps merged 3 commits intomainfrom
fix/RAN-68-capture-target-exclusion-v011

Conversation

@aksOps
Copy link
Copy Markdown
Contributor

@aksOps aksOps commented Apr 26, 2026

Summary

  • Lands RAN-15 (exclude SnipIT windows from capture targets) on origin/main for the first time. The fix existed locally on the maintainer's main (commit bc216cc) at the time of the v0.1.0 cut but was never pushed, so the v0.1.0 release notes' Fixed entry attributing this fix to v0.1.0 was inaccurate.
  • Refines the capture path so Invoke-FullScreenCapture and Invoke-WindowCapture route through Invoke-CaptureLoop with a per-iteration factory — fixes the use-after-dispose blank/crash on iteration 2+ (RAN-14 follow-up).
  • Corrects the v0.1.0 release-notes inaccuracy in CHANGELOG.md: moves the capture-flow Fixed line out of [v0.1.0] and into a new [v0.1.1] - 2026-04-26 section, and adds a Correction (2026-04-26) callout under [v0.1.0] pointing readers at v0.1.1. The v0.1.0 git tag annotation and GitHub Release body remain immutable per OSPS evidence policy; this CHANGELOG entry is the authoritative record.
  • Drops the literal bc216cc SHA from the RAN-15 gotcha in CLAUDE.md (the cherry-pick lands on a new SHA).
  • Closes RAN-68.

Commits

  1. fix(RAN-15): exclude SnipIT windows from capture targets — cherry-picked from local bc216cc. Adds Test-IsSelfWindowHandle / Resolve-WindowCaptureTarget pure helpers, the $script:SelfWindowHandles registry, IsWindowVisible / ShowWindow PInvoke + Hide-/Show-OwnSnipITWindowsForCapture helpers, and wires them into Show-SmartOverlay, Invoke-FullScreenCapture, and Invoke-WindowCapture. Adds 15 pure-logic regression tests.
  2. fix(RAN-14): route full-screen/window capture through Invoke-CaptureLoopInvoke-FullScreenCapture / Invoke-WindowCapture previously grabbed one bitmap outside the do/while and reused it across iterations; the preview disposes the bitmap on close, so iteration 2+ crashed. Now they go through Invoke-CaptureLoop with a per-iteration capture factory that re-runs the chrome-hide each grab. Adds 6 structural source-inspection guards in Test-SnipIT.ps1.
  3. docs(RAN-68): correct v0.1.0 release-notes inaccuracy + open v0.1.1 section — CHANGELOG + CLAUDE.md edits described above.

Test plan

  • pwsh ./Test-SnipIT.ps1 — 111/111 pass (15 RAN-15 + 7 RAN-14 + 6 new RAN-14 structural call-site guards + the rest of the suite).
  • Required CI checks (PSScriptAnalyzer, Trivy, Semgrep, Gitleaks, jscpd, SBOM, Pester) green.
  • Auto-merge on green CI.
  • Post-merge: signed v0.1.1 annotated tag on main HEAD, pushed to origin.
  • Post-merge: GitHub Release v0.1.1 published with body sourced from the v0.1.1 CHANGELOG section.

Out of scope

  • Any edit to the v0.1.0 GH Release body or tag annotation (immutable per OSPS evidence policy).
  • Any non-RAN-15 / non-RAN-14 capture-flow features.

aksOps and others added 3 commits April 26, 2026 05:17
- Add Test-IsSelfWindowHandle / Resolve-WindowCaptureTarget pure helpers
  in the Core region (cross-platform unit-tested) so the capture path
  has a single, testable place to ask "is this hwnd one of ours?".
- Maintain a $script:SelfWindowHandles registry; register the console,
  hotkey form, floating widget, and preview window when they are
  created, and unregister widget/preview on close.
- Add IsWindowVisible / ShowWindow PInvoke and
  Hide-/Show-OwnSnipITWindowsForCapture helpers that hide every visible
  SnipIT-owned hwnd before CopyFromScreen and restore them via SW_SHOWNA
  after the snapshot. Wraps the snapshot in try/finally so a thrown
  exception still restores chrome.
- Wire the helpers into Show-SmartOverlay, Invoke-FullScreenCapture,
  and Invoke-WindowCapture. Window capture now consults
  Resolve-WindowCaptureTarget and falls back to a full virtual-desktop
  capture (with chrome hidden) when the foreground window is SnipIT.

Adds 15 new pure-logic regression tests (Test-IsSelfWindowHandle and
Resolve-WindowCaptureTarget). Full suite: 105/105 pass.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
Invoke-FullScreenCapture and Invoke-WindowCapture grabbed one
System.Drawing.Bitmap outside the do/while loop, then handed that same
reference to Show-PreviewWindow on every iteration. After the first
iteration the preview disposes the bitmap (per the RAN-14 capture-loop
contract), so iteration 2+ used a disposed object and crashed / showed
a blank frame.

- Wrap each grab in a per-iteration factory closure that re-runs
  Hide-OwnSnipITWindowsForCapture / New-ScreenBitmap / Show-...
  (so the chrome-hide from RAN-15 still applies to every snapshot).
- Route both functions through Invoke-CaptureLoop so the preview owns
  the bitmap and a fresh one is created each loop.
- Add structural regression guards in Test-SnipIT.ps1 (Describe block
  'Full-screen and window capture New-snip paths (RAN-14 regression)')
  that inspect SnipIT.ps1 source to ensure neither function can
  regress to the pre-loop pattern (no New-ScreenBitmap outside a
  scriptblock; no `} while ($again)` reuse).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
…ection

CHANGELOG.md
- Open new [v0.1.1] - 2026-04-26 section above [v0.1.0]:
  - RAN-15 capture flow — exclude SnipIT widget/preview/tray windows
    from the capture target (the line incorrectly published under v0.1.0
    Fixed; the underlying commit was never on origin/main at v0.1.0
    cut time).
  - RAN-14 full-screen / window capture refactor — route both functions
    through Invoke-CaptureLoop with a per-iteration capture factory.
- Remove the RAN-15 capture-flow line from [v0.1.0] Fixed.
- Append a "Correction (2026-04-26)" callout under [v0.1.0] Fixed
  pointing readers at the v0.1.1 entry. The v0.1.0 git tag annotation
  and GitHub Release body remain immutable per OSPS evidence policy;
  this CHANGELOG entry is the authoritative record.
- Add v0.1.1 link reference; retarget [Unreleased] compare to v0.1.1.

CLAUDE.md
- Drop the literal `bc216cc` SHA from the RAN-15 capture-target
  exclusion gotcha (the cherry-pick lands on a new SHA on main).
  Replace with "shipped in v0.1.1".

.bestpractices.json
- Unchanged. maintained_justification (line 53) already cites
  RAN-15 capture-target exclusion as recent activity, which stays
  true once v0.1.1 lands.

Tests: Test-SnipIT.ps1 — 111/111 pass (15 RAN-15 + 7 RAN-14 +
6 structural call-site guards).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@aksOps aksOps enabled auto-merge (squash) April 26, 2026 05:20
@aksOps aksOps merged commit 7ca91eb into main Apr 26, 2026
12 checks passed
@aksOps aksOps deleted the fix/RAN-68-capture-target-exclusion-v011 branch April 26, 2026 05:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant