npm package: @leg3ndy/otto-bridge
Description: Local companion for Otto Bridge device pairing and WebSocket runtime.
Latest version: 1.1.8

# Otto Bridge

Companion local do Otto para:

- reivindicar um codigo de pareamento gerado pela web
- armazenar o `device_token` do dispositivo
- manter um WebSocket persistente com o backend
- executar jobs locais com executor proprio do Otto no macOS, `mock` ou `clawd-cursor`

## Guia de uso

Para um passo a passo de instalacao, pareamento, uso, desconexao e desinstalacao, veja [USER_GUIDE.md](https://github.com/LGCYYL/ottoai/blob/main/otto-bridge/USER_GUIDE.md).

Para o estado atual da arquitetura, capacidades entregues, limitacoes e roadmap do Otto Bridge, veja [`leg3ndy-ai-backend/docs/otto-bridge/OTTO_BRIDGE_ARCHITECTURE.md`](../leg3ndy-ai-backend/docs/otto-bridge/OTTO_BRIDGE_ARCHITECTURE.md).

Para o corte de arquitetura do `0.9.0`, veja [`leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_0_9_0_RELEASE.md`](../leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_0_9_0_RELEASE.md).

Para o patch atual `1.1.8`, veja [`leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_1_8_PATCH.md`](../leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_1_8_PATCH.md). Para o corte funcional da linha `1.1.0`, veja [`leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_1_0_RELEASE.md`](../leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_1_0_RELEASE.md).

## Distribuicao

Fluxo recomendado agora:

1. publicar como pacote npm privado/publico para time interno e beta testers
2. validar pareamento, atualizacao e telemetria em ambiente real
3. depois empacotar em `.dmg/.pkg` no macOS e `.msi` no Windows

O pacote ja esta estruturado para install via CLI:

```bash
npm install -g @leg3ndy/otto-bridge
otto-bridge
otto-bridge status
otto-bridge version
```

Enquanto o pacote nao estiver publicado, voce pode gerar um tarball local:

```bash
npm pack
npm install -g ./leg3ndy-otto-bridge-1.1.8.tgz
```

Na linha `1.1.8`, `playwright` segue como dependencia obrigatoria no `otto-bridge`. O primeiro `npm install -g @leg3ndy/otto-bridge` pode demorar mais porque instala o browser persistente usado pelo WhatsApp Web e pelos fluxos web em background do bridge.

No macOS, a linha `1.1.8` usa o provider `macos-helper`, um helper `WKWebView` sem Dock para o WhatsApp Web. O helper sobe com user-agent de Chrome moderno para evitar o bloqueio do WhatsApp ao detectar Safari/WebKit. O runtime antigo com Chromium/Playwright fica disponivel apenas como override explicito via `OTTO_BRIDGE_WHATSAPP_RUNTIME_PROVIDER=embedded-playwright`.

No nivel arquitetural, o `0.9.0` marcou a mudanca de papel do bridge: ele publica tools e resultados estruturados para o Otto, em vez de injetar resposta pronta como caminho principal do chat. O `1.0.0` oficializou isso como runtime agentico; o `1.1.8` mantem a camada workspace-first com rail de coding, trust/policy por workspace, source control first-class, working set persistido e grounding remoto por repositório, enquanto endurece o `Otto Console`, evita que `otto-bridge update` dispare setup interativo no meio da autoatualizacao e faz o scroll por wheel/trackpad funcionar no Terminal.app sem reativar click tracking.

## Publicacao

Checklist de release:

```bash
npm whoami
npm install
npm run release:check
npm publish --access public
```

O publish exige permissao no scope `@leg3ndy`.

Se o seu `npm` local estiver com cache travado por permissao, rode com cache temporario:

```bash
npm_config_cache=/tmp/otto-npm-cache npm run release:check
npm_config_cache=/tmp/otto-npm-cache npm publish --access public
```

## Comandos

### Listar ajuda

```bash
otto-bridge help
otto-bridge --help
```

### Abrir o hub interativo e ligar o runtime

```bash
otto-bridge
```

Em TTY, o comando sem argumentos agora abre o hub interativo com banner, setup, status, extensoes e o `Otto Console`. Se ja existir pairing salvo, o próprio `otto-bridge` sobe o runtime local automaticamente e mostra o estado da conexão no hub.

Na web, o acesso ao Otto Bridge fica no botao com icone de estrela/brilho ao lado do botao de anexos.

### Setup interativo

```bash
otto-bridge setup
```

Esse fluxo pede `API base URL`, `pairing code`, nome do dispositivo e executor. Em install global interativo, o pacote tambem tenta abrir esse setup automaticamente quando ainda nao existe pairing salvo.

O `pairing code` e gerado no modal do Otto Bridge aberto pela interface web, no botao com icone de estrela ao lado de anexos.

### Parear o dispositivo

```bash
otto-bridge pair --api http://localhost:8000 --code ABC123
```

Opcoes suportadas:

- `--name`: nome amigavel do dispositivo
- `--timeout-seconds`: limite de espera pela aprovacao web
- `--poll-interval-ms`: intervalo de polling do claim
- `--executor`: `native-macos`, `mock` ou `clawd-cursor`
- `--clawd-url`: base URL da API local do `clawd-cursor`
- `--clawd-poll-interval-ms`: polling do status/logs do `clawd-cursor`

No macOS, o caminho recomendado agora e o executor nativo do Otto Bridge. Se nenhum `--executor` for informado, o `pair` usa `native-macos` por padrao no Mac.

### Runtime principal do bridge

```bash
otto-bridge
```

Esse agora e o fluxo principal do produto: o hub abre, conecta o runtime local e deixa o Otto pronto para handoff e approvals sem depender de nenhum comando separado de runtime.

Se precisar do executor nativo no macOS sem reparar, atualize o pairing/config e reabra o hub:

```bash
otto-bridge setup
```

O adapter `clawd-cursor` continua disponivel como override opcional no pairing legado:

```bash
otto-bridge pair --executor clawd-cursor --clawd-url http://127.0.0.1:3847
```

### Falar com o Otto no terminal

```bash
otto-bridge console
```

O console usa a mesma sessão local já ligada pelo `otto-bridge`, envia prompts naturais ao backend usando `device_token`, respeita quota/plano do usuário e só vira handoff local quando o pedido realmente tiver cara de ação no computador. Quando houver `device_job`, ele acompanha polling e resolve `confirm_required` no terminal.

Dentro do console, use:

- `/model fast` para `OttoAI Fast`
- `/model thinking` para `OttoAI Thinking`
- `/approval preview`, `/approval confirm` ou `/approval trusted` para trocar o modo de aprovação do device
- `/status` para ver detalhes técnicos do bridge e do runtime
- `/workspace` ou `/workspace status` para ver o workspace ativo desta sessão
- `/workspace list` para listar workspaces anexados ao device
- `/workspace attach <path>` para anexar uma pasta/repo novo pelo helper autenticado
- `/workspace use <id|n>` para fixar um workspace anexado na sessão atual
- `/workspace clear` para limpar o binding atual do chat/sessão
- `/new` para iniciar uma nova sessão e limpar o contexto local do console

No TTY, o console agora entra em `alternate screen` ao abrir o `Otto Console`, para esconder o scrollbar manual/nativo do terminal e deixar só a viewport interna do Otto. O header é impresso uma vez no topo da sessão, o transcript continua completo dentro da tela do console e o composer fica preso no rodapé com placeholder `Peça algo ao Otto`. Ao digitar `/`, o bridge abre uma palette navegável por setas, com `Enter` preenchendo comandos como `/new` para iniciar uma nova sessão local. Wheel/trackpad usam `alternate scroll` do terminal para navegar o transcript como setas; `PageUp/PageDown` continuam funcionando e cliques deixam de ser reportados como input do console.

No modo `OttoAI Thinking`, o terminal agora marca explicitamente o trecho de raciocínio com `Pensando (OttoAI Thinking)` e separa esse bloco da resposta final do Otto.

Quando o handoff local devolver resultado estruturado, o CLI agora mostra inline a listagem de arquivos e o conteúdo de `read_file`, em vez de só resumir que executou a tarefa.

### Abrir um shell local pelo hub

```bash
otto-bridge terminal
```

Esse comando abre um shell local interativo para instalar extensoes, rodar comandos externos e fazer operacao manual sem encerrar o bridge. No hub principal, a opcao `Terminal` faz a mesma coisa e volta ao menu quando voce sair com `exit`.

### WhatsApp Web em background

Fluxo recomendado na linha `1.1.8`:

```bash
otto-bridge extensions --install whatsappweb
otto-bridge extensions --setup whatsappweb
otto-bridge extensions --status whatsappweb
```

O setup agora abre o login do WhatsApp Web no helper/background browser do proprio bridge. Depois do QR code, o Otto usa a sessao local em background, sem depender de aba visivel no Safari.

Contrato da linha `1.1.8`:

- `otto-bridge extensions --setup whatsappweb`: autentica a sessao uma vez
- `otto-bridge`: mantem o browser persistente do WhatsApp vivo em background enquanto o runtime do hub estiver ativo, sem depender de uma aba aberta no Safari
- ao fechar o `otto-bridge`: o browser em background e desligado, mas a sessao local fica lembrada para o proximo boot

## Handoff rapido da linha 1.1.8

Ja fechado no codigo:

- provider `macos-helper` dockless no macOS como runtime padrao do WhatsApp
- user-agent do helper ajustado para evitar bloqueio do WhatsApp por detecao de Safari/WebKit
- resultado final dos `device_job` agora e persistido como contexto mais forte para o proximo turno do Otto
- prompt bridge-aware no chat normal para ajudar o Otto a responder com base no que realmente aconteceu no device
- runtime local agora publica `local_tools` para o Otto/backend saberem exatamente o que o device consegue fazer
- o runtime agentico agora executa `execution_graph` granular por acao, em vez de colapsar a corrida local inteira num unico `tool_call`
- o protocolo do runtime agora publica `graph_id`/`step_id` nos eventos de job e aceita controles por step para confirmacao/cancelamento
- o executor `native-macos` agora reporta o step atual por acao e publica inline artifacts estruturados para resultados locais nao-uploadados
- o `runtime_contract` agora pode declarar `workspace_context` com roots/targets e descriptors de `instruction_bundle`, `repo_manifest`, `workspace_index`, `workspace_memory` e `workspace_policy` para jobs de arquivo e shell
- o bridge agora resolve `workspace_context` em paths absolutos, detecta `repo_root`, carrega `AGENTS.md` por precedencia e publica `instruction_bundle`, `repo_manifest`, `workspace_index`, `workspace_memory` e `workspace_policy` no resultado
- workspaces anexados pelo modal web agora tambem viram parte do metadata do helper: o `otto-bridge` consulta `/v1/devices/runtime/workspaces` com `device_token`, sonda localmente `repo_root`, `branch` e a cadeia de `AGENTS.md` antes do `device.hello`, e reage a `device.metadata.refresh` para republicar esse snapshot quando o usuario anexa/remove um workspace com o bridge online
- filesystem e shell locais agora respeitam os roots declarados do workspace, em vez de operar como superficie global quando o job vier escopado
- `workspace_policy` agora aplica perfis `observe_only`, `dev_assist`, `workspace_coding` e `release_operator` antes da execucao local de actions escopadas
- cada workspace anexado agora tambem persiste o proprio `policy_profile_id`; o modal do Otto Bridge permite trocar esse perfil, o banner do chat mostra o trust atual e o runtime trata esse valor como teto real da sessao antes de shell, patch, delete ou release
- `write_json_file`, `mkdir`, `move_file` e `delete_file` agora fazem parte da familia inicial de file ops tipadas do workspace
- `workspace.patch`, `git.clone`, `git.fetch`, `git.checkout`, `git.rebase`, `git.merge`, `git.tag`, `git.status`, `git.diff`, `git.stage`, `git.commit`, `git.push` e `workspace.tests` agora fazem parte da primeira familia tipada de coding agent do catalogo local
- `apply_patch`, `git_status`, `git_diff`, `run_tests`, `git_clone`, `git_fetch`, `git_checkout`, `git_rebase`, `git_merge`, `git_tag`, `git_add`, `git_commit` e `git_push` agora executam dentro do workspace escopado e devolvem snapshots estruturados em vez de shell cru
- `apply_patch` entende o formato `*** Begin Patch ... *** End Patch`, devolve `patch_set` estruturado e continua bloqueando paths fora do workspace permitido
- `run_tests` agora aceita `command` explicito ou `profile` tipado (`pytest`, `npm_test`, `pnpm_test`, `yarn_test`, `bun_test`, `lint`, `build`) e devolve `resolved_command` no snapshot final
- `git_clone`, `git_fetch`, `git_checkout`, `git_rebase`, `git_merge`, `git_tag`, `git_add`, `git_commit` e `git_push` sobem com `requires_confirmation`, devolvem receipts estruturados (`git_clone_receipt`, `git_fetch_receipt`, `git_checkout_receipt`, `git_rebase_receipt`, `git_merge_receipt`, `git_tag_receipt`, `git_stage_receipt`, `git_commit_receipt`, `git_push_receipt`) e tratam `nothing_to_commit` / `Everything up-to-date` como resultado observavel do job
- `repo_manifest` e `workspace_index` agora saem com `scoped_root_path`, manifests/lockfiles, key files e extensoes dominantes para grounding leve de repo
- `workspace_memory` agora reaproveita o historico recente do mesmo `workspace_id` e volta atualizada no resultado do job para grounding curto entre execucoes
- `workspace_memory` agora tambem respeita governanca persistida no backend, com `retention_days`, `retention_job_limit`, `last_cleared_at` e `last_cleared_reason`, que o modal do Otto Bridge pode ajustar sem sair do runtime
- automacoes locais do canal `bridge` agora disparam `/v1/devices/automations/local/bridge/trigger` em cada tick, reaproveitando o mesmo runtime agentico do chat com `device_job`, approvals e replay auditaveis
- o `runtime_contract` agora tambem pode declarar `worker_profiles`, e o executor ecoa esse bundle em `worker_profiles`/artifact para deixar explicito quais perfis de leitura, mudanca, validacao e release foram ativados no job
- o `execution_graph` agora pode marcar `worker_id` por step, e o `runtime_contract` tambem pode declarar `worker_execution` com `budget_seconds`, `timeout_seconds`, `retry_limit` e `max_parallel_tasks` por worker para preparar fan-out controlado
- o backend agora deriva `runtime_workers` e `runtime_handoffs` persistidos do mesmo graph, incluindo `worker_run_id`, `fanout_level/wave/group` e retry por worker a partir de `retry_of_worker_run_id` / `retry_attempt`
- `git_diff` agora carrega `stat` e `diff_excerpt`, e o backend usa isso para grounding mais estrito de respostas sobre diff longo
- o `runtime_contract` agora tambem declara `command_packs` formais (`plan-fast`, `plan-deep`, `instruction-updater`), e o bridge ecoa esses modos como artifact estruturado para deixar claro qual intensidade de planejamento/manutencao foi aplicada no job
- o `instruction_updater` agora e um descriptor explicito do runtime, com `source_entrypoints`, `target_paths` e `recommended_validation_stage_ids` quando o plano toca `AGENTS.md`, `README.md` ou `docs/`
- `workspace.tests` agora consegue resolver `profile=auto` via `validation_ladder`, executando stages como `typecheck`, `build`, `node_test`, `lint` e `pytest` por stack, com snapshot agregado por etapa
- o executor `native-macos` agora publica `runtime_hook_trace` somando hooks de lifecycle e tool-use (`session_start`, `pre_tool_use`, `post_tool_use`, `validation_ladder_started/completed`, `session_end`), preparando enforcement, replay fino e metricas futuras
- o frontend agora consome `runtime_hook_trace`, `runtime_replay` e o progresso corrente como feed inline persistente no chat, para o usuario ver o Otto lendo, procurando, editando, validando e concluindo em tempo real
- o chat web agora mostra esse plano/checklist acima do input enquanto o job local roda, e deixa o bloco detalhado de runtime apenas para o resultado final quando houver detalhe real de arquivo/diff/source control/validacao/erro
- o catalogo local agora inclui `filesystem.open_path`, usado para abrir um arquivo/pasta local no app padrao do macOS ou revelar no Finder a partir dos links clicaveis do timeline
- o modal do Otto Bridge agora mostra `Jobs locais` em resumo textual, `Snapshot do workspace` com source control/validacao/working set e links de path que disparam `open_path` local, sem repetir a timeline detalhada do chat
- o bridge agora possui um CLI interativo proprio com setup inicial, hub terminal e `Otto Console` para conversar com o Otto pelo proprio terminal
- o backend agora expoe caminhos `device-auth` para o console do bridge usar chat com quota/plano (`/v1/devices/cli/chat/completions`) e acompanhar approval/job usando apenas `device_token`
- o caminho principal do bridge usa `summary`/`narration_context` no lugar de resposta automatica pronta
- `read_file` agora entrega conteudo completo segmentado em `content_chunks` para o Otto
- `list_files` sem `limit` agora lista o diretorio inteiro, sem fallback silencioso para 40 itens
- o planner do bridge prioriza o modelo para escolher a tool certa pelo contexto; regex fica como fallback

### Testes locais do runtime

```bash
npm run test:runtime
```

Ainda precisa reteste em campo:

- fluxo completo do WhatsApp no helper `macos-helper`
- confirmacao de que o helper realmente passa do gate de compatibilidade do WhatsApp
- perguntas de follow-up como `o que voce mandou?` depois de uma acao local de mensagem

### Ver estado local

```bash
otto-bridge status
```

### Ver versao instalada

```bash
otto-bridge version
otto-bridge --version
```

### Atualizar o pacote

Atualizacao automatica via npm:

```bash
otto-bridge update
```

Para apenas ver qual comando sera executado:

```bash
otto-bridge update --dry-run
```

Para instalar manualmente:

```bash
npm install -g @leg3ndy/otto-bridge@latest
```

### Remover pareamento local

```bash
otto-bridge unpair
```

## Variaveis de ambiente

- `OTTO_API_BASE_URL`
- `OTTO_BRIDGE_HOME`
- `OTTO_BRIDGE_NAME`
- `OTTO_BRIDGE_EXECUTOR`
- `OTTO_CLAWD_BASE_URL`
- `OTTO_CLAWD_POLL_INTERVAL_MS`

## Payload esperado para jobs desktop

Os executores locais do Otto Bridge procuram a tarefa em uma destas chaves, nessa ordem:

- `task`
- `prompt`
- `instruction`
- `instructions`
- `message`

O executor nativo do macOS tambem aceita payload estruturado em `actions[]`, por exemplo:

```json
{
  "job_type": "desktop_actions",
  "payload": {
    "actions": [
      { "type": "open_app", "app": "Safari" },
      { "type": "open_url", "url": "https://www.youtube.com", "app": "Safari" }
    ]
  }
}
```

Exemplo:

```json
{
  "job_type": "desktop_task",
  "payload": {
    "task": "Abra o Safari e pesquise Otto AI"
  }
}
```