Skip to content

Iteration 39: LLM ergonomics — help text, hints & recipes#41

Merged
ractive merged 2 commits intomainfrom
iter-39/llm-ergonomics
Apr 9, 2026
Merged

Iteration 39: LLM ergonomics — help text, hints & recipes#41
ractive merged 2 commits intomainfrom
iter-39/llm-ergonomics

Conversation

@ractive
Copy link
Copy Markdown
Owner

@ractive ractive commented Apr 9, 2026

Summary

  • Help text improvements: Added output format examples to --help for 10 key commands, documented default limits/sort orders, expanded --wait-text/--wait-selector/--no-daemon descriptions
  • Actionable error hints: Element-not-found suggests dom --count, tab-not-found suggests ff-rdp tabs, URL rejection mentions --allow-unsafe-urls, timeouts suggest --wait-timeout
  • Zero-result hints: JSON "hint" field added when cookies, console, or network return empty results
  • Fallback indicators: a11y and sources now add "fallback": true, "fallback_method": "js-eval" to output metadata when falling back to JS eval
  • Recipes: Added interaction workflows (form fill, dynamic content), error handling (check before click, retry), and cross-command workflows (full audit, console monitoring)
  • LLM help: Added output examples, troubleshooting section, and workflow patterns to llm-help command

Test plan

  • cargo fmt — clean
  • cargo clippy --workspace --all-targets -- -D warnings — clean
  • cargo test --workspace — all 249+ tests pass
  • Pre/post dogfooding sessions documented (sessions 34 & 35)
  • Manual: verify ff-rdp tabs --help shows output format
  • Manual: verify ff-rdp click "nonexistent" shows hint in error
  • Manual: verify ff-rdp cookies with 0 results shows hint in JSON

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • JSON outputs now include top-level "hint" when results are empty.
    • Outputs include fallback metadata when JS-eval fallback is used.
  • Improvements

    • Help text expanded with JSON output examples, default counts/sorting, and clearer flag descriptions (--no-daemon, --wait-timeout, --allow-unsafe-urls).
    • Error messages provide actionable remediation (e.g., selector checks, tab listing, timeout guidance).
    • Recipes and troubleshooting guidance added to built-in help.
  • Documentation

    • New dogfooding and iteration notes documenting changes and verification.

- Add output format examples to --help for 10 key commands (tabs, navigate,
  eval, dom, console, network, perf, screenshot, cookies, snapshot)
- Document default limits/sort in network (20, duration desc), console (50,
  timestamp desc), perf (20, duration desc)
- Expand --wait-text/--wait-selector/--no-daemon help descriptions
- Add output examples, troubleshooting, and workflow patterns to llm-help
- Add actionable hints to error messages: element-not-found suggests dom
  --count, tab-not-found suggests ff-rdp tabs, URL rejection mentions
  --allow-unsafe-urls, timeouts suggest --wait-timeout
- Add "hint" JSON field on zero-result output for cookies, console, network
- Add fallback/fallback_method to meta when a11y/sources fall back to JS eval
- Add interaction, error handling, and cross-command workflow recipes
- Pre/post dogfooding sessions documented (sessions 34 & 35)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d68e0ce0-e4bb-47b3-812c-7579f9fe68ae

📥 Commits

Reviewing files that changed from the base of the PR and between ba9583a and d98c332.

📒 Files selected for processing (9)
  • crates/ff-rdp-cli/src/cli/args.rs
  • crates/ff-rdp-cli/src/commands/a11y.rs
  • crates/ff-rdp-cli/src/commands/cookies.rs
  • crates/ff-rdp-cli/src/commands/llm_help.rs
  • crates/ff-rdp-cli/src/commands/network.rs
  • crates/ff-rdp-cli/src/commands/recipes.rs
  • crates/ff-rdp-cli/src/commands/sources.rs
  • crates/ff-rdp-cli/src/tab_target.rs
  • kb/iterations/iteration-39-llm-ergonomics.md

📝 Walkthrough

Walkthrough

Adds richer CLI help text and recipes, inserts actionable hints into error messages and empty-result JSON envelopes, records JS-eval fallback usage in output metadata, and adds dogfooding/iteration docs. No public API signatures or runtime control flow semantics were changed.

Changes

