Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/all-commands-qa.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ Create `UPLOAD_FILE` with any small text payload. Capture IDs from JSON output w
- [ ] Run `$CLI connect`; expect an already-approved rejection that identifies the extension instance.
- [ ] Run `$CLI window new "$BASE" --json`; save `WINDOW` and `TAB`.
- [ ] Run `$CLI window --json`; expect `WINDOW` in the window list.
- [ ] Run `$CLI window select "id:$WINDOW" --json`; expect `WINDOW` to be selected.
- [ ] Run `$CLI window select "id:$WINDOW" --json`; expect `WINDOW` to be brought forward without establishing a durable target.
- [ ] Run `$CLI tab --window "id:$WINDOW" --json`; expect `TAB` in the tab list.
- [ ] Run `$CLI tab new "${BASE}?tab2" --window "id:$WINDOW" --json`; save `TAB2`.
- [ ] Run `$CLI tab select "id:$TAB2" --json`; expect `TAB2` to be active.
- [ ] Run `$CLI tab select "id:$TAB2" --json`; expect `TAB2` to be brought forward without establishing a durable target.
- [ ] Run `$CLI open "${BASE}?open" --tab "id:$TAB2" --json`; expect `TAB2` to navigate.
- [ ] Run `$CLI open --new-tab "${BASE}?tab3" --window "id:$WINDOW" --json`; save `TAB3`.
- [ ] Run `$CLI back --tab "id:$TAB2" --json`; expect navigation success.
Expand Down Expand Up @@ -132,12 +132,12 @@ Create `UPLOAD_FILE` with any small text payload. Capture IDs from JSON output w
- [ ] Run `$CLI errors clear --tab "id:$TAB2" --json`; expect success.
- [ ] Run `$CLI errors list --tab "id:$TAB2" --json`; expect an error-list result.
- [ ] Run `$CLI highlight "#highlight-target" --tab "id:$TAB2" --json`; expect success.
- [ ] Run `$CLI set viewport 1000 700 --tab "id:$TAB2" --json`; expect window dimensions in the response.
- [ ] Run `$CLI set viewport 1000 700 --window "id:$WINDOW" --json`; expect window dimensions in the response.
- [ ] Run `$CLI diff title "firefox-cli disposable E2E" --tab "id:$TAB2" --json`; expect `"matches": true`.
- [ ] Run `$CLI diff url "${BASE}?open" --tab "id:$TAB2" --json`; expect `"matches": true`.
- [ ] Run `$CLI batch '[["fill","#email","batch@example.test"],["click","#submit"],["wait","--text","Submitted batch@example.test","--timeout","5000"],["get","text","#status"]]' --tab "id:$TAB2" --json`; expect all batch steps to pass.
- [ ] Run `printf '[["get","title"]]' | $CLI batch --stdin --tab "id:$TAB2" --json`; expect the stdin batch step to pass.
- [ ] Run `$CLI pdf "$PDF" --tab "id:$TAB2" --json`; expect `UNSUPPORTED_CAPABILITY`.
- [ ] Run `$CLI pdf "$PDF" --json`; expect `UNSUPPORTED_CAPABILITY`.
- [ ] Run `$CLI close`; expect `UNSUPPORTED_CAPABILITY`.
- [ ] Run `$CLI quit`; expect `UNSUPPORTED_CAPABILITY`.
- [ ] Run `$CLI exit`; expect `UNSUPPORTED_CAPABILITY`.
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The first approval request creates a pair token. The extension stores the token

## Targeting

Commands resolve targets inside the extension. Default target selection uses the active tab/window. Explicit targets use the indexes printed by `tab`/`window` or Firefox IDs with `id:<number>`.
Commands resolve targets inside the extension. Omitted selectors are accepted only when the required window or tab is unique. Explicit selectors use `active`, the indexes printed by `tab`/`window`, or Firefox IDs with `id:<number>`; a tab ID also identifies its owning window.

Private windows are guarded at the extension command boundary. Read-only listings can report private tabs/windows; commands that would mutate private browsing state are rejected.

Expand Down
22 changes: 13 additions & 9 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ All commands use the paired Firefox session. Add `--json` for structured output

## Targets

Commands that operate on a page accept:
Commands advertise their supported selectors in `-h`. Selector values are:

