Community코딩 & 개발github.com

EugineKosenko/majordom

사용자 프로젝트의 org/md 산문을 ~/.claude/rules/org-babel.md에 정의된 산문 서식 규칙(~...~ vs =...= 마크업, 약어 대소문자, /.../ 용어집 용어, 실제 org 링크 vs 이탤릭/일반 텍스트, 두 마크업 사이의 공백, 후행 개행, 채움 열)에 따라 검사합니다. 산문 단락 편집 직후(각 규칙을 수동으로 기억하는 대신)와 사용자가 명시적으로 org 규칙 확인/린트를 요청하거나 clippy 실행에 비유할 때 자동으로 실행됩니다.

majordom란 무엇인가요?

이 에이전트 기술은 `~/.claude/rules/org-babel.md`에 정의된 산문 서식 규칙을 자동으로 검사하고 수정하는 린터(linter)입니다. `.org` 및 `.md` 파일의 산문 단락, 제목을 대상으로 하며, 코드 블록(`#+begin_src`, `#+begin_example`)은 제외됩니다. 주요 기능은 두 단계로 나뉩니다. 첫 번째 단계는 Python 스크립트(lint.py)를 실행하여 기계적으로 발견 가능한 위반 사항(예: 마크업 사이 공백 누락, 잘못된 파일 경로, 후행 개행 부재, 특수 용어 오용 등)을 찾아내고, '확실한 위반'은 자동 수정하며 '수동 확인 필요' 항목은 사용자에게 검토를 요청합니다. 두 번째 단계는 스크립트가 잡지 못하는 항목(예: 올바른 마크업 선택(`~...~` vs `=...=`), 약어 표기법, 링크 형식, 용어집 참조)을 수동 체크리스트로 제공합니다. 마지막 단계에서는 `emacsclient`를 통해 실제 `org-fill-paragraph`를 호출하여 단락을 정렬하고, 이때 `font-lock-ensure`을 먼저 실행하여 Emacs 미러 이미지와 동일한 결과를 보장합니다. 이 기술은 Claude Code, Cursor, Codex 등 모든 AI 에이전트 플랫폼에서 사용할 수 있으며, 사용자가 실수 없이 일관된 서식을 유지하도록 도와줍니다.

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

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

org-lint

~/.claude/rules/org-babel.md에 문서화된 org/md 파일 산문 서식 규칙을 검사하는 린터입니다. 목표는 매번 각 규칙을 수동으로 기억하는 데 의존하지 않고(이로 인해 방금 언급한 규칙만 고치고 나머지는 놓치는 위험이 있음), 명시적인 목록을 통해 텍스트를 검사하는 것입니다.

적용 시점

  • .org/.md 파일에서 새 산문 단락을 편집하거나 작성한 직후(각 규칙을 수동으로 기억하여 확인하는 대신) — 결과를 사용자에게 보여주기 전에.
  • 사용자의 명시적 요청("org 규칙 확인", "린트 실행", clippy와 비교 등) 시.
  • #+begin_src/#+begin_example 블록(코드) 내용에는 적용되지 않음 — 오직 산문 단락과 제목에만 적용.

1단계 — 기계적 검사

편집한 파일에 대해 스크립트를 실행하세요:

python3 ~/.claude/skills/org-lint/scripts/lint.py 파일/경로.org

스크립트가 정규식으로 잡아내는 항목:

  • ~...~/=...= 주변에 공백 없는 / (~a~/~b~ 대신 ~a~ / ~b~) — 확실한 위반.
  • [[file:../ — 현재 디렉터리 기준 상대 경로 대신 root: 약어 사용 — 확실한 위반.
  • 파일 끝에 개행(newline) 없음 — 확실한 위반.
  • =...= 안에 대문자 약어 (예: =CSS=) — 확인 필요 (드문 예외 허용).
  • 이탤릭 /단어/ — 확인 필요: 프로젝트 용어집의 용어인지( spcfctn/glossary.org에 해당 섹션이 있는가? 이 파일에서 첫 언급 시 링크가 있는가?), 아니면 실수로 변환되지 않은 섹션/파일 링크인지( [[*섹션][...]]여야 함).
  • 파일 언급이 =경로/파일.org= 형태 — 확인 필요: 실제 [[file:...]] 링크여야 하는 것은 아닌지.
  • "매개변수"/"매개변수들"/... 단어 — 확인 필요: Rust/Yew 컴포넌트 속성( struct ...Props )을 의미한다면 올바른 번역은 "속성들"/"속성"이며, "매개변수들"/"매개변수"는 구식 용어입니다. Yew 컴포넌트 외부(함수 매개변수, CLI, REST 프로시저 등)에서는 "매개변수"가 적절하므로 건드리지 마세요.
  • :noweb-ref 정의 블록이 :noweb-ref 선언 블록보다 앞에 있음 — 확인 필요: 선언이 먼저 와야 하며, 파일을 위에서 아래로 읽는 순서를 따라야 함 (org-babel.md 참고).
  • 동일한 :tangle 경로를 가진 여러 #+begin_src 블록이 있고, 파일 내에 :noweb yes/<<...>>가 하나도 없음 — 확실한 위반 (구식 연결 방식, 이전 gitignore.org와 같음 — org-babel.md 참고). 하나의 컨테이너 블록으로 :tangle+:noweb yes + <<이름>> 플레이스홀더와 :noweb-ref 이름 섹션으로 재구성하세요.
  • 파일이 여러 다른 대상 파일로 탱글되고, 그중 최소 두 개가 noweb을 소비(스켈레톤 #+begin_src에 :noweb yes 있음, 예: config.org → .env.example + parameters.php)하지만, 하나 이상의 :noweb-ref/<<...>> 블록에 대상 접두사가 없음 (이름 대신 env:이름) — 확실한 위반 (multi-target org 파일의 접두사 규칙, org-babel.md 참고). 하나의 대상 파일만 있는 경우, 그리고 하나의 대상만 noweb을 소비하고 나머지는 <<...>> 없는 독립적인 단일 블록 :tangle 대상(예: gitignore.org: 5개의 :tangle 대상이지만 오직 루트 .gitignore만 noweb 스켈레톤 사용)인 경우에는 접두사가 필요하지 않습니다. 실제 모호성이 없기 때문입니다.
  • #+begin_src 헤더의 매개변수 순서가 잘못됨 — 확실한 위반. 올바른 순서: 블록 타입 → :noweb yes → :noweb-sep "..." → 나머지 매개변수 → :tangle 경로 또는 :noweb-ref 이름 (가장 끝, org-babel.md 참고).
  • 파일 이름이 cargo.org인 경우 — 확실한 위반 (Rust 프로젝트의 구식 이름; config.org로 변경, org-babel.md 참고).
  • :tangle이 절대 경로(/..., ~/...) 또는 상위 디렉터리 ..를 사용 — 확실한 위반 (org-babel.md 참고); 대상은 org 파일에서 하위 디렉터리로만 향하는 상대 경로여야 합니다. 대상이 실제로 소스 트리 외부에 있다면, symlink나 다른 디렉터리 구조를 사용해야 하며 ../절대 경로를 사용하지 않아야 합니다(사례: farba-override → farba-theme via ../farba-theme/..., 작업 FS-1085).
  • =...= 밖의 대문자 (예: 아님, 오직) — 확인 필요: 단어 강조라면 약어/축약어가 아닌 경우, 대문자 대신 org bold (*아님*)로 대체.
  • "훅"/"각" (React/Yew "hook" 번역) — 구식; 올바른 번역은 "갈고리"(산문에만 해당, use_effect_with 같은 코드 식별자는 제외).
  • 105자를 초과하는 산문 줄 — emacsclient를 통한 fill-paragraph 필요 (아래 참고).

"확실한" 발견은 항상 수정하세요. "수동 확인 필요"는 각각 검토하되, 모두 오류는 아닙니다(예: =rest=/=forge-yew=는 합법적인 약어/크레이트 이름으로 위반이 아님).

2단계 — 수동 체크리스트 (스크립트가 잡지 못하는 항목)

  • 코드 식별자/타입/함수/변수/모듈 — 그리고 모든 코드 조각이나 표현식(예: id=1, value == 0, items()) — 틸드 ~...~. 약어/두문자어와 크레이트/라이브러리의 "공개" 형태 이름(하이픈 포함) — 등호 =...=. 정규화된 경로 크레이트::타입은 코드 타입 이름이므로, 크레이트 접두사가 있더라도 전체를 틸드 안에 넣습니다.
  • 약어/두문자어 — 문장 중간에서는 소문자, 문장 시작에서만 첫 글자 대문자(모두 대문자 금지), 드문 확립된 예외는 제외.
  • 같은 파일 내 섹션 링크 — [[*헤딩 제목][제목]], 이탤릭이나 일반 텍스트가 아님. 같은 디렉터리의 파일 링크 — 그냥 [[file:이웃.org][설명]]; 다른 디렉터리의 파일(특히 공통 작업 디렉터리 내 다른 git 리포지토리) — root: 약어 사용 ([[root:code/ads-back/파일.org::N][설명]]), ../../../ 현재 디렉터리 기준 상대 경로 아님. 약어는 작업 디렉터리 루트의 .dir-locals.el에 선언됩니다(locate-dominating-file을 사용한 eval 형식) — 프로젝트에 아직 없으면 생성하세요.
  • 이탤릭 /.../ — 오직 프로젝트 용어집 용어만 해당(바로 뒤에 번역 /translation/ 포함); 각 파일에서 용어 첫 언급 시 — 해당 섹션에 대한 [[file:.../spcfctn/glossary.org::*용어][...]] 링크, 정의 반복 금지.

3단계 — 정렬

편집한 각 단락에 대해 수동 정렬 대신 emacsclient --eval을 통해 실제 fill-paragraph를 호출하세요 (org-babel.md의 해당 규칙 참고). 단락 텍스트를 new_string/파일 생성 시 한 줄로 작성하고, 스스로 줄 바꿈을 추측하지 마세요 — 어차피 fill-paragraph가 완전히 결정합니다.

반드시 org-fill-paragraph 전에 (font-lock-ensure)를 호출하세요: find-file-noselect로 headless로 연 버퍼는 폰트화가 진행되지 않아 org 링크 [[경로][설명]]가 짧은 가시 텍스트 설명으로 "접히지" 않습니다. font-lock-ensure 없이 fill-paragraph는 링크의 긴 원시 텍스트를 기준으로 줄 바꿈을 계산하므로, 라이브 대화형 Emacs에서 M-q가 제공하는 결과와 달라집니다. 예:

emacsclient --eval '
(let ((buf (find-file-noselect "파일/경로.org")))
  (with-current-buffer buf
    (org-mode)
    (font-lock-ensure)
    (goto-char (point-min))
    (search-forward "단락의 고유 부분")
    (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).

관련 스킬