feat(record): capture interactions in embedded frames

Track recording per document so injectable child frames are captured while partial frame failures remain visible in exported traces.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
“haonan”
2026-08-17 14:41:02 +08:00
co-authored by Cursor
parent 61a0e0d218
commit f7e08f461b
28 changed files with 1374 additions and 144 deletions
+1
View File
@@ -285,6 +285,7 @@ bsk record stop [--output trace] # terminal fallback if the browser panel is u
- `target.ref` values like `@e12` exist **only inside** the bundle for disambiguation; do **not** copy `@eN` refs into SKILL.md or agent runbooks — use visible names from the observation text instead.
- `--purpose` is optional context metadata; it does **not** change what gets captured.
- `--redact-values` masks all form values in page files as `[filled]` / `[empty]`.
- Recording captures interactions in the **top frame and injectable child frames** (same-origin and cross-origin where the extension can attach). Embedded frames that cannot be injected are omitted; the trace may include `frame_capture.status: "partial"` with failure details.
- Do **not** record on banking/SSO/password-manager pages; passwords are redacted but traces may still contain sensitive text.
## Error handling
+10 -2
View File
@@ -8,8 +8,8 @@ use std::time::Duration;
use anyhow::Context;
use bsk_protocol::tools::{
RecordAwaitParams, RecordAwaitResult, RecordStartParams, RecordStartResult, RecordStopParams,
RecordStopResult, TRACE_VERSION, Trace, TraceState,
FrameCaptureStatus, RecordAwaitParams, RecordAwaitResult, RecordStartParams, RecordStartResult,
RecordStopParams, RecordStopResult, TRACE_VERSION, Trace, TraceState,
};
use bsk_protocol::{ErrorCode, Method};
use clap::{Args, Subcommand};
@@ -550,6 +550,13 @@ fn render_finish(
trace_path.display(),
pages_dir.display()
);
if let Some(frame_capture) = &trace.frame_capture {
if matches!(frame_capture.status, FrameCaptureStatus::Partial) {
eprintln!(
"warning: trace is partial — some embedded frames were not recorded (see frame_capture.failures in trace.json)"
);
}
}
}
}
Ok(())
@@ -584,6 +591,7 @@ mod tests {
bsk: "0.1.10".into(),
vom: VOM_FORMAT_VERSION,
},
frame_capture: None,
states: vec![TraceState {
id: state_id.into(),
url: "https://example.com/".into(),
@@ -96,6 +96,7 @@ fn sample_trace() -> Trace {
bsk: "0.1.10".into(),
vom: VOM_FORMAT_VERSION,
},
frame_capture: None,
states: vec![TraceState {
id: "s1".into(),
url: "https://example.com/".into(),