EugineKosenko/majordom

Gera um novo componente/comando/crate no estilo Rust literato org-babel deste usuário (modelado nos padrões crates/api e crates/cli do ads-back — um arquivo org por comando com um bloco esqueleto :tangle, blocos noweb Декларації antes de Визначення/Дії, um título por conceito). Use sempre que o usuário pedir para adicionar um novo componente, comando, procedimento, subcomando CLI, componente Yew, módulo ou crate em um projeto Rust literato org-babel (ads-back, ads-front ou similar), incluindo a integração de um novo crate com seus config.org/env.org/main.org no config.org federado do workspace.

O que é majordom?

Esta skill automatiza a criação de novos componentes em projetos Rust literatos que utilizam o estilo org-babel, como ads-back e ads-front. Ela identifica o tipo de componente desejado (procedimento em crate existente, subcomando CLI, componente Yew ou um novo crate federado) e gera a estrutura de arquivos org com blocos noweb seguindo a convenção de declarações antes de definições/ações, com um título por conceito. A skill é útil para manter a consistência do código-fonte literato, reduzir erros de sintaxe e acelerar o desenvolvimento, garantindo que cada novo componente siga o padrão documentado. Ela também lida automaticamente com a criação de config.org, env.org e main.org para novos crates, registrando-os no config.org raiz do workspace, e realiza verificações de tangled real, cargo check e org-lint após cada alteração significativa.

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

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

create-cmpnnt

Habilidade para criar um novo componente (cmpnnt) — comando, procedimento, subcomando, Yew-componente ou um crate inteiro — no estilo literato org-babel, documentado em ~/.claude/CLAUDE.md. Baseia-se nos arquivos reais de code/ads-back (crates/api/create-card.org, crates/api/retrve-card.org, crates/cli/main.org, crates/svc/main.org, raiz config.org, env.org).

Passo 0 — determinação da variante

Por padrão (sem argumentos explícitos), determine a variante a partir da própria solicitação do usuário; se ambíguo — faça uma pergunta esclarecedora via AskUserQuestion, não adivinhe silenciosamente:

  • A. Procedimento/comando em crate existente — caso típico (ex.: novo rocket-handler em crates/api, nova função de biblioteca em crates/db). Um novo arquivo org, sem alterações em config.org.
  • B. Subcomando de CLI existente — novo arquivo <subcomando>.org (mod) + inserção no main.org existente desse crate (mod, Command:Elementos, Variantes).
  • C. Yew-componente (ads-front) — estrutura mais próxima de crates/app/marker.org: seção "Propriedades" com as propriedades do componente, blocos Html. Mesmo esqueleto (Declarações antes de Definições, um título por conceito), terminologia de blocos diferente.
  • D. Novo crate ("cargo federado") — quando o componente logicamente não cabe em nenhum crate existente. Então, além do próprio componente, são necessários config.org, env.org, main.org do novo crate e registro no config.org raiz (veja Passo 4).

Não atribua a variante D "por precaução" — apenas quando o usuário explicitamente solicitar um novo crate, ou quando nenhum crate existente for logicamente adequado (e isso for confirmado pelo usuário).

Passo 1 — idioma do arquivo org

