DOMShell

Navegue pela web com comandos de sistema de arquivos. 38 ferramentas MCP permitem que agentes de IA executem ls, cd, grep, clique e digitação através do Chrome por meio de uma Extensão do Chrome.

Documentação

DOMShell

           | |
        ___|_|___
       |___|_|___|
       |   | |   |
       |___|_|___|
        /  | |  \
       /   | |   \
      |____|_|____|
      |           |
      |  DOMSHELL |
      |           |
      |___________|
      |###########|
      |###########|
       \#########/
        \_______/
 
  ██   ██ ██ ███████
  ██   ██ ██   ███
  ███████ ██   ██
  ██░░░██ ██   ██
  ██   ██ ██   ██
  ░░   ░░ ░░   ░░
   ███████ ██   ██ ███████
     ███   ███████ ██░░░░░
     ███   ██░░░██ █████
     ███   ██   ██ ██░░░
     ███   ██   ██ ███████
     ░░░   ░░   ░░ ░░░░░░░
   ██████   ██████  ███    ███  ██
   ██   ██ ██    ██ ████  ████  ██
   ██   ██ ██    ██ ██ ████ ██  ██
   ██   ██ ██    ██ ██  ██  ██  ░░
   ██████   ██████  ██      ██  ██
   ░░░░░░   ░░░░░░  ░░      ░░  ░░

O navegador é o seu sistema de arquivos. Uma extensão do Chrome que permite que agentes de IA (e humanos) naveguem na web usando comandos Linux padrão — ls, cd, cat, grep, click — por meio de um terminal no Painel Lateral do Chrome.

Instalar pela Chrome Web Store | pacote npm | Leia o post no blog | Página do projeto

O DOMShell mapeia o navegador em um sistema de arquivos virtual. Janelas e abas tornam-se diretórios de nível superior (~). A Árvore de Acessibilidade de cada aba torna-se um sistema de arquivos aninhado, onde elementos contêiner são diretórios e botões, links e campos de entrada são arquivos. Navegue pelo Chrome da mesma forma que navegaria pelo /usr/local/bin.

Por quê

Agentes de IA que interagem com sites normalmente dependem de capturas de tela, coordenadas de pixels ou seletores CSS frágeis. O DOMShell adota uma abordagem diferente: ele expõe a própria Árvore de Acessibilidade do navegador como uma metáfora familiar de sistema de arquivos.

Isso significa que um agente pode:

  • Navegar pelas abas com ls ~/tabs/ e alternar com cd ~/tabs/123 em vez de adivinhar qual aba está ativa
  • Explorar uma página com ls e tree em vez de analisar capturas de tela
  • Navegar para seções com cd navigation/ em vez de adivinhar coordenadas
  • Agir sobre elementos com click submit_btn em vez de consultas DOM frágeis
  • Ler conteúdo com cat ou extrair em massa com text em vez de raspar innerHTML
  • Buscar elementos com find --type combobox em vez de escrever seletores

A abstração de sistema de arquivos é determinística, semântica e funciona em qualquer site — sem necessidade de adaptadores específicos por site.

Instalação

Chrome Web Store (Recomendado)

Instale o DOMShell diretamente da Chrome Web Store. Nenhuma etapa de build é necessária.

A partir do código-fonte

git clone https://github.com/apireno/DOMShell.git
cd DOMShell
npm install
npm run build

Carregar no Chrome

  1. Abra chrome://extensions/
  2. Ative o Modo desenvolvedor (alternância no canto superior direito)
  3. Clique em Carregar sem compactação
  4. Selecione a pasta dist/
  5. Clique no ícone do DOMShell na sua barra de ferramentas — o painel lateral abre

Uso

Primeiros passos

Abra qualquer página da web e, em seguida, abra o painel lateral do DOMShell. Você verá um terminal:

╔══════════════════════════════════════╗
║   DOMShell v1.1.0                    ║
║   The browser is your filesystem.    ║
╚══════════════════════════════════════╝

Type 'help' to see available commands.
Type 'tabs' to see open browser tabs, then 'cd tabs/<id>' to enter one.

dom@shell:~$

Você começa em ~ (a raiz do navegador). Vá direto para a aba ativa com here, ou explore:

dom@shell:~$ ls
  windows/       (2 windows)
  tabs/          (5 tabs)

dom@shell:~$ here
✓ Entered tab 123
  Title: Google
  URL:   https://google.com
  AX Nodes: 247

Navegando por abas e janelas

# List all open tabs
dom@shell:~$ tabs
  ID     TITLE                       URL                        WIN
  123    Google                       google.com                 1
  124    GitHub - apireno             github.com/apireno         1
  125    Wikipedia                    en.wikipedia.org                 2

# Switch to a tab by ID
dom@shell:~$ cd tabs/125
✓ Entered tab 125
  Title: Wikipedia
  URL:   https://en.wikipedia.org
  AX Nodes: 312

# You're now inside the tab's DOM tree
dom@shell:~$ pwd
~/tabs/125

# Go back to browser level
dom@shell:~$ cd ~
dom@shell:~$

# Or use substring matching
dom@shell:~$ cd tabs/github
✓ Entered tab 124 (GitHub - apireno)

# List windows (shows tabs grouped under each window)
dom@shell:~$ windows
Window 1 (focused)
├── *123   Google                        google.com
├──  124   GitHub - apireno              github.com/apireno
└──  125   Wikipedia                     en.wikipedia.org

Window 2
├── *126   Stack Overflow                stackoverflow.com
└──  127   MDN Web Docs                  developer.mozilla.org

# Browse a specific window's tabs
dom@shell:~$ cd windows/2
dom@shell:~/windows/2$ ls
  ID     TITLE                       URL
  125    Wikipedia                    en.wikipedia.org
  126    LinkedIn                     linkedin.com

Você também pode navegar ou abrir novas abas:

# Navigate the current tab to a URL (requires being inside a tab)
dom@shell:~$ navigate https://example.com

# Open a URL in a new tab (works from anywhere)
dom@shell:~$ open https://github.com
✓ Opened new tab
  URL:   https://github.com
  Title: GitHub
  AX Nodes: 412

Grupos de abas (isolamento)

Por padrão, o DOMShell opera no seu navegador geral — modo compartilhado, exatamente como antes. O comando group coloca uma sessão em seu próprio grupo de abas isolado do Chrome, para que o agente trabalhe em uma faixa claramente demarcada enquanto você continua navegando livremente em outras abas:

# Create an isolated tab group and work inside it
dom@shell:~$ group new research
✓ Created isolated group '🐚 research'  [id 4]
  Working tab: 312

# While isolated, every command is confined to the group's tabs —
# entering a tab outside the group is rejected:
dom@shell:~$ cd tabs/126
cd: tab 126 is outside the session group (id 4). ...

# Show the current mode and group
dom@shell:~$ group
Group mode: isolated
  Group: 🐚 research  [id 4]
  Tabs:  1

# Leave the group (it stays open) — back to shared mode
dom@shell:~$ group detach

# Close the group's DOMShell tabs (your own tabs are kept)
dom@shell:~$ group close

