CommunityProgramación y desarrollogithub.com

EugineKosenko/majordom

Gestiona sesiones de claude-code-ide.el en Emacs en vivo mediante emacsclient sin cabeza: iniciar/continuar/reanudar sin bloqueos, detener de forma segura, alternar modo de permisos y autoaceptación, y navegar en selectores interactivos. Úsalo cuando la sesión 'Mayordomo' necesite levantar, continuar, detener o inspeccionar una sesión de claude-code-ide para otro proyecto.

¿Qué es majordom?

Esta habilidad proporciona un conjunto de recetas precisas de `emacsclient --eval` para gestionar sesiones de `claude-code-ide.el` desde cualquier sesión con acceso al mismo servidor Emacs (como la sesión 'Mayordomo'). Su propósito es permitir la automatización segura de operaciones sobre sesiones de Claude Code dentro de Emacs, evitando bloqueos fatales que ocurren al usar comandos interactivos en modo headless. Soporta plataformas: Emacs con `claude-code-ide.el` instalado y un servidor Emacs en ejecución. La habilidad es útil porque resuelve problemas críticos de bloqueo: el único comando seguro para iniciar es `claude-code-ide-start`, ya que `continue`, `resume` y el antiguo `claude-code-ide` pueden quedar atascados pidiendo entrada interactiva. También proporciona métodos para verificar el estado remoto (`remote-control`), detener sesiones correctamente desactivando el flag `query-on-exit` de forma preventiva, navegar en selectores interactivos (listas de reanudación, menús de permisos) mediante secuencias ANSI, alternar el modo de permisos (`Shift+Tab`) y gestionar la autoaceptación de `ediff`. Funciona inyectando comandos Elisp o secuencias ANSI directamente en el proceso del búfer de Claude Code, leyendo después el contenido del búfer para confirmar los cambios. Es una herramienta esencial para automatizar flujos de trabajo con Claude Code en Emacs sin intervención manual.

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

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

cc-sessions

Guía de recetas concretas de emacsclient --eval para gestionar sesiones de claude-code-ide.el desde "Mayordomo" (o cualquier otra sesión con acceso al mismo servidor de Emacs). Los principios (por qué se hace así) están en majordom.md; aquí solo las invocaciones listas para usar.

CRÍTICO: el único comando seguro para iniciar es claude-code-ide-start

claude-code-ide-continue, claude-code-ide-resume y el antiguo claude-code-ide (todos sin argumentos) — NUNCA deben llamarse directamente en modo headless. Cada uno de ellos, cuando ya hay una sesión activa para el directorio, invoca un (read-string "Instance name (empty for auto): ") bloqueante que se queda colgado para siempre sin un usuario vivo frente al teclado (confirmado empíricamente en los tres). La única excepción es la invocación interactiva directa M-x por parte de un humano.

claude-code-ide-start (firma (&optional instance-name continue resume)) cubre los tres casos con una sola llamada que NUNCA pide el nombre de forma interactiva:

;; inicio normal de una nueva conversación
(let ((default-directory "/home/eugine/job/<proyecto>/")
      (claude-code-ide-cli-extra-flags "--remote-control <proyecto>"))
  (claude-code-ide-start "<nombre-o-nil>"))

;; en lugar de claude-code-ide-continue
(claude-code-ide-start "<nombre-o-nil>" t nil)

;; en lugar de claude-code-ide-resume (abre un selector interactivo DENTRO de la terminal de claude,
;; no a través del minibúfer de Emacs — la llamada en sí no bloquea emacsclient)
(claude-code-ide-start "<nombre-o-nil>" nil t)

instance-name (1.er argumento) nil ⇒ número automático (vedmid-2, vedmid-3...). Asígnale un valor explícito solamente cuando el usuario haya nombrado él mismo el objetivo/nombre de la nueva copia — si no está claro, pregunta al usuario, no inventes.

Antes de iniciar: verifica el estado actual

(mapcar (lambda (b) (list (buffer-name b) (and (get-buffer-process b) (process-status (get-buffer-process b)))))
        (seq-filter (lambda (b) (string-match-p "claude-code\[<proyecto>" (buffer-name b))) (buffer-list)))
  • No hay sesión activa → (claude-code-ide-start nil t nil) (retomará la última conversación del proyecto, como continue).
  • Hay sesión activa → NUNCA la detengas "para reiniciarla". Levanta una COPIA ADICIONAL con el mismo claude-code-ide-start (con resume=t, si el objetivo es elegir una conversación anterior concreta, o sin él — una nueva conversación al lado).

Después de iniciar: confirma remote-control buscando realmente en el búfer

La ausencia de congelamiento NO prueba que --remote-control haya funcionado (caso real: olvidó la bandera — la sesión se levantó limpia, pero quedó sin remote).

(with-current-buffer "*claude-code[<proyecto>]*"
  (save-excursion (goto-char (point-min))
    (if (search-forward "remote-control" nil t) "ENCONTRADO" "NO ENCONTRADO")))

