Skip to content

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

GitHub stars GitHub forks GitHub issues Platform OpenCode NVIDIA NIM

opencode_termux

Tudo que você precisa para rodar OpenCode no Termux (Android) como um serviço web acessível de qualquer lugar via Cloudflare Tunnel, com notificação push.

Público-alvo: Android 14+ (arm64, MIUI/Xiaomi), Termux F-Droid + proot-distro Ubuntu. Testado com Poco X7 Pro, Android 14, MIUI HyperOS.


Estrutura do repositório

opencode_termux/
├── .config/opencode/              ← GLOBAL: skills, agentes, config (symlink de ~/.config/opencode)
│   ├── opencode.jsonc             ← config global do opencode
│   ├── skills/                    ← 50 skills (24 globais + 14 do obra/superpowers + 10 upstream + 2 unificadas)
│   │   ├── code-reviewer/
│   │   ├── executing-plans/
│   │   ├── design-system/
│   │   ├── frontend-complete/
│   │   ├── fastapi-expert/
│   │   └── ...
│   └── agents/                    ← subagentes (git-commit, code-review, task-planner, dev, task-build)
│       ├── git-commit.md
│       └── code-review.md
├── opencode.json                  ← config DO PROJETO (aponta para skills e agentes locais)
├── bin/
│   ├── opencode-web.sh             ← manager fire-and-forget (Cloudflare)
│   ├── opencode-web-stop.sh        ← stopper (Cloudflare)
│   ├── opencode-tailscale.sh       ← manager fire-and-forget (Tailscale)
│   ├── opencode-tailscale-stop.sh  ← stopper (Tailscale)
│   ├── termux-ssh.sh               ← inicia sshd + notifica IP
│   └── termux-ssh-stop.sh          ← para sshd
├── run-cloudflare-tunnel.sh       ← script executado dentro do proot (Cloudflare)
├── run-opencode-tailscale.sh      ← script executado dentro do proot (Tailscale)
├── shell/aliases.sh               ← aliases para bash
├── scripts/setup.sh               ← configuração inicial em qualquer device
├── docs/                          ← documentação de referência
│   ├── AGENTS_TEMPLATE.md         ← template de AGENTS.md para projetos
│   ├── MULTI_AGENT_ORCHESTRATION.md ← orquestração multi-agente
│   ├── SESSION_CONTEXT_20260618.md ← contexto da sessão de criação
│   ├── decisions/                 ← ADRs (decisões arquiteturais)
│   ├── proot-distro/
│   │   └── README.md              ← docs completas do proot-distro
│   ├── termux/
│   │   ├── filesystem-layout.md   ← paths, $PREFIX, $TMPDIR
│   │   ├── termux-notification.md ← API de notificações
│   │   └── ssh-sftp-access.md     ← referência SSH/SFTP
│   ├── tailscale/
│   │   └── README.md              ← docs completas do Tailscale
│   └── cloudflare/
│       ├── quick-tunnel.md        ← Quick Tunnel / TryCloudflare
│       ├── downloads.md           ← cloudflared arm64 .deb
│       ├── config-file.md         ← YAML config structure
│       └── run-parameters.md      ← tunnel run flags
├── AI_HANDOVER.md                 ← handover entre sessões
├── .env                           ← configurações reais
└── .env.example                   ← template de configuração

📌 Como funciona: ~/.config/opencode/ → symlink → opencode_termux/.config/opencode/ Skills e agentes vivem no repositório e são referenciados globalmente pelo symlink. Clone em qualquer device, rode bash scripts/setup.sh, e tudo funciona.

📖 Documentação completa: Para detalhes sobre orquestração de agentes, veja docs/MULTI_AGENT_ORCHESTRATION.md.


