@softize/opus 12.10.0 → 13.0.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 +56 -0
- package/bin/lib/check.mjs +1098 -310
- package/bin/lib/copy.mjs +12 -5
- package/docs/adr/0003-dictionary-presentation-is-declared.md +3 -0
- package/docs/adr/0004-page-content-state-is-composed.md +65 -0
- package/docs/adr/0005-structural-surfaces-share-an-explicit-anatomy.md +180 -0
- package/docs/adr/0006-semantic-context-precedes-visual-variant.md +182 -0
- package/docs/adr/0007-toast-actions-form-an-ordered-collection.md +63 -0
- package/docs/adr/0008-hierarchical-navigation-is-composed-at-the-consumer-boundary.md +71 -0
- package/docs/radius-scale.md +1 -1
- package/package.json +1 -1
- package/registry/instructions/opus.md +5 -0
- package/registry/skills/build-opus-ui/SKILL.md +27 -16
- package/registry/skills/build-opus-ui/references/evaluations.md +16 -5
- package/registry/skills/build-opus-ui/references/ui-patterns.md +38 -15
- package/registry/skills/maintain-opus-docs/SKILL.md +83 -0
- package/registry/skills/maintain-opus-docs/agents/openai.yaml +4 -0
- package/registry/skills/maintain-opus-docs/references/editorial-standard.md +85 -0
- package/registry/skills/maintain-opus-docs/references/evaluations.md +34 -0
- package/registry/skills/maintain-opus-docs/scripts/audit-docs.mjs +81 -0
- package/registry/skills/model-opus-dictionary/SKILL.md +4 -2
- package/registry/skills/model-opus-dictionary/references/evaluations.md +4 -3
- package/registry/templates/app/src/App.tsx +1 -1
- package/src/core/dictionary.ts +52 -14
- package/src/core/index.ts +10 -0
- package/src/core/ui-context.ts +29 -0
- package/src/schema/drivers/zod.ts +17 -8
- package/src/ui/components/patterns/action-form-card.tsx +18 -12
- package/src/ui/components/patterns/confirm.tsx +163 -40
- package/src/ui/components/patterns/content-header.tsx +335 -61
- package/src/ui/components/patterns/data-state.tsx +23 -10
- package/src/ui/components/patterns/list.tsx +1097 -783
- package/src/ui/components/patterns/page-state.tsx +115 -0
- package/src/ui/components/patterns/page.tsx +231 -41
- package/src/ui/components/patterns/sidebar.tsx +357 -83
- package/src/ui/components/patterns/trigger.tsx +37 -30
- package/src/ui/components/patterns/view.tsx +7 -11
- package/src/ui/components/primitives/alert.tsx +298 -110
- package/src/ui/components/primitives/ask.tsx +2 -1
- package/src/ui/components/primitives/badge.tsx +91 -30
- package/src/ui/components/primitives/button.tsx +99 -60
- package/src/ui/components/primitives/calendar.tsx +39 -39
- package/src/ui/components/primitives/card.tsx +96 -23
- package/src/ui/components/primitives/detail.tsx +2 -2
- package/src/ui/components/primitives/dialog.tsx +196 -39
- package/src/ui/components/primitives/dictionary-value.tsx +9 -14
- package/src/ui/components/primitives/dot.tsx +74 -21
- package/src/ui/components/primitives/drawer.tsx +40 -24
- package/src/ui/components/primitives/empty.tsx +3 -3
- package/src/ui/components/primitives/item.tsx +135 -79
- package/src/ui/components/primitives/menu.tsx +11 -3
- package/src/ui/components/primitives/metric-card.tsx +133 -0
- package/src/ui/components/primitives/sonner.tsx +187 -8
- package/src/ui/components/primitives/table.tsx +2 -2
- package/src/ui/docs/DocBrowser.tsx +104 -25
- package/src/ui/docs/changelog.tsx +1 -1
- package/src/ui/docs/content/accordion.md +22 -16
- package/src/ui/docs/content/action-form-card.md +8 -8
- package/src/ui/docs/content/action-form-dialog.md +9 -9
- package/src/ui/docs/content/action-form.md +28 -34
- package/src/ui/docs/content/action-list-dialog.md +11 -6
- package/src/ui/docs/content/action-list.md +64 -39
- package/src/ui/docs/content/action-trigger.md +21 -14
- package/src/ui/docs/content/action-view.md +8 -8
- package/src/ui/docs/content/actions.md +9 -9
- package/src/ui/docs/content/ai.md +3 -3
- package/src/ui/docs/content/alert.md +54 -28
- package/src/ui/docs/content/aspect-ratio.md +4 -4
- package/src/ui/docs/content/audit.md +2 -2
- package/src/ui/docs/content/auth.md +3 -3
- package/src/ui/docs/content/avatar.md +34 -14
- package/src/ui/docs/content/badge.md +21 -22
- package/src/ui/docs/content/breadcrumb.md +13 -8
- package/src/ui/docs/content/button.md +93 -15
- package/src/ui/docs/content/calendar.md +5 -5
- package/src/ui/docs/content/card.md +6 -6
- package/src/ui/docs/content/carousel.md +16 -11
- package/src/ui/docs/content/chat.md +3 -3
- package/src/ui/docs/content/checkbox.md +7 -7
- package/src/ui/docs/content/cli.md +5 -5
- package/src/ui/docs/content/collapsible.md +8 -8
- package/src/ui/docs/content/command.md +16 -8
- package/src/ui/docs/content/composer.md +2 -2
- package/src/ui/docs/content/content.md +44 -0
- package/src/ui/docs/content/copyable.md +4 -3
- package/src/ui/docs/content/customization.md +7 -7
- package/src/ui/docs/content/cycle.md +3 -3
- package/src/ui/docs/content/data-state.md +11 -12
- package/src/ui/docs/content/data.md +26 -33
- package/src/ui/docs/content/detail.md +8 -5
- package/src/ui/docs/content/dialog.md +339 -31
- package/src/ui/docs/content/dictionary-value.md +19 -18
- package/src/ui/docs/content/dock.md +3 -3
- package/src/ui/docs/content/dot.md +7 -7
- package/src/ui/docs/content/drawer.md +32 -16
- package/src/ui/docs/content/empty-value.md +2 -2
- package/src/ui/docs/content/empty.md +19 -12
- package/src/ui/docs/content/events.md +4 -4
- package/src/ui/docs/content/field.md +34 -12
- package/src/ui/docs/content/getting-started.md +1 -1
- package/src/ui/docs/content/icon-picker.md +8 -4
- package/src/ui/docs/content/input-otp.md +20 -12
- package/src/ui/docs/content/input.md +121 -9
- package/src/ui/docs/content/item.md +64 -24
- package/src/ui/docs/content/kbd.md +19 -11
- package/src/ui/docs/content/label.md +5 -3
- package/src/ui/docs/content/log.md +4 -4
- package/src/ui/docs/content/markdown.md +7 -6
- package/src/ui/docs/content/mcp.md +13 -15
- package/src/ui/docs/content/menu.md +36 -17
- package/src/ui/docs/content/metric-card.md +41 -0
- package/src/ui/docs/content/observability.md +2 -2
- package/src/ui/docs/content/page.md +93 -10
- package/src/ui/docs/content/pagination.md +22 -17
- package/src/ui/docs/content/popover.md +16 -8
- package/src/ui/docs/content/progress.md +7 -5
- package/src/ui/docs/content/queue.md +5 -5
- package/src/ui/docs/content/radio-group.md +20 -12
- package/src/ui/docs/content/router.md +11 -6
- package/src/ui/docs/content/scheduler.md +4 -5
- package/src/ui/docs/content/scroll-area.md +12 -7
- package/src/ui/docs/content/select.md +42 -29
- package/src/ui/docs/content/semantic-context.md +63 -0
- package/src/ui/docs/content/separator.md +5 -5
- package/src/ui/docs/content/sidebar.md +325 -56
- package/src/ui/docs/content/skeleton.md +5 -4
- package/src/ui/docs/content/slider.md +8 -7
- package/src/ui/docs/content/spinner.md +8 -8
- package/src/ui/docs/content/split.md +8 -5
- package/src/ui/docs/content/storage.md +6 -8
- package/src/ui/docs/content/switch.md +8 -7
- package/src/ui/docs/content/table.md +16 -6
- package/src/ui/docs/content/tabs.md +28 -14
- package/src/ui/docs/content/testing.md +9 -11
- package/src/ui/docs/content/textarea.md +5 -4
- package/src/ui/docs/content/toast.md +47 -13
- package/src/ui/docs/content/toggle.md +75 -7
- package/src/ui/docs/content/tokens.md +31 -3
- package/src/ui/docs/content/tooltip.md +19 -11
- package/src/ui/docs/content/truncate.md +7 -8
- package/src/ui/docs/content/ui.md +10 -9
- package/src/ui/docs/content/upgrading.md +7 -8
- package/src/ui/docs/doc-client.tsx +2 -2
- package/src/ui/docs/registry.tsx +580 -229
- package/src/ui/lib/semantic-context.ts +30 -0
- package/src/ui/meta.ts +278 -286
- package/src/ui/react.tsx +377 -111
- package/src/ui/theme.css +116 -0
- package/src/ui/components/primitives/alert-dialog.tsx +0 -190
- package/src/ui/docs/content/alert-dialog.md +0 -73
- package/src/ui/docs/content/button-group.md +0 -71
- package/src/ui/docs/content/confirm.md +0 -120
- package/src/ui/docs/content/input-group.md +0 -78
- package/src/ui/docs/content/toggle-group.md +0 -81
package/package.json
CHANGED
|
@@ -15,6 +15,11 @@ artefatos de agentes fica em `base.json`; cada app Opus mantém seu marcador `op
|
|
|
15
15
|
- Manter contrato compartilhável separado de banco, segredo e driver server-only; usar
|
|
16
16
|
`defineContract` com `bindAction` quando cliente e servidor consomem a mesma action.
|
|
17
17
|
- Não duplicar schemas, tipos de transporte, validação ou fetch que o contrato já fornece.
|
|
18
|
+
- Em UI semântica, declarar primeiro `context` (`neutral`, `primary`, `info`, `success`, `warning`
|
|
19
|
+
ou `danger`) e usar `variant` somente para o tratamento visual (`solid`, `subtle`, `outline`,
|
|
20
|
+
`ghost` ou `link`). Dicionários de status e estágio declaram `context`; `tone` e variantes
|
|
21
|
+
semânticas antigas são apenas compatibilidade de migração. `destructive` permanece uma
|
|
22
|
+
propriedade comportamental de actions e se projeta visualmente como `danger`.
|
|
18
23
|
- Declarar datasets persistentes com `defineSeed` + `bindSeed`, registrá-los em `opus.config.ts`
|
|
19
24
|
e operá-los por `opus seed`; não criar comandos de seed paralelos nem reset implícito.
|
|
20
25
|
- Regenerar o inventário com `opus copy` quando mudar copy em contrato ou componente Opus
|
|
@@ -19,46 +19,54 @@ existentes, mantendo navegação observável e componentes reutilizáveis sem la
|
|
|
19
19
|
mensagem de vocabulário fechado vêm do dicionário do domínio (`labelFor`/`metaFor`); ao
|
|
20
20
|
encontrar catálogo repetido à mão ou vocabulário ainda sem dicionário, carregar
|
|
21
21
|
`$model-opus-dictionary`.
|
|
22
|
-
3.
|
|
22
|
+
3. Em componentes semânticos, declarar `context` antes de escolher `variant`: `context` comunica
|
|
23
|
+
`neutral`, `primary`, `info`, `success`, `warning` ou `danger`; `variant` descreve somente o
|
|
24
|
+
tratamento `solid`, `subtle`, `outline`, `ghost` ou `link`, conforme o subconjunto aceito pelo
|
|
25
|
+
componente. Não usar `variant="success"`, `variant="destructive"` nem `tone` em código novo.
|
|
26
|
+
`destructive` permanece metadata comportamental de action e se projeta como `context="danger"`.
|
|
27
|
+
4. Apresentar valor de dicionário por `DictionaryValue` ou pela coluna de `ActionList`, que
|
|
23
28
|
aplicam o papel declarado em `presentation` (classificação em badge `outline`, status e estágio
|
|
24
|
-
em badge
|
|
29
|
+
em badge `context + subtle`, `plain` em texto). Não escolher badge, contexto ou ícone pelo nome do dicionário:
|
|
25
30
|
dicionário sem papel declarado renderiza texto e pede classificação por
|
|
26
31
|
`$model-opus-dictionary` antes de qualquer destaque visual. Sobrepor os defaults só com motivo
|
|
27
32
|
explícito nas props do renderer.
|
|
28
|
-
|
|
33
|
+
5. Dar a cada dimensão independente usada para comparação ou filtro um campo, coluna ou espaço
|
|
29
34
|
identificável próprio, com rótulo. Hierarquia tipográfica (texto secundário sob um nome) não
|
|
30
35
|
pode fazer uma dimensão parecer explicação de outra. Cor e ícone reforçam; o texto do valor
|
|
31
36
|
permanece sempre presente.
|
|
32
|
-
|
|
37
|
+
6. Deixar ausência, paginação e largura de filtro com o pattern: célula e `DetailField` já
|
|
33
38
|
representam valor ausente (`EmptyValue`, `empty` para o significado do domínio); listas
|
|
34
39
|
paginam pela primitiva `Pagination`; selects inline de filtro têm largura fixa. Não reescrever
|
|
35
40
|
esses defaults na tela.
|
|
36
|
-
|
|
41
|
+
7. Tratar página, filtro, seleção e modal importante como estado navegável por URL quando
|
|
37
42
|
o produto precisa de deep link, back/forward ou refresh.
|
|
38
|
-
|
|
39
|
-
`
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
8. Compor superfícies pela gramática estrutural do catálogo: `Page` contém `PageHeader` e
|
|
44
|
+
`PageBody`; `Content` contém `ContentHeader` e `ContentBody`; Card, Drawer e Pane usam seus
|
|
45
|
+
respectivos `*Body`. Para o caso direto, usar a sintaxe abreviada de `Page` ou `Content` com
|
|
46
|
+
`title`, `description`, `meta` e `actions`; não misturá-la com o header explícito. Ajustar o
|
|
47
|
+
nível do heading pela hierarquia semântica, não pelo destaque visual. O `Page` mantém seu teto
|
|
48
|
+
centralizado padrão de `80rem`.
|
|
49
|
+
9. Manter margem e posicionamento no consumidor; componente reutilizável controla apenas
|
|
42
50
|
seu interior.
|
|
43
|
-
|
|
51
|
+
10. Não definir a fonte raiz em uma biblioteca ou componente. O navegador e a aplicação são
|
|
44
52
|
responsáveis por `font-size` em `html`; medidas escaláveis da UI usam `rem` ou a escala
|
|
45
53
|
relativa do Tailwind. Reservar `px` a hairlines e compensações presas à geometria da borda,
|
|
46
54
|
com justificativa e cobertura explícitas.
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
11. Evoluir um pattern compartilhado apenas quando a recorrência e o contrato estiverem claros.
|
|
56
|
+
12. Tratar tokens de superfície como pares indivisíveis no mesmo fragmento de classes:
|
|
49
57
|
`bg-card text-card-foreground` e `bg-popover text-popover-foreground`. Não depender da
|
|
50
58
|
igualdade atual com `--foreground`, porque o app pode sobrescrever cada par.
|
|
51
|
-
|
|
59
|
+
13. Usar diretamente a escala `rounded-*`; não criar radius por nome de componente quando
|
|
52
60
|
`rounded-xs` a `rounded-2xl` já expressam a forma. Escolher o degrau pela escala visual:
|
|
53
61
|
detalhes e itens internos tendem a `xs`/`sm`, controles e flutuantes compactos a `md`,
|
|
54
62
|
molduras estruturais a `lg`, e superfícies principais ou modais a `xl`. Essa associação
|
|
55
63
|
orienta o default, não cria uma restrição semântica. Em aninhamento, evitar moldura dupla e
|
|
56
64
|
reduzir o raio interno; em grupos conectados, remover os raios das arestas internas. Tamanho
|
|
57
65
|
e forma permanecem eixos separados; usar `shape="pill"` quando a pílula for intencional.
|
|
58
|
-
|
|
66
|
+
14. Distinguir uma região disponível para criação ou vínculo, representada por `Empty` com
|
|
59
67
|
moldura tracejada, de um resultado vazio dentro de uma estrutura existente, que preserva
|
|
60
68
|
a moldura sólida dessa estrutura.
|
|
61
|
-
|
|
69
|
+
15. Testar estados de loading, vazio, erro, sucesso, permissão e interação relevante.
|
|
62
70
|
|
|
63
71
|
## Verificação
|
|
64
72
|
|
|
@@ -76,8 +84,11 @@ Inspecionar visualmente a rota real e validar navegação por URL quando aplicá
|
|
|
76
84
|
- Não criar fetch, schema ou tipo paralelo ao contrato.
|
|
77
85
|
- Não copiar componente da lib para customizar sem antes verificar extensão/composição.
|
|
78
86
|
- Não forçar modal roteável quando o estado é efêmero e sem valor de navegação.
|
|
79
|
-
- Não inferir apresentação de dicionário: nem badge para todo valor, nem
|
|
87
|
+
- Não inferir apresentação de dicionário: nem badge para todo valor, nem contexto ou ícone
|
|
80
88
|
inventados, nem tooltip que repete o rótulo.
|
|
89
|
+
- Não usar nomes de compatibilidade (`tone`, `variant="success"`, `variant="destructive"`) em
|
|
90
|
+
código novo; consultar a página “Contexto & Variante” do catálogo quando a combinação não estiver
|
|
91
|
+
clara.
|
|
81
92
|
- Não repetir fallback de ausência, paginador ou largura de filtro que o pattern já resolve.
|
|
82
93
|
|
|
83
94
|
## Recursos
|
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
- Dispara: “Monte a tela de edição usando a form action do Opus.”
|
|
4
4
|
- Não dispara: “Ajuste o CSS de um e-mail estático.”
|
|
5
5
|
- Execução: implementar uma lista com modal roteável e provar loading, erro, vazio e back.
|
|
6
|
-
- Execução estrutural: montar uma página de relatório com `Page
|
|
7
|
-
`ActionFilterBar` separado do renderer, `ItemGroup` para
|
|
8
|
-
`ActionFormDialog`; provar teto padrão de `
|
|
9
|
-
sólido, `Empty` apenas para criação ou vínculo, números sem alinhamento
|
|
10
|
-
`ghost` no modal.
|
|
6
|
+
- Execução estrutural: montar uma página de relatório com `Page > PageHeader + PageBody`, uma seção
|
|
7
|
+
`Content > ContentHeader + ContentBody`, `ActionFilterBar` separado do renderer, `ItemGroup` para
|
|
8
|
+
uma coleção secundária e um `ActionFormDialog`; provar teto padrão de `80rem`, hierarquia por
|
|
9
|
+
`level`, vazio estrutural sólido, `Empty` apenas para criação ou vínculo, números sem alinhamento
|
|
10
|
+
inferido e cancelamento `ghost` no modal.
|
|
11
|
+
- Execução abreviada: montar outra página com `<Page title description actions>` e uma seção com
|
|
12
|
+
`<Content title description actions>`, provando que ambas produzem a mesma anatomia e que o lint
|
|
13
|
+
rejeita a mistura entre props abreviadas e headers explícitos.
|
|
11
14
|
- Execução de forma: compor uma tabela dentro de Card sem moldura duplicada, manter a moldura
|
|
12
15
|
estrutural standalone em `rounded-lg` e os controles internos em `rounded-md`.
|
|
13
16
|
- Reprova: criar uma casca `bg-card` que herda o texto global ou introduzir `rounded-widget`
|
|
@@ -17,11 +20,19 @@
|
|
|
17
20
|
- Reprova: reconstruir manualmente o container de página, usar `Empty` tracejado como vazio de
|
|
18
21
|
tabela, alinhar toda coluna numérica à direita por inferência ou destacar “Cancelar” como ação
|
|
19
22
|
primária em modal.
|
|
23
|
+
- Reprova: deixar `ContentHeader` fora de `Content`, omitir `PageBody`/`ContentBody` na composição
|
|
24
|
+
explícita, usar `CardContent`/`PaneContent` em código novo ou tratar `DialogContent` como Body.
|
|
20
25
|
- Execução de dicionários: montar a lista de clientes com “Pessoa física/Empresa” e
|
|
21
26
|
“Prospect/Cliente”; provar que o tipo ocupa a coluna “Tipo” como classificação (badge `outline`
|
|
22
27
|
com os ícones declarados `user` e `building`), que o estágio ocupa a coluna “Estágio” como badge
|
|
23
28
|
tonal sem `outline`, que nenhuma das duas usa `cells`, que o texto do valor está presente e que
|
|
24
29
|
não há tooltip em “Pessoa física/Empresa” quando a descrição não acrescenta ao rótulo.
|
|
30
|
+
- Execução de contexto: montar ações, badges, alertas e indicadores com o mesmo estado `warning`;
|
|
31
|
+
exigir `context="warning"`, variantes visuais coerentes por componente e tokens da mesma família.
|
|
32
|
+
Uma exclusão continua `destructive` no contrato, mas usa `context="danger"` na projeção visual.
|
|
33
|
+
- Reprova: usar `tone` em componente novo, `variant="success"`, `variant="warning"` ou
|
|
34
|
+
`variant="destructive"`; usar `light`/`dark` como contexto; ou tratar `secondary` como sinônimo
|
|
35
|
+
de estado neutro.
|
|
25
36
|
- Reprova: envolver todo valor de dicionário em badge sem papel declarado, ou escolher a variante
|
|
26
37
|
pelo nome do dicionário.
|
|
27
38
|
- Reprova: colocar duas dimensões independentes na mesma célula sem identificação, como o tipo em
|
|
@@ -4,12 +4,24 @@
|
|
|
4
4
|
- Campos, labels, mensagens e invalidações pertencem ao contrato quando são parte da
|
|
5
5
|
operação, não a uma tela isolada.
|
|
6
6
|
- URL representa estado que precisa sobreviver a refresh, deep link ou histórico.
|
|
7
|
-
- `Page` fornece o `<main
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
- `Page` fornece o `<main>` e o container centralizado com teto padrão de `80rem`. Sua forma
|
|
8
|
+
explícita é `Page > PageHeader (PageTitle, PageDescription, PageMeta, PageActions) + PageBody`;
|
|
9
|
+
`title`, `description`, `meta` e `actions` no próprio `Page` são a abreviação para o caso direto.
|
|
10
|
+
Não misturar as duas formas. Alterar `className` apenas quando a superfície tiver uma necessidade
|
|
11
|
+
real de largura; não reconstruir esse container em cada rota.
|
|
12
|
+
- `PageState` substitui todo o conteúdo principal quando a página carrega, falha ou está vazia. Na
|
|
13
|
+
forma curta ele pode ser escrito como filho direto de `Page`, que cria o `PageBody`; na forma
|
|
14
|
+
explícita, fica dentro de `PageBody`. O cabeçalho permanece visível. Estados de seção ou coleção
|
|
15
|
+
continuam em `DataState`, `ActionView`, `ActionList` ou `Alert`; não elevar uma falha parcial a
|
|
16
|
+
estado da página.
|
|
17
|
+
- `Content` delimita uma seção e segue a mesma anatomia: `Content > ContentHeader (ContentTitle,
|
|
18
|
+
ContentDescription, ContentMeta, ContentActions) + ContentBody`. `ContentHeader` nunca fica
|
|
19
|
+
solto. `title`, `description`, `meta` e `actions` no `Content` são a abreviação para o caso
|
|
20
|
+
direto e não podem ser misturados ao header explícito. `level` preserva a hierarquia semântica
|
|
21
|
+
do heading.
|
|
22
|
+
- Card, Drawer e Pane nomeiam a região principal como `CardBody`, `DrawerBody` e `PaneBody`.
|
|
23
|
+
`*Content` permanece reservado a raízes técnicas ou painéis cujo papel não é o corpo de uma
|
|
24
|
+
estrutura, como `DialogContent`, `PopoverContent` e `TabsContent`.
|
|
13
25
|
- Componentes compartilhados não impõem margem externa; páginas e shells compõem layout.
|
|
14
26
|
- A fonte raiz pertence ao navegador e à aplicação. Medidas escaláveis usam `rem` ou a escala
|
|
15
27
|
relativa do Tailwind; `px` fica restrito a hairlines e compensações ligadas a essas bordas.
|
|
@@ -55,18 +67,23 @@
|
|
|
55
67
|
valor trunca no trigger e a opção inteira fica na lista. Não dimensionar filtro pelo conteúdo
|
|
56
68
|
nem pela label; o modal usa `w-full`.
|
|
57
69
|
- Catálogo e API efetivos vêm dos exports da versão instalada, não de memória ou exemplo antigo.
|
|
70
|
+
- Em componentes semânticos, `context` responde por que há destaque e `variant` responde como ele
|
|
71
|
+
aparece. O vocabulário canônico é `neutral | primary | info | success | warning | danger`; as
|
|
72
|
+
variantes visuais são `solid | subtle | outline | ghost | link`, limitadas por componente.
|
|
73
|
+
`light`/`dark` são temas, `secondary` não substitui estado neutro e `destructive` é comportamento
|
|
74
|
+
de action projetado visualmente como `danger`.
|
|
58
75
|
|
|
59
76
|
## Dicionários e dimensões
|
|
60
77
|
|
|
61
78
|
O dicionário declara o papel; a tela só escolhe onde o valor fica. Tabela de decisão aplicada
|
|
62
79
|
por `DictionaryValue` e pelas colunas de `ActionList`:
|
|
63
80
|
|
|
64
|
-
| Papel declarado | Exemplos | Forma | Variante | Ícone | Tooltip |
|
|
65
|
-
|
|
66
|
-
| `classification` | Tipo de cliente, categoria, natureza | Badge | `outline`; ignora `
|
|
67
|
-
| `status` | Aberto, resolvido, degradado | Badge |
|
|
68
|
-
| `stage` | Prospect, cliente; etapa do funil | Badge | igual a `status` | idem | idem |
|
|
69
|
-
| `plain` ou ausente | Fonte, formato, período | Texto | — | idem | idem |
|
|
81
|
+
| Papel declarado | Exemplos | Forma | Contexto | Variante | Ícone | Tooltip |
|
|
82
|
+
|---|---|---|---|---|---|---|
|
|
83
|
+
| `classification` | Tipo de cliente, categoria, natureza | Badge | `neutral` | `outline`; ignora `context` da entrada | se a entrada declara `icon` do catálogo | se `description` acrescenta ao rótulo |
|
|
84
|
+
| `status` | Aberto, resolvido, degradado | Badge | pela entrada; `neutral` por padrão | `subtle`; nunca `outline` | idem | idem |
|
|
85
|
+
| `stage` | Prospect, cliente; etapa do funil | Badge | igual a `status` | `subtle` | idem | idem |
|
|
86
|
+
| `plain` ou ausente | Fonte, formato, período | Texto | — | — | idem | idem |
|
|
70
87
|
|
|
71
88
|
Regras que não dependem da tabela:
|
|
72
89
|
|
|
@@ -88,7 +105,7 @@ export const customerKindDict = t.dict(
|
|
|
88
105
|
{ doc: 'Natureza da parte no cadastro global.', presentation: 'classification' },
|
|
89
106
|
)
|
|
90
107
|
export const customerStageDict = t.dict(
|
|
91
|
-
{ prospect: { label: 'Prospect' }, customer: { label: 'Cliente',
|
|
108
|
+
{ prospect: { label: 'Prospect' }, customer: { label: 'Cliente', context: 'success' } },
|
|
92
109
|
{ doc: 'Estágio comercial atual da parte.', presentation: 'stage' },
|
|
93
110
|
)
|
|
94
111
|
// contrato:
|
|
@@ -112,7 +129,7 @@ cells={{
|
|
|
112
129
|
),
|
|
113
130
|
stage: (item) =>
|
|
114
131
|
item.stage === 'customer'
|
|
115
|
-
? <Badge variant="
|
|
132
|
+
? <Badge context="neutral" variant="solid">Cliente</Badge>
|
|
116
133
|
: <Badge variant="outline">Prospect</Badge>,
|
|
117
134
|
}}
|
|
118
135
|
|
|
@@ -124,7 +141,13 @@ cells={{
|
|
|
124
141
|
|
|
125
142
|
// Tooltip que repete o rótulo; cor como único sinal.
|
|
126
143
|
<Tooltip>
|
|
127
|
-
<TooltipTrigger><Dot
|
|
144
|
+
<TooltipTrigger><Dot context="success" /></TooltipTrigger>
|
|
128
145
|
<TooltipContent>Cliente</TooltipContent>
|
|
129
146
|
</Tooltip>
|
|
147
|
+
|
|
148
|
+
// Contexto semântico usado como variante: a IA perdeu um eixo da API.
|
|
149
|
+
<Badge variant="success">Concluído</Badge>
|
|
150
|
+
|
|
151
|
+
// Risco comportamental usado como nome visual.
|
|
152
|
+
<Button variant="destructive">Excluir</Button>
|
|
130
153
|
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: maintain-opus-docs
|
|
3
|
+
description: Cria, reorganiza e revisa a documentação publicada do Opus, incluindo páginas conceituais, famílias de componentes, exemplos vivos, props, navegação e redirects. Use ao documentar ou revisar o catálogo e os guias de @softize/opus.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Manter documentação Opus
|
|
7
|
+
|
|
8
|
+
## Resultado
|
|
9
|
+
|
|
10
|
+
Entregar documentação que ajuda a pessoa a escolher e usar o recurso pelo caminho canônico,
|
|
11
|
+
preserva a relação entre páginas, catálogo e API pública e continua verificável pelos gates do
|
|
12
|
+
repositório.
|
|
13
|
+
|
|
14
|
+
## Entradas
|
|
15
|
+
|
|
16
|
+
Identificar o público, a tarefa que levou a pessoa à página e o conjunto de APIs públicas coberto.
|
|
17
|
+
Ler [padrão editorial](references/editorial-standard.md) antes de escrever. Inspecionar o componente,
|
|
18
|
+
seus testes, metadata, exportações e páginas relacionadas; a documentação não define um contrato que
|
|
19
|
+
o código não sustenta.
|
|
20
|
+
|
|
21
|
+
## Procedimento
|
|
22
|
+
|
|
23
|
+
1. Inventariar as páginas, componentes e rotas afetadas antes de alterar a organização.
|
|
24
|
+
2. Decidir a unidade da página pelo conceito ensinado. Manter componentes compostos da mesma família
|
|
25
|
+
na mesma página quando compartilham decisão de uso e vocabulário; separar conceitos independentes.
|
|
26
|
+
3. Conduzir a leitura do caso comum para o específico: situação reconhecível, escolha recomendada,
|
|
27
|
+
exemplo mínimo, composição, variações, comportamentos e referência.
|
|
28
|
+
4. Escrever cada seção para funcionar por link direto, repetindo apenas o contexto indispensável.
|
|
29
|
+
5. Usar exemplos pequenos, executáveis e coerentes entre si. Explicar antes o que observar e depois
|
|
30
|
+
o comportamento automático ou a consequência que não esteja evidente no código.
|
|
31
|
+
6. Manter uma tabela de propriedades identificada para cada componente público coberto pela página.
|
|
32
|
+
Não usar uma tabela genérica para contratos diferentes.
|
|
33
|
+
7. Ao renomear ou agrupar páginas, atualizar registry, metadata, navegação e links; preservar slugs
|
|
34
|
+
publicados por redirect ou alias quando o endereço canônico mudar.
|
|
35
|
+
8. Reler todo o texto no fluxo renderizado e aplicar o checklist do padrão editorial linha por linha.
|
|
36
|
+
9. Atualizar testes, inventário de copy e projeções afetadas pelo mesmo conjunto de mudanças.
|
|
37
|
+
|
|
38
|
+
## Decisões
|
|
39
|
+
|
|
40
|
+
- A página ensina uma decisão de uso; a tabela de props documenta o contrato. Nenhuma substitui a
|
|
41
|
+
outra.
|
|
42
|
+
- O exemplo canônico aparece antes da enumeração de possibilidades. Alternativas entram no ponto em
|
|
43
|
+
que a pessoa precisa escolher entre elas.
|
|
44
|
+
- Defaults, efeitos automáticos, limites e riscos ficam próximos do exemplo em que se tornam
|
|
45
|
+
relevantes.
|
|
46
|
+
- Páginas conceituais podem ser extensas quando constroem um fluxo completo; páginas de componente
|
|
47
|
+
permanecem compactas e usam previews para carregar parte da explicação.
|
|
48
|
+
- Inspiração editorial externa orienta progressão e clareza, não autoriza copiar texto, idioma,
|
|
49
|
+
personalidade promocional ou convenções incompatíveis com o Opus.
|
|
50
|
+
|
|
51
|
+
## Verificação
|
|
52
|
+
|
|
53
|
+
Executar `node scripts/audit-docs.mjs "$(git rev-parse --show-toplevel)"` a partir do diretório
|
|
54
|
+
desta skill e, depois, os testes do renderer e do catálogo, typecheck, `opus check` e
|
|
55
|
+
`opus copy --check`. Conferir
|
|
56
|
+
que todos os previews renderizam, que cada API pública documentada possui sua própria referência,
|
|
57
|
+
que nenhum arquivo publicado ficou órfão e que links e redirects chegam à página esperada. Fazer uma
|
|
58
|
+
passada visual nas páginas alteradas e registrar qualquer limitação que o gate automático não cubra.
|
|
59
|
+
|
|
60
|
+
## Saída
|
|
61
|
+
|
|
62
|
+
Informar páginas criadas, agrupadas ou reescritas, decisões editoriais aplicadas, verificações
|
|
63
|
+
executadas e pendências reais. Em revisão ampla, fornecer o inventário coberto para tornar explícito
|
|
64
|
+
o significado de “toda a documentação”.
|
|
65
|
+
|
|
66
|
+
## Limites
|
|
67
|
+
|
|
68
|
+
- Não inventar comportamento, prop, default ou recomendação a partir do nome do componente.
|
|
69
|
+
- Não transformar a documentação em sequência de tabelas nem antecipar a referência antes do modelo
|
|
70
|
+
mental necessário.
|
|
71
|
+
- Não criar uma página por exportação quando os símbolos formam uma única família de uso.
|
|
72
|
+
- Não esconder APIs públicas de uma família em uma tabela de props compartilhada.
|
|
73
|
+
- Não editar projeção gerada quando existe fonte canônica.
|
|
74
|
+
- Não promover alteração de documentação a release, publicação ou push sem autorização específica.
|
|
75
|
+
|
|
76
|
+
## Recursos
|
|
77
|
+
|
|
78
|
+
- Ler [padrão editorial](references/editorial-standard.md) para anatomia, tom e revisão linha por
|
|
79
|
+
linha.
|
|
80
|
+
- Usar [avaliações](references/evaluations.md) ao criar ou alterar substancialmente esta skill.
|
|
81
|
+
- Usar `scripts/audit-docs.mjs [raiz-do-repositório]` para detectar páginas órfãs, fences
|
|
82
|
+
incompletos, saltos de heading e nomes genéricos de referência. O script complementa a leitura;
|
|
83
|
+
não decide clareza, progressão ou exatidão técnica.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Padrão editorial da documentação Opus
|
|
2
|
+
|
|
3
|
+
## Anatomia da página
|
|
4
|
+
|
|
5
|
+
Adotar a menor sequência que forme o modelo mental necessário:
|
|
6
|
+
|
|
7
|
+
1. **Situação e escolha:** dizer o que o recurso resolve e quando escolhê-lo. Contrastar com o
|
|
8
|
+
componente vizinho apenas quando essa distinção evita uma decisão errada.
|
|
9
|
+
2. **Exemplo canônico:** mostrar o menor uso realista e funcional antes das opções.
|
|
10
|
+
3. **Composição:** nomear as partes públicas e explicar a relação entre elas.
|
|
11
|
+
4. **Variações:** introduzir uma variação por necessidade observável, não por enumeração da API.
|
|
12
|
+
5. **Comportamentos e cuidados:** explicitar defaults, efeitos automáticos, acessibilidade, limites e
|
|
13
|
+
consequências perto do exemplo relevante.
|
|
14
|
+
6. **Referência:** terminar com uma seção identificada por componente público, sem fundir contratos
|
|
15
|
+
diferentes numa única tabela.
|
|
16
|
+
|
|
17
|
+
Nem toda página precisa de todas as seções. Remover a seção vazia em vez de preenchê-la com prosa
|
|
18
|
+
genérica.
|
|
19
|
+
|
|
20
|
+
## Voz
|
|
21
|
+
|
|
22
|
+
- Partir do objetivo da pessoa: “Use `Alert` para manter uma informação visível no contexto da
|
|
23
|
+
página.”
|
|
24
|
+
- Preferir verbo concreto e voz ativa: “O `PageHeader` organiza título e ações.”
|
|
25
|
+
- Apresentar o caminho recomendado com segurança; usar “pode” somente quando a alternativa é de
|
|
26
|
+
fato opcional.
|
|
27
|
+
- Introduzir termos técnicos em linguagem comum antes de depender deles.
|
|
28
|
+
- Manter tom próximo, sóbrio e profissional. Evitar propaganda, slogans, superlativos e entusiasmo
|
|
29
|
+
artificial.
|
|
30
|
+
- Evitar começar pela implementação: substituir “O componente é responsável por renderizar...”
|
|
31
|
+
pela decisão ou resultado que importa a quem usa.
|
|
32
|
+
- Usar frases e parágrafos curtos, sem fragmentar relações necessárias nem recorrer a abreviações.
|
|
33
|
+
|
|
34
|
+
## Exemplos
|
|
35
|
+
|
|
36
|
+
- Preparar o exemplo com uma frase que indique o objetivo ou o que deve ser observado.
|
|
37
|
+
- Manter exemplos executáveis, focados e coerentes com o caminho recomendado.
|
|
38
|
+
- Preferir uma pequena narrativa contínua a exemplos isolados que trocam de domínio sem necessidade.
|
|
39
|
+
- Não demonstrar combinações inválidas apenas para listar props.
|
|
40
|
+
- Depois do código, explicar somente efeitos que não sejam óbvios pela leitura: default aplicado,
|
|
41
|
+
estado controlado, ação automática, limite ou consequência.
|
|
42
|
+
- Usar preview para comportamento visual e bloco de código para integração sem palco executável.
|
|
43
|
+
|
|
44
|
+
## Famílias e referência
|
|
45
|
+
|
|
46
|
+
- Agrupar componentes quando a pessoa precisa compreendê-los em conjunto para realizar uma tarefa,
|
|
47
|
+
como `Button` e `ButtonGroup` ou `Page`, `PageHeader`, `PageBody` e `PageState`.
|
|
48
|
+
- Manter títulos e âncoras explícitos para cada membro da família.
|
|
49
|
+
- Criar `## Propriedades de ComponentName` para cada componente público que possui contrato próprio.
|
|
50
|
+
- Omitir tabela apenas para export sem props próprias ou alias cuja equivalência esteja declarada.
|
|
51
|
+
- Posicionar tipos compartilhados depois dos componentes que os utilizam ou numa seção claramente
|
|
52
|
+
nomeada.
|
|
53
|
+
|
|
54
|
+
## Links e navegação
|
|
55
|
+
|
|
56
|
+
- Inserir links no ponto da decisão: ao recomendar `Toast` como alternativa efêmera, ligar a palavra
|
|
57
|
+
à página correspondente.
|
|
58
|
+
- Não depender de uma seção genérica de “Veja também” para relações essenciais.
|
|
59
|
+
- Ao consolidar páginas, escolher um endereço canônico e preservar os anteriores com redirect.
|
|
60
|
+
- Conferir título visível, slug, registry, metadata e links como uma única identidade editorial.
|
|
61
|
+
|
|
62
|
+
## Revisão linha por linha
|
|
63
|
+
|
|
64
|
+
Para cada título, parágrafo, item, exemplo e célula de tabela, verificar:
|
|
65
|
+
|
|
66
|
+
1. A pessoa entende por que esta linha existe neste ponto da leitura?
|
|
67
|
+
2. A linha começa pela necessidade ou introduz detalhe interno cedo demais?
|
|
68
|
+
3. A afirmação é sustentada pelo código, teste ou decisão registrada?
|
|
69
|
+
4. Está claro se é default, obrigação, recomendação, alternativa ou exceção?
|
|
70
|
+
5. Há termo ainda não apresentado, pronome ambíguo ou contexto que só existe na cabeça de quem
|
|
71
|
+
implementou?
|
|
72
|
+
6. A frase pode ficar menor sem perder relação, condição ou consequência?
|
|
73
|
+
7. O exemplo mostra o caminho recomendado e continua compilável?
|
|
74
|
+
8. O texto ao redor do exemplo explica intenção e comportamento, sem narrar cada linha do código?
|
|
75
|
+
9. O título permite localizar a informação pela tarefa, inclusive por link direto?
|
|
76
|
+
10. Pontuação, capitalização, concordância e paralelismo estão consistentes?
|
|
77
|
+
|
|
78
|
+
Ao terminar cada página, reler a sequência inteira. Linhas corretas isoladamente ainda podem formar
|
|
79
|
+
uma página repetitiva, invertida ou sem progressão.
|
|
80
|
+
|
|
81
|
+
## Referência de estilo
|
|
82
|
+
|
|
83
|
+
O padrão absorve da documentação do Laravel a progressão do caso comum para os detalhes, os exemplos
|
|
84
|
+
como eixo narrativo, a explicação dos comportamentos automáticos e a navegação por decisões. O Opus
|
|
85
|
+
mantém sua própria voz em pt-BR: mais compacta, menos promocional e apoiada em previews visuais.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Avaliações
|
|
2
|
+
|
|
3
|
+
## Deve disparar
|
|
4
|
+
|
|
5
|
+
“Agrupe Button Group na página de Button, preserve a rota antiga e documente as props dos dois.”
|
|
6
|
+
|
|
7
|
+
“Revise toda a documentação publicada do Opus linha por linha e corrija a escrita.”
|
|
8
|
+
|
|
9
|
+
## Não deve disparar
|
|
10
|
+
|
|
11
|
+
“Escreva a regra de reembolso na documentação interna do produto.” Esse texto não pertence à
|
|
12
|
+
documentação publicada do SDK Opus.
|
|
13
|
+
|
|
14
|
+
“Corrija o alinhamento do ícone no Alert.” Uma mudança somente no componente pertence à
|
|
15
|
+
implementação de UI; esta skill entra apenas se a documentação também for criada ou alterada.
|
|
16
|
+
|
|
17
|
+
## Execução real
|
|
18
|
+
|
|
19
|
+
Fornecer uma página de família que começa pela lista completa de props, usa a mesma tabela para dois
|
|
20
|
+
componentes, mantém exemplos isolados sem objetivo, descreve implementação antes da decisão de uso e
|
|
21
|
+
remove a rota publicada do componente agrupado. Pedir a reorganização sem informar a resposta
|
|
22
|
+
esperada.
|
|
23
|
+
|
|
24
|
+
Aprovar somente quando a página começar pela situação e escolha, apresentar um exemplo canônico
|
|
25
|
+
executável, explicar defaults ou consequências no ponto relevante, criar referência identificada
|
|
26
|
+
para cada contrato público e preservar a rota anterior por redirect ou alias. Exigir que a escrita
|
|
27
|
+
seja próxima, direta e sóbria, sem copiar formulações da referência externa nem adotar tom
|
|
28
|
+
promocional.
|
|
29
|
+
|
|
30
|
+
Na revisão ampla, fornecer registry, metadata, componentes, testes e todas as páginas publicadas.
|
|
31
|
+
Exigir inventário explícito, leitura linha por linha, correção na fonte canônica, verificação dos
|
|
32
|
+
previews, typecheck, gates de copy e confirmação de que não restaram páginas órfãs. Reprovar se a
|
|
33
|
+
execução se limitar às páginas mais longas, fizer apenas busca por padrões ou declarar cobertura
|
|
34
|
+
total sem listar o universo revisado.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
const repoRoot = resolve(process.argv[2] ?? process.cwd());
|
|
7
|
+
const contentDir = resolve(repoRoot, "packages/opus/src/ui/docs/content");
|
|
8
|
+
const registryPath = resolve(repoRoot, "packages/opus/src/ui/docs/registry.tsx");
|
|
9
|
+
|
|
10
|
+
if (!existsSync(contentDir) || !existsSync(registryPath)) {
|
|
11
|
+
console.error(
|
|
12
|
+
"Não encontrei packages/opus/src/ui/docs/content e registry.tsx. Passe a raiz do repositório Opus.",
|
|
13
|
+
);
|
|
14
|
+
process.exit(2);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const registry = readFileSync(registryPath, "utf8");
|
|
18
|
+
const importedFiles = new Set(
|
|
19
|
+
[...registry.matchAll(/\.\/content\/([^"']+\.md)\?raw/g)].map((match) => match[1]),
|
|
20
|
+
);
|
|
21
|
+
const files = readdirSync(contentDir)
|
|
22
|
+
.filter((file) => file.endsWith(".md"))
|
|
23
|
+
.sort();
|
|
24
|
+
const findings = [];
|
|
25
|
+
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
const source = readFileSync(resolve(contentDir, file), "utf8");
|
|
28
|
+
const lines = source.split("\n");
|
|
29
|
+
|
|
30
|
+
if (!importedFiles.has(file)) {
|
|
31
|
+
findings.push(`${file}: página órfã; não há import no registry`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let inFence = false;
|
|
35
|
+
let previousHeading = 0;
|
|
36
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
37
|
+
const line = lines[index];
|
|
38
|
+
const lineNumber = index + 1;
|
|
39
|
+
|
|
40
|
+
if (/^```/.test(line)) {
|
|
41
|
+
inFence = !inFence;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (inFence) continue;
|
|
45
|
+
|
|
46
|
+
const heading = /^(#{1,6})\s+/.exec(line);
|
|
47
|
+
if (heading) {
|
|
48
|
+
const level = heading[1].length;
|
|
49
|
+
if (previousHeading > 0 && level > previousHeading + 1) {
|
|
50
|
+
findings.push(`${file}:${lineNumber}: heading salta de h${previousHeading} para h${level}`);
|
|
51
|
+
}
|
|
52
|
+
previousHeading = level;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (/^#{2,6}\s+Props(?:\s|$)/i.test(line)) {
|
|
56
|
+
findings.push(`${file}:${lineNumber}: nomeie a referência como “Propriedades de Componente”`);
|
|
57
|
+
}
|
|
58
|
+
if (/^\|\s*Prop\s*\|/i.test(line) || /\|\s*Default\s*\|/.test(line)) {
|
|
59
|
+
findings.push(`${file}:${lineNumber}: use “Propriedade” e “Padrão” no cabeçalho da tabela`);
|
|
60
|
+
}
|
|
61
|
+
if (/\b(?:pra|pro|pros|numa)\b/i.test(line)) {
|
|
62
|
+
findings.push(`${file}:${lineNumber}: abreviação coloquial na prosa`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (inFence) findings.push(`${file}: fence de código sem fechamento`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (const importedFile of importedFiles) {
|
|
70
|
+
if (!files.includes(importedFile)) {
|
|
71
|
+
findings.push(`${importedFile}: importado pelo registry, mas o arquivo não existe`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (findings.length > 0) {
|
|
76
|
+
console.error(findings.join("\n"));
|
|
77
|
+
console.error(`\n${findings.length} problema(s) estrutural(is) encontrado(s).`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.log(`${files.length} páginas auditadas; nenhuma inconsistência estrutural encontrada.`);
|
|
@@ -35,7 +35,8 @@ da mesma instância, sem catálogo repetido em enum, opção estática ou format
|
|
|
35
35
|
- **status** — situação operacional que muda com o tempo;
|
|
36
36
|
- **stage** — etapa de um ciclo ou funil;
|
|
37
37
|
- **plain** — valor que só precisa ser legível (o mesmo efeito de omitir).
|
|
38
|
-
Por entrada, declarar `
|
|
38
|
+
Por entrada, declarar `context` somente em status e estágio, usando `neutral`, `info`, `success`,
|
|
39
|
+
`warning` ou `danger`; `icon` somente com nome existente no
|
|
39
40
|
catálogo `iconPickerIcons`, e `description` somente quando acrescentar algo ao rótulo. `doc`
|
|
40
41
|
continua sendo o entendimento de negócio para manifest e Lens; não é tooltip.
|
|
41
42
|
4. Derivar o schema por `.zod()` e usá-lo em todo contrato que valide o código; não redeclarar a
|
|
@@ -68,7 +69,8 @@ contrato ou componente mapeado, regenerar com `opus copy` e executar os checks d
|
|
|
68
69
|
- Não tratar metadata de dicionário como autorização ou invariante de integridade.
|
|
69
70
|
- Não omitir `presentation` esperando que a tela deduza o papel pelo nome do dicionário; sem
|
|
70
71
|
papel declarado, o valor é texto.
|
|
71
|
-
- Não declarar `
|
|
72
|
+
- Não declarar `context` em classificação, nem usar o alias legado `tone` em código novo, nem
|
|
73
|
+
`icon` fora do catálogo, nem `description` que
|
|
72
74
|
repita o rótulo.
|
|
73
75
|
|
|
74
76
|
## Recursos
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
interface lê rótulos por `labelFor`/`metaFor`.
|
|
12
12
|
- Execução de apresentação: dado um cadastro com “Pessoa física/Empresa” e “Prospect/Cliente”,
|
|
13
13
|
declarar o primeiro como `classification` com ícones `user` e `building` do catálogo e o segundo
|
|
14
|
-
como `stage` com `
|
|
15
|
-
projeta `presentation` e que `t.dict` rejeita
|
|
16
|
-
- Reprova: declarar `
|
|
14
|
+
como `stage` com `context` explícito, sem `description` que repita o rótulo; provar que o manifest
|
|
15
|
+
projeta `presentation` e `context` e que `t.dict` rejeita valores fora do vocabulário.
|
|
16
|
+
- Reprova: declarar `context` em uma classificação, usar o alias legado `tone` em código novo,
|
|
17
|
+
inventar `icon` fora do catálogo, copiar `doc`
|
|
17
18
|
para `description` ou deixar `presentation` ausente em um status esperando que a tela infira o
|
|
18
19
|
badge.
|
|
@@ -26,7 +26,7 @@ export function App(): React.ReactElement {
|
|
|
26
26
|
{items.map((t) => (
|
|
27
27
|
<li key={t.id} className="flex items-center justify-between gap-2 text-sm">
|
|
28
28
|
<span>{t.title}</span>
|
|
29
|
-
<Badge
|
|
29
|
+
<Badge context={t.done ? 'success' : 'neutral'}>{t.done ? 'Feita' : 'Aberta'}</Badge>
|
|
30
30
|
</li>
|
|
31
31
|
))}
|
|
32
32
|
</ul>
|