์๋ฆฌ์ฆ: oh-my-codex ์ํคํ ์ฒ ํด๋ถ
์ด ์๋ฆฌ์ฆ๋ OpenAI Codex CLI ํ์ฅ ๋ฐํ์์ธ oh-my-codex(OMX)์ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๋จ๊ณ๋ณ๋ก ํด๋ถํ๋ ๊ณผ์ ์ด๋ค.
| ํธ | ๋ด์ฉ | ํต์ฌ |
|---|---|---|
| 0ํธ | Overview | 3-Plane ์ํคํ ์ฒ, OMC์์ ์ฐจ์ด, ์ ์ฒด ํ๋ฆ |
| 1ํธ | Codex CLI Foundation | Codex CLI ์์ฒด์ ๊ตฌ์กฐ์ ํ์ฅ ํฌ์ธํธ |
| 2ํธ (๋ณธ๋ฌธ) | OMX Integration | OMX๊ฐ Codex์ ์ด๋ป๊ฒ ์ฐ๊ฒฐ๋๋ |
| 3ํธ | Skill System | ์ํฌํ๋ก์ฐ๋ฅผ ์ด๋ป๊ฒ ์ ์ํ๋ |
| 4ํธ | Prompt & Agent System | ์์ด์ ํธ๋ ๋ญ๊ณ ์ด๋ป๊ฒ ์ ํ๋๋ |
| 5ํธ | MCP Servers | ์ด๋ค MCP ๋๊ตฌ๋ฅผ ์ธ ์ ์๋ |
| 6ํธ | State & Lifecycle | ์ํ๋ฅผ ์ด๋ป๊ฒ ์ ์งํ๋ |
| 7ํธ | Team Orchestration | Team ๋ชจ๋๋ ์ด๋ป๊ฒ ๋์ํ๋ |
| 8ํธ | Native & Spark | Rust ๋ค์ดํฐ๋ธ ๋๊ตฌ๋ ๋ญ๊ฐ |
- OMX Integration์ oh-my-codex๊ฐ Codex CLI์ ํ์ฅ ํฌ์ธํธ์ ์ฐ๊ฒฐ๋๋ ํตํฉ ๋ฉ์ปค๋์ฆ
- Codex CLI๋ฅผ ์์ ํ์ง ์๊ณ AGENTS.md, config.toml, ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ํตํด ํ๋์ ์ฃผ์ ํ๋ non-invasive ํตํฉ ๋ฐฉ์
- OMC์ Hook(stdin/stdout JSON) ๊ธฐ๋ฐ ๊ฒฐ์ ๋ก ์ (Deterministic) ์ด๋ฒคํธ ๊ฐ๋ก์ฑ๊ธฐ์ ๋๋น๋๋, LLM ํด์์ ์์กดํ๋ ํ๋ฅ ๋ก ์ (Probabilistic) AGENTS.md ๊ธฐ๋ฐ ํค์๋ ๋งคํ ์ํคํ ์ฒ
ํด๋น ๊ฐ๋ ์ด ํ์ํ ์ด์
- 1ํธ์์ Codex CLI์ ๊ตฌ์กฐ์ ํ์ฅ ํฌ์ธํธ(AGENTS.md, config.toml, MCP)๋ฅผ ์ดํดํ์
- ํ์ง๋ง **โOMX๊ฐ ์ด ํ์ฅ ํฌ์ธํธ๋ค์ ์ค์ ๋ก ์ด๋ป๊ฒ ํ์ฉํ๋์งโ**๊ฐ ์์ง ๋น ์ ธ ์์
- ์ด ํํธ๋ OMX์ ์ค์น ํ๋ฆ(
omx setup), ์คํ ๋ฐฉ์(omx launch), ์ค์ผ์คํธ๋ ์ด์ ๋ธ๋ ์ธ(AGENTS.md), ํค์๋ ๊ฐ์ง ๋ฉ์ปค๋์ฆ์ ๋ค๋ฃจ์ด ๊ทธ ๊ฐ๊ทน์ ๋ฉ์
AS-IS (OMC โ Claude Code ํตํฉ ๋ฐฉ์)
sequenceDiagram autonumber participant U as User participant HC as hooks.json participant KD as keyword-detector.mjs participant CC as Claude Code participant SK as Skill tool U->>CC: "ultrawork refactor API" CC->>HC: UserPromptSubmit ์ด๋ฒคํธ ๋ฐ์ HC->>KD: stdin JSON ์ ๋ฌ KD->>KD: "ultrawork" ํค์๋ ๊ฐ์ง KD-->>HC: stdout JSON (์คํฌ ๋งคํ ๊ฒฐ๊ณผ) HC->>CC: ๊ฒฐ๊ณผ ์ฃผ์ CC->>SK: Skill("omc:ultrawork") ํธ์ถ
TO-BE (OMX โ Codex CLI ํตํฉ ๋ฐฉ์)
sequenceDiagram autonumber participant U as User participant CX as Codex CLI participant AM as AGENTS.md participant SK as skills/ultrawork/SKILL.md U->>CX: "ultrawork refactor API" CX->>AM: ์ธ์ ์์ ์ ์ง์นจ ๋ก๋ Note over CX,AM: AGENTS.md์ ํค์๋ ๋งคํ ํ ์ด๋ธ ๋ด์ฅ CX->>CX: "ultrawork" ํค์๋ ๊ฐ์ง (LLM์ด ์ง์ ํด์) CX->>SK: $ultrawork โ SKILL.md ์ฝ๊ธฐ CX->>CX: ์คํฌ ์ง์นจ์ ๋ฐ๋ผ ์์ ์ํ
omx setup / omx launch โ ์คํ ์ฃผ์ฒด์ ์์
ํต์ฌ: ์ด ๋ ๋ช ๋ น์ด๋ AGENTS.md๋ LLM์ด ํธ๋ฆฌ๊ฑฐํ์ง ์๋๋ค. ์ฌ๋์ด ํฐ๋ฏธ๋์์ ์ง์ ์ ๋ ฅํ๋ CLI ๋ช ๋ น์ด๋ค.
OMX๋ npm์ผ๋ก ์ค์น๋๋ Node.js CLI ๋๊ตฌ์ด๋ฉฐ, bin/omx.js๊ฐ ์ง์
์ ์ด๋ค. src/cli/ ํ์์ ๊ฐ ์๋ธ์ปค๋งจ๋ ํธ๋ค๋ฌ๊ฐ ์๊ณ , ์ด๋ 3-Plane ์ํคํ
์ฒ์ Control Plane์ ํด๋นํ๋ค.
[์ฌ๋์ด ํฐ๋ฏธ๋์์ ์ง์ ์
๋ ฅ]
$ omx setup โ ์ต์ด 1ํ, ํ๊ฒฝ ๊ตฌ์ฑ (src/cli/setup.ts)
$ omx launch โ ๋งค ์ธ์
, Codex CLI ๊ธฐ๋ (src/cli/launch.ts)
| Plane | ๋ฌด์์ด ์คํ์ํค๋ | ์์ |
|---|---|---|
| Control Plane | ์ฌ๋ (ํฐ๋ฏธ๋ ์ง์ ์ ๋ ฅ) | omx setup, omx launch, omx team |
| Execution Plane | LLM (AGENTS.md ํด์ โ ํ๋ฅ ๋ก ์ ) | ํค์๋ ๊ฐ์ง, ์คํฌ ์คํ, ์์ |
| State Plane | MCP ์๋ฒ ์๋ ๋์ | state_write, memory_store |
AGENTS.md๋ omx launch๋ก Codex CLI๊ฐ ๊ธฐ๋๋ ์ดํ LLM์ด ์ฝ๋ ํ์ผ์ด๋ค. omx setup/omx launch๋ ๊ทธ ์ด์ ์ ์ฌ๋์ด ์๋์ผ๋ก ์คํํ๋ ์ ํ ์กฐ๊ฑด์ด๋ค.
sequenceDiagram autonumber participant H as ์ฌ๋ (ํฐ๋ฏธ๋) participant CP as Control Plane (omx CLI) participant CX as Codex CLI (LLM) participant AM as AGENTS.md H->>CP: omx setup (์ต์ด 1ํ) CP->>CP: AGENTS.md ์์ฑ, config.toml ๋ฑ๋ก, skills/ ๋ฐฐ์น H->>CP: omx launch (๋งค ์ธ์ ) CP->>CP: agents-overlay.ts (src/hooks/) โ ์ธ์ ํฉ๋ณธ AGENTS.md ์์ฑ Note over CP: user AGENTS.md + project AGENTS.md + ๋ฐํ์ ์ค๋ฒ๋ ์ด ๋จธ์ง CP->>CX: codex (model_instructions_file = .omx/state/{sessionId}/AGENTS.md) Note over CX: ๋ค์ดํฐ๋ธ AGENTS.md ์ฒด์ธ์ ๋ฌด๋ ฅํ๋จ CX->>CX: ์ธ์ ํฉ๋ณธ AGENTS.md๋ฅผ ์์คํ ํ๋กฌํํธ๋ก ๋ก๋ (1ํ) Note over CX: ์ดํ ํค์๋ ๊ฐ์ง๋ ํ๋ฅ ๋ก ์
omx setup โ ์ค์น ํ๋ฆ
omx setup์ OMX์ ๋ชจ๋ ๊ตฌ์ฑ ์์๋ฅผ Codex CLI๊ฐ ์ธ์ํ๋ ์์น์ ๋ฐฐ์นํ๋ ๋ถํธ์คํธ๋ํ ๋ช
๋ น์ด๋ค. ์์ค๋ src/cli/setup.ts.
Scope ๊ฒฐ์ : user-scope vs project-scope
| ํญ๋ชฉ | user-scope | project-scope |
|---|---|---|
| ๋์ | ์ ์ญ (๋ชจ๋ ํ๋ก์ ํธ) | ํน์ ํ๋ก์ ํธ๋ง |
| AGENTS.md | ~/.codex/AGENTS.md | ./.codex/AGENTS.md |
| Skills | ~/.agents/skills/ | ./.agents/skills/ |
| OMX ์ค์ | ~/.omx/ | ./.omx/ |
| Prompts | ~/.codex/prompts/ | ./.codex/prompts/ |
์ค์น๋๋ ๊ฒ๋ค
graph LR Setup["omx setup"] Setup --> A["AGENTS.md ์์ฑ/๋จธ์ง"] Setup --> B["config.toml์ MCP ์๋ฒ 5๊ฐ ๋ฑ๋ก"] Setup --> C["prompts/*.md โ prompts/ ๋๋ ํ ๋ฆฌ"] Setup --> D["skills/*/SKILL.md โ skills/ ๋๋ ํ ๋ฆฌ"] Setup --> E["๋ค์ดํฐ๋ธ ์์ด์ ํธ ์ค์ โ .omx/agents/"] style Setup fill:#4CAF50,color:#fff
- AGENTS.md: ๊ธฐ์กด ํ์ผ์ด ์์ผ๋ฉด ๋จธ์ง, ์์ผ๋ฉด ์๋ก ์์ฑ
- config.toml: 5๊ฐ MCP ์๋ฒ(state, memory, code-intel, trace, team) ๋ฑ๋ก
- prompts/: 33๊ฐ ์ญํ ๋ณ ์์ด์ ํธ ํ๋กฌํํธ ํ์ผ ๋ฐฐ์น
- skills/: 35+ ์ํฌํ๋ก์ฐ ์คํฌ์ SKILL.md ํ์ผ ๋ฐฐ์น
- ๋ค์ดํฐ๋ธ ์์ด์ ํธ ์ค์ :
.omx/agents/์ ์์ด์ ํธ ๋ฉํ๋ฐ์ดํฐ ์ ์ฅ
omx launch โ Codex๋ฅผ ์ด๋ค ํ๋๊ทธ๋ก ์คํํ๋
omx launch๋ Codex CLI๋ฅผ OMX๊ฐ ์๋ํ ๋๋ก ๋์์ํค๊ธฐ ์ํด ์ ์ ํ ํ๋๊ทธ์ ํ๊ฒฝ๋ณ์๋ฅผ ์ธํ
ํ์ฌ ์คํํ๋ ๋ํผ ๋ช
๋ น์ด๋ค.
ํต์ฌ ์ค์
- model_instructions_file:
agents-overlay.ts๊ฐ ์์ฑํ ์ธ์ ํฉ๋ณธ AGENTS.md(.omx/state/{sessionId}/AGENTS.md) ๊ฒฝ๋ก๋ฅผ ์ง์ . ์ด ์ค์ ์ด ํ์ฑํ๋๋ฉด Codex CLI์ ๋ค์ดํฐ๋ธ AGENTS.md ๊ณ์ธต์ ๋จธ์ง๊ฐ ๋ฌด๋ ฅํ๋๋ฏ๋ก, OMX๊ฐ ์ง์ user/project AGENTS.md๋ฅผ ํฉ์ณ ๋ฃ๋๋ค. - CODEX_HOME: project-scope์ผ ๋ ํ๋ก์ ํธ ๋ฃจํธ์
.codex/๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์ค์
์ฃผ์ ํ๋๊ทธ
| ํ๋๊ทธ | ๋์ |
|---|---|
--yolo | Codex full-auto ๋ชจ๋ (์น์ธ ์์ด ์คํ) |
--high / --xhigh | ์ถ๋ก ๋ ธ๋ ฅ(reasoning effort) ๋ ๋ฒจ ์กฐ์ |
--madmax | ์น์ธ ์ฐํ โ ์ ๋ขฐ ํ๊ฒฝ ์ ์ฉ |
--spark | Worker์ ์คํํฌ ๋ชจ๋ธ ์ฌ์ฉ |
-w, --worktree | Git worktree ๊ฒฉ๋ฆฌ ๋ชจ๋๋ก ์คํ |
agents-overlay.ts โ ์ธ์ ๋ณ ํฉ๋ณธ AGENTS.md ์์ฑ
agents-overlay.ts๋ ์ธ์
๋ณ๋ก ๊ณตํต AGENTS.md + ๋ฐํ์ ์ค๋ฒ๋ ์ด๋ฅผ ํฉ์น ์ธ์
์ ์ฉ AGENTS.md๋ฅผ ์์ฑํ๋ ๋ชจ๋์ด๋ค. ์์ค ์์น๋ **src/hooks/agents-overlay.ts**์ด๋ฉฐ, src/cli/index.ts๊ฐ importํ์ฌ omx launch ๊ณผ์ ์์ ํธ์ถํ๋ค. Node.js(Control Plane)๊ฐ ๊ฒฐ์ ๋ก ์ ์ผ๋ก ์คํํ๋ค.
model_instructions_file โ ๊ณต์ ์ ์ (Codex ์์ค: codex-rs/core/src/config/mod.rs)
โOptional path to a file containing model instructions that will override the built-in instructions for the selected model. Users are STRONGLY DISCOURAGED from using this field, as deviating from the instructions sanctioned by Codex will likely degrade model performance.โ
model_instructions_file์ config.toml์ ํค๋ก, Codex ๋ด์ฅ ๋ชจ๋ธ ์ง์นจ์ ์ค๋ฒ๋ผ์ด๋ํ๋ ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ค. ์ฐ์ ์์: CLI ํ๋๊ทธ > ํ๋กํ์ผ > ๋ฃจํธ config.
ํต์ฌ:
model_instructions_file์ ์ค์ ํ๋ฉด Codex CLI์ ๋ค์ดํฐ๋ธ AGENTS.md ๊ณ์ธต์ ํ์ยท๋จธ์ง๊ฐ ๋ฌด๋ ฅํ๋๋ค (1ํธ Foundation ์ฐธ์กฐ: โ--no-project-doc๋๋model_instructions_file๋ก ๋นํ์ฑํ/๋์ฒด ๊ฐ๋ฅโ). OMX๋ ๋ฐํ์ ์ค๋ฒ๋ ์ด๋ฅผ ์ฃผ์ ํ๊ธฐ ์ํด ์ด ํค๋ฅผ ์ฌ์ฉํ๋๋ฐ, ๊ทธ ์๊ฐ ๋ค์ดํฐ๋ธ ๋จธ์ง๊ฐ ๊บผ์ง๋ฏ๋ก OMX๊ฐ ์ง์ AGENTS.md๋ฅผ ์ฌ๋จธ์งํด์ผ ํ๋ค.
| ํญ๋ชฉ | model_instructions_file | AGENTS.md ๋ค์ดํฐ๋ธ ์ฒด์ธ |
|---|---|---|
| ์ญํ | ์ง์ ๋ ๋จ์ผ ํ์ผ์ ๋ชจ๋ธ ์ง์นจ์ผ๋ก ์ฌ์ฉ | ๊ณ์ธต์ ํ์ยท์ฐ๊ฒฐ(concatenate) |
| ์ค์ ์ | ๋ค์ดํฐ๋ธ AGENTS.md ์ฒด์ธ ๋ฌด๋ ฅํ | ์ ์ ๋์ |
| OMX ํ์ฉ | ์ธ์ ํฉ๋ณธ AGENTS.md ๊ฒฝ๋ก ์ค์ | omx setup์ด ์๋ณธ AGENTS.md์ ์ง์นจ ์ฃผ์
|
์คํ ํ๋ฆ (์์ค ํ์ธ: writeSessionModelInstructionsFile())
sequenceDiagram autonumber participant H as ์ฌ๋ participant CLI as src/cli/index.ts participant AO as src/hooks/agents-overlay.ts participant UA as ~/.codex/AGENTS.md participant PA as {cwd}/AGENTS.md participant SF as .omx/state/{sessionId}/AGENTS.md participant CX as Codex CLI (LLM) H->>CLI: omx launch (Control Plane) CLI->>AO: writeSessionModelInstructionsFile() ํธ์ถ AO->>UA: โ user-level AGENTS.md ์ฝ๊ธฐ AO->>PA: โก project-level AGENTS.md ์ฝ๊ธฐ AO->>AO: โข project-scope ์คํฌ ์ค๋ณต ์ฐธ์กฐ ๋ผ์ธ ์ ๊ฑฐ AO->>AO: โฃ โ + โก concatenate (๋ค์ดํฐ๋ธ ๋จธ์ง๋ฅผ ์ง์ ์ฌ๊ตฌํ) AO->>AO: โค + ๋ฐํ์ ์ค๋ฒ๋ ์ด append AO->>SF: โฅ ์ธ์ ํฉ๋ณธ AGENTS.md ์ฐ๊ธฐ CLI->>CX: codex ๊ธฐ๋ (model_instructions_file = SF ๊ฒฝ๋ก) Note over CX: ๋ค์ดํฐ๋ธ AGENTS.md ์ฒด์ธ์ ๋ฌด๋ ฅํ๋จ CX->>SF: ์ธ์ ์์ ์ ํฉ๋ณธ ํ์ผ ๋ก๋ (1ํ) Note over CX: ์ดํ ํค์๋ ๊ฐ์ง๋ ํ๋ฅ ๋ก ์ (Execution Plane)
์๋ณธ AGENTS.md ํ์ผ๋ค์ ์์ ํ์ง ์๋๋ค. ์ธ์
์ด ๋๋๋ฉด .omx/state/{sessionId}/AGENTS.md๋ ์ ๋ฆฌ๋๋ค.
์ธ์ ์ค ๋์ ๊ฐฑ์ ๊ฐ๋ฅ ์ฌ๋ถ
๋ถ๊ฐ๋ฅํ๋ค. model_instructions_file๋ก ์ง์ ๋ ํ์ผ์ ์ธ์
์์ ์ 1ํ ์ฝํ ์์คํ
ํ๋กฌํํธ์ ์ฝ์
๋๋ค. ์ดํ ํ์ผ์ ๋ณ๊ฒฝํด๋ ์ด๋ฏธ context window์ ๋ค์ด๊ฐ ๋ด์ฉ์ ๊ต์ฒด๋์ง ์๋๋ค.
์ธ์
์์ ์
AGENTS.md + ์ค๋ฒ๋ ์ด โ ์์คํ
ํ๋กฌํํธ (context window์ ๊ณ ์ )
์ธ์
์ค ํ์ผ ๋ณ๊ฒฝ
โ context window์๋ ๋ฐ์ ์ ๋จ (LLM์ ์ด๋ฏธ ์ด์ ๋ด์ฉ์ผ๋ก ์๋ ์ค)
MCP ํด ์ถ๊ฐ๋ ๋์ผํ ์ด์ ๋ก ์ธ์
์ค ๋ฐ์ ๋ถ๊ฐ๋ค. config.toml์ MCP ์๋ฒ ๋ชฉ๋ก๋ Codex CLI ๊ธฐ๋ ์ ๋ก๋๋๋ฏ๋ก, ์ธ์
์ค MCP ์๋ฒ๋ฅผ ์ถ๊ฐํด๋ ํด๋น ์ธ์
์์๋ ์ฌ์ฉํ ์ ์๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ๋ค์ omx launch ์ ๋ฐ์๋๋ค.
| ๋ณ๊ฒฝ ์ ํ | ์ธ์ ์ค ๋ฐ์ | ๋ฐ์ ์์ |
|---|---|---|
| ์ค๋ฒ๋ ์ด ํ์ผ ์์ | X | ๋ค์ omx launch |
| AGENTS.md ์์ | X | ๋ค์ omx launch |
| MCP ์๋ฒ ์ถ๊ฐ (config.toml) | X | ๋ค์ omx launch |
| MCP ํด ๊ฒฐ๊ณผ (์ํ ๊ธฐ๋ก ๋ฑ) | O | ์ฆ์ (๋๊ตฌ ํธ์ถ ์๋ต์ผ๋ก context์ ์ถ๊ฐ) |
์ธ์ ์ด ๋๋๋ฉด ์ค๋ฒ๋ ์ด ์์ ํ์ผ์ ์ ๋ฆฌ๋๋ค.
AGENTS.md โ ์ค์ผ์คํธ๋ ์ด์ ๋ธ๋ ์ธ
AGENTS.md๋ OMX์์ โtop-level operating contract for the workspaceโ ์ญํ ์ ํ๋ ํต์ฌ ํ์ผ์ด๋ค. Codex CLI๋ ์ด ํ์ผ์ ์์คํ ํ๋กฌํํธ์ ์ผ๋ถ๋ก ๋ก๋ํ๋ฏ๋ก, OMX๋ ์ฌ๊ธฐ์ ๋ชจ๋ ์ค์ผ์คํธ๋ ์ด์ ๋ก์ง์ ์ฃผ์ ํ๋ค.
Guidance Schema โ ์ง์นจ์ ๊ตฌ์กฐ
docs/guidance-schema.md์ ์ ์๋ 6๊ฐ ์น์
๊ตฌ์กฐ:
| ์น์ | ์ญํ |
|---|---|
| Role & Intent | ์์ด์ ํธ์ ์ญํ ๊ณผ ๋ชฉ์ ์ ์ |
| Operating Principles | ํ๋ ์์น 5๊ฐ |
| Execution Protocol | ํค์๋ ๊ฐ์ง, ์์ ๊ท์น, ์คํ ์ ์ฐจ |
| Constraints & Safety | ์ ์ฝ ์กฐ๊ฑด ๋ฐ ์์ ์ฅ์น |
| Verification & Completion | ์์ ์๋ฃ ๊ฒ์ฆ ํ๋กํ ์ฝ |
| Recovery & Lifecycle Overlays | ์ฅ์ ๋ณต๊ตฌ ๋ฐ ์๋ช ์ฃผ๊ธฐ ์ค๋ฒ๋ ์ด |
Operating Principles 5๊ฐ
- โSolve the task directly when you can do so safely and well.โ โ ์ง์ ํด๊ฒฐ ์ฐ์
- โDelegate only when it materially improves quality, speed, or correctness.โ โ ์์์ ์ค์ง์ ์ด์ ์ด ์์ ๋๋ง
- โKeep progress short, concrete, and useful.โ โ ์งํ ๋ณด๊ณ ๋ ์งง๊ณ ๊ตฌ์ฒด์ ์ผ๋ก
- โPrefer evidence over assumption; verify before claiming completion.โ โ ์ฆ๊ฑฐ ๊ธฐ๋ฐ ๊ฒ์ฆ
- โUse the lightest path that preserves quality: direct action, MCP, then delegation.โ โ ๊ฒฝ๋ ๊ฒฝ๋ก ์ฐ์ (์ง์ โ MCP โ ์์)
์ด 5๊ฐ ์์น์ ์์ค์ปฌ๋ ์ด์ ์ฌ๋ค๋ฆฌ๋ฅผ ํ์ฑํ๋ค. ์์ด์ ํธ๋ ํญ์ ๊ฐ์ฅ ๊ฐ๋ฒผ์ด ๋ฐฉ๋ฒ๋ถํฐ ์๋ํ๊ณ , ํ์ํ ๋๋ง ๋ ๋ฌด๊ฑฐ์ด ๋ฐฉ๋ฒ(MCP ํธ์ถ, ๋ค๋ฅธ ์์ด์ ํธ ์์)์ผ๋ก ์ฌ๋ผ๊ฐ๋ค.
Keyword Detection ํ ์ด๋ธ
AGENTS.md์ ๋ด์ฅ๋ ํค์๋ ๋งคํ ํ
์ด๋ธ์ ์ฌ์ฉ์ ์
๋ ฅ์์ ํน์ ํค์๋๋ฅผ ๊ฐ์งํ๋ฉด ์ด๋ค ์คํฌ/์์ด์ ํธ๋ฅผ ํ์ฑํํ ์ง ์ ์ํ๋ค. ์ด ํ
์ด๋ธ์ AGENTS.md ํ
ํ๋ฆฟ์ ์ ์ ์ผ๋ก ํ๋์ฝ๋ฉ๋์ด ์์ผ๋ฉฐ (์์ค ํ์ธ: <keyword_detection> ์น์
), keyword-registry.ts์์ ๋์ ์์ฑ๋๋ ๊ฒ์ด ์๋๋ค.
| ํค์๋ | ์ฐ์ ์์ | ๋งคํ ๋์ |
|---|---|---|
ralplan | 11 | ralph plan ๋ชจ๋ |
autopilot | 10 | autopilot ์คํฌ |
ultrawork | 10 | ultrawork ์คํฌ |
ralph | 9 | ralph ์์ด์ ํธ |
| โฆ | โฆ | 30+ ์ถ๊ฐ ํค์๋ |
Delegation Rules & Verification Protocol
- Delegation Rules: ์ด๋ค ์์ ์ ์ด๋ค ์์ด์ ํธ์๊ฒ ์์ํ ์ง์ ๊ท์น
- Verification Protocol: ์์ ์๋ฃ ์ ๊ฒ์ฆํด์ผ ํ ํญ๋ชฉ๋ค
- Continuation Check: ์์ ์ด ์ ๋ง ๋๋ฌ๋์ง ํ์ธํ๋ ์ต์ข ์ฒดํฌ
ํค์๋ ๊ฐ์ง โ OMC Hook ๋ฐฉ์ vs OMX AGENTS.md ๋ฐฉ์
์ด ์ฐจ์ด๋ ๋ ์์คํ ์ ์ํคํ ์ฒ์ ์ฑ๊ฒฉ์ ๊ฐ์ฅ ์ ๋ช ํ๊ฒ ๋๋ฌ๋ด๋ ์ง์ ์ด๋ค.
OMC ๋ฐฉ์: ๊ฒฐ์ ๋ก ์ (Deterministic) Hook ํ์ดํ๋ผ์ธ
graph LR UP["UserPromptSubmit ์ด๋ฒคํธ"] --> HJ["hooks.json"] HJ --> KD["keyword-detector.mjs"] KD --> STDIN["stdin: JSON"] STDIN --> KD KD --> STDOUT["stdout: JSON"] STDOUT --> CC["Claude Code"] style KD fill:#e8f0fe
keyword-detector.mjs๊ฐ stdin/stdout JSON ํ๋กํ ์ฝ๋ก ์ด๋ฒคํธ๋ฅผ ๊ฐ๋ก์ฑ- Hook ์คํฌ๋ฆฝํธ๊ฐ ์ง์ ํค์๋๋ฅผ ํ์ฑํ๊ณ , ๋งค์นญ ๊ฒฐ๊ณผ๋ฅผ LLM ์ธ๋ถ์์ ๊ฐ์ ์ฃผ์ โ LLM์ ํด์ ์ฌ๋ถ์ ๋ฌด๊ดํ๊ฒ ์คํ๋จ
- ๊ฒฐ์ ๋ก ์ : ํค์๋ ๋งค์นญ ์ ๋ฐ๋์ ์คํฌ์ด ์คํ๋จ (LLM ํ๋จ ๋ถ๊ฐ์ )
- ์ฅ์ : ํ๋ก๊ทธ๋๋ฐ ๋ก์ง์ผ๋ก ๋ณต์กํ ์กฐ๊ฑด ์ฒ๋ฆฌ ๊ฐ๋ฅ
- ๋จ์ : ๋ณ๋ ์คํฌ๋ฆฝํธ ์คํ ์ค๋ฒํค๋, ๋๋ฒ๊น ์ด๋ ค์
OMX ๋ฐฉ์: ํ๋ฅ ๋ก ์ (Probabilistic) AGENTS.md ๋ด์ฅ + LLM ์ง์ ํด์
graph LR AM["AGENTS.md<br>ํค์๋ ํ ์ด๋ธ (์ ์ ํ๋์ฝ๋ฉ)"] --> CX["Codex CLI (LLM)"] CX --> MATCH["ํค์๋ ๋งค์นญ"] MATCH --> SKILL["$skill โ SKILL.md ๋ก๋"] KR["keyword-registry.ts"] -.->|"import"| KD["keyword-detector.ts<br>(ํ๋ก๊ทธ๋๋ฐ์ 2์ฐจ ๊ฐ์ง)"] style CX fill:#fef7e0
- AGENTS.md์ ํค์๋ ๋งคํ ํ
์ด๋ธ์ด ๋งํฌ๋ค์ด ํ
์คํธ๋ก ์ ์ ํ๋์ฝ๋ฉ (
<keyword_detection>์น์ ) - Codex CLI์ LLM์ด ์ฌ์ฉ์ ์ ๋ ฅ์ ์ฝ๊ณ ์ง์ ํค์๋๋ฅผ ํด์ โ ๊ฐ์ ์ฃผ์ ์ฑ๋ ์์
keyword-registry.ts๋ AGENTS.md ์ฃผ์ ์ฉ์ด ์๋๋ผ,keyword-detector.ts(ํ๋ก๊ทธ๋๋ฐ์ 2์ฐจ ๊ฐ์ง)์ ํค์๋ ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ๋ ๋ชจ๋ (์์ค ํ์ธ:setup.ts์์ importํ์ง ์์)- ๋์๋ฌธ์ ๋ฌด์, ๋ฉ์์ง ์ด๋์์๋ ๋งค์นญ
- ํ๋ฅ ๋ก ์ : ํค์๋๊ฐ ์์ด๋ LLM์ด ๋ฌด์ํ๊ฑฐ๋ ๋ค๋ฅด๊ฒ ํด์ํ ์ ์์ (์จ๋ยท์ปจํ ์คํธ ํฌํยทํํ ๋ณํ ๋ฑ)
keyword-detector.ts / keyword-registry.ts โ ์คํ ์์ ๊ณผ ์ญํ (์์ค ํ์ธ)
์์ค ์ฃผ์ (src/hooks/keyword-detector.ts:1-12):
โIn OMC, this runs as a UserPromptSubmit hook that detects magic keywords and injects skill prompts via system-reminder.โ โIn OMX, this logic is embedded in the AGENTS.md orchestration brain, and can also be used by the notify hook for state tracking.โ โWhen Codex CLI adds pre-hook support, this module can be promoted to an external hook handler.โ
keyword-registry.ts โ ํค์๋ ์ ์ ๋ฐ์ดํฐ ๋ชจ๋
- ๋
๋ฆฝ ์คํ๋์ง ์๋๋ค.
keyword-detector.ts๊ฐ importํ๋ ๋ฐ์ดํฐ ๋ชจ๋์ผ ๋ฟ - 58๊ฐ ํค์๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ
{ keyword, skill, priority, guidance }ํํ๋ก export - AGENTS.md์ ์ฃผ์ ํ๋ ๋ฐ ์ฌ์ฉ๋์ง ์์ (setup.ts์์ importํ์ง ์์ โ ์์ค ํ์ธ ์๋ฃ)
keyword-detector.ts โ ์คํ ์์
OMX์ ์์ฒด Hook ์์คํ
(src/hooks/extensibility/)์ด ์ด๋ฒคํธ๋ฅผ ๋ฐํํ ๋ Control Plane์์ ํธ์ถ๋๋ค.
recordSkillActivation(): ์ฌ์ฉ์ ์ ๋ ฅ ํ ์คํธ์์ ํค์๋๋ฅผ ๊ฐ์งํ๊ณskill-active-state.json์ ์ํ ๊ธฐ๋ก- ์ด ์ํ ํ์ผ์
agents-overlay.ts๊ฐ ๋ค์ ์ธ์ ์ ์ค๋ฒ๋ ์ด ์์ฑ ์ ์ฐธ์กฐ - Codex CLI์๋
UserPromptSubmit๊ฐ์ ์ฌ์ฉ์ ์ ๋ ฅ ๊ฐ๋ก์ฑ๊ธฐ ์ด๋ฒคํธ๊ฐ ์์ผ๋ฏ๋ก, ํค์๋๋ฅผ ๊ฐ์งํด๋ LLM์ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ์ฃผ์ ํ ์ฑ๋์ด ์์
graph LR KR["keyword-registry.ts<br>(๋ฐ์ดํฐ ๋ชจ๋)"] -->|import| KD["keyword-detector.ts<br>(ํ๋ก๊ทธ๋๋ฐ์ ๊ฐ์ง)"] KD -->|recordSkillActivation()| SF["skill-active-state.json"] SF -->|๋ค์ ์ธ์ ์์ ์ฝ๊ธฐ| AO["agents-overlay.ts"] AM["AGENTS.md<br><keyword_detection> ์น์ "] -->|LLM์ด ์ง์ ํด์| CX["Codex CLI (LLM)"] style AM fill:#fef7e0 style KD fill:#e8f0fe
๊ฒฐ๋ก : AGENTS.md๊ฐ 1์ฐจ ๊ฐ์ง(ํ๋ฅ ๋ก ์ , LLM ํด์), keyword-detector.ts๋ ์ํ ์ถ์ ์ฉ 2์ฐจ ๋ณด์กฐ. OMX์ ๋ชจ๋ ์คํฌ ์คํ์ ๊ฒฐ๊ตญ LLM์ ํ๋จ์ ์์กด โ ์ ๊ณ์ธต์ด ํ๋ฅ ๋ก ์ .
Hook ํ์ฅ์ฑ โ .omx/hooks/*.mjs (์์ค ํ์ธ: src/hooks/extensibility/)
Codex CLI ์์ฒด์๋ Hook ์ด๋ฒคํธ ์์คํ
์ด ์๋ค. ํ์ง๋ง OMX๋ ์์ฒด Hook ์์คํ
์ ๋ฐ๋ฐ๋ฅ๋ถํฐ ๊ตฌํํ์ฌ .omx/hooks/*.mjs ํ๋ฌ๊ทธ์ธ์ ์ง์ํ๋ค.
์๋ ์๋ฆฌ โ Codex CLI์ Hook์ด ์๋๋ฐ ์ด๋ป๊ฒ?
OMX๋ ๋ ๊ฐ์ง ๊ฒฝ๋ก๋ก ์ด๋ฒคํธ๋ฅผ ๋ฐํํ๋ค:
- native ์ด๋ฒคํธ: OMX์ Control Plane(
src/cli/index.ts)์ด Codex CLI ํ๋ก์ธ์ค์ ์๋ช ์ฃผ๊ธฐ ์ง์ ์์ ์ฝ๋ ๋ ๋ฒจ๋ก ์ง์ ๋ฐํ (emitNativeHookEvent()ํธ์ถ). ํฐ๋ฏธ๋ ์ถ๋ ฅ์ ํ์ฑํ๋ ๊ฒ์ด ์๋. - derived ์ด๋ฒคํธ: ๋ณ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค(
scripts/hook-derived-watcher.js)๊ฐ Codex CLI์ rollout JSONL ํ์ผ(~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl)์ ํด๋ง(800ms ์ฃผ๊ธฐ)ํ์ฌ ํ์ฑยท์ถ๋ก . confidence ์ ์ ํฌํจ (0~1 ๋ฒ์).OMX_HOOK_DERIVED_SIGNALS=1ํ๊ฒฝ๋ณ์๋ก ํ์ฑํ.
graph LR subgraph Native ["Native ๊ฒฝ๋ก (์ฝ๋ ๋ ๋ฒจ ์ง์ ๋ฐํ)"] CLI["src/cli/index.ts"] -->|"emitNativeHookEvent()"| D["dispatcher.ts"] end subgraph Derived ["Derived ๊ฒฝ๋ก (rollout ํ์ผ ํด๋ง)"] CX["Codex CLI"] -->|"rollout-*.jsonl ๊ธฐ๋ก"| RF["~/.codex/sessions/.../rollout-*.jsonl"] RF -->|"800ms ํด๋ง"| W["hook-derived-watcher.js"] W -->|"ํ์ฑ + ์ถ๋ก (confidence)"| D end D -->|"child process spawn"| P1[".omx/hooks/plugin-a.mjs"] D -->|"child process spawn"| P2[".omx/hooks/plugin-b.mjs"] style CLI fill:#e8f0fe style W fill:#fef7e0
์ด๋ฒคํธ ๋ชจ๋ธ (์์ค: src/hooks/extensibility/types.ts, src/cli/index.ts, scripts/hook-derived-watcher.js)
types.ts์๋ 16๊ฐ ์ด๋ฒคํธ + open-ended ํ์ฅ(string & {})์ด ์ ์๋์ด ์๋ค. ํ์ง๋ง types.ts์ source ๋ถ๋ฅ์ ์ค์ ๋ฐํ ๋ฐฉ์์ด ๋ค๋ฅธ ๊ฒฝ์ฐ๊ฐ ์์ผ๋ฏ๋ก, ์์ค ์ฝ๋ ๊ธฐ์ค์ผ๋ก 3๊ฐ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฅํ๋ค.
Native ์ด๋ฒคํธ โ ์ค์ ๋ฐํ ํ์ธ (์์ค: src/cli/index.ts:1764)
emitNativeHookEvent() ํจ์๊ฐ ์ฝ๋ ๋ ๋ฒจ์์ ๊ฒฐ์ ๋ก ์ ์ผ๋ก ์ง์ ๋ฐํํ๋ค. ํ์
์๊ทธ๋์ฒ์ 4๊ฐ๊ฐ ์ ์๋์ด ์์ผ๋, ํ์ฌ ์ค์ ๋ฐํ ์ฝ๋๊ฐ ํ์ธ๋ ๊ฒ์ 2๊ฐ์ด๋ค.
| ์ด๋ฒคํธ | ๊ฐ์ง ๋ฐฉ์ | ๋ฐํ ์์น | ๋น๊ณ |
|---|---|---|---|
session-start | Codex CLI ํ๋ก์ธ์ค spawn ์งํ ์ง์ ๋ฐํ | index.ts:1323 | context์ project ์ ๋ณด ํฌํจ |
session-end | Codex CLI ํ๋ก์ธ์ค ์ข ๋ฃ ์ cleanup์์ ์ง์ ๋ฐํ | index.ts:1746 | exit code๋ก finished/failed status ๊ฒฐ์ ํ context์ ํฌํจ |
session-idle | ํ์ ์๊ทธ๋์ฒ์ ์ ์๋จ | index.ts:1766 (์๊ทธ๋์ฒ) | ๋ฐํ ์ฝ๋ ๋ฏธํ์ธ |
turn-complete | ํ์ ์๊ทธ๋์ฒ์ ์ ์๋จ | index.ts:1766 (์๊ทธ๋์ฒ) | ํ ์คํธ ์ฝ๋์์๋ง ์ฌ์ฉ, ๋ฐํ ์ฝ๋ ๋ฏธํ์ธ |
// src/cli/index.ts โ Native ์ด๋ฒคํธ ๋ฐํ ํจ์ (ํ์
์๊ทธ๋์ฒ์ 4๊ฐ ์ ์)
async function emitNativeHookEvent(
cwd: string,
event: 'session-start' | 'session-end' | 'session-idle' | 'turn-complete',
opts: { session_id?: string; context?: Record<string, unknown>; ... } = {},
): Promise<void> {
const payload = buildHookEvent(event, { source: 'native', context: opts.context || {} });
await dispatchHookEvent(payload, { cwd });
}
// session-start ๋ฐํ (index.ts:1323) โ Codex CLI spawn ์งํ
await emitNativeHookEvent(cwd, 'session-start', {
session_id: sessionId,
context: { project_path: cwd, project_name: basename(cwd), ... },
});
// session-end ๋ฐํ (index.ts:1746) โ Codex CLI ์ข
๋ฃ ์ cleanup
const normalizedEvent = process.exitCode && process.exitCode !== 0 ? 'failed' : 'finished';
await emitNativeHookEvent(cwd, 'session-end', {
session_id: sessionId,
context: { status: normalizedEvent, exit_code: process.exitCode, ... },
// โ finished/failed๋ ๋ณ๋ ์ด๋ฒคํธ๊ฐ ์๋๋ผ session-end์ context.status๋ก ํฌํจ
});์ฐธ๊ณ :
finished์failed๋ ๋ณ๋ ์ด๋ฒคํธ๋ก ๋ฐํ๋์ง ์๋๋ค.session-end์ด๋ฒคํธ์ context ๋ดstatusํ๋('finished'๋๋'failed')๋ก ํฌํจ๋๋ค.
Derived ์ด๋ฒคํธ โ ์ค์ ๋ฐํ ํ์ธ (์์ค: scripts/hook-derived-watcher.js)
hook-derived-watcher.js๊ฐ Codex CLI์ rollout JSONL ํ์ผ์ ํด๋งยทํ์ฑํ์ฌ ํ๋ฅ ๋ก ์ ์ผ๋ก ์ถ๋ก ๋ฐํํ๋ค. ๋ชจ๋ derived ์ด๋ฒคํธ๋ confidence ์ ์๋ฅผ ํฌํจํ๋ค.
| ์ด๋ฒคํธ | ๊ฐ์ง ๋ฐฉ์ | confidence | ๋น๊ณ |
|---|---|---|---|
pre-tool-use | rollout JSONL์์ tool_call_start ๋ฑ payload type ๋งค์นญ | 0.80 | types.ts: derived |
post-tool-use | rollout JSONL์์ tool_call_end ๋ฑ payload type ๋งค์นญ | 0.80 | types.ts: derived |
needs-input | assistant_message์์ ์ง๋ฌธ ํจํด ์ ๊ท์ ๋งค์นญ (?, can you, please provide ๋ฑ) | 0.55 | types.ts: derived. ๊ฐ์ฅ ๋ฎ์ confidence |
test-started | exec_command๊ฐ ํ
์คํธ ๋ช
๋ น์ด๋ก ๋ถ๋ฅ(classifyExecCommand)๋ ๋ | 0.92 | types.ts์์๋ native๋ก ์ ์๋๋ ์ค์ ๋ก๋ derived ๋ฐํ |
test-finished | ํ
์คํธ ๋ช
๋ น์ด ๊ฒฐ๊ณผ ์ฑ๊ณต ์ (result.success === true) | 0.95 | types.ts์์๋ native๋ก ์ ์๋๋ ์ค์ ๋ก๋ derived ๋ฐํ |
test-failed | ํ
์คํธ ๋ช
๋ น์ด ๊ฒฐ๊ณผ ์คํจ ์ (result.success === false) | 0.95 | types.ts์์๋ native๋ก ์ ์๋๋ ์ค์ ๋ก๋ derived ๋ฐํ |
pr-created | PR ์์ฑ ๋ช ๋ น์ด ๊ฒฐ๊ณผ์์ PR ๋ฒํธ/URL ๊ฐ์ง | 0.97 | types.ts์์๋ native๋ก ์ ์๋๋ ์ค์ ๋ก๋ derived ๋ฐํ |
// scripts/hook-derived-watcher.js โ Derived ์ด๋ฒคํธ์ ํต์ฌ ๊ฐ์ง ๋ก์ง
// 1. rollout JSONL ํ์ผ ํด๋ง (800ms ์ฃผ๊ธฐ)
const pollMs = 800;
async function pollFiles() {
for (const [path, meta] of fileState.entries()) {
const delta = content.slice(meta.offset); // ๋ง์ง๋ง ์ฝ์ ์์น๋ถํฐ ์ ๋ด์ฉ๋ง
for (const line of lines) { await processLine(meta, line); }
}
}
// 2. pre-tool-use / post-tool-use ๊ฐ์ง โ payload type ๋งค์นญ
function inferDerivedEvent(parsed, meta) {
if (['tool_call_start', 'tool_use_start'].includes(payloadType)) {
return { event: 'pre-tool-use', confidence: 0.8, source: 'derived' };
}
if (['tool_call_end', 'tool_use_end'].includes(payloadType)) {
return { event: 'post-tool-use', confidence: 0.8, source: 'derived' };
}
// 3. needs-input ๊ฐ์ง โ ์ง๋ฌธ ํจํด ์ ๊ท์ (๊ฐ์ฅ ๋ฎ์ confidence)
if (payloadType === 'assistant_message') {
const looksLikeQuestion = /\?|\b(can you|could you|please provide|need input)\b/i.test(message);
if (looksLikeQuestion) return { event: 'needs-input', confidence: 0.55, source: 'derived' };
}
}
// 4. test-started/finished/failed, pr-created ๊ฐ์ง โ exec_command ๊ฒฐ๊ณผ ๋ถ์
function inferOperationalCall(parsed, meta) {
if (payload.name === 'exec_command') {
const classified = classifyExecCommand(command); // 'test' | 'pr-create' | ...
// test ๋ช
๋ น์ด ์์ โ test-started (confidence 0.92)
// test ๊ฒฐ๊ณผ ์ฑ๊ณต โ test-finished (confidence 0.95)
// test ๊ฒฐ๊ณผ ์คํจ โ test-failed (confidence 0.95)
// PR ์์ฑ ๊ฒฐ๊ณผ โ pr-created (confidence 0.97)
}
}types.ts ๋ถ๋ฅ vs ์ค์ ๋ถ๋ฅ ๋ถ์ผ์น:
test-started,test-finished,test-failed,pr-created๋ types.ts์์ native๋ก ์ ์๋์ด ์์ง๋ง, ์ค์ ๋ก๋hook-derived-watcher.js์์buildDerivedHookEvent()๋ก ๋ฐํํ๋ค. ์ด๋ค์ rollout ํ์ผ์exec_command์ถ๋ ฅ์ ๋ถ์ํ์ฌ ์ถ๋ก ํ๊ธฐ ๋๋ฌธ์ ๊ตฌ์กฐ์ ์ผ๋ก derived์ ํด๋นํ๋ค.
ํ์ ์ ์๋ง ์กด์ฌ โ ๋ฐํ ๋ฏธํ์ธ
| ์ด๋ฒคํธ | types.ts ๋ถ๋ฅ | ๋น๊ณ |
|---|---|---|
blocked | native | ๋ฐํ ์ฝ๋ ๋ฏธํ์ธ. ์๋ฌ ํธ๋ค๋ง์์ ๋ฌธ์์ด๋ก๋ง ์ฌ์ฉ |
finished | native | ๋ณ๋ ์ด๋ฒคํธ ์๋. session-end์ context status๋ก ํฌํจ |
failed | native | ๋ณ๋ ์ด๋ฒคํธ ์๋. session-end์ context status๋ก ํฌํจ |
retry-needed | native | ๋ฐํ ์ฝ๋ ๋ฏธํ์ธ |
handoff-needed | native | ๋ฐํ ์ฝ๋ ๋ฏธํ์ธ |
ํ๋ฌ๊ทธ์ธ SDK (HookPluginSdk)
ํ๋ฌ๊ทธ์ธ์ onHookEvent(event, sdk) ํจ์๋ฅผ exportํ๋ฉฐ, SDK๋ก ๋ค์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ค:
| SDK ๋ฉ์๋ | ๊ธฐ๋ฅ |
|---|---|
sdk.tmux.sendKeys() | tmux pane์ ํค ์ ๋ ฅ ์ ์ก |
sdk.log.info/warn/error() | .omx/logs/์ ๋ก๊ทธ ๊ธฐ๋ก |
sdk.state.read/write/delete/all() | .omx/state/์ ์ํ ์ฝ๊ธฐ/์ฐ๊ธฐ |
ํ์ฑํ ๋ฐ ๋น๊ต
OMX_HOOK_PLUGINS=1ํ๊ฒฝ๋ณ์๋ก ํ์ฑํ (๊ธฐ๋ณธ ๋นํ์ฑํ).omx/hooks/๋๋ ํ ๋ฆฌ์.mjsํ์ผ๋ก ํ๋ฌ๊ทธ์ธ ์์ฑ- ํ๋ฌ๊ทธ์ธ์ child process๋ก ๊ฒฉ๋ฆฌ ์คํ (timeout ์ง์)
| ๋น๊ต | OMC Hook | OMX Hook |
|---|---|---|
| ๊ธฐ๋ฐ | Claude Code์ ๋นํธ์ธ Hook ์์คํ | OMX๊ฐ ์์ฒด ๊ตฌํํ Hook ์์คํ |
| ์ด๋ฒคํธ ์ | 21๊ฐ | 16๊ฐ ์ ์ (์ค์ ๋ฐํ: native 2๊ฐ + derived 7๊ฐ) |
| Native ๊ฐ์ง | Claude Code๊ฐ ๋ค์ดํฐ๋ธ๋ก ๋ฐํ | OMX ์ฝ๋๊ฐ ์๋ช
์ฃผ๊ธฐ ์ง์ ์์ ์ง์ ๋ฐํ (emitNativeHookEvent()) |
| Derived ๊ฐ์ง | ์์ (๋ชจ๋ ํ์ ์ ) | hook-derived-watcher.js๊ฐ rollout JSONL ํ์ผ ํด๋งยทํ์ฑ์ผ๋ก ์ถ๋ก (confidence ํฌํจ) |
| ํ์ฑํ | hooks.json์ ๋ฑ๋กํ๋ฉด ์๋ | ํ๊ฒฝ๋ณ์๋ก opt-in (OMX_HOOK_PLUGINS=1, derived๋ OMX_HOOK_DERIVED_SIGNALS=1) |
| ํ๋กํ ์ฝ | stdin/stdout JSON | child process spawn + SDK ์ฃผ์ |
| ์ญํ | ํค์๋ ๊ฐ์ง์ ์ฃผ์ ๋ฉ์ปค๋์ฆ (๊ฒฐ์ ๋ก ์ ) | ์ํ ์ถ์ ยท๋ชจ๋ํฐ๋ง ๋ณด์กฐ ๋ฉ์ปค๋์ฆ |
| ํต์ฌ ๊ฐ์ง | Hook ์คํฌ๋ฆฝํธ๊ฐ ๋ด๋น | AGENTS.md๊ฐ ๋ด๋น |
| ์คํ ๋ณด์ฅ | ๊ฒฐ์ ๋ก ์ โ LLM ์ธ๋ถ์์ ๊ฐ์ ์ฃผ์ | ํ๋ฅ ๋ก ์ โ LLM์ด ํ๋จํ์ฌ ์คํ |