Subcomandos: group (status), group new [name], group attach <id>, group detach, group close, group list. O modo isolado mantém o agente fora das suas outras abas; o modo compartilhado é o padrão e permanece inalterado.

Quando um cliente MCP se conecta, o DOMShell automaticamente dá a essa sessão seu próprio grupo 🐚 agent novo. O grupo é deixado aberto quando a sessão se desconecta (não destrutivo) — o agente é instruído a perguntar se você gostaria que ele fosse fechado antes de encerrar, e você sempre pode limpar os resíduos manualmente com group close.

Multissessão. Cada cliente DOMShell recebe sua própria faixa de sessão — cada janela do painel lateral, cada conexão MCP, isoladas separadamente. Dois painéis laterais em duas janelas do Chrome mantêm posições independentes; múltiplos agentes MCP simultâneos trabalham cada um em seu próprio grupo 🐚 agent com seu próprio cursor. Execute group list a qualquer momento para ver todas as faixas ativas; group close <id> para fechar uma.

Múltiplos agentes em uma única conexão MCP. Alguns clientes MCP (por exemplo, Claude Desktop) compartilham uma conexão entre todos os chats — então, por padrão, dois chats no mesmo cliente cairiam na mesma faixa. Cada chat pode reservar sua própria faixa passando o parâmetro group_id para domshell_execute: passe "new" para criar uma nova (seu id é retornado ao final da resposta como [lane: <id>]) e, em seguida, passe esse id em todas as chamadas posteriores. Dois chats → duas faixas → sem colisão. Os agentes também podem usar isso para transferência — um agente reporta seu id de faixa, o próximo agente o passa como group_id e continua no mesmo estado. Os agentes são instruídos a fechar qualquer faixa que criarem quando a tarefa for concluída.

Navegando pelo DOM

Uma vez dentro de uma aba, a Árvore de Acessibilidade aparece como um sistema de arquivos:

# List children of the current node
dom@shell:~$ ls
navigation/
main/
complementary/
contentinfo/
skip_to_content_link
logo_link

# Long format shows type prefixes and roles
dom@shell:~$ ls -l
[d] navigation     navigation/
[d] main           main/
[x] link           skip_to_content_link
[x] link           logo_link

# Filter by type
dom@shell:~$ ls --type link
skip_to_content_link
logo_link

# Show DOM metadata (href, src, id) inline — great for finding URLs
dom@shell:~$ ls --meta --type link
[x] link           skip_to_content_link  href=https://example.com/#content <a>
[x] link           logo_link             href=https://example.com/ <a>

# Paginate large directories
dom@shell:~$ ls -n 10              # First 10 items
dom@shell:~$ ls -n 10 --offset 10  # Items 11-20

# Count children by type
dom@shell:~$ ls --count
45 total (12 [d], 28 [x], 5 [-])

# Enter a directory (container element)
dom@shell:~$ cd navigation

# See where you are
dom@shell:~$ pwd
~/tabs/125/navigation

# Go back up
dom@shell:~$ cd ..

# Jump to browser root
dom@shell:~$ cd ~

# Multi-level paths work too
dom@shell:~$ cd main/article/form

# Path variable: %here% expands to the focused tab (via its window)
dom@shell:~$ cd %here%           # Enter the active tab
dom@shell:~$ cd %here%/..        # Go to the window containing the active tab
dom@shell:~$ cd %here%/main      # Enter the active tab and cd into main

Prefixos de tipo

Cada nó tem um prefixo de tipo que comunica metadados sem depender apenas de cor:

PrefixoSignificadoExemplos
[d]Diretório (contêiner, pode receber cd)navigation/, form/, main/
[x]Interativo (clicável/focalizável)botões, links, campos de entrada, caixas de seleção
[-]Estático (somente leitura)títulos, imagens, texto

Lendo conteúdo

# Inspect an element — cat shows full AX + DOM metadata
dom@shell:~$ cat submit_btn
--- submit_btn ---
  Role:  button
  Type:  [x] interactive
  AXID:  42
  DOM:   backend#187
  Tag:   <button>
  ID:    submit-form
  Class: btn btn-primary
  Text:  Submit Form
  HTML:  <button id="submit-form" class="btn btn-primary">Submit Form</button>

# cat on a link reveals the href URL
dom@shell:~$ cat Read_more
--- Read_more ---
  Role:  link
  Type:  [x] interactive
  AXID:  98
  DOM:   backend#312
  Tag:   <a>
  URL:   https://en.wikipedia.org/wiki/Article_Title
  Text:  Read more
  HTML:  <a href="https://en.wikipedia.org/wiki/Article_Title">Read more</a>

# Navigate to parent to find its properties (e.g. span inside a link)
dom@shell:~$ cd ..
dom@shell:~$ cat parent_link

# Bulk extract ALL text from a section (one call instead of 50+ cat calls)
dom@shell:/main$ text
[textContent of /main — 4,821 chars]
Heading: Welcome to Our Site
Today we announce the launch of our new product...
(full article text continues)

# Extract text from a specific child
dom@shell:~$text main
[textContent of main — 4,821 chars]

# Limit output length
dom@shell:~$text main -n 500

# Include link URLs inline as markdown [text](url)
dom@shell:~$text --links main/article/paragraph_2978
--- Text (with links): paragraph_2978 ---
Artificial intelligence (AI) is the capability of [computational systems](https://en.wikipedia.org/wiki/Computer)
to perform tasks typically associated with [human intelligence](https://en.wikipedia.org/wiki/Human_intelligence),
such as [learning](https://en.wikipedia.org/wiki/Learning), [reasoning](https://en.wikipedia.org/wiki/Reason)...
(text + link URLs in a single call)

# Get a tree view (default depth: 2)
dom@shell:~$tree
navigation/
├── [x] home_link
├── [x] about_link
├── [x] products_link
└── [x] contact_link

# Deeper tree
dom@shell:~$tree 4

Buscando

# Search current directory
dom@shell:~$grep login
[x] login_btn (button)
[d] login_form (form)
[x] login_link (link)

# Recursive search across all descendants
dom@shell:~$grep -r search
[x] search_search (combobox)
[x] search_btn (button)

# Limit results
dom@shell:~$grep -r -n 5 link

# Deep search with full paths (like Unix find)
dom@shell:~$find search
[x] /search_2/search_search (combobox)
[x] /search_2/search_btn (button)

# Find by role type
dom@shell:~$find --type combobox
[x] /search_2/search_search (combobox)

dom@shell:~$find --type textbox
[x] /main/form/email_input (textbox)
[x] /main/form/name_input (textbox)

# Limit results
dom@shell:~$find --type link -n 5

# Find all links with their URLs (great for content extraction)
dom@shell:~$find --type link --meta
[x] /nav/home_link (link)  href=https://example.com/ <a>
[x] /main/Read_more (link)  href=https://example.com/article <a>

Encadeamento de comandos (composição estilo Bash)

O DOMShell funciona como um sistema de arquivos — use o mesmo modelo mental de buscar arquivos no disco. grep descobre onde o conteúdo vive (como grep -r no bash), cd define o escopo do seu contexto, e text/cat/find lê o conteúdo (como cat/head/less). O operador pipe (|) filtra a saída, exatamente como no bash.

O padrão é: grep (localizar) → cd (definir escopo) → extrair (ler).

# Workflow 1: Find and read an article section
dom@shell:~$ grep -r article
[d] article (article)  →  ./main/article/
dom@shell:~$ cd main/article
dom@shell:~/main/article$ text
[full article content in one call]

# Workflow 2: Find a section and extract its links
dom@shell:~$ grep -r references
[d] references (region)  →  ./main/article/references/
dom@shell:~$ cd main/article/references
dom@shell:~/main/article/references$ find --type link --meta
[x] /wiki_link (link)  href=https://en.wikipedia.org/... <a>
[x] /paper_link (link)  href=https://arxiv.org/... <a>

# Workflow 3: Find a table and extract structured data
dom@shell:~$ grep -r table
[d] table_4091 (table)  →  ./main/section/table_4091/
dom@shell:~$ extract_table table_4091
| Name   | Value  | Date       |
|--------|--------|------------|
| Alpha  | 42     | 2025-01-15 |
| Beta   | 87     | 2025-02-20 |

# Workflow 4: Discover sections, then drill into one
dom@shell:~$ grep -r heading
[−] Introduction_heading (heading)  →  ./main/article/Introduction_heading
[−] Methods_heading (heading)  →  ./main/article/Methods_heading
[−] Results_heading (heading)  →  ./main/article/Results_heading
dom@shell:~$ cd main/article/Results_heading
dom@shell:~/main/article/Results_heading$ text
[text content of the Results section]

# Workflow 5: Find elements by visible text (not just name)
dom@shell:~$ grep -r --content "sign up"
[x] get_started_btn (button)  →  ./main/hero/get_started_btn
# The button's NAME is "get_started_btn" but its displayed text says "Sign Up Free"
dom@shell:~$ click get_started_btn

Operador pipe

O operador pipe (|) permite filtrar a saída de comandos, exatamente como no bash:

# Filter find results to only GitHub links
dom@shell:~$ find --type link --meta | grep github
[x] /main/repo_link (link)  href=https://github.com/example <a>

# Filter ls output to elements mentioning "login"
dom@shell:~$ ls --text | grep login
[x] login_btn  "Log in to your account"

# Limit results with head
dom@shell:~$ find --type heading | head -n 3
[−] /main/intro_heading (heading)
[−] /main/features_heading (heading)
[−] /main/pricing_heading (heading)

# Chain multiple pipes
dom@shell:~$ find --type link --meta | grep docs | head -n 5

Resolução de caminhos

Todos os comandos aceitam caminhos relativos, eliminando a necessidade de cd primeiro:

# Read text from a nested element directly
dom@shell:~$ text main/article/paragraph_2971

# Click a button inside a form without cd'ing
dom@shell:~$ click main/form/submit_btn

# Inspect a link in the nav
dom@shell:~$ cat navigation/home_link

Navegação entre irmãos

Use os sinalizadores --after e --before em ls para encontrar conteúdo relativo a um ponto de referência:

# Show the 3 elements after a heading
dom@shell:~$ ls --after See_also_heading -n 3 --text
[d] related_topics_list  "Machine Learning, Deep Learning, Neural..."
[−] paragraph_4512       "For more information on these topics..."
[x] Read_more_link       "Read more on Wikipedia"

# Find links after a specific section heading
dom@shell:~$ ls --after References_heading --type link --meta
[x] source_1_link (link)  href=https://arxiv.org/... <a>
[x] source_2_link (link)  href=https://doi.org/... <a>

A percepção fundamental: a saída de grep alimenta cd, e cd define o escopo de todo o resto. Quando você não sabe onde o conteúdo vive em uma página, sempre faça grep primeiro, depois defina o escopo e, por fim, extraia.

Interagindo com elementos

# Click a button or link
dom@shell:~$click submit_btn
✓ Clicked: submit_btn (button)
(tree will auto-refresh on next command)

# Focus an input field
dom@shell:~$focus email_input
✓ Focused: email_input

# Type into the focused field
dom@shell:~$type hello@example.com
✓ Typed 17 characters

# Navigate to a URL (current tab)
dom@shell:~$navigate https://example.com
✓ Navigated to https://example.com

# Open a URL in a new tab
dom@shell:~$open https://github.com
✓ Opened new tab → https://github.com

Atualização automática em mudanças do DOM

O DOMShell detecta automaticamente quando a página muda — navegação, mutações do DOM ou atualizações de conteúdo provenientes de cliques. Você não precisa mais executar refresh manualmente:

dom@shell:~$click search_btn
✓ Clicked: search_btn (button)
(tree will auto-refresh on next command)

dom@shell:~$ls
(page changed — tree refreshed, 312 nodes, path reset to tab root)
main/
navigation/
search_results/
...

Se a página navegou, o CWD é redefinido para a raiz da aba. Se o DOM apenas foi atualizado no lugar, seu CWD é preservado. Você ainda pode forçar uma atualização manual:

dom@shell:~$refresh
✓ Refreshed. 312 AX nodes loaded.

Autocompletar com Tab

Pressione Tab para autocompletar comandos e nomes de elementos — funciona como no bash:

dom@shell:$ ta<Tab>
# completes to: tabs

dom@shell:$ cd nav<Tab>
# completes to: cd navigation/

dom@shell:$ click sub<Tab>
# if multiple matches, shows options:
#   submit_btn
#   subscribe_link
  • Correspondência única: autocompleta inline
  • Múltiplas correspondências: mostra opções abaixo, preenche o prefixo comum mais longo
  • cd completa apenas diretórios; outros comandos completam todos os elementos

Suporte a colar

Cmd+V (Mac) / Ctrl+V (Windows/Linux) cola texto diretamente no terminal. Colagens de múltiplas linhas são achatadas em uma única linha.

Comandos do sistema

# Check if you're authenticated (reads cookies)
dom@shell:~$whoami
URL: https://example.com
Status: Authenticated
Via: session_id
Expires: 2025-12-31T00:00:00.000Z
Total cookies: 12

# Environment variables
dom@shell:~$env
SHELL=/bin/domshell
TERM=xterm-256color

# Set a variable
dom@shell:~$export API_KEY=sk-abc123

# Debug the raw AX tree
dom@shell:~$debug stats
--- Debug Stats ---
  Total AX nodes:   247
  Ignored nodes:    83
  Generic nodes:    41
  With children:    62
  Iframes:          2

Obtendo ajuda

Todo comando suporta --help:

dom@shell:$ ls --help
ls — List children of the current node

Usage: ls [options]

Options:
  -l, --long      Long format: type prefix, role, and name
  -r, --recursive Show nested children (one level deep)
  -n N            Limit output to first N entries
  --offset N      Skip first N entries (for pagination)
  --type ROLE     Filter by AX role (e.g. --type button)
  --count         Show count of children only
...

Referência de comandos

Nível do navegador

ComandoDescrição
tabsLista todas as abas abertas (atalho para ls ~/tabs/)
windowsLista todas as janelas com suas abas agrupadas abaixo
hereVai para a aba ativa na janela em foco
cd ~Vai para a raiz do navegador
cd ~/tabs/<id>Alterna para uma aba por ID (entra automaticamente)
cd ~/tabs/<pattern>Alterna para uma aba por correspondência de substring no título/URL
cd ~/windows/<id>Navega pelas abas de uma janela
navigate <url>Navega a aba atual para uma URL
open <url>Abre uma URL em uma nova aba e entra nela
backVolta no histórico do navegador (como o botão voltar)
forwardAvança no histórico do navegador
close [tab-id]Fecha a aba atual (ou uma aba específica por ID)

Árvore do DOM

ComandoDescrição
ls [options]Lista filhos (-l, --meta, --text, -r, -n N, --offset N, --type ROLE, --count, --after NAME, --before NAME, --json)
cd <path>Navega (.., ~ ou / para a raiz do navegador, %here% para a aba em foco, main/form para múltiplos níveis)
pwdImprime o caminho atual (caminho do DOM ou caminho do navegador)
tree [depth]Visualização em árvore do nó atual (profundidade padrão: 2)
cat <name> [--json]Metadados completos do elemento: informações de AX + propriedades do DOM (tag, href, src, id, class, outerHTML)
text [name] [-n N] [--links]Extrai em massa todo o texto de uma seção (--links insere URLs inline como [text](url))
read [name] [opts]Extração estruturada de subárvore (--meta, --text, -d N profundidade) — árvore + conteúdo em uma única chamada
grep [opts] <pattern>Busca por nome/role/valor (-r recursivo, --content corresponde ao texto visível, -n N limite)
find [opts] <pattern>Busca recursiva profunda (--type ROLE com aliases difusos: input, dropdown, nav, toggle, modal, image, etc.; --meta, --text, --content, -n N, --json)
extract_links [name]Extrai todos os links no formato [text](url) (limite de -n N)
extract_table <name>Extrai tabela como markdown ou CSV (--format csv, limite de linhas -n N)
click <name>Clica em um elemento (recorre a clique baseado em coordenadas)
focus <name>Focaliza um elemento de entrada
type <text>Digita texto no elemento em foco
submit <input> <val>Preenchimento atômico de formulário: focalizar + limpar + digitar + enviar (--submit btn ou Enter)
scroll [down|up] [N]Rola a página por N alturas de viewport (padrão: 1). Retorna a porcentagem da posição de rolagem.
scroll <name>Rola um elemento específico para o centro do viewport
js <code>Executa JavaScript no contexto da aba. Retorna resultado serializado em JSON. Suporta async/await.
screenshotCaptura uma captura de tela PNG da aba atual (retorna imagem via MCP, base64 no shell)
select <name> <value>Seleciona uma opção de menu suspenso por valor ou texto visível (dispara eventos change/input)
wait <pattern> [--type ROLE] [--timeout N]Aguarda um elemento correspondente ao padrão aparecer (verifica a árvore AX, timeout padrão de 5s, máximo de 30s)
eval <expr>Avalia uma expressão JS (somente leitura, sem necessidade de --allow-write). Igual a js, mas no nível de Leitura.
diff [--json]Compara a árvore AX com o snapshot pré-ação. Mostra elementos adicionados/removidos/alterados após clique/envio/navegação.
refreshForça a reobtenção da Árvore de Acessibilidade

Automação

ComandoDescrição
watch <cmd> [--interval N] [--times N] [--until-change]Reexecuta um comando periodicamente. --until-change para quando a saída difere. Limitado a 28s.
for <source-cmd> : <action-tpl>Itera sobre linhas de saída. {} é substituído por cada linha. Limitado a 50 itens / 28s.
script list|save|show|run|deleteSalva e executa scripts de múltiplos comandos. script run name arg1 substitui $1 nos comandos salvos. Persistido.
each [--pattern FILTER] <cmd>Executa um comando em todas as abas correspondentes. Restaura a aba original depois.
functions [pattern] [--json]Lista funções JS globais chamáveis na página com nome, aridade, parâmetros.
call <funcName> [arg1] [arg2] ...Chama uma função JS global pelo nome. Argumentos analisados automaticamente (JSON ou string). Nível de escrita.

Sistema

ComandoDescrição
whoamiVerificar cookies de sessão/auth da página atual
envMostrar variáveis de ambiente
export K=VDefinir uma variável de ambiente
history [-n N]Mostrar histórico de comandos. history clear para redefinir. !N para recuperar o comando N.
bookmark [name] [path]Salvar/listar caminhos nomeados. bookmark inbox salva o caminho atual. cd @inbox volta. bookmark --delete name remove.
debug [sub]Inspecionar árvore AX bruta (stats, raw, node <id>)
connect <token>Conectar a um servidor MCP via ponte WebSocket
disconnectDesconectar do servidor MCP, limpar token
helpMostrar todos os comandos disponíveis
clearLimpar o terminal

Como Funciona o Mapeamento do Sistema de Arquivos

O DOMShell mapeia o navegador em um sistema de arquivos virtual de dois níveis:

Nível do Navegador (~)

O próprio navegador se torna o topo da hierarquia do sistema de arquivos:

~                              (browser root)
├── windows/                   (all Chrome windows)
│   ├── <window-id>/           (tabs in that window)
│   │   ├── <tab-id>           (cd into = enter AX tree)
│   │   └── ...
│   └── ...
└── tabs/                      (flat listing of ALL tabs)
    ├── <tab-id>               (cd into = enter AX tree)
    └── ...

Entrar (cd) em uma aba anexa o CDP de forma transparente e o leva para a árvore DOM dela.

Nível do DOM (dentro de uma aba)

A Árvore de Acessibilidade (AXTree) de cada aba é lida via Chrome DevTools Protocol. Cada nó AX é mapeado para um arquivo ou diretório virtual:

Diretórios (papéis de contêiner): navigation/, main/, form/, search/, list/, region/, dialog/, menu/, table/, Iframe/, etc.

Arquivos (papéis interativos/folha): submit_btn, home_link, email_input, agree_chk, theme_switch, etc.

cd .. a partir da raiz do DOM volta para a listagem de abas. cd ~ retorna à raiz do navegador de qualquer lugar.

Heurística de Nomenclatura

Os nomes são gerados a partir do nome acessível e do papel do nó:

Nó AXNome Gerado
role=button, name="Submit"submit_btn
role=link, name="Contact Us"contact_us_link
role=textbox, name="Email"email_input
role=checkbox, name="I agree"i_agree_chk
role=navigationnavigation/
role=generic, no name, 1 child(achatado — filho promovido para cima)

Nomes duplicados são automaticamente desambiguados com _2, _3, etc.

Achatamento de Nós

A árvore AX contém muitos nós "wrapper" — nós ignorados, genéricos sem nome e elementos com role=none que adicionam ruído estrutural sem significado semântico. O DOMShell achata recursivamente esses nós, promovendo seus filhos para cima, para que você veja os elementos significativos sem navegar por camadas de divs invisíveis.

Suporte a Iframes

O DOMShell descobre iframes via Page.getFrameTree e busca a árvore AX de cada iframe separadamente. Os nós de iframe são mesclados à árvore principal com IDs prefixados para evitar colisões, então elementos dentro de iframes aparecem naturalmente no sistema de arquivos.

Codificação de Cores

CorSignificado
Azul (negrito)Diretórios (contêineres)
Verde (negrito)Botões
Magenta (negrito)Links
Amarelo (negrito)Campos de texto / caixas de busca
Ciano (negrito)Caixas de seleção / botões de opção / interruptores
BrancoOutros elementos
CinzaImagens, metadados

Arquitetura

┌────────────────────┐
│  Claude Desktop    │──┐
└────────────────────┘  │
┌────────────────────┐  │  HTTP POST/GET/DELETE              ┌─────────────────────┐
│  Claude CLI        │──┼─ localhost:3001/mcp ──┐            │  Side Panel (UI)    │
└────────────────────┘  │  (Bearer token auth)  │            │                     │
┌────────────────────┐  │                       │            │  React + Xterm.js   │
│  Cursor / Other    │──┘                       │            │  - Paste support    │
└────────────────────┘                          ▼            │  - Tab completion   │
                               ┌─────────────────────┐      │  - Command history  │
                               │  MCP Server          │      └─────────┬───────────┘
                               │  (mcp-server/)       │                │
                               │                      │       chrome.runtime
                               │  Express HTTP server  │       .connect()
                               │  Per-session MCP      │                │
                               │  Security layer:     │      ┌─────────▼───────────┐
                               │  - Auth token        │      │  Background Worker  │
                               │  - Command tiers     │      │   (Shell Kernel)    │
                               │  - Domain allowlist  │      │                     │
                               │  - Audit log         │      │  Browser hierarchy  │
                               └──────────┬───────────┘      │  (~, tabs, windows) │
                                          │                  │  Command parser     │
                               WebSocket (localhost:9876)     │  Shell state (CWD)  │
                               + auth token                  │  VFS mapper         │
                               + alarm keepalive             │  CDP client         │
                                          │                  │  DOM change detect  │
                                          └─────────────────►│  WebSocket bridge   │
                                                             └─────────┬───────────┘
                                                                       │
                                                              chrome.debugger
                                                              (CDP 1.3)
                                                                       │
                                                             ┌─────────▼───────────┐
                                                             │   Active Tab        │
                                                             │   Accessibility     │
                                                             │   Tree + iframes    │
                                                             │                     │
                                                             │   DOM events ──────►│
                                                             │   (auto-refresh)    │
                                                             └─────────────────────┘

O servidor MCP roda como um serviço HTTP autônomo ao qual qualquer número de clientes MCP pode se conectar simultaneamente. Ele expõe duas portas: um endpoint HTTP para clientes MCP (padrão 3001) e uma ponte WebSocket para a extensão do Chrome (padrão 9876).

A extensão segue um modelo Cliente Leve / Host Pesado. O painel lateral é um terminal "burro" — ele captura teclas, lida com colagem e renderiza texto colorido ANSI. Toda a lógica vive no service worker em segundo plano: análise de comandos, travessia da árvore AX, mapeamento do sistema de arquivos, interação com CDP, navegação na hierarquia do navegador e detecção de mudanças no DOM.

Estrutura do Código-Fonte

src/
  background/
    index.ts        # Shell kernel — commands, state, message router, auto-refresh, WS bridge
    cdp_client.ts   # Promise-wrapped chrome.debugger API + iframe discovery
    vfs_mapper.ts   # Accessibility Tree → virtual filesystem mapping
  sidepanel/
    index.html      # Side panel entry HTML
    index.tsx        # React entry point
    Terminal.tsx     # Xterm.js terminal (paste, tab completion, history)
  shared/
    types.ts        # Message types, AXNode interfaces, role constants
public/
  manifest.json     # Chrome Manifest V3
  options.html      # Extension settings page (MCP bridge config)
mcp-server/
  index.ts          # MCP server — standalone Express HTTP + StreamableHTTP, WebSocket bridge, security
  proxy.ts          # Stdio↔HTTP bridge for clients that require command/args (e.g. Claude Desktop)
  package.json      # MCP server dependencies
  tsconfig.json     # MCP server TypeScript config

Pilha Tecnológica

  • React + TypeScript — UI do painel lateral
  • Xterm.js (@xterm/xterm) — Emulador de terminal com esquema de cores Tokyo Night
  • Vite — Ferramenta de build com suporte a múltiplas entradas para extensões do Chrome
  • Chrome DevTools Protocol (CDP 1.3) via chrome.debugger — acesso à árvore AX, interação com elementos, descoberta de iframes, eventos de mutação do DOM
  • Chrome Manifest V3 — permissões sidePanel, debugger, activeTab, cookies, storage, alarms

Desenvolvimento

# Watch mode (rebuilds on file changes)
npm run dev

# One-time production build
npm run build

# Type checking
npm run typecheck

Após o build, recarregue a extensão em chrome://extensions/ e reabra o painel lateral para aplicar as alterações.

Conectando Clientes MCP (Claude Desktop, CLI, Cursor, etc.)

O DOMShell inclui um servidor MCP endurecido que permite que qualquer cliente compatível com MCP controle o navegador por meio de comandos do DOMShell. O servidor roda como um serviço HTTP autônomo — vários clientes podem se conectar simultaneamente.

Três caminhos de instalação

O servidor MCP do DOMShell suporta três caminhos de instalação — escolha o que melhor se adequa à sua configuração. O Caminho 1 é o padrão documentado e o que a maioria dos usuários quer. Os Caminhos 2 e 3 são opcionais e existem para usuários que desejam isolamento de contêiner ou gerenciamento de ciclo de vida.

CaminhoO que você executaComportamento na reinicializaçãoQuando escolher
1. Nativo (npx)npx @apireno/domshell --allow-write --token <token>Sobrevive naturalmente — o cliente MCP (Claude Desktop, Cursor, …) o inicia sob demandaVocê quer a instalação mais simples — sem Docker, sem ferramentas extras
2. Dockerizado (compose)docker compose up -d a partir de mcp-server/ com um arquivo .envSobrevive com a opção "Iniciar no login" do Docker Desktop (restart: unless-stopped)Você quer isolamento de contêiner, mas não precisa de um supervisor multi-MCP
3. Gerenciado pelo ToolHive (thv)thv run + um agente de inicialização automática launchd únicoSobrevive via launchd → thv restart --allVocê está executando vários servidores MCP e quer um único lugar para thv list / thv logs todos eles

Instruções completas dos Caminhos 2 / 3 (build, padrão de instalação .env, template de inicialização automática launchd, recuperação após reinicialização): docs/deploy/container-and-toolhive.md. O restante deste README cobre o Caminho 1 — o padrão mais simples e recomendado.

Instalação via npm (Caminho 1 — padrão)

npm install -g @apireno/domshell

Ou execute diretamente sem instalar:

npx @apireno/domshell --allow-write --token my-secret-token

Arquitetura

User starts independently:
  npx @apireno/domshell --allow-write --token xyz
    → HTTP on :3001/mcp  (MCP clients)
    → WebSocket on :9876  (Chrome extension)

Claude Desktop spawns (stdio proxy):                    ┐
  npx domshell-proxy --port 3001 --token xyz            ├─► HTTP :3001/mcp
Claude CLI connects directly:                           │
  url: http://localhost:3001/mcp?token=xyz              │
Gemini CLI connects directly:                           │
  url: http://localhost:3001/mcp?token=xyz              ┘

O servidor MCP é um serviço HTTP autônomo — você o inicia de forma independente, e qualquer número de clientes MCP se conecta a ele. Nenhum cliente individual "possui" o processo do servidor. Para clientes que exigem stdio (como o Claude Desktop), um pequeno proxy faz a ponte entre stdio e o servidor HTTP em execução.

Configuração

Configuração rápida (recomendada):

npx @apireno/domshell init

O assistente detecta clientes MCP instalados (Claude Desktop, Cursor, Windsurf), gera um token compartilhado e grava a configuração de cada cliente. Você então inicia o servidor uma vez em um terminal — todos os clientes se conectam a ele.

Use --yes para o modo não interativo com padrões sensatos:

npx @apireno/domshell init --yes

Configuração manual:

1. Inicie o servidor MCP:

npx @apireno/domshell --allow-write --token my-secret-token

O servidor inicia dois listeners:

  • HTTP em http://127.0.0.1:3001/mcp — endpoint do cliente MCP
  • WebSocket em ws://127.0.0.1:9876 — ponte da extensão do Chrome

Dica: Use --token para definir um token conhecido e pré-configurar os clientes. Se omitido, um token aleatório é gerado e exibido na inicialização.

2. Conecte os clientes MCP:

Claude CLI / Gemini CLI / Cursor (HTTP direto — recomendado):

http://localhost:3001/mcp?token=my-secret-token

Claude Desktop (exige stdio — use o proxy):

Adicione em ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "domshell": {
      "command": "npx",
      "args": ["-y", "@apireno/domshell", "--allow-write", "--token", "my-secret-token"]
    }
  }
}

Reinicie o Claude Desktop. As ferramentas do DOMShell aparecerão.

3. Conecte a extensão (Página de Opções):

  1. Vá para chrome://extensions/
  2. Encontre DOMShell e clique em Options (ou clique com o botão direito no ícone da extensão → Options)
  3. Ative a opção MCP Bridge
  4. Cole o mesmo token que você usou na configuração do Claude Desktop (my-secret-token)
  5. Clique em Save — o indicador de status fica verde quando conectado

A página de opções mostra o status de conexão em tempo real: Disabled, Connecting, Connected ou Disconnected.

Alternativa: Conecte via terminal

Você também pode conectar pelo terminal do DOMShell em vez da página de opções:

dom@shell:$ connect my-secret-token

4. Teste:

Pergunte ao Claude: "Liste minhas abas abertas e me diga o que há na primeira."

Segurança

O servidor MCP é endurecido com múltiplas camadas de segurança. Por padrão, é somente leitura — o Claude pode navegar, mas não clicar ou digitar.

Níveis de Comandos

NívelComandosPadrãoAtivar Com
Leiturals, cd, pwd, cat, text, grep, find, tree, refresh, tabs, windows, here, screenshot, wait, eval, diff, history, bookmark, functions, watch, for, script, eachAtivado(sempre ativo)
Navegaçãonavigate, goto, open, back, forwardDesativado--allow-write
Escritaclick, focus, type, scroll, js, select, close, callDesativado--allow-write
Sensívelwhoami (expõe cookies)Desativado--allow-sensitive

O nível Navegação é separado do de Escrita porque navegar equivale a digitar uma URL — exige --allow-write, mas pula o prompt de confirmação interativo. Isso é importante para o Claude Desktop, onde /dev/tty não está disponível.

Flags de Segurança

FlagDescrição
--allow-writeAtivar comandos de clique/foco/digitação/rolagem/js/seleção/fechar/navegar/voltar/avançar
--allow-sensitiveAtivar whoami (acesso a cookies)
--allow-allAtalho para ambos
--confirmOptar por prompts y/n por ação no terminal do servidor antes de cada escrita. Desativado por padrão.
--no-confirmNo-op (mantido para compatibilidade retroativa — prompts por ação estão desativados por padrão).
--domains example.com,app.example.comRestringir comandos a domínios específicos
--expose-cookiesMostrar valores completos de cookies (padrão: ocultos)
--mcp-port NPorta do endpoint HTTP MCP (padrão: 3001)
--port NPorta da ponte WebSocket (padrão: 9876)
--log-file PATHArquivo de log de auditoria (padrão: audit.log)

Confirmação por Ação (opt-in)

Os prompts de terminal por ação estão desativados por padrão — o terminal do servidor MCP é separado de onde o agente e o painel lateral realmente rodam, então o prompt é difícil de responder em qualquer configuração iniciada por GUI (Claude Desktop, Cursor, harness do CLI-Anything). O log de auditoria captura todos os comandos, e as flags de nível (--allow-write, --allow-sensitive) mais --domains continuam sendo os limites reais de segurança.

Se você iniciar o servidor no seu próprio terminal e quiser um prompt y/n antes de cada escrita, adicione --confirm:

[DOMShell] Claude wants to: click submit_btn
Allow? (y/n):

--no-confirm é preservado como no-op (corresponde ao padrão), então qualquer configuração existente que o use continua funcionando sem alterações.

Token de Autenticação

  • Use --token para definir um token conhecido na configuração do servidor MCP, ou deixe o servidor gerar um aleatório na inicialização
  • A extensão deve apresentar esse token (via página de opções ou connect <token>) antes que a ponte funcione
  • Conexões WebSocket sem um token válido são rejeitadas
  • O token é armazenado em chrome.storage.local — sobrevive a reinicializações do service worker

Lista de Domínios Permitidos

Com --domains, os comandos só são executados quando a URL da aba ativa corresponde:

npx tsx index.ts --allow-write --domains "github.com,docs.google.com"

Log de Auditoria

Cada comando é registrado com timestamps em audit.log (ou --log-file):

[2026-02-07T12:00:00.000Z] EXECUTE: ls -l
[2026-02-07T12:00:01.000Z] RESULT: 12 items
[2026-02-07T12:00:05.000Z] [WRITE] EXECUTE: click submit_btn
[2026-02-07T12:00:05.500Z] [WRITE] RESULT: ✓ Clicked: submit_btn (button)

Desconectando

Desative a opção MCP Bridge na página de opções da extensão, ou execute disconnect no terminal do DOMShell:

dom@shell:$ disconnect
✓ Disconnected from MCP server.

A interface domshell_execute

O servidor MCP do DOMShell expõe uma única ferramenta por padrão — domshell_execute — a forma recomendada de usar o DOMShell. Você passa uma string de comando, exatamente como digitaria no terminal do DOMShell:

domshell_execute("ls")
domshell_execute("cd tabs/4815")
domshell_execute("find --type link --meta")

Chamadas com múltiplos comandos. Passe vários comandos separados por novas linhas e eles serão executados em sequência, com a saída combinada retornada — um fluxo de trabalho inteiro em uma única chamada de ferramenta:

domshell_execute("open https://example.com
cd main
text")

Uma única ida e volta em vez de três, e menos ciclos de chamadas de ferramenta.

Semântica de múltiplas linhas. Cada linha é executada em ordem na mesma sessão e faixa do MCP, então cwd, env e histórico persistem entre as linhas (o cd main da segunda linha é relativo à aba recém-aberta da primeira linha). Um erro em qualquer linha individual não interrompe o restante — sua mensagem de erro é incluída na saída combinada e as linhas subsequentes ainda são executadas. Esse é o formato certo para expressões idiomáticas de linha de limpeza como "cd path\ngrep pattern\ncd back", onde a restauração final deve ser executada mesmo se a etapa intermediária falhar. Implementação: mcp-server/index.ts:1115-1136.

Dois modos:

ModoFerramentas expostasUse quando
Ferramenta única (padrão)Somente domshell_executeUso normal. Uma aprovação cobre a sessão inteira — sem prompts por comando.
Granular (--granular)38 ferramentas por comando (domshell_ls, domshell_click, …)Você quer que seu cliente MCP solicite aprovação por tipo de operação — supervisão humana mais refinada na camada do cliente.

Inicie o servidor com --granular para as ferramentas por comando:

npx @apireno/domshell --granular

A segurança é idêntica em ambos os modos. Os níveis do lado do servidor do DOMShell (write / sensitive — definidos por --allow-write, --allow-sensitive, com --confirm opcional para prompts do terminal do servidor por ação) controlam operações arriscadas independentemente de qual ferramenta emitiu o comando. O modo granular não adiciona segurança — ele adiciona um prompt de aprovação extra no seu cliente MCP por tipo de operação. Isso é mais supervisão humana, não mais proteção.

Referência de Ferramentas MCP (modo --granular)

A tabela abaixo lista as ferramentas por comando expostas quando o servidor é executado com --granular. No modo de ferramenta única padrão, execute os mesmos comandos por meio de domshell_execute — a coluna Maps To mostra a string de comando.

Ferramenta MCPMapeia paraNível
domshell_tabstabs (listar todas as abas)Leitura
domshell_herehere (ir para a aba ativa)Leitura
domshell_lsls [options] (nível DOM ou navegador)Leitura
domshell_cdcd <path> (~, ~/tabs/, /, ..)Leitura
domshell_pwdpwdLeitura
domshell_catcat <name>Leitura
domshell_texttext [name] [-n N] [--links] (texto em massa; links=true incorpora URLs)Leitura
domshell_readread [name] [--meta] [--text] [-d N] (subárvore estruturada)Leitura
domshell_findfind [pattern] [--type ROLE/alias] [--meta] [--text] [-n N] (o tipo aceita aliases difusos: input, dropdown, nav, etc.)Leitura
domshell_grepgrep [-r] [-n N] [--content] <pattern> (descoberta de seções)Leitura
domshell_treetree [depth]Leitura
domshell_extract_linksextract_links [name] [-n N] (todos os links como [text](url))Leitura
domshell_extract_tableextract_table <name> [--format csv] (tabela → markdown/CSV)Leitura
domshell_refreshrefreshLeitura
domshell_navigatenavigate <url> (aba atual)Navegação
domshell_openopen <url> (nova aba)Navegação
domshell_clickclick <name>Escrita
domshell_focusfocus <name>Escrita
domshell_scrollscroll [down|up] [N] ou scroll <target>Escrita
domshell_jsjs <code> (execução arbitrária de JavaScript)Escrita
domshell_typetype <text>Escrita
domshell_submitsubmit <input> <value> [--submit btn] (preenchimento atômico de formulário)Escrita
domshell_backback (voltar no histórico do navegador)Navegação
domshell_forwardforward (avançar no histórico do navegador)Navegação
domshell_closeclose [tab-id] (fechar uma aba)Escrita
domshell_screenshotscreenshot (capturar aba como imagem PNG)Leitura
domshell_selectselect <name> <value> (seleção em dropdown)Escrita
domshell_waitwait <pattern> [--type ROLE] [--timeout N] (aguardar por elemento)Leitura
domshell_evaleval <expression> (avaliação JS somente leitura, sem --allow-write necessário)Leitura
domshell_diffdiff [--json] (comparar árvore com snapshot pré-ação)Leitura
domshell_whoamiwhoamiSensível
domshell_functionsfunctions [pattern] [--json] (listar funções de página chamáveis)Leitura
domshell_callcall <funcName> [args] (chamar uma função JS global)Escrita
domshell_watchwatch <cmd> [--interval N] [--times N] [--until-change] (re-execução periódica)Leitura
domshell_forfor <source> : <template> (iterar sobre linhas de saída, {} substituído)Leitura
domshell_scriptscript list|save|show|run|delete (scripts com substituição de $1)Leitura
domshell_eacheach [--pattern FILTER] <cmd> (operações entre abas)Leitura
domshell_execute(qualquer comando)Variável

Roteiro

Distribuição e Configuração

  • Listagem na Chrome Web Storedisponível na Chrome Web Store
  • Lançamento no GitHub com .crxlançamento v1.1.1 com zip da extensão
  • Assistente de configuração MCPnpx @apireno/domshell init detecta clientes MCP instalados, gera um token e grava a configuração automaticamente
  • Suporte para outros clientes MCP — Gemini Desktop, OpenAI ChatGPT desktop, Cursor, Windsurf e outros hosts compatíveis com MCP

Novos Comandos

  • watch — re-execução periódica de um comando (ex.: watch ls --times 3 --interval 1 para verificar mudanças no DOM)
  • history — histórico de comandos com recall (history, !n para re-executar)
  • back / forward — navegação de histórico no estilo navegador dentro da aba atual
  • close — fechar a aba atual (close ou close <tab-id>)
  • screenshot — capturar uma captura de tela da aba atual (útil para verificação visual junto com a inspeção da árvore AX)
  • pipe / | — canalizar saída entre comandos (ex.: find --type link | grep login)
  • select <name> — selecionar uma opção de um dropdown <select> por valor ou texto visível
  • scroll — rolar a página ou um elemento específico (scroll down, scroll up, scroll <name>)
  • wait — aguardar um elemento específico aparecer (ex.: wait submit_btn bloqueia até que ele exista na árvore)
  • Loop for — iterar sobre linhas de saída de comando (ex.: for "find --type heading -n 3" : text {}) — substitui a iteração manual
  • Comando script — salvar e executar scripts de múltiplos comandos (ex.: script save scrape open url ; cd main ; text) para fluxos de trabalho repetíveis

Camada JavaScript

  • Comando js — executar JavaScript arbitrário no contexto da aba e retornar o resultado
  • functions + callfunctions [pattern] lista funções JS globais chamáveis com nome/aridade/parâmetros; call funcName arg1 arg2 as invoca. call é do nível de escrita.
  • eval <expr> — avaliação rápida de expressões (ex.: eval document.title, eval window.location.href)

Ergonomia para Agentes

  • Flag --text — mostrar pré-visualizações de texto visível inline com ls e find usando .innerText (somente texto renderizado, respeita a visibilidade CSS); comprimento configurável via --textlen N; cat também mostra VisibleText separadamente do textContent
  • Flag --meta — mostrar propriedades DOM (href, src, id, tag) inline com a saída de ls, find e read — essencial para extrair URLs sem chamadas cat separadas
  • Correspondência --content — pesquisar por conteúdo de texto visível com grep --content e find --content (ou find --text "pattern") — encontra elementos pelo que eles exibem, não apenas pelo nome AX
  • Resolução de caminhos — todos os comandos aceitam caminhos relativos (ex.: text main/article/paragraph, click form/submit_btn) — elimina idas e voltas cd desnecessárias
  • Navegação entre irmãos — flags --after/--before em ls para fatiar filhos relativos a um elemento de referência (ex.: ls --after heading --type link --meta)
  • Flag --links em text — incluir URLs de hiperlinks inline como [text](url) markdown na saída de texto; extrai tanto o conteúdo quanto os destinos dos links em uma única chamada (ex.: text --links main/paragraph)
  • Aliases de tipo difusos para findfind --type aceita aliases em linguagem natural (input, dropdown, nav, toggle, modal, image, btn, sidebar, etc.) que se expandem para papéis AX correspondentes — elimina chamadas de ferramenta desperdiçadas ao adivinhar nomes exatos de papéis
  • Cache de texto visível — cache preguiçoso para resultados de innerText, indexado por backendDOMNodeId, limpo na reconstrução da árvore — elimina chamadas CDP redundantes durante a correspondência --content em grep/find
  • bookmark / alias — salvar caminhos nomeados para navegação rápida (ex.: bookmark inbox ~/tabs/gmail/main/inbox_list, cd @inbox)
  • each (multi-aba) — executar um comando em várias abas (ex.: each --pattern wiki text para extrair texto de todas as abas da Wikipédia)
  • Modo de saída estruturada — flag --json em comandos para saída analisável por máquina (ex.: ls --json, cat --json, find --json, diff --json)
  • Persistência de sessão — salvar e restaurar o estado do shell (caminho, variáveis de ambiente, favoritos, histórico) entre reinicializações do service worker via chrome.storage.local
  • diff — comparar snapshots da árvore AX para ver o que mudou após uma ação (snapshots automáticos antes de clicar/enviar/navegar)
  • Isolamento de grupo de abas por sessão — as abas de cada sessão são colocadas em um grupo de abas do Chrome rotulado e cada comando é confinado a esse grupo, para que o agente trabalhe em sua própria faixa enquanto você continua navegando livremente em outras abas da mesma janela (#32)
  • DOMShell multi-sessão — cada console do painel lateral e cada conexão MCP obtém sua própria sessão de shell independente (seu próprio diretório atual, aba e cursor DOM), para que vários consoles humanos e agentes concorrentes trabalhem cada um em uma faixa isolada em vez de compartilhar um cursor global (#33)
  • Sessões declaradas por agente — um group_id opcional em domshell_execute permite que um agente se dirija a uma faixa específica: omita-o para a faixa atual, "new" para uma nova, ou passe um id para entrar em uma faixa existente — para que dois chats de agentes compartilhando uma conexão MCP permaneçam isolados, e um agente possa entregar uma sessão a outro (#34)

Plataforma

  • Navegador headless autônomo — distribuir o DOMShell como um processo Chromium headless autônomo (via Chrome for Testing ou Chromium incorporado) que os agentes iniciam diretamente — sem instalação de extensão, sem perfil do Chrome do usuário; apenas npx @apireno/domshell --headless e conectar via MCP. Ideal para pipelines de CI, automação no lado do servidor e fluxos de trabalho agente-em-loop onde um navegador visível não é necessário
  • Extensão para Firefox — portar para Firefox usando a API WebExtensions + protocolo de depuração remota
  • Backend Playwright/Puppeteer — alternativa à extensão do Chrome para fluxos de trabalho headless de agentes
  • Modo API REST — expor comandos do DOMShell via HTTP para integrações não-MCP
  • Build WASM — compilar o DOMShell para WebAssembly para que possa ser incorporado diretamente em um site para demonstrações interativas sem exigir instalação de extensão do Chrome

Experimentos

  • Nexa: DOMShell vs HTML bruto — mesmo modelo (Qwen3-4B), mesmas tarefas: compare a interface de texto/árvore AX do DOMShell com a raspagem de HTML bruto. Testes em ambos os backends nexa serve e Ollama. Encontrei uma interação cruzada: Ollama+DOMShell e Nexa+HTML são igualmente melhores (média de 1,20). Veja experiments/nexa_ollama/.
  • Nexa vs Claude (tamanho do modelo) — comparei Qwen3-1.7B/4B em tarefas progressivas. Limite de capacidade em T3 (extração de parágrafos). O 4B mostra melhor recuperação de erros. Veja experiments/nexa_claude/.
  • Disputa de modelos — comparei Qwen3-4B, Hermes3-3B, Granite4-Tiny, Llama3.2-3B em Ollama+DOMShell. Qwen3-4B continua sendo o melhor (8/15), único modelo a quebrar o limite T3. Llama3.2-3B em segundo lugar (7/15, zero alucinações). Veja experiments/model_shootout/.
  • Benchmark de custo de tokens — medir o total de tokens de entrada/saída por tarefa entre DOMShell e navegação baseada em captura de tela (CiC). Estender o experiments/claude_domshell_vs_cic/ existente com contagem de tokens. Hipótese: texto estruturado (2-3KB por resposta) vs capturas de tela em base64 (500KB+) deve mostrar economia de tokens >2x além da redução de 2x na contagem de chamadas já medida

Integrações

Nexa AI (LLM local)

Execute o DOMShell com modelos locais via nexa-sdk — automação de navegador totalmente no dispositivo, sem necessidade de API em nuvem. Usa o mesmo protocolo MCP do Claude Desktop, mas alimentado por inferência local (Granite-4-Micro, Qwen3, etc.).

python integrations/nexa/agent.py --task "Open wikipedia.org/wiki/AI and extract the first paragraph" --verbose

Veja integrations/nexa/ para configuração e uso.

Como Este Projeto Foi Construído

A especificação técnica do DOMShell foi escrita pelo Google Gemini, projetada como um prompt abrangente que poderia ser entregue diretamente a um agente de codificação para construir e estruturar todo o projeto do zero. A especificação original completa está preservada em intitial_project_prompt.md.

A implementação foi então construída pelo Claude (Anthropic) via Claude Code, trabalhando a partir dessa especificação.

Um projeto projetado por IA, construído por outra IA, destinado ao uso por agentes de IA. São agentes até o fim.

Links

Licença

MIT