
cannonball
Você não começa do zero — chega com impulso. Guarda as peças de site que você já fez e as encontra de volta antes de gerar qualquer coisa outra vez. Agent Sk…
Install with your AI
This project is repository unavailable — not recommended for automated install, so we don't generate an auto-install prompt for it. Read the repo and decide for yourself.
// compatibility
| Platforms | cli, api, web, mobile |
|---|---|
| Operating systems | — |
| AI compatibility | claude |
| License | MIT |
| Pricing | open-source |
| Language | Python |
cannonball
Você não começa do zero. Você já chega com impulso.
Plugin do Claude Code que guarda as peças de site que você já fez — e as encontra de volta, antes de qualquer coisa ser gerada outra vez.
O acervo é seu, e começa quase vazio: vêm três peças de exemplo e mais nada. Você alimenta com o que já tem — prompt, componente, efeito, design system, projeto inteiro — e a partir daí as skills decidem a partir do que existe ali dentro, não de uma lista fixa escrita por outra pessoa.
Nenhuma skill carrega número fixo. Todas leem o acervo na hora, então o mesmo motor serve quem tem três peças e quem tem mil — e fica melhor a cada uma que entra.
O ciclo
ingerir → indexar → buscar → montar → registrar armadilha → ingerir…
Cada volta o acervo fica melhor, e as skills junto com ele. Não há número fixo em lugar nenhum: toda skill lê o acervo na hora.
python scripts/perfil.py
É o retrato de agora — famílias, setores, stacks, cobertura por função, lacunas, armadilhas registradas e os avisos de saúde. Toda skill começa por aí.
Instalar
As nove skills originais exigem apenas Python 3 e usam a biblioteca padrão. A
skill opcional /lab exige também Node.js 22.13+; ela instala suas dependências
npm somente quando o usuário abre o laboratório pela primeira vez.
Claude Code
git clone https://github.com/harebeats/cannonball.git
cd cannonball
claude plugin marketplace add .
claude plugin install cannonball@cannonball
Codex, Gemini CLI, Cursor e os outros
A CLI do Agent Skills instala nos agentes que encontrar:
npx skills add harebeats/cannonball -g
-g instala para o seu usuário (~/.codex/skills, ~/.gemini/skills,
~/.agents/skills…); sem ele, instala no projeto atual. Para mirar um só:
npx skills add harebeats/cannonball -g -a codex
npx skills add harebeats/cannonball -g -a gemini
npx skills list harebeats/cannonball # ver as 10 antes de instalar
Cada pasta em skills/ é autocontida — carrega o SKILL.md, o scripts/ que ele
chama, o references/ que cita e o seed/. Você pode instalar as dez ou só a que
interessa: kit-cor e kit-tipo, por exemplo, resolvem paleta e licença de fonte sem
depender de acervo nenhum.
Manual, em qualquer agente
git clone https://github.com/harebeats/cannonball.git
ln -s "$(pwd)/cannonball/skills/kit-buscar" ~/.agents/skills/kit-buscar
O símbolo mantém a instalação em dia com o seu clone. Serve para ~/.codex/skills,
~/.gemini/skills, ~/.cursor/skills — a pasta muda, o resto não.
Por que funciona igual em todos. Nenhum
SKILL.mdusa variável de ambiente de agente. Cada um resolve os próprios scripts a partir da pasta de onde foi lido, o que é informação que todo harness dá. Ver AGENTS.md.O frontmatter fica nos seis campos da spec do Agent Skills —
name,description,license,compatibility,metadata,allowed-tools. Campo fora da spec não é ignorado lá fora:npx skills adde a Skills API falham com erro duro.publicar.pyrecusa exportar se algum escapar.
O acervo é criado em ~/.cannonball na primeira vez que uma skill roda, já com as
três peças de exemplo dentro.
O que vem na caixa
Três componentes originais, e eles existem tanto para a primeira busca devolver alguma coisa quanto para servir de modelo de ficha bem escrita:
| Peça | O que resolve |
|---|---|
kit-agendamento | serviço → data/hora → contato, com expediente, duração e antecedência como configuração |
kit-calendario | seleção de data com teclado, idioma via Intl, disponibilidade por predicado |
kit-mapa | localização sem chave de API, na paleta do site por filtro CSS |
Vêm com 11 armadilhas registradas — sobreposição de horário que dobra a agenda,
new Date() durante a renderização quebrando hidratação entre servidor UTC e
visitante UTC−3, iframe de mapa roubando o scroll da página. Busque por
agendamento e leia: é o formato que o resto do acervo deve seguir.
Nenhuma tem dependência npm nem asset externo. Toda a aparência sai de variável CSS
(--kit-*, com fallback nos tokens do site e, por último, currentColor), e texto e
regra de negócio saem de prop. Trocar de cliente é trocar configuração.
São suas depois de copiadas: edite, melhore ou apague. Nada volta a sobrescrever.
Vincule a sua pasta — é o primeiro passo, e o mais fácil de esquecer
Sem isso o acervo nasce em ~/.cannonball, que serve para experimentar mas quase
nunca é onde você quer o material a longo prazo. Faça antes de ingerir qualquer
coisa — depois é mover pasta na mão.
python scripts/vincular.py --para ~/meu-acervo
O ponteiro é gravado em ~/.cannonball/aonde, fora do plugin. Isso importa: o
plugin instalado é uma cópia em cache que a próxima atualização apaga, então qualquer
configuração gravada dentro dele se perde em silêncio.
python scripts/vincular.py # onde está agora, e quem está mandando
python scripts/vincular.py --para <pasta> --mover # leva junto o que já tem
python scripts/vincular.py --soltar # volta para o padrão
Se preferir variável de ambiente, ela vence o ponteiro:
export CANNONBALL_ACERVO="/caminho/para/o/acervo".
Aponte para uma pasta versionada num repositório privado seu: o acervo é material seu e de terceiros, e não é para redistribuir.
Por onde começar
Para instalar e abrir o laboratório 3D local, use apenas:
/lab
Na primeira execução, o comando instala o aplicativo em ~/.cannonball/3d-lab.
Depois inicia o Lab e abre http://localhost:5555. O pacote público não inclui o
corpus usado no desenvolvimento, pesos do SF3D, outputs ou credenciais.
O plugin não impõe ordem — as skills disparam sozinhas quando o assunto aparece. Mas existe uma sequência que dá resultado muito melhor, e ela sai adaptada ao estado do seu acervo em:
python scripts/perfil.py
Uma vez, ao instalar:
| 1 | vincular.py --para <pasta> | diga qual pasta é o seu acervo |
| 2 | /kit-ingerir | encha com o que você já tem — arquivo, texto colado, projeto inteiro, registro shadcn |
| 3 | /kit-curar | depois da primeira leva grande: acha ficha fraca, que é peça invisível para a busca |
Em cada projeto novo:
| 1 | /kit-buscar | o que eu já tenho pra isso? Dispara sozinha antes de construir |
| 2 | /kit-cor | decida a cor antes de escolher o design system |
| 3 | /kit-tipo | confira a licença antes de adotar a fonte |
| 4 | /kit-montar | pergunta a stack e o tipo de hero, e monta |
| 5 | /kit-otimizar-3d | se tem WebGL, antes de entregar |
| 6 | /kit-ingerir | guarde o que deu certo e registre a armadilha |
A ordem de 2 e 3 não é preciosismo: escolher o design system primeiro faz a cor e a fonte virem de brinde, e é exatamente assim que se chega no automático — e como se descobre na entrega que a fonte é paga.
O passo 6 é o que fecha o ciclo. Sem ele o plugin é uma biblioteca parada; com ele, cada projeto deixa o próximo mais rápido.
As duas que trabalham com prompt
Nem todo trabalho termina em código escrito aqui. Metade do que circula em web design hoje é prompt — o brief que você leva ao v0, o texto que alguém te mandou no Twitter, a spec que você guarda para reusar. Duas skills existem só para isso, e elas são as portas de entrada e de saída do acervo.
/kit-prompt — o acervo vira prompt
Entrevista sobre o site e devolve um prompt de construção completo, no padrão dos que já funcionaram: stack, fontes com licença conferida, paleta com contraste medido, estrutura seção a seção, medidas exatas e proibições explícitas.
O resultado é texto. Você leva para o v0, o Lovable, o Cursor, outro modelo — ou guarda no acervo para a próxima vez.
"gera um prompt pra uma landing de clínica" → o texto, pronto para levar
O que separa isso de pedir um prompt a qualquer modelo: ele é alimentado pelo seu
acervo. A paleta sai da kit-cor com contraste já medido, a fonte sai da kit-tipo
com licença já conferida, a estrutura sai de um template que já rodou. Prompt genérico
devolve site genérico.
/kit-adaptar — o prompt de fora vira seu
O caminho inverso, e o mais subestimado. Alguém te manda um prompt em inglês, sem contexto, que constrói sabe-se lá o quê. Esta skill lê e devolve em português:
- que tipo de site é, e qual o escopo real (hero solto ou landing inteira)
- seção por seção, o que cada uma faz
- a técnica por trás (hover, cursor, scroll, WebGL, vídeo) e o que ela custa
- stack e dependências
- o mapa de assets — o caminho exato de cada arquivo que o prompt vai pedir
Essa última linha é a que economiza a tarde: prompt de fora sempre assume mídia que você não tem. O que faltar vira placeholder descrito, não erro no meio do build.
Depois ela torce o prompt para o seu projeto — sua stack, seu setor, seu cliente. Aceita print ou vídeo do site original junto, se você tiver.
[cola um prompt em inglês] → "o que é isso?" → "adapta pra clínica"
As duas funcionam com o acervo vazio. A kit-adaptar não depende de peça nenhuma,
e a kit-prompt fica melhor com acervo mas não precisa dele. São o caminho mais curto
para tirar valor do plugin no primeiro dia — e o que sair bom delas, você ingere.
O exemplo
exemplo/ — a SHUI, loja de streetwear com 81 produtos, 765
variantes e 99 páginas estáticas, montada de três peças do acervo: um template deu as
rotas e o carrinho, outro deu a ficha de produto, um design system deu a identidade.
E os quatro bugs que a montagem encontrou — SKU repetido entre tamanhos, opcao1
que não é a cor, next/link baixando doze páginas por clique, a mesma cor cadastrada
de cinco jeitos. Nenhum dá erro. Todos viraram armadilha nas peças de origem.
É o ciclo inteiro num lugar só: buscar → montar → tropeçar → registrar.
As skills
| Skill | Quando dispara |
|---|---|
kit-buscar | "que hero eu tenho pra clínica?" — e sozinha, antes de construir qualquer seção |
kit-montar | "monta uma landing pra joalheria" — do briefing ao código |
kit-prompt | "gera um prompt pra esse site" — do briefing ao texto, para levar ao v0, Lovable, Cursor. Detalhe ↑ |
kit-adaptar | "o que esse prompt constrói?" — lê prompt de fora, traduz, mapeia os assets e adapta ao seu projeto. Detalhe ↑ |
kit-cor | "define a paleta", "está tudo no automático" — decide a cor antes do design system |
kit-tipo | "que fonte usar", "essa fonte é paga?" — licença, substituto livre, par e escala |
kit-otimizar-3d | "a cena trava no celular" — e antes de entregar qualquer projeto com WebGL |
lab | /lab — instala e abre o Cannonball 3D Lab em localhost:5555 |
kit-ingerir | "guarda isso" — arquivo, texto colado, projeto inteiro, registro shadcn ou MCP |
kit-curar | saúde do acervo: duplicatas, fichas fracas, assets mortos |
Cinco delas funcionam com o acervo vazio: lab, kit-cor, kit-tipo,
kit-otimizar-3d e kit-adaptar não dependem de peça guardada. As outras degradam
com uma frase em vez de quebrar, e mandam você ingerir.
As famílias
Um acervo mistura naturezas diferentes, e é a natureza que decide como a peça se usa:
| Família | O que é | Como se usa |
|---|---|---|
receita | composição de peças que já deu certo | ponto de partida |
template | projeto de site completo e rodável | você clona |
design-system | identidade visual: paleta, tipografia, regras | você aplica |
efeito | wrapper WebGL ou objeto 3D | você copia |
ui | componente React pronto | você copia |
animacao | demo isolada de uma técnica | você extrai |
html | página completa sem build | abre no navegador |
mcp | ficha aqui, código gerado sob medida por um servidor | você pede |
prompt | spec em linguagem natural de uma página | você executa |
Ordem de preferência quando mais de uma serve: receita → template → código → prompt. Prompt por último porque re-gera tudo e o resultado varia.
A combinação que dá o maior ganho, e a razão de o acervo existir:
template ou prompt dá a estrutura — rotas, seções, componentes. design system dá a identidade — paleta, tipografia, espaçamento, regras.
Os dois eixos são independentes, então N templates × M identidades é um espaço de combinação grande sem repetir visual entre clientes.
O que faz a busca funcionar
Cada peça tem quando_usar e nao_usar_quando. São eles que fazem a skill decidir
sozinha, em vez de devolver 12 heros para você escolher na mão.
nao_usar_quando fica fora do texto pesquisável de propósito: se entrasse,
buscar "mobile" ranquearia no topo justamente as peças que dizem "não use em mobile".
Ao guardar peça nova, esses dois campos são o trabalho que importa. Concreto vence genérico: "clínica odontológica que quer destacar um procedimento" serve; "sites modernos e bonitos" não serve para nada. Uma peça mal descrita continua no disco e some da busca — e some da busca é o mesmo que não ter.
Armadilhas — o ciclo que faz o acervo aprender
nao_usar_quando responde "devo escolher esta peça?". Armadilha responde outra
coisa: "escolhi — onde vou tropeçar?".
Toda montagem descobre o que não estava em documentação nenhuma. Esse conhecimento custou caro e não pode morrer dentro da nota de um projeto:
python scripts/armadilhas.py --add luxury-hero \
--texto "Tailwind v4: o reset '*{padding:0}' precisa ficar dentro de @layer base — solto, anula o espaçamento inteiro em silêncio" \
--origem imobiliaria-luxo-escura --grau alta
python scripts/indexar.py
A busca imprime como ARMADILHA: e o texto entra no índice — quem procura
"contraste" acha as peças que já reprovaram.
--grau separa o que trava do que incomoda: critica (página em branco, build
falhando, dado errado gravado), alta (visual quebrado, performance no chão) e
media (ajuste fino). A busca ordena por gravidade — sem isso, a que derruba o site
sai lado a lado com a que desalinha 2px.
É o que nenhum catálogo externo tem. Catálogo descreve o que a peça faz; só o seu acervo sabe onde ela já te derrubou.
Cor e tipografia: os dois vieses previsíveis
Todo acervo montado a partir de site real herda os mesmos dois defeitos. Os dois são mensuráveis, e as skills medem em vez de adivinhar.
Cor — mesmice. Design system vem de marca, marca converge para neutro e azul, tema claro. Puxar design system sem ter decidido a cor devolve o lugar-comum.
python scripts/cor.py --vies # de onde vem o automático
python scripts/cor.py --paleta --fundo … --tinta … --acento …
python scripts/cor.py --contraste "#767676" "#ffffff"
O script deriva 11 papéis a partir de três decisões e mede WCAG 2.x em cada par que existe na tela — separando o que tem mínimo obrigatório do que não tem. Divisória decorativa não precisa de 3:1, e forçá-la produz aquela borda pesada que denuncia site feito por régua.
Tipo — fragmentação, e o problema é legal. Site de marca paga por tipo, então o acervo enche de fonte comercial que você não pode servir. Design system nomeia a fonte e não diz onde carregá-la; prompt de página puxa de site de redistribuição.
python scripts/tipo.py --vies
python scripts/tipo.py --licenca "Aeonik" # comercial, CoType
python scripts/tipo.py --substituir "Roobert" # -> General Sans
python scripts/tipo.py --par "Instrument Serif"
python scripts/tipo.py --escala --base 17 --razao 1.25
Cor é de graça; tipo não é. SF Pro é o caso que mais passa batido: está
instalada em todo Mac e a licença da Apple não permite servi-la na web.
A base de licenças (scripts/fontes_licenca.json) vem com o plugin e não depende do
acervo.
MCPs que o cannonball usa
Nenhum é obrigatório — o motor funciona sozinho. Cada um fecha um buraco distinto, e as skills só disparam a seção correspondente quando o MCP está ligado.
| MCP | Para quê | Livre | Com cota |
|---|---|---|---|
| GetLayers | composição (esqueleto de layout), background de vídeo, cena 3D nova — o que um acervo de código não tem por natureza | start, search, browse, compositions, palettes, fonts, source | materialize; downloadProject = 3/dia |
| Motion Sites | catálogo de prompt de página inteira | list_prompts, search_prompts, get_related_prompts | get_prompt = 3 na conta sem plano |
| OriginKit | componente gerado já na sua stack | list_components, search | get_component |
| Higgsfield | imagem e vídeo do hero, quando o cliente não tem material | get_cost (preflight) | generate_image, generate_video — crédito real |
Detalhes de cada um em references/. O Higgsfield é o único que gasta dinheiro do usuário por chamada: higgsfield.md traz a disciplina de custo, os modelos e o que a moderação reprova por engano.
O critério, não só as peças
O acervo responde "o que eu já tenho pra isso". Não responde "isso deveria
existir assim". references/fundamentos-visuais.md
cobre o segundo — o vocabulário que decide antes da peça e julga depois dela:
- as perguntas que substituem "está bonito?" — o que isso quer que eu sinta, que eu faça, e que decisões me levaram lá
- os cinco níveis — estética, organização, comunicação, persuasão, memória — e o teto de cada um
- seis níveis de movimento, nove tipos de contraste, cinco usos da cor, psicologia de forma
- seis técnicas de geração de conceito, para quando o briefing está pobre
- sete testes executáveis, todos de minutos e sem ferramenta
Os testes são a parte que mais rende, e estão ligados como passo 7.9 da
kit-montar: o passo 8 registra o que quebrou; o 7.9 pega o que não quebra e
mesmo assim falha. O melhor deles inverte o instinto — cubra a mensagem
principal, veja o que sobrou roubando atenção, e reduza antes de apagar.
Comandos
python scripts/perfil.py # o retrato de agora
python scripts/buscar.py "landing de clínica odontológica"
python scripts/buscar.py --setor joias --estrutura scroll-cinematica
python scripts/buscar.py --listar setor
python scripts/ingerir.py <arquivo> --analisar # peça avulsa
python scripts/ingerir_projeto.py <pasta> --analisar # projeto inteiro
python scripts/ingerir_design.py <arquivo> --analisar # design system
python scripts/ingerir_registro.py --url <url>.json # componente de registro shadcn
python scripts/ingerir_mcp.py --catalogo <c>.json # catálogo servido por MCP
python scripts/lote.py <lote>.json --simular # muitos projetos de uma vez
python scripts/receita.py criar <slug> --pecas a,b,c # salvar uma composição
python scripts/capturar.py --tudo # preview das peças que rodam sozinhas
python scripts/capturar.py --url <url> --viewport 390x844 --saida <png>
python scripts/painel.py --abrir # o acervo com miniatura
python scripts/curar.py # saúde do acervo
python scripts/curar.py --assets # testa as URLs externas
python scripts/curar.py --autoteste # checa o detector de import
python scripts/publicar.py --autoteste # checa a rede anti-vazamento
python scripts/indexar.py # SEMPRE depois de ingerir ou editar ficha
indexar.py no fim não é opcional: os scripts gravam no disco, mas a busca lê
acervo/index.json. Sem reindexar, nada muda.
O preview — o acervo deixou de ser só texto
Peça que roda sozinha ganha preview.png ao lado da ficha: família html, e
animacao/template com um index.html dentro.
python scripts/capturar.py --tudo && python scripts/indexar.py
python scripts/painel.py --abrir
Usa o Chrome que já está na máquina, em headless — sem Playwright, sem dependência
nova. Aponte outro binário com CANNONBALL_CHROME.
A captura é julgada antes de ser gravada. Um PNG válido não prova nada: canvas WebGL que não inicializou, página que não carregou e loader que nunca saiu produzem imagem perfeita e inútil. O script mede variação de cor e brilho, e recusa com o motivo escrito. Recusa é informação, não erro.
Componente React solto fica de fora: precisaria de build. São 159 peças capturáveis hoje, e as 130 animações são justamente onde "como é que isso fica?" mais dói.
O mesmo script serve à revisão do passo 7.9 da /kit-montar, apontado para a página
que você acabou de construir:
python scripts/capturar.py --url http://localhost:3000 --viewport 1440x900 --saida /tmp/d.png
python scripts/capturar.py --url http://localhost:3000 --viewport 390x844 --saida /tmp/m.png
Assets pesados ficam fora
Template e animação guardam só o código. Imagem, vídeo e fonte continuam no
projeto original — o campo projeto_origem diz onde, e curar.py verifica se o
caminho ainda existe. Num template típico 99% do peso é mídia, que não cabe no git e
é trocada por material do cliente de qualquer forma.
Se a pasta de material mudar de lugar:
python scripts/relocalizar.py --verificar
python scripts/relocalizar.py --assets-de "<raiz antiga>" --assets-para "<raiz nova>"
python scripts/indexar.py
Depois de editar scripts ou skills
O plugin instalado é uma cópia. Force a atualização:
claude plugin marketplace update cannonball
claude plugin uninstall cannonball@cannonball && claude plugin install cannonball@cannonball
Coisas que mordem
- A extensão mente. Arquivo
.mdcontendo TSX puro é comum. A classificação é sempre por conteúdo, nunca por extensão. @/lib/utils(a funçãocn) não é pacote npm, é arquivo que precisa existir no projeto. Quase todo componente de origem shadcn importa isso.- Componente de registro puxa outros. A busca imprime
PRECISA JUNTO:— colar sem a base quebra o import, e o erro não diz que falta uma peça, diz que falta um módulo. motioneframer-motionsão a mesma lib com nomes diferentes. Misturar instala duas vezes. Padronize emmotion, que é o sucessor.- Componente autorado em Framer convertido para Next.js deixa resíduo (shim
RenderTarget, JSDoc@framer*,props: any) e exige Tailwind v4. - A peça sai do acervo por cópia, e import relativo não sabe disso. Escrito para
o layout do acervo, ele quebra no destino com
Module not found— que parece falta de pacote npm e não falta de peça.curar.pytem uma seção só para isso e, quando o alvo já está no acervo com outro id, imprime o de-para. - Asset em bucket temporário morre.
curar.py --assetstesta de verdade; a busca avisaASSET MORTOna hora da escolha, não na entrega. - Fonte de
db.onlinewebfonts.comé redistribuição de fonte comercial. Verifique a licença antes de entregar a cliente.
Publicar sua própria versão
O acervo é seu e não deve ir junto num repositório público — peça de terceiro, projeto de cliente e prompt comprado não são seus para redistribuir.
python scripts/publicar.py --para ../cannonball-publico --listar
python scripts/publicar.py --para ../cannonball-publico
Exporta o motor (scripts, skills, referências) e o seed/ das três peças de exemplo,
e recusa a exportação se qualquer material privado escapar para o destino.
O que fica de fora: acervo/, _fonte/ e todo artefato de importação em massa.
Histórico
O que mudou em cada versão, e por quê: CHANGELOG.md.
Créditos
A disciplina de ficha da /kit-ingerir — mecanismo numa frase, três pilhas, regra
ancorada na falha que evita, números em vez de adjetivos — vem do
web-technique-to-skill do Meng To (MIT),
traduzida para o vocabulário do acervo. O repo dele é a metade oposta deste: acervo
curado de técnica de web design, sem motor de busca.
O §15 da /kit-otimizar-3d — depurar shader extraindo os valores internos como
pixel, em vez de mexer na constante até a imagem melhorar — vem do
shader-debugging do vgpu da
vercel-labs (MIT). O vgpu é WebGPU/WGSL e não é dependência daqui: o que foi
trazido é o método, reescrito para WebGL2/GLSL, mais a correção que ele traz sobre
captura headless no Linux.
Licença
MIT — ver LICENSE. A licença cobre o motor. O que você guardar no acervo continua sob a licença de origem de cada peça.
// faq
What is cannonball?
Você não começa do zero — chega com impulso. Guarda as peças de site que você já fez e as encontra de volta antes de gerar qualquer coisa outra vez. Agent Skills para Claude Code, Codex, Gemini CLI e Cursor.. It is open-source on GitHub.
Is cannonball free to use?
cannonball is open-source under the MIT license, so it is free to use.
What category does cannonball belong to?
cannonball is listed under plugins in the Claudeers registry of Claude-compatible tools.
// embed badge
[](https://claudeers.com/cannonball)
// retro hit counter
[](https://claudeers.com/cannonball)
// reviews
// guestbook
// related in Claude Plugins
A single CLAUDE.md file to improve Claude Code behavior, derived from Andrej Karpathy's observations on LLM coding pitfalls.
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explainin…
"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/
financial-services — a Claude ecosystem project on GitHub.