Cohort / File(s) Summary
CLI help & examples
crates/ff-rdp-cli/src/cli/args.rs, crates/ff-rdp-cli/src/commands/llm_help.rs, crates/ff-rdp-cli/src/commands/recipes.rs
Added long_about help text with JSON output examples, default counts/sorting notes, troubleshooting and workflow patterns; expanded recipes and fixed example formatting.
Empty-result hints (JSON envelope)
crates/ff-rdp-cli/src/commands/console.rs, crates/ff-rdp-cli/src/commands/cookies.rs, crates/ff-rdp-cli/src/commands/network.rs
Inject top-level "hint" into output when results are empty; network now differentiates daemon vs non-daemon messaging and uses actual shown-count in summaries.
Fallback tracking & metadata
crates/ff-rdp-cli/src/commands/a11y.rs, crates/ff-rdp-cli/src/commands/sources.rs
Introduce used_js_fallback boolean and add meta.fallback: true / meta.fallback_method: "js-eval" when JS-eval fallback is used.
Error / user guidance text
crates/ff-rdp-cli/src/commands/click.rs, crates/ff-rdp-cli/src/commands/type_text.rs, crates/ff-rdp-cli/src/commands/navigate.rs, crates/ff-rdp-cli/src/commands/wait.rs, crates/ff-rdp-cli/src/commands/url_validation.rs, crates/ff-rdp-cli/src/tab_target.rs
Enhanced error messages with actionable follow-ups (e.g., ff-rdp dom ... --count, --wait-timeout, --allow-unsafe-urls, ff-rdp tabs, ff-rdp launch).
Minor help/test adjustments
crates/ff-rdp-cli/src/commands/llm_help.rs (tests)
Expanded llm_help content and updated unit test subcommands list to include additional subcommand coverage.
Documentation / dogfooding records
kb/dogfooding/dogfooding-session-34.md, kb/dogfooding/dogfooding-session-35.md, kb/iterations/iteration-39-llm-ergonomics.md
Added pre- and post-implementation dogfooding notes and an iteration plan summarizing help, hint, and recipe changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰
I hopped through help and hints with care,
Left breadcrumbs in outputs for those who stare,
A fallback whisper, a guide when results are nil,
Recipes stitched for a smoother thrill,
Carrots, code, and clearer paths — hop on, we fixed the drill! 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: help text improvements, hints in error messages and zero-result outputs, and recipe/workflow additions across the codebase.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch iter-39/llm-ergonomics

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
crates/ff-rdp-cli/src/commands/network.rs (1)

126-175: Add focused tests for empty-hint decision paths.

Please add tests for: (1) truly empty capture, and (2) filtered-empty with captured events, so hint text stays accurate over time.

As per coding guidelines "**/*.rs: Make Rust code unit testable and add tests when feasible; add e2e tests for all commands/subcommands."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/ff-rdp-cli/src/commands/network.rs` around lines 126 - 175, Write unit
tests in crates/ff-rdp-cli/src/commands/network.rs to cover the two empty-hint
decision paths: (1) truly empty capture (results == vec![]) and (2)
filtered-empty where results contains events but the applied OutputControls
filtering/sorting/fields results in no shown items. In each test, construct a
CLI-like context and meta, call the same code paths that compute empty_hint and
produce the final envelope (exercise the use_detail branch via
OutputPipeline::from_cli + envelope_with_truncation and the summary branch via
build_network_summary + output::envelope), then assert the produced JSON
envelope contains a "hint" field with the expected message for the truly empty
case and that the filtered-empty case either preserves or omits the hint as
intended (use the same logic around empty_hint, envelope.as_object_mut, and
insertion). Name tests e.g. test_empty_capture_shows_hint and
test_filtered_empty_keeps_accurate_hint and keep them deterministic by
controlling InputControls/cli so apply_limit/apply_fields produce the desired
empty vs non-empty outcomes.
crates/ff-rdp-cli/src/commands/sources.rs (1)

115-121: Add a unit-test seam for fallback metadata emission.

This introduces a user-visible output branch (meta.fallback, meta.fallback_method) but it isn’t directly asserted in tests. Consider extracting meta construction into a small pure helper and adding tests for both used_js_fallback = true/false.

As per coding guidelines: "Make Rust code unit testable and add tests when feasible; add e2e tests for all commands/subcommands".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/ff-rdp-cli/src/commands/sources.rs` around lines 115 - 121, Extract
the inline meta construction into a small pure helper (e.g., fn
construct_meta(host: &str, port: u16, used_js_fallback: bool) ->
serde_json::Value) and replace the current block that builds `meta` with a call
to that helper; the helper should produce {"host", "port"} and conditionally
insert "fallback" and "fallback_method" when `used_js_fallback` is true
(matching the current keys "fallback" and "fallback_method" / value "js-eval").
Add unit tests for the helper that assert the JSON contains the fallback fields
when `used_js_fallback = true` and does not contain them when false, and use the
helper from the command implementation so behavior is covered by unit tests.
crates/ff-rdp-cli/src/commands/a11y.rs (1)

