EugineKosenko/majordom

Gerenciamento de sessões claude-code-ide.el em Emacs ativo via emacsclient headless — iniciar/continuar/retomar sem solicitações bloqueantes, parada segura, alternância de permission-mode e auto-accept, navegação em pickers interativos.

O que é majordom?

Este skill capacita um agente AI (como um 'Mordomo' em uma sessão separada do Emacs) a controlar remotamente sessões de Claude Code em um mesmo servidor Emacs, usando chamadas emacsclient --eval. Ele fornece receitas testadas para iniciar, continuar ou retomar sessões claude-code-ide.el sem bloquear, evitando erros comuns como prompts interativos que congelam o terminal. Inclui verificações de segurança (como desabilitar query-on-exit antes de parar) e orientações para navegar em listas de retomada e menus de permissão via sequências ANSI. Suporta alternância do modo de permissão interno do Claude (Shift+Tab) e do auto-accept (que controla apenas o diff do ediff). O objetivo final é permitir que um agente orquestre múltiplas sessões de Claude Code para diferentes projetos, sem interação humana direta.

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

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

cc-sessions

Guia de receitas específicas emacsclient --eval para gerenciar sessões claude-code-ide.el a partir do "Mordomo" (ou de qualquer outra sessão com acesso ao mesmo servidor Emacs). Os princípios (por que assim) estão em majordom.md; aqui — apenas as chamadas prontas.

CRÍTICO: o único comando seguro para iniciar é claude-code-ide-start

claude-code-ide-continue, claude-code-ide-resume e o antigo claude-code-ide (todos sem argumentos) — NUNCA devem ser chamados diretamente headless. Cada um deles, quando já existe uma sessão ativa para o diretório, invoca um bloqueante (read-string "Instance name (empty for auto): "), que trava para sempre sem um usuário vivo no teclado (confirmado empiricamente em todos os três). A única exceção é o M-x interativo direto por um humano.

claude-code-ide-start (assinatura (&optional instance-name continue resume)) cobre todos os três casos com uma única chamada que NUNCA pergunta o nome interativamente:

;; início normal de uma nova conversa
(let ((default-directory "/home/eugine/job/<projeto>/")
      (claude-code-ide-cli-extra-flags "--remote-control <projeto>"))
  (claude-code-ide-start "<nome-ou-nil>"))

;; em vez de claude-code-ide-continue
(claude-code-ide-start "<nome-ou-nil>" t nil)

;; em vez de claude-code-ide-resume (abre um picker interativo DENTRO do terminal do claude,
;; não pelo minibuffer do Emacs — a chamada em si não bloqueia o emacsclient)
(claude-code-ide-start "<nome-ou-nil>" nil t)

instance-name (1º argumento) nil ⇒ numeração automática (vedmid-2, vedmid-3...). Defina-o explicitamente apenas quando o usuário nomeou o destino/nome da nova cópia — se não souber, pergunte ao usuário, não invente.

Antes de iniciar: verifique o estado atual

