@softize/opus 11.0.0 → 11.1.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.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,22 @@ Este arquivo viaja no pacote: num projeto, leia `node_modules/@softize/opus/CHAN
6
6
  Depois de qualquer bump, rode os gates (`typecheck` · `test` · `opus check` ·
7
7
  `manifest:check`) — eles apontam o que a mudança cobra do seu código.
8
8
 
9
+ ## 11.1.0 — 2026-08-21
10
+
11
+ O Opus passa a distribuir a skill `write-product-communication` para orientar documentação,
12
+ interface, mensagens de erro, CLI, onboarding e textos explicativos a partir da situação do
13
+ leitor. A página antes dedicada apenas a microcopy agora reúne a referência canônica de
14
+ comunicação, incluindo escrita normativa e tratamento de erros.
15
+
16
+ O `opus setup` expande o conteúdo dessa referência ao materializar a skill em `.agents` e
17
+ `.claude`. As instruções permanentes e as skills de UI, actions, mudanças e upgrades passam a
18
+ acionar a orientação nos fluxos em que produzem texto. Testes de criação e setup confirmam que
19
+ projetos novos recebem o conteúdo completo, sem depender de um link externo.
20
+
21
+ A home, as páginas iniciais e a mensagem de sucesso do `opus check` começam a migração da voz
22
+ existente: apresentam contexto e efeito antes das regras, evitam slogans e informam a próxima
23
+ etapa em linguagem natural.
24
+
9
25
  > As entradas 2.30.1–2.31.5 foram **reconstruídas do git** (o release publicava sem
10
26
  > passar por aqui). Uma delas — a 2.31.5, que mudou o rem base — é visual GLOBAL e
11
27
  > tinha ficado sem registro nenhum, o que é exatamente o caso que este arquivo existe
package/bin/cli.mjs CHANGED
@@ -190,7 +190,7 @@ async function cmdCheck(dir) {
190
190
  }
191
191
  const viaContrato = contracts > 0 ? ` (${contracts} contrato(s))` : ''
192
192
  if (findings.length === 0) {
193
- log('success', `✓ opus check: ${actions} action(s)${viaContrato}, 0 violação — padrão ok.`)
193
+ log('success', `✓ opus check: ${actions} action(s)${viaContrato}; nenhuma violação encontrada.`)
194
194
  return
195
195
  }
196
196
 
package/bin/lib/init.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  /** opus setup: aplica o marcador per-app e os artefatos Opus rastreáveis no repo. */
2
2
 
3
3
  import { promises as fs } from "node:fs";
4
+ import { tmpdir } from "node:os";
4
5
  import path from "node:path";
5
6
 
6
7
  import { materializeOpus, PACKAGE_VERSION } from "./materialize.mjs";
@@ -27,7 +28,12 @@ async function readJson(p) {
27
28
  /** Raiz do repo (sobe até achar `.git`); sem repo → null (o chamador decide o fallback). */
28
29
  export async function repoRootOf(dir) {
29
30
  let cur = path.resolve(dir);
31
+ const temporaryRoot = path.resolve(tmpdir());
30
32
  for (;;) {
33
+ // O diretório temporário global pode receber marcadores transitórios de ferramentas
34
+ // e sandboxes. Um projeto dentro dele ainda pode ter sua própria raiz Git, mas não deve
35
+ // herdar `/tmp/.git` como se todos os fixtures pertencessem ao mesmo repositório.
36
+ if (cur === temporaryRoot) return null;
31
37
  if (await exists(path.join(cur, ".git"))) return cur;
32
38
  const up = path.dirname(cur);
33
39
  if (up === cur) return null;
@@ -5,6 +5,7 @@ import { dirname, extname, join, relative, resolve } from 'node:path'
5
5
  import { fileURLToPath } from 'node:url'
6
6
 
7
7
  import { validateSkill } from './validate-skill.mjs'
8
+ import { expandDocIncludes } from './docs-include.mjs'
8
9
 
9
10
  export const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../..')
10
11
  export const PACKAGE_NAME = '@softize/opus'
@@ -97,7 +98,8 @@ function expectedFiles(exclude) {
97
98
  for (const file of filesUnder(join(PACKAGE_ROOT, sourceRoot))) {
98
99
  const source = `${sourceRoot}/${file.relative}`
99
100
  const destination = `${destinationRoot}/${file.relative}`
100
- const content = readFileSync(file.path, 'utf8')
101
+ const sourceContent = readFileSync(file.path, 'utf8')
102
+ const content = file.relative === 'SKILL.md' ? expandDocIncludes(sourceContent) : sourceContent
101
103
  expected.set(destination, { source, content, output: addMarker(destination, source, content) })
102
104
  }
103
105
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softize/opus",
3
- "version": "11.0.0",
3
+ "version": "11.1.0",
4
4
  "description": "End-to-end action protocol for TypeScript. Single package with subpath exports (core + adapters).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,3 +15,6 @@ artefatos de agentes fica em `base.json`; cada app Opus mantém seu marcador `op