O idioma depende da situação, não é fixo de antemão. Antes de criar o arquivo, verifique o idioma dos arquivos org vizinhos no diretório de destino (code/ads-back/env.org — inglês, a maioria de crates/api/*.org — ucraniano): se o diretório tiver uma maioria clara — escreva no mesmo idioma; se for um novo diretório ou o idioma dos vizinhos for ambíguo — pergunte ao usuário com uma única pergunta, não adivinhe.

Passo 2 — esqueleto comum (todas as variantes)

Independentemente da variante, cada novo arquivo org com seu próprio alvo :tangle:

  1. #+title: ... — nome do componente (no idioma do passo 1).

  2. Se necessário — parágrafo com referência à especificação ([[https://...][especificação]]), como em create-card.org.

  3. Primeiro título (* Módulo / * Arquivo / * Crate — nome conforme exemplo dos arquivos vizinhos no mesmo diretório, não é estritamente fixo) com bloco esqueleto:

    #+begin_src rust :noweb yes :mkdirp yes :tangle src/NOME_DO_ARQUIVO.rs
      <<Declarações>>
    
      <<Definições>>
    #+end_src
    
  4. Imediatamente após o esqueleto — seção * Executor (para procedimento/comando) com dois blocos: :noweb-ref Declarações (imports, incluindo tipos Request/Response de ads_api) e :noweb-ref Definições (a própria função pub fn run(...), cujo corpo é principalmente <<Ações>> dentro de db::cnnctn().transaction(...), se for necessária uma transação).

  5. Cada detalhe seguinte da lógica (verificação, obtenção de campo, inserção em tabela, etc.) — um título */** separado com seus próprios :noweb-ref Declarações (se forem necessários novos use) e :noweb-ref Ações — nessa ordem (declaração antes do uso, como em todo lugar). Não agrupe toda a lógica em um único bloco — cada passo significativo deve ter seu próprio título, como em create-card.org (lá são 15+ títulos separados para um único procedimento).

  6. Se um passo gerar uma função auxiliar (ex.: upsert_phone em create-card.org) — próprio :noweb-ref Definições para a assinatura da função, e o corpo — através de um noweb-ref nomeado próprio (upsert-phone:Ações), e subtítulos **/*** para cada ação dentro dela.

A variante B (subcomando CLI) difere por não ter um novo bloco esqueleto — em vez disso, adicione no main.org existente três blocos noweb sem um novo título-esqueleto: :noweb-ref Declarações (mod novo_subcomando;), :noweb-sep ",\n" :noweb-ref Command:Elementos (variante do enum Command com campos-argumentos), e :noweb yes :noweb-sep ",\n" :noweb-ref Variantes (Command::Variante { ... } => crate::módulo::run(...)) — cada um em seu título *, nomeado pela ação (ex.: * Criação de organização), e a implementação em si — em um novo arquivo org separado do subcomando conforme o esqueleto comum (passo 2, variante A).

A variante C (Yew-componente) difere pelos nomes das seções: em vez de "Executor" — seção "Propriedades" (struct ...Props, uma propriedade = um subseção **, :noweb-sep ",\n" :noweb-ref NomeProps:Propriedades), e seção "Componente" (#[function_component(...)], corpo — <<Nome:Estado>>, <<Nome:Efeitos>>, <<Nome:Manipuladores>>, html! { <<Nome:Html>> }). Veja code/ads-front/crates/app/marker.org como exemplo vivo desta variante.

Passo 3 — função main típica (variante D, inicialmente)

A primeira versão de main.org de um novo crate deve ser a mais simples possível — sem tratamento de erros, sem Result, sem async, sem inicialização de logger/env, a menos que haja uma necessidade específica:

#+title: NOME DO CRATE

* Arquivo

#+begin_src rust :noweb yes :mkdirp yes :tangle src/main.rs
  <<Declarações>>

  <<Definições>>

  fn main() {
      <<Ações>>
  }
#+end_src

<<Ações>> pode inicialmente estar completamente vazio (o novo crate ainda não faz nada) — este é um primeiro passo normal, os títulos seguintes gradualmente o preenchem, como em crates/cli/main.org/crates/svc/main.org. Tratamento de erros (Result, ?), async, inicialização de dotenv/env_logger, etc., adicione em títulos separados mais tarde, quando um passo específico realmente exigir — não antecipadamente.

Passo 4 — novo crate: config.org e registro no config.org federado

  1. crates/NOME/config.org — arquivo do crate (veja crates/cli/config.org como exemplo):

    #+title: =Cargo=-arquivo
    
    * Arquivo
    
    #+begin_src toml :noweb yes :tangle Cargo.toml
      [package]
      name = "NOME"
      version = "0.1.0"
      edition = "2021"
    
      [dependencies]
      <<Dependências>>
    #+end_src
    

    Cada dependência — um título * =nome_do_crate= separado com :noweb-ref Dependências (nome = { workspace = true }), ordenado conforme regra de CLAUDE.md (terceiros → forge → crates do projeto, caso contrário — alfabético). Blocos * Versão =Rust=/* Configuração local (rust-toolchain.toml/.cargo/config.toml) copie do config.org vizinho apenas se no diretório já for prática — não os adicione "por precaução", se nenhum crate vizinho fizer isso. Se copiar — o arquivo se torna multi-target (vários :tangle diferentes), então todos os blocos noweb (incluindo Dependências) passam a usar nomes prefixados (Cargo:Dependências, config:Definições etc., veja CLAUDE.md) — como no config.org raiz abaixo.

  2. No config.org RAIZ (workspace), adicione um novo título * =NOME= com dois blocos — conforme o modelo das seções * =db=/* =api= na raiz:

    #+begin_src toml :noweb-sep ",\n" :noweb-ref Cargo:Crates
      "crates/NOME"
    #+end_src
    
    #+begin_src toml :noweb-ref Cargo:Dependências
      NOME = { path = "crates/NOME" }
    #+end_src
    
  3. env.org — se o novo crate não introduzir variáveis de ambiente próprias, não mexa em nada. Se introduzir — e o projeto já tiver um env.org raiz compartilhado — adicione lá uma nova seção * com próprio :noweb-ref (como * Database access/* =JWT= parameters), e não crie um arquivo separado. Crie um env.org SEPARADO para o novo crate apenas quando ele for um deploy independente (próprio .env, não o mesmo processo) e não houver nenhum env.org compartilhado. Em qualquer caso, o primeiro env.org pode ficar completamente sem variáveis específicas (pode ficar sem valores, apenas o arquivo principal) — apenas um esqueleto:

    #+title: =dotenv= file
    
    * Configuration file
    
    #+begin_src conf :noweb yes :tangle .env.example
      <<Definições>>
    #+end_src
    

    e preenchê-lo com seções * =X= parameters específicas mais tarde, quando surgirem variáveis reais.

Passo 5 — verificação após cada alteração

Após cada edição significativa da fonte org:

  1. Tangle real via emacsclient --eval (nunca escreva o conteúdo de .rs/.toml/.env.example manualmente — veja a regra global correspondente).
  2. cargo check -p CRATE (adicione --target wasm32-unknown-unknown para ads-front) — zero avisos e erros.
  3. Execute a habilidade org-lint no arquivo alterado e corrija imediatamente os achados "CERTOS", os "requer verificação" — revise.
  4. Para prosa recém-escrita/alterada — (font-lock-ensure) + org-fill-paragraph através do mesmo emacsclient, não manualmente.

Não mostre o componente ao usuário como pronto até que esses quatro pontos sejam concluídos para cada arquivo org novo ou alterado.

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

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).

EugineKosenko/majordom

Check org/md prose in this user's projects against the prose-formatting conventions in ~/.claude/rules/org-babel.md (~...~ vs =...= markup, acronym casing, /.../ glossary terms, real org-links vs italics/plain text, spaces around / between two markups, trailing newline, fill-column). Use proactively right after editing prose paragraphs in an .org or .md file (in place of manually re-deriving each rule from memory), and whenever the user explicitly asks to check/lint org rules or compares the request to running clippy.

Habilidades Relacionadas