Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .claude/rules/tool-layer-boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ atelier autopilot check stagnation # stdin payload 해석

- 등록 자체도 결정적 변환이므로 `atelier git hook register <type> <matcher> <command>`
로 수행한다. LLM 이 `Write` 로 settings.json 을 직접 편집하지 않는다 (#762).
- **plugin-declared hook**: setup·프로젝트 설정과 무관하게 플러그인 활성화만으로 모든
세션에 적용돼야 하는 config-free·non-blocking hook(예: `check-cli-version`)은
플러그인 루트의 `hooks/hooks.json` 에 리터럴 `${CLAUDE_PLUGIN_ROOT}` 로 선언한다.
이는 settings.json 편집이 아니므로 `hook register` 가 필요 없고, 활성 플러그인 버전
경로로 해석돼 frozen 이 없다. 반대로 프로젝트별 설정이나 차단(exit 2)이 필요한 hook
(guard 류)은 opt-in 이라 `hook register` 로 settings.json 에 등록한다.

## 판단 기준

Expand Down
15 changes: 9 additions & 6 deletions plugins/atelier/commands/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ bash "${CLAUDE_PLUGIN_ROOT}/scripts/ensure-binary.sh"
- plugin.json 버전과 설치된 `atelier --version` 을 SemVer 비교해 필요 시 빌드/설치합니다 (`~/.local/bin/atelier`)
- 실패하면(cargo 부재 등) 이후 Step 을 진행하지 말고 에러를 안내합니다

> CLI 버전 드리프트 알림(SessionStart)은 setup 이 등록하지 않습니다 — 플러그인이 `hooks/hooks.json` 으로
> 직접 선언해 활성화 시 자동 적용됩니다(`${CLAUDE_PLUGIN_ROOT}` 해석으로 버전 frozen 없음). Step 0 이
> *setup 시점* 바이너리를 보장하면, 그 hook 이 *이후 드리프트*를 알리는 한 쌍입니다.

## Step 1 — 설치 모듈 선택

`AskUserQuestion` 으로 설치할 모듈을 선택합니다 (multiSelect).
Expand Down Expand Up @@ -86,11 +90,8 @@ bash "${CLAUDE_PLUGIN_ROOT}/scripts/ensure-binary.sh"
## Step 2b — autopilot 모듈

1. 프로젝트 설정 파일 `github-autopilot.local.md` 생성 (기존 스키마/경로 동일 — 호환).
2. autopilot hook 3종 등록 — 로직이 아직 `.sh` 에 있으므로(#776 에서 CLI 이전 예정) `${CLAUDE_PLUGIN_ROOT}` 리터럴 shim 으로 기록:
2. autopilot hook 2종 등록 — 로직이 아직 `.sh` 에 있으므로(#776 에서 CLI 이전 예정) `${CLAUDE_PLUGIN_ROOT}` 리터럴 shim 으로 기록 (버전 드리프트 알림 hook 은 setup 이 등록하지 않음 — Step 0 안내 참조, 플러그인이 `hooks/hooks.json` 으로 직접 선언):
```bash
atelier git hook register SessionStart "*" \
'${CLAUDE_PLUGIN_ROOT}/hooks/check-cli-version.sh' --project-dir "$HOME"

atelier git hook register PreToolUse "Bash" \
'${CLAUDE_PLUGIN_ROOT}/hooks/guard-pr-base.sh' --project-dir "$HOME"

Expand Down Expand Up @@ -134,7 +135,9 @@ bash "${CLAUDE_PLUGIN_ROOT}/scripts/ensure-binary.sh"
4. 사용자에게 치환 목록을 보여주고 AskUserQuestion 으로 확인
5. 매칭 entry 마다: atelier git hook unregister <type> <old-command> --project-dir "$HOME"
→ 아래 표의 대응 command 로 atelier git hook register (hook register 는 command 기준
중복 제거를 하므로 frozen + atelier 양쪽에 있던 hook 도 한 개만 남음)
중복 제거를 하므로 frozen + atelier 양쪽에 있던 hook 도 한 개만 남음).
단, 표에서 "제거만" 으로 표시된 hook 은 plugin-declared 로 대체됐으므로 unregister 만
하고 재등록하지 않는다 (재등록 시 hooks.json 선언과 SessionStart 이중 실행)
```

> **멱등성**: 이미 atelier 로 재작성된 settings.json 에 재실행하면 변경 0건이어야 합니다.
Expand All @@ -143,7 +146,7 @@ bash "${CLAUDE_PLUGIN_ROOT}/scripts/ensure-binary.sh"

| frozen 경로 | atelier 등록 command |
|---|---|
| `github-autopilot/hooks/check-cli-version.sh` | `${CLAUDE_PLUGIN_ROOT}/hooks/check-cli-version.sh` (리터럴) |
| `github-autopilot/hooks/check-cli-version.sh` | **제거만** (재등록 안 함) — 플러그인이 `hooks/hooks.json` 으로 직접 선언 |
| `github-autopilot/hooks/guard-pr-base.sh` | `${CLAUDE_PLUGIN_ROOT}/hooks/guard-pr-base.sh` (리터럴) |
| `github-autopilot/hooks/protect-stagnation.sh` | `${CLAUDE_PLUGIN_ROOT}/hooks/protect-stagnation.sh` (리터럴) |
| `coding-style/hooks/suggest-simplify.sh` | `${CLAUDE_PLUGIN_ROOT}/hooks/suggest-simplify.sh` (리터럴) |
Expand Down
26 changes: 8 additions & 18 deletions plugins/atelier/hooks/check-cli-version.sh
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
#!/usr/bin/env bash
# check-cli-version.sh — SessionStart hook
# 세션 시작 시 atelier CLI 버전이 plugin.json과 일치하는지 확인합니다.
# 과거 버전이면 업데이트 안내를 출력합니다.
# 세션 시작 시 설치된 atelier CLI 버전이 활성 플러그인 버전과 일치하는지 확인합니다.
#
# 트리거: SessionStart
# 트리거: SessionStart (글로벌 등록 — atelier 설치 여부로 스스로 판단)
# 동작:
# - autopilot 프로젝트가 아니면 → exit 0 (skip)
# - CLI 미설치 또는 과거 버전 → 안내 출력 후 exit 0
# - 최신 버전 → exit 0
# - atelier CLI 미설치 → exit 0 (무음 — atelier 미사용 환경 배려)
# - 설치 버전 < 플러그인 버전 → 업데이트 안내 한 줄 출력 후 exit 0
# - 최신/상위 버전 → exit 0 (무음)

set -euo pipefail

PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
CONFIG_FILE="${PROJECT_DIR}/github-autopilot.local.md"

# autopilot 프로젝트가 아니면 skip
if [[ ! -f "$CONFIG_FILE" ]]; then
exit 0
fi
# atelier 미설치 환경은 가장 싼 builtin 검사로 먼저 가른다 — 이 hook 은 모든 세션에서
# 실행되므로(미설치가 다수), plugin.json 파싱·stdin 처리 전에 즉시 종료한다.
command -v atelier &> /dev/null || exit 0

# stdin 소비 (SessionStart hook은 session info를 stdin으로 받음)
cat > /dev/null
Expand All @@ -37,11 +32,6 @@ if [[ -z "$PLUGIN_VERSION" ]]; then
fi

# --- 설치된 CLI 버전 확인 ---
if ! command -v atelier &> /dev/null; then
echo "atelier CLI가 설치되어 있지 않습니다. /atelier:setup 을 실행하여 설치하세요."
exit 0
fi

INSTALLED_VERSION=$(atelier --version 2>/dev/null | awk '{print $NF}' || echo "")

if [[ -z "$INSTALLED_VERSION" ]]; then
Expand Down
15 changes: 15 additions & 0 deletions plugins/atelier/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"hooks": {
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/check-cli-version.sh"
}
]
}
]
}
}
Loading