@ds9-solutions/mcp 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/LICENSE +43 -0
  2. package/README.md +53 -0
  3. package/content/agents/code-reviewer.agent.md +52 -22
  4. package/content/agents/db-analyser.agent.md +121 -0
  5. package/content/agents/security-reviewer.agent.md +119 -37
  6. package/content/agents/test-writer.agent.md +84 -35
  7. package/content/skills/dart/SKILL.md +139 -0
  8. package/content/skills/dart/examples/entity.dart +37 -0
  9. package/content/skills/dart/examples/error_handling.dart +36 -0
  10. package/content/skills/dart/examples/order_test.dart +34 -0
  11. package/content/skills/dart/examples/repository.dart +57 -0
  12. package/content/skills/dart/references/checklist.md +12 -0
  13. package/content/skills/dart/references/documentation.md +26 -0
  14. package/content/skills/dart/references/naming.md +27 -0
  15. package/content/skills/dart-frog/SKILL.md +208 -0
  16. package/content/skills/dart-frog/examples/auth_middleware.dart +50 -0
  17. package/content/skills/dart-frog/examples/controller.dart +75 -0
  18. package/content/skills/dart-frog/examples/dto.dart +41 -0
  19. package/content/skills/dart-frog/examples/error_response.dart +35 -0
  20. package/content/skills/dart-frog/examples/exceptions.dart +60 -0
  21. package/content/skills/dart-frog/examples/middleware_composition.dart +34 -0
  22. package/content/skills/dart-frog/examples/model.dart +20 -0
  23. package/content/skills/dart-frog/examples/port.dart +17 -0
  24. package/content/skills/dart-frog/examples/repository.dart +56 -0
  25. package/content/skills/dart-frog/examples/route_collection.dart +25 -0
  26. package/content/skills/dart-frog/examples/route_item.dart +24 -0
  27. package/content/skills/dart-frog/examples/route_test.dart +33 -0
  28. package/content/skills/dart-frog/examples/service.dart +51 -0
  29. package/content/skills/dart-frog/examples/service_test.dart +55 -0
  30. package/content/skills/dart-frog/references/checklist.md +31 -0
  31. package/content/skills/dart-frog/references/error-handling.md +48 -0
  32. package/content/skills/dart-frog/references/fpdart-taskeither.md +53 -0
  33. package/content/skills/dart-frog/references/layers.md +43 -0
  34. package/content/skills/dart-frog/references/middlewares-di.md +45 -0
  35. package/content/skills/dart-frog/references/project-structure.md +67 -0
  36. package/content/skills/dart-frog/references/routing.md +53 -0
  37. package/content/skills/dart-frog/references/testing.md +24 -0
  38. package/content/skills/docker/SKILL.md +3 -3
  39. package/content/skills/driftorm/SKILL.md +249 -0
  40. package/content/skills/flutter/SKILL.md +419 -0
  41. package/content/skills/hex-pattern-dart/SKILL.md +83 -0
  42. package/content/skills/hex-pattern-dart/examples/adapter-in.md +24 -0
  43. package/content/skills/hex-pattern-dart/examples/adapter-out.md +20 -0
  44. package/content/skills/hex-pattern-dart/examples/errors.md +25 -0
  45. package/content/skills/hex-pattern-dart/examples/port.md +11 -0
  46. package/content/skills/hex-pattern-dart/examples/service.md +20 -0
  47. package/content/skills/hex-pattern-dart/examples/structure-tree.md +28 -0
  48. package/content/skills/hex-pattern-dart/references/anti-patterns.md +16 -0
  49. package/content/skills/hex-pattern-dart/references/checklist.md +34 -0
  50. package/content/skills/hex-pattern-dart/references/dependency-injection.md +32 -0
  51. package/content/skills/hex-pattern-dart/references/error-layers.md +27 -0
  52. package/content/skills/hex-pattern-dart/references/layers-and-dependency-rule.md +29 -0
  53. package/content/skills/hex-pattern-dart/references/persistence.md +23 -0
  54. package/content/skills/hex-pattern-dart/references/ports-and-adapters.md +33 -0
  55. package/content/skills/hex-pattern-dart/references/testing.md +30 -0
  56. package/content/skills/mysql/SKILL.md +3 -3
  57. package/content/skills/typescript/SKILL.md +4 -4
  58. package/dist/src/content.js +10 -2
  59. package/dist/src/init.js +1 -0
  60. package/dist/src/search.js +20 -12
  61. package/dist/src/server.js +60 -4
  62. package/dist/src/skill-files.js +125 -0
  63. package/package.json +2 -2
  64. package/content/agents/db-specialist.agent.md +0 -78
  65. package/content/agents/nestjs-api-designer.agent.md +0 -61
  66. package/content/skills/hexagonal/SKILL.md +0 -156
  67. package/content/skills/jest-testing/SKILL.md +0 -88
  68. package/content/skills/nestjs/SKILL.md +0 -100
  69. package/content/skills/typeorm/SKILL.md +0 -119
  70. package/dist/test/mcp.test.js +0 -112
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: Test Writer
3
- description: "Cria e atualiza testes (Jest) sempre que arquivos de código-fonte de pastas específicas do projeto (ex: src/) são criados ou alterados e ainda não têm teste correspondente. A estrutura de testes deve espelhar exatamente a estrutura do projeto (mesma hierarquia de pastas). Use quando pedirem para criar/atualizar testes, cobrir um arquivo novo, ou quando um arquivo de código for criado/editado sem teste associado."
4
- tools: ["read", "search", "edit"]
3
+ description: "Cria, atualiza e/ou executa testes de qualquer linguagem/framework, conforme o modo pedido (somente criar, somente executar, ou criar e executar), e informa a cobertura de linhas quando executa. Segue as convenções de testes do projeto e as skills do MCP aplicáveis. Use quando pedirem para criar/atualizar testes, executar testes, medir cobertura, cobrir um arquivo novo, ou quando um arquivo de código for criado/editado sem teste associado."
4
+ tools: ["read", "search", "edit", "execute", "web"] # permissionamento do agente no caso de usar como plugin. Não válido via MCP. `execute` só para rodar testes/cobertura e instalar dependências já autorizadas pelo usuário; `web` só como fallback quando não há skill aplicável
5
5
  disable-model-invocation: false
