Commit Graph
20 Commits
Author SHA1 Message Date
daniel156161 914508e2db feat(read): target any tab for page info and extraction
Testing / test (push) Successful in 40s
Testing / remote-protocol-compat (0.16.0) (push) Successful in 31s
Testing / remote-protocol-compat (0.15.0) (push) Successful in 39s
- 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
2026-08-28 11:19:02 +02:00
daniel156161 6352d9994e Bound extension job and window-alias state
Testing / test (push) Successful in 48s
Testing / remote-protocol-compat (0.16.0) (push) Successful in 39s
Testing / remote-protocol-compat (0.15.0) (push) Successful in 41s
Two service-worker leaks. Running jobs were only bounded by their watchdog, so
a command flood could hold many timers and results for up to JOB_TIMEOUT_MS;
cap concurrent jobs at 32 and reject beyond that, since a clear error beats an
unresponsive worker. Window aliases were never removed, so storage kept an
entry for every window the user had ever renamed.

Prune aliases against the live window set on list, rename, and close rather
than only on close, because windows also disappear without going through
windows.close.

Also extract the repeated job summary in perf.status into a helper.
2026-08-09 20:49:37 +02:00
daniel156161 6270d8c956 feat: add remote trust and server identity pinning
Testing / remote-protocol-compat (0.16.0) (push) Successful in 1m1s
Testing / remote-protocol-compat (0.15.0) (push) Successful in 1m3s
Testing / test (push) Failing after 1m15s
Build & Publish Package / publish (push) Successful in 51s
Package Extension / package-extension (push) Successful in 1m6s
- Add SSH-style server identity keys and known-host verification for remote serve endpoints.
- Add remote add/list/remove commands for explicit endpoint persistence.
- Fix remote clients listing to fan out through target discovery instead of ambiguous auto-routing.
- Add URL glob matching for tabs filter and count with extension tests.
- Add n8n credential pinning for server public keys or SHA256 fingerprints.
- Remove obsolete compat shim behavior while keeping empty compat seams for future protocol changes.
- Bump browser-cli to 0.16.4 and n8n node to 0.3.1.
- Cover known-hosts, remote registry, compat seams, n8n protocol verification, and URL matching with tests.
2026-06-26 08:53:21 +02:00
daniel156161 6fa931aa36 feat: harden remote serve and reuse connections
Testing / remote-protocol-compat (0.9.5) (push) Successful in 56s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 59s
Testing / test (push) Successful in 1m1s
Build & Publish Package / publish (push) Successful in 33s
Package Extension / package-extension (push) Successful in 36s
- Gate TCP serve commands with safe-by-default policies, per-key allow tokens, per-key rate limiting, and audit labels.
- Reuse authenticated encrypted remote sessions and parallelize/caches multi-browser fanout to reduce repeated handshake roundtrips.
- Increase paged native-host batch size with extension-side byte budgeting to speed large tab listings safely.
- Point install output at public Chrome Web Store / Firefox AMO listings by default, with --dev preserving unpacked workflows.
- Share search-engine metadata between CLI and SDK and bump the package/extension version to 0.16.0.
- Cover the new security, pooling, paging, install, and fanout behavior with expanded Python and extension tests.
2026-06-18 14:24:15 +02:00
daniel156161 7cb2a8b618 refactor: modularize auth transport and markdown
Testing / remote-protocol-compat (0.9.5) (push) Successful in 1m4s
Testing / test (push) Successful in 1m22s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 1m7s
Package Extension / package-extension (push) Successful in 1m1s
Build & Publish Package / publish (push) Successful in 1m5s
- Split auth into focused package modules for agent keys, file keys,
  signing, and post-quantum transport helpers while keeping the public
  browser_cli.auth import surface intact.
- Move transport encoding internals into a package with separate codec and
  binary-hoisting helpers, preserving browser_cli.transport compatibility.
- Extract remote TCP auth/socket helpers and serve challenge setup out of the
  runtime paths to make connection handling easier to reason about.
- Move the extension markdown extractor into a dedicated content/markdown
  folder with separate root selection, code normalization, renderer, and utils.
- Centralize CLI Rich rendering helpers for tab/window tree and table output,
  and add rendering tests for the shared builders.
- Remove local typing ignores in SDK/decorator/script plumbing and bump the
  package and extension version to 0.15.3.
