Skip to content

Modernize Poratake capture, recording, and release systems - #13

Merged
SDSLeon merged 73 commits into
mainfrom
poracode/eager-ember-bef5af0f
Aug 21, 2026
Merged

Modernize Poratake capture, recording, and release systems#13
SDSLeon merged 73 commits into
mainfrom
poracode/eager-ember-bef5af0f

Conversation

@SDSLeon

@SDSLeon SDSLeon commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator
  • Rebrand the application, remove hosted licensing dependencies, and add compliant product and third-party notices.
  • Unify cross-platform capture overlays and introduce the Windows Rust daemon for screenshots, recording, OCR, QR scanning, and related system features.
  • Enhance recording controls, video editing, audio/video export, history, settings, device management, and theming.
  • Modernize tooling, dependencies, CI/release workflows, packaging, and comprehensive test coverage.

saeedvaziry and others added 30 commits August 6, 2026 21:55
Ports the macOS-only app to Windows. The Swift daemon gains a Rust
counterpart under src/main/daemon-win that mirrors it module for module,
so the main process speaks one daemon protocol on both platforms.

- src/main/daemon-win: Rust daemon (protocol, router, overlay, ui) with
  modules for screen capture, screenshot, scroll capture, area/window/
  display selection, camera preview, audio and camera recording, recording
  overlay and controls, OCR, QR, print, desktop helper and wallpaper,
  freeze screen, and timer control
- src/main/system/capabilities.ts, src/main/utils/platform.ts,
  src/renderer/utils/capabilities.ts, src/types/capabilities.ts: platform
  and capability plumbing
- src/main/capture/area-capture, src/main/capture/screenshot/native-capture.ts:
  Windows capture paths
- scripts/build-{daemon,ffmpeg,whisper}-win.ps1, scripts/dev.mjs,
  scripts/ensure-daemon.mjs: Windows toolchain
- .gitattributes: pin line endings so checkouts stay consistent across
  platforms
- tests/unit: platform, capability, path, and capture coverage

Accumulated across several agent threads in a shared worktree; committed as
one changeset to establish a baseline before verifying the build on Windows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the native area-capture path with an Electron overlay window so
the selection UI shows an HDR-correct frozen frame of each display.

The daemon's screenshot module now captures a full display frame, writes
it to a temp .bmp, and retains it in memory behind `retain`/`cached`
flags plus a `release` method. The overlay renders that file per display
and crops the confirmed selection from the retained frame before
releasing it. This avoids re-capturing after selection, which previously
let the screen change between freeze and capture.

Also normalizes HDR scRGB surfaces by the OS SDR white level in
desktop_frame.rs and display_color.rs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- replace native overlay selection on Windows with an interactive
  Electron backend, adding session/window management plus reusable
  selection geometry, pointer state machine, aspect ratio, size editor,
  and all-in-one toolbar components
- gate screenshot freeze behind shared isFreezeScreenEnabled preference
- add media device discovery and camera/microphone settings with live
  mic level meter and camera preview testing (including mirror flip)
- track window title-bar theme and persist window bounds; add Windows
  window-controls spacers and transparent-body support
- add dev-lock script to guard against concurrent dev sessions
- migrate video editor state to v2 and harden shortcut parsing
- extend Rust daemon with shared panel rendering, process-wide MTA COM
  guards, media-device/mic-level modules, scroll-capture and recording
  control fixes, and DwmFlush for uncached captures
- build and package Windows artifacts in CI
- Rebrand from Capty to Poratake across README, package.json, scripts, daemon, and settings, updating icons, fonts, and app naming
- Migrate UI primitives (button, card, tabs, tooltip, switch, slider, etc.) to the new component library and upgrade to React 19
- Add configurable app theme presets with appearance settings and contrast-safe tokens
- Rework settings UI with new registry, search results, sidebar, and select components
- Add Windows recording control window and video export session lifecycle management
- Harden Windows daemon OCR, QR code, window selector, and overlay modules
- Strengthen release workflow with asset validation and updated CI scripts
- Add AGPL compliance tests, THIRD_PARTY_NOTICES.md, and bundled license texts
- Capture windows with HDR GPU tone-map, fit letterbox, and accent outline
- Allow mid-recording mic, system audio, and camera changes with visible ranges
- Route Windows area, window, and all-in-one selection through Electron overlay
- Add camera timeline track, timeline split, music/export UI, and wallpaper render
- Extract auto-zoom types; expand tests and document Windows capture behavior
fix: finish Poratake standalone repository readiness
- Point package homepage, README, and About tab to porabuild.com/poratake
- Align rebrand compliance tests with the new URL and version metadata
* feat: remove Capty licensing and complete Poratake rebrand

