- Add --tab option to all extract commands and page info - Thread tab_id through the SDK extract and page namespaces - Route page.info with a tab_id to tabs.status for cross-tab metadata - Accept tab_id in the MCP page_info, extract_text, extract_markdown tools - Forward tabId in the extension page.info and extract.html handlers - Keep the active tab as default when no tab is given - Cover tab-scoped reads in API, CLI, and MCP tests - Bump package and extension version to 0.16.7 - Refresh uv.lock with current dependency versions
77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
import json
|
|
|
|
import click
|
|
from browser_cli.commands import client_from_ctx, handle_errors, tab_option
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
|
|
console = Console()
|
|
|
|
@click.group("extract")
|
|
def extract_group():
|
|
"""Extract content from the active tab."""
|
|
|
|
@extract_group.command("links")
|
|
@tab_option
|
|
@handle_errors
|
|
def extract_links(tab_id):
|
|
"""Extract all links from the active tab or --tab."""
|
|
links = client_from_ctx().extract.links(tab_id)
|
|
if not links:
|
|
console.print("[yellow]No links found[/yellow]")
|
|
return
|
|
table = Table(show_header=True, header_style="bold cyan")
|
|
table.add_column("Text", width=40)
|
|
table.add_column("URL")
|
|
for lnk in links:
|
|
table.add_row((lnk.get("text") or "")[:60], lnk.get("href") or "")
|
|
console.print(table)
|
|
|
|
@extract_group.command("images")
|
|
@tab_option
|
|
@handle_errors
|
|
def extract_images(tab_id):
|
|
"""Extract all images from the active tab or --tab."""
|
|
images = client_from_ctx().extract.images(tab_id)
|
|
if not images:
|
|
console.print("[yellow]No images found[/yellow]")
|
|
return
|
|
table = Table(show_header=True, header_style="bold cyan")
|
|
table.add_column("Alt", width=30)
|
|
table.add_column("Src")
|
|
for img in images:
|
|
table.add_row((img.get("alt") or "")[:40], img.get("src") or "")
|
|
console.print(table)
|
|
|
|
@extract_group.command("text")
|
|
@tab_option
|
|
@handle_errors
|
|
def extract_text(tab_id):
|
|
"""Extract all visible text from the active tab or --tab."""
|
|
console.print(client_from_ctx().extract.text(tab_id))
|
|
|
|
@extract_group.command("json")
|
|
@click.argument("selector")
|
|
@tab_option
|
|
@handle_errors
|
|
def extract_json(selector, tab_id):
|
|
"""Parse and pretty-print JSON content inside SELECTOR in the active tab or --tab."""
|
|
data = client_from_ctx().extract.json(selector, tab_id)
|
|
console.print_json(json.dumps(data))
|
|
|
|
@extract_group.command("html")
|
|
@tab_option
|
|
@handle_errors
|
|
def extract_html(tab_id):
|
|
"""Print the full HTML of the active tab or --tab to stdout."""
|
|
click.echo(client_from_ctx().extract.html(tab_id))
|
|
|
|
@extract_group.command("markdown")
|
|
@click.option("--selector", help="Extract only the DOM subtree matching this CSS selector.")
|
|
@tab_option
|
|
@handle_errors
|
|
def extract_markdown(selector, tab_id):
|
|
"""Extract the page's main content as Markdown from the active tab or --tab."""
|
|
markdown = client_from_ctx().extract.markdown(selector, tab_id)
|
|
click.echo(markdown or "", nl=not (markdown or "").endswith("\n"))
|