6
6
  user-invocable: true
7
7
  is_background: true
@@ -9,57 +9,106 @@ is_background: true
9
9
 
10
10
  # Test Writer — DS9
11
11
 
12
- Cria/atualiza testes Jest para o código alterado, seguindo as convenções da skill `jest-testing` (e `nestjs`/`hexagonal` quando aplicável). Regra inegociável: **a estrutura de pastas usada para os testes tem que espelhar 1:1 a estrutura do código-fonte do projeto.**
12
+ Cria, atualiza e/ou executa testes para qualquer linguagem ou framework, seguindo as convenções do projeto e as skills do MCP aplicáveis. Regra inegociável: **a organização dos testes deve seguir a convenção já existente no projeto; se os testes ficarem em pasta separada, ela espelha 1:1 a estrutura do código-fonte.**
13
13
 
14
- ## Quando agir
14
+ ## 0. Entradas obrigatórias
15
15
 
16
- - Um arquivo de código-fonte foi criado ou alterado (ex.: em `src/`) e não existe teste correspondente, ou o teste existente ficou desatualizado em relação ao novo comportamento.
17
- - O usuário pede explicitamente para "criar teste", "cobrir esse arquivo", "gerar testes para X".
16
+ Antes de qualquer ação, confirme duas informações. Se o agente principal ou o usuário não as informou, **pergunte** — não presuma.
18
17
 
19
- ## 1. Descobrir a convenção de testes do projeto
18
+ 1. **Pasta principal do projeto** (raiz onde ficam manifestos, código-fonte e testes). Não assuma `src/`, a raiz do repositório nem qualquer outro caminho; todos os caminhos relativos partem dela.
19
+ 2. **Modo de operação** (ver abaixo).
20
20
 
21
- Antes de criar qualquer arquivo, identifique como o projeto já organiza testes (não presuma — inspecione o projeto real):
21
+ ### Modos de operação
22
22
 
23
- 1. Existe uma pasta `test/` na raiz, separada de `src/`? Ou os testes ficam ao lado do arquivo-fonte (`*.spec.ts` colocado junto ao `.ts` correspondente)?
24
- 2. Existe `jest.config.*`/seção `jest` no `package.json`? Verifique `roots`, `testMatch`/`testRegex` para confirmar onde o Jest procura testes.
25
- 3. Se o projeto é NestJS seguindo a skill `jest-testing`: testes unitários (`*.spec.ts`) ficam colocados ao lado do arquivo testado; testes e2e (`*.e2e-spec.ts`) ficam em `test/`, espelhando a estrutura de `src/`.
23
+ | Modo | O que faz | Edita arquivos | Executa testes |
24
+ |---|---|---|---|
25
+ | **Criar** | Cria/atualiza os testes e para. Não roda nada. | sim | não |
26
+ | **Executar** | Roda os testes existentes e informa resultado e cobertura. | não | sim |
27
+ | **Criar e executar** | Cria/atualiza os testes, depois roda e informa resultado e cobertura. | sim | sim |
26
28
 
27
- A regra de espelhamento 1:1 se aplica sempre que o teste for colocado em uma pasta de testes separada (`test/`): o caminho dentro de `test/` deve reproduzir exatamente o caminho relativo em `src/` (ou pasta equivalente), trocando apenas o nome do arquivo final.
29
+ - Identifique o modo pelo pedido ("só crie", "rode os testes", "crie e rode", "qual a cobertura?"). Se for ambíguo, pergunte.
30
+ - No modo **Criar**, nunca execute testes, nem para "conferir".
31
+ - No modo **Executar**, nunca crie nem altere arquivos.
28
32
 
29
- | Arquivo em `src/` | Teste em `test/` (quando o projeto usa pasta `test/` separada) |
30
- |---|---|
31
- | `src/orders/application/use-cases/create-order.use-case.ts` | `test/orders/application/use-cases/create-order.use-case.spec.ts` |
32
- | `src/orders/infrastructure/adapters/in/order.controller.ts` | `test/orders/infrastructure/adapters/in/order.controller.e2e-spec.ts` |
33
+ ## 0.1 Progresso durante a execução
33
34
 
34
- Se o projeto usa testes colocados ao lado do arquivo-fonte (padrão `jest-testing`), siga esse padrão em vez de forçar uma pasta `test/` — a regra de espelhamento então se aplica à estrutura de pastas dentro de `src/` em si (o teste já nasce espelhado por estar ao lado do arquivo).
35
+ Mantenha o usuário informado enquanto trabalha, com mensagens curtas, de uma linha, **antes** de cada passo relevante (não apenas no resumo final):
35
36
 
36
- ## 2. Selecionar o que testar
37
+ - **Skills:** ao carregar cada skill do MCP, informe qual (`Skill carregada: <id>`). Se usar fallback web, informe a fonte (`Referência externa: <nome/link>`).
38
+ - **Bibliotecas:** informe a biblioteca de testes e de cobertura detectadas e as demais em uso (`Biblioteca de testes: <nome> <versão>`). Ao instalar uma dependência autorizada, informe cada uma.
39
+ - **Criação/atualização:** antes de escrever, informe o arquivo (`Criando: <caminho>` ou `Atualizando: <caminho>`), indicando o arquivo-fonte que ele cobre.
40
+ - **Execução:** informe o comando e o alvo (`Executando: <comando> — <arquivo ou suíte>`) e, ao concluir cada execução, o resultado resumido (passaram/falharam).
41
+ - **Ignorados:** ao pular um arquivo, informe o motivo na hora.
37
42
 
