AkiraAkira.dev
3 min de leitura

Spectra, dia um

Arranquei o Spectra numa quinta de manhã. À meia-noite já estava a ler rotas reais de Laravel. O primeiro commit que importou não foi o que parecia importar.

também em EN FR

Arranquei o Spectra às 9h de uma quinta-feira. À meia-noite já estava a varrer rotas reais de Laravel de um projeto real no meu disco.

Isto foi a 2026-05-08. O primeiro commit no repo arrancou o template do Wails. O segundo commit desse dia entregou o scanner. Nove dias depois havia uma build beta com auto-updates e billing ligado. A história de como o Spectra começou é sobretudo a história de uma regra que me impus no dia um.

A decisão

Tinha passado o mês anterior a queixar-me do Postman em privado e a não entregar nada sobre isso. Queixar-se é grátis. Por isso parei, abri um terminal e corri wails init.

A stack não foi uma escolha por hype. Escolhi Go porque o produto precisa de chamar o PHP por baixo e fazer parse do output sem lutar contra um runtime de linguagem. Escolhi Wails porque o Electron carrega 200MB de Chromium que não quero enviar para o MacBook de um programador Laravel. Escolhi React porque a UI vai ser cheia e não tenho interesse em reescrever gestão de estado de formulários por diversão. Nenhuma destas escolhas é esperta. São as escolhas chatas que sobrevivem ao contacto com o segundo mês.

O primeiro commit foi um template. Isso é normal. O que não foi normal foi a regra ligada a ele.

O dia um tinha de entregar o scanner

A regra: se o Spectra não consegue ler um projeto Laravel real no dia em que foi arrancado, é vapor. Não vapor na semana seguinte. Vapor agora. O que distingue um cliente de API que conhece o teu framework de mais um executor de pedidos HTTP é o scanner. Tudo o resto é verniz. Se entregasse o verniz primeiro, nunca voltaria ao motor.

Por isso o segundo commit de 2026-05-08 entregou um scanner real de rotas Laravel, persistido em SQLite. Chama php artisan route:list --json contra um caminho de projeto que o utilizador escolhe, faz parse do output e escreve os endpoints numa base de dados local.

// internal/drivers/laravel/route_list.go
cmd := exec.CommandContext(ctx, phpPath, "artisan", "route:list", "--json")
cmd.Dir = projectPath
cmd.Env = enrichedEnv()

É essa a ideia toda. Não há inferência esperta. O framework já publica as suas próprias rotas. O Spectra lê o que já está lá.

No fim dessa quinta-feira o scanner tinha aterrado, o filtro só-API tinha aterrado, e um executor universal de pedidos HTTP com um base URL de workspace estava ligado. Um dia, três commits que provaram o ciclo: escolher um projeto Laravel, ver as suas rotas, disparar um pedido. A coisa estava viva.

Estava feia. A UI era um esboço. Não havia deteção de auth, nem inferência de schema, nem exporter, nem nada. Mas estava viva na única forma que importava: dizia a verdade sobre uma codebase real no momento em que a apontavas para ela. Cada feature depois disso era uma feature em cima de um sistema a funcionar. Nenhuma era uma feature em cima de uma promessa.

O fecho

O primeiro commit que importou não foi o arranque. Foi o que provou que o framework responderia. Se estás a começar um produto, encontra a tua versão de route:list --json no dia um. O resto é verniz.

share
Caption copied — paste in the compose box