```sh
--tab active
Expand All @@ -17,6 +17,10 @@ Commands that operate on a page accept:

Bare numeric targets are indexes printed by `firefox-cli tab` and `firefox-cli window`; `id:` targets use Firefox tab or window IDs.

Omitted selectors are accepted only when the required browser surface is unique. Multiple windows require `--window id:<id>` or explicit `--window active`; multiple tabs in a selected window require `--tab id:<id>` or explicit `--tab active`. A globally unique tab ID also identifies its owning window.

Page-targeted commands accept both selectors. `tab`, `tab new`, `window select`, `window close`, and `set viewport` accept `--window` only. `open --new-tab` resolves only a window. Targetless commands accept neither. Unsupported selector flags fail before a request is sent.

Private windows are listed and readable. Mutating commands against private windows return `UNSUPPORTED_CAPABILITY`.

## Setup And Diagnostics
Expand All @@ -34,14 +38,14 @@ Private windows are listed and readable. Mutating commands against private windo

| Command | Behavior |
| --- | --- |
| `firefox-cli tab [--json]` | List tabs. |
| `firefox-cli tab new [url] [--json]` | Open a new tab. |
| `firefox-cli tab select [target] [--json]` | Select a tab. |
| `firefox-cli tab [--window target] [--json]` | List tabs in the selected or only window. |
| `firefox-cli tab new [url] [--window target] [--json]` | Open a new tab in the selected window. |
| `firefox-cli tab select [target] [--json]` | Bring a tab forward to the user; later commands still require explicit selectors when ambiguous. |
| `firefox-cli tab close [target] [--json]` | Close a tab. |
| `firefox-cli window [--json]` | List windows. |
| `firefox-cli window new [url] [--json]` | Open a new window. |
| `firefox-cli window select [target] [--json]` | Select a window. |
| `firefox-cli window close [target] [--json]` | Close a window. |
| `firefox-cli window select [target] [--window target] [--json]` | Bring a window forward to the user; later commands still require explicit selectors when ambiguous. |
| `firefox-cli window close [target] [--window target] [--json]` | Close a selected window. |
| `firefox-cli open [--new-tab] <url> [--json]` | Navigate the target tab or open a URL in a new tab. |
| `firefox-cli back|forward|reload [--json]` | Run browser navigation in the target tab. |

Expand Down Expand Up @@ -131,9 +135,9 @@ firefox-cli screenshot [path] [--format png|jpeg] [--screenshot-quality 1-100] [
firefox-cli batch <json> | --stdin [--bail] [--timeout ms] [--max-output bytes] [--json]
```

`eval` runs in the page main world and returns JSON-serializable values or `undefined`. Screenshot output captures the visible tab as PNG or JPEG; `--full` returns `UNSUPPORTED_CAPABILITY`.
`eval` runs in the page main world and returns JSON-serializable values or `undefined`. Screenshot output captures the visible tab as PNG or JPEG and may activate the selected tab/window; `--full` returns `UNSUPPORTED_CAPABILITY`.

`batch` accepts an array of protocol command objects or CLI argv arrays. Steps run serially. With `--bail`, execution stops after the first failed step; without it, later steps continue and the batch result reports failures.
`batch` accepts an array of protocol command objects or CLI argv arrays. Steps run serially against a once-resolved default target; window-only batches do not require a tab. With `--bail`, execution stops after the first failed step; without it, later steps continue and the batch result reports failures.

Example:

Expand All @@ -160,7 +164,7 @@ Example:
| `firefox-cli console|errors list|clear [--json]` | List or clear page console/error capture buffers. |
| `firefox-cli highlight <selector\|@ref> [--json]` | Outline an element. |
| `firefox-cli notify [--id id] <title> [message...] [--json]` | Show a native Firefox notification. |
| `firefox-cli set viewport <width> <height> [--json]` | Request a target browser window resize and report Firefox's observed window dimensions. Tiling/window-manager rules can prevent the requested size from taking effect. |
| `firefox-cli set viewport <width> <height> [--window target] [--json]` | Request a target browser window resize and report Firefox's observed window dimensions. Tiling/window-manager rules can prevent the requested size from taking effect. |
| `firefox-cli diff url|title|snapshot <expected> [--json]` | Compare URL, title, or snapshot text with an expected value. |
| `firefox-cli pdf <path> [--json]` | Returns `UNSUPPORTED_CAPABILITY`; Firefox saves PDFs through a browser dialog rather than a requested CLI path. |

Expand Down
28 changes: 17 additions & 11 deletions docs/firefox-cli-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,20 @@ Startup handshake:

Target resolution is owned by the extension.

- `active` means Firefox's active tab in the active/focused normal window at command resolution time.
- `active` is an explicit selector. `--window active` chooses Firefox's focused normal window; `--tab active` chooses the active tab within the selected window.
- Window and tab IDs use Firefox IDs in JSON output.
- Human-facing indexes are derived from deterministic `browser.windows.getAll({ populate: true })` ordering: focused window first, then remaining windows by Firefox window ID; tabs by index within each window.
- Private windows are reported but commands return `UNSUPPORTED_CAPABILITY` unless the extension has private browsing permission and the command is explicitly allowed there.
- Container tab metadata should be included when Firefox exposes it, but no persistent container/session model is added.
- Each command snapshots its resolved target before execution to avoid active-tab races.
- Selector values are `active`, a non-negative listing index, or `id:<non-negative Firefox ID>`. A route supports neither selector, `--window` only, `--tab` only, or both as advertised by its CLI help; unsupported selector flags fail before dispatch.
- An omitted window selector is accepted only when exactly one normal window exists. A globally unique `--tab id:<id>` also identifies its owning window. Other tab selectors remain window-relative.
- A tab-dependent command accepts an omitted tab selector only when the selected window has exactly one tab. Pass `--tab active` explicitly to choose Firefox's active tab when several tabs exist.
- Ambiguous omission returns `INVALID_TARGET` with `Ambiguous window` or `Ambiguous tab` guidance before browser side effects.
- Page-targeted routes support both dimensions. `tab`, `tab new`, `window select`, `window close`, and `set viewport` are window-scoped. `open --new-tab` resolves only a window. Targetless routes support neither.
- `tab select` and `window select` bring a browser surface forward to the user. They do not establish durable CLI target state or remove the requirement to pass selectors explicitly to later target-dependent commands.

