EugineKosenko/majordom

Verifica a prosa dos projetos deste usuário contra as convenções de formatação de prosa em ~/.claude/rules/org-babel.md (marcação ~...~ vs =...=, maiúsculas/minúsculas em acrônimos, termos de glossário /.../, links org reais vs itálico/texto simples, espaços ao redor/entre duas marcações, nova linha final, coluna de preenchimento). Use proativamente logo após editar parágrafos de prosa em um arquivo .org ou .md (no lugar de derivar manualmente cada regra da memória) e sempre que o usuário pedir explicitamente para verificar/inspecionar regras org ou comparar a solicitação com a execução do clippy.

O que é majordom?

Esta skill (majordom) atua como um linter para regras de formatação de prosa em arquivos `.org` e `.md`, com base nas convenções documentadas em `~/.claude/rules/org-babel.md`. O objetivo principal é automatizar a verificação de regras de formatação — como uso correto de marcações `~...~` (para identificadores de código) vs `=...=` (para acrônimos/nomes públicos), espaçamento adequado entre marcações, capitalização de acrônimos, uso de links org reais em vez de itálico/texto simples, e consistência de termos de glossário — evitando que o usuário precise lembrar e aplicar manualmente cada regra após editar texto. A skill é acionada proativamente imediatamente após a edição de parágrafos de prosa em arquivos `.org` ou `.md`, ou sob demanda quando o usuário solicita explicitamente uma verificação (ex: "verifique regras org", "execute lint", ou compara com `clippy`). Ela suporta ambientes onde Emacs está disponível, usando `emacsclient --eval` para executar `fill-paragraph` com font-lock ativado (para garantir que links org sejam exibidos corretamente antes do preenchimento). O processo é dividido em três etapas: (1) verificação mecânica via script Python que aplica expressões regulares para detectar violações definitivas e prováveis, (2) checklist manual para itens que o script não captura (como tipo de marcação para identificadores de código vs acrônimos, links para seções/arquivos, e uso de itálico apenas para termos de glossário), e (3) alinhamento automático de parágrafos via `fill-paragraph` do Emacs, garantindo que o texto se encaixe no limite de 105 caracteres por linha. A skill é particularmente útil para projetos com múltiplos arquivos org que compartilham regras de formatação complexas, como aqueles que usam noweb tangling, referências cruzadas entre repositórios e glossários de projeto.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/EugineKosenko/majordom/tree/HEAD/skills/org-lint

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

org-lint

Linter para regras de formatação de prosa em arquivos org/md, documentadas em ~/.claude/rules/org-babel.md. O objetivo é não depender sempre da memória manual para cada regra (e do risco: corrigir a recém-mencionada e esquecer as demais), mas sim processar o texto através de uma lista explícita.

Quando aplicar

  • Imediatamente após editar ou escrever um novo parágrafo de prosa em um arquivo .org/.md (em vez de verificar manualmente cada regra de memória) — antes de mostrar o resultado ao usuário.
  • Mediante solicitação explícita do usuário ("verifique regras org", "execute lint", comparação com clippy, etc.).
  • Não se aplica ao conteúdo de blocos #+begin_src/#+begin_example (código) — apenas a parágrafos de prosa e títulos.

Passo 1 — verificação mecânica

Execute o script no(s) arquivo(s) que foram editados:

python3 ~/.claude/skills/org-lint/scripts/lint.py CAMINHO/DO/ARQUIVO.org