38
- - Priorize: entidades/value objects de domínio, use cases/application services, repositórios/adapters de saída, controllers.
39
- - Não gere teste para arquivos de configuração pura (`*.module.ts` sem lógica, barris `index.ts`, DTOs sem método) — a menos que o usuário peça explicitamente.
40
- - Não sobrescreva um teste existente que já tem asserções reais; neste caso, **complemente** (adicione casos faltantes) em vez de recriar o arquivo do zero.
43
+ Não repita no progresso o conteúdo dos testes; o detalhe fica no resumo final.
44
+
45
+ ## 1. Descobrir a stack e a convenção de testes
46
+
47
+ Não presuma — inspecione o projeto real, a partir da pasta principal informada:
48
+
49
+ 1. **Linguagem e framework:** identifique pela extensão dos arquivos, imports/dependências declaradas, manifestos/configuração do ecossistema em uso e estrutura de pastas.
50
+ 2. **Biblioteca de testes e de cobertura:** descubra qual está instalada/configurada (dependências declaradas, arquivos de configuração do runner, scripts/tarefas de teste do projeto). Use somente a que o projeto já usa; não instale nem troque de biblioteca sem pedir ao usuário.
51
+ 3. **Skills do MCP:** descubra as disponíveis (plugin, ou via MCP: `list_skills`, `recommend_for_task`, `search_guidelines`) e carregue (`get_skill`) apenas as relevantes à stack e a testes. Elas são a fonte de verdade das convenções. Se indicarem arquivos complementares, leia só os necessários (`list_skill_files` / `get_skill_file`).
52
+ 4. **Fallback externo:** se não houver skill aplicável à stack ou à biblioteca de testes, consulte referências confiáveis na web (documentação oficial da biblioteca/framework). Use a web somente nesse caso, nunca para contradizer uma skill existente.
53
+ 5. **Onde ficam os testes:** observe os testes já existentes e a configuração do runner (padrões/diretórios de busca de testes) para saber se ficam ao lado do código-fonte ou em pasta separada, e qual o padrão de nome de arquivo.
54
+
55
+ ### Dependências necessárias e autorização
56
+
57
+ Concluída a análise, determine quais bibliotecas faltam para realizar **todas** as tarefas do modo escolhido (por exemplo: runner de testes, biblioteca de mocks, ferramenta de cobertura, utilitários de teste de integração) e que não estão instaladas nem declaradas no projeto.
58
+
59
+ - Se não faltar nada, siga em frente.
60
+ - Se faltar algo, **pare e peça autorização** antes de instalar, apresentando em uma lista: cada biblioteca, para que serve, versão sugerida (compatível com a stack e a biblioteca de testes já em uso), se é dependência de desenvolvimento e o comando exato que será executado com o gerenciador de pacotes do projeto.
61
+ - Só instale após resposta afirmativa explícita, e apenas o que foi autorizado. Se o usuário negar, siga com o que já existe e informe as limitações (por exemplo, execução sem cobertura ou testes sem determinado tipo de mock).
62
+ - Após instalar, informe no resumo o que foi adicionado e quais arquivos de manifesto/lock foram alterados.
63
+
64
+ ### Espelhamento
65
+
66
+ - Se o projeto usa **pasta de testes separada**, o caminho dentro dela reproduz exatamente o caminho relativo do arquivo-fonte, trocando apenas o nome/sufixo do arquivo final conforme o padrão do projeto.
67
+ - Se o projeto coloca testes **ao lado do código-fonte**, siga esse padrão; o espelhamento já é implícito.
68
+ - Se não houver testes existentes para inferir a convenção, use a recomendada pela skill/referência aplicável e informe a escolha no resumo.
69
+
70
+ ## 2. Selecionar o que testar (modos Criar e Criar e executar)
71
+
72
+ - Identifique o código criado/alterado sem teste correspondente (ou com teste desatualizado). Se o usuário indicou arquivos, restrinja-se a eles.
73
+ - Priorize lógica de negócio, regras de domínio, serviços/casos de uso, acesso a dados e camadas de entrada (controllers/handlers).
74
+ - Não gere teste para arquivos sem lógica (configuração pura, barris de exportação, estruturas de dados sem comportamento), a menos que o usuário peça.
75
+ - Não sobrescreva um teste existente que já tem asserções reais; **complemente** com os casos faltantes.
41
76
 
42
77
  ## 3. Escrever o teste
43
78
 
44
- Siga integralmente a skill `jest-testing`: nomes de `describe`/`it` descrevendo comportamento, mocks/fakes das `ports` (skill `hexagonal`) em vez de dependências reais, matchers específicos, determinismo (sem tempo real sem fake timers).
79
+ Siga as skills/referências aplicáveis à stack. Princípios gerais:
80
+
81
+ - Nomes que descrevem comportamento, não implementação.
82
+ - Isole dependências externas com mocks/fakes/stubs no estilo da biblioteca em uso.
83
+ - Teste pelo comportamento público; cubra o caminho feliz, bordas e pelo menos um caso de erro.
84
+ - Determinismo: sem dependência de tempo real, rede, ordem de execução ou estado compartilhado.
85
+ - Não deixe apenas esqueleto vazio (`todo`/`skip`) se for possível escrever uma asserção real; use-os só quando faltar contexto de verdade e explique no resumo.
86
+
87
+ ## 4. Executar e medir cobertura (modos Executar e Criar e executar)
45
88
 
