Browser and terminal tabs
People switch between tabs, not windows. aos window sees one Chrome window; the thing you want is the pull request in its ninth tab, or the terminal tab sitting in ~/src/aos. aos tab reaches inside the window.
- A browser or a terminal is just a window kind:
aos window listnow printsbrowser,terminal,editor,filesorother, and--kind=filters on it. - Each app is asked in the language it speaks: AppleScript (JXA) on macOS, UI Automation on Windows, the accessibility tree as the catch-all.
- Apps that are not running are skipped, never launched.
1. See what is open
Section titled “1. See what is open”$ aos window list --kind=terminal* Ghostty terminal mon 2 1920x963+0+30 host.local: deemwar-one-os Ghostty terminal mon 1 864x1084-864+33 me@host:/private/tmp
$ aos tab list --app=chrome chrome:1658109204:1658109205 browser Example Domain https://example.com/* chrome:1658109204:1658109210 browser Example Domains https://www.iana.org/help/example-domains chrome:1658109204:1658109212 browser aos-bg-test data:text/html,<title>aos-bg-test</title>bg* marks the selected tab of each window. Terminals print the folder instead of a URL, and split panes indented under their tab:
$ aos tab list --app=ghostty --window=tab-group-8039faee0 ghostty:tab-group-8039faee0:tab-802a71200 terminal me@host:/private/tmp /private/tmp* ghostty:tab-group-8039faee0:tab-802a71c00 terminal me@host:/usr /usr * ghostty:tab-group-8039faee0:tab-802a71c00:41E9EDB7-DBC0-43E6-9A86-EE7ED8CCF27F me@host:/usr /usr ghostty:tab-group-8039faee0:tab-802a71c00:C8A30C61-013D-4EB2-A97E-2D301201105D me@host:/var /var--json gives every field an agent needs:
$ aos tab list --app=ghostty --json[ { "id": "ghostty:tab-group-8039faee0:tab-802a71200", "app": "Ghostty", "kind": "terminal", "window": "22626", "native_window": "tab-group-8039faee0", "index": 1, "title": "me@host:/private/tmp", "cwd": "/private/tmp", "active": true, "source": "applescript" }]window is the aos window id from window list, matched by app, bounds and title. native_window is the app’s own id. Listing 63 Chrome tabs takes about 100 ms: aos reads every title and URL in one request instead of one per tab.
2. Switch to a tab
Section titled “2. Switch to a tab”Name it by title, URL, folder or id. aos raises the window and selects the tab.
$ aos tab focus --title=aos-bg-test --app=chromechrome:1658109204:1658109212 aos-bg-test
$ aos tab focus --url=iana.org --app=safarisafari:22718:2 Example Domains
$ aos tab focus --cwd=/usr --app=ghosttyghostty:tab-group-8039faee0:tab-802a73a00 me@host:/usr
$ aos tab focus --title=nomatchxyzaos: no tab matched title="nomatchxyz"$ echo $?3Matching is a case-insensitive substring; --exact wants the whole title, URL or folder. When several tabs match, the selected one wins, else the first. A pane id focuses that split.
3. Open a tab
Section titled “3. Open a tab”The new tab’s id is printed, ready for focus, send or close.
$ aos tab open https://www.iana.org/help/example-domains --app=chrome --window=1658109204chrome:1658109204:1658109210
$ aos tab open "data:text/html,<title>aos-bg-test</title>bg" --app=Chrome --window=1658109204 --backgroundchrome:1658109204:1658109212
$ aos tab open --app=ghostty --window=tab-group-8039faee0 --cwd=/usr --command="echo opened-by-aos-tab" --backgroundghostty:tab-group-8039faee0:tab-802a73a00--windowtakes an aos window id, the app’s own id, or any tab id in that window. Without it the tab goes into the front window.--new-windowopens a window instead.--backgroundleaves the current tab selected and the app where it was.- In a terminal,
--commandruns once and the tab stays open with your normal shell after it.
4. Type into a terminal tab
Section titled “4. Type into a terminal tab”No focus needed: the terminal receives the text directly, so the person can keep working in another window.
$ aos tab send --id=ghostty:tab-group-8039faee0:tab-802a73a00 --text="echo sent-by-aos"$ aos tab send --id=ghostty:tab-group-8039faee0:tab-802a73a00 --key=enter$ aos tab send --id=iterm:22758:2 --key=ctrl+c
$ aos tab send --id=chrome:1658109204:1658109205 --text=hiaos: Google Chrome tabs cannot receive input from aos: a browser tab has no input channel; focus it and use `aos key` / `aos type`5. Close a tab
Section titled “5. Close a tab”One tab at a time, never the whole window, and never a close that would stop on a confirmation prompt.
$ aos tab close --id=chrome:1658109204:1658109210closed chrome:1658109204:1658109210 Example Domains
$ aos tab close --title=aos-bg-test --app=chromeclosed chrome:1658109204:1658109212 aos-bg-testIf the flags match more than one tab, close (and send) refuse with exit 4 and list the candidates; name one with --id or --exact. Index ids (Safari, iTerm2, Terminal) shift when an earlier tab closes, so pass --expect-title to make sure the id still points at the tab you listed:
$ aos tab close --id=safari:22718:2 --expect-title=Exampleclosed safari:22718:2 Example DomainsWhat each app supports
Section titled “What each app supports”| app | list | focus | open | send | close |
|---|---|---|---|---|---|
| Chrome, Edge, Brave, Vivaldi, Chromium | title, URL | yes | URL, new window, background | no | yes |
| Safari | title, URL | yes | URL, new window, background | no | yes |
| Ghostty 1.3+ | title, folder, panes | tab and pane | folder, command | text, keys | yes |
| iTerm2 | title, folder, panes | tab and pane | folder, command | text, enter, ctrl+letter | yes |
| Terminal.app | title | yes | new window only | text (run as a command) | a window’s only tab, when idle |
| any other app (macOS) | title, from the accessibility tree | yes | no | no | cmd+w, best-effort |
| any app (Windows) | title, from UI Automation | yes | Edge, Chrome, Brave, Windows Terminal | no | ctrl+w (browsers, Notepad), ctrl+shift+w (Windows Terminal), best-effort |
Accessibility close is best-effort: aos re-checks that the tab’s window is in front immediately before pressing the shortcut, and reports success only when the tab count dropped. Apps whose shortcut it does not know are refused. On Windows no URL or folder goes through cmd.exe; --command for Windows Terminal is a shell command by design.
Linux is not supported yet; aos tab exits 2 there.
If it does not work
Section titled “If it does not work”| Symptom | Fix |
|---|---|
macOS blocked aos from controlling Google Chrome (Automation permission) |
macOS asks once per app. If it was denied, turn it on in System Settings > Privacy & Security > Automation, or run tccutil reset AppleEvents and try again to get the prompt back. |
aos tab: Google Chrome: timed out on stderr |
The app took longer than 1.5 s to answer, usually a beachballing browser. The other apps’ tabs still print. |
… is gone (list again with aos tab list) |
The tab or window closed since you listed it. Index ids (Safari, iTerm2, Terminal) also shift when an earlier tab closes. |
| A Ghostty or Terminal window’s aos id changed | macOS makes each native tab its own window. Use native_window or a tab id with --window. |