에이전트 협업 인프라 구축 — .claude/ 확장
All checks were successful
Publish ParaWiki / build-and-deploy (push) Successful in 29s

- PLAN.md · PROGRESS.md 도입: 병렬 에이전트 조정 지점
- CLAUDE.md 린화 + 에이전트 작업 흐름 섹션 (상세는 Output/guides/로 분리)
- Output/guides/cimery-dev-guide.md, obsidian-cli.md 신설
- Agents: cimery-architect-researcher, adr-drafter
- Commands: /plan, /progress, /adr, /research, /cimery-start
- Skill: plan-commit
- Hooks: raw/ 쓰기 차단, SessionStart PLAN/PROGRESS 주입,
  wiki/ADR 변경 시 log 갱신 알림, auto-approve (deny 훅 우선 유지)
- .gitignore: .claude/ 공유 자산 포함, 로컬 상태·바이너리만 유지 제외

Closes #3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-14 17:21:11 +09:00
parent d90ef2cfe1
commit 3bd01e31c9
23 changed files with 1059 additions and 67 deletions

View File

@@ -0,0 +1,21 @@
#!/bin/bash
# PreToolUse: auto-approve tool invocations to skip permission prompts.
#
# SAFETY NOTE:
# Specific deny hooks (e.g. block-raw-writes.sh) take precedence because
# Claude Code aggregates hook decisions — any "deny" wins over "allow".
# That is, this hook grants blanket allow, but surgical blocks remain enforced.
#
# This hook is user-scoped convenience. Remove or narrow its matcher if
# multiple team members share this project.
cat <<'EOF'
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "auto-approved by .claude/hooks/auto-approve.sh"
}
}
EOF
exit 0

View File

@@ -0,0 +1,32 @@
#!/bin/bash
# PreToolUse(Write|Edit): block writes to raw/ directory
# Karpathy LLM Wiki rule #1: raw/ is immutable
json=$(cat)
# Extract file_path from JSON (works for Write, Edit, MultiEdit tools)
path=$(printf '%s' "$json" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
if [ -z "$path" ]; then
exit 0
fi
# Normalize Windows backslashes to forward slashes
path_norm=$(printf '%s' "$path" | tr '\\' '/')
case "$path_norm" in
*/raw/*|raw/*)
cat <<'EOF'
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "raw/ is immutable (Karpathy LLM Wiki rule #1). Edit or place new sources via manual copy only."
}
}
EOF
exit 0
;;
esac
exit 0

View File

@@ -0,0 +1,61 @@
#!/usr/bin/env python3
"""SessionStart hook: inject PLAN.md P0/P1 and PROGRESS.md snapshot as additionalContext."""
import json
import os
import re
import sys
def read_file(path: str) -> str:
try:
with open(path, encoding="utf-8") as f:
return f.read()
except Exception:
return ""
def main() -> None:
proj = os.environ.get("CLAUDE_PROJECT_DIR", ".")
plan = read_file(os.path.join(proj, "PLAN.md"))
progress = read_file(os.path.join(proj, "PROGRESS.md"))
parts: list[str] = []
# PLAN: "### P0" through (not including) "## 백로그"
m = re.search(r"^### P0.*?(?=^## 백로그)", plan, re.M | re.S)
if m:
parts.append("## PLAN.md — 현재 스프린트\n\n" + m.group(0).strip())
# PROGRESS: "## 현재 스냅샷" to EOF
m = re.search(r"^## 현재 스냅샷.*$", progress, re.M | re.S)
if m:
parts.append(m.group(0).strip())
if not parts:
sys.exit(0)
ctx = "\n\n".join(parts) + (
"\n\n**에이전트 작업 시작 시 PLAN.md · PROGRESS.md를 읽는 것이 필수입니다.**"
)
print(
json.dumps(
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": ctx,
}
},
ensure_ascii=False,
)
)
sys.exit(0)
if __name__ == "__main__":
try:
main()
except Exception as exc:
sys.stderr.write(f"session-start-context: {exc}\n")
sys.exit(0)

View File

@@ -0,0 +1,31 @@
#!/bin/bash
# PostToolUse(Write|Edit): remind to update wiki/log.md and PROGRESS.md
# when wiki pages or Output/reports/ADRs are modified
json=$(cat)
path=$(printf '%s' "$json" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
if [ -z "$path" ]; then
exit 0
fi
path_norm=$(printf '%s' "$path" | tr '\\' '/')
# Skip the log/index themselves — they ARE the trackers
case "$path_norm" in
*/wiki/log.md|*/wiki/index.md|*/PROGRESS.md|*/PLAN.md)
exit 0
;;
esac
case "$path_norm" in
*/wiki/*|*/Output/reports/*|*/Output/guides/*)
fname=$(basename "$path_norm")
# Minimal JSON — no escaping of special chars needed since message is literal
printf '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"Reminder: %s 변경됨. wiki/log.md 기록 + PROGRESS.md 갱신 여부 확인."}}\n' "$fname"
exit 0
;;
esac
exit 0