46
- - Para use cases: teste unitário mockando as ports (`InMemory*Repository` ou `jest.Mocked<Port>`), cobrindo o caminho feliz e pelo menos um erro de domínio.
47
- - Para controllers: teste de integração com `supertest`, cobrindo status code, shape da resposta e um caso de validação inválida.
48
- - Para entidades/value objects: teste unitário puro das invariantes (construtor/factory lançando erro de domínio em estado inválido).
49
- - Não implemente apenas esqueleto vazio (`it.todo`) quando for possível escrever uma asserção real com a informação disponível no arquivo-fonte; use `it.todo`/`.skip` apenas quando genuinamente faltar contexto (ex.: dependência externa não mapeada) e explique o motivo no resumo final.
89
+ 1. Use o comando de teste e de cobertura que o projeto já define; se não houver, derive-o da documentação da biblioteca descoberta. Execute a partir da pasta principal.
90
+ 2. Rode com cobertura habilitada. Se a ferramenta de cobertura não estiver instalada/configurada, inclua-a na solicitação de autorização de dependências (seção 1). Sem autorização, execute os testes sem cobertura e informe que ela não está disponível, sugerindo como habilitar.
91
+ 3. Execute somente comandos de teste/cobertura e, quando autorizado, a instalação das dependências aprovadas. Não rode comandos que alterem o repositório ou o ambiente (`git commit/push/checkout/reset`, migrations, deploy etc.).
92
+ 4. Se houver falhas, **não corrija o código de produção**. Reporte cada teste que falhou, com a mensagem e a causa provável.
93
+ 5. Extraia do relatório a **cobertura de linhas** (percentual total e, quando disponível, por arquivo revisado/alterado). Se o relatório também trouxer ramos/funções, pode citar, mas o número principal é o de linhas.
50
94
 
51
- ## 4. Resumo final
95
+ ## 5. Resumo final
52
96
 
53
- Ao terminar, apresente:
97
+ Apresente, conforme o modo:
54
98
 
55
- 1. **Criados:** arquivos de teste novos, com o caminho completo.
56
- 2. **Atualizados:** arquivos de teste existentes que receberam novos casos.
57
- 3. **Ignorados:** arquivos de código sem teste gerado e o motivo (ex.: módulo sem lógica, DTO puro).
58
- 4. **Pendências:** casos que ficaram como `it.todo`/`.skip` e o que falta para implementá-los.
99
+ 1. **Stack detectada:** linguagem/framework, biblioteca de testes e de cobertura, skills consultadas ou referências externas usadas (nome e link).
100
+ 2. **Criados / Atualizados / Ignorados:** caminhos completos e o motivo dos ignorados (modos com criação).
101
+ 3. **Execução:** comando usado, total de testes, passaram, falharam, ignorados (modos com execução).
102
+ 4. **Cobertura de linhas:** percentual total e dos arquivos relevantes; ou o motivo de não estar disponível (modos com execução).
103
+ 5. **Pendências:** testes marcados como `todo`/`skip`, falhas a tratar e o que falta para resolvê-los.
59
104
 
60
105
  ## Não fazer
61
106
 
62
- - Não alterar código de produção (`src/`) — apenas arquivos de teste.
63
- - Não quebrar a estrutura espelhada entre `src/` e `test/` quando o projeto usa pasta `test/` separada.
107
+ - Não presumir a pasta principal do projeto nem o modo de operação; perguntar.
108
+ - Não alterar código de produção — apenas arquivos de teste.
109
+ - Não executar testes no modo Criar, nem criar/alterar arquivos no modo Executar.
110
+ - Não instalar dependências sem autorização explícita do usuário, nem trocar a biblioteca de testes do projeto.
111
+ - Não corrigir código de produção para fazer teste passar; apenas reportar a falha.
64
112
  - Não sobrescrever testes existentes com asserções reais sem necessidade.