Si es NO ENCONTRADO — no siempre es un error: verifica el contenido completo del búfer (buffer-substring-no-properties (point-min) (point-max)), la línea puede estar fuera de lo renderizado, o (para sesiones grandes) fuera del scrollback visible de eat — el propio terminal solo conserva la historia reciente, no toda la conversación.

Detener sesión: primero desactiva query-on-exit, luego stop

claude-code-ide-stop en sí mismo es seguro y NO depende de si la sesión tenía remote-control. Pero la consulta normal de Emacs Buffer "..." has a running process; kill it? aparece DE FORMA ASÍNCRONA (en process-sentinel, ya DESPUÉS de que claude-code-ide-stop ha retornado) — por lo tanto, un envoltorio let alrededor de la propia llamada no sirve. Desactiva la bandera en el proceso DE ANTEMANO, con una llamada separada:

(let ((proc (get-buffer-process "*claude-code[<proyecto>]*")))
  (when proc (set-process-query-on-exit-flag proc nil)))
(with-current-buffer "*claude-code[<proyecto>]*" (claude-code-ide-stop))

Si hay varias copias para el directorio (vedmid, vedmid:2, vedmid:masazh...) — invoca claude-code-ide-stop en el contexto EXACTO de ese búfer (with-current-buffer), no a través de default-directory: el mensaje confirmará cuál detuvo ("Stopping Claude Code vedmid:masazh...").

Si la consulta igualmente se escapó y se quedó colgada (ps aux | grep emacsclient muestra un proceso atascado) — NUNCA intentes desbloquearla tú mismo (ni repetir --eval, ni enviar señales a emacs) — pide al usuario que responda en el Emacs vivo. Consulta emacs.md para el contexto completo de este peligro.

Navegación en selectores interactivos (lista de reanudación, solicitudes de permisos)

La lista de sesiones (resume) y los menús de confirmación de permisos se renderizan DENTRO de la terminal (no a través del minibúfer de Emacs) — se controlan con secuencias ANSI normales mediante process-send-string en bruto, no con llamadas Elisp vía emacsclient --eval:

(process-send-string (get-buffer-process "*claude-code[<proyecto>]*") "\e[B")   ; flecha abajo
(process-send-string (get-buffer-process "*claude-code[<proyecto>]*") "\e[A")   ; flecha arriba
(process-send-string (get-buffer-process "*claude-code[<proyecto>]*") "\e[6~")  ; Av Pág
(process-send-string (get-buffer-process "*claude-code[<proyecto>]*") "\r")     ; Enter (confirmar)

Después de cada pulsación enviada, vuelve a leer el contenido del búfer (buffer-substring-no-properties), para ver la nueva posición del cursor (❯) y el título (N of M), antes de seguir moviéndote o confirmar — no te muevas al azar varios pasos sin verificar. Las teclas numéricas ("3") para seleccionar directamente un elemento del menú de confirmación NO están confirmadas como funcionales — la navegación con flechas + Enter es más fiable.

Alternar modo de permisos (Shift+Tab) — algo distinto de auto-accept

La línea de estado del terminal (⏸ manual mode on, ⏵⏵ accept edits on, ⏸ plan mode on, ⏵⏵ auto mode on) se controla exclusivamente por el propio binario claude — Emacs no sabe nada de esto. Ciclo (Shift+Tab, cuatro estados): manual → accept edits → plan → auto → manual.

(process-send-string (get-buffer-process "*claude-code[<proyecto>]*") "\e[Z")

El cambio A VECES genera una solicitud de confirmación intermedia de herramienta (Do you want to proceed?) — selecciona el elemento "Yes, and switch to auto mode" mediante navegación con flechas (no con número) + Enter, si el objetivo es precisamente volver a auto.

claude-code-ide-toggle-auto-accept — función de Emaps aparte, no el mismo estado

No confundir con el ciclo de modo de permisos anterior. Esta función solo alterna una bandera Elisp en la estructura de la sesión y afecta SOLO a la herramienta MCP openDiff (propuesta de vista ediff antes de guardar el archivo): ON → ediff no se muestra, el archivo se guarda de inmediato (FILE_SAVED); OFF → ediff normal. La línea de estado del terminal NO cambia con esta llamada.

(with-current-buffer "*claude-code[<proyecto>]*" (claude-code-ide-toggle-auto-accept))

Mostrar el contenido del búfer al usuario "como si él estuviera mirando"

(with-current-buffer "*claude-code[<proyecto>]*" (buffer-substring-no-properties (point-min) (point-max)))

Para sesiones grandes, recorta ((max (point-min) (- (point-max) N)) (point-max)) — el contenido completo puede ser de megabytes, aunque el scrollback visible de eat siempre es limitado (la parte realmente renderizada no crece indefinidamente).

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

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

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