62-73: Consider adding direct tests for fallback metadata.

This adds user-visible metadata fields in one branch; extracting meta assembly into a helper would make fallback/fallback_method easy to unit test.

As per coding guidelines: "Make Rust code unit testable and add tests when feasible; add e2e tests for all commands/subcommands".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/ff-rdp-cli/src/commands/a11y.rs` around lines 62 - 73, Extract the
JSON metadata assembly into a small helper function (e.g., build_meta or
assemble_meta) that accepts the base fields (host, port, depth, max_chars) and a
used_js_fallback flag and returns a serde_json::Value (or serde_json::Map) with
the "fallback" and "fallback_method" keys added when used_js_fallback is true;
update the current code to call that helper. Add unit tests that call the helper
directly to assert that when used_js_fallback is true the returned meta contains
"fallback": true and "fallback_method": "js-eval", and when false those keys are
absent. Ensure tests reference the helper (assemble_meta/build_meta) so they
don’t depend on CLI plumbing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/ff-rdp-cli/src/commands/network.rs`:
- Around line 126-132: The empty_hint currently uses results.is_empty() which
triggers when filters remove all items, producing a misleading "No network
events captured" message; change the condition to check the pre-filtered
collection (the original captured events variable used before applying
--filter/--method) instead of results so the hint only appears when there truly
were no captured events, and apply the same change at the other two occurrences
referenced (the blocks around lines 155-161 and 170-175).

In `@crates/ff-rdp-cli/src/commands/recipes.rs`:
- Around line 155-156: The recipe title currently promises "check status" but
the shown command only extracts links (ff-rdp dom "a[href]" --attrs --jq
'[.results[].href]'); either update the recipe title/text to only say "Extract
all links" or add an additional command step that takes the extracted URLs and
performs an HTTP status check (for example, iterate the jq output and run a
status probe with curl or an HTTP client) so the docs match the behaviour;
update the recipe description and any example command string near ff-rdp dom
"a[href]" --attrs --jq '[.results[].href]' to reflect the chosen fix.

In `@crates/ff-rdp-cli/src/tab_target.rs`:
- Around line 29-33: The current numeric tab-selection branch constructs a range
"1–{count}" even when count == 0, producing confusing messages like "1–0 tabs
available"; before using n and count in the existing conditional (the branch
returning Err(AppError::User(...)) that references n and count), add a guard for
count == 0 and return a clear error such as "no tabs available; use `ff-rdp
tabs` to list available tabs" (or similar) so numeric --tab values are handled
separately when the tabs list is empty; update the code in tab_target.rs around
the existing n/count check to perform this special-case early return.

In `@kb/iterations/iteration-39-llm-ergonomics.md`:
- Around line 35-37: The fenced code block that contains the example response
(the block starting with "Output: {\"results\": ...}") is missing a language
tag; update that fenced block in kb/iterations/iteration-39-llm-ergonomics.md by
adding a language specifier (preferably json) after the opening backticks so the
block becomes ```json to satisfy MD040 and improve readability.
- Line 29: Replace inline code-style paths with Obsidian wikilinks: find
occurrences of the filename string dogfooding-session-34.md (and the other
inline path referenced near line 88) and change them to Obsidian-style
[[dogfooding-session-34]] links; ensure the file retains YAML frontmatter and
that all cross-references in the markdown use [[wikilinks]] instead of inline
code paths for Obsidian compatibility.

---

Nitpick comments:
In `@crates/ff-rdp-cli/src/commands/a11y.rs`:
- Around line 62-73: Extract the JSON metadata assembly into a small helper
function (e.g., build_meta or assemble_meta) that accepts the base fields (host,
port, depth, max_chars) and a used_js_fallback flag and returns a
serde_json::Value (or serde_json::Map) with the "fallback" and "fallback_method"
keys added when used_js_fallback is true; update the current code to call that
helper. Add unit tests that call the helper directly to assert that when
used_js_fallback is true the returned meta contains "fallback": true and
"fallback_method": "js-eval", and when false those keys are absent. Ensure tests
reference the helper (assemble_meta/build_meta) so they don’t depend on CLI
plumbing.