15
15
  branch antes de commit/review e usar `upgrade-opus` para ler changelog e aplicar migrações.
16
16
  - Consultar as skills Opus materializadas conforme o workflow; não atribuir ao SDK decisões
17
17
  universais de domínio ou arquitetura.
18
+ - Usar `write-product-communication` ao criar ou alterar documentação, textos de interface,
19
+ mensagens de erro, CLI, onboarding ou explicações. Partir da situação do leitor, apresentar
20
+ contexto antes da regra e evitar slogans, absolutos e linguagem de manifesto.
@@ -26,6 +26,8 @@ existentes, mantendo navegação observável e componentes reutilizáveis sem la
26
26
  7. Usar diretamente a escala `rounded-*`; não criar radius por nome de componente quando
27
27
  `rounded-sm` a `rounded-xl` já expressam a forma.
28
28
  8. Testar estados de loading, vazio, erro, sucesso, permissão e interação relevante.
29
+ 9. Usar `write-product-communication` para labels, ajuda, estados vazios, confirmações e erros;
30
+ revisar o fluxo completo, não apenas cada string isolada.
29
31
 
30
32
  ## Verificação
31
33
 
@@ -21,6 +21,8 @@ registrados no runtime do projeto.
21
21
  1. Rodar `node scripts/scaffold.mjs <resource> <verb> <kind>` a partir desta skill.
22
22
  2. Colocar o contrato em módulo importável pelos consumidores e o binding no lado servidor.
23
23
  3. Substituir os exemplos do scaffold por schemas, descrições e comportamento do domínio.
24
+ Usar `write-product-communication` nas descrições, mensagens e textos projetados para UI
25
+ ou documentação.
24
26
  4. Declarar `requires` somente com `authorize` efetivo; `requires` sozinho não protege a action.
25
27
  5. Exportar e registrar o binding no domínio/runtime existente.
26
28
  6. Acionar `test-opus-action` para cobrir contrato, sucesso, erros e efeitos relevantes.
@@ -25,6 +25,8 @@ dependências server-only, bindings registrados, testes e gates verdes.
25
25
  5. Usar `create-opus-action`, `test-opus-action` ou `build-opus-ui` quando a mudança entrar
26
26
  nesses workflows especializados.
27
27
  6. Atualizar manifest, docs geradas e exemplos somente pelos comandos do repo.
28
+ 7. Usar `write-product-communication` sempre que a mudança alcançar documentação, UI, CLI,
29
+ mensagens de erro ou outro texto destinado a uma pessoa.
28
30
 
29
31
  ## Verificação
30
32
 
@@ -19,6 +19,8 @@ materializados e projeções geradas consistentes no mesmo diff.
19
19
  4. Aplicar migrações no código por domínio, sem compatibilidade temporária silenciosa.
20
20
  5. Rodar `opus check`, typecheck, testes, build e geradores declarados pelo projeto.
21
21
  6. Conferir `base.json`, lockfile, skills, hooks, instruções e outputs gerados no diff.
22
+ 7. Usar `write-product-communication` ao redigir changelog, guia de migração e mensagens
23
+ adicionadas ou alteradas durante o upgrade.
22
24
 
23
25
  ## Verificação
