{"id":50677089,"url":"https://github.com/deeeed/capture-helper","last_synced_at":"2026-06-08T16:05:15.328Z","repository":{"id":361164221,"uuid":"1253343329","full_name":"deeeed/capture-helper","owner":"deeeed","description":"Generic macOS ScreenCaptureKit CLI for window discovery, capture, snapshots, recording, and agent evidence streams","archived":false,"fork":false,"pushed_at":"2026-06-06T07:51:46.000Z","size":139,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-06T09:21:41.425Z","etag":null,"topics":["agent","evidence","macos","screen-capture","screencapturekit","window-capture"],"latest_commit_sha":null,"homepage":"https://github.com/deeeed/capture-helper#readme","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deeeed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-29T11:16:42.000Z","updated_at":"2026-06-06T07:48:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/deeeed/capture-helper","commit_stats":null,"previous_names":["deeeed/capture-helper"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/deeeed/capture-helper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fcapture-helper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fcapture-helper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fcapture-helper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fcapture-helper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deeeed","download_url":"https://codeload.github.com/deeeed/capture-helper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fcapture-helper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34069511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","evidence","macos","screen-capture","screencapturekit","window-capture"],"created_at":"2026-06-08T16:05:13.932Z","updated_at":"2026-06-08T16:05:15.313Z","avatar_url":"https://github.com/deeeed.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @siteed/capture-helper\n\nGeneric window capture helper for agents, automation tools, and evidence pipelines — macOS (ScreenCaptureKit) and Linux/X11 (XComposite + ffmpeg).\n\nOn macOS, `capture-helper` is a small Swift CLI built on ScreenCaptureKit: it discovers windows, captures exact window targets, streams H.264 Annex B bytes, and records MP4 evidence with a native AVFoundation writer (no ffmpeg). On Linux it reproduces the same CLI/protocol over X11 using an XComposite grabber plus ffmpeg — see [Linux support](#linux-support).\n\n## Status\n\nEarly standalone extraction from Farmslot's internal `tools/capture-helper`.\n\nThe CLI is intentionally generic. Product-specific concepts such as Farmslot slots, iOS simulator aliases, MetaMask runners, or recipe semantics belong in the caller.\n\n## Requirements\n\n- macOS 13.0+\n- Xcode command-line tools / Swift toolchain\n- Screen Recording permission for the terminal or parent app\n- Optional: `ffmpeg` for external workflows that still want it; built-in `record` mode is native.\n\n## Linux support\n\nOn Linux the same CLI/protocol is implemented by a Node backend that drives a small\nC grabber (XComposite per-window capture) and `ffmpeg` for H.264 encoding. The\n`capture-helper` command auto-dispatches to it on Linux; commands, flags, the framed\nstream protocol, and JSON events are identical to macOS (see [docs/protocol.md](docs/protocol.md)).\n\nRequirements:\n\n- **X11 (Xorg) session.** GNOME-on-Wayland per-window capture is portal-gated and\n  not automatable — log into an Xorg session (e.g. \"Ubuntu on Xorg\", or set\n  `WaylandEnable=false` in `/etc/gdm3/custom.conf`). A graphical desktop must be\n  logged in (the GDM greeter has no app windows; use autologin for headless nodes).\n- **Captured apps must be X11 clients** (Wayland-native surfaces are invisible to the\n  X path). Force X11 where needed: `GDK_BACKEND=x11`, `QT_QPA_PLATFORM=xcb`,\n  Electron `--ozone-platform=x11`.\n- **Build/runtime deps** (`ffmpeg` is required on Linux):\n\n  ```bash\n  sudo apt install -y gcc ffmpeg libx11-dev libxcomposite-dev libxdamage-dev libxfixes-dev libxext-dev\n  # or run the helper:\n  bash scripts/setup-linux-node.sh\n  ```\n\nHardware H.264 encoding is opt-in via `--encoder h264_nvenc` (or\n`CAPTURE_HELPER_ENCODER=h264_nvenc`); the default `libx264` works everywhere.\nVerify readiness with `capture-helper doctor --json`. On Linux, `id` values are X11\nwindow ids (XIDs).\n\n## Install\n\nUse with `npx` without installing globally:\n\n```bash\nnpx -y @siteed/capture-helper@latest doctor --json\nnpx -y @siteed/capture-helper@latest list --json\n```\n\nInstall globally with npm:\n\n```bash\nnpm install -g @siteed/capture-helper\ncapture-helper doctor --json\n```\n\nDownload the native release binary directly:\n\n```bash\ncurl -L https://github.com/deeeed/capture-helper/releases/latest/download/capture-helper-darwin-arm64 \\\n  -o /usr/local/bin/capture-helper\nchmod +x /usr/local/bin/capture-helper\n```\n\n## Build from source\n\n```bash\nswift build -c release\n# or\nnpm run build:native\n```\n\nThe npm build script copies the release binary to:\n\n```text\nnative/capture-helper\n```\n\nWhen installed as an npm package, `postinstall` builds the native backend for the current platform if it's missing: on macOS it builds the Swift binary (`native/capture-helper`); on Linux it compiles the X11 grabber (`native/x11-grabber`) via `gcc`. If the toolchain or dev headers are absent it prints the install command and skips (the install never hard-fails). Set `SITEED_CAPTURE_HELPER_SKIP_POSTINSTALL=1` to skip that step.\n\n## Commands\n\n```bash\n# Human default: list likely capturable windows\ncapture-helper\ncapture-helper -l\n\n# Version / provenance\ncapture-helper version\ncapture-helper --version\n\n# Environment readiness and permissions diagnostics\ncapture-helper doctor --json\n# includes stable codes like screen_recording_denied, window_server_unavailable, ffmpeg_missing\n\n# Request/open macOS Screen Recording permissions where possible\ncapture-helper permissions\ncapture-helper doctor --open-permissions --json\n\n# List windows as a machine-readable JSON object\ncapture-helper list --json\n\n# Human-readable table\ncapture-helper list --human\ncapture-helper -l\ncapture-helper list -h\ncapture-helper list --on-screen --capturable --human\ncapture-helper list --all --human\n\n# Legacy JSON-lines listing\ncapture-helper --list-windows\ncapture-helper list --json-lines\n\n# Capture a specific target as raw H.264 Annex B\ncapture-helper capture --window-id 12345 \u003e /tmp/capture.h264\ncapture-helper capture --pid 12345 \u003e /tmp/capture.h264\ncapture-helper capture --app-name Simulator --window-name \"mm-1\" \u003e /tmp/capture.h264\n\n# Legacy capture syntax remains supported\ncapture-helper --window-name \"Simulator\" \u003e /tmp/capture.h264\n\n# Framed multi-window stream with stdin control\ncapture-helper stream --framed --window-id 12345 \u003e /tmp/windows.h264\n\n# Record MP4 evidence (macOS: native AVFoundation, no ffmpeg; Linux: ffmpeg)\ncapture-helper record --window-id 12345 --duration 5 --output evidence.mp4 --open\n```\n\n## Resolve and snapshot\n\n`resolve` lets agents debug target selection before starting video capture:\n\n```bash\ncapture-helper resolve --app-name \"Google Chrome\" --window-name \"MetaMask\"\n```\n\nIt returns the selected window, selector type, and all candidates considered for that selector.\n\n`snapshot` captures a one-frame PNG using the same target selectors:\n\n```bash\ncapture-helper snapshot --window-id 12345 --output screenshot.png\n```\n\n## Target selectors\n\nPrefer selectors in this order:\n\n1. `--window-id` from `capture-helper list --json` for exact capture.\n2. `--pid` when the caller owns the process tree and wants the largest suitable window.\n3. `--app-name` + `--window-name` for human-friendly fallback matching.\n4. `--window-name` alone only for ad hoc use.\n\n## npm wrapper\n\nThis package exposes a Node wrapper so JavaScript-based agents can call the native binary through a normal `bin` entry:\n\n```bash\nnode bin/capture-helper.js doctor --json\n```\n\nThe wrapper resolves the binary in this order:\n\n1. `SITEED_CAPTURE_HELPER_BIN`\n2. `native/capture-helper`\n3. `.build/release/capture-helper`\n4. `/opt/homebrew/bin/capture-helper`\n5. `/usr/local/bin/capture-helper`\n\n## Output contract\n\n- raw capture stdout: H.264 Annex B byte stream\n  - 4-byte start codes: `00 00 00 01`\n  - SPS/PPS emitted before keyframes\n  - baseline profile, no B-frames\n- `list` / `doctor` / `version`: JSON on stdout by default\n- streaming/capture diagnostics: JSON lines on stderr\n- command failures: JSON error lines on stderr with stable `code` values such as `target_required` and `window_not_found`\n- signal handling: `SIGINT`/`SIGTERM` perform cleanup for direct capture; `record --duration` stops automatically\n\nSee [docs/protocol.md](docs/protocol.md) for the framed stream and event contract.\n\n## Permissions\n\nGrant Screen Recording permission to the terminal app, IDE, or agent host that launches the helper:\n\n**System Settings → Privacy \u0026 Security → Screen \u0026 System Audio Recording**\n\nAfter granting permission, restart the launching app. Use this to check readiness:\n\n```bash\ncapture-helper doctor --json\n```\n\nIf you see `Code=-3801` / `screen_recording_denied`, especially over SSH, see [docs/troubleshooting.md](docs/troubleshooting.md).\n\n## Integration principle\n\nKeep this tool generic:\n\n- good: window IDs, PIDs, app names, window titles, capture formats, diagnostics\n- bad: Farmslot slots, project resources, simulator naming conventions, MetaMask-specific selectors\n\nHigher-level tools should resolve their domain objects to a concrete macOS window target, then call `capture-helper`.\n\n## Development\n\n```bash\nswift build -c release\nswift test # includes subprocess CLI/error-shape tests\nnpm run build:native\nnpm run doctor\nnpm pack --dry-run\n```\n\n## Release\n\nSee [docs/release.md](docs/release.md).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeeeed%2Fcapture-helper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeeeed%2Fcapture-helper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeeeed%2Fcapture-helper/lists"}