In `@crates/ff-rdp-cli/src/commands/network.rs`:
- Around line 126-175: Write unit tests in
crates/ff-rdp-cli/src/commands/network.rs to cover the two empty-hint decision
paths: (1) truly empty capture (results == vec![]) and (2) filtered-empty where
results contains events but the applied OutputControls filtering/sorting/fields
results in no shown items. In each test, construct a CLI-like context and meta,
call the same code paths that compute empty_hint and produce the final envelope
(exercise the use_detail branch via OutputPipeline::from_cli +
envelope_with_truncation and the summary branch via build_network_summary +
output::envelope), then assert the produced JSON envelope contains a "hint"
field with the expected message for the truly empty case and that the
filtered-empty case either preserves or omits the hint as intended (use the same
logic around empty_hint, envelope.as_object_mut, and insertion). Name tests e.g.
test_empty_capture_shows_hint and test_filtered_empty_keeps_accurate_hint and
keep them deterministic by controlling InputControls/cli so
apply_limit/apply_fields produce the desired empty vs non-empty outcomes.

In `@crates/ff-rdp-cli/src/commands/sources.rs`:
- Around line 115-121: Extract the inline meta construction into a small pure
helper (e.g., fn construct_meta(host: &str, port: u16, used_js_fallback: bool)
-> serde_json::Value) and replace the current block that builds `meta` with a
call to that helper; the helper should produce {"host", "port"} and
conditionally insert "fallback" and "fallback_method" when `used_js_fallback` is
true (matching the current keys "fallback" and "fallback_method" / value
"js-eval"). Add unit tests for the helper that assert the JSON contains the
fallback fields when `used_js_fallback = true` and does not contain them when
false, and use the helper from the command implementation so behavior is covered
by unit tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f341d5c-52ba-42aa-b8d0-7a152bac93f6

📥 Commits

Reviewing files that changed from the base of the PR and between 518166b and ba9583a.

📒 Files selected for processing (17)
  • crates/ff-rdp-cli/src/cli/args.rs
  • crates/ff-rdp-cli/src/commands/a11y.rs
  • crates/ff-rdp-cli/src/commands/click.rs
  • crates/ff-rdp-cli/src/commands/console.rs
  • crates/ff-rdp-cli/src/commands/cookies.rs
  • crates/ff-rdp-cli/src/commands/llm_help.rs
  • crates/ff-rdp-cli/src/commands/navigate.rs
  • crates/ff-rdp-cli/src/commands/network.rs
  • crates/ff-rdp-cli/src/commands/recipes.rs
  • crates/ff-rdp-cli/src/commands/sources.rs
  • crates/ff-rdp-cli/src/commands/type_text.rs
  • crates/ff-rdp-cli/src/commands/url_validation.rs
  • crates/ff-rdp-cli/src/commands/wait.rs
  • crates/ff-rdp-cli/src/tab_target.rs
  • kb/dogfooding/dogfooding-session-34.md
  • kb/dogfooding/dogfooding-session-35.md
  • kb/iterations/iteration-39-llm-ergonomics.md

Comment thread crates/ff-rdp-cli/src/commands/network.rs Outdated
Comment thread crates/ff-rdp-cli/src/commands/recipes.rs Outdated
Comment thread crates/ff-rdp-cli/src/tab_target.rs Outdated
Comment thread kb/iterations/iteration-39-llm-ergonomics.md Outdated
Comment thread kb/iterations/iteration-39-llm-ergonomics.md Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves ff-rdp’s “LLM ergonomics” by expanding CLI help text with output examples and defaults, adding actionable hints to errors/empty outputs, surfacing fallback metadata, and documenting common multi-command workflows (“recipes”) plus updated LLM reference help.

Changes:

  • Expanded --help output for key commands (output schema examples, defaults, clarified wait flags / --no-daemon).
  • Added actionable hints to common errors/timeouts and added "hint" fields for zero-result outputs (cookies/console/network), plus standardized fallback metadata for a11y/sources.
  • Added/updated “recipes” and llm-help documentation with troubleshooting and workflow patterns; added iteration + dogfooding KB entries.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
