OMC는 Claude가 보는 텍스트를 파일(CLAUDE.md)·입력 가로채기(키워드 훅)·세션 복원 세 군데에서 조립해, 백지 상태로 시작하는 모델에게 “무엇을 알고 시작할지”를 심는다.
왜 배우나: 키워드 한 단어로 모드가 켜지는 마법의 정체가 이 “프롬프트 조립”이며, 직접 하네스를 만들 때 가장 먼저 베껴야 할 핵심이다.
그림
flowchart TD
A["설치 1회: omc-setup"] --> B["CLAUDE.md에<br/>OMC:START~END 마커 블록 끼우기"]
B -. "세션마다 CC가 자동 로드" .-> M["모델 시스템 프롬프트<br/>(항상 켜진 운영 매뉴얼)"]
S["세션 시작 SessionStart"] --> S1["상태 복원<br/>(ralph·ultrawork·메모리·notepad)"]
S1 --> AC["additionalContext<br/>(추가 주입 텍스트)"]
U["사용자 입력 UserPromptSubmit"] --> K["키워드 탐지기"]
K --> K1["청소: 코드·인용·옛 로그 제거"]
K1 --> K2{"매직 키워드?"}
K2 -- "예" --> K3["모드 상태파일 쓰기<br/>+ MAGIC KEYWORD 안내문"]
K2 -- "아니오" --> K4["그냥 통과"]
U --> J["스킬 주입기"]
J --> J1["트리거 매칭 + 점수"]
J1 --> J2["학습된 스킬 요약 블록"]
K3 --> AC
J2 --> AC
AC --> M
M --> R["모델 응답:<br/>모드/스킬 실행"]
쉽게 풀기
Claude 본체는 기억이 없는 천재 가정교사다. 매번 새로 출근해 책상 위 종이만 읽고 일을 시작하며, 어제 한 일도 집에 있는 도구도 스스로는 모른다. OMC는 그 가정교사가 출근하기 전에 책상에 종이를 미리 깔아두는 비서다. 종이를 까는 자리가 세 군데다.
flowchart LR
subgraph 정적["1. 벽 안내문 (설치 1회)"]
P1["CLAUDE.md 마커 블록"]
end
subgraph 동적["2. 현관 쪽지 (매 입력)"]
P2["키워드 탐지 훅"]
P3["스킬 주입기"]
end
subgraph 복원["3. 어제 일지 (세션 시작)"]
P4["SessionStart 복원"]
end
정적 --> 모델["기억 없는 천재 모델"]
동적 --> 모델
복원 --> 모델
벽에 붙인 상시 안내문 (CLAUDE.md 마커 블록) — 설치 때 딱 한 번, CLAUDE.md에 <!-- OMC:START --> … <!-- OMC:END --> 주석 테두리 블록을 끼운다. 안에는 직원(에이전트)·연장(도구)·위임 규칙·모델 라우팅이 적혀 있다. Claude Code가 세션마다 CLAUDE.md를 자동 로드하므로 이 안내문은 항상 걸려 있는 운영 매뉴얼이 된다. 따로 주입 코드를 돌릴 필요 없이 파일에 박아두면 끝.
현관에서 쪽지 끼우기 (키워드 훅, 매 입력) — 사용자가 문장을 칠 때마다 UserPromptSubmit 훅이 먼저 가로챈다. ralph·autopilot·ultrawork·ccg 같은 매직 키워드가 보이면 “이 모드를 시작하라”는 쪽지를 끼워준다(keyword-detector.mjs). 동시에 입력과 관련 있는 “학습된 스킬” 요약도 함께 끼운다(skill-injector.mjs).
출근 직후 어제 일지 복원 (SessionStart) — 새 세션이 시작되면 프로젝트 메모리·위키·notepad 우선순위 메모·중단됐던 모드 상태(ralph 루프 등)를 다시 책상에 올린다(session-start.mjs / wiki-session-start.mjs).
핵심 비유: 모델은 추론기, OMC는 그 앞에 종이를 까는 담당자. 마법 같은 자동화는 전부 “어떤 종이를 깔았느냐”의 결과다.
가로챈 쪽지를 모델이 왜 따를까?
훅이 끼운 텍스트는 모델에게 “시스템이 준 추가 지시문”으로 보인다. 사용자 글인지 비서 쪽지인지 구분 못 하고 한 덩어리로 읽기 때문에, 키워드 한 단어가 모드를 켠다.
// src/installer/index.tsconst START_MARKER = '<!-- OMC:START -->';const END_MARKER = '<!-- OMC:END -->';const versionMarker = version ? `<!-- OMC:VERSION:${version} -->\n` : '';// 기존 사용자 본문이 없을 때:return `${START_MARKER}\n${versionMarker}${cleanOmcContent}\n${END_MARKER}\n`;// 사용자 본문이 있을 때는 마커 블록 + 빈 줄 + USER_CUSTOMIZATIONS + 사용자 본문 보존
B. 키워드 매칭 후 끼워지는 안내문 (본문이 아니라 “경로 + 안내”만)
핵심은 스킬 본문을 인라인하지 않고 경로만 가리킨다는 점이다. 흐름은 아래와 같다.
sequenceDiagram
participant U as 사용자
participant H as keyword-detector
participant CC as Claude Code
participant M as 모델
U->>H: 입력 ("ralph 시작")
H->>H: sanitize → 키워드 매칭
H->>H: 모드 상태파일 atomic write
H-->>CC: additionalContext (경로+안내, 본문 X)
CC->>M: 원문 + 주입텍스트 병합
M->>M: SKILL.md 읽어 워크플로 시작
펼쳐보기: 실제 MAGIC KEYWORD 안내문 출력
// scripts/keyword-detector.mjs — createSkillInvocation()`[MAGIC KEYWORD: ${skillName.toUpperCase()}]Skill routing detected: ${skillName}Preferred invocation: /oh-my-claudecode:${skillName}Read fallback: open ${skillPath} and follow its SKILL.md instructions.User request (compact echo; original prompt remains authoritative):${compactHookText(originalPrompt)}IMPORTANT: Start the ${skillName} workflow immediately. ...`
<mnemosyne>
## Relevant Learned Skills
Compact descriptors only; full learned skill bodies stay on disk to avoid prompt bloat.
### <name> (<scope>)
<skill-metadata>{"path":"...","triggers":[...],"score":10,"scope":"project"}</skill-metadata>
Summary: ...
Load instructions: if this skill is needed, read <path> and follow the full instructions there.
</mnemosyne>
키워드가 매칭되면 텍스트만 넣는 게 아니라 <omcRoot>/state/sessions/<sid>/<mode>-state.json을 atomic write 한다. 예: ralph는 {active, iteration, max_iterations:100, prompt, session_id, linked_ultrawork:true, awaiting_confirmation:true}. 이 파일을 Stop 훅(persistent-mode.mjs)이 읽어 루프 강제에, SessionStart가 읽어 모드 복원에 쓴다. 그래서 ralph 키워드는 ultrawork 상태파일도 같이 만든다.
직접 만들 때 체크리스트
마커 래퍼는 START/END + VERSION 3줄, 교체 시 사용자 본문 보존(^START\r?\n[\s\S]*?^END).
키워드 훅은 stdin JSON 읽고 hookSpecificOutput.additionalContext로만 반환(message 아님).
정보성 질문/코드블록/과거 echo는 sanitize 후 매칭(자기강화 루프 방지).
자동 스폰 위험 키워드(team류)는 자동감지에서 빼고 슬래시 전용으로.
스킬 본문 인라인 금지, “경로 + 요약”만(세션당 개수/문자 예산 둘 것).
모드 상태는 session-scoped JSON atomic write, SessionStart에서 복원.
.mcp.json — MCP 서버 t 등록(bridge/mcp-server.cjs)
(경로 prefix: /home/seunghyeong/harness-work/oh-my-claudecode/)
Codex 교차검증
별도 Codex 교차검증 기록은 없다. 핵심 사실(마커 블록 자동 로드, additionalContext 필드 필수, team 자동감지 제외, 스킬 예산 제한, ralph→ultrawork 동반 상태파일)은 모두 위 근거 파일의 실코드/실측에 근거하며 추측으로 변경하지 않았다. 추후 교차검증 결과는 이 콜아웃에 누적한다.