npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@noclaf/cli-core

v1.11.0

Published

Core whitelabel de MCP server + CLI para gestão de projetos a partir de assistentes de IA: módulos por domínio, marca injetada, pacote de cliente por cima.

Readme

@noclaf/cli-core

Core whitelabel de MCP server + CLI para gestão de projetos a partir de assistentes de IA (Claude Code, Codex CLI, Copilot, Cowork). O core não tem marca nem binário: cada cliente é um pacote pequeno que escolhe os módulos, passa a marca e publica o próprio CLI.

Montar um cliente

// src/app.ts
import { fileURLToPath } from 'node:url';
import { coreModules } from '@noclaf/cli-core/modules';
import type { ClientOptions } from '@noclaf/cli-core/cli';
import { brand } from './brand.js';

export const options = {
  brand,
  modules: coreModules,
  packageRoot: fileURLToPath(new URL('..', import.meta.url)),
  supabase: { url: 'https://<projeto>.supabase.co', anonKey: '<anon key>' },
} satisfies ClientOptions;
// src/cli.ts
#!/usr/bin/env node
import { runCli } from '@noclaf/cli-core/cli';
import { options } from './app.js';

await runCli(options);

src/mcp-server.ts é igual, com runMcpServer de @noclaf/cli-core/mcp.

O package.json do cliente declara os bin apontando pra dist/cli.js e dist/mcp-server.js e depende do core por major (^1.0.0). packageRoot é a raiz do pacote do cliente: dele saem a versão, o caminho do binário MCP gravado nos configs e o conteúdo da extensão .mcpb. A tabela de tools e comandos do README do cliente sai de updateReadme(options, caminhoDoReadme), entre <!-- TOOLS:START/END --> e <!-- COMMANDS:START/END -->.

Referência viva: nos-cli (todos os módulos) e qas-cli (sem time).

Exports

| Subpath | O que tem | | --- | --- | | . | createApp, defineModule, defineTool, projectIdArg, z, NotFoundError, LOCALES, tipos (Brand, Module, ports, entidades) | | ./modules | coreModules e cada módulo: projects, tasks, time, delivery, exec, sprints, releases, calendar, homeOffice | | ./modules/<nome> | um módulo só | | ./adapters/supabase | gateway, client autenticado, helpers de query | | ./cli | runCli, buildProgram, updateReadme, ClientOptions | | ./mcp | runMcpServer |

Use o z reexportado pelo core nos módulos de cliente: o inputSchema das tools sai do zod do core, e o zod é pinado em versão exata porque a saída do JSON Schema muda entre minors.

Marca

Brand (em .) junta nome do binário, prefixos das tools (toolPrefix pras tools de produto, cliToolPrefix pras que espelham o CLI; os dois ^[a-z][a-z0-9]*_$), prefixo de env, pasta em ~, arquivo de config do repo, PAT, repo e pacote de skills e o locale. createApp registra a marca; textos, env e caminhos do core leem dela. Um processo roda uma marca por vez.

Módulos

Cada domínio é um módulo em src/modules/<nome>/: tools/, i18n/<locale>.ts, port.ts (o que ele exige do gateway) e supabase*.ts (o adapter desse port). createApp({ brand, modules }) monta o registry MCP e os comandos do CLI dos módulos ligados; requires declara dependência entre módulos e falha cedo quando falta. O locale vem da marca: um módulo que não traz o locale da marca não compila.

  • Entidade do core é fechada. Campo a mais em task, sprint ou release não entra no módulo do core: vira um módulo do cliente, com tabela própria (task_id), tool própria e i18n própria. Exemplo completo em examples/module-extra/ (migration, port, adapter, tool, i18n e o cliente ligando tudo); o adapter entra por supabase.gateway nas opções do cliente. bun run check:examples compila o exemplo contra o build do pacote.
  • Módulo não conhece a marca. Tools recebem os textos já resolvidos e o prefixo entra na montagem.
  • Backend só no supabase*.ts do módulo. O resto fala com o port.ts.

Contrato de backend