kb/iterations/iteration-39-llm-ergonomics.md Iteration 39 plan/writeup (help text, hints, recipes, acceptance criteria).
kb/dogfooding/dogfooding-session-34.md Pre-implementation dogfooding findings for LLM ergonomics.
kb/dogfooding/dogfooding-session-35.md Post-implementation verification notes for the ergonomics changes.
crates/ff-rdp-cli/src/cli/args.rs Adds/expands clap long_about help including output examples/defaults.
crates/ff-rdp-cli/src/tab_target.rs Improves “tab not found” errors with actionable ff-rdp tabs/launch hints.
crates/ff-rdp-cli/src/commands/url_validation.rs Mentions --allow-unsafe-urls in scheme rejection errors.
crates/ff-rdp-cli/src/commands/wait.rs Adds --wait-timeout suggestion to wait timeout error message.
crates/ff-rdp-cli/src/commands/navigate.rs Adds --wait-timeout suggestion to navigate wait timeout error message.
crates/ff-rdp-cli/src/commands/click.rs Adds selector-debugging hint to “Element not found” JS exception.
crates/ff-rdp-cli/src/commands/type_text.rs Adds selector-debugging hint to “Element not found” JS exception.
crates/ff-rdp-cli/src/commands/cookies.rs Adds zero-result "hint" field (and consent banner note) when no cookies found.
crates/ff-rdp-cli/src/commands/console.rs Adds zero-result "hint" field when no console messages captured.
crates/ff-rdp-cli/src/commands/network.rs Adds zero-result "hint" field; refactors envelope creation to allow hint insertion.
crates/ff-rdp-cli/src/commands/a11y.rs Adds structured fallback metadata when JS eval fallback is used.
crates/ff-rdp-cli/src/commands/sources.rs Adds structured fallback metadata when JS eval fallback is used.
crates/ff-rdp-cli/src/commands/recipes.rs Adds workflow “recipes” sections (interaction, error handling, cross-command).
crates/ff-rdp-cli/src/commands/llm_help.rs Expands LLM reference with output examples, troubleshooting, workflows + test coverage update.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


