Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
**openadapt-capture** is the data collection component of the OpenAdapt GUI automation ecosystem. It captures platform-agnostic GUI interaction streams (mouse, keyboard, screen) with time-aligned media for training ML models or replaying workflows.

Key responsibilities:
- Record human demonstrations with mouse, keyboard, and screen capture
- Record human demonstrations with native mouse, keyboard, and screen capture
- Time-align all events and media (video, audio)
- Process raw events into structured actions (clicks, drags, typing)
- Support privacy scrubbing of sensitive data
- Retain optional action-time structural evidence where a provider exists
- Keep raw captures local unless a caller invokes an explicit transfer path
- Expose an optional privacy integration without claiming automatic scrubbing

**Always use PRs, never push directly to main**

Expand All @@ -18,8 +20,8 @@ Key responsibilities:
# Install the package
uv add openadapt-capture

# Install with audio support (large download)
uv add "openadapt-capture[audio]"
# Install with on-device transcription support (large download)
uv add "openadapt-capture[transcribe-fast]"

# Run tests (exclude browser bridge tests which need websockets fixtures)
uv run pytest tests/ -v --ignore=tests/test_browser_bridge.py
Expand Down Expand Up @@ -60,7 +62,7 @@ openadapt_capture/
extensions/ # SynchronizedQueue (multiprocessing.Queue wrapper)
utils.py # Timestamps, screenshots, monitor dims
config.py # Recording config (RECORD_VIDEO, RECORD_AUDIO, etc.)
video.py # Video encoding (av/ffmpeg)
video.py # External FFmpeg process boundary and frame extraction
audio.py # Audio recording + transcription
visualize/ # Demo GIF and HTML viewer generation
share.py # Magic Wormhole sharing
Expand Down Expand Up @@ -101,7 +103,7 @@ SQLAlchemy-based per-capture databases:
# Fast tests (unit + integration, no recording)
uv run pytest tests/ -v --ignore=tests/test_browser_bridge.py -m "not slow"

# Slow tests (full recording pipeline with pynput synthetic input)
# Slow tests (full native recording pipeline with synthetic input)
uv run pytest tests/ -v -m slow

# All tests
Expand Down
37 changes: 26 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,17 @@ Documentation for the whole stack lives at

| Recording path | Current implementation |
| --- | --- |
| Windows and RDP demonstrations | `openadapt-capture` records native input and action-gated screen video; `openadapt-flow` converts the session into compiler input. |
| Browser demonstrations | `openadapt-flow` records its Playwright browser directly. It does not require this package. |
| Chrome extension in this repository | Experimental DOM-capture code for development; it is not the supported web recorder or governed replay path. |
| Windows, macOS, and Linux demonstrations | `openadapt-capture` records native input and action-gated screen video; Windows can also retain action-time UI Automation evidence. `openadapt-flow` converts the session into compiler input. |
| RDP and Citrix/VDI demonstrations | `openadapt-capture` records the selected client window in its own pixel space. The remote application remains externally black-box, and `openadapt-flow` converts the session into compiler input. |
| Browser demonstrations | `openadapt-flow` uses its Playwright recorder. It can launch Chromium or attach to one existing signed-in local Chromium tab. It does not require this package. |
| Chrome extension in this repository | Prototype alternate acquisition transport. It is not the supported recorder and must not perform direct replay. |

The browser path stays inside `openadapt-flow` because the compiler needs
ordered before/after frames, page state, secret-field redaction, and events in
its own recording format. The extension captures useful DOM context, but it
does not provide that end-to-end contract.
ordered before/after frames, page state, secret-field redaction, and one bound
event schema. Flow now supports an existing authenticated browser session
through its local-loopback CDP attach mode. The extension can become another
acquisition transport after it emits that same evidence contract. It must not
create a second compiler format or bypass governed replay.

## Use it with OpenAdapt

Expand Down Expand Up @@ -283,20 +286,32 @@ boundary. `openadapt-flow` still refuses desktop `--secret` authoring until its
source-time field-redaction contract can prove that sensitive values were not
retained. Review the desktop guide before recording sensitive workflows.