2026-06-15 01:23:57 +02:00
daniel156161 0b43408a8d feat(cli): improve tab and window tree rendering
- Add shared rendering helpers for width-aware tree labels, truncation, and no-wrap Rich text.
- Preserve tab index and group window metadata through the extension and SDK factories.
- Render tab trees in browser/window/index order with grouped tab details and optional shortened URLs.
- Reuse the tab tree labels in window trees to keep output compact and consistent.
- Cover legacy missing-index responses, grouped/collapsed tabs, URL display, and rendering helpers with tests.
2026-06-15 01:04:02 +02:00
daniel156161 477a00db1a feat(extension): add Firefox WebExtension support
Testing / remote-protocol-compat (0.9.5) (push) Successful in 48s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 47s
Build & Publish Package / publish (push) Successful in 46s
Package Extension / package-extension (push) Successful in 59s
Testing / test (push) Failing after 50s
- Add a neutral WebExtension API adapter that uses Firefox browser.* or Chromium chrome.* without mutating globals.
- Switch extension runtime code to the adapter and add Firefox-specific typings for tabs, windows, tab groups, storage, scripting, and native messaging ports.
- Fix Firefox temporary add-on instructions to load the packaged manifest with background.scripts instead of the Chromium service worker manifest.
- Detect Firefox in clients.list via runtime.getBrowserInfo and keep Chromium user-agent fallback support.
- Make navigate.open wait briefly for Firefox to replace initial about:blank with the requested URL.
- Add JS coverage for API selection, clients.list browser detection, and Firefox navigate.open URL polling.
- Bump package and extension version to 0.15.2.
2026-06-14 19:09:10 +02:00
daniel156161 9b8cefcd72 feat: add Firefox extension support
Testing / remote-protocol-compat (0.9.5) (push) Successful in 48s
Testing / test (push) Failing after 53s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 52s
- Add Firefox as an install target with native messaging manifest support.
- Generate Firefox-specific extension packages with Gecko metadata and AMO-compatible manifest transforms.
- Keep tab group commands available in Firefox through dynamic tab group API helpers.
- Avoid Firefox linter warnings for static tab group API references and direct eval tokens.
- Add Firefox packaging and installer regression coverage.
- Bump the package and extension version to 0.15.1.
2026-06-14 17:19:25 +02:00
daniel156161 5cec57e06d feat!: harden raw browser control and packaging
Testing / remote-protocol-compat (0.9.3) (push) Successful in 40s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 38s
Testing / test (push) Failing after 1m3s
Package Extension / package-extension (push) Successful in 29s
Build & Publish Package / publish (push) Successful in 33s
- Add safe-by-default policy gates for raw command surfaces: command, script, and serve-http /command.

- Require explicit opt-ins for page reads, browser control, and high-risk commands such as dom.eval, storage.*, and screenshots.

- Remove all cookies support from CLI, SDK, extension commands, permissions, constants, docs, and tests.

- Add diagnostic, events, watch, workspace, remote, raw command, script, HTTP gateway, tree-view, session import/export, and extension info/capability commands.

- Add Chrome Web Store packaging that strips manifest.key while keeping local packages with a stable native-messaging extension ID.

- Bump browser-cli and extension version to 0.14.1 and cover the new behavior with pytest and extension packaging tests.

BREAKING CHANGE: cookies commands and the b.cookies SDK namespace have been removed; generic raw command execution now blocks non-safe commands unless explicitly allowed.
2026-06-14 14:33:15 +02:00
daniel156161 3e3b8d529c fix: make navigation no-focus by default
Testing / test (push) Failing after 15s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 46s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 47s
- Change nav open and open-wait to avoid activating newly created tabs unless
  --focus is explicitly requested.
- Send background=true for default opens so older or remote extensions also
  avoid stealing focus even if they ignore the new focus flag.
- Remove the redundant --bg flag from navigation and search CLI commands now
  that no-focus/background behavior is the default.
- Thread focus support through the sync SDK, async SDK, tab helpers, and
  workflow decorators.
- Update README and demo usage to document the new default and --focus opt-in.
- Bump package and extension metadata to 0.12.3.
- Add regression coverage for CLI help, wire payloads, and extension behavior.
2026-06-14 13:59:15 +02:00
daniel156161 509f1387de fix: prevent browser target and focus surprises
Testing / remote-protocol-compat (0.9.5) (push) Successful in 57s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 1m1s
Testing / test (push) Successful in 1m7s
- Respect the globally selected browser when renaming client aliases.
- Pass the resolved local profile into sync and async local transports so
  BROWSER_CLI_PROFILE is honored consistently.