O script captura via regex:

  • / sem espaços ao redor de ~...~/=...= (~a~/~b~ em vez de ~a~ / ~b~) — VIOLAÇÃO DEFINITIVA.
  • [[file:../ — link relativo ao diretório atual em vez da abreviatura root: — VIOLAÇÃO DEFINITIVA.
  • ausência de newline final no arquivo — VIOLAÇÃO DEFINITIVA.
  • acrônimo em maiúsculas dentro de =...= (ex.: =CSS=) — requer confirmação (exceções raras são permitidas).
  • itálico /Palavra/ — requer verificação: é realmente um termo do glossário do projeto (existe seção em spcfctn/glossary.org? há link para ele na primeira menção neste arquivo?), ou é um link para seção/arquivo INCORRETAMENTE NÃO convertido (deveria ser [[*Seção][...]]).
  • menção de arquivo como =caminho/arquivo.org= — requer verificação: não deveria ser um link real [[file:...]].
  • palavra "parâmetro"/"parâmetros"/... — requer verificação: se refere a propriedades de componente Rust/Yew (struct ...Props), a tradução correta é "propriedades"/"propriedade", não "parâmetros"/"parâmetro" (termo obsoleto). Fora de componentes Yew (parâmetros de função, CLI, procedimentos REST, etc.) "parâmetro" — OK, não altere.
  • bloco :noweb-ref Definição está em uma seção antes do bloco :noweb-ref Declarações — requer verificação: a declaração deve vir primeiro, na ordem de leitura do arquivo de cima para baixo (veja org-babel.md).
  • vários blocos #+begin_src com o MESMO :tangle CAMINHO e sem nenhum :noweb yes/<<...>> no arquivo — VIOLAÇÃO DEFINITIVA (concatenação obsoleta, como no antigo gitignore.org — veja org-babel.md). Refatore para um único bloco container :tangle+:noweb yes com placeholder(s) <<Nome>> e seções com :noweb-ref Nome.
  • o arquivo é tangado em VÁRIOS arquivos de destino diferentes, dos quais PELO MENOS DOIS consomem noweb (têm :noweb yes em um #+begin_src esqueleto, ex.: config.org → .env.example + parameters.php), mas pelo menos um bloco :noweb-ref/<<...>> é nomeado sem prefixo de destino (Nome em vez de env:Nome) — VIOLAÇÃO DEFINITIVA (veja org-babel.md, regra sobre prefixos em arquivos org multi-alvo). Para arquivos com UM único arquivo de destino, e também para arquivos onde apenas UM destino consome noweb e os demais são destinos :tangle autossuficientes de bloco único sem <<...>> (ex.: gitignore.org: 5 destinos :tangle, mas apenas o .gitignore raiz — via esqueleto noweb) — prefixo não é necessário, pois não há ambiguidade real.
  • parâmetros no cabeçalho #+begin_src estão em ordem incorreta — VIOLAÇÃO DEFINITIVA. Ordem correta: tipo do bloco → :noweb yes → :noweb-sep "..." → demais parâmetros → :tangle CAMINHO ou :noweb-ref Nome (no final, veja org-babel.md).
  • o arquivo se chama cargo.org — VIOLAÇÃO DEFINITIVA (nome obsoleto para projetos Rust; renomeie para config.org, veja org-babel.md).
  • :tangle usa caminho absoluto (/..., ~/...) ou ascendente .. — VIOLAÇÃO DEFINITIVA (veja org-babel.md); o destino deve ser estritamente um caminho relativo descendente a partir do arquivo org. Se o destino estiver realmente fora da árvore de origem — é necessário um symlink ou outra estrutura de diretórios, não ../caminho absoluto (episódio: farba-override → farba-theme via ../farba-theme/..., tarefa FS-1085).
  • maiúsculas fora de =...= (ex.: NÃO, APENAS) — requer verificação: se for destaque de palavra, e não acrônimo/abreviatura, substitua por negrito org (*não*), não por CAIXA ALTA.
  • palavra "hook"/"gancho" (tradução de "hook", React/Yew) — obsoleto; a tradução correta é "gancho" (aplica-se apenas à prosa, não a identificadores de código como use_effect_with).
  • linhas de prosa com mais de 105 caracteres — requer fill-paragraph via emacsclient (veja abaixo).

"VIOLAÇÕES DEFINITIVAS" sempre devem ser corrigidas. "Requer verificação manual" — revise cada uma, mas nem todas são erros (ex.: =rest=/=forge-yew= — legítimas abreviaturas/nomes de crate, não violação).

Passo 2 — checklist manual (o que o script não captura)

  • Identificadores de código/tipos/funções/variáveis/módulos — e quaisquer fragmentos ou expressões de código (ex.: id=1, value == 0, items()) — til ~...~. Abreviaturas/acrônimos e a forma "pública" do nome de crate/biblioteca (com hífen) — sinal de igual =...=. Caminho qualificado crate::Tipo — é um nome de tipo do código, portanto inteiramente em til, mesmo com prefixo de crate.
  • Abreviaturas/acrônimos — em minúsculas dentro da frase, apenas a primeira letra maiúscula no início da frase (sem CAIXA ALTA completa), exceto para raras exceções consolidadas.
  • Link para seção no mesmo arquivo — [[*Nome do título][Nome]], não itálico e nem texto simples. Link para arquivo no mesmo diretório — simplesmente [[file:arquivo-vizinho.org][descrição]]; para arquivo em outro diretório (especialmente em outro repositório git dentro do diretório de trabalho comum) — via abreviatura root: ([[root:code/ads-back/arquivo.org::N][descrição]]), não ../../../ relativo ao diretório atual. A abreviatura é declarada em .dir-locals.el na raiz do diretório de trabalho (forma eval com locate-dominating-file) — se ainda não existir no projeto, crie.
  • Itálico /.../ — apenas para termos do glossário do projeto (com tradução (/translation/) imediatamente após); na primeira menção do termo em cada arquivo — [[file:.../spcfctn/glossary.org::*Termo][...]] para a seção correspondente, e não repetição da definição.

Passo 3 — alinhamento

Para cada parágrafo editado, chame o fill-paragraph real via emacsclient --eval, em vez de alinhar manualmente (veja a regra correspondente em org-babel.md). Escreva o texto do parágrafo em new_string/ao criar o arquivo em uma única linha, sem tentar adivinhar quebras de linha, — pois isso será integralmente determinado pelo fill-paragraph.

É OBRIGATÓRIO chamar (font-lock-ensure) ANTES de org-fill-paragraph: o buffer aberto headless via find-file-noselect não passa por fontificação, portanto links org [[caminho][descrição]] ainda não estão "dobrados" para o texto visível curto descrição — sem font-lock-ensure o fill-paragraph contará a quebra de linha pelo longo texto bruto do link, e não pela sua largura visível, e o resultado divergirá do que M-q fornece em um Emacs interativo. Exemplo:

emacsclient --eval '
(let ((buf (find-file-noselect "CAMINHO/DO/ARQUIVO.org")))
  (with-current-buffer buf
    (org-mode)
    (font-lock-ensure)
    (goto-char (point-min))
    (search-forward "fragmento único do parágrafo")
    (org-fill-paragraph)
    (save-buffer)))
'

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

EugineKosenko/majordom

Analyse a Figma .fig file kept in a project's spcfctn/ui/draft. Unpacks and decodes it offline (kiwi), breaks it into sections, screens, text rows and rasters, writes the analysis to spcfctn/ui/*.md, then fetches the author's comments through the figma MCP by link, binds them to screens by geometry, checks that the comments agree with the content of the file and asks the user to clarify what does not. Use when the user asks to analyse, decode or re-read a .fig file or Figma wireframes, or to refresh spcfctn/ui after a new export.

EugineKosenko/majordom

Керування сесіями claude-code-ide.el у живому Emacs через emacsclient headless — старт/continue/resume без блокуючих запитів, безпечна зупинка, перемикання permission-mode і auto-accept, навігація в інтерактивних picker'ах. Використовуй, коли сесія "Мажордом" має підняти, продовжити, зупинити чи інспектувати сесію claude-code-ide для іншого проєкту.

EugineKosenko/majordom

Scaffold a new component/command/crate in this user's literate org-babel Rust style (modeled on ads-back's crates/api and crates/cli patterns — one org file per command with a :tangle skeleton block, Декларації-before-Визначення/Дії noweb blocks, one heading per concern). Use whenever the user asks to add a new component, command, procedure, CLI subcommand, Yew component, module, or crate in an org-babel-literate Rust project (ads-back, ads-front, or similar), including wiring a brand-new crate's config.org/env.org/main.org into the workspace's federated config.org.

EugineKosenko/majordom

Bootstrap a new project in this user's standard layout — .claude-root, .dir-locals.el (root: org-link abbreviation), code/, spcfctn/code/ (with its own git repository) and a .claude/ directory with its own git repository and a CLAUDE.md that fixes the project's prose language and its short two-letter project code (chosen by the user from options the agent proposes) — and translate any files already present into that language. Use whenever the user asks to create, start, set up, initialise or "оформити" a new project (or to bring an existing bare directory to the standard layout).

Habilidades Relacionadas