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
10 changes: 7 additions & 3 deletions crates/ff-rdp-cli/src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ COOKBOOK:
OUTPUT FORMAT (iter-60 compact defaults):
Default JSON: {\"results\": ..., \"total\": N} (meta omitted when empty)
--verbose restores meta.connection (host, port, pid, uptime) to the envelope
meta.route (iter-128, all commands since iter-134) is always present on
every browser-touching command's envelope — \"daemon\" or \"direct\" —
regardless of --verbose, so you can tell how a command executed without a
separate `daemon status` call
Truncated output adds: {\"truncated\": true, \"hint\": \"showing 20 of 84, use --all\"}
--format json (default) machine-readable JSON — the stable API contract
--format text human-readable tables and trees
Expand Down Expand Up @@ -630,9 +634,9 @@ Field fidelity by source:
`hint` is always present (iter-128) — null when there's nothing to report, a
string when results are truncated, a timeout fired, or the capture was empty.

`meta.route` (iter-128) is always present — \"daemon\" or \"direct\" — regardless
of --verbose, so you can tell how this command executed without a separate
`daemon status` call.
`meta.route` (iter-128; all browser-touching commands since iter-134) is
always present — \"daemon\" or \"direct\" — regardless of --verbose, so you
can tell how this command executed without a separate `daemon status` call.

Default: 20 results, sorted by duration (slowest first).
Output (summary mode): {\"results\": {\"total_requests\": N, \"total_transfer_bytes\": N, \"by_cause_type\": {...}, \"slowest\": [...], \"timeout_reached\": false, \"hint\": null}, \"total\": N, \"meta\": {\"route\": \"daemon\", ...}}
Expand Down
8 changes: 8 additions & 0 deletions crates/ff-rdp-cli/src/commands/a11y.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ pub fn run(
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
if used_js_fallback && let Some(m) = meta.as_object_mut() {
m.insert("fallback".to_string(), json!(true));
m.insert("fallback_method".to_string(), json!("js-eval"));
Expand Down Expand Up @@ -426,6 +430,10 @@ pub fn run_critical(cli: &Cli, root_selector: Option<&str>) -> Result<(), AppErr
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);

let controls = OutputControls::from_cli(cli, SortDir::Asc);
let mut items = violations;
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/a11y_contrast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ pub fn run(cli: &Cli, selector: Option<&str>, fail_only: bool) -> Result<(), App
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);

// Apply output controls (sort, limit, fields).
let controls = OutputControls::from_cli(cli, SortDir::Desc);
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/a11y_summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ pub fn run(cli: &Cli) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&output_results, 1, &meta);

// Custom text rendering for a11y summary.
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/cascade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,10 @@ pub fn run(
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);

let envelope = output::envelope(&Value::Array(results), total, &meta);
let hint_ctx = HintContext::new(HintSource::Styles).with_selector(selector);
Expand Down
9 changes: 6 additions & 3 deletions crates/ff-rdp-cli/src/commands/click.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn run_core(
wait_for_network: Option<&str>,
network_timeout: Option<u64>,
opts: &ClickOptions<'_>,
) -> Result<Value, AppError> {
) -> Result<(Value, bool), AppError> {
let mut ctx = connect_and_get_target(cli)?;

// When --wait-for-network is requested in direct mode, subscribe to the
Expand Down Expand Up @@ -232,7 +232,7 @@ pub fn run_core(
result["match_count"] = json!(match_count);
result["chosen_index"] = json!(chosen_index);
}
Ok(result)
Ok((result, ctx.via_daemon))
}

pub fn run(
Expand All @@ -242,7 +242,8 @@ pub fn run(
network_timeout: Option<u64>,
opts: &ClickOptions<'_>,
) -> Result<(), AppError> {
let mut result = run_core(cli, selector, wait_for_network, network_timeout, opts)?;
let (mut result, via_daemon) =
run_core(cli, selector, wait_for_network, network_timeout, opts)?;

// Preserve the pre-iter-61c CLI output shape: `settle_method` belongs in
// `meta`, not in `results`. The script runner reads it from `results`
Expand All @@ -267,6 +268,8 @@ pub fn run(
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose.
crate::connection_meta::merge_route(&mut meta, via_daemon);
let envelope = output::envelope(&result, 1, &meta);

let hint_ctx = HintContext::new(HintSource::Click).with_selector(selector);
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/computed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ pub fn run(cli: &Cli, selector: &str, props: &[String], include_all: bool) -> Re
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&results, total, &meta);

let hint_ctx = HintContext::new(HintSource::Computed).with_selector(selector);
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/consent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ pub fn run(cli: &Cli) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&result, 1, &meta);

OutputPipeline::from_cli(cli)?.finalize(&envelope)
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ pub fn run(cli: &Cli, level: Option<&str>, pattern: Option<&str>) -> Result<(),
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let mut envelope =
output::envelope_with_truncation(&json!(limited), shown, total, truncated, &meta);

Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/cookies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ pub fn run(cli: &Cli, name: Option<&str>, include_document_cookie: bool) -> Resu
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
if total == 0
&& let Some(note) = detect_consent_banner(&mut ctx)
&& let Some(m) = meta.as_object_mut()
Expand Down
12 changes: 12 additions & 0 deletions crates/ff-rdp-cli/src/commands/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ pub fn run(
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);

// Normalise to an array unconditionally (dogfood-49 #3): every `dom`
// call now returns `results` as an array regardless of match count so
Expand Down Expand Up @@ -422,6 +426,10 @@ pub fn run_count(cli: &Cli, selector: &str) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&results, usize::try_from(count).unwrap_or(0), &meta);

let hint_ctx = HintContext::new(HintSource::Dom).with_selector(selector);
Expand Down Expand Up @@ -589,6 +597,10 @@ pub fn run_stats(cli: &Cli) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&stats, 1, &meta);

let hint_ctx = HintContext::new(HintSource::DomStats);
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/dom_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ pub fn run(cli: &Cli, selector: Option<&str>, depth: u32, max_chars: u32) -> Res
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);

// Text short-circuit: render indented tree instead of JSON.
if cli.format == "text" && cli.jq.is_none() {
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/emulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ pub fn run(cli: &Cli, args: &EmulateArgs) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, via_daemon);

let envelope = output::envelope(&results, 1, &meta);
OutputPipeline::from_cli(cli)?.finalize(&envelope)
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,10 @@ pub fn run(
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&result_json, 1, &meta);

let hint_ctx = HintContext::new(HintSource::Eval);
Expand Down
8 changes: 8 additions & 0 deletions crates/ff-rdp-cli/src/commands/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ pub fn run(cli: &Cli, selectors: &[String], include_hidden: bool) -> Result<(),
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&empty, 0, &meta);
let first_sel = selectors.first().map_or("*", String::as_str);
let hint_ctx = HintContext::new(HintSource::Geometry).with_selector(first_sel);
Expand Down Expand Up @@ -173,6 +177,10 @@ pub fn run(cli: &Cli, selectors: &[String], include_hidden: bool) -> Result<(),
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);

// Text short-circuit: render a human-readable table instead of JSON.
if cli.format == "text" && cli.jq.is_none() {
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ pub fn run(cli: &Cli, actor_id: &str, depth: u32) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&result, 1, &meta);
let hint_ctx = HintContext::new(HintSource::Inspect);
OutputPipeline::from_cli(cli)?.finalize_with_hints(&envelope, Some(&hint_ctx))
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ pub fn run(cli: &Cli) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);

let envelope = output::envelope(&results, 1, &meta);
OutputPipeline::from_cli(cli)?.finalize(&envelope)
Expand Down
17 changes: 15 additions & 2 deletions crates/ff-rdp-cli/src/commands/nav_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ pub fn run(cli: &Cli, action: NavAction) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
let envelope = output::envelope(&result, 1, &meta);

let hint_source = match action {
Expand Down Expand Up @@ -213,7 +217,13 @@ fn run_reload_wait_idle_daemon(
}
};

emit_reload_result(cli, requests_observed + inflight_count, idle_at_ms, force)
emit_reload_result(
cli,
requests_observed + inflight_count,
idle_at_ms,
force,
true,
)
}

/// True when an I/O error kind signals the peer closed the connection
Expand Down Expand Up @@ -302,7 +312,7 @@ fn run_reload_wait_idle_direct(
let _ =
WatcherActor::unwatch_resources(ctx.transport_mut(), &watcher_actor, &["network-event"]);

emit_reload_result(cli, requests_observed, idle_at_ms, force)
emit_reload_result(cli, requests_observed, idle_at_ms, force, false)
}

/// Drain network events from `transport` until idle or timeout.
Expand Down Expand Up @@ -392,6 +402,7 @@ fn emit_reload_result(
requests_observed: u64,
idle_at_ms: u64,
force: bool,
via_daemon: bool,
) -> Result<(), AppError> {
let result = if force {
json!({
Expand All @@ -415,6 +426,8 @@ fn emit_reload_result(
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose.
crate::connection_meta::merge_route(&mut meta, via_daemon);
let envelope = output::envelope(&result, 1, &meta);

let hint_ctx = HintContext::new(HintSource::Reload);
Expand Down
9 changes: 6 additions & 3 deletions crates/ff-rdp-cli/src/commands/navigate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1480,7 +1480,7 @@ pub fn run_core(
cli: &Cli,
url: &str,
wait_opts: &WaitAfterNav<'_>,
) -> Result<serde_json::Value, AppError> {
) -> Result<(serde_json::Value, bool), AppError> {
validate_url_with_opts(url, cli.allow_file_urls, cli.allow_unsafe_urls)?;
let mut ctx = connect_and_get_target(cli)?;
let target_actor = ctx.target.actor.clone();
Expand Down Expand Up @@ -1795,7 +1795,7 @@ pub fn run_core(
{
obj.insert("wait_for".to_string(), wf);
}
Ok(result)
Ok((result, ctx.via_daemon))
}

/// Run the iter-129 CMP-detection-and-accept flow and merge its result into
Expand Down Expand Up @@ -1828,7 +1828,7 @@ pub fn run(
wait_opts: &WaitAfterNav<'_>,
auto_consent: bool,
) -> Result<(), AppError> {
let mut result = run_core(cli, url, wait_opts)?;
let (mut result, via_daemon) = run_core(cli, url, wait_opts)?;
if auto_consent {
merge_auto_consent(cli, &mut result);
}
Expand All @@ -1840,6 +1840,9 @@ pub fn run(
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — matches the
// `--with-network` variant below, which already got this in iter-128.
crate::connection_meta::merge_route(&mut meta, via_daemon);
let envelope = output::envelope(&result, 1, &meta);

let hint_ctx = HintContext::new(HintSource::Navigate);
Expand Down
4 changes: 4 additions & 0 deletions crates/ff-rdp-cli/src/commands/page_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ pub fn run(cli: &Cli) -> Result<(), AppError> {
None,
cli.is_verbose(),
);
// iter-134: always present, not gated by --verbose — an
// agent can tell how this command executed without a
// separate `daemon status` round-trip.
crate::connection_meta::merge_route(&mut meta, ctx.via_daemon);
// `results` holds the text string directly; the old `.text` alias has been
// removed (iter-61j A1). Use `--jq '.results'` to extract the text.
let envelope = output::envelope(&json!(text), 1, &meta);
Expand Down
Loading
Loading