Cada módulo declara em supabase-contract.ts as tabelas que espera: colunas, tipo, nulidade, referências e as regras de acesso (estas em i18n/<locale>-backend.ts). As colunas são checadas pelo compilador contra database.types.ts, e um teste garante que toda tabela e coluna que o adapter lê está no contrato do módulo ou das suas dependências. O núcleo (perfis e a edge function que troca o PAT) fica em adapters/supabase/contract.ts.

No cliente:

  • <bin> backend contract -o BACKEND.md gera o contrato em Markdown só para os módulos ligados. É o documento para quem implementa o backend.
  • <bin> backend check valida o Supabase configurado: tabelas, colunas, tipos, valores de enum, a função de PAT e se o anon lê alguma linha. Logado, também confere o acesso de um usuário real. Sai com código 1 se houver erro; --json para automação.

Módulo do cliente com tabela própria declara backend(t) devolvendo um BackendContract (o helper tipado tables() só cobre as tabelas do core).

Documentação

<bin> docs gera a documentação do cliente num HTML único e abre no navegador: guias (instalação, autenticação, backend), comandos gerais e uma página por módulo ligado, com os comandos de CLI, as tools MCP e o contrato de backend. -o <arquivo> grava onde quiser, --no-open não abre o navegador e --json emite só o modelo. O visual vem de @noclaf/cli-docs.

O conteúdo sai do próprio app montado, sem arquivo de documentação à parte. Cada módulo só declara docs(t) com título, resumo e, se quiser, uma visão geral em Markdown (os textos ficam no i18n do módulo). O logo vem de brand.icon (URL ou data URI).

Histórico de versões da documentação

Se o pacote do cliente traz um docs-history.json na raiz, o docs mostra o seletor de versões, a comparação e o changelog. O arquivo é gerado no release, a partir do histórico publicado na versão anterior (sem retroativo: o primeiro release com a etapa cria um histórico de uma versão). Histórico de outro pacote, malformado ou de outro formato é ignorado.

No workflow de publicação do cliente (checkout com fetch-depth: 0), depois do build:

- name: Docs history
  env: { NO_UPDATE_NOTIFIER: '1' }
  run: |
    node dist/cli.js docs --json > "$RUNNER_TEMP/model.json"
    npx cli-core-docs-history --model "$RUNNER_TEMP/model.json" --out docs-history.json

Inclua docs-history.json em files e no .gitignore. Flags: --model <arquivo|->, --repo ., --out, --dry-run, --tmp <dir>. O tamanho é checado (aviso acima de 64 KB, erro acima de 128 KB). As notas vêm dos commits feat:/fix: desde a tag anterior, do corpo do commit de release e do CHANGELOG do core na faixa de versões.

Versionamento

Semver com changesets. Todo PR que muda o pacote traz um bunx changeset.

| Mudança | Versão | | --- | --- | | Nome ou schema de tool (fixture tool-schemas), contrato de módulo, port, ClientOptions, migration destrutiva | major | | Tool nova, módulo novo, export novo, migration aditiva | minor | | Texto, correção | patch |

Publicar

bun run release                     # aplica os changesets: versão + CHANGELOG
git commit -am "release v$(node -p "require('./package.json').version")"
git tag -a "v$(node -p "require('./package.json').version")" -m release && git push --follow-tags

A tag v* dispara .github/workflows/publish.yml (npm público, trusted publishing via OIDC). O CI de PR roda lint, testes, build e, com a variable CLIENT_REPO definida, instala o cliente contra o tarball do PR (canary).

O mesmo workflow gera o site geral da documentação (todos os módulos, marca neutra) e anexa como artefato docs-site-<tag> do run (fica 90 dias). Ele não é publicado; localmente, bun run docs:site grava em site/index.html.

Convenções

  • Idioma: textos em pt-BR (por módulo, em i18n/). Código em inglês.
  • Backups: escrita em arquivo de config existente gera .bak.<timestamp> ao lado.
  • stdout reservado pro JSON-RPC no MCP server; logs vão pra stderr.
  • Testes rodam com a marca fixture de src/__tests__/brand.ts, carregada pelo bunfig.toml.