(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\\[<projeto>" (buffer-name b))) (buffer-list)))
  • Nenhuma sessão ativa → (claude-code-ide-start nil t nil) (retoma a última conversa do projeto, como continue).
  • Há uma sessão ativa → NUNCA a pare "para reiniciar". Abra uma CÓPIA ADICIONAL com o mesmo claude-code-ide-start (com resume=t se o objetivo for escolher uma conversa antiga específica, ou sem — nova conversa ao lado).

Após iniciar: confirme remote-control com busca real no buffer

Ausência de travamento AINDA não prova que --remote-control funcionou (episódio: esqueceu a flag — a sessão subiu limpa, mas permaneceu não remota).

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

Se NOT FOUND — nem sempre é erro: verifique o conteúdo completo do buffer (buffer-substring-no-properties (point-min) (point-max)), a linha pode estar fora da parte renderizada, ou (para sessões grandes) fora do scrollback visível de eat — o próprio terminal mantém apenas o histórico recente, não a conversa toda.

Parar sessão: primeiro desabilite query-on-exit, depois pare

claude-code-ide-stop por si só é seguro e NÃO depende de a sessão ter tido remote-control. Mas o prompt normal do Emacs Buffer "..." has a running process; kill it? aparece ASSINCRONAMENTE (no process-sentinel, APÓS claude-code-ide-stop já ter retornado) — portanto, um let-wrapper ao redor da própria chamada não salva. Desabilite a flag no processo ANTES, com uma chamada separada:

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

Se houver várias cópias para o mesmo diretório (vedmid, vedmid:2, vedmid:masazh...) — chame claude-code-ide-stop no contexto DO PRÓPRIO buffer (with-current-buffer), não via default-directory: a mensagem confirmará qual foi parada ("Stopping Claude Code vedmid:masazh...").

Se o prompt ainda assim aparecer e travar (ps aux | grep emacsclient mostrar um processo pendurado) — NUNCA tente desbloquear sozinha (nenhum --eval repetido, nenhum sinal para o emacs) — peça ao usuário para responder no Emacs ativo. Veja emacs.md para contexto completo desse perigo.

Navegação em pickers interativos (lista de retomada, solicitações de permissão)

A lista de sessões (resume) e os menus de confirmação de permissões são renderizados DENTRO do terminal (não pelo minibuffer do Emacs) — controlados por sequências ANSI comuns via process-send-string, não por emacsclient --eval com chamadas elisp:

(process-send-string (get-buffer-process "*claude-code[<projeto>]*") "\e[B")   ; seta para baixo
(process-send-string (get-buffer-process "*claude-code[<projeto>]*") "\e[A")   ; seta para cima
(process-send-string (get-buffer-process "*claude-code[<projeto>]*") "\e[6~")  ; Page Down
(process-send-string (get-buffer-process "*claude-code[<projeto>]*") "\r")     ; Enter (confirmar)

Após cada pressionamento enviado, releia o conteúdo do buffer (buffer-substring-no-properties) para ver a nova posição do cursor (❯) e o título (N of M), antes de avançar ou confirmar — não se mova às cegas vários passos sem verificar. Teclas numéricas ("3") para seleção direta de item de menu de confirmação NÃO são confirmadas como funcionais — navegação com setas + Enter é mais confiável.

Alternância de permission-mode (Shift+Tab) — é outra coisa, não auto-accept

A linha de status do terminal (⏸ manual mode on, ⏵⏵ accept edits on, ⏸ plan mode on, ⏵⏵ auto mode on) é controlada exclusivamente pelo binário claude — o Emacs não sabe nada sobre isso. Ciclo (Shift+Tab, quatro estados): manual → accept edits → plan → auto → manual.

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

A alternância ÀS VEZES invoca uma solicitação intermediária de confirmação de ferramenta (Do you want to proceed?) — escolha o item "Yes, and switch to auto mode" via navegação com setas (não com número) + Enter, se o objetivo for retornar ao auto.

claude-code-ide-toggle-auto-accept — função Emacs separada, não o mesmo estado

Não confundir com o ciclo permission-mode acima. Esta função alterna apenas uma flag elisp na estrutura da sessão e afeta APENAS a ferramenta MCP openDiff (oferta de visualização ediff antes de salvar arquivo): ON → ediff não é mostrado, o arquivo é salvo imediatamente (FILE_SAVED); OFF → ediff normal. A linha de status do terminal NÃO muda com esta chamada.

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

Mostrar conteúdo do buffer para o usuário "como se estivesse olhando"

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

Para sessões grandes, corte ((max (point-min) (- (point-max) N)) (point-max)) — o conteúdo completo pode ser de megabytes, embora o scrollback visível de eat seja sempre limitado (a parte realmente renderizada não cresce 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.

Habilidades Relacionadas