@softize/opus
v21.0.1
Published
End-to-end action protocol for TypeScript. Single package with subpath exports (core + adapters).
Readme
Opus
Pacote único
@softize/opuscom subpath exports (core + adapters). Uma versão, sem semver por módulo.
Protocolo de actions de ponta a ponta para TypeScript. Declare uma vez — input, autorização, execução, auditoria, feedback — e deixe os adapters materializarem a action na interface, no cliente, no servidor e no log.
O Opus não é framework. Não tem ciclo de vida próprio. É o contrato comum que todas as camadas falam.
Filosofia
- Pipeline declarado, não escrita declarada. Action é qualquer unidade que flui pelo pipeline (validate → load → authorize → execute → audit → return), independente de mudar estado. Cobre write (form, simple) e read estruturado (list, view).
- Três primitivas declarativas. Action (humano/AI dispara) + Reaction (evento dispara) + Schedule (tempo dispara). Fecha o ciclo de ação proativa.
- Provenance rastreável. Toda execução carrega origem estruturada (http, schedule, reaction, ai-agent, background, ...) com cadeia preservada via
originalProvenance. Audit registra a árvore de causalidade do user até a action final. - Kind como discriminator. v0 suporta
simple,form,list,view. - Contrato, não feature. Tudo que entra no core padroniza forma; tudo que faz trabalho usa lib externa.
- Fail-closed por default. Action sem
authorizeé negada. Audit default-on. - Adapters plugáveis. Cada categoria é uma superfície (subpath) com interface fechada e drivers trocáveis.
- Declaração é a fonte; doc é projeção. As declarações (
defineContract,bindAction,defineEntity,defineDataProduct) são a fonte dos contratos; manifest, OpenAPI e a doc gerada são projeções.docs/protocol.mddescreve o protocolo em 16 seções (15 + glossário).
Superfícies
Um pacote (@softize/opus), uma versão. Cada categoria abaixo é um subpath ESM, não um pacote separado.
| Superfície | Drivers | Propósito |
|---|---|---|
| @softize/opus (core) | — | Protocolo, Actions, entities, Produtos de Dados e runtime |
| @softize/opus/schema | /zod, /openapi | Tipos lógicos (t.*) e gerador de OpenAPI |
| @softize/opus/server | /fastify, /node | Transporte HTTP e montagem de endpoints |
| @softize/opus/client | /fetch | Adapter de cliente para invocar actions |
| @softize/opus/ui | /react, /meta, /docs | Componentes, Provider e hooks (useAction, useListAction) |
| @softize/opus/data | /kysely, /readonly-pool | Adapter de dados (ctx.db, ctx.repo) |
| @softize/opus/auth | /jwt, /better-auth | Adapter de autenticação (ctx.user, ctx.can) |
| @softize/opus/audit | /console, /pg | Destinos de auditoria |
| @softize/opus/log | /pino | Adapter de log (console é o default no core) |
| @softize/opus/queue | /bullmq | Execução de jobs em segundo plano |
| @softize/opus/executions | /memory, /pg, /pg-changes, /stream | Projeção e SSE de acompanhamento (experimental, opt-in) |
| @softize/opus/events | /mitt | EventBus em processo |
| @softize/opus/scheduler | /node-cron | Adapter de agendamento (ação iniciada por tempo) |
| @softize/opus/storage | /fs, /s3 | Armazenamento de arquivos (experimental) |
| @softize/opus/cache | /memory | Cache de leitura para handlers (experimental) |
| @softize/opus/ai | /anthropic | Capability de IA generativa: complete e extract (experimental) |
| @softize/opus/mcp | — | Expõe actions ai:enabled como tools MCP para agentes externos |
| @softize/opus/observability | /opentelemetry | Traces e contexto de execução, com porta vendor-neutral no core |
| @softize/opus/testing | — | Harness de teste de actions pela fronteira do contrato (experimental) |
| @softize/opus/dsl | — | Expressões declarativas avaliadas em load e em consultas |
| @softize/opus/seed | — | Declaração e binding de datasets verificáveis operados pela CLI |
| @softize/opus/presentation | — | Presentations portáteis: definePresentation, invocação e rotas |
| @softize/opus/vite | — | Plugins Vite: runtime em modo design e auth de sessão fixa |
Os drivers são resolvidos por subpath ESM (no estilo do Drizzle): @softize/opus/server/fastify, @softize/opus/data/kysely.
Quick start
pnpm add @softize/opus zod fastifyimport Fastify from 'fastify'
import { z } from 'zod'
import { createRuntime, defineAction } from '@softize/opus'
import { t } from '@softize/opus/schema/zod'
import { fastifyServer } from '@softize/opus/server/fastify'
const archiveDeal = defineAction({
name: 'deal.archive',
kind: 'simple',
input: z.object({ dealId: z.string() }),
output: z.object({ archivedAt: t.datetime() }),
authorize: (ctx) => ctx.can('deal:archive'),
handler: async (_ctx, input) => ({ archivedAt: new Date().toISOString() }),
})
const app = Fastify()
const server = fastifyServer({ app })
const runtime = createRuntime({ server })
runtime.register([archiveDeal])
await runtime.start()
server.mountEndpoints({ openapi: true })
await app.listen({ port: 3000 })
// POST http://localhost:3000/api/deal/archive
// GET http://localhost:3000/openapi.json
// GET http://localhost:3000/health
// GET http://localhost:3000/readyEstrutura
src/
core/ schema/ server/ client/ ui/ data/ auth/ audit/
log/ queue/ events/ scheduler/ storage/ cache/ ai/ mcp/
observability/ testing/ dsl/ seed/ vite/ presentation/
registry/ # scaffolds + skills Opus — geração e conhecimento do SDK, não runtime
bin/ # CLI (opus create/setup/gen/copy/check/db/seed/pre-push/introspect/mcp) + libs
docs/
protocol.md # contrato completo (16 seções)
data-layer.md · data-products.md · seeds.md · releasing.md · code-style.mdSeeds de projeto
Datasets persistentes de desenvolvimento, teste e demonstração usam defineSeed + bindSeed e
ficam registrados em opus.config.ts. A CLI descobre e valida sem abrir conexão, exige escopo
explícito para operar e bloqueia produção:
pnpm exec opus seed list
pnpm exec opus seed check
pnpm exec opus seed plan customers.scenarios --profile smoke --scope local
pnpm exec opus seed apply customers.scenarios --profile smoke --scope local
pnpm exec opus seed verify customers.scenarios --profile smoke --scope localO contrato não oferece reset/truncate, e apply precisa convergir quando repetido. Veja
docs/seeds.md.
Status
- Hoje: 22 superfícies, suíte vitest com cobertura medida por
pnpm test:cov. O threshold de 100% emvitest.config.tsé aspiracional e não faz parte do gate de release (ver docs/releasing.md). - Próximos: drivers adicionais (Hono, Drizzle, ArkType, Vue, Inngest, Redis events) e o plano de migração da Conversya.
Desenvolvimento
pnpm install # instala deps
pnpm typecheck # tsc --noEmit
pnpm test # vitest run
pnpm test:cov # com coverage reportQualidade de copy
O Opus extrai o papel semântico dos textos declarados nos contratos; a política universal e
seus fundamentos ficam na @softize/base. Uma allowlist pequena também cobre texto estático
de componentes importados diretamente de @softize/opus/ui ou seus subpaths. O inventário
derivado usa o protocolo v2, é versionado e conferido sem escrita nos gates:
# No projeto criado por `opus create` (o scaffold declara este script):
pnpm run setup
pnpm exec opus copy
pnpm exec opus copy --check
pnpm exec base copy checkNeste repositório-fonte, que não declara um script setup na raiz, a materialização
equivalente usa os comandos reais e os cwd exigidos por cada protocolo:
node packages/opus/bin/cli.mjs setup
pnpm --filter @softize/opus exec base setupO manifesto lista com hash todo JS/TS submetido à análise, inclusive arquivos com zero entradas,
e reporta as contagens observáveis; ele não afirma cobertura total do repositório. O gate verde
não cobre JSX nativo nem wrappers locais; essas superfícies continuam na revisão editorial.
Texto de runtime que ocupa uma superfície Opus mapeada falha visivelmente, e aria-label não
mascara copy visual opaca. Detalhes e mapeamentos estão em
docs/code-style.md.
Publicar
Publicado no npm público (registry.npmjs.org). pnpm release
[patch|minor|major|x.y.z] bumpa + publica. Passo a passo
(verificar, testar local, auth) em docs/releasing.md.
Licença
A decidir. Ver docs/protocol.md — Decisões em aberto.