65
- - Não testar detalhes de implementação privada — teste pelo comportamento público (ver skill `jest-testing`).
113
+ - Não usar a web quando houver skill aplicável, nem para contradizer uma skill.
114
+ - Não aplicar tratamento diferente por linguagem/framework além do que a skill ou referência aplicável determinar.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: dart
3
+ description: Convenções da linguagem Dart da DS9 — orientação a objetos como abordagem padrão, nomenclatura oficial do Dart (Effective Dart), documentação com `///`, null safety, tratamento de erros, análise estática, formatação e testes. Use ao escrever ou revisar qualquer código Dart (CLI, servidor, pacote ou app Flutter), definir classes/tipos, nomear arquivos e identificadores, documentar código, ou quando o usuário pedir "boas práticas Dart", "padrão Dart", "nomenclatura Dart" ou "documentar com ///".
4
+ ---
5
+
6
+ # Dart — Diretrizes DS9
7
+
8
+ Convenções da **linguagem Dart**, válidas para qualquer projeto (CLI, servidor, pacote ou aplicativo). Regras específicas de Flutter (widgets, estado, UI) não fazem parte desta skill. Base: guia oficial *Effective Dart*, documentação do Dart e as skills Dart do projeto `lazy_forge` (`.agents/skills`). Em caso de dúvida sobre versão da linguagem, confirme a versão do SDK no `pubspec.yaml` antes de usar recursos novos.
9
+
10
+ ## 1. Orientação a objetos como padrão
11
+
12
+ O código Dart da DS9 é **orientado a objetos**. Modele o domínio com classes e deixe o comportamento junto dos dados.
13
+
14
+ - **Comportamento em métodos, não em funções soltas:** lógica de negócio vive em classes (entidades, serviços, casos de uso). Funções de nível superior ficam restritas a `main()` e a pequenos utilitários verdadeiramente genéricos e sem estado; mesmo estes, prefira como métodos estáticos de uma classe coesa ou como `extension`.
15
+ - **Encapsulamento:** campos privados (`_campo`) com acesso por getters/métodos; exponha o mínimo necessário. Estado interno nunca é alterado de fora da classe.
16
+ - **Imutabilidade por padrão:** campos `final`, construtores `const` quando possível, e novas instâncias (`copyWith`/métodos que retornam um novo objeto) em vez de mutação onde o domínio pedir.
17
+ - **Composição sobre herança:** injete dependências pelo construtor (como `abstract interface class` ou `abstract class`) e componha objetos; use herança só para relação "é um" genuína.
18
+ - **Polimorfismo no lugar de `if`/`switch` por tipo:** variação de comportamento vai em subclasses/implementações, não em cadeias de `is`/`switch` espalhadas. Use `sealed class` para famílias fechadas de tipos; `switch` exaustivo sobre elas é aceitável quando o comportamento não pertence ao tipo (ex.: decodificar dados externos).
19
+ - **Contratos explícitos:** dependências externas (banco, rede, relógio) atrás de uma interface (`abstract interface class`), para troca e teste.
20
+
21
+ ### Evite o estilo funcional como abordagem principal
22
+
23
+ Dart é multiparadigma, mas aqui o padrão é objetos. Isso **não** proíbe os recursos idiomáticos da linguagem; proíbe construir a arquitetura em torno de funções.
24
+
25
+ - Evite pipelines longos e encadeados (`map().where().fold().expand()...`) que escondem regra de negócio; se passar de 2 ou 3 etapas, extraia para um método nomeado ou use um laço `for` claro.
26
+ - Evite passar funções/closures como mecanismo principal de extensão (callbacks em cascata, funções de ordem superior como "estratégia"); prefira um objeto com método bem nomeado.
27
+ - Evite funções que retornam funções, currying e composição de funções; evite tipos como `Function` solto (use `typedef` ou interface quando um callback for inevitável).
28
+ - Evite `Either`/`Result` genéricos e estilos monádicos criados à mão quando exceção tipada ou um tipo de resultado `sealed` do domínio resolve de forma mais legível. **Exceção:** em projetos que seguem as skills `hex-pattern-dart`, `dart-frog` ou `flutter`, o `TaskEither` do `fpdart` (com `TaskEither.tryCatch`, `map`, `flatMap`, `mapLeft`) é o padrão obrigatório nos contratos entre camadas; ele não se estende ao domínio e aos models, que continuam orientados a objetos.
29
+ - Aceitável e idiomático: `for` com `collection-if`/`collection-for` em literais, `map`/`where`/`toList` simples (1 a 2 etapas), `async`/`await`, callbacks exigidos por APIs de terceiros e a composição de `TaskEither` conforme essas skills.
30
+
31
+ ## 2. Nomenclatura (Effective Dart)
32
+
33
+ | Elemento | Convenção | Exemplo |
34
+ |---|---|---|
35
+ | Classes, enums, mixins, extensions, typedefs, parâmetros de tipo | `UpperCamelCase` | `OrderService`, `PaymentStatus`, `T` |
36
+ | Variáveis, parâmetros, campos, métodos, funções, getters | `lowerCamelCase` | `totalPrice`, `findById()` |
37
+ | **Constantes** (incl. `const`/`static const`/valores de enum) | `lowerCamelCase` (**não** `SCREAMING_CAPS`) | `defaultTimeout`, `maxRetries` |
38
+ | Pacotes, diretórios, arquivos, prefixos de import | `lowercase_with_underscores` | `order_service.dart`, `import '...' as http_client;` |
39
+ | Membros e tipos privados da biblioteca | prefixo `_` | `_cache`, `_OrderMapper` |
40
+
41
+ Regras adicionais:
42
+
43
+ - **Arquivo = classe principal:** `UserRepository` fica em `user_repository.dart`. Uma classe pública principal por arquivo; testes em `<nome>_test.dart`.
44
+ - **Siglas:** com mais de duas letras, capitalize como palavra (`HttpClient`, `JsonParser`, `UserId`); com duas letras, mantenha maiúsculas (`IOSink`).
45
+ - **Sem prefixos/sufixos de tipo:** não use `I` para interfaces (`IUserRepository`), notação húngara, nem `k` em constantes (`kTimeout`).
46
+ - **Booleanos** com nome afirmativo: `isEmpty`, `hasPermission`, `canRetry`; evite negações (`isNotValid`).
47
+ - **Métodos** começam com verbo (`calculateTotal`, `save`); **getters e propriedades** são substantivos, sem prefixo `get` (`total`, não `getTotal`).
48
+ - **Nomes descritivos:** sem abreviações obscuras nem nomes de uma letra fora de laços/lambdas curtos; o nome expressa intenção, não implementação.
49
+ - **Variáveis não usadas:** use `_` (wildcard) em vez de nomes sem uso.
50
+ - **Ordem em arquivos:** `dart:` → `package:` → relativos, cada grupo em ordem alfabética; prefira imports relativos dentro de `lib/` do próprio pacote, exceto quando a skill do framework definir outro padrão (a `flutter` usa `package:`).
51
+
52
+ ## 3. Documentação e comentários (`///`)
53
+
54
+ **Regra de inclusão:** toda declaração **pública** (biblioteca, classe, enum, mixin, extension, construtor nomeado relevante, método, função, getter/setter, campo e constante) **deve** ter comentário de documentação com `///`. Declarações privadas só precisam quando a lógica não for óbvia. Código novo sem `///` nas declarações públicas é pendência de review.
55
+
56
+ - Use **sempre `///`**, em linhas consecutivas; **nunca** `/** ... */`. Use `//` apenas para comentários de implementação internos, explicando o **porquê**, nunca o óbvio.
57
+ - **Primeira linha:** uma frase única e resumida, terminada em ponto, seguida de uma linha `///` vazia antes do restante. Uma linha totalmente em branco (sem `///`) encerra o comentário.
58
+ - **Abertura por tipo de membro:** propriedades/getters com sintagma nominal (`/// O raio da esfera.`); booleanos com "Se"/"Whether" no idioma do projeto (`/// Se a conexão está ativa.`); métodos com verbo na 3ª pessoa (`/// Inicializa o banco.`).
59
+ - **Sem redundância:** não repita a assinatura nem o nome ("Esta classe é...", "O método foo faz...").
60
+ - **Sem tags estilo Javadoc** (`@param`, `@return`, `@throws`): descreva parâmetros, retorno e exceções em prosa, referenciando parâmetros com `[nome]`.
61
+ - **Links:** use colchetes para símbolos no escopo (`[Order]`, `[Order.total]`, sem parênteses); construtor sem nome como `[Order.new]`; crases para palavras-chave e literais (`` `null` ``, `` `true` ``). Blocos de código com a linguagem (` ```dart `).
62
+ - **Posição:** o comentário `///` vem **antes** das anotações (`@override` etc.).
63
+ - **Herança e pares getter/setter:** não duplique documentação em `@override` sem mudança de comportamento; em par getter/setter, documente só o getter.
64
+ - **Idioma:** siga o idioma já usado no projeto, de forma consistente.
65
+ - Valide com `dart analyze` (referências entre colchetes resolvidas) e, opcionalmente, `dart doc`.
66
+
67
+ ```dart
68
+ // Evitar
69
+ /**
70
+ * Busca o pedido.
71
+ * @param id identificador
72
+ * @return o pedido
73
+ */
74
+ Order find(String id) { ... }
75
+
76
+ // Preferir
77
+ /// Busca o pedido pelo [id].
78
+ ///
79
+ /// Lança [OrderNotFoundException] se não existir pedido com esse identificador.
80
+ Order findById(String id) { ... }
81
+ ```
82
+
83
+ ## 4. Construtores e classes
84
+
85
+ - Prefira **parâmetros iniciais** (`this.campo`) e `super.parametro` a atribuições manuais; use `required` em parâmetros nomeados obrigatórios.
86
+ - Construtores `const` em classes imutáveis; `factory` para validação/cache e para criar a partir de dados externos (`fromJson`).
87
+ - **Invariantes no construtor/factory:** estado inválido não pode existir; valide e lance exceção de domínio.
88
+ - **Primary constructors** (declarar campos no cabeçalho da classe): disponíveis só a partir do Dart 3.13 (experimental no 3.12, via flag). Use **somente se o SDK do projeto suportar**; caso contrário, use construtores tradicionais. Não migre código existente apenas por isso.
89
+ - Use `sealed`, `final`, `base` e `interface` para controlar quem pode estender ou implementar uma classe, quando a API for pública.
90
+
91
+ ## 5. Null safety e tipos
92
+
93
+ - Nada de `dynamic` em código novo; tipos explícitos em APIs públicas, em genéricos (`List<Order>`) e em retornos.
94
+ - Evite `!` (asserção de nulo); prefira promoção de tipo, `?.`, `??` ou tratar o nulo. `late` só quando a inicialização estiver garantida antes do uso.
95
+ - Prefira `final` a `var` quando o valor não muda; evite `as` sem garantia do tipo em tempo de execução.
96
+ - **Pattern matching e records** (Dart 3): use para decodificar dados externos (JSON) e `switch` exaustivo em `sealed`; não use para o que um `is` simples, um acesso a propriedade ou uma comparação booleana resolvem. Dados malformados devem falhar com erro explícito (`FormatException`), nunca ser descartados em silêncio.
97
+
98
+ ## 6. Tratamento de erros
99
+
100
+ - Falhas recuperáveis: **`Exception` tipada do domínio** (`class OrderNotFoundException implements Exception`), nunca `throw 'texto'` nem lançar `Exception` genérica. Em projetos `hex-pattern-dart`/`dart-frog`, as falhas trafegam como `Left` de `TaskEither` com as exceções por camada definidas em `hex-pattern-dart` (em Flutter, siga a skill `flutter`) (`BusinessException`, `ClientException`, `MiddlewareException`).
101
+ - **Nunca capture `Error`** (nem `TypeError`, `ArgumentError`, etc.): indicam bugs de programação. Capture tipos específicos; não use `catch (e)` amplo sem relançar.
102
+ - Use `rethrow` para propagar preservando o stack trace; não engula exceções em silêncio nem registre dados sensíveis.
103
+ - Mensagens de erro expostas a usuários não vazam detalhes internos.
104
+
105
+ ## 7. Assincronismo
106
+
107
+ - `async`/`await` em vez de encadear `.then()`; sempre aguarde (`await`) ou trate explicitamente os `Future`s (sem "fire-and-forget" acidental).
108
+ - Libere recursos (`close`/`cancel`/`dispose`) em `try/finally`; cancele subscriptions e controllers de `Stream`.
109
+ - Não bloqueie o isolate principal com trabalho pesado síncrono; use isolates quando necessário.
110
+
111
+ ## 8. Qualidade, formatação e testes
112
+
113
+ - **Análise estática:** `analysis_options.yaml` na raiz do pacote com um conjunto base (`package:lints/recommended.yaml` ou `package:flutter_lints/flutter.yaml`) e `strict-casts`, `strict-inference` e `strict-raw-types` ativos. Exclua só código gerado (`**/*.g.dart`).
114
+ - Rode `dart analyze` e corrija os avisos; use `dart fix --apply` para correções mecânicas (revise com `--dry-run`) e `dart format .` antes de commitar. Suprima diagnósticos (`// ignore:`) só com justificativa e no menor escopo.
115
+ - **Testes:** `package:test` (ou `flutter_test` em Flutter), arquivos em `test/` espelhando `lib/` com sufixo `_test.dart`; `group()` por funcionalidade, `setUp()`/`tearDown()` para preparo, `expect()` com matchers; dependências externas isoladas por interface/mocks. Para criar e executar testes, use o agente `test-writer`.
116
+
117
+ ## 9. Checklist de review
118
+
119
+ - [ ] Regra de negócio está em classes, sem funções soltas nem cadeias funcionais longas?
120
+ - [ ] Toda declaração pública tem `///` no formato da seção 3?
121
+ - [ ] Nomes seguem a tabela da seção 2 (inclusive constantes em `lowerCamelCase` e arquivos em `snake_case`)?
122
+ - [ ] Sem `dynamic`, `!` desnecessário ou `catch` de `Error`?
123
+ - [ ] Campos `final`, encapsulamento e construtores `const` onde cabem?
124
+ - [ ] `dart analyze` limpo, `dart format` aplicado e testes cobrindo o comportamento novo?
125
+
126
+ ## 10. Arquivos complementares
127
+
128
+ Em caso de dúvida, consulte (via `list_skill_files` / `get_skill_file` com `skill="dart"`; ou direto na pasta `dart/`, se o host não tiver as tools):
129
+
130
+ - `examples/` — código de referência: `entity.dart`, `repository.dart`, `error_handling.dart`, `order_test.dart`. Use quando precisar de um exemplo de entidade, contrato/caso de uso, erros ou teste.
131
+ - `references/` — `naming.md` (nomenclatura), `documentation.md` (`///`), `checklist.md` (review detalhado).
132
+
133
+ ## Não fazer
134
+
135
+ - Não usar `/** ... */` nem tags `@param`/`@return`/`@throws`.
136
+ - Não usar `SCREAMING_CAPS`, prefixo `I`, `k` ou notação húngara.
137
+ - Não criar funções de nível superior com regra de negócio nem pipelines funcionais extensos (exceto a composição de `TaskEither` exigida pelas skills `hex-pattern-dart`, `dart-frog` e `flutter`).
138
+ - Não declarar `dynamic`, `Function` solto ou `throw` de strings.
139
+ - Não duplicar regras de outras skills; para testes, ver o agente `test-writer`.
@@ -0,0 +1,37 @@
1
+ /// Exemplo: entidade imutável, encapsulada e documentada com `///`.
2
+ library;
3
+
4
+ /// Status possíveis de um [Order].
5
+ enum OrderStatus {
6
+ /// Pedido criado e ainda não pago.
7
+ pending,
8
+
9
+ /// Pedido pago.
10
+ paid,
11
+ }
12
+
13
+ /// Pedido do domínio, com invariantes validadas na criação.
14
+ class Order {
15
+ /// Cria um pedido.
16
+ ///
17
+ /// Lança [ArgumentError] se [id] estiver vazio ou [total] for negativo.
18
+ Order({required this.id, required this.total, this.status = OrderStatus.pending}) {
19
+ if (id.isEmpty) throw ArgumentError.value(id, 'id', 'não pode ser vazio');
20
+ if (total < 0) throw ArgumentError.value(total, 'total', 'não pode ser negativo');
21
+ }
22
+
23
+ /// Identificador único do pedido.
24
+ final String id;
25
+
26
+ /// Valor total do pedido.
27
+ final double total;
28
+
29
+ /// Situação atual do pedido.
30
+ final OrderStatus status;
31
+
32
+ /// Se o pedido já foi pago.
33
+ bool get isPaid => status == OrderStatus.paid;
34
+
35
+ /// Retorna uma cópia deste pedido já marcada como paga.
36
+ Order markAsPaid() => Order(id: id, total: total, status: OrderStatus.paid);
37
+ }
@@ -0,0 +1,36 @@
1
+ /// Exemplo: exceções tipadas e tratamento sem engolir erros.
2
+ library;
3
+
4
+ /// Falha ao decodificar dados externos.
5
+ class InvalidPayloadException implements Exception {
6
+ /// Cria a exceção com a [message] explicando o problema.
7
+ const InvalidPayloadException(this.message);
8
+
9
+ /// Descrição do problema, segura para exibir.
10
+ final String message;
11
+
12
+ @override
13
+ String toString() => 'InvalidPayloadException: $message';
14
+ }
15
+
16
+ /// Lê um valor numérico de um payload externo.
17
+ class PayloadReader {
18
+ /// Lê o campo `amount` de [json].
19
+ ///
20
+ /// Lança [InvalidPayloadException] se ele não existir ou não for numérico.
21
+ double readAmount(Map<String, Object?> json) {
22
+ return switch (json['amount']) {
23
+ final num amount => amount.toDouble(),
24
+ _ => throw const InvalidPayloadException('campo "amount" ausente ou inválido'),
25
+ };
26
+ }
27
+
28
+ /// Lê o valor e propaga falhas de domínio preservando o stack trace.
29
+ double readOrRethrow(Map<String, Object?> json) {
30
+ try {
31
+ return readAmount(json);
32
+ } on InvalidPayloadException {
33
+ rethrow; // nunca `catch (e)` amplo nem captura de `Error`
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,34 @@
1
+ /// Exemplo: teste unitário com `group`, `setUp` e `expect`.
2
+ ///
3
+ /// Em um projeto real o arquivo fica em `test/`, espelhando `lib/`.
4
+ library;
5
+
6
+ import 'package:test/test.dart';
7
+
8
+ import 'entity.dart';
9
+ import 'repository.dart';
10
+
11
+ void main() {
12
+ group('PayOrder', () {
13
+ late InMemoryOrderRepository repository;
14
+ late PayOrder useCase;
15
+
16
+ setUp(() {
17
+ repository = InMemoryOrderRepository();
18
+ useCase = PayOrder(repository);
19
+ });
20
+
21
+ test('marca o pedido como pago e persiste', () async {
22
+ await repository.save(Order(id: '1', total: 10));
23
+
24
+ final paid = await useCase.execute('1');
25
+
26
+ expect(paid.isPaid, isTrue);
27
+ expect((await repository.findById('1'))!.isPaid, isTrue);
28
+ });
29
+
30
+ test('lança OrderNotFoundException quando o pedido não existe', () {
31
+ expect(() => useCase.execute('x'), throwsA(isA<OrderNotFoundException>()));
32
+ });
33
+ });
34
+ }
@@ -0,0 +1,57 @@
1
+ /// Exemplo: contrato (porta) e implementação, com dependência injetada.
2
+ library;
3
+
4
+ import 'entity.dart';
5
+
6
+ /// Contrato de persistência de pedidos.
7
+ abstract interface class OrderRepository {
8
+ /// Busca o pedido pelo [id]; retorna `null` se não existir.
9
+ Future<Order?> findById(String id);
10
+
11
+ /// Salva o [order].
12
+ Future<void> save(Order order);
13
+ }
14
+
15
+ /// Implementação em memória, útil em testes.
16
+ class InMemoryOrderRepository implements OrderRepository {
17
+ final Map<String, Order> _orders = {};
18
+
19
+ @override
20
+ Future<Order?> findById(String id) async => _orders[id];
21
+
22
+ @override
23
+ Future<void> save(Order order) async {
24
+ _orders[order.id] = order;
25
+ }
26
+ }
27
+
28
+ /// Caso de uso: paga um pedido existente.
29
+ class PayOrder {
30
+ /// Cria o caso de uso com o [repository] injetado.
31
+ PayOrder(this._repository);
32
+
33
+ final OrderRepository _repository;
34
+
35
+ /// Marca como pago o pedido [id].
36
+ ///
37
+ /// Lança [OrderNotFoundException] se o pedido não existir.
38
+ Future<Order> execute(String id) async {
39
+ final order = await _repository.findById(id);
40
+ if (order == null) throw OrderNotFoundException(id);
41
+ final paid = order.markAsPaid();
42
+ await _repository.save(paid);
43
+ return paid;
44
+ }
45
+ }
46
+
47
+ /// Erro de domínio: pedido não encontrado.
48
+ class OrderNotFoundException implements Exception {
49
+ /// Cria a exceção para o pedido [id].
50
+ const OrderNotFoundException(this.id);
51
+
52
+ /// Identificador procurado.
53
+ final String id;
54
+
55
+ @override
56
+ String toString() => 'Pedido não encontrado: $id';
57
+ }
@@ -0,0 +1,12 @@
1
+ # Dart — Checklist de review detalhado
2
+
3
+ - [ ] Regra de negócio em classes; sem funções soltas nem pipelines longos.
4
+ - [ ] Dependências externas atrás de `abstract interface class`, injetadas no construtor.
5
+ - [ ] Campos `final`, construtores `const` onde couber, estado privado encapsulado.
6
+ - [ ] Toda declaração pública com `///` (sem `/** */`, sem `@param`).
7
+ - [ ] Nomes: `UpperCamelCase` (tipos), `lowerCamelCase` (membros e constantes), `snake_case` (arquivos).
8
+ - [ ] Sem `dynamic`, `!` desnecessário, `Function` solto ou `throw` de string.
9
+ - [ ] Sem `catch` de `Error`; `rethrow` preserva o stack trace.
10
+ - [ ] `Future`s aguardados; recursos liberados em `try/finally`.
11
+ - [ ] `dart analyze` limpo, `dart format` aplicado.
12
+ - [ ] Testes em `test/` espelhando `lib/`, com `group`/`setUp`/`expect`.
@@ -0,0 +1,26 @@
1
+ # Dart — Documentação com `///` (referência detalhada)
2
+
3
+ Complementa a seção 3 do `SKILL.md`.
4
+
5
+ ## Modelo
6
+
7
+ ```dart
8
+ /// Calcula o total do pedido.
9
+ ///
10
+ /// Soma os itens de [items] e aplica [discount] (entre 0 e 1).
11
+ /// Lança [ArgumentError] se [discount] estiver fora do intervalo.
12
+ double calculateTotal(List<Item> items, {double discount = 0}) { ... }
13
+ ```
14
+
15
+ ## Regras rápidas
16
+
17
+ - Primeira linha: frase única, terminada em ponto; depois linha `///` vazia.
18
+ - Propriedade: sintagma nominal. Booleano: "Se ...". Método: verbo na 3ª pessoa.
19
+ - Sem `@param`/`@return`; use prosa e `[nome]`.
20
+ - `///` antes de `@override` e outras anotações.
21
+ - Par getter/setter: documente só o getter.
22
+ - Não documente `@override` sem mudança de comportamento.
23
+
24
+ ## Validação
25
+
26
+ `dart analyze` resolve referências entre colchetes; `dart doc` gera a documentação.
@@ -0,0 +1,27 @@
1
+ # Dart — Nomenclatura (referência detalhada)
2
+
3
+ Complementa a seção 2 do `SKILL.md`.
4
+
5
+ ## Certo x errado
6
+
7
+ | Evitar | Preferir | Motivo |
8
+ |---|---|---|
9
+ | `MAX_RETRIES`, `kMaxRetries` | `maxRetries` | Constantes usam `lowerCamelCase` |
10
+ | `IUserRepository` | `UserRepository` | Sem prefixo `I` |
11
+ | `UserRepository.dart` | `user_repository.dart` | Arquivos em `snake_case` |
12
+ | `getTotal()` | `total` (getter) | Propriedade é substantivo, sem `get` |
13
+ | `isNotValid` | `isValid` | Booleano afirmativo |
14
+ | `HTTPClient` | `HttpClient` | Siglas com mais de 2 letras viram palavra |
15
+ | `data`, `tmp`, `x` | `orderTotals` | Nome expressa intenção |
16
+
17
+ ## Ordem de imports
18
+
19
+ 1. `dart:`
20
+ 2. `package:`
21
+ 3. relativos
22
+
23
+ Cada grupo em ordem alfabética, separado por linha em branco.
24
+
25
+ ## Privacidade
26
+
27
+ O prefixo `_` torna o membro privado à **biblioteca** (arquivo), não à classe.