471 lines
22 KiB
Markdown
471 lines
22 KiB
Markdown
# 3-플랫폼 동기화 Phase 1 — commands Implementation Plan
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** Claude의 13개 슬래시 command(`.claude/commands/*.md`)를 Codex CLI **skills**(`.agents/skills/<cmd>/SKILL.md`)와 Antigravity CLI **workflows**(`.agents/workflows/<cmd>.md`)로 생성하는 기능을 `scripts/sync_automation.py` 에 `commands` 타깃으로 추가한다.
|
||
|
||
**Architecture:** Phase 0의 SSOT→생성 모델을 commands로 확장한다. SSOT = `.claude/commands/<cmd>.md`(frontmatter `description`+`argument-hint` + 본문). 생성기는 (1) frontmatter를 플랫폼별 헤더로 변환, (2) `$ARGUMENTS` 토큰을 자연어 각괄호 인자(`argument-hint` 값)로 치환, (3) 본문의 platform-neutral 절차는 그대로 보존, (4) codex skill / antigravity workflow 두 포맷으로 직렬화한다. command 본문은 agent 본문과 달리 Claude 전용 tool 표현(`Read tool` 등)을 쓰지 않고 절차적 prose + shell + 서브에이전트 이름(Phase 0에서 3 플랫폼에 모두 포팅됨)만 참조하므로 기계 변환이 충분하다.
|
||
|
||
**Tech Stack:** Python 3.12 (stdlib), pytest (venv: `/home/donghyeon/dev/llm-wiki-private/.venv/bin/python`).
|
||
|
||
---
|
||
|
||
## 배경 / 확정된 포맷 사실 (공식문서 + 리서치)
|
||
|
||
- **Codex skills** (`developers.openai.com/codex/skills`): 디스커버리 `<repo>/.agents/skills/<name>/SKILL.md`(repo 커밋). frontmatter 필수 2필드 `name`(폴더명과 일치 권장) + `description`(언제 발동). **인자 placeholder 없음 — 자연어로 전달**(`$ARGUMENTS`/`$1` 미지원). `/skills` picker 또는 `$name` 멘션으로 명시 호출 + description 의미 매칭.
|
||
- **Antigravity workflows** (Google Codelabs / atamel.dev): `<repo>/.agents/workflows/<name>.md`, frontmatter **`description`만**(name=파일명), 본문은 prose 지시, 인자는 `<idea>` 식 각괄호 prose(placeholder 없음), `/<name> <args>` 호출.
|
||
- Codelab 실제 예시(verbatim):
|
||
```
|
||
---
|
||
description: Start the Autonomous AI Developer Pipeline sequence with a new idea
|
||
---
|
||
|
||
When the user types `/startcycle <idea>`, orchestrate the development process ...
|
||
```
|
||
- **경로 규약 결정**: 이 repo는 이미 `.agents/`(복수) 규약(`.agents/agents/`, `.agents/hooks.json`)을 쓰고 antigravity가 그것을 로드 중 → **antigravity workflows도 `.agents/workflows/`(복수)** 로 통일. codex skills는 공식 고정 경로 `.agents/skills/`.
|
||
- **알려진 충돌(미해결, 경험적 확인 필요)**: 일부 antigravity 빌드는 `.agents/skills/`도 skill로 읽어, codex command-skill이 antigravity에 semantic-trigger skill로 *이중 등록*될 수 있음(workflow + skill). 공식문서로 확정 불가 → **Task 1에서 실제 설치된 CLI로 경험적 확인** 후 필요 시 완화.
|
||
|
||
### 13개 command (SSOT: `.claude/commands/*.md`)
|
||
`blogify` · `branch` · `branch-spec` · `coverage` · `daily` · `depth` · `ingest` · `interviewize` · `lint` · `migrate-claims` · `projectize` · `query` · `tag`
|
||
|
||
frontmatter 공통: `description:` + `argument-hint:`. 본문은 `$ARGUMENTS` 토큰 + 절차(`## 작업 절차`) + 규칙. 일부는 `.claude/hooks/wiki_structure_lint.py`(실제 repo 스크립트, 크로스플랫폼 실행 가능 — 유지)와 포팅된 서브에이전트(`branch-depth-auditor` 등) 참조.
|
||
|
||
---
|
||
|
||
## File Structure
|
||
|
||
- Modify: `scripts/sync_automation.py` — `COMMAND_NAMES` 리스트, command frontmatter 파서 재사용(`parse_frontmatter`), `transform_command_body`, `render_codex_skill`, `render_antigravity_workflow`, `generate_command_one`, `main()` 의 `target` choices에 `commands` 추가.
|
||
- Modify: `scripts/test_sync_automation.py` — command 변환 단위 테스트.
|
||
- Create (생성물): `.agents/skills/<cmd>/SKILL.md` ×13 (codex), `.agents/workflows/<cmd>.md` ×13 (antigravity).
|
||
- Create: `docs/superpowers/notes/2026-06-04-phase1-empirical-format-check.md` — Task 1 경험적 확인 결과 기록.
|
||
- Modify (말미): `CLAUDE.md` §2 표 + `.codex/agents/README.md` — commands→skills/workflows 매핑 1단락.
|
||
|
||
> 책임 경계: 생성기는 frontmatter 변환 + `$ARGUMENTS` 치환 + 포맷 직렬화만. 본문 절차 prose는 platform-neutral이므로 보존. codex skill 본문에서 antigravity 전용 표기를 만들지 않고, antigravity workflow 본문에서 codex 전용 표기를 만들지 않는다(생성기가 플랫폼별로 분기).
|
||
|
||
---
|
||
|
||
## Task 1: 경험적 포맷·충돌 확인 + 결정 잠금
|
||
|
||
**Files:**
|
||
- Create: `docs/superpowers/notes/2026-04-phase1-empirical-format-check.md` (디렉토리 없으면 생성)
|
||
|
||
> 목적: 공식문서가 확정 못한 두 가지를 실제 설치된 CLI로 확인하고, 생성기 타깃 경로/인자 규약을 잠근다. CLI가 없으면 "가정 + 보류" 로 명시 기록(생성물은 가정대로 진행, 추후 검증).
|
||
|
||
- [ ] **Step 1: 설치 여부 확인**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
command -v codex && codex --version 2>&1 | head -1 || echo "codex: NOT INSTALLED"
|
||
ls -d ~/.gemini/antigravity-cli 2>/dev/null && echo "antigravity-cli home present" || echo "antigravity: home absent"
|
||
command -v agy 2>&1 || echo "agy (antigravity CLI) not on PATH"
|
||
```
|
||
|
||
- [ ] **Step 2: (codex 있으면) skill 디스커버리 경로 확인**
|
||
|
||
scratch skill을 만들어 codex가 `.agents/skills/`를 읽는지 확인:
|
||
```bash
|
||
mkdir -p /tmp/codex-skill-probe/.agents/skills/probe-skill
|
||
printf -- '---\nname: probe-skill\ndescription: probe codex skill discovery\n---\nprobe body\n' > /tmp/codex-skill-probe/.agents/skills/probe-skill/SKILL.md
|
||
# codex의 skills 목록 확인 (codex 설치 시): 예) `codex` TUI에서 /skills, 또는 가능한 CLI 서브커맨드
|
||
codex --help 2>&1 | grep -iE "skill|prompt" || echo "no skill subcommand surfaced in --help"
|
||
```
|
||
결과(읽힘/안읽힘/불명)를 노트에 기록.
|
||
|
||
- [ ] **Step 3: (antigravity 있으면) `.agents/skills/` 이중 로드 여부 확인**
|
||
|
||
antigravity가 `.agents/skills/`를 skill로 읽는지(=codex command-skill 이중 등록 위험) 실제 빌드에서 확인. 가능한 방법: antigravity CLI의 skill/workflow 목록 출력 커맨드, 또는 `~/.gemini/antigravity-cli/` 로그/registry 확인. 결과를 노트에 기록.
|
||
|
||
- [ ] **Step 4: 결정 기록**
|
||
|
||
노트에 다음을 표로 확정(경험 결과 또는 "UNVERIFIED — 가정"):
|
||
| 항목 | 결정 | 근거 |
|
||
|---|---|---|
|
||
| codex skill 경로 | `.agents/skills/<cmd>/SKILL.md` | 공식 디스커버리 경로 |
|
||
| antigravity workflow 경로 | `.agents/workflows/<cmd>.md` | repo `.agents/` 복수 규약 일치 |
|
||
| `$ARGUMENTS` 매핑 | argument-hint 각괄호 prose로 치환 | 양 플랫폼 placeholder 미지원 |
|
||
| `.agents/skills/` antigravity 이중로드 | {{읽음→완화 필요 / 안읽음→무관 / UNVERIFIED}} | Step 3 결과 |
|
||
|
||
- [ ] **Step 5: Commit**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
git add docs/superpowers/notes/
|
||
git commit -m "docs(phase1): empirical format + skills-collision check, lock target paths"
|
||
```
|
||
|
||
---
|
||
|
||
## Task 2: command 파싱 + skill/workflow 직렬화 (순수 함수, TDD)
|
||
|
||
**Files:**
|
||
- Modify: `scripts/sync_automation.py`
|
||
- Test: `scripts/test_sync_automation.py`
|
||
|
||
- [ ] **Step 1: Write the failing test**
|
||
|
||
```python
|
||
# append to scripts/test_sync_automation.py
|
||
|
||
_SAMPLE_CMD = (
|
||
"---\n"
|
||
"description: 브랜치 노트의 구현 착수 깊이 점검\n"
|
||
"argument-hint: <브랜치 이름>\n"
|
||
"---\n\n"
|
||
"브랜치 노트 1개의 깊이를 점검합니다.\n\n"
|
||
"**브랜치 이름:** $ARGUMENTS\n\n"
|
||
"## 작업 절차\n1. `branch-depth-auditor` 서브에이전트를 디스패치한다.\n"
|
||
)
|
||
|
||
|
||
def test_transform_command_body_replaces_arguments():
|
||
out = s.transform_command_body(_body_of(_SAMPLE_CMD), "<브랜치 이름>")
|
||
assert "$ARGUMENTS" not in out
|
||
assert "<브랜치 이름>" in out
|
||
# platform-neutral 절차/에이전트 참조는 보존
|
||
assert "branch-depth-auditor 서브에이전트를 디스패치" in out
|
||
|
||
|
||
def test_render_codex_skill_frontmatter():
|
||
out = s.render_codex_skill(
|
||
name="depth",
|
||
description="브랜치 노트의 구현 착수 깊이 점검",
|
||
arg_hint="<브랜치 이름>",
|
||
body="**브랜치 이름:** <브랜치 이름>\n\n## 작업 절차\n1. ...\n",
|
||
)
|
||
fm, body = s.parse_frontmatter(out)
|
||
assert fm["name"] == "depth"
|
||
assert fm["description"] # non-empty
|
||
assert "$ARGUMENTS" not in body
|
||
assert "## 작업 절차" in body
|
||
|
||
|
||
def test_render_antigravity_workflow_frontmatter_and_invocation():
|
||
out = s.render_antigravity_workflow(
|
||
name="depth",
|
||
description="브랜치 노트의 구현 착수 깊이 점검",
|
||
arg_hint="<브랜치 이름>",
|
||
body="## 작업 절차\n1. ...\n",
|
||
)
|
||
fm, body = s.parse_frontmatter(out)
|
||
assert set(fm.keys()) == {"description"} # name comes from filename, not frontmatter
|
||
# 호출 안내가 본문 상단에 있어야 함 (Codelab 패턴)
|
||
assert "/depth <브랜치 이름>" in body
|
||
assert "## 작업 절차" in body
|
||
```
|
||
|
||
(헬퍼 `_body_of` 는 테스트 상단에 추가: `def _body_of(md): return s.parse_frontmatter(md)[1]`.)
|
||
|
||
- [ ] **Step 2: Run test to verify it fails**
|
||
|
||
Run: `cd /home/donghyeon/dev/llm-wiki-private && .venv/bin/python -m pytest scripts/test_sync_automation.py -k "command or codex_skill or workflow" -v`
|
||
Expected: FAIL with `AttributeError: ... 'transform_command_body'`.
|
||
|
||
- [ ] **Step 3: Write minimal implementation**
|
||
|
||
```python
|
||
# add near COMMAND-related code in sync_automation.py
|
||
|
||
COMMAND_NAMES = [
|
||
"blogify", "branch", "branch-spec", "coverage", "daily", "depth",
|
||
"ingest", "interviewize", "lint", "migrate-claims", "projectize",
|
||
"query", "tag",
|
||
]
|
||
|
||
CLAUDE_COMMANDS = REPO / ".claude" / "commands"
|
||
CODEX_SKILLS = REPO / ".agents" / "skills"
|
||
ANTIGRAV_WORKFLOWS = REPO / ".agents" / "workflows"
|
||
|
||
|
||
def transform_command_body(body: str, arg_hint: str) -> str:
|
||
# Neither Codex skills nor Antigravity workflows support a $ARGUMENTS
|
||
# placeholder; both take arguments as natural language. Replace the token
|
||
# with the argument-hint's angle-bracket prose so the body still reads well.
|
||
return body.replace("$ARGUMENTS", arg_hint)
|
||
|
||
|
||
def render_codex_skill(name: str, description: str, arg_hint: str, body: str) -> str:
|
||
# description drives implicit trigger; fold in the arg hint for clarity.
|
||
desc = f"{description} (입력: {arg_hint})"
|
||
return (
|
||
"---\n"
|
||
f"name: {name}\n"
|
||
f"description: {desc}\n"
|
||
"---\n\n"
|
||
f"{body.rstrip()}\n"
|
||
)
|
||
|
||
|
||
def render_antigravity_workflow(name: str, description: str, arg_hint: str, body: str) -> str:
|
||
invocation = f"사용자가 `/{name} {arg_hint}` 를 입력하면 아래 절차를 수행한다.\n\n"
|
||
return (
|
||
"---\n"
|
||
f"description: {description}\n"
|
||
"---\n\n"
|
||
f"{invocation}{body.rstrip()}\n"
|
||
)
|
||
```
|
||
|
||
- [ ] **Step 4: Run test to verify it passes**
|
||
|
||
Run: `cd /home/donghyeon/dev/llm-wiki-private && .venv/bin/python -m pytest scripts/test_sync_automation.py -k "command or codex_skill or workflow" -v`
|
||
Expected: PASS.
|
||
|
||
- [ ] **Step 5: Commit**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
git add scripts/sync_automation.py scripts/test_sync_automation.py
|
||
git commit -m "feat(sync): command body transform + codex skill / antigravity workflow renderers"
|
||
```
|
||
|
||
---
|
||
|
||
## Task 3: command 로더 + CLI `commands` 타깃 (TDD)
|
||
|
||
**Files:**
|
||
- Modify: `scripts/sync_automation.py`
|
||
- Test: `scripts/test_sync_automation.py`
|
||
|
||
- [ ] **Step 1: Write the failing test**
|
||
|
||
```python
|
||
def test_load_command_inputs_for_existing_command():
|
||
ci = s.load_command_inputs("depth")
|
||
assert ci.name == "depth"
|
||
assert ci.description
|
||
assert ci.arg_hint.startswith("<") or "--" in ci.arg_hint
|
||
assert "$ARGUMENTS" in ci.body or "작업 절차" in ci.body # raw body still has token
|
||
|
||
|
||
def test_generate_command_writes_both(tmp_path, monkeypatch):
|
||
monkeypatch.setattr(s, "CODEX_SKILLS", tmp_path / "skills")
|
||
monkeypatch.setattr(s, "ANTIGRAV_WORKFLOWS", tmp_path / "workflows")
|
||
s.generate_command_one("depth", check=False)
|
||
skill = tmp_path / "skills" / "depth" / "SKILL.md"
|
||
wf = tmp_path / "workflows" / "depth.md"
|
||
assert skill.exists() and wf.exists()
|
||
sfm, sbody = s.parse_frontmatter(skill.read_text())
|
||
assert sfm["name"] == "depth" and "$ARGUMENTS" not in sbody
|
||
wfm, wbody = s.parse_frontmatter(wf.read_text())
|
||
assert "/depth" in wbody and "$ARGUMENTS" not in wbody
|
||
|
||
|
||
def test_main_commands_target_check_is_clean_after_generate():
|
||
# after generation (Task 4), --check must be drift-free
|
||
rc = s.main(["commands", "--check"])
|
||
assert rc == 0
|
||
```
|
||
|
||
> 마지막 테스트는 Task 4 생성 이후에만 통과한다. Task 3 단계에서는 앞 두 테스트만 대상으로 실행하고, 세 번째는 Task 4 검증에서 green 확인.
|
||
|
||
- [ ] **Step 2: Run test to verify it fails**
|
||
|
||
Run: `cd /home/donghyeon/dev/llm-wiki-private && .venv/bin/python -m pytest scripts/test_sync_automation.py -k "load_command or generate_command" -v`
|
||
Expected: FAIL with `AttributeError: ... 'load_command_inputs'`.
|
||
|
||
- [ ] **Step 3: Write minimal implementation**
|
||
|
||
```python
|
||
@dataclass
|
||
class CommandInputs:
|
||
name: str
|
||
description: str
|
||
arg_hint: str
|
||
body: str
|
||
|
||
|
||
def load_command_inputs(name: str) -> CommandInputs:
|
||
fm, body = parse_frontmatter((CLAUDE_COMMANDS / f"{name}.md").read_text())
|
||
return CommandInputs(
|
||
name=name,
|
||
description=fm.get("description", "").strip(),
|
||
arg_hint=fm.get("argument-hint", "").strip(),
|
||
body=body,
|
||
)
|
||
|
||
|
||
def generate_command_one(name: str, check: bool, drift: list[str] | None = None) -> None:
|
||
drift = drift if drift is not None else []
|
||
ci = load_command_inputs(name)
|
||
tbody = transform_command_body(ci.body, ci.arg_hint)
|
||
skill_text = render_codex_skill(ci.name, ci.description, ci.arg_hint, tbody)
|
||
wf_text = render_antigravity_workflow(ci.name, ci.description, ci.arg_hint, tbody)
|
||
_write_or_check(CODEX_SKILLS / name / "SKILL.md", skill_text, check, drift)
|
||
_write_or_check(ANTIGRAV_WORKFLOWS / f"{name}.md", wf_text, check, drift)
|
||
```
|
||
|
||
그리고 `main()` 을 확장: `target` choices에 `commands` 추가하고 분기.
|
||
|
||
```python
|
||
def main(argv: list[str] | None = None) -> int:
|
||
ap = argparse.ArgumentParser(description="Sync Claude agents/commands -> Codex/Antigravity native files")
|
||
ap.add_argument("target", choices=["agents", "commands"], help="what to sync")
|
||
ap.add_argument("--check", action="store_true", help="fail (exit 2) if outputs drift from SSOT")
|
||
ap.add_argument("--only", help="single name (default: all)")
|
||
args = ap.parse_args(argv)
|
||
|
||
if args.target == "agents":
|
||
names = [args.only] if args.only else AGENT_NAMES
|
||
gen = generate_one
|
||
label = "agents (codex .toml + antigravity agent.json)"
|
||
else:
|
||
names = [args.only] if args.only else COMMAND_NAMES
|
||
gen = generate_command_one
|
||
label = "commands (codex skill + antigravity workflow)"
|
||
|
||
drift: list[str] = []
|
||
for name in names:
|
||
try:
|
||
gen(name, check=args.check, drift=drift)
|
||
except FileNotFoundError as e:
|
||
print(f"ERROR: missing SSOT for '{name}': {e.filename}", file=sys.stderr)
|
||
return 1
|
||
if args.check and drift:
|
||
print("DRIFT detected in:\n " + "\n ".join(drift), file=sys.stderr)
|
||
return 2
|
||
action = "checked" if args.check else "generated"
|
||
print(f"{action} {len(names)} {label}")
|
||
return 0
|
||
```
|
||
|
||
- [ ] **Step 4: Run test to verify it passes**
|
||
|
||
Run: `cd /home/donghyeon/dev/llm-wiki-private && .venv/bin/python -m pytest scripts/test_sync_automation.py -k "load_command or generate_command" -v`
|
||
Expected: PASS. Also run the FULL suite to confirm the `main()` refactor didn't break agents:
|
||
Run: `.venv/bin/python -m pytest scripts/test_sync_automation.py -q`
|
||
Expected: all green. Then sanity: `python3 scripts/sync_automation.py agents --check` still exits 0.
|
||
|
||
- [ ] **Step 5: Commit**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
git add scripts/sync_automation.py scripts/test_sync_automation.py
|
||
git commit -m "feat(sync): commands target — load + generate codex skills / antigravity workflows"
|
||
```
|
||
|
||
---
|
||
|
||
## Task 4: 13개 command 전체 생성 + 검증 + drift-0
|
||
|
||
**Files:**
|
||
- Generate: `.agents/skills/<cmd>/SKILL.md` ×13, `.agents/workflows/<cmd>.md` ×13
|
||
|
||
- [ ] **Step 1: 생성 + 검증**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
python3 scripts/sync_automation.py commands
|
||
echo "--- counts ---"
|
||
echo "skills: $(ls .agents/skills/*/SKILL.md | wc -l) | workflows: $(ls .agents/workflows/*.md | wc -l)"
|
||
echo "--- validate ---"
|
||
.venv/bin/python -c "
|
||
import sys; sys.path.insert(0,'scripts'); import sync_automation as s
|
||
for n in s.COMMAND_NAMES:
|
||
sfm,sbody=s.parse_frontmatter(open(f'.agents/skills/{n}/SKILL.md').read())
|
||
assert sfm['name']==n and sfm['description'] and '\$ARGUMENTS' not in sbody, n
|
||
wfm,wbody=s.parse_frontmatter(open(f'.agents/workflows/{n}.md').read())
|
||
assert 'description' in wfm and f'/{n}' in wbody and '\$ARGUMENTS' not in wbody, n
|
||
print('all 13 commands ok (skill name+desc, workflow desc+invocation, no \$ARGUMENTS)')
|
||
"
|
||
echo "--- no {{ }} placeholders leaked into workflows (antigravity G3) ---"
|
||
! grep -l '{{' .agents/workflows/*.md || echo "WARNING: {{ }} found"
|
||
```
|
||
Expected: `skills: 13 | workflows: 13`, validation ok, no `{{` warning.
|
||
|
||
- [ ] **Step 2: drift-0**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
python3 scripts/sync_automation.py commands --check; echo "exit=$?"
|
||
```
|
||
Expected: `checked 13 commands ...` + `exit=0`.
|
||
|
||
- [ ] **Step 3: 전체 테스트(세 번째 main commands check 테스트 포함)**
|
||
|
||
Run: `.venv/bin/python -m pytest scripts/test_sync_automation.py -q`
|
||
Expected: all green.
|
||
|
||
- [ ] **Step 4: Commit**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
git add .agents/skills/ .agents/workflows/
|
||
git commit -m "feat(sync): generate 13 commands as codex skills + antigravity workflows"
|
||
```
|
||
|
||
---
|
||
|
||
## Task 5: 대표 command 실호출 스모크 (CLI 있으면)
|
||
|
||
> Phase 0 agents와 달리 commands는 사용자가 실제로 호출하는 표면이므로, 설치된 CLI에서 1~2개를 실호출해 형식이 맞는지 확인한다. CLI 미설치면 SKIP + 노트 기록.
|
||
|
||
- [ ] **Step 1: codex skill 인식 확인 (codex 있으면)**
|
||
|
||
`.agents/skills/depth/SKILL.md` 가 codex의 `/skills` 또는 `$depth` 로 인식되는지 확인. 인식 안 되면 frontmatter/경로를 Task 1 노트와 대조해 진단.
|
||
|
||
- [ ] **Step 2: antigravity workflow 인식 확인 (antigravity 있으면)**
|
||
|
||
`.agents/workflows/depth.md` 가 antigravity에서 `/depth` 로 등록되는지 확인. 동시에 Task 1의 이중로드 가설(코덱스 skill이 antigravity에 새는지)을 `/skills` 목록으로 재확인.
|
||
|
||
- [ ] **Step 3: 결과를 Task 1 노트에 추가 기록 + (필요 시) 완화**
|
||
|
||
- 이중로드가 실제로 발생하고 바람직하지 않으면: 완화안을 노트에 적고 사용자에게 에스컬레이션(예: codex skill만 두고 antigravity는 workflow만 쓰도록 build 설정, 또는 경로 분리). **이 단계에서 임의로 큰 구조 변경하지 말 것** — 결과만 보고.
|
||
|
||
- [ ] **Step 4: Commit (노트 갱신 시)**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
git add docs/superpowers/notes/
|
||
git commit -m "docs(phase1): empirical smoke results for codex skills / antigravity workflows"
|
||
```
|
||
|
||
---
|
||
|
||
## Task 6: 문서 갱신 (commands→skills/workflows 매핑)
|
||
|
||
**Files:**
|
||
- Modify: `CLAUDE.md` (§2 디렉터리 역할 표 또는 자동화 섹션)
|
||
- Modify: `.codex/agents/README.md`
|
||
|
||
- [ ] **Step 1: CLAUDE.md 에 1단락**
|
||
|
||
§2의 자동화 목록에 codex/antigravity의 command 등가물을 명시:
|
||
- Codex: `.agents/skills/<cmd>/SKILL.md` (13개, `$cmd` 호출), 생성 `python3 scripts/sync_automation.py commands`.
|
||
- Antigravity: `.agents/workflows/<cmd>.md` (13개, `/cmd` 호출).
|
||
- 인자는 placeholder 없이 자연어(각괄호 prose).
|
||
|
||
- [ ] **Step 2: `.codex/agents/README.md` 의 "Native generation" 노트에 commands 줄 추가**
|
||
|
||
`sync_automation.py commands` 로 13개 command가 `.agents/skills/`(codex) + `.agents/workflows/`(antigravity)에 생성됨을 1줄 추가.
|
||
|
||
- [ ] **Step 3: 검증 + Commit**
|
||
|
||
```bash
|
||
cd /home/donghyeon/dev/llm-wiki-private
|
||
grep -c "sync_automation.py commands" CLAUDE.md .codex/agents/README.md
|
||
git add CLAUDE.md .codex/agents/README.md
|
||
git commit -m "docs(sync): document commands -> codex skills + antigravity workflows"
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 1 완료 기준 (Definition of Done)
|
||
|
||
- `sync_automation.py commands` 타깃 동작 + 테스트 green.
|
||
- `.agents/skills/<cmd>/SKILL.md` 13개 + `.agents/workflows/<cmd>.md` 13개 생성·검증.
|
||
- `python3 scripts/sync_automation.py commands --check` exit 0 (drift 0).
|
||
- `$ARGUMENTS` 토큰이 생성물에 0개, antigravity workflow에 `{{ }}` 0개.
|
||
- Task 1/5 경험적 확인 결과가 노트에 기록(또는 CLI 미설치 시 가정으로 명시).
|
||
- CLAUDE.md + codex README에 매핑 문서화.
|
||
|
||
이후: **Phase 2**(hooks → `.codex/hooks.json`, `AGENTS.md`, CLAUDE.md의 구식 codex "수동 cat" 서술 정리 — line 76)는 별도 plan.
|
||
|
||
---
|
||
|
||
## Self-Review (작성자 체크)
|
||
|
||
- **Spec coverage**: 설계 §4 Phase 1(commands → codex skills + antigravity workflows, 생성기 commands 타깃 확장)의 모든 요소가 Task 2~4에 매핑. 설계 §6 리스크의 `.agents/skills/` 충돌은 Task 1/5 경험적 확인으로 처리.
|
||
- **Placeholder scan**: 코드 스텝은 실제 코드 포함. Task 1/5는 경험적 절차라 결과가 환경 의존 — 명령 + 기록 표 + "UNVERIFIED 시 가정 명시" 로 결정론화.
|
||
- **Type consistency**: `transform_command_body(body, arg_hint)`, `render_codex_skill(name,description,arg_hint,body)`, `render_antigravity_workflow(name,description,arg_hint,body)`, `CommandInputs`, `load_command_inputs(name)`, `generate_command_one(name,check,drift)` — 전 Task 일관. `_write_or_check`/`parse_frontmatter`는 Phase 0 함수 재사용.
|
||
- **알려진 한계**: command 본문이 platform-neutral하다는 가정에 의존(실측: `.claude/commands/*.md`는 `Read tool` 류 미사용, shell·서브에이전트명·repo 경로만 참조). 만약 특정 command가 Claude 전용 표기를 쓰면 그 command만 생성 후 hand-review 필요 — Task 4 검증의 `$ARGUMENTS`/`{{`grep으로 1차 포착.
|