Ir para o conteúdo principal
Background Image

Coding Adventures: OpenSpec

·1727 palavras·9 minutos
Lucas Limeira
Autor
Lucas Limeira

Eu já estava há um tempo querendo escrever um pouco sobre Specification-Driven Development, em especial sobre uma ferramenta que tenho usado bastante no dia-a-dia: o OpenSpec. Cheguei a testar várias ferramentas do mesmo segmento como agent-os e spec-kit, porém a simplicidade e facilidade de uso do OpenSpec me conquistou.

Para demonstrar um pouco de como eu o utilizo, vou criar um projetinho do zero, mas quero deixar claro que o OpenSpec funciona muito bem em projetos já em desenvolvimento, a grande diferença será apenas no investimento de tempo que você terá em popular o arquivo project.md com as informações sobre o estado atual do projeto. Vou criar esse projeto de exemplo usando o Cursor já que é o editor que tenho usado bastante ultimamente e o OpenSpec funciona muito bem com ele.

Instalação
#

Para começar, é necessário ter Node instalado e na versão maior ou igual a 20.19.0, como especificado na página do Github do OpenSpec. Com isso feito, a instalação é simples, basta executar o comando npm install -g @fission-ai/openspec@latest e o OpenSpec estará instalado!

Inicialização do projeto
#

Após isso, para começar a utilizar o OpenSpec em um repositório, é necessário usar o comando openspec init na raiz do repositório. Isso executará o assistente de inicialização que te guia por todo o processo. Para iniciar a configuração, basta pressionar Enter.

Assistente de inicialização

No passo seguinte, o assistente te perguntará quais ferramentas você utilizará com o OpenSpec. Basicamente, o assistente de inicialização irá criar os arquivos necessários para facilitar seu processo de desenvolvimento de forma integrada com a sua ferramenta de escolha, o que inclui atalhos em slash commands assim como a configuração do prompt necessária para o seu agente. Geralmente, eu seleciono apenas o Claude Code, pois é outra ferramenta que uso e o Cursor tem suporte aos mesmos tipos de arquivo, mas também poderia selecionar o Cursor na lista para criar os arquivos específicos para ele.

Integrações

Vale lembrar que além de todas essas ferramentas listadas, o OpenSpec também oferece suporte universal através do arquivo AGENTS.md.

Após confirmar sua escolha, o seu repositório estará inicializado com todos os arquivos necessários para utilizar o OpenSpec e, além disso, o assistente te guia sobre como iniciar seu desenvolvimento utilizando a ferramenta.

Prompts Iniciais

Vou seguir as instruções e usar o primeiro prompt sugerido para popular meu arquivo project.md com os detalhes do meu projeto. Para este exemplo, vou usar o modelo auto do Cursor, mas pode utilizar qualquer modelo de sua preferência.

Caso esteja com um repositório já em desenvolvimento, o agente irá vasculhar os arquivos para obter um mínimo entendimento e preencher o project.md. Como no meu caso eu tenho um repositório vazio, o agente me questionou sobre os detalhes do projeto:

Questionamentos

Esse projeto de exemplo será uma aplicação para trackear pontuações de partidas de vôlei. Então o preenchi as informações a seguir:

1. Purpose: Matchd is a aplication to help tracking volleyball matches scores.

2. Tech Stack: We should use Typescript with React

3. Keep the code formatted using the recommended patterns for Typescript and use a formatter for automation

4. No preferences

5. We should follow a TDD approach and have unit tests for functional parts of the application

6. We should use Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0/

E esse foi o project.md resultante:

# Project Context

## Purpose
Matchd is an application to help tracking volleyball match scores. The primary goal is to provide a reliable and user-friendly interface for recording and managing volleyball match statistics and scores.

## Tech Stack
- **Frontend**: TypeScript, React
- **Build Tool**: [To be determined - e.g., Vite, Create React App, Next.js]
- **Package Manager**: [To be determined - e.g., npm, yarn, pnpm]

## Project Conventions

### Code Style
- Follow recommended TypeScript patterns and best practices
- Use an automated formatter (e.g., Prettier) for consistent code formatting
- Naming conventions:
  - camelCase for variables and functions
  - PascalCase for components and classes
  - kebab-case for file names (or follow React conventions)
- Use ESLint with TypeScript-specific rules
- Maintain consistent indentation and spacing (configured via formatter)

### Architecture Patterns
- Component-based architecture (React)
- Separation of concerns between UI components and business logic
- [Additional patterns to be determined as the project evolves]

### Testing Strategy
- **Approach**: Test-Driven Development (TDD)
- **Unit Tests**: Required for all functional parts of the application
- **Test Framework**: [To be determined - e.g., Jest, Vitest]
- **Testing Library**: [To be determined - e.g., React Testing Library]
- Write tests before implementation (red-green-refactor cycle)
- Focus on testing business logic, component behavior, and user interactions