- Stop tabs.active from explicitly focusing the OS browser window, avoiding
  virtual-desktop jumps during tab activation.
- Make window merging skip audible, unmuted windows so video playback windows
  are not selected as merge targets.
- Bump the Python package and extension manifest versions to 0.12.2.
- Add regression coverage for browser selection and focus-stealing behavior.
2026-06-14 13:00:33 +02:00
daniel156161 076914e5b7 refactor: reorganize client transport and extension internals
- Split client, native, remote, serve, markdown, and SDK internals into focused packages with direct imports.
- Move local and remote transport framing/protocol helpers behind clearer module boundaries.
- Break up the extension injected DOM logic into a separate content dispatch bundle and dedicated content modules.
- Add explicit client handling for passive remote discovery without noisy PQ warnings.
- Keep behavior covered with updated unit, integration, and extension tests.
2026-06-13 23:31:24 +02:00
daniel156161 0813ae2de9 feat(tabs): batch-close tabs by id list
Testing / remote-protocol-compat (0.9.5) (push) Successful in 44s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 45s
Testing / test (push) Successful in 52s
Build & Publish Package / publish (push) Successful in 32s
Package Extension / package-extension (push) Successful in 35s
Closing many tabs previously meant one IPC round-trip per tab
(tab.close() in a loop). Add a single batched path so callers can
close N tabs in one command, reusing the existing large-operation
throttle so the browser UI stays responsive.

- extension: tabs.close accepts tabIds: number[]; new branch feeds
  the array through processInBatches/chrome.tabs.remove
- sdk: tabs_close(tab_ids=...) takes tab IDs or Tab objects; the
  payload always carries "tabIds" (null when unused)
- tests: cover id-list and Tab-object batch close in test_api.py
- bump 0.10.3 -> 0.10.4 (pyproject.toml, manifest.json)
2026-06-11 10:31:53 +02:00
daniel156161 ba01be1c5d refactor(extension): class-based command registry + modular src layout
Testing / remote-protocol-compat (0.9.5) (push) Successful in 45s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 47s
Testing / test (push) Successful in 52s
Restructure the MV3 background worker from a monolithic core.ts/index.ts
into a class-based command architecture. Behavior is identical — the 83
registered commands dispatch byte-for-byte the same as before.

Structure
- One class per command group, each extending CommandGroup and exporting a
  `commands` map keyed by the full command id ("tabs.close"). Groups:
  Navigation, TabsMutation, TabsQuery, Groups, Windows, Dom (dom/extract/
  page), BrowserData (storage/cookies), Session (session/clients + autosave
  + lazy-tab activation), Perf (perf + jobs.status/cancel), Extension.
- CommandRegistry merges the group maps (throws on duplicate ids), routes
  background specs to JobManager and paginates array results via
  makePagedData. JobManager owns the job map + lifecycle. NativeConnection
  owns the native-port lifecycle and the inbound message router.
- index.ts is now thin wiring: JobManager -> ctx -> assembleRegistry ->
  onActivated -> NativeConnection.start().
- Infra classes live in classes/ (PascalCase, file = class name); command
  groups in commands/; shared helpers split out of core.ts into core/
  (errors, throttle, scripting, tab-helpers, group-helpers, storage); all
  types moved into types/ (json, jobs, session, tabs, messages,
  command-args) behind a barrel.

DRY cleanup
- resolveTabUrl(tabId) and assertScriptableUrl(url, action) collapse the
  tab/URL-guard boilerplate duplicated across dom.ts and browser-data.ts.
- processInBatches() centralizes the throttled, cancellable batch loop
  shared by tabs.close, group.close and tabs.merge_windows.
- captureCurrentSession() dedups the snapshot-and-signature block shared by
  session.save and the autosave path.
- DomArgs type alias replaces 21 inline ContentArgs & { tabId? } copies.
- Drop fetchTabHtml's redundant retry loop (executeScript already retries
  transient frame/tab errors), a dead tabInfo import, and two stale
  comments referencing a removed asArgs helper.

Type safety & tests
- Full noImplicitAny; no `any`/`unknown` annotations remain in src.
- JS unit-test harness using node --test + node:assert (zero new deps),
  bundled via the existing esbuild. Covers JobManager retention/lifecycle
  and the autosave listener-wiring/debounce with an in-memory chrome mock.