let empty_hint = if results.is_empty() {
Some(json!(
"No network events captured. Events are buffered by the daemon; navigate first with: ff-rdp navigate <url> --with-network, or use --follow to stream events in real time."
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSON hint text here always says events are buffered by the daemon, but results.is_empty() can happen in direct mode (--no-daemon) too. This can mislead users who are connected directly.

Consider making the hint conditional on ctx.via_daemon (daemon-buffer wording vs. “page may have loaded before subscribing”) or rephrasing it to be accurate in both modes.

Suggested change
"No network events captured. Events are buffered by the daemon; navigate first with: ff-rdp navigate <url> --with-network, or use --follow to stream events in real time."
"No network events captured. The page may have loaded before subscribing; navigate first with: ff-rdp navigate <url> --with-network, or use --follow to stream events in real time."

Copilot uses AI. Check for mistakes.
// The non-timed drain_network_events() stops on idle, so timeout is never reached.
let summary = build_network_summary(&results, false);
let envelope = output::envelope(&summary, 1, &meta);
let mut envelope = output::envelope(&summary, 1, &meta);
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In summary mode, the envelope is built with total set to 1, which makes .total meaningless for network (it should represent the number of captured requests). It also prevents the “total==0” convention from working consistently for zero-result hints.

Consider setting total to results.len() (or the pre-filter count, if that’s the intended semantic) so summary/detail modes report consistent totals.

Suggested change
let mut envelope = output::envelope(&summary, 1, &meta);
let mut envelope = output::envelope(&summary, results.len(), &meta);

Copilot uses AI. Check for mistakes.
"hint".to_string(),
json!(
"No cookies found. The page may not set cookies, or try navigating first. \
If a consent banner is present, accept it or use `ff-rdp launch --auto-consent`."
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hint suggests ff-rdp launch --auto-consent, but --auto-consent requires either --profile or --temp-profile (see launch validation). As written, following the hint will error.

Adjust the suggested command to include --temp-profile (and optionally --headless) or mention the requirement explicitly.

Suggested change
If a consent banner is present, accept it or use `ff-rdp launch --auto-consent`."
If a consent banner is present, accept it or use `ff-rdp launch --temp-profile --auto-consent`."

Copilot uses AI. Check for mistakes.
Comment thread crates/ff-rdp-cli/src/cli/args.rs Outdated
affect which requests Firefox records.

Default: 20 results, sorted by duration (slowest first).
Output (summary mode): {\"results\": {\"summary\": {...}, \"top_slowest\": [...]}, \"total\": N, \"meta\": {...}}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The network command’s documented summary output shape here (results.summary / top_slowest) doesn’t match what build_network_summary() actually returns (total_requests, total_transfer_bytes, slowest, etc.).

Please update the example JSON in long_about to reflect the real summary keys so --help output stays accurate.

Suggested change
Output (summary mode): {\"results\": {\"summary\": {...}, \"top_slowest\": [...]}, \"total\": N, \"meta\": {...}}
Output (summary mode): {\"results\": {\"total_requests\": N, \"total_transfer_bytes\": N, \"slowest\": [...]}, \"total\": N, \"meta\": {...}}

Copilot uses AI. Check for mistakes.
ff-rdp perf compare https://old.example.com https://new.example.com --label "Before,After"

Extract all links and check status:
ff-rdp dom "a[href]" --attrs --jq '[.results[].href]'"#
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The recipes output ends with an extra " before the raw-string terminator ("#). This will print a stray quote at the end of the last command line, making the recipe easy to copy/paste incorrectly.

Remove the extra quote so the final recipe line ends cleanly and the raw string terminator is not part of the displayed text.

Suggested change
ff-rdp dom "a[href]" --attrs --jq '[.results[].href]'"#
ff-rdp dom "a[href]" --attrs --jq '[.results[].href]'#

Copilot uses AI. Check for mistakes.
@@ -317,6 +317,68 @@ All commands return JSON by default with envelope: `{"results": ..., "total": N,
When results are truncated: `{"results": ..., "total": N, "truncated": true, "hint": "showing 20 of 84, use --all for complete list", "meta": {...}}`
Use `--jq` to filter: operates on `.results` automatically (implies --detail mode).
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --jq behavior is described as “operates on .results automatically”, but OutputPipeline::finalize() applies the jq filter to the full {results,total,meta,...} envelope. This mismatch will cause users/LLMs to write incorrect filters.

Update this line (or the pipeline behavior) so the documentation matches reality; currently filters need to reference .results explicitly.

Suggested change
Use `--jq` to filter: operates on `.results` automatically (implies --detail mode).
Use `--jq` to filter the full JSON envelope; reference `.results` explicitly when filtering results (implies --detail mode).

Copilot uses AI. Check for mistakes.
{"results": [{"url": "https://...", "title": "Page Title", "actor": "server1.conn0.tab1", "selected": true}], "total": 1, "meta": {"host": "localhost", "port": 6000}}

### network output (summary mode, default)
{"results": {"summary": {"total_requests": 42, "total_duration_ms": 3200}, "top_slowest": [...]}, "total": 42, "meta": {...}}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The network “summary mode” example here doesn’t match the actual network command output:

  • build_network_summary() returns keys like total_requests and slowest, not a nested {summary: ..., top_slowest: ...} structure.
  • The example also shows "total": 42, but the current summary-mode implementation builds the envelope with total = 1.

Please update the example JSON to match the real schema (or adjust the command to make total consistent with request count).

Suggested change
{"results": {"summary": {"total_requests": 42, "total_duration_ms": 3200}, "top_slowest": [...]}, "total": 42, "meta": {...}}
{"results": {"total_requests": 42, "total_duration_ms": 3200, "slowest": [...]}, "total": 1, "meta": {...}}

Copilot uses AI. Check for mistakes.
- network: condition empty_hint on watcher_was_empty, add filter-specific hint,
  use via_daemon for context-aware message, fix summary total to results.len()
- cookies: include --temp-profile in --auto-consent hint
- args/llm_help: fix network summary output example keys, clarify --jq docs
- recipes: fix "Extract all links" title (no status check)
- tab_target: handle count==0 edge case for numeric tab selector
- KB: use wikilinks, add json language tag to fenced code block
- fmt: fix let-chain formatting in a11y.rs and sources.rs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ractive ractive merged commit a5f971f into main Apr 9, 2026
4 of 6 checks passed
@ractive ractive deleted the iter-39/llm-ergonomics branch April 9, 2026 06:12
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.

2 participants