plugins/mst/skills/discussion/SKILL.md
설정된 AI 팀원들이 합의에 도달할 때까지 반복 토론합니다. 사용자가 '토론', '합의', '디스커션'을 말하거나 /mst:discussion를 호출할 때 사용. 1회성 의견 수집은 /mst:ideation 사용.
npx skillsauth add myrtlepn/gran-maestro discussionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
설정된 AI 팀원들이 합의에 도달할 때까지 반복 토론합니다. PM(Claude)이 사회자 역할로 발산점을 식별하고 수렴을 유도합니다. Maestro 모드 활성 여부에 관계없이 사용 가능합니다.
| | ideation | discussion | |---|---|---| | 목적 | 다양한 관점 수집 (발산) | 합의 도달 (수렴) | | 라운드 | 1회 | N회 반복 | | 종료 조건 | PM 종합 완료 | 참여자 합의 또는 max rounds | | 출력 | synthesis.md | consensus.md |
<!-- @end-include -->경로 규칙 (MANDATORY): 이 스킬의 모든
.gran-maestro/경로는 절대경로로 사용합니다. 스킬 실행 시작 시PROJECT_ROOT를 취득하고, 이후 모든 경로에{PROJECT_ROOT}/접두사를 붙입니다.PROJECT_ROOT=$(pwd)
{PLUGIN_ROOT}는 이 스킬의 "Base directory"에서skills/{스킬명}/을 제거한 절대경로입니다. 상대경로(.claude/...)는 절대 사용하지 않습니다.
{PROJECT_ROOT}/.gran-maestro/discussion/ 디렉토리 존재 확인, 없으면 생성python3 {PLUGIN_ROOT}/scripts/mst.py counter next --type dsc → 출력 ID 사용{PROJECT_ROOT}/.gran-maestro/discussion/counter.json 파일 Readnext_id = last_id + 1{PROJECT_ROOT}/.gran-maestro/discussion/ 하위의 기존 DSC-* 디렉토리 스캔
b. {PROJECT_ROOT}/.gran-maestro/archive/ 내 discussion-* tar.gz 파일명에서 ID 범위 추출 (예: discussion-DSC001-DSC006-*.tar.gz → max 6)
c. 모든 소스에서 최대 번호 결정 → counter.json 생성: { "last_id": {max_number} }
d. next_id = last_id + 1counter.json 업데이트: { "last_id": {next_id} }{PROJECT_ROOT}/.gran-maestro/discussion/DSC-NNN/ 디렉토리 생성 (NNN은 3자리 zero-padded)session.json 작성:⏱️ 타임스탬프 취득 (MANDATORY):
TS=$(python3 {PLUGIN_ROOT}/scripts/mst.py timestamp now)위 명령 실패 시 폴백:python3 -c "from datetime import datetime, timezone; print(datetime.now(timezone.utc).isoformat())"출력값을created_at필드에 기입한다. 날짜만 기입 금지.
{
"id": "DSC-NNN",
"topic": "{사용자 주제}",
"source_ideation": "{IDN-NNN 또는 null}",
"focus": "{focus 또는 null}",
"status": "analyzing",
"max_rounds": "{Bash(python3 {PLUGIN_ROOT}/scripts/mst.py config get discussion.default_max_rounds) 출력값}",
"current_round": 0,
"created_at": "{TS — mst.py timestamp now 출력값}",
"dispatch_started_at": null,
"participants": [
{ "key": "architect(codex)", "role": "architect", "perspective": "", "type": "opinion", "status": "pending", "provider": "codex", "started_at": null, "completed_at": null },
{ "key": "ux(codex)", "role": "ux", "perspective": "", "type": "opinion", "status": "pending", "provider": "codex", "started_at": null, "completed_at": null },
{ "key": "security(codex)", "role": "security", "perspective": "", "type": "opinion", "status": "pending", "provider": "codex", "started_at": null, "completed_at": null },
{ "key": "architecture(gemini)", "role": "architecture", "perspective": "", "type": "opinion", "status": "pending", "provider": "gemini", "started_at": null, "completed_at": null },
{ "key": "cost(gemini)", "role": "cost", "perspective": "", "type": "opinion", "status": "pending", "provider": "gemini", "started_at": null, "completed_at": null },
{ "key": "risk(claude)", "role": "risk", "perspective": "", "type": "opinion", "status": "pending", "provider": "claude", "started_at": null, "completed_at": null }
],
"critics": {
"claude": { "status": "pending", "provider": "claude" }
},
"critic_count": 1,
"participant_config": { "codex": 3, "gemini": 2, "claude": 1 },
"rounds": []
}
participants는 config의 discussion.agents를 읽어 생성합니다.
{role}(provider) 형태{role}(provider) 형태 유지provider 필드 기록participants 키 없으면 기본값 { codex:1, gemini:1, claude:1 } 사용.
PM이 주제/포커스를 분석해 participants 수만큼 관점을 배정하고 critics를 결정합니다.
session.json에 participants, critics, critic_count, participant_config, status: "initializing" 기록.
- 백그라운드 작업 완료 시 사용자에게 확인 질문 금지
- 모든 단계는 사용자 입력 없이 자동 진행
- 모든 호출이 모두 완료되면 즉시 다음 step 진행
- Step 4e 종료 판단은 PM이 자율적으로 처리
- 최종 사용자 보고는 Step 6에서만
- ⚠️ Step 4c 건너뜀 금지: critic_count > 0이면 opinions 수집 후 반드시 Critic 평가 수행
shared-context.md는 단독 Write, 프롬프트 파일은 단일 combined 파일 Write → 스크립트 split 패턴을 사용합니다:
session.json, shared-context.md 작성은 기존대로 단일 응답 내 Write 처리prompts/combined-prompts.txt 1개에 ===SPLIT: {filename}=== 구분기호로 모두 포함python3 {PLUGIN_ROOT}/scripts/mst.py session split-prompts --dir {absolute_path}/rounds/NN/prompts 실행IDN-NNN 입력 시: ideation 의견 파일들을 rounds/00/{participant.key}.md로 복사 → Step 4 진입
새 주제인 경우:
Dispatch 프롬프트 조립 — feature flag 분기
config 확인:
python3 {PLUGIN_ROOT}/scripts/mst.py config get prompt_builder.enabled prompt_builder.fallback_on_error
shared-context.md 본문을 .gran-maestro/tmp/ctx-{session_id}.md로 Write (기존 shared-context.md와 동일 내용, tmp 복사본)dispatch-input.json을 아래 스키마로 Write:
{
"format": "mst.dispatch",
"schema_version": 1,
"common": {
"topic": "{DSC-NNN 주제}",
"constraints": ["..."],
"reference_context_file": ".gran-maestro/tmp/ctx-{session_id}.md"
},
"tasks": [
{"role": "{participant.key}", "angle": "{perspective}", "ask": "핵심 질문 1~3개 ≤200자"},
{"role": "{participant.key}", "angle": "{perspective}", "ask_file": ".gran-maestro/tmp/task-{role}-ask.md"}
]
}
format: "mst.dispatch", schema_version: 1common: topic, constraints[], reference_context_file: ".gran-maestro/tmp/ctx-{session_id}.md"tasks[]: 각 participant/critic마다 {role: "{participant.key}", angle: "{perspective}", ask: "...≤200자"} 또는 ask_file: "..."}.gran-maestro/tmp/task-{role}-ask.md로 Write 후 ask_file 경로 참조python3 {PLUGIN_ROOT}/scripts/mst.py prompt build \
--input {absolute_path}/dispatch-input.json \
--out-dir {absolute_path}/rounds/00/prompts \
--sid {session_id}
rounds/00/prompts/combined-prompts.txt를 기존대로 session split-prompts로 분할:
python3 {PLUGIN_ROOT}/scripts/mst.py session split-prompts --dir {absolute_path}/rounds/00/prompts
→ rounds/00/prompts/{participant.key}-prompt.md × N, rounds/00/prompts/critique-{criticKey}-prompt.md × M 자동 생성단일 응답에서 동시 Write 후 split 실행:
rounds/00/shared-context.md — 주제 배경 + 핵심 논점rounds/00/prompts/combined-prompts.txt — N+M개 프롬프트를 ===SPLIT: {filename}=== 구분기호로 구분하여 1개 파일에 모두 포함
(participant N개 + critic M개, 아래 포맷 그대로 적용)combined-prompts.txt Write 완료 직후:
python3 {PLUGIN_ROOT}/scripts/mst.py session split-prompts --dir {absolute_path}/rounds/00/prompts
→ rounds/00/prompts/{participant.key}-prompt.md × N, rounds/00/prompts/critique-{criticKey}-prompt.md × M 자동 생성
(a) 경로 실행 중 mst.py prompt build가 exit 2/3 등 실패 반환 시:
config.prompt_builder.fallback_on_error=false이면 repair 실패 시 워크플로우를 중단하고 사용자 에스컬레이션참고: mst.py prompt build는 오류 반환만 담당하며, repair 1회/fallback 전환은 본 스킬(discussion)의 책임이다.
이후 2번(participant Task 발송)부터는 기존 내용 그대로 진행.
개별 프롬프트 포맷 (Round 0):
# {Role} 관점 의견 요청 — DSC-NNN Round 0
## 공유 컨텍스트
{absolute_path}/rounds/00/shared-context.md 파일을 Read하세요.
## 당신의 역할
{perspective} 관점에서 분석합니다.
## 질문
{역할별 핵심 질문 1~3개}
## 출력 요구사항
- {absolute_path}/rounds/00/{participant.key}.md에 저장
- {response_char_limit}자 이내
Critic 프롬프트 템플릿 (Round 0):
# Critic 평가 요청 — {session_id} Round 0
## 대기 지시
다음 명령을 실행하고 결과를 기다리세요:
python3 {PLUGIN_ROOT}/scripts/mst.py wait-files {participants 순회 → {absolute_path}/rounds/00/{participant.key}.md 절대 경로 목록}
마지막 줄이 ALL_READY면 다음 단계를 수행합니다.
TIMEOUT이면 완료된 파일들만으로 진행합니다.
## 역할
비판적 시각에서 모든 의견의 허점, 엣지 케이스, 반론을 식별합니다.
## 출력 요구사항
- {absolute_path}/rounds/00/critique-{criticKey}.md에 저장
- {critique_char_limit}자 이내
participant Task() + critic Task() 동시 발송 (단일 응답):
모델 결정:
Bash(python3 {PLUGIN_ROOT}/scripts/mst.py config get discussion.agents.claude.tier models.providers.claude.default_tier)로 tier를 구한 뒤models.providers.claude[{tier}]로 resolve (opus / sonnet)
participant 발송 (participants 동적 순회):
provider: "codex":
Bash(
run_in_background: true,
command: "codex exec --full-auto -m $(python3 {PLUGIN_ROOT}/scripts/mst.py resolve-model codex discussion 2>/dev/null || echo \"gpt-5.3-codex\") -C $(pwd) \"$(cat {absolute_path}/rounds/00/prompts/{participant.key}-prompt.md)\" > {absolute_path}/rounds/00/{participant.key}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/rounds/00/{participant.key}.md; exit $EC"
)
provider: "gemini":
Bash(
run_in_background: true,
command: "gemini -p \"$(cat {absolute_path}/rounds/00/prompts/{participant.key}-prompt.md)\" --model {config.models.providers.gemini[discussion.agents.gemini.tier || default_tier]} --approval-mode yolo --sandbox=false > {absolute_path}/rounds/00/{participant.key}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/rounds/00/{participant.key}.md; exit $EC"
)
provider: "claude":
Task(
subagent_type: "general-purpose",
model: "{config.models.providers.claude[discussion.agents.claude.tier || default_tier]}",
run_in_background: true,
prompt: "{absolute_path}/rounds/00/prompts/{participant.key}-prompt.md 파일을 Read하고 지시에 따라 분석. 결과를 {absolute_path}/rounds/00/{participant.key}.md에 Write. 완료 후 '완료'"
)
critic 동시 발송 (critics 동적 순회):
provider: "codex":
Bash(
run_in_background: true,
command: "codex exec --full-auto -m $(python3 {PLUGIN_ROOT}/scripts/mst.py resolve-model codex discussion 2>/dev/null || echo \"gpt-5.3-codex\") -C $(pwd) \"$(cat {absolute_path}/rounds/00/prompts/critique-{criticKey}-prompt.md)\" > {absolute_path}/rounds/00/critique-{criticKey}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/rounds/00/critique-{criticKey}.md; exit $EC"
)
provider: "gemini":
Bash(
run_in_background: true,
command: "gemini -p \"$(cat {absolute_path}/rounds/00/prompts/critique-{criticKey}-prompt.md)\" --model {config.models.providers.gemini[discussion.agents.gemini.tier || default_tier]} --approval-mode yolo --sandbox=false > {absolute_path}/rounds/00/critique-{criticKey}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/rounds/00/critique-{criticKey}.md; exit $EC"
)
provider: "claude":
Task(
subagent_type: "general-purpose",
model: "{config.models.providers.claude[discussion.agents.claude.tier || default_tier]}",
run_in_background: true,
prompt: "{absolute_path}/rounds/00/prompts/critique-{criticKey}-prompt.md 파일을 Read하고 비판적 시각으로 분석. 결과를 {absolute_path}/rounds/00/critique-{criticKey}.md에 Write. 완료 후 '완료'"
)
진행 상황 출력 (모든 Task() dispatch 완료 직후):
의견 수집 중 ({session_id} Round 0)
─────────────────────────────
[→] {participant.role} ({participant.provider}) ← participants 배열 동적 순회
...
── 비평 ──
[→] critic: {criticKey} ({critic.provider}) ← critics 객체 동적 순회
─────────────────────────────
완료 알림을 기다리는 중...
── 비평 ── 섹션 전체 생략participants 배열, critics 객체를 각각 동적 순회 (고정 인원 표기 금지)각 호출은 Task(run_in_background: true)로 병렬 실행됩니다.
rounds/00/synthesis.md 생성: rounds/00/{participant.key}.md 순회 → templates/discussion-round-synthesis.md 템플릿 사용 → status: "debating", current_round: 0
critic_count >= 1이면: rounds/00 응답 기반으로 rounds/00/prompts/critique-{criticKey}-prompt.md 생성 → Step 4c와 동일 방식으로 rounds/00/critique-{criticKey}.md 저장. Step 4 미실행 시에도 Critic 평가 보장.
NOTE: "Step 4c와 동일 방식"은 Step 2 (R0) critic 발송 블록의 Bash 직접 호출 패턴을 가리킵니다.
provider: "codex"→Bash(codex exec ...),provider: "gemini"→Bash(gemini -p ...),provider: "claude"→Task(...)방식으로 dispatch하되, 경로는rounds/00/prompts/critique-{criticKey}-prompt.md→rounds/00/critique-{criticKey}.md를 사용합니다.
participants 순회 → rounds/00/{participant.key}.md 존재 여부 확인 (성공: "done", 실패: "failed")
session.json 단일 Write:
participants 상태 반영, rounds 배열에 { "round": 0, "status": "completed" } 추가, current_round: 0, status: "debating"이전 라운드 발산점 기반으로 단일 응답에서 Write 후 split 실행:
rounds/NN/shared-context.md — 이전 라운드 입장 요약 테이블 + 발산점 목록rounds/NN/prompts/combined-prompts.txt — N개 프롬프트를 ===SPLIT: {filename}=== 구분기호로 구분하여 1개 파일에 모두 포함combined-prompts.txt Write 완료 직후:
python3 {PLUGIN_ROOT}/scripts/mst.py session split-prompts --dir {absolute_path}/rounds/NN/prompts
→ rounds/NN/prompts/{participant.key}-prompt.md × N 자동 생성
Round N의 critic 프롬프트가 있는 경우 같은 combined 파일에 포함하여 함께 split
shared-context.md 구조 (Round N):
# DSC-NNN Round N — 공유 컨텍스트
## 이전 라운드 입장 요약
| 역할 | 핵심 주장 |
|------|----------|
| {role} ({provider}) | {1~2줄 요약} |
...
## 핵심 발산점
1. {발산점 1}
2. {발산점 2}
## 이번 라운드 목표
{PM이 수렴 방향 제시}
개별 프롬프트 포맷 (Round N):
# {Role} 반론 수용 요청 — DSC-NNN Round N
## 공유 컨텍스트
{absolute_path}/rounds/NN/shared-context.md 파일을 Read하세요.
## 당신의 역할
{role} 관점에서 응답합니다.
이전 라운드 당신의 핵심 입장: {1~2줄}
## 이번 라운드 질문
{역할에 맞춘 반론/수렴 질문 1~3개}
## 출력 요구사항
- {absolute_path}/rounds/NN/{participant.key}.md에 저장
- {response_char_limit}자 이내
단일 응답에서 participant 프롬프트 파일 + critic 프롬프트 파일을 함께 생성 후, participant Task() + critic Task() 동시 발송.
Critic 프롬프트 템플릿 (Round N):
# Critic 평가 요청 — {session_id} Round {N}
## 대기 지시
다음 명령을 실행하고 결과를 기다리세요:
python3 {PLUGIN_ROOT}/scripts/mst.py wait-files {participants 순회 → {absolute_path}/rounds/NN/{participant.key}.md 절대 경로 목록}
마지막 줄이 ALL_READY면 다음 단계를 수행합니다.
TIMEOUT이면 완료된 파일들만으로 진행합니다.
## 역할
비판적 시각에서 모든 의견의 허점, 엣지 케이스, 반론을 식별합니다.
## 출력 요구사항
- {absolute_path}/rounds/NN/critique-{criticKey}.md에 저장
- {critique_char_limit}자 이내
participant 발송 (participants 동적 순회):
provider: "codex":
Bash(
run_in_background: true,
command: "codex exec --full-auto -m $(python3 {PLUGIN_ROOT}/scripts/mst.py resolve-model codex discussion 2>/dev/null || echo \"gpt-5.3-codex\") -C $(pwd) \"$(cat {absolute_path}/rounds/NN/prompts/{participant.key}-prompt.md)\" > {absolute_path}/rounds/NN/{participant.key}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/rounds/NN/{participant.key}.md; exit $EC"
)
provider: "gemini":
Bash(
run_in_background: true,
command: "gemini -p \"$(cat {absolute_path}/rounds/NN/prompts/{participant.key}-prompt.md)\" --model {config.models.providers.gemini[discussion.agents.gemini.tier || default_tier]} --approval-mode yolo --sandbox=false > {absolute_path}/rounds/NN/{participant.key}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/rounds/NN/{participant.key}.md; exit $EC"
)
provider: "claude":
Task(
subagent_type: "general-purpose",
model: "{config.models.providers.claude[discussion.agents.claude.tier || default_tier]}",
run_in_background: true,
prompt: "{absolute_path}/rounds/NN/prompts/{participant.key}-prompt.md 파일을 Read하고 지시에 따라 분석. 결과를 {absolute_path}/rounds/NN/{participant.key}.md에 Write. 완료 후 '완료'"
)
critic 동시 발송 (critics 동적 순회):
provider: "codex":
Bash(
run_in_background: true,
command: "codex exec --full-auto -m $(python3 {PLUGIN_ROOT}/scripts/mst.py resolve-model codex discussion 2>/dev/null || echo \"gpt-5.3-codex\") -C $(pwd) \"$(cat {absolute_path}/rounds/NN/prompts/critique-{criticKey}-prompt.md)\" > {absolute_path}/rounds/NN/critique-{criticKey}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/rounds/NN/critique-{criticKey}.md; exit $EC"
)
provider: "gemini":
Bash(
run_in_background: true,
command: "gemini -p \"$(cat {absolute_path}/rounds/NN/prompts/critique-{criticKey}-prompt.md)\" --model {config.models.providers.gemini[discussion.agents.gemini.tier || default_tier]} --approval-mode yolo --sandbox=false > {absolute_path}/rounds/NN/critique-{criticKey}.md < /dev/null 2>&1; EC=$?; echo \"EXIT_CODE:$EC\" >> {absolute_path}/rounds/NN/critique-{criticKey}.md; exit $EC"
)
provider: "claude":
Task(
subagent_type: "general-purpose",
model: "{config.models.providers.claude[discussion.agents.claude.tier || default_tier]}",
run_in_background: true,
prompt: "{absolute_path}/rounds/NN/prompts/critique-{criticKey}-prompt.md 파일을 Read하고 비판적 시각으로 분석. 결과를 {absolute_path}/rounds/NN/critique-{criticKey}.md에 Write. 완료 후 '완료'"
)
진행 상황 출력 (모든 Task() dispatch 완료 직후):
토론 라운드 {N} ({session_id})
─────────────────────────────
[→] {participant.role} ({participant.provider}) ← participants 배열 동적 순회
...
── 비평 ──
[→] critic: {criticKey} ({critic.provider}) ← critics 객체 동적 순회
─────────────────────────────
완료 알림을 기다리는 중...
── 비평 ── 섹션 전체 생략participants 배열, critics 객체를 각각 동적 순회 (고정 인원 표기 금지)절대 건너뛰기 금지:
critic_count > 0이면 Step 4d로 진행하기 전critique-{criticKey}.md파일이 존재해야 한다.
critics 키 순회 → rounds/NN/critique-{criticKey}.md 존재 + 비어있지 않음: "done", 아니면: "failed".
실패 시 에러 처리는 기존 에러 처리 섹션 준수.
사전 조건:
critic_count > 0이면rounds/NN/critique-{criticKey}.md존재 필수. 없으면 Step 4c로 복귀.
rounds/{NN-1}/synthesis.md + rounds/NN/{participant.key}.md + rounds/NN/critique-{criticKey}.mdrounds/NN/synthesis.md (templates/discussion-round-synthesis.md 동적 표 사용)status, current_round 업데이트participants 순회 → rounds/NN/{participant.key}.md 존재 여부 (성공: "done", 실패: "failed")
critics 순회 → rounds/NN/critique-{criticKey}.md 존재 여부 (성공: "done", 실패: "failed")
session.json 단일 Write: participants/critics 상태 반영, rounds 배열에 { "round": N, "status": "completed" } 추가, current_round: N
PM이 합의 정도 판정: 기준 충족 또는 최대 라운드 도달 시 Step 5, 미충족 시 다음 라운드 수행.
최종 consensus.md 생성: participants 키/Provider 동적 나열, 미합의 사항 행 반복, 라운드 합의 이력 및 critic 기여 기록.
.gran-maestro/discussion/DSC-NNN/
├── session.json
├── rounds/
│ ├── 00/
│ │ ├── shared-context.md # 공유 배경 컨텍스트 (Step 2 병렬 Write)
│ │ ├── prompts/
│ │ │ ├── {participant.key}-prompt.md # 경량 프롬프트 (shared-context.md Read 지시 포함)
│ │ │ ├── critique-{criticKey}-prompt.md
│ │ │ └── synthesis-prompt.md
│ │ ├── {participant.key}.md
│ │ ├── critique-{criticKey}.md
│ │ └── synthesis.md
│ └── NN/
│ ├── shared-context.md # 이전 입장 요약 + 발산점 (Step 4a 병렬 Write)
│ ├── prompts/
│ │ ├── {participant.key}-prompt.md # 경량 프롬프트 (shared-context.md Read 지시 포함)
│ │ └── critique-{criticKey}-prompt.md
│ ├── {participant.key}.md
│ ├── critique-{criticKey}.md
│ └── synthesis.md
├── consensus.md
--focus {architecture|ux|performance|security|cost}: 분석 포커스 지정--max-rounds {N}: 최대 토론 라운드 지정총합 2~7명 규칙과 participants/critics 동적 배정은 ideation과 동일.
tools
Internal shared include material for Gran Maestro skills. This is not a user-invocable workflow.
development
화면 설계, 컴포넌트 구조, 인터랙션 흐름, 디자인 시스템을 설계하는 Design Wing 템플릿 스킬. PM Conductor가 변수를 치환하여 /mst:codex로 실행.
development
Stitch SDK를 사용해 UI 화면을 설계합니다. 명시적 디자인 요청, 새 화면 추가, 전체 디자인 변경 시 사용.
tools
Codex CLI 프로젝트에 oh-my-codex(OMX)를 설치·초기화·gitignore 등록·AGENTS.md 주입하는 4단계 자동화를 수행합니다. 사용자가 'OMX 설치', 'oh-my-codex 설정', '/mst:setup-omx'를 호출할 때 사용.