24
26
 
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: write-product-communication
3
+ description: Escreve e revisa comunicação de produto clara, humana e orientada ao leitor. Usar ao criar ou alterar documentação, mensagens de erro, textos de interface, CLI, onboarding, ajuda, explicações, comentários ou qualquer conteúdo que uma pessoa precise compreender.
4
+ ---
5
+
6
+ # Escrever comunicação de produto
7
+
8
+ ## Resultado
9
+
10
+ Entregar uma comunicação que parte da situação do leitor, oferece o contexto necessário e
11
+ permite que a pessoa compreenda ou prossiga sem decodificar a linguagem interna da equipe.
12
+
13
+ ## Procedimento
14
+
15
+ 1. Identificar quem lerá o texto, o que essa pessoa tenta fazer e o que precisa compreender ou
16
+ decidir em seguida.
17
+ 2. Ler a comunicação no fluxo completo em que aparecerá, incluindo estados anteriores e
18
+ posteriores.
19
+ 3. Escrever a partir do problema e do efeito percebido; introduzir mecanismos e termos técnicos
20
+ somente quando acrescentarem precisão.
21
+ 4. Distinguir princípios, regras, recomendações, comportamentos, verificações e exceções.
22
+ 5. Revisar o texto fora do contexto da implementação e remover pressupostos, slogans,
23
+ advertências desnecessárias e detalhes internos.
24
+ 6. Confirmar que erros explicam o ocorrido, o impacto e uma próxima ação real quando ela existir.
25
+
26
+ ## Referência canônica
27
+
28
+ <!-- opus-doc: microcopy.md -->
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Comunicação de produto"
3
+ short_description: "Escreva textos claros, humanos e úteis"
4
+ default_prompt: "Use $write-product-communication para revisar esta comunicação pelo ponto de vista do leitor."
@@ -5,8 +5,8 @@
5
5
  *
6
6
  * 1. **Pool com teto** — crie o `Pool` com `max` (e/ou use `maxConcurrent` aqui):
7
7
  * query de LLM não esgota as conexões do app.
8
- * 2. **Transação READ ONLY** — `BEGIN TRANSACTION READ ONLY`: escrita morre no
9
- * servidor, qualquer que seja o SQL.
8
+ * 2. **Transação READ ONLY** — `BEGIN TRANSACTION READ ONLY`: o servidor rejeita
9
+ * qualquer tentativa de escrita, independentemente do SQL recebido.
10
10
  * 3. **`SET LOCAL ROLE` por transação** — o alcance é do contexto: com grants
11
11
  * default-fechado, `sales_read` não enxerga `hr_employees.salary` nem por
12
12
  * SELECT criativo. (Criar os roles/grants é migração sua; aqui só se assume.)
@@ -4,9 +4,9 @@ title: Actions & contratos
4
4
 
5
5
  # Actions & contratos
6
6
 
7
- A action é a unidade do Opus. O contrato (entidade + input/output + metadados) mora no package
8
- compartilhado; a API amarra o handler; a web renderiza a partir do mesmo contrato. Um shape,
9
- três consumidores.
7
+ Uma action descreve uma operação que cliente e servidor precisam compreender da mesma forma.
8
+ Seu contrato reúne entidade, entrada, saída e metadados no package compartilhado. A API conecta
9
+ o handler e a web usa a mesma definição para executar ou renderizar a operação.
10
10
 
11
11
  ## Contrato primeiro
12
12
 
@@ -51,8 +51,9 @@ export const workspaceCreate = bindAction(workspaceCreateContract, {
51
51
 
52
52
  ## Ordem canônica dos campos
53
53
 
54
- > O `opus check` reprova fora desta ordem é a régua, 0 violação antes de entregar. A skill
55
- > `create-opus-action` gera contrato e binding no formato certo por construção.
54
+ > Esta ordem mantém contratos previsíveis para leitura e geração. O `opus check` informa os
55
+ > campos que precisam ser reposicionados, e a skill `create-opus-action` cria o contrato e o
56
+ > binding nessa estrutura.
56
57
 
57
58
  ```text
58
59
  name → kind → (label / summary / messages / tags…)
@@ -130,7 +131,7 @@ descartável — vira o contrato que o backend honra.
130
131
  import { useLookupAction } from '@softize/opus/client'
131
132
  import { ActionForm } from '@softize/opus/ui/react'
132
133
 
133
- // Lista paginada, tipada pelo contrato zero shape duplicado.
134
+ // O contrato mantém a lista paginada tipada sem exigir uma definição paralela.
134
135
  const { rows, fetchNextPage } = useLookupAction(workspaceListContract)
135
136
 
136
137
  // Form contract-driven: os campos (fields) moram NO contrato.
@@ -21,8 +21,9 @@ interface AuthAdapter {
21
21
  }
22
22
  ```
23
23
 
24
- `req` é o request cru do `ServerAdapter`. O `user` sai dos claims/sessão; o `can` é a régua
25
- de autorização o Opus chama, não decide.
24
+ `req` é o request cru do `ServerAdapter`. O `user` vem dos claims ou da sessão, e o driver
25
+ fornece a função `can` que decide cada autorização. O Opus chama essa função sem definir a
26
+ política usada por ela.
26
27
 
27
28
  ## Drivers
28
29
 
@@ -9,7 +9,8 @@ valida as convenções e expõe o estado vivo pros agentes via MCP.
9
9
 
10
10
  ## Gates
11
11
 
12
- > A régua de entrega: 0 violação antes de qualquer handoff. Rode no CI e antes de commitar.
12
+ > Use o check no CI e antes de entregar uma mudança. Ele informa quais contratos precisam de
13
+ > ajuste e encerra com sucesso quando não encontra violações.
13
14
 
14
15
  ```bash
15
16
  opus check src # valida as convenções das actions (exit ≠ 0 se violar)
@@ -88,7 +88,7 @@ const { rows } = await bi.query(sqlDoLlm, { role: roleFor(ctx) })
88
88
 
89
89
  1. **Pool com teto** (`max` do pool e/ou `maxConcurrent`) — query de LLM não esgota as
90
90
  conexões do app;
91
- 2. **`BEGIN TRANSACTION READ ONLY`** — escrita morre no servidor;
91
+ 2. **`BEGIN TRANSACTION READ ONLY`** — o servidor rejeita tentativas de escrita;
92
92
  3. **`SET LOCAL ROLE` por transação** — o alcance é do CONTEXTO (crie os roles com grants
93
93
  default-fechado nas suas migrações: sem isso, `sales_read` leria `hr_employees`);
94
94
  4. **Protocolo estendido** — o SQL roda sempre com array de valores; multi-sentença
@@ -4,42 +4,34 @@ title: Getting started
4
4
 
5
5
  # Getting started
6
6
 
7
- O Opus é um SDK/protocolo spec-driven: o domínio **É** a aplicação (contratos +
8
- actions); front e back são cascas. Um projeto Opus-based pina o Opus, herda o runtime e segue os gates.
7
+ O Opus ajuda cliente e servidor a preservar as mesmas regras à medida que uma aplicação
8
+ evolui. Entidades e contratos de action ficam em uma camada compartilhada; o runtime, a UI e
9
+ as ferramentas usam essas definições sem exigir schemas e tipos paralelos.
9
10
 
10
11
  ## O modelo
11
12
 
12
- > Antes de qualquer arquivo: por que o Opus existe e o que ele assume.
13
+ > Comece pelo problema que o modelo compartilhado resolve antes de conhecer seus arquivos.
13
14
 
14
- A aplicação é o **domínio** entidades, dicts e contratos de action. A API e a web são cascas
15
- que consomem esse domínio: zero shape duplicado. O Opus entrega o núcleo (runtime, adapters, UI,
16
- CLI) e os gates que mantêm o padrão. O que cada projeto adiciona é o seu domínio; o resto vem pinado.
15
+ As regras de uma aplicação costumam aparecer em vários lugares: validação, transporte, API,
16
+ formulários e documentação. No Opus, entidades, dicts e contratos de action descrevem essas
17
+ regras uma vez. A API e a web consomem a mesma definição, enquanto runtime, adapters, UI, CLI
18
+ e verificações ajudam a mantê-la consistente. Cada projeto acrescenta seu domínio sobre essa
19
+ base versionada.
17
20
 
18
21
  ## Começar do zero
19
22
 
20
23
  > Projeto novo não se monta à mão: o esqueleto canônico sai do `opus create`, com os
21
24
  > pré-requisitos do protocolo, da UI e do preview já plugados — e os gates verdes.
22
25
 
23
- O Opus mora no registry da Softize (não no npm público) — uma vez por máquina, ensine
24
- o escopo ao pnpm; dentro do projeto criado o `.npmrc` já cuida disso:
25
-
26
26
  ```bash
27
- pnpm config set @softize:registry https://registry.softize.com.br/ --global # 1x por máquina
28
-
29
27
  pnpm dlx @softize/opus create meu-app
30
28
  cd meu-app && git init && pnpm install && pnpm test
31
29
  ```
32
30
 
33
- Máquina nova: se o pnpm reclamar que o diretório global de binários não está no PATH
34
- (o `dlx` exige), rode `pnpm setup` e reabra o terminal — também é 1x por máquina. Se o
35
- setup acusar seção pnpm antiga no shell rc (`ERR_PNPM_BAD_SHELL_SECTION`), é resquício
36
- de versão anterior: `pnpm setup --force` substitui o bloco dele.
37
-
38
- Release recém-saída (menos de 24h): a quarentena do pnpm resolve o `dlx` pra versão
39
- ANTIGA em silêncio ("Comando desconhecido" = sintoma clássico). Fure com a versão
40
- explícita — `pnpm dlx @softize/opus@<versão> create meu-app` — ou com a flag
41
- `pnpm --config.minimum-release-age=0 dlx …`. Dentro de projeto o pnpm se resolve
42
- sozinho (auto-exclui o Opus da quarentena no install).
31
+ O comando cria a estrutura inicial e instala a versão estável disponível. Para experimentar
32
+ uma versão específica, acrescente-a ao pacote: `pnpm dlx @softize/opus@<versão> create meu-app`.
33
+ Se o pnpm informar que o diretório global de binários não está no `PATH`, execute `pnpm setup`
34
+ e abra uma nova sessão do terminal antes de tentar novamente.
43
35
 
44
36
  Nasce com: `opus.config.ts` + domínio-exemplo canônico (0 violações, spec documentada),
45
37
  vite + react + tema do Opus (Tailwind v4 CSS-first), dev server na porta que o Maestro
@@ -59,8 +51,8 @@ pnpm dlx @softize/opus create apps/portal # o app (modo detectado)
59
51
 
60
52
  ## Carregar o Opus num projeto existente
61
53
 
62
- > O pin vive no `opus.json`; o setup grava o esqueleto local. Ausência de `opus.json` = projeto
63
- > não inicializado não improvise, rode o setup.
54
+ > O `opus.json` registra a versão usada pelo projeto. Se o arquivo ainda não existe, o setup
55
+ > cria a estrutura necessária antes das demais etapas.
64
56
 
65
57
  A versão do Opus fica pinada em `opus.json`. O `opus setup` é per-app: grava o `opus.json`,
66
58
  mantém o bloco gerenciado do `CLAUDE.md` (fora dele o arquivo é seu) e semeia o dia zero
@@ -1,83 +1,130 @@
1
1
  ---
2
- title: Microcopy
2
+ title: Comunicação
3
3
  ---
4
4
 
5
- # Microcopy
5
+ # Comunicação
6
6
 
7
- Código em inglês; o que humano (UI, comentário, doc) em pt-BR. Frases começam com
8
- maiúscula e terminam com ponto; labels curtos em sentence case, sem ponto. **Esta página
9
- é a fonte** `build-opus-ui` aplica esta convenção (regra duplicada em vez de apontada é
10
- defeito).
7
+ Toda comunicação do produto deve ajudar alguém a compreender o que está acontecendo e a
8
+ seguir adiante com confiança. Esta orientação vale para documentação, interfaces, mensagens
9
+ de erro, CLI, onboarding, textos explicativos, comentários e respostas produzidas por agentes.
11
10
 
12
- ## Língua por camada
11
+ Clareza não significa apenas escrever frases curtas. Um texto claro parte da situação do
12
+ leitor, apresenta o que ele precisa saber e oferece contexto suficiente para que a próxima
13
+ decisão não dependa de adivinhação.
13
14
 
14
- > Regra dura — não tem caso a caso.
15
+ ## Antes de escrever
15
16
 
16
- | Camada | Língua |
17
- |---|---|
18
- | Identificadores de código (vars, funções, tipos, arquivos, dirs, domínios) | Inglês |
19
- | Nomes de action / rota | Inglês (`resource.verb`) |
20
- | Colunas e tabelas de banco | Inglês (snake_case) |
21
- | Valores de código (enums, status, chaves de dict) | Inglês — mesmo em exemplos e fixtures (`active`, não `ativo`); a UI mostra o label pt |
22
- | Texto de UI visível (labels, headings, botões, placeholders, mensagens) | pt-BR |
23
- | Comentários e docs (`.md`) | pt-BR |
17
+ Identifique quem lerá o texto, o que essa pessoa está tentando fazer e qual decisão ou ação
18
+ deve ser possível depois da leitura. Quando essas respostas não estiverem claras, investigue o
19
+ fluxo antes de escolher as palavras.
24
20
 
25
- ## Frase vs label
21
+ Organize a explicação nesta ordem sempre que ela ajudar:
26
22
 
27
- > Frase (mensagem, descrição, tooltip, help): maiúscula no início, ponto no fim. Label
28
- > (botão, heading, item de menu, chip): sentence case, sem ponto.
23
+ 1. apresente a situação ou o problema reconhecível pelo leitor;
24
+ 2. explique o benefício ou o efeito esperado;
25
+ 3. descreva o mecanismo somente no nível necessário;
26
+ 4. indique a próxima ação quando houver uma.
29
27
 
30
- | Tipo | Assim | Assim não |
28
+ Não comece pela arquitetura interna quando a necessidade do leitor oferece uma introdução
29
+ mais natural. Termos técnicos são bem-vindos quando acrescentam precisão, mas devem ser
30
+ apresentados antes de serem usados como parte da explicação.
31
+
32
+ ## Voz
33
+
34
+ Escreva de maneira calma, próxima e segura. A comunicação pode ser firme sem parecer uma
35
+ ordem interna ou um manifesto.
36
+
37
+ - Prefira explicações completas a slogans, máximas e frases de efeito.
38
+ - Evite absolutos como “sempre”, “nunca”, “zero” e “é” quando houver contexto, condição ou
39
+ exceção relevante.
40
+ - Não use caixa-alta, negrito ou pontuação para fabricar autoridade.
41
+ - Evite sequências telegráficas, equações e símbolos usados como conectores em prosa.
42
+ - Não presuma que o leitor já concorda com a arquitetura ou conhece o vocabulário da equipe.
43
+ - Explique decisões pelo valor que oferecem às pessoas, não apenas pela disciplina que impõem.
44
+ - Mantenha o mesmo termo para o mesmo conceito em todas as superfícies.
45
+
46
+ Em vez de “O domínio é a aplicação. Front e back são cascas”, explique a relação:
47
+
48
+ > O Opus mantém as regras e os contratos do domínio em uma camada compartilhada. Assim,
49
+ > cliente e servidor trabalham com as mesmas definições, sem duplicar schemas, validações ou
50
+ > tipos de transporte.
51
+
52
+ ## Documentação
53
+
54
+ Uma documentação deve formar o modelo mental do leitor antes de cobrar decisões baseadas
55
+ nele. Apresente primeiro o problema, depois a ideia, um exemplo concreto e os próximos passos.
56
+ Detalhes operacionais e situações excepcionais devem ficar próximos da etapa em que se tornam
57
+ úteis, sem interromper a introdução principal.
58
+
59
+ Ao registrar uma norma, deixe claro o peso da afirmação:
60
+
61
+ - **Princípio:** explica a intenção que orienta as decisões.
62
+ - **Regra:** descreve um requisito obrigatório e seu escopo.
63
+ - **Recomendação:** apresenta o caminho preferido quando outras opções continuam válidas.
64
+ - **Comportamento:** informa o que o produto faz automaticamente.
65
+ - **Verificação:** mostra como confirmar que a regra foi atendida.
66
+ - **Exceção:** delimita quando a orientação não se aplica.
67
+
68
+ Uma regra normativa deve informar a condição em que se aplica, a razão que a sustenta e como
69
+ ela é verificada. Por exemplo:
70
+
71
+ > Cada action deve ser declarada em um arquivo próprio. Essa separação permite que o registro e
72
+ > os geradores identifiquem cada action de forma determinística. O `opus check` informa quais
73
+ > arquivos precisam ser separados quando encontra mais de uma declaração.
74
+
75
+ Evite substituir essa explicação por “Uma por arquivo. O gate reprova”. A versão curta omite o
76
+ motivo, não delimita o escopo e transforma uma ajuda em uma advertência.
77
+
78
+ ## Mensagens de erro
79
+
80
+ Uma mensagem de erro deve responder, nessa ordem, ao que aconteceu, como isso afeta a tarefa e
81
+ o que a pessoa pode fazer. Não culpe o usuário e não exponha endpoint, stack trace, status HTTP
82
+ ou detalhes do runtime na interface; esses dados pertencem ao log ou à área de diagnóstico.
83
+
84
+ | Situação | Prefira | Evite |
85
+ |---|---|---|
86
+ | Serviço indisponível | O Multica não respondeu. Tente novamente em alguns instantes. | ERRO: request failed (500) |
87
+ | Recurso ausente | Este workspace não existe mais. Volte à lista para escolher outro. | Workspace inválido. |
88
+ | Permissão | Você não tem acesso a este workspace. Peça acesso a um administrador. | Acesso negado. |
89
+ | Validação | Informe um endereço de e-mail válido. | Campo inválido. |
90
+
91
+ Quando não houver uma ação possível, diga isso com honestidade e preserve o trabalho já feito.
92
+ Não ofereça “tente novamente” como resposta automática para falhas que uma nova tentativa não
93
+ pode resolver.
94
+
95
+ ## Textos de interface
96
+
97
+ Código e valores internos permanecem em inglês. O que uma pessoa lê na interface usa pt-BR,
98
+ salvo quando o produto declarar outro idioma.
99
+
100
+ - Frases começam com maiúscula e terminam com ponto.
101
+ - Labels, títulos, itens de menu e botões usam sentence case e não levam ponto.
102
+ - Placeholders de seleção usam `Selecione <artigo> <coisa>…`.
103
+ - Placeholders ajudam a responder, mas não substituem o label do campo.
104
+ - Botões descrevem a ação que executarão, como `Publicar` ou `Salvar alterações`.
105
+ - Textos de ajuda explicam o efeito percebido, não a implementação interna.
106
+ - Abreviações são usadas somente quando o espaço ou o vocabulário do domínio as justificam.
107
+
108
+ | Tipo | Prefira | Evite |
31
109
  |---|---|---|
32
- | Frase | Opus não inicializado. | ~~opus nao inicializado~~ |
33
- | Frase | O Multica não respondeu — tente de novo. | ~~ERRO: request failed (500)~~ |
34
- | Label | Publicar | ~~PUBLICAR~~ |
35
- | Label | Nova sessão | ~~Nova sessão.~~ |
36
- | Placeholder | Selecione um cliente… | ~~Selecionar~~ · ~~digite o nome…~~ |
37
-
38
- ## As regras que mais pegam
39
-
40
- > Erros recorrentes de revisão atenção redobrada nestes.
41
-
42
- - **Maiúscula é ortografia, não estilo.** Toda frase começa com maiúscula — em UI,
43
- hint/help **e comentário de código** e nome próprio idem (Engineer, Multica, GitHub).
44
- Vale com interpolação: mensagem que começaria com valor ganha um artigo na frente
45
- (`O workspace '${slug}' não existe…`).
46
- - **Frase fluida, não telegrama.** Símbolo não é conector: nada de `—`/`+`/`≈` amarrando
47
- ideias em label ou help. `Staff acesso ao back-office + todos os workspaces` vira
48
- label `Staff` + help `Tem acesso ao back-office e a todos os workspaces.`.
49
- - **"Opus" e "Softize" são nomes próprios.** Em prosa, maiúscula (`o Opus`, `a Softize`);
50
- os tokens técnicos ficam minúsculos: `opus check`, `@softize/opus`, `opus.json`,
51
- `softize.com.br`. É o nome maiúscula; é código minúscula.
52
- - **Abreviação é último caso.** Por extenso: `mínimo`, `máximo`, `configuração`.
53
- `Config indisponível.` é duplamente errado (seco E abreviado): `A configuração não
54
- carregou.`. `Ex.:` em placeholder é tolerado (com `E` maiúsculo).
55
- - **Placeholder de seleção segue UM padrão** (select simples, buscável, múltiplo):
56
- `Selecione <artigo> <coisa>…` — com `…` (o caractere único), nunca o genérico
57
- `Selecionar`. Declare no contrato (`fields.<campo>.placeholder`) — o default do
58
- componente é rede de segurança, não estilo; dois pickers na mesma tela com padrões
59
- diferentes é defeito.
60
- - **Nada de maiúsculo deliberado.** Sem ALL-CAPS — nem a classe `uppercase` — em labels,
61
- headers ou badges.
62
- - **Exemplos são neutros e duráveis.** Nada de cliente real ou com cara de real: use
63
- Empresa X / Empresa Y (`contato@empresa-x.com.br`). Exemplo "de verdade" envelhece,
64
- vaza contexto e vira dívida.
65
-
66
- ## Tom
67
-
68
- > Fale com o usuário, não com o log.
69
-
70
- - **Calmo e informativo, não alarmista.** "Indisponível" em vez de "ERRO"/"FALHOU".
71
- Não culpe o usuário.
72
- - **Orientado à ação.** Quando dá, diga o próximo passo: `Inicie o ambiente`,
73
- `Crie a primeira acima`.
74
- - **Conciso, mas natural — não telegráfico.** Prefira a forma completa do verbo a um
75
- corte abrupto. O meio-termo é a régua: nem seco demais (`rode no projeto`) nem manual
76
- técnico (jargão de arquitetura num help).
77
- - **Explique pelo efeito, não pelo mecanismo.** Se precisou citar sistema interno pra
78
- explicar (`o push sobrescreve o runtime`), reescreva pelo que acontece pro usuário
79
- (`os agentes deste workspace passam a usar esta skill`). Mecanismo é doc/comentário,
80
- não tooltip.
81
- - **Nada de endpoint, status ou stack na tela** — detalhe técnico vai pro console/log.
82
- - **Termos do produto** (sessão, ambiente, cliente, agente), não do código. E o mesmo
83
- termo sempre: se a UI fala "cliente", nenhum label diz "client".
110
+ | Frase | A configuração não carregou. | Config indisponível. |
111
+ | Label | Nova sessão | Nova sessão. |
112
+ | Botão | Publicar | PUBLICAR |
113
+ | Placeholder | Selecione um cliente… | Selecionar |
114
+ | Ajuda | Os agentes deste workspace passam a usar esta skill. | O push sobrescreve o runtime. |
115
+
116
+ ## Revisão
117
+
118
+ Antes de entregar, releia o texto fora do contexto da implementação e confirme:
119
+
120
+ - o leitor consegue reconhecer a situação sem conhecer o código;
121
+ - conceitos novos são explicados antes de orientar decisões;
122
+ - regras obrigatórias estão separadas de recomendações;
123
+ - a razão da orientação aparece quando ajuda a compreendê-la;
124
+ - mensagens de erro preservam a calma e oferecem uma saída real;
125
+ - a frase soa como uma conversa profissional, não como log, slogan ou ordem interna;
126
+ - detalhes técnicos permanecem disponíveis no lugar adequado sem dominar a comunicação.
127
+
128
+ Leia o fluxo completo, não apenas strings isoladas. Um conjunto de frases corretas ainda pode
129
+ produzir uma experiência confusa quando repete informações, muda de vocabulário ou apresenta
130
+ ações fora da ordem em que a pessoa precisa delas.
@@ -6,7 +6,7 @@ title: Atualizar o Opus
6
6
 
7
7
  Projeto em produção fica meses sem tocar no Opus — e um dia precisa pular várias
8
8
  versões de uma vez. O ritual é o mesmo para humano e IA, e não depende de memória:
9
- cada peça do caminho está escrita ou é um gate que quebra alto.
9
+ cada etapa está documentada ou é verificada por um gate que informa o que precisa ser corrigido.
10
10
 
11
11
  ## 1. Saber que está atrás
12
12
 
@@ -267,7 +267,7 @@ export const UI_SECTIONS: DocSection[] = [
267
267
  {
268
268
  pages: [
269
269
  { slug: 'tokens', title: 'Tokens & Tema', render: doc(tokensMd) },
270
- { slug: 'microcopy', title: 'Microcopy', render: doc(microcopyMd) },
270
+ { slug: 'microcopy', title: 'Comunicação', render: doc(microcopyMd) },
271
271
  { slug: 'customization', title: 'Customização', render: doc(customizationMd) },
272
272
  ],
273
273
  },