Programando com uma IA como par — o que aprendi construindo o PharoWiki
Abril de 2026
Nos últimos dias venho trabalhando num projeto chamado PharoWiki — uma wiki navegável gerada automaticamente a partir do código-fonte do Pharo Smalltalk. O que torna esse projeto diferente não é só o que estamos construindo, mas como estamos construindo.
Estou usando o Claude como par de programação. Não como assistente. Como par.
E a diferença importa.
A ideia (para qualquer leitor)
O Pharo Smalltalk é uma linguagem viva — literalmente. Você roda uma "imagem" que contém todo o sistema operando em memória, com todas as classes, métodos e histórico de mudanças disponíveis para inspeção a qualquer momento.
A inspiração veio de Andrej Karpathy, que plugou o Claude Code num cofre do Obsidian para criar uma base de conhecimento que evolui com o tempo. Pensei: e se fizéssemos isso com o código-fonte do Pharo?
O resultado é o PharoWiki — um gerador que usa reflexão da própria imagem Pharo para produzir arquivos Markdown por classe, com links navegáveis entre classes, métodos e implementadores. Abro no Obsidian e tenho uma wiki do Pharo que posso navegar, buscar e anotar.
Como trabalhamos (para qualquer leitor)
A sessão de trabalho tem um ritmo próprio que foi se estabelecendo naturalmente.
Trabalho dentro de um Projeto no
Claude.ai — não uso o Claude Code. O projeto tem arquivos de contexto (CONVENTIONS.md, PHAROWIKI_CONTEXT.md) que o Claude lê automaticamente no início de cada sessão. É uma escolha deliberada: prefiro o controle explícito do fluxo a uma ferramenta que age de forma mais autônoma no repositório.
Eu proponho uma direção. O Claude pensa em voz alta — explica o que vai fazer antes de fazer. Eu corrijo, questiono, sugiro. O Claude ajusta. Codificamos em ciclos curtos com testes depois de cada mudança.
Há um arquivo chamado CONVENTIONS.md que vivemos atualizando juntos. Nele estão coisas como:
"Mensagens curtas devem ser completas — sem elipses."
"Explicar antes de implementar."
"Metacello não remove métodos — remover manualmente no browser antes de recarregar."
Esse arquivo é lido pelo Claude no início de cada sessão. É a nossa memória compartilhada.
O que me surpreendeu: o Claude lembra das decisões de design da sessão anterior. Não porque tem memória persistente — mas porque construímos um contexto rico o suficiente para que as decisões passadas sejam visíveis no código e nos arquivos do projeto.
O fluxo técnico (para programadores)
O projeto usa Pharo 13 num Mac M4. O código vive num repositório GitHub em formato Tonel — o formato nativo do Pharo para versionamento. O fluxo é:
Editar o .class.st no VSCode (com highlight Smalltalk via extensão do Pharo)
Recarregar na imagem via Metacello no Playground
Rodar os testes
Commit via Terminal — a mensagem vem do Claude
Nunca editamos direto no browser do Pharo. O repositório é a fonte da verdade.
Quando algo dá errado — um erro no debugger, uma stack trace inesperada, um estado estranho no Inspector — uma imagem do IDE do Pharo colada na conversa vale mais que uma longa descrição em texto. O Claude lê e interpreta capturas de tela diretamente, desde que não estejam muito recortadas ou confusas.
Os testes são BDD-style, com TestCase padrão do Pharo. Temos 54 testes verdes cobrindo todas as classes:
PWikiClassPage — introspecção de uma classe via reflexão
PWikiMethodSection — encapsula um método compilado e sua AST
PWikiMicrodownConverter — converte links Microdown para formato Obsidian
PWikiSelectorPage — gera notas de implementadores por seletor
PWikiGenerator — orquestra tudo com Jobs aninhados para progresso visual
PWikiFileWriter — escreve os .md no sistema de arquivos
O que o wiki gera (para programadores)
Para cada classe Pharo, o wiki gera um arquivo .md com:
Herança e subclasses como links Obsidian ([[Object]])
Comentário da classe convertido de Microdown para Markdown
Métodos organizados por protocolo
Para cada método, a lista de mensagens enviadas — cada uma como link para uma nota de implementadores
Essa última parte é o que mais me animou. Ao clicar em [[_plus_ implementors| ]] no método de Point, abro uma nota com todos os 35 implementadores do seletor na imagem — Integer, Float, Point, Duration, e mais. Clicar em qualquer um vai direto para o método naquela classe.
É navegação semântica do código, no Obsidian.
O que aprendi sobre trabalhar com IA (para qualquer leitor)
Algumas coisas que funcionaram bem:
Construir convenções explícitas. O CONVENTIONS.md foi uma das melhores decisões. Força clareza sobre como queremos trabalhar — e o Claude aplica essas convenções consistentemente.
Uma coisa de cada vez. Toda vez que tentei resolver dois problemas ao mesmo tempo, ficou confuso. Ciclos curtos funcionam melhor.
O Playground como aliado. No Pharo, o Playground é o REPL — permite testar hipóteses rapidamente sem escrever testes formais. Quando havia dúvida sobre o comportamento de um método, íamos ao Playground antes de modificar qualquer coisa.
A IA erra — e erra de forma interessante. Algumas vezes o Claude propôs uma solução que parecia razoável mas tinha um bug sutil. O processo de diagnosticar juntos foi valioso.
Contexto é tudo. O Claude lê o contexto do projeto no início de cada sessão. Quanto mais rico esse contexto, melhor a colaboração. Investir tempo em documentar decisões de design paga dividendos nas sessões seguintes. No futuro o PharoWiki fará parte desse contexto.
O que vem a seguir
Estamos construindo a feature de Senders — o complemento natural dos Implementors. Além de ver quem implementa um seletor, poderemos navegar para quem o envia.
Depois: gerar a imagem completa do Pharo. Mais de 3000 classes. Vamos ver o que emerge quando toda a hierarquia está navegável no Obsidian.
O projeto está no GitHub:
github.com/chicoary/PharoWik…
Este artigo foi escrito com o Claude como interlocutor — não como ghostwriter. As ideias, as escolhas e os erros são meus.
Checklist de uma sessão de desenvolvimento (para quem quiser replicar)
Este é o fluxo que usamos. Pode ser adaptado para qualquer projeto Pharo com Claude.
Antes de começar
Abrir o Pharo 13 com a imagem do projeto
Abrir o VSCode com o repositório local
Abrir o Terminal na pasta do repositório
Verificar o branch atual (git status)
Ler o CONVENTIONS.md e o CONTEXT.md (ou garantir que o Claude os leu)
Executar o script Rodar todos os testes — confirmar que está tudo verde antes de começar
Definir o objetivo da sessão em uma frase
Durante a sessão
Ciclo padrão de mudança:
Descrever o problema ou feature em linguagem natural
Pedir ao Claude que explique o racional antes de gerar código
Quando precisar mostrar uma classe ao Claude, usar o script Gerar código da classe
Revisar o código proposto antes de aplicar
Editar o .class.st no VSCode
Executar o script Recarregar pacote no Playground
Executar o script Rodar todos os testes
Se vermelho: diagnosticar com Playground ou debugger antes de modificar
Se verde: commit
Quando usar cada ferramenta:
Playground — testar hipóteses rápidas, inspecionar estado, verificar APIs desconhecidas
Debugger — entender falhas em testes ou erros em tempo de execução
Browser do Pharo — remover métodos que o Metacello não remove automaticamente
Terminal — commits, push, gerenciamento de branches
Screenshot do IDE — quando algo dá errado, uma imagem do debugger ou da stack trace colada na conversa é mais eficiente que descrever o erro em texto
Regras durante a sessão:
Uma coisa de cada vez — não misturar correção de bug com nova feature
Nunca commitar com testes falhando
Criar um branch para mudanças que afetam muitas classes
Ao renomear ou remover um método: apagar no browser do Pharo antes de recarregar
Ao finalizar
Todos os testes verdes
Commit com mensagem descritiva
Push para o GitHub
Atualizar CONVENTIONS.md se alguma nova convenção emergiu
Atualizar CONTEXT.md se o estado do projeto mudou significativamente
Registrar próximos passos (pode ser um comentário no final da sessão de chat)
Scripts essenciais (para programadores)
Adapte os caminhos para o seu ambiente. Estes scripts ficam num arquivo scripts.md no repositório e são referenciados por nome durante a sessão.
Recarregar pacote
| gitPath |
gitPath := '/SEU/CAMINHO/PARA/RAIZ/DO/GIT'.
Transcript
clear;
show: '[', DateAndTime now printString, '] Recarregando...'; cr.
Metacello new
baseline: 'NomeDoProjeto'; "corresponde à classe BaselineOfNomeDoProjeto"
repository: 'tonel://', gitPath, '/src';
load.
self inform: 'Ok'
Rodar todos os testes
| result suite |
Transcript
clear;
show: '[', DateAndTime now printString, '] Rodando testes...'; cr.
suite := TestSuite new.
"Adicione aqui um addTest: para cada TestCase do seu projeto"
suite addTest: SuaClasseDeTesteTest suite.
result := suite run.
Transcript
show: result passed size printString, ' passaram'; cr;
show: result failures size printString, ' falharam'; cr;
show: result errors size printString, ' erros'; cr.
self inform: 'Ok'
Gerar código de uma classe (para compartilhar com a IA)
TonelWriter sourceCodeOf: NomeDaClasse
Este script gera o código completo da classe no formato Tonel — com categoria, protocolo e estrutura — pronto para ser colado numa conversa com a IA. No futuro, o PharoWiki vai suprir essa necessidade de outra forma: em vez de copiar código, apontaremos para a página .md da classe no vault, que já terá todo o contexto necessário.