- Remove license activation, entitlement, and Capty Cloud access flows
- Rename daemon, environment, temporary-file, and native identifiers
- Allow unrestricted video export and default cloud configuration to S3
- Update configuration and tests for the new product behavior

* chore(build): align Windows build metadata with Poratake

- Rename MSYS2 and FFmpeg build environment variables
- Update CI package workspace name to Poratake

* fix: format files flagged by CI prettier check

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

* feat: add pre-commit hook that rejects unformatted files

Adds a dependency-free git pre-commit hook (`.githooks/pre-commit`) that
checks every staged TS/JS/JSON/CSS/MD file with prettier after LF
normalization, so local commits catch what CI's format:check fails on.
Wired via `core.hooksPath` and a `prepare` script so fresh clones get it
automatically.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

* perf(ci): cut PR checks below 5 minutes

Moves the full Windows package build (FFmpeg + whisper.cpp + electron-builder)
out of the PR path into a main-push-only job, since it is the 21-minute
dominant step and PRs only need the Rust gates. Adds Bun and Rust target
caching, plus CI-only skip-when-built guards so cached native binaries
are reused instead of recompiled.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

* fix(ci): include daemon source in the native cache key

The native-binary cache key hashed the build scripts and Cargo.lock but
not the daemon's Rust sources, so a source-only change could restore a
stale capty-daemon.exe and the CI skip guard would validate the wrong
binary. Hash Cargo.toml and src/**.rs so any daemon change invalidates
the cached natives.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

* fix(ci): skip the Electron binary download in non-packaging jobs

The windows-native job failed with a socket hang up while the electron
postinstall script downloaded its ~120MB prebuilt binary.

Neither the checks nor the windows-native job runs electron-builder, and
every test mocks the electron module, so that binary is never used. Only
the npm package (types, mocked module surface) is needed, and that still
installs. Setting ELECTRON_SKIP_BINARY_DOWNLOAD removes the flaky
download from both jobs and shortens their install step.

windows-package keeps the download since electron-builder requires it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
- Split macOS and Windows release builds before publishing
- Validate Windows installer metadata and asset hashes
- Enable and test Windows update checks and installation
- Migrate screenshots, OCR, QR, all-in-one, and window picking to shared overlays
- Add native frozen-frame screenshot capture and macOS capture sound
- Rebuild scroll capture with Electron control and preview windows
- Improve recording controls, camera, audio, device, and window targeting flows
- Add development daemon builds, window loading helpers, and platform fallbacks
- Update onboarding, settings notices, icons, documentation, and tests
SDSLeon and others added 29 commits August 17, 2026 01:18
- Add branded hero, links, and feature overview
- Document installation, development, and contributing guidance
- Expand license and third-party attribution details
- Make capture previews focusable on Windows
- Set the default window screenshot shortcut to Alt+Shift+2 on Windows
- Add platform-specific preview and shortcut coverage
- Stream Windows freeze captures and restore overlay foreground state
- Synchronize overlay reveal and focus handling across platforms
- Debounce and atomically flush settings writes on quit
- Add development timing diagnostics and coverage tests
… add staged pre-commit checks (#5)

* chore(git-hooks): run staged format, lint, and type checks

* chore(tooling): migrate linting and formatting to Oxfmt and Oxlint

- update TypeScript targets, types, and modern collection APIs
- normalize renderer, main-process, and test code
- update CI, release scripts, dependencies, and lint configuration
- adjust tests and mocks for stricter validation
* internal: remove redundant package dependencies

* internal: enforce LF formatting across platforms

* internal: update Electron and shared Vite toolchain

* internal: update native media dependencies

* internal: harden dependency builds and packaging

* fix: make license inventory independent of Bun hoisting

* fix: preserve dependency build safety

* internal: update remaining dependencies to latest

* fix: complete Vite 8 JSX migration

* internal: migrate Windows daemon to Rust 2024

* internal: enable React Compiler with Bun

* fix: enforce React immutability in video playback

* fix: enforce React memo dependencies in editor

* fix: preserve editor callback memoization

* fix: derive naming pattern draft during render

* test: enforce React render purity in hook probes

* fix: enforce React ref purity in editor interactions

* fix: enforce React effect dependencies

* fix: derive editor state without effects

* fix: enforce React state effect purity

* test: cover compiler timing migrations

* refactor: rename daemon binary and project extension to Poratake

Complete the Capty -> Poratake rebrand for the two remaining
user- and build-visible identifiers:

- Rename the Rust daemon crate and its output binary from
  capty-daemon to poratake-daemon, updating the build scripts,
  dev lock process matcher, runtime resolution paths, packaging
  config, CI workflows, and .gitignore.
- Change PROJECT_EXTENSION and the macOS document type
  declarations from .capty to .poratake.
- Drop the legacy migrateCloudConfig branch that force-disabled
  cloud sync for the retired 'capty' provider.

Extend rebrand-compliance coverage to lock in the new extension
and daemon crate name, and ignore *.tsbuildinfo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Get-FileHash is a function in the autoloaded Microsoft.PowerShell.Utility
module. Under the MSYS2 environment used by the Windows package job,
PSModulePath is rewritten to POSIX paths, so autoloading fails and the
build stamp computation aborts the whole Windows package build.

Compute the SHA-256 with System.Security.Cryptography directly, which has
no module dependency.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vsrc_gfxcapture_winrt.cpp is the only C++ translation unit this FFmpeg
configuration builds. Under clang/libc++ on the arm64 runner, the
'#include <version>' it pulls in through <optional> resolves to FFmpeg's
own VERSION file: the case-insensitive Windows filesystem matches it via
the -I. on FFmpeg's compile line, so the compiler parses "9.0.1" as C++
and the arm64 release build fails.

Poratake captures through its own daemon and never uses the filter, so
disable it. This also keeps the x64 and arm64 binaries in step.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…#7)

* internal: add debug instrumentation for AIO overlay timing

* internal: add env-gated file-trigger for unattended AIO measurement

* internal: variant A - trigger only, no instrumentation

* Revert "internal: variant A - trigger only, no instrumentation"

This reverts commit 4414d13.

* internal: always-on event-loop lag monitor and shortcut lifecycle logging

* internal: untrack scratch measurement scripts

* internal: remove AIO debug instrumentation

Drops the temporary debug logging, the env-gated file trigger and the
always-on event-loop lag monitor added while investigating the Windows
shortcut latency. The always-on 100ms interval was itself masking the
bug by keeping the libuv loop from parking.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(main): dispatch user actions without waiting for an idle event loop

In the main process, promise continuations only run when the libuv loop
turns. While the app is idle the loop parks, so a callback arriving from
Chromium rather than libuv stalled at its first await until an unrelated
event woke the loop. Measured 349-2252ms from Alt+Shift+S to the first
native call, with the whole delay ahead of any I/O.

A flow whose first act is real I/O was immune, because daemon.call()
writes to stdin synchronously before returning its promise. That is why
the plain area screenshot looked fine: it happens to call
desktop-helper.hide first. Turning off "hide desktop icons" gave that
path the same 93-1548ms stall, confirming the mechanism.

flushPendingContinuations() schedules one loop turn; a single microtask
checkpoint then drains the queue to empty, unwinding the resolved chain
to the first real I/O. Applied at the three boundaries that start
user-initiated flows: the shortcut dispatcher, the tray menu template
funnel, and area-overlay:toolbar, whose mode switch reaches the daemon
only via a freezeTransition microtask. Deliberately not a periodic
timer, which would mask the problem and cost battery when idle.

shortcuts.ts collapses eight near-identical register functions into one
table-driven dispatcher, unifying the feature, handler and accelerator
maps into a single source of truth, and now validates the action from
shortcuts:register instead of casting it to a capture mode.

Alt+Shift+S to first native call: 1238ms avg -> 4.3ms avg.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* internal: split package-win out of build-win

build-win rebuilds ffmpeg and whisper, which needs MSYS2 and fails on a
machine without it even when those binaries are already present. The new
package-win runs only the clean, tsc, vite and electron-builder steps, so
a JS-only rebuild no longer requires the native toolchain. build-win
keeps its existing behaviour by chaining the two.

Also ignores .scratch* so local measurement scratch dirs stay untracked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…#8)

- Add color picker component and update area overlay toolbar and window
- Enhance area overlay session management and interactive capture handling
- Update OCR, QR code, video recording actions, and cloud services
- Add notification utility in main process
- Add and update unit test coverage across capture, UI, and utility modules
- Update `test` script to run once and add `test:watch` in `package.json`
- Add unit tests for capture preview disposal in `recording-actions`
- Update `packageManager` in package.json to bun@1.4.0
- Bump `bun-version` to 1.4.0 in CI checks and release workflows
- Update rebrand compliance unit tests to match the new version
- Add `releaseNotesToText` utility to strip HTML tags and decode entities
- Format release notes before setting update state in updater and dev mode
- Add unit tests for release notes conversion and entity decoding
- Add cloud secrets and wallpaper asset handling to settings with migration support
- Improve video recording projects, IPC state handlers, and audio export pipeline
- Refine capture preview, screenshot tools, and area overlay windows
- Update history tracking mechanisms and history window interface
- Streamline preload APIs, renderer theme hooks, and recording tray controls
- Add comprehensive integration and unit tests for settings, capture, and editor
- Split history and settings logic into focused modules
- Remove obsolete native UI and daemon handlers
- Type daemon methods and expand parity and migration tests
@SDSLeon
SDSLeon merged commit 7581fe2 into main Aug 21, 2026
6 checks passed
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.

3 participants