CommunityProgramación y desarrollogithub.com

EugineKosenko/majordom

Andamia un nuevo componente/comando/crate en el estilo literario org-babel Rust (modelado en los patrones crates/api y crates/cli de ads-back: un archivo org por comando con un bloque esqueleto :tangle, bloques noweb Declaraciones-antes-Definiciones/Acciones, un encabezado por asunto). Úsalo cuando el usuario pida añadir un nuevo componente, comando, procedimiento, subcomando CLI, componente Yew, módulo o crate en un proyecto Rust literario org-babel (ads-back, ads-front o similar), incluyendo cablear el config.org/env.org/main.org de un crate nuevo en el config.org federado del workspace.

¿Qué es majordom?

Esta habilidad (skill) para agentes de IA como Claude Code, Cursor o Codex automatiza la creación de nuevos componentes en proyectos Rust que siguen un estilo literario con org-babel, típicamente en repositorios como ads-back o ads-front. El agente puede generar desde una simple función dentro de un crate existente hasta un crate completamente nuevo, incluyendo su configuración federada. Soporta cuatro variantes principales: A) procedimiento/comando en crate existente, B) subcomando CLI, C) componente Yew (frontend), y D) crate nuevo. La habilidad se basa en los patrones de archivos org reales del proyecto (como create-card.org, main.org, config.org) y asegura que cada nuevo componente siga la estructura de un encabezado por concepto, bloques noweb de declaraciones antes de definiciones, y un esqueleto :tangle que vincula el código Rust. Además, incluye pasos para verificar el resultado mediante tangled real con emacsclient, cargo check y org-lint, garantizando cero errores y advertencias.

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

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

create-cmpnnt

Habilidad para crear un nuevo componente (cmpnnt) — comando, procedimiento, subcomando, Yew-componente o crate completo — en el estilo literario org-babel, documentado en ~/.claude/CLAUDE.md. Se basa en los archivos reales de code/ads-back (crates/api/create-card.org, crates/api/retrve-card.org, crates/cli/main.org, crates/svc/main.org, el config.org raíz, env.org).

Paso 0 — determinar la variante

Por defecto (sin argumentos explícitos), determina la variante a partir de la propia solicitud del usuario; si es ambiguo, pregunta mediante AskUserQuestion, no adivines en silencio:

  • A. Procedimiento/comando en crate existente — caso típico (ej. nuevo manejador rocket en crates/api, nueva función de biblioteca en crates/db). Un nuevo archivo org, sin cambios en config.org.
  • B. Subcomando de CLI existente — nuevo archivo <subcomando>.org (mod) + inserción en el main.org existente de ese crate (mod, Command:Elementos, Variantes).
  • C. Componente Yew (ads-front) — estructura similar a crates/app/marker.org: sección "Propiedades" con las propiedades del componente, bloques Html. Mismo esqueleto (Declaraciones antes de Definiciones, un encabezado por concepto), diferente terminología de bloques.
  • D. Nuevo crate ("cargo federativo") — cuando el componente lógicamente no cabe en ningún crate existente. Entonces, además del propio componente, se necesitan config.org, env.org, main.org del nuevo crate y el registro en el config.org raíz (ver Paso 4).

No asignes la variante D "por si acaso" — solo cuando el usuario pida explícitamente un nuevo crate, o cuando ningún crate existente sea lógicamente adecuado (y esto sea confirmado por el usuario).

Paso 1 — idioma del archivo org