### Git Workflow
- **Commit Format**: [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
  - Format: `<type>[optional scope]: <description>`
  - Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`, `build`, `ci`
  - Breaking changes: Use `!` after type/scope or include `BREAKING CHANGE:` footer
  - Examples:
    - `feat: add score tracking for volleyball matches`
    - `fix(ui): correct score display alignment`
    - `feat(api)!: change score data structure`
- **Branching Strategy**: [To be determined - e.g., GitHub Flow, Git Flow]
- **PR Requirements**: Code review, passing tests, updated documentation if needed

## Domain Context
- **Volleyball Match Scoring**: The application tracks scores for volleyball matches
- **Key Concepts**:
  - Match: A complete volleyball game between two teams
  - Score: Points accumulated by each team during a match
  - Sets: Volleyball matches are typically played in sets (best of 3 or 5)
- **User Needs**: Coaches, referees, or players need to accurately record and track match scores
- **Functional Requirements**: 
  - Record scores for each set
  - Track match progress
  - Display current score and match status
  - [Additional requirements to be defined as the project evolves]

## Important Constraints
- **Browser Compatibility**: [To be determined - e.g., modern browsers, mobile support]
- **Performance**: Application should be responsive and handle real-time score updates efficiently
- **Data Persistence**: [To be determined - e.g., local storage, backend API, database]
- **Offline Support**: [To be determined - whether the app needs to work offline]

## External Dependencies
- **React**: UI library
- **TypeScript**: Type-safe JavaScript
- **Build Tools**: [To be determined - e.g., Vite, Webpack]
- **Testing Libraries**: [To be determined - e.g., Jest, React Testing Library]
- **Formatting Tools**: [To be determined - e.g., Prettier]
- **Linting Tools**: [To be determined - e.g., ESLint with TypeScript plugin]
- [Additional dependencies to be added as the project develops]

Esse é o momento em que você deve revisar seu project.md, adicionar e validar informações até que chegue em um estado que reflita a visão do seu projeto.

Criando propostas
#

A partir de agora, podemos começar as implementações para o nosso projeto. Para fazer isso, vamos criar uma proposta (proposal). Seguindo o fluxo do OpenSpec, para cada nova implementação devemos criar uma proposta com o que esperamos que seja alcançado. Fazemos isso através do slash command /openspec/proposal, ou caso sua ferramenta não tenha suporte à essa integração, pode utilizar um prompt como o sugerido pelo assistente de inicialização:

I want to add [YOUR FEATURE HERE]. Please create an OpenSpec change proposal for this feature

Minha primeira proposta será a seguinte:

/openspec/proposal I want create the initial project setup. The expected output from this is a working application in Typescript + React with a sample page showing the name of the project.

Pessoalmente, eu tenho obtido melhores resultados sempre criando um novo agente (chat) para cada proposta, dessa forma evito o contexto ficar muito poluído com informações desnecessárias.

Após submeter o prompt, o agente irá checar especificações existentes, seu project.md e irá criar os diretórios e arquivos necessários para a sua proposta. Todos esses arquivos ficam dentro da pasta openspec dentro do diretório do seu projeto. Geralmente, os arquivos criados são os seguintes:

  • proposal.md: Contém a descrição da sua proposta descrevendo o porquê, o que será mudado no projeto e o impacto que essa mudança causa (especificações, códigos e ferramentas afetadas).
  • design.md: Contém as informações relacionadas a escolhas de design para essa proposta. Contém um breve contexto, objetivos, o que está fora do escopo, decisões (assim como o racional por trás delas), riscos e questões em aberto.
  • spec.md: Contém a especificação em si, descrevendo cenários, comportamentos esperados e requisitos.
  • tasks.md: Contém uma lista de tarefas numeradas em formato de checklist.

Esse é o momento em que se deve checar bem cada um desses documentos gerados para ter certeza que estão de acordo com o que se espera dessa proposta. Em especial, recomendo checar o proposal.md e o design.md, neste último, eu costumo sempre tentar responder as perguntas abertas que estão no documento (faço isso através do prompt do agente). Após isso, você pode pedir que o agente revise todos os arquivos da proposta para atualizar pontos necessários e podemos partir para o próximo passo: a aplicação de uma proposta.

Aplicando uma proposta
#

Com nossa proposta em um estado satisfatório, podemos usar o próximo slash command /openspec/apply seguido do nome (slug) da sua proposta. Assim como no passo anterior, também é possível utilizar um prompt como:

Please, apply the OpenSpec proposal <name-of-your-proposal>

Você pode checar o nome da sua proposta assim como listar todas as propostas existentes através do comando openspec list na raiz do seu repositório.

openspec list

No meu caso, utilizei o slash command: /openspec/apply setup-initial-project. Com isso, o agente inicia a implementação, marcando cada tarefa completada na checklist do tasks.md. Após concluir a execução, o resultado foi a estrutura inicial do projeto criada assim como requisito funcional da tela simples com o nome do projeto atendido:

Resultado

Agora é o momento em que você se torna um Code Reviewer e checa se o código gerado condiz com o que você espera e faz alterações necessárias (uma tarefa já conhecida para todos nós usando IA durante desenvolvimento de software 😂). Recomendo sempre utilizar propostas pequenas para facilitar a revisão e alteração de código.

Após concluir a aplicação da sua proposta, caso use o comando openspec list, irá ver que a mudança está marcada como completa:

openspec list final

Caso ela não esteja marcada como completa, o número de tarefas não completadas será exibido. Nesse caso, recomendo checar o tasks.md, pois o agente pode ter deixado de implementar algumas das tarefas por limitações e próximos prompts serão necessários para guiar a IA.

Eu vejo, como grande benefício do uso do OpenSpec, dar um processo bem definido e estruturado para a IA, diminuindo a possibilidade de delírios ou dela querer ser desnecessariamente eficiente (que acontece com frequência nos modelos mais recentes).