`open <url>` navigates the resolved active tab to match `agent-browser`. Use `tab new [url]` or `open --new-tab <url>` to create a new tab.
`open <url>` navigates the resolved target tab to match `agent-browser`. Use `tab new [url]` or `open --new-tab <url>` to create a new tab.

## Snapshot And Ref Model

Expand Down Expand Up @@ -278,7 +284,7 @@ Generated DOM events are not trusted user input. Sites that check `event.isTrust
Start with visible-tab screenshots.

- `screenshot [path]` captures the active visible tab of the target window.
- If a non-active target is requested, the command may activate the target tab/window before capture and must report that side effect in diagnostics.
- If the requested target is not active or focused, the command activates its tab and/or focuses its window before capture and reports those side effects in diagnostics. Invalid target resolution happens before activation.
- If activation is impossible or would require unsupported user activation, return `UNSUPPORTED_CAPABILITY`.
- Write image bytes through the native host to the requested path; JSON output should include path, format, dimensions when known, and diagnostics.
- Support visible-tab PNG and JPEG captures with JPEG quality.
Expand All @@ -289,7 +295,7 @@ Start with visible-tab screenshots.
`batch` executes a serialized command transaction.

- Input is a JSON array of argv arrays or command objects.
- Default target is resolved once at batch start unless a step overrides it.
- The required default window and/or tab is resolved once at batch start unless a step overrides it. Window-only batches do not require or inject a tab selector.
- Steps share ref registry entries created earlier in the batch.
- `--bail` stops at the first failed step.
- Output is an ordered result array with per-step success/error, diagnostics, and final exit status.
Expand Down Expand Up @@ -329,7 +335,7 @@ Global options:
- `--json`: emit machine-readable JSON.
- `--timeout <ms>`: override command timeout.
- `--max-output <chars>`: cap text output.
- `--window <id|index|active>` and `--tab <id|index|active>`: choose a target without hidden sessions.
- `--window <target>` and `--tab <target>`: route-specific target selectors; use only flags advertised by that route's help.
- `--debug`: include transport/protocol diagnostics.

Setup and diagnostics:
Expand Down Expand Up @@ -411,12 +417,12 @@ Unsupported unless Firefox provides an equivalent:

## MVP Command Contracts

Every MVP command returns `{ target, diagnostics }` in JSON output. `target` includes resolved window ID, tab ID, URL when available, and title when available. Text output may omit fields that are not useful for agents.
Target-dependent MVP command results include resolved window/tab metadata where their result schema exposes it. Text output may omit fields that are not useful for agents.

Navigation:

- `open <url> [--new-tab]`: params are normalized URL and new-tab flag. Result is final target, URL, navigation status, and load state when known. Errors include invalid URL, no active tab, permission denied, navigation timeout, and unsupported restricted page.
- `back`, `forward`, `reload`: params are empty except target and timeout. Result is final URL and load state when known. Errors include no history entry, no active tab, navigation timeout, and restricted page.
- `open <url> [--new-tab]`: params are normalized URL and new-tab flag. Result is final target, URL, navigation status, and load state when known. Errors include invalid URL, ambiguous or missing target, permission denied, navigation timeout, and unsupported restricted page.
- `back`, `forward`, `reload`: params are empty except target and timeout. Result is final URL and load state when known. Errors include no history entry, ambiguous or missing target, navigation timeout, and restricted page.

Snapshot:

Expand Down Expand Up @@ -453,14 +459,14 @@ Waits:

Tabs and windows:

- `tab`: lists tabs for the resolved or active window. Result includes ID, index, active flag, title, URL when permitted, window ID, private flag, and container metadata when available.
- `tab`: lists tabs for the selected or only window. Result includes ID, index, active flag, title, URL when permitted, window ID, private flag, and container metadata when available.
- `tab new [url]`: creates a new tab. Result is created tab target and URL when provided.
- `tab close [id|index|active]`: closes a tab. Result is closed tab ID and next active tab when known.
- `tab select <id|index>`: activates a tab. Result is selected target.
- `tab select [id|index|active]`: brings a tab forward to the user. Result is the selected target; later target-dependent commands still require explicit selectors when their target is ambiguous.
- `window`: lists normal windows and their active tabs. Result includes Firefox window IDs, focus/active flags, bounds when available, and tab count.
- `window new [url]`: creates a new window. Result is created window ID and active tab ID.
- `window close <id|active>`: closes a window. Result is closed window ID.
- `window select <id|index>`: focuses a window. Result is selected window ID and active tab.
- `window select [id|index|active]`: brings a window forward to the user. Result includes refreshed focus metadata and its active tab; later target-dependent commands still require explicit selectors when their target is ambiguous.

Screenshots:

Expand Down
Loading