⚠️ Antes de começar — leia

  • Use o Termux da F-Droid, não o da Play Store (a versão Play é abandonada e quebra).
  • O ambiente Ubuntu via proot é obrigatório — o OpenCode CLI exige glibc, e o Termux nativo usa bionic.
  • pkg não funciona como root dentro do proot. Você instalará pacotes manualmente via dpkg -i com .deb baixados.
  • termux-notification não funciona em MIUI/Xiaomi (o app Termux:API não pode ser instalado). Este projeto usa ntfy.sh para notificações push, que funciona em qualquer Android.
  • O Cloudflare Tunnel é efêmero (Quick Tunnel). A URL muda a cada execução.
  • O Ctrl+C do opencode serve tem um bug conhecido (#21505) que impede o processo de terminar. Este projeto contorna isso com uma arquitetura Fire-and-Forget — o manager inicia e sai, deixando o serviço em background. Use opencode_web_stop para parar.

Tutorial passo a passo

1. Termux — setup inicial

Instale o Termux pela F-Droid.

Ao abrir pela primeira vez, atualize os pacotes:

pkg upgrade -y
pkg install proot-distro curl -y

2. Ubuntu via proot

proot-distro install ubuntu
proot-distro login ubuntu

Dentro do proot (usuário root), teste a rede:

curl -s https://ifconfig.me

3. Node.js inside proot

apt update && apt install nodejs npm -y
node -v
npm -v

4. OpenCode CLI

npm install -g opencode-linux-arm64 --force
ln -sf /data/data/com.termux/files/usr/lib/node_modules/opencode-linux-arm64/bin/opencode /data/data/com.termux/files/usr/bin/opencode
hash -r
opencode --version

Por que --force? O npm detecta o OS como "android" e bloqueia a instalação. --force contorna isso. Por que o symlink? O npm global no proot não adiciona o binário ao PATH. O symlink garante que opencode seja encontrado.

4.1. Primeira execução do OpenCode

Após instalar o OpenCode CLI (step 4), execute pela primeira vez:

opencode

Por que é lento?

O OpenCode usa SQLite como banco de dados local. Na primeira execução:

1. Criação do banco de dados

O banco é criado em: ~/.local/share/opencode/opencode.db

Se o diretório não existir, o OpenCode cria automaticamente.

2. Schema migrations (Drizzle ORM)

O OpenCode usa Drizzle ORM para gerenciar o schema do banco. Na primeira vez, ele executa migrations que criam tabelas como project, session, message, tool, participant, worktree, além de índices e journal de migrations.

3. Inicialização de plugins

O OpenCode baixa e inicializa oh-my-opencode (content checker) e verifica atualizações de plugins.

4. Carregamento de configuração

Lê ~/.config/opencode/opencode.json e opencode.json do diretório atual.


Quanto tempo leva?

Ambiente Tempo estimado
Desktop (Intel/AMD) 5-15 segundos
Termux (ARM64) 30-90 segundos
Termux (ARM64, 1ª vez) 2-5 minutos

O que você verá no terminal:

$ opencode
Loading configuration...
Performing one time database migration...
Database migration complete
Initializing plugins...
Loading models...
Ready.

Dicas importantes:

  1. Wake lock — Execute antes para evitar que Android suspenda:

    termux-wake-lock
  2. Não interrompa — NÃO feche o terminal nem pressione Ctrl+C durante a migração. Isso pode corromper o banco.

  3. Se travar — Se não houver progresso por mais de 2 minutos:

    pkill -f opencode
    rm ~/.local/share/opencode/opencode.db
    opencode
  4. Primeira vez vs subsequentes:

    • 1ª vez: 30-90s (migration + plugins)
    • 2ª vez: 2-5s (banco já existe)
    • Após update: 5-15s (nova migration se necessário)

Problemas comuns:

Problema Causa Solução
"Database is locked" Outro processo usando o banco pkill -f opencode e tente novamente
"Migration failed" Banco corrompido Delete opencode.db e reexecute
Timeout na inicialização Plugin não baixa Verifique conexão com internet

5. cloudflared

curl -LO https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb
dpkg -i cloudflared-linux-arm64.deb
cloudflared version

6. Sair do proot e clonar o repositório

exit  # sai do proot

De volta ao Termux nativo:

git clone <url-do-repositorio> opencode_termux
cd opencode_termux

7. Rodar o setup

bash scripts/setup.sh

O que setup.sh faz:

  1. Faz backup de ~/.config/opencode/ existente (se não for symlink)
  2. Cria symlink: ~/.config/opencode/ → opencode_termux/.config/opencode/
  3. Instala dependências npm do .config/opencode/
  4. Instrui sobre aliases

Isso torna skills e agentes disponíveis globalmente para todos os projetos.

8. Configurar aliases

Adicione ao ~/.bashrc do Termux nativo (não dentro do proot):

echo 'source /root/Projetos/opencode_termux/shell/aliases.sh' >> ~/.bashrc
source ~/.bashrc

9. Copiar .env e ajustar

cp .env.example .env
# edite NTFY_TOPIC, PROJECT_DIR se necessário

10. Primeira execução

opencode_web

O que acontece:

  1. O script manager adquire wake lock (impede o Android de dormir)
  2. Inicia proot-distro login ubuntu --shared-tmp rodando run-cloudflare-tunnel.sh
  3. Dentro do proot: opencode web → cloudflared tunnel → ntfy.sh push
  4. A URL pública aparece no terminal e chega como notificação no Android
  5. O manager sai — o serviço fica rodando em background (PID salvo)

Para parar:

opencode_web_stop

Para ver o status (manual):

cat $PREFIX/tmp/opencode_web.pid   # PID
cat $PREFIX/tmp/opencode_url.txt   # URL ativa

Acesso SSH/SFTP ao Termux

Acesse os arquivos do Termux via SSH/SFTP usando o Termius ou qualquer cliente SSH.

Instalar openssh

pkg install openssh -y

Configurar senha

passwd

Iniciar sshd

termux_ssh

O que acontece:

  1. Verifica se openssh está instalado
  2. Inicia sshd na porta 8022
  3. Detecta o IP do dispositivo
  4. Envia notificação push com o comando SSH formatado
  5. No Termius, cole o comando: ssh root@<IP> -p 8022

Parar sshd

termux_ssh_stop

Configuração no Termius

  1. Abra o Termius → New Host
  2. Preencha:
    • Hostname: <IP do dispositivo>
    • Port: 8022
    • Username: root
    • Password: (a senha que você definiu com passwd)
  3. Salve e conecte

Acessar via SFTP

No Termius, após conectar via SSH:

  • Clique no ícone SFTP na barra lateral
  • Navegue pelos diretórios do Termux

Ou use um cliente SFTP separado (FileZilla, WinSCP) com as mesmas credenciais.

Caminhos acessíveis

Caminho Descrição
$HOME (~) Diretório home do Termux
$PREFIX/tmp Temp (limpo ao reiniciar)
/sdcard Armazenamento interno do Android
/storage/emulated/0 Armazenamento compartilhado

⚠️ Limitação: $PREFIX/tmp é apagado ao reiniciar o Termux. Para arquivos persistentes, use ~/storage após rodar termux-setup-storage.


Arquitetura

Camada de config — symlink global

~/.config/opencode/  ──symlink──►  opencode_termux/.config/opencode/
                                         │
                                      skills/ (50 skills)
                                    agents/ (git-commit.md, code-review.md, task-planner.md, dev.md, task-build.md)
                                    opencode.jsonc

Todos os projetos enxergam skills e agentes via ~/.config/opencode/

Camada de execução — Termux → proot

Termux (nativo)                     proot (Ubuntu)
────────────────────────────────────────────────────
opencode-web.sh  ──proot──►  run-cloudflare-tunnel.sh
(fire-and-forget)                   ├── opencode web (porta 4096)
                                    ├── cloudflared tunnel
                                    └── curl ntfy.sh (notificação)
                                    │
                              notify_file (/tmp/opencode_url.txt)
                                    │
                              ┌─────┘
                              ▼
                     ntfy push (notificação remota)
                     termux-notification (local, best-effort)

Fluxo

Passo Quem O que faz
1 opencode-web.sh Adquire wake lock, inicia proot com --shared-tmp
2 proot + run-cloudflare-tunnel.sh Sobe opencode web em 127.0.0.1:4096
3 proot Sobe cloudflared tunnel --url http://127.0.0.1:4096
4 proot Extrai URL do log do cloudflared, escreve em /tmp/opencode_url.txt
5 proot Envia notificação ntfy.sh com a URL
6 opencode-web.sh Lê o notify file (via --shared-tmp), mostra a URL no terminal, tenta termux-notification (best-effort)
7 opencode-web.sh Sai — serviço continua em background

Por que Fire-and-Forget?

O opencode serve (e o opencode web) têm um bug conhecido onde Ctrl+C não termina o processo (#21505), e o processo deixa órfãos (#20899). Com Fire-and-Forget:

  • O manager não aguarda o proot — usa nohup + disown + PID file
  • O stop é feito por um script dedicado (opencode-web-stop.sh) que mata o proot graceful → force e limpa processos órfãos/zumbis por padrão
  • Sem traps, sem raw mode, sem travamentos de terminal

Skills e Subagentes

50 skills em .config/opencode/skills/ (24 globais + 14 do obra/superpowers + 10 upstream + 2 unificadas), além de customize-opencode (built-in do opencode, sem diretório).

Agente Modo Responsabilidade
task-build primary Orquestra pipelines completas
task-planner subagent Planeja tasks antes da implementação
dev subagent Implementa código
code-review subagent Revisa código
git-commit subagent Cria commits semânticos

Prompts dos 5 agentes reforçados em 19–21/08/2026 (58fc4ea, 609d579, 68e2b11, 825294a, 5a1bf2b) — detalhes em docs/MULTI_AGENT_ORCHESTRATION.md.

Nota: customize-opencode é built-in do opencode (sem diretório em skills/)

Skills obrigatórias: executing-plans, systematic-debugging, verification-before-completion, plan-reviewer — carregadas automaticamente pelo agent task-build.

Regra: Code review é obrigatório antes de cada commit (individual + consolidado).

Subagentes: git-commit, code-review, task-planner, dev, task-build (prompts em .config/opencode/agents/). Lista completa: opencode.json permission.skill e docs/SESSION_CONTEXT_20260618.md.


Referência

bin/opencode-web.sh

Manager fire-and-forget. Inicia, notifica e sai.

Variáveis (via .env ou env var):

Variável Default Descrição
OPENCODE_PORT 4096 Porta local do OpenCode Web
OPENCODE_HOSTNAME 127.0.0.1 Hostname do opencode web (usar 127.0.0.1 dentro do proot — 0.0.0.0 crasha com getifaddrs)
NTFY_TOPIC opencode-tunnel Tópico ntfy.sh para notificação
PROJECT_DIR diretório do script Onde está run-cloudflare-tunnel.sh
NOTIFY_FILE $PREFIX/tmp/opencode_url.txt Arquivo de handoff da URL
PID_FILE $PREFIX/tmp/opencode_web.pid Arquivo do PID
LOG_FILE $PREFIX/tmp/opencode_web.log Log da execução no proot

bin/opencode-web-stop.sh

Para o serviço e limpa processos órfãos/zumbis.

  1. Carrega .env via $SCRIPT_DIR com defaults (OPENCODE_PORT=4096, OPENCODE_HOSTNAME=127.0.0.1) — usa as mesmas variáveis do bin/opencode-web.sh (vide tabela acima).
  2. Mata o proot graceful → force: SIGTERM, espera 3×1s checando se virou zumbi, depois SIGKILL se ainda vivo.
  3. Limpeza de órfãos — roda sempre (mesmo sem PID file): run-cloudflare-tunnel.sh + processo na porta do OpenCode + cloudflared tunnel (match por padrão com a porta).
  4. Nunca usa pkill -f "opencode web" — risco de matar a sessão TUI.
  5. Verificação final: zumbis → log INFO (serão reaped pelo init), vivos → log WARN.
  6. Cleanup: remove PID file, notify file, log file; executa stty sane e termux-wake-unlock.

run-cloudflare-tunnel.sh

Executado dentro do proot. Sobe opencode web + cloudflared tunnel + ntfy.sh push.

shell/aliases.sh

Define os aliases opencode_web, opencode_web_stop, opencode_tailscale, opencode_tailscale_stop, termux_ssh, termux_ssh_stop e limpar_opencode.

bin/termux-ssh.sh

Inicia o serviço SSH do Termux para acesso remoto.

Variáveis (via .env ou env var):

Variável Default Descrição
NTFY_TOPIC opencode-tunnel Tópico ntfy.sh para notificação
SSH_PORT 8022 Porta do sshd
SSHD_PID_FILE $PREFIX/tmp/termux_sshd.pid Arquivo do PID

bin/termux-ssh-stop.sh

Para o serviço sshd: kill graceful → kill -9 → cleanup.


NVIDIA NIM — Modelos gratuitos

O OpenCode suporta NVIDIA NIM como provedor de inferência com tier gratuito (sem billing por token, ~40 requests/minuto).

Configuração rápida

  1. Obtenha uma API key em build.nvidia.com (conta gratuita)

  2. No OpenCode, use o comando /connect:

    /connect nvidia
    
  3. Ou configure manualmente em opencode.json do seu projeto:

    {
      "$schema": "https://opencode.ai/config.json",
      "provider": {
        "nvidia": {
          "options": {
            "baseURL": "https://integrate.api.nvidia.com/v1"
          }
        }
      }
    }
  4. Defina a variável de ambiente (dentro do proot):

    export NVIDIA_API_KEY="nvapi-xxx..."

Modelos populares (gratuitos)

Modelo Descrição
meta/llama-3.1-70b-instruct Geral, bom custo-benefício
nvidia/nemotron-70b-instruct Instruções complexas
deepseek/deepseek-v4-flash Rápido, respostas curtas

Plugin de sincronização (opcional)

Para auto-sincronizar modelos disponíveis:

opencode plugin nim-sync -g

Nota: O tier gratuito tem limite de ~40 requests/minuto. Para uso intenso, considere um plano pago em build.nvidia.com.


FAQ

Pergunta Resposta
O opencode não abre o navegador sozinho? Sim, o CLI tenta abrir o navegador. No Termux isso falha silenciosamente. Use a URL do tunnel.
Como saber a URL atual? No momento da inicialização ela aparece no terminal e chega por ntfy.sh. Depois, cat $PREFIX/tmp/opencode_url.txt.
O que é --shared-tmp? Faz o /tmp do proot compartilhar o mesmo diretório do Termux nativo ($PREFIX/tmp), permitindo que o manager leia o notify file.
termux-wake-lock falha? Instale termux-api (F-Droid) ou ignore — o wake lock não é estritamente necessário.
O tunnel caiu e não sobe de novo? opencode_web_stop primeiro, depois opencode_web novamente (o stop agora limpa órfãos/zumbis por padrão).
opencode web vs opencode serve? Ambos funcionam. web é a interface web (recomendado). serve expõe via SSE.
Como mudar a porta? Edite .env: OPENCODE_PORT=8080.
Posso rodar sem cloudflared? Sim, mas o acesso será apenas local (http://127.0.0.1:4096). Edite run-cloudflare-tunnel.sh e remova o cloudflared.
Preciso de API key da Anthropic? Não necessariamente — use NVIDIA NIM (gratuito), OpenAI, ou outros provedores via /connect. Veja seção NVIDIA NIM.
Como usar NVIDIA NIM (gratuito)? Obtenha API key em build.nvidia.com, use /connect nvidia no OpenCode ou configure provider.nvidia em opencode.json.
Posso usar outros provedores além da Anthropic? Sim — OpenCode suporta OpenAI, Google Gemini, NVIDIA NIM, e outros via /connect. Configure o provider em opencode.json.
Como mudar de modelo? No OpenCode Web, use o seletor de modelo na UI. Ou edite opencode.json → campo model.
Como acessar os arquivos do Termux via SSH? Instale openssh, configure senha com passwd, rode termux_ssh. Conecte com Termius na porta 8022.
O SSH funciona com SFTP? Sim — use o Termius ou qualquer cliente SFTP com as mesmas credenciais (IP, porta 8022, root, senha).
Preciso de IP fixo? Não — o script detecta o IP automaticamente e envia via notificação push.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages