Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Ralph iteration 1: work in progress
  • Loading branch information
IsraelAraujo70 committed Feb 13, 2026
commit f713781e36c31690c4eea8d4dc2845df8919db5f
10 changes: 4 additions & 6 deletions .ralph/ralph-history.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
"iterations": [
{
"iteration": 1,
"startedAt": "2026-02-13T00:01:28.721Z",
"endedAt": "2026-02-13T00:01:38.534Z",
"durationMs": 4807,
"startedAt": "2026-02-13T00:01:58.908Z",
"endedAt": "2026-02-13T00:02:05.853Z",
"durationMs": 1943,
"toolsUsed": {},
"filesModified": [
".ralph/",
"packages/opencode/test/auth/",
"packages/console/app/public/email"
],
"exitCode": 0,
Expand All @@ -19,7 +17,7 @@
]
}
],
"totalDurationMs": 4807,
"totalDurationMs": 1943,
"struggleIndicators": {
"repeatedErrors": {
"ProviderModelNotFoundError: ProviderModelNotFoundError": 1,
Expand Down
2 changes: 1 addition & 1 deletion .ralph/ralph-loop.state.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"tasksMode": false,
"taskPromise": "READY_FOR_NEXT_TASK",
"prompt": "\n# Plano Completo: Multi-Auth para OpenCode\n\n## 1. Objetivo\n\nPermitir multiplas contas por provider no OpenCode (exemplo: `openai/work` e `openai/personal`) com:\n\n- troca rapida de conta ativa\n- selecao explicita por projeto/sessao quando necessario\n- compatibilidade total com formato legado de credenciais\n- zero regressao para usuarios com uma unica conta\n\n## 2. Problema Atual\n\nHoje o armazenamento de auth eh indexado por `providerID` com apenas uma credencial por provider.\nIsso impede cenarios comuns:\n\n- separar conta pessoal e conta corporativa no mesmo provider\n- alternar billing sem relogar\n- padronizar por projeto (repo A usa `work`, repo B usa `personal`)\n\n## 3. Escopo\n\n### Em escopo\n\n- novo modelo de dados para auth com contas nomeadas\n- comandos CLI para gerenciar contas\n- interface no TUI/app para trocar conta ativa sem depender apenas de CLI\n- selecao de conta no runtime com regras de precedencia\n- migracao compativel com auth legado\n- testes unitarios e de integracao de fluxo principal\n- documentacao de uso e troubleshooting\n\n### Fora de escopo (fase inicial)\n\n- sincronizacao cloud de multiplas contas\n- politicas de equipe via servidor remoto (pode vir na fase 2)\n\n## 4. Requisitos Funcionais\n\n1. Cadastrar varias contas para o mesmo provider.\n2. Definir conta default por provider.\n3. Trocar conta default sem novo login.\n4. Selecionar conta por projeto/sessao via config/env.\n5. Listar contas e visualizar qual esta ativa.\n6. Remover conta especifica sem apagar as demais.\n7. Remover provider inteiro quando desejado.\n8. Ler auth legado sem erro.\n9. Ter interface no TUI/app para selecionar e trocar conta ativa por provider.\n\n## 5. Requisitos Nao Funcionais\n\n1. Backward compatibility total.\n2. Armazenamento local com permissao `0600`, igual ao comportamento atual.\n3. Sem uso de `any`.\n4. Sem degradar tempo de inicializacao de forma perceptivel.\n5. Cobertura de testes para paths criticos (legacy + novo).\n6. Build e typecheck devem passar ao final da implementacao.\n\n## 6. Arquitetura Proposta\n\n### 6.1 Modelo de dados (auth.json v2)\n\nFormato proposto:\n\n```json\n{\n \"openai\": {\n \"default\": \"work\",\n \"accounts\": {\n \"work\": {\n \"type\": \"oauth\",\n \"access\": \"...\",\n \"refresh\": \"...\",\n \"expires\": 1769999999,\n \"accountId\": \"org_work\"\n },\n \"personal\": {\n \"type\": \"api\",\n \"key\": \"sk-...\"\n }\n }\n },\n \"anthropic\": {\n \"default\": \"default\",\n \"accounts\": {\n \"default\": {\n \"type\": \"api\",\n \"key\": \"...\"\n }\n }\n }\n}\n```\n\n### 6.2 Compatibilidade com legado\n\nFormato legado atual:\n\n```json\n{\n \"openai\": { \"type\": \"api\", \"key\": \"...\" }\n}\n```\n\nRegra:\n\n- leitura: se valor de provider estiver no formato legado, tratar em memoria como:\n - `default = \"default\"`\n - `accounts.default = <credencial_legada>`\n- escrita: qualquer mutacao salva no formato v2\n\n### 6.3 Schema em codigo\n\nArquivo principal: `packages/opencode/src/auth/index.ts`\n\nAdicionar:\n\n- `Auth.Accounts` (objeto com `default` e `accounts`)\n- `Auth.Storage` (record provider -> Accounts)\n- parser que aceite `Info | Accounts` no input e normalize para `Accounts`\n\n## 7. API Interna de Auth\n\nEvolucao da namespace `Auth`:\n\n1. `all(): Promise<Record<string, Accounts>>`\n2. `list(providerID?: string): Promise<Record<string, Info> | Record<string, Record<string, Info>>>`\n3. `get(providerID: string, account?: string): Promise<Info | undefined>`\n4. `set(providerID: string, info: Info, account?: string): Promise<void>`\n5. `use(providerID: string, account: string): Promise<void>`\n6. `remove(providerID: string, account?: string): Promise<void>`\n7. `default(providerID: string): Promise<string | undefined>`\n\nRegras:\n\n- `account` default para `\"default\"` no `set` quando provider nao existir\n- `set` em conta nova nao deve alterar default automaticamente se ja existir default\n- `remove(provider, account)`:\n - se remover conta ativa e houver outras, promover uma conta deterministica (ordem alfabetica)\n - se remover ultima conta, remover provider inteiro\n\n## 8. Design CLI\n\nArquivo: `packages/opencode/src/cli/cmd/auth.ts`\n\n### 8.1 `opencode auth login`\n\nFluxo:\n\n1. selecionar provider (igual hoje)\n2. executar fluxo de auth (oauth/api/plugin)\n3. perguntar alias da conta:\n - default sugestao: `default`\n - validacao: `^[a-z0-9][a-z0-9-_]{0,31}$`\n4. opcional: \"usar como conta padrao agora?\" (sim/nao)\n\n### 8.2 `opencode auth list`\n\nExibir por provider:\n\n- provider name\n- tipo de cada conta (`api`, `oauth`, `wellknown`)\n- marcador da conta ativa (`*`)\n- metadados relevantes quando existirem (`accountId`)\n\nExemplo:\n\n```txt\nOpenAI\n * work oauth accountId=org_work\n personal api\n```\n\n### 8.3 `opencode auth use`\n\nNovo comando:\n\n```bash\nopencode auth use\nopencode auth use openai personal\n```\n\nCom argumento opcional para modo nao interativo.\nSem argumentos, abre prompt provider -> conta.\n\n### 8.4 `opencode auth logout`\n\nAjustar para permitir:\n\n- remover conta especifica\n- remover provider inteiro (acao explicita)\n\nFluxo recomendado:\n\n1. selecionar provider\n2. selecionar conta ou \"all accounts\"\n3. confirmar quando for \"all accounts\"\n\n### 8.5 Interface obrigatoria para troca de conta (TUI/app)\n\nObjetivo: permitir troca de conta ativa sem sair da interface principal.\n\nRequisitos minimos:\n\n1. Expor acao no TUI (slash command ou dialog de provider) para \"Switch account\".\n2. Listar contas por provider com marcador da conta ativa.\n3. Permitir trocar conta com confirmacao visual imediata.\n4. Reutilizar backend de `Auth.use` para manter consistencia com a CLI.\n5. Cobrir fluxo com teste de integracao (quando aplicavel ao modulo).\n\n## 9. Resolucao de Conta no Runtime\n\nArquivos alvo:\n\n- `packages/opencode/src/provider/auth.ts`\n- `packages/opencode/src/config/config.ts`\n- pontos de chamada que leem credencial para provider\n\n### 9.1 Precedencia de resolucao\n\n1. override explicito da chamada (quando existir)\n2. config de projeto (`opencode.json`) para conta do provider\n3. env var dedicada (opcional na fase 1, recomendado fase 1.5)\n4. conta default do provider\n\n### 9.2 Chave de configuracao sugerida\n\nNo `opencode.json`:\n\n```json\n{\n \"auth\": {\n \"account\": {\n \"openai\": \"work\",\n \"anthropic\": \"personal\"\n }\n }\n}\n```\n\nSe essa chave for adicionada na fase 1, deve entrar no schema de config com docs.\nSe ficar para fase 2, manter apenas default global via `auth use`.\n\n## 10. OAuth e Plugins\n\nNos fluxos OAuth/plugin:\n\n- continuar salvando `accountId` quando o provider retornar esse campo\n- associar resultado ao alias escolhido no CLI\n- manter comportamento atual para providers que retornam `provider` custom no callback\n\n## 11. Migracao\n\n### 11.1 Estrategia\n\n- migracao lazy na leitura\n- persistencia no novo formato na primeira escrita\n- sem comando manual obrigatorio\n\n### 11.2 Integridade\n\n- parse robusto por item\n- entradas invalidas sao ignoradas (como hoje), sem derrubar carga inteira\n- escrita atomica via `Bun.write`\n\n### 11.3 Rollback\n\nNao ha rollback automatico de arquivo.\nPara seguranca operacional, documentar backup manual:\n\n```bash\ncp ~/.local/share/opencode/auth.json ~/.local/share/opencode/auth.json.bak\n```\n\n## 12. Plano de Testes\n\n### 12.1 Unitarios (Auth core)\n\nArquivo sugerido: `packages/opencode/test/auth/auth.test.ts`\n\nCenarios:\n\n1. ler formato legado e normalizar corretamente\n2. `set` cria provider e conta default\n3. `set` adiciona segunda conta sem trocar default\n4. `use` troca default para conta existente\n5. `remove` conta nao default preserva default\n6. `remove` conta default promove outra\n7. `remove` ultima conta apaga provider\n8. parser ignora entradas invalidas\n\n### 12.2 CLI integration\n\nArquivos em `packages/opencode/test/...`\n\n1. `auth list` mostra marcador de default\n2. `auth use` altera conta ativa\n3. `auth logout` remove somente conta escolhida\n\n### 12.3 Runtime integration\n\n1. provider resolve conta por default\n2. provider resolve conta por override de config\n3. fallback legado continua funcional\n\n## 13. Riscos e Mitigacoes\n\n1. Risco: quebrar leitura de auth legado.\n Mitigacao: parser dual + testes de fixture legado.\n\n2. Risco: confusao de UX com muitas opcoes.\n Mitigacao: defaults fortes e fluxo interativo curto.\n\n3. Risco: conflito de nomes de conta.\n Mitigacao: validacao e confirmacao de overwrite.\n\n4. Risco: providers com oauth diferente por tenant.\n Mitigacao: preservar `accountId` e expor no `auth list`.\n\n## 14. Fases de Entrega\n\n### Fase 1 (core)\n\n- schema/auth storage v2\n- compat legado\n- API interna (`get/set/use/remove/list`)\n- testes unitarios de auth\n\n### Fase 2 (CLI)\n\n- `auth login` com alias\n- `auth list` com contas\n- `auth use`\n- `auth logout` granular\n- interface no TUI/app para troca de conta ativa\n- testes de CLI\n\n### Fase 3 (runtime/config)\n\n- resolucao por conta ativa\n- override por config/env (se aprovado no escopo)\n- testes de integracao de provider\n\n### Fase 4 (docs e hardening)\n\n- docs de comandos novos\n- troubleshooting multi-auth\n- validacao final com cenarios work/personal\n\n## 15. Definicao de Pronto (DoD)\n\n1. Usuario consegue autenticar duas contas OpenAI no mesmo ambiente.\n2. Usuario alterna conta ativa com um comando (`auth use`) sem relogar.\n3. Sessao usa a conta esperada conforme regra de precedencia.\n4. Usuarios legados nao precisam fazer nenhuma acao manual.\n5. Suite de testes adicionada e passando nos modulos afetados.\n6. Docs publicadas com exemplos reais.\n7. Existe interface no TUI/app para trocar conta ativa por provider.\n8. `typecheck` e `build` passam sem erros nos pacotes afetados.\n\n## 16. Checklist de Implementacao\n\n1. Atualizar `Auth` schema e normalizacao legado.\n2. Implementar API interna multi-account.\n3. Atualizar fluxos de `auth login/list/logout`.\n4. Adicionar `auth use`.\n5. Integrar resolucao de conta no runtime.\n6. Adicionar/atualizar testes.\n7. Atualizar docs PT-BR + EN.\n8. Validar manualmente com duas contas no mesmo provider.\n9. Implementar interface no TUI/app para troca de conta.\n10. Garantir `build` e `typecheck` verdes antes de merge.\n\n## 17. Exemplos de Uso Final\n\n```bash\n# login da conta corporativa\nopencode auth login\n# alias: work\n\n# login da conta pessoal\nopencode auth login\n# alias: personal\n\n# ver estado\nopencode auth list\n\n# trocar conta ativa\nopencode auth use openai personal\n\n# remover so a conta pessoal\nopencode auth logout\n```\n\n## 18. Open Questions\n\n1. Queremos incluir override por config ja na primeira entrega?\n2. Precisamos de suporte explicito por sessao (`--account`) na CLI principal?\n3. Qual UX final preferimos para troca no TUI: comando dedicado (`/account`) ou dentro de `/connect`?\n",
"startedAt": "2026-02-13T00:01:23.702Z",
"startedAt": "2026-02-13T00:01:53.900Z",
"model": "minimax-coding-plan/MiniMax-M2.5",
"agent": "opencode"
}