The experimental Chrome extension can observe pages across its configured host
The Chrome extension prototype can observe pages across its configured host
permissions and can emit DOM text and keyboard events to a local WebSocket.
Treat it as development code; do not deploy it in a sensitive browser profile.
It does not yet provide source-time secret exclusion, authenticated
profile/tab/document/session binding, acknowledged ordered delivery, or exact
frame-to-event evidence. Its direct DOM replay does not use Flow's identity,
policy, fresh-frame, and effect checks. Treat it as development code. Do not
deploy it in a sensitive browser profile.

Use Flow's supported attach recorder when an existing SSO or 2FA browser
session is required. See the
[`openadapt-flow` browser recording guide](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/BROWSER_RECORDING.md).

## Current limitations

- Native recording requires a visible user session plus the operating system's
screen-recording and input-monitoring permissions.
- Native Windows capture retains UIA evidence when the application exposes it;
opaque remote applications still require Flow's visual and OCR bindings.
- The Flow adapter rejects unsupported input such as drag, non-left-click, and
modifier-chord actions instead of silently compiling an incomplete workflow.
- The Flow adapter compiles left and right clicks, left-button drags, typed
text, named keys, modifier chords, and scrolling. It rejects unsupported
input such as middle clicks, non-left-button drags, malformed shortcuts, and
unmapped keys instead of silently compiling an incomplete workflow.
- Browser-extension installation, security hardening, and compiler integration
are not part of the current product path.
are not part of the current product path. Promotion requires the shared Flow
schema, source-time secret exclusion, authenticated and sequenced delivery,
exact frame binding, compiler integration, and removal of direct replay.

See the organization-wide
[repository lifecycle registry](https://github.com/OpenAdaptAI/.github/blob/main/REPOSITORY_LIFECYCLE.md)
Expand Down
47 changes: 47 additions & 0 deletions chrome_extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# OpenAdapt Capture Chrome extension prototype

This directory is a development prototype. It is not the supported OpenAdapt
browser recorder or a governed replay path.

Use the Playwright recorder in `openadapt-flow` for browser workflows. It can
launch a clean Chromium browser or attach to one existing signed-in local
Chromium tab. Both modes retain the compiler's event, DOM identity, exact
before/after frame, field geometry, and source-time secret-redaction contract.
See the
[`openadapt-flow` browser recording guide](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/BROWSER_RECORDING.md).

## Current prototype behavior

The extension can collect DOM events and visible HTML and send them to the
Capture WebSocket bridge on `localhost:8765`. It also contains legacy direct
DOM replay code.

Do not use it in a sensitive browser profile. The current implementation does
not provide these supported-path controls:

- source-time password and declared-secret exclusion;
- authenticated profile, tab, document, run, and recording-session binding;
- an acknowledged, ordered event sequence with reconnect recovery;
- exact retained frame-to-event binding in one coordinate system;
- compiler integration through the shared Flow recording schema; or
- governed replay with identity, policy, fresh-frame, and effect checks.

## Promotion contract

This extension can become a supported alternate acquisition transport. It
must first:

1. Emit the shared Flow event and evidence schema.
2. Remove direct replay. All execution must use the governed Flow runtime.
3. Exclude secrets before an event leaves the content script.
4. Authenticate and bind the browser profile, tab, document, run, session, and
monotonic event sequence.
5. Acknowledge or safely resume every event after a reconnect. It must not drop
an event and report success.
6. Bind each action to exact before/after frames and viewport metadata.
7. Pass at least three trials for record and compile, secret exclusion,
ambiguity refusal, reconnect behavior, and browser lifecycle preservation.

Until these items pass the same acceptance gate as the Playwright recorder,
this directory stays a prototype component. This status applies only to this
directory. It does not apply to the `openadapt-capture` package.
6 changes: 3 additions & 3 deletions chrome_extension/manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"manifest_version": 3,
"name": "OpenAdapt Capture",
"name": "OpenAdapt Capture (Prototype)",
"version": "1.0.0",
"description": "DOM-level event capture for browser interactions with coordinate tracking and semantic element references",
"description": "Development prototype for DOM event capture; use openadapt-flow for supported browser recording",
"permissions": [
"activeTab",
"tabs",
Expand Down Expand Up @@ -34,6 +34,6 @@
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"default_title": "OpenAdapt Capture"
"default_title": "OpenAdapt Capture prototype"
}
}
9 changes: 9 additions & 0 deletions docs/DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# openadapt-capture Design

> **Historical design record.** This file retains early goals and proposed
> formats. It is not the current package contract. The current recorder
> writes `recording.db` plus verified time-aligned MP4 media, uses native input
> observers on Windows, macOS, and Linux, retains action-time Windows UIA
> evidence, and supports window-scoped capture on Windows and macOS. See
> [`README.md`](../README.md) and the public API for the current behavior. Items
> such as `capture.db`, chunked continuous capture, and structural observers on
> every operating system remain historical proposals where the code differs.

## Problem Statement

We need a platform-agnostic representation of GUI interactions that:
Expand Down
5 changes: 5 additions & 0 deletions docs/VISUALIZATION_DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Visualization Design

> **Historical design record.** This file contains early visualization
> proposals. The current API and privacy rules are in [`README.md`](../README.md)
> and `openadapt_capture.visualize`. In particular, the current HTML viewer does
> not embed recorded audio by default.

## Goals

1. **README Demo**: Automated GIF/video generation showing a recording with visual event overlays
Expand Down
8 changes: 7 additions & 1 deletion openadapt_capture/browser_bridge.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
"""WebSocket server for Chrome extension communication.
"""Prototype WebSocket transport for Chrome extension development.

This module is not the supported OpenAdapt browser recorder or a governed
replay path. Use the Playwright launch or attach recorder in ``openadapt-flow``
for compile-ready browser demonstrations. The transport remains available for
development while it gains authenticated session binding, acknowledged
ordering, source-time secret exclusion, and exact event/frame evidence.

This module provides the BrowserBridge WebSocket server that connects to
the Chrome extension for capturing browser DOM events. It handles:
Expand Down
6 changes: 5 additions & 1 deletion openadapt_capture/browser_events.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
"""Browser event schemas for Chrome extension communication.
"""Event schemas for the Chrome extension development prototype.

These passive schemas do not make the extension a supported recorder or its
legacy direct DOM replay a governed execution path. The supported browser
recorder is the Playwright launch or attach path in ``openadapt-flow``.

This module defines Pydantic models for all browser event types captured by
the Chrome extension. These events include DOM-level interactions with rich
Expand Down
9 changes: 6 additions & 3 deletions openadapt_capture/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ def record(
unless RECORD_AUDIO_RETAIN_WAVEFORM is explicitly enabled.
Requires an on-device transcription backend to be installed.
images: Also save screenshots as PNGs (default: False).
browser_events: Capture browser DOM events via Chrome extension (default: False).
Requires the openadapt-capture Chrome extension to be installed and
connects via WebSocket on localhost:8765.
browser_events: Enable the development Chrome extension prototype
(default: False). It is not the supported browser recorder. Use
openadapt-flow browser launch or attach mode for a compile-ready
recording. The prototype connects to localhost:8765.
send_profile: Send profiling data via wormhole after recording (default: False).
window_owner: Owner-app substring for window-scoped recording — capture
ONE window in its own pixel space (e.g. --window-owner Parallels).
Expand Down Expand Up @@ -86,6 +87,8 @@ def record(
if window:
print(f"Window-scoped: owner={window_owner!r} title={window_title!r}")
if browser_events:
print("PROTOTYPE: Capture Chrome-extension events are not a supported path.")
print("Use openadapt-flow browser launch or attach mode for real workflows.")
print("Browser event capture enabled (WebSocket on localhost:8765)")
print("Make sure the openadapt-capture Chrome extension is installed.")
print("Press Ctrl+C or type stop sequence to stop recording...")
Expand Down