479a0f1964
Testing / remote-protocol-compat (0.9.3) (push) Successful in 43s
Testing / test (push) Successful in 1m1s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 39s
Build & Publish Package / publish (push) Successful in 58s
Package Extension / package-extension (push) Successful in 1m15s
- Allow remote host aliases passed via --browser to fan out for read-only multi-browser SDK paths while preserving strict routing for mutating commands. - Add remote host grouping and scoped profile labels to tabs tree output so global views avoid repeated host prefixes. - Carry browser family metadata through remote targets, tabs, and groups and style tree browser labels by family. - Split CLI rendering helpers into a typed rendering package with dedicated common, label, tabs-tree, and windows-tree modules. - Bump browser-cli and extension versions to 0.15.5. - Cover the new routing and rendering behavior with unit and CLI tests.
64 lines
2.5 KiB
Python
64 lines
2.5 KiB
Python
"""Rich label helpers for tab/window tree renderers."""
|
|
from __future__ import annotations
|
|
|
|
from rich.text import Text
|
|
|
|
from browser_cli.commands.rendering.common import Row, int_value, item_value, shorten, text_value
|
|
|
|
BROWSER_FAMILY_STYLES = {
|
|
"firefox": "orange1",
|
|
"chrome": "cyan",
|
|
"chromium": "cyan",
|
|
"brave": "cyan",
|
|
"edge": "cyan",
|
|
"vivaldi": "cyan",
|
|
}
|
|
DEFAULT_SCOPE = "local"
|
|
DEFAULT_BROWSER_STYLE = "bold cyan"
|
|
|
|
def no_wrap_text() -> Text:
|
|
"""Text configured for one-line tree labels with edge ellipsis."""
|
|
return Text(no_wrap=True, overflow="ellipsis")
|
|
|
|
def tab_tree_label(tab: Row, *, title_limit: int, show_urls: bool = False, url_limit: int = 55) -> Text:
|
|
"""Reusable one-line label for a browser tab in tree views."""
|
|
label = no_wrap_text()
|
|
label.append(f"[{text_value(item_value(tab, 'id'))}] ", style="dim")
|
|
label.append(shorten(text_value(item_value(tab, 'title'), "(untitled)") or "(untitled)", title_limit))
|
|
if bool(item_value(tab, "active", False)):
|
|
label.append(" *", style="green")
|
|
url = text_value(item_value(tab, "url"))
|
|
if show_urls and url:
|
|
label.append(" — ", style="dim")
|
|
label.append(shorten(url, url_limit), style="dim")
|
|
return label
|
|
|
|
def group_tree_label(group_id: object, group: Row | None, *, title_limit: int) -> Text:
|
|
"""Reusable one-line label for a browser tab group in tree views."""
|
|
title = text_value(item_value(group, "title", "") if group is not None else "") or f"Group {group_id}"
|
|
color = text_value(item_value(group, "color", "") if group is not None else "") or "group"
|
|
count = int_value(item_value(group, "tab_count", item_value(group, "tabCount", 0)) if group is not None else 0)
|
|
collapsed = bool(item_value(group, "collapsed", False)) if group is not None else False
|
|
label = no_wrap_text()
|
|
label.append(shorten(title, title_limit), style="bold")
|
|
meta = [color]
|
|
if count:
|
|
meta.append(f"{count} tab" + ("" if count == 1 else "s"))
|
|
if collapsed:
|
|
meta.append("collapsed")
|
|
label.append(" (" + ", ".join(meta) + ")", style="dim")
|
|
return label
|
|
|
|
def browser_label_style(browser_name: str | None) -> str:
|
|
"""Return a Rich style for a browser family label."""
|
|
name = (browser_name or "").lower()
|
|
for family, style in BROWSER_FAMILY_STYLES.items():
|
|
if family in name:
|
|
return style
|
|
return DEFAULT_BROWSER_STYLE
|
|
|
|
def scoped_browser_label(browser: str, scope: str, *, grouped: bool) -> str:
|
|
"""Shorten browser labels under a remote/local group node."""
|
|
prefix = f"{scope}:"
|
|
return browser[len(prefix):] if grouped and browser.startswith(prefix) else browser
|