Conversation
Add a `read-page` command that extracts the current page's main article as clean markdown using dom_smoothie (Readability port) and htmd (HTML-to-Markdown converter). Pipeline: single CDP call fetches HTML + URL simultaneously, runs Readability extraction with DomSmoothie candidate selection, unwraps iframe tags (innermost-first to handle arbitrary nesting), converts to markdown stripping only truly inert elements (scripts, styles, svg, canvas), and enriches output with title/byline/excerpt/site_name/url metadata. Non-article pages (SPAs, dashboards, search results) fall back to full-page conversion so content is never silently dropped. Structural containers (nav, footer, aside) are preserved for LLM navigation.
…tool commands Add dual-API detection to list-3p-tools and execute-3p-tool: prefer document.modelContext (WebMCP Origin Trial) when available, fall back to window.__dtmcp for older Chrome versions. - list-3p-tools: probe getTools() first, enrich output with origin and annotations (readOnlyHint, untrustedContentHint) - execute-3p-tool: find tool via getTools(), execute via executeTool(tool, paramsJson); track hasModelContext for accurate error messages when WebMCP is present but tool not found - Add awaitPromise:true to list-3p-tools (getTools() returns Promise) - Surface API source label (WebMCP / DTMCP legacy) in text output
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughTwo features are added: a new ChangesNew read-page Command
WebMCP Support in Third-Party Tools
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant CdpClient
participant Page
User->>CLI: read-page
CLI->>CdpClient: Runtime.evaluate(fetch HTML+URL)
CdpClient->>Page: Execute JS snippet
Page-->>CdpClient: {html, url}
CdpClient-->>CLI: Payload returned
CLI->>CLI: extract_content(html)
CLI->>CLI: unwrap_iframes()
CLI->>CLI: format_output(markdown/json)
CLI-->>User: Markdown or JSON output
sequenceDiagram
participant User
participant CLI
participant CdpClient
participant Page
User->>CLI: list-3p-tools
CLI->>CdpClient: Runtime.evaluate(detect & list tools)
CdpClient->>Page: Check modelContext / __dtmcp
Page-->>CdpClient: {api, groups, tools, metadata}
CdpClient-->>CLI: Payload with api discriminator
CLI->>CLI: Render API header + tool details
CLI-->>User: Formatted tool list with API label
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Code Review
This pull request adds a new read-page command to extract page content as clean markdown using dom_smoothie and htmd, and updates third-party tool integration to support WebMCP (document.modelContext) alongside the legacy __dtmcp API. Feedback highlights opportunities to optimize performance and safety in src/commands/read_page.rs. Specifically, it is recommended to replace full-string lowercasing with a zero-allocation case-insensitive search helper in extract_title_from_html and unwrap_iframes to avoid excessive memory allocations, and to use a Unicode Private Use Area character instead of a null byte placeholder in decode_html_entities to prevent issues with null-terminated strings.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/commands/third_party.rs (2)
177-185: 💤 Low valueInconsistent use of
paramsvariable in WebMCP path.Line 177 declares
const params = {safe_params_json};, but line 185 passes{safe_params_json}directly toexecuteToolinstead of using the localparamsvariable. While functionally equivalent, this inconsistency differs from the legacy paths (lines 201, 208) which correctly useparams.♻️ Suggested fix for consistency
- const result = await document.modelContext.executeTool(tool, {safe_params_json}); + const result = await document.modelContext.executeTool(tool, params);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/commands/third_party.rs` around lines 177 - 185, In the WebMCP path execution block, the code declares a params variable at the beginning but then passes the raw safe_params_json directly to the executeTool method call instead of using the declared params variable. Change the executeTool call to use the params variable that was already defined, making it consistent with how the legacy paths handle parameter passing in the same function.
131-140: 💤 Low valueSimplify
filter_maptomapsince the closure always returnsSome.The
filter_mapwith an unconditionalSome(...)is equivalent tomap. This is a minor readability improvement.♻️ Suggested simplification
let parts: Vec<String> = ann .as_object() .map(|obj| { obj.iter() - .filter_map(|(k, v)| { - Some(format!("{}={}", k, v)) - }) + .map(|(k, v)| format!("{}={}", k, v)) .collect() }) .unwrap_or_default();🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/commands/third_party.rs` around lines 131 - 140, The code uses filter_map with a closure that unconditionally returns Some, which is unnecessary since filter_map is only needed when you want to selectively filter out values. Replace the filter_map call on obj.iter() with a simple map call, and remove the Some(...) wrapper from the closure body so it directly returns the format string result instead of wrapping it in Some.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/commands/third_party.rs`:
- Around line 182-186: The executeTool method call is passing the entire tool
object as the first argument, but the WebMCP API signature requires a string
tool name. In the if statement where executeTool is called, change the first
parameter from tool to tool.name so that the method receives the tool name
string instead of the tool object.
---
Nitpick comments:
In `@src/commands/third_party.rs`:
- Around line 177-185: In the WebMCP path execution block, the code declares a
params variable at the beginning but then passes the raw safe_params_json
directly to the executeTool method call instead of using the declared params
variable. Change the executeTool call to use the params variable that was
already defined, making it consistent with how the legacy paths handle parameter
passing in the same function.
- Around line 131-140: The code uses filter_map with a closure that
unconditionally returns Some, which is unnecessary since filter_map is only
needed when you want to selectively filter out values. Replace the filter_map
call on obj.iter() with a simple map call, and remove the Some(...) wrapper from
the closure body so it directly returns the format string result instead of
wrapping it in Some.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ea6c1f59-b5f7-4c52-bc1b-6471efec0168
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (6)
Cargo.tomlsrc/commands/executor.rssrc/commands/mod.rssrc/commands/read_page.rssrc/commands/third_party.rssrc/lib.rs
|
/gemini review |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Code Review
This pull request introduces the read-page command to extract page content as clean markdown using dom_smoothie and htmd, along with updating third-party tool integration to support WebMCP. Feedback highlights a bug in the case-insensitive search function find_ci where the search needle is not lowercased, and notes that the manual HTML title extraction and entity decoding are fragile and incomplete, suggesting the use of the html-escape crate. Additionally, adding error handling for potential promise rejections in the WebMCP tool listing is recommended.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@AGENTS.md`:
- Around line 11-40: The markdown code fence in AGENTS.md that displays the
repository tree structure is missing a language tag, which causes markdownlint
to flag it. Find the opening fence marker (```) for the repository tree that
starts with "src/" and add the language tag "text" to it by changing ``` to
```text. This satisfies the markdownlint requirement for all code fences to have
a language identifier.
In `@src/commands/read_page.rs`:
- Around line 161-178: The issue is that when no closing tag is found in the
code block starting at line 161, the opening tag is stripped and the loop breaks
immediately, preventing the processing of any subsequent iframe tags in the
document. Replace the `break;` statement on line 165 (after stripping the
unclosed tag and resetting best_open and best_close to None) with `continue;` so
the loop continues to the next iteration and processes remaining tags instead of
exiting prematurely.
In `@src/commands/third_party.rs`:
- Around line 16-30: The promise chain returned by
document.modelContext.getTools() lacks error handling, which allows promise
rejections to propagate uncaught to Runtime.evaluate. Add a .catch() handler to
the getTools() promise chain to handle potential errors (permissions, internal
errors, etc.) and return an appropriate error response or default value, similar
to how the legacy path and execute_3p_tool operations wrap their logic in
try/catch blocks.
In `@wiki/read-page.md`:
- Around line 42-53: Remove the null-valued fields from the JSON response
example in the read-page documentation. Specifically, delete the lines
containing "byline": null and "site_name": null from the example JSON object,
since the formatter omits missing metadata keys entirely rather than including
them with null values. The resulting example should only show fields that have
actual values (markdown, title, excerpt, url).
- Around line 61-67: The code fence containing the pipeline diagram (starting
with "CDP Runtime.evaluate") is missing a language tag, which causes
markdownlint to flag it. Add the language tag `text` to the opening fence by
changing the opening ``` to ```text while keeping the closing ``` and all the
diagram content unchanged.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 74df3b87-d1b2-42d4-a836-514fd8f3335a
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
AGENTS.mdCargo.tomlREADME.mdskill/chrome-devtools/SKILL.mdsrc/commands/executor.rssrc/commands/mod.rssrc/commands/read_page.rssrc/commands/third_party.rssrc/lib.rswiki/read-page.md
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new read-page command to extract page content as clean, LLM-friendly markdown using dom_smoothie (a Rust port of Mozilla Readability) and htmd (HTML to Markdown). It also updates the third-party tools commands (list-3p-tools and execute-3p-tool) to support WebMCP (document.modelContext) alongside the legacy __dtmcp global. A review comment correctly points out a robustness issue in unwrap_iframes where a malformed or unclosed <iframe> tag (lacking a closing >) would cause the loop to break prematurely, preventing the processing of subsequent valid iframes. The reviewer's suggestion to advance search_from and continue instead of breaking is highly recommended.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
@coderabbitai full review |
✅ Action performedFull review finished. |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new read-page command to extract page content as clean markdown using dom_smoothie and htmd, and updates third-party tool commands to support WebMCP. The review feedback suggests optimizing the case-insensitive search helper, correcting a misleading doc comment regarding HTML entity decoding, and hardening the iframe unwrapping logic against malformed tags.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/commands/third_party.rs`:
- Around line 176-191: The `document.modelContext.executeTool()` method expects
parameters as a JSON string, but the current code in the `executeTool` call
within the async function is passing an object literal by interpolating
safe_params_json directly. Replace the second argument of the executeTool call
from the current object literal syntax to JSON.stringify(params), which will
properly serialize the already-defined params object into a JSON string as
required by the WebMCP specification.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d4417a20-63a6-4790-b83a-37c02afe378a
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
AGENTS.mdCargo.tomlREADME.mdskill/chrome-devtools/SKILL.mdsrc/commands/executor.rssrc/commands/mod.rssrc/commands/read_page.rssrc/commands/third_party.rssrc/lib.rswiki/read-page.md
- Reuse needle bytes during case-insensitive matching - Use html_escape entity decoding directly - Avoid crossing tag boundaries when locating iframe close tags
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new read-page command to extract page content as clean markdown using dom_smoothie and htmd, complete with documentation, tests, and a dedicated wiki page. It also updates third-party tool integration to support WebMCP (document.modelContext) alongside the legacy __dtmcp global. Feedback focuses on fixing a bug in unwrap_iframes where the nested tag check incorrectly matches the < of the closing tag itself, and a minor optimization to reuse the params variable in the WebMCP tool execution block.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- Exclude the current '<' when checking for nested tag boundaries in iframe unwrapping - Pass resolved `params` to `executeTool` instead of the original serialized param
|
@coderabbitai full review |
|
/gemini review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Code Review
This pull request introduces the read-page command, which extracts page content as clean markdown using dom_smoothie and htmd, complete with iframe unwrapping, fallback handling, and structured output formats. It also updates the third-party tools commands to support WebMCP (document.modelContext) alongside the legacy __dtmcp global. Feedback focuses on improving robustness: implementing a find_tag_end helper to correctly parse HTML tags with attributes containing > characters, adding a null check for document.documentElement to prevent TypeError on empty tabs, and explicitly mapping the "none" API type to "None" in the CLI output.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- Safely return empty HTML when document.documentElement is unavailable - Add quote-aware tag end detection to avoid parsing '>' inside attributes - Reuse tag parser for title extraction and iframe unwrapping - Display "None" for third-party tools without an API type
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new read-page command that extracts the main article content of a page as clean markdown using dom_smoothie and htmd. It also updates the third-party tools integration to support WebMCP (document.modelContext) alongside the legacy __dtmcp global. The review feedback suggests checking for exceptionDetails first when listing third-party tools to handle JS exceptions gracefully, and avoiding redundant JSON.stringify calls in the evaluated JavaScript for read-page to prevent double serialization and simplify the Rust deserialization logic.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new read-page command that extracts the main article content of a page as clean, LLM-friendly markdown using dom_smoothie and htmd. It also updates the third-party tools command to support WebMCP (document.modelContext) alongside the legacy __dtmcp global. The review feedback points out a compilation error in third_party.rs due to an un-prefixed bail! macro, and suggests an optimization in read_page.rs to avoid heap allocation by passing a static array instead of a Vec to skip_tags.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new read-page command to the Chrome DevTools CLI, which extracts the main article content of a page as clean, LLM-friendly markdown using dom_smoothie and htmd. It includes nested iframe unwrapping, fallback mechanisms for non-article pages, and comprehensive unit tests and documentation. Additionally, the third-party tool commands (list-3p-tools and execute-3p-tool) have been updated to support the WebMCP API (document.modelContext) alongside the legacy __dtmcp global. There are no review comments provided, so I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Summary by CodeRabbit
read-pagecommand to extract main page/article content, convert it to clean Markdown, and optionally write output to a file (including title/metadata with non-article fallback behavior).read-pagewiki page with usage and guidance.