- The structural pytest checks track the new file homes and the centralized
  processInBatches helper.

Verification: npm run check:extension green (tsc + esbuild 84.5kb +
node --check + 18 JS tests); uv run pytest -q -> 409 passed, 105 skipped.
No version bump.
2026-06-11 00:33:00 +02:00
daniel156161 545abeb515 feat: add performance controls for large browser ops
- Add throttled large-operation handling for tab, group, and session commands.
- Introduce performance profiles, audible-tab aware gentle mode, and job progress tracking.
- Support background session restores with status/cancel commands and lazy placeholders.
- Expose new perf and extension CLI groups plus matching Python SDK methods.
- Preserve pinned tabs during session snapshots and debounce auto-save updates.
- Bump browser-cli and extension versions to 0.10.0 and add pytest-cov to dev deps.
- Add coverage for performance controls, background jobs, lazy restores, and tab metadata.
2026-05-20 22:13:57 +02:00
daniel156161 eaa1469143 fix(extension): detect browser error pages earlier
Testing / test (push) Successful in 26s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 27s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 20s
Package Extension / package-extension (push) Successful in 28s
Build & Publish Package / publish (push) Successful in 31s
- Add shared browser error URL detection for Chrome, Edge, Brave, and Firefox-style about:error pages.
- Short-circuit read-only DOM and HTML commands with safe fallbacks when tabs are already on browser error pages.
- Fail navigation waits, DOM waits, polling, and URL watches with clearer error-page messages.
- Bump package and extension version to 0.9.8 and extend regression coverage for cross-browser error-page handling.
2026-05-14 13:54:21 +02:00
daniel156161 f79ff0e3c2 fix(extension): handle browser error pages gracefully
Testing / test (push) Successful in 37s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 39s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 24s
- Treat chrome error page script failures as transient during injection retries.
- Return safe fallback values for read-only DOM commands when tabs land on browser error pages.
- Improve URL watch handling by checking pending URLs and reporting last seen URL/status on timeout.
- Bump package and extension version to 0.9.6 and add regression coverage for error-page behavior.
2026-05-14 13:39:09 +02:00
daniel156161andClaude Sonnet 4.6 4b2abbbfc5 feat: Ed25519 challenge-response auth + YubiKey/SSH agent support (v0.9.0)
Testing / test (push) Successful in 26s
Package Extension / package-extension (push) Successful in 22s
Build & Publish Package / publish (push) Successful in 27s
Security:
- serve.py: server now sends nonce challenge before accepting any command;
  clients sign nonce + SHA256(canonical_payload) with Ed25519 key
- New --authorized-keys FILE option for serve; token auth still works as fallback
- Connection limit: BoundedSemaphore(64) in serve.py
- Secure file creation with os.open(..., 0o600) for token/key files
- New auth.py module: keygen, file key load/save, SSH agent protocol (pure Python),
  sign/verify helpers compatible with both file keys and agent-held keys (YubiKey,
  TPM, gpg-agent)

Features:
- YubiKey support via SSH agent protocol — no new runtime deps, just $SSH_AUTH_SOCK
- New `browser-cli auth` command group: keygen, trust, show, keys
- Global --key PATH flag (or BROWSER_CLI_KEY env) selects signing key;
  pass "agent" or "agent:<selector>" to use SSH agent key
- BrowserCLI Python API gains key= parameter

Bug fixes (11 issues across two review passes):
- client.py: check response is not None before json.loads
- native_host.py: _read_exact_stream loop handles EINTR short reads; fix Windows
  Listener leak on accept error
- __init__.py: open_wait / tabs_watch_url raise RuntimeError instead of silent None
- extension/tabs.ts: dedupe skips tabs without URL; tabsSort uses pendingUrl fallback
- extension/session.ts: removeListener before addListener prevents duplicate handlers

Breaking: TCP serve protocol now sends a challenge frame first (v0.9.0)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 16:20:39 +02:00
daniel156161 bd37c68e80 fix bug that getAliases got not found and update version to 0.8.3
Testing / test (push) Successful in 26s
2026-05-01 20:04:34 +02:00
daniel156161 7ee664153b change background.js into split typescript files for better managemand and build background.js from typescript 2026-05-01 19:28:36 +02:00