El idioma depende de la situación, no está fijado de antemano. Antes de crear el archivo, revisa el idioma de los archivos org vecinos en el directorio destino (code/ads-back/env.org — en inglés, la mayoría de crates/api/*.org — en ucraniano): si el directorio tiene una mayoría clara, escribe en ese mismo idioma; si es un directorio nuevo o el idioma de los vecinos es ambiguo, pregunta al usuario con una sola pregunta, no adivines.

Paso 2 — esqueleto común (todas las variantes)

Independientemente de la variante, cada nuevo archivo org con su propio destino :tangle:

  1. #+title: ... — nombre del componente (en el idioma del paso 1).

  2. Si es necesario, un párrafo con enlace a la especificación ([[https://...][especificación]]), como en create-card.org.

  3. Primer encabezado (* Módulo / * Archivo / * Crate — nombre según el ejemplo de los archivos vecinos del mismo directorio, no está estrictamente fijo) con un bloque esqueleto:

    #+begin_src rust :noweb yes :mkdirp yes :tangle src/NOMBRE_ARCHIVO.rs
      <<Declaraciones>>
    
      <<Definiciones>>
    #+end_src
    
  4. Inmediatamente después del esqueleto — sección * Ejecutor (para procedimiento/comando) con dos bloques: :noweb-ref Declaraciones (imports, incluyendo los tipos Request/Response de ads_api) y :noweb-ref Definiciones (la función pub fn run(...), cuyo cuerpo es principalmente <<Acciones>> dentro de db::cnnctn().transaction(...), si se necesita una transacción).

  5. Cada detalle lógico siguiente (verificación, obtención de campo, inserción en tabla, etc.) — encabezado */** separado con sus propios :noweb-ref Declaraciones (si se necesitan nuevos use) y :noweb-ref Acciones — en ese orden (declaración antes del uso, como en todas partes). No juntes toda la lógica en un solo bloque — cada paso significativo debe tener su propio encabezado, como en create-card.org (allí hay 15+ encabezados separados para un solo procedimiento).

  6. Si un paso genera una función auxiliar (ej. upsert_phone en create-card.org) — un :noweb-ref Definiciones propio para la firma de la función, y el cuerpo a través de su propio noweb-ref nombrado (upsert-phone:Acciones), y subencabezados **/*** para cada acción dentro de ella.

La variante B (subcomando CLI) difiere en que no habrá un nuevo bloque esqueleto — en su lugar, añade en el main.org existente tres bloques noweb sin un nuevo encabezado-esqueleto: :noweb-ref Declaraciones (mod nuevo_subcomando;), :noweb-sep ",\n" :noweb-ref Command:Elementos (variante del enum Command con campos de argumentos), y :noweb yes :noweb-sep ",\n" :noweb-ref Variantes (Command::Variante { ... } => crate::módulo::run(...)) — cada uno en su propio encabezado *, nombrado con la acción (ej. * Creación de organización), y la implementación en sí en un nuevo archivo org del subcomando según el esqueleto común (paso 2, variante A).

La variante C (componente Yew) difiere en los nombres de las secciones: en lugar de "Ejecutor" — sección "Propiedades" (struct ...Props, una propiedad = un subapartado **, :noweb-sep ",\n" :noweb-ref NombreProps:Propiedades), y sección "Componente" (#[function_component(...)], cuerpo — <<Nombre:Estado>>, <<Nombre:Efectos>>, <<Nombre:Manejadores>>, html! { <<Nombre:Html>> }). Mira code/ads-front/crates/app/marker.org como ejemplo vivo de esta variante.

Paso 3 — función main típica (variante D, inicialmente)

La primera versión de main.org de un nuevo crate debe ser lo más simple posible — sin manejo de errores, sin Result, sin async, sin inicialización de logger/env, a menos que haya una necesidad concreta:

#+title: NOMBRE DEL CRATE

* Archivo

#+begin_src rust :noweb yes :mkdirp yes :tangle src/main.rs
  <<Declaraciones>>

  <<Definiciones>>

  fn main() {
      <<Acciones>>
  }
#+end_src

<<Acciones>> al principio puede estar completamente vacío (el nuevo crate aún no hace nada) — este es un primer paso normal; los siguientes encabezados lo llenan gradualmente, como en crates/cli/main.org/crates/svc/main.org. El manejo de errores (Result, ?), async, inicialización de dotenv/env_logger, etc., se añaden en encabezados separados más tarde, cuando un paso concreto realmente lo requiera — no por adelantado.

Paso 4 — nuevo crate: config.org y registro en el config.org federativo

  1. crates/NOMBRE/config.org — archivo del crate (ver crates/cli/config.org como ejemplo):

    #+title: =Cargo=-archivo
    
    * Archivo
    
    #+begin_src toml :noweb yes :tangle Cargo.toml
      [package]
      name = "NOMBRE"
      version = "0.1.0"
      edition = "2021"
    
      [dependencies]
      <<Dependencias>>
    #+end_src
    

    Cada dependencia — un encabezado * =nombre_crate= separado con :noweb-ref Dependencias (nombre = { workspace = true }), ordenado según la regla de CLAUDE.md (terceros → forge → crates del proyecto, de lo contrario alfabético). Los bloques * Versión =Rust=/* Configuración local (rust-toolchain.toml/.cargo/config.toml) se copian del config.org vecino solo si es una práctica común en ese directorio — no los añadas "por si acaso" si ningún crate vecino lo hace. Si copias, el archivo se vuelve multi-destino (varios :tangle diferentes), por lo que todos los bloques noweb (incluyendo Dependencias) pasan a usar nombres con prefijo (Cargo:Dependencias, config:Definiciones, etc., ver CLAUDE.md) — como en el config.org raíz más abajo.

  2. En el config.org RAÍZ (workspace), añade un nuevo encabezado * =NOMBRE= con dos bloques — siguiendo el ejemplo de las secciones * =db=/* =api= en la raíz:

    #+begin_src toml :noweb-sep ",\n" :noweb-ref Cargo:Crates
      "crates/NOMBRE"
    #+end_src
    
    #+begin_src toml :noweb-ref Cargo:Dependencias
      NOMBRE = { path = "crates/NOMBRE" }
    #+end_src
    
  3. env.org — si el nuevo crate no introduce variables de entorno propias, no toques nada. Si introduce, y en el proyecto ya existe un env.org raíz compartido, añade allí una nueva sección * con su propio :noweb-ref (como * Database access/* =JWT= parameters), y no crees un archivo separado. Crea un env.org SEPARADO para el nuevo crate solo cuando este sea un despliegue independiente (su propio .env, no el mismo proceso) y no haya un env.org compartido. En cualquier caso, el primer env.org puede dejarse completamente sin variables concretas ("puede estar sin valores, solo el archivo principal") — simplemente un esqueleto:

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

    y llenarlo con secciones * =X= parameters más tarde, cuando aparezcan variables reales.

Paso 5 — verificación después de cada cambio

Después de cada edición sustancial del código fuente org:

  1. tangle real mediante emacsclient --eval (nunca escribas el contenido de .rs/.toml/.env.example manualmente — ver la regla global correspondiente).
  2. cargo check -p CRATE (añade --target wasm32-unknown-unknown para ads-front) — cero advertencias y errores.
  3. Ejecuta la habilidad org-lint en el archivo modificado y corrige los hallazgos "CIERTOS" de inmediato; "requiere revisión" — revísalos.
  4. Para la prosa recién escrita/modificada — (font-lock-ensure) + org-fill-paragraph a través del mismo emacsclient, no manualmente.

No muestres el componente al usuario como terminado hasta que estos cuatro puntos se hayan completado para cada archivo org nuevo o modificado.

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.

Skills relacionados