210 lines
6.9 KiB
Bash
Executable File
210 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
#
|
||
# gameservice-fe-agent installer
|
||
# 현재 Git 프로젝트의 .claude/common 경로에 gameservice-fe-agent 저장소를
|
||
# submodule 로 추가하고, templates/ 에서 프로젝트 지침 양식과
|
||
# CLAUDE.md 템플릿을 복사합니다.
|
||
#
|
||
# 사용법:
|
||
# bash scripts/install.sh <repo-url> [<branch>]
|
||
#
|
||
# 예:
|
||
# bash scripts/install.sh https://git.sginfra.net/sgp-web-d/gameservice-fe-agent master
|
||
#
|
||
set -euo pipefail
|
||
|
||
REPO_URL="${1:-}"
|
||
BRANCH="${2:-master}"
|
||
TARGET_PATH=".claude/common"
|
||
PROJECT_PATH=".claude/project"
|
||
|
||
if [[ -z "$REPO_URL" ]]; then
|
||
echo "❌ 사용법: bash scripts/install.sh <repo-url> [branch]" >&2
|
||
echo " 예: bash scripts/install.sh https://git.sginfra.net/sgp-web-d/gameservice-fe-agent master" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# Git 프로젝트인지 확인
|
||
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||
echo "❌ 현재 디렉토리는 Git 저장소가 아닙니다. 먼저 'git init' 후 실행해주세요." >&2
|
||
exit 1
|
||
fi
|
||
|
||
# 루트로 이동
|
||
cd "$(git rev-parse --show-toplevel)"
|
||
|
||
# 1) Submodule 추가
|
||
if [[ -d "$TARGET_PATH" ]]; then
|
||
echo "⚠️ '$TARGET_PATH' 경로가 이미 존재합니다. submodule 추가를 건너뜁니다."
|
||
else
|
||
echo "📦 gameservice-fe-agent 를 submodule 로 추가합니다..."
|
||
git submodule add -b "$BRANCH" "$REPO_URL" "$TARGET_PATH"
|
||
git submodule update --init --recursive
|
||
echo "✅ submodule 추가 완료: $TARGET_PATH"
|
||
fi
|
||
|
||
# 2) 프로젝트 지침 양식 복사 (templates/project/ → .claude/project/)
|
||
mkdir -p "$PROJECT_PATH"
|
||
|
||
TEMPLATE_DIR="$TARGET_PATH/templates/project"
|
||
if [[ -d "$TEMPLATE_DIR" ]]; then
|
||
echo "📝 프로젝트 지침 양식을 복사합니다..."
|
||
for f in "$TEMPLATE_DIR"/*.md; do
|
||
[[ -e "$f" ]] || continue
|
||
name="$(basename "$f")"
|
||
dest="$PROJECT_PATH/$name"
|
||
if [[ -f "$dest" ]]; then
|
||
echo " ⏭ $dest (이미 존재 - 건너뜀)"
|
||
else
|
||
cp "$f" "$dest"
|
||
echo " ✅ $dest"
|
||
fi
|
||
done
|
||
else
|
||
echo "⚠️ $TEMPLATE_DIR 를 찾지 못했습니다. 공통 저장소의 templates 가 오래됐을 수 있습니다."
|
||
fi
|
||
|
||
# 3) 루트 CLAUDE.md 템플릿 복사
|
||
if [[ ! -f "CLAUDE.md" ]]; then
|
||
TPL_FILE="$TARGET_PATH/templates/CLAUDE.md.tpl"
|
||
if [[ -f "$TPL_FILE" ]]; then
|
||
cp "$TPL_FILE" CLAUDE.md
|
||
echo "✅ CLAUDE.md 템플릿을 생성했습니다."
|
||
else
|
||
cat > CLAUDE.md <<'EOF'
|
||
# <프로젝트 이름>
|
||
|
||
## 공통 지침
|
||
@.claude/common/CLAUDE.md
|
||
|
||
## 프로젝트 지침
|
||
@.claude/project/overview.md
|
||
@.claude/project/conventions.md
|
||
@.claude/project/architecture.md
|
||
|
||
## 슬래시 커맨드 연결
|
||
|
||
- `/init` 커맨드가 실행되면 반드시 `project-init` 스킬을 호출하세요.
|
||
|
||
## Behavioral Guidelines
|
||
|
||
Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed.
|
||
|
||
> Tradeoff: These guidelines bias toward caution over speed. For trivial tasks, use judgment.
|
||
|
||
### 1. Think Before Coding
|
||
|
||
Don't assume. Don't hide confusion. Surface tradeoffs.
|
||
|
||
Before implementing:
|
||
|
||
- State your assumptions explicitly. If uncertain, ask.
|
||
- If multiple interpretations exist, present them — don't pick silently.
|
||
- If a simpler approach exists, say so. Push back when warranted.
|
||
- If something is unclear, stop. Name what's confusing. Ask.
|
||
|
||
### 2. Simplicity First
|
||
|
||
Minimum code that solves the problem. Nothing speculative.
|
||
|
||
- No features beyond what was asked.
|
||
- No abstractions for single-use code.
|
||
- No "flexibility" or "configurability" that wasn't requested.
|
||
- No error handling for impossible scenarios.
|
||
- If you write 200 lines and it could be 50, rewrite it.
|
||
|
||
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
|
||
|
||
### 3. Surgical Changes
|
||
|
||
Touch only what you must. Clean up only your own mess.
|
||
|
||
When editing existing code:
|
||
|
||
- Don't "improve" adjacent code, comments, or formatting.
|
||
- Don't refactor things that aren't broken.
|
||
- Match existing style, even if you'd do it differently.
|
||
- If you notice unrelated dead code, mention it — don't delete it.
|
||
|
||
When your changes create orphans:
|
||
|
||
- Remove imports/variables/functions that YOUR changes made unused.
|
||
- Don't remove pre-existing dead code unless asked.
|
||
|
||
The test: Every changed line should trace directly to the user's request.
|
||
|
||
### 4. Goal-Driven Execution
|
||
|
||
Define success criteria. Loop until verified.
|
||
|
||
Transform tasks into verifiable goals:
|
||
|
||
- "Add validation" → "Write tests for invalid inputs, then make them pass"
|
||
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
|
||
- "Refactor X" → "Ensure tests pass before and after"
|
||
|
||
For multi-step tasks, state a brief plan:
|
||
|
||
1. [Step] → verify: [check]
|
||
2. [Step] → verify: [check]
|
||
3. [Step] → verify: [check]
|
||
|
||
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
|
||
|
||
These guidelines are working if: fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.
|
||
EOF
|
||
echo "✅ CLAUDE.md 템플릿을 생성했습니다. (fallback)"
|
||
fi
|
||
else
|
||
echo "ℹ️ 기존 CLAUDE.md 가 이미 존재합니다. 아래 블록을 수동으로 추가하세요:"
|
||
echo ""
|
||
echo " ## 공통 지침"
|
||
echo " @.claude/common/CLAUDE.md"
|
||
echo ""
|
||
echo " ## 프로젝트 지침"
|
||
echo " @.claude/project/overview.md"
|
||
echo " @.claude/project/conventions.md"
|
||
echo " @.claude/project/architecture.md"
|
||
echo ""
|
||
echo " ## Behavioral Guidelines"
|
||
echo " (자세한 내용은 $TARGET_PATH/templates/CLAUDE.md.tpl 참고)"
|
||
echo ""
|
||
fi
|
||
|
||
# 4) 공통 skill 심볼릭 링크 (.claude/common/skills/* → .claude/skills/*)
|
||
SKILLS_SRC="$TARGET_PATH/skills"
|
||
SKILLS_DEST=".claude/skills"
|
||
|
||
if [[ -d "$SKILLS_SRC" ]]; then
|
||
echo "🔗 공통 skill 을 $SKILLS_DEST 로 링크합니다..."
|
||
mkdir -p "$SKILLS_DEST"
|
||
for dir in "$SKILLS_SRC"/*/; do
|
||
[[ -d "$dir" ]] || continue
|
||
name="$(basename "$dir")"
|
||
[[ "$name" == "README"* ]] && continue
|
||
link_src="../common/skills/$name"
|
||
link_dest="$SKILLS_DEST/$name"
|
||
if [[ -L "$link_dest" ]]; then
|
||
echo " ⏭ $link_dest (이미 링크됨)"
|
||
elif [[ -e "$link_dest" ]]; then
|
||
echo " ⚠️ $link_dest (실제 파일/폴더 존재 - 건너뜀. link-skills.sh --force 로 덮어쓰기)"
|
||
else
|
||
ln -s "$link_src" "$link_dest"
|
||
echo " ✅ $link_dest → $link_src"
|
||
fi
|
||
done
|
||
fi
|
||
|
||
echo ""
|
||
echo "🎉 설치가 완료되었습니다."
|
||
echo " - 공통 지침: $TARGET_PATH/CLAUDE.md"
|
||
echo " - 프로젝트 지침: $PROJECT_PATH/"
|
||
echo " - 공통 skill: $SKILLS_DEST/ (submodule 에 심볼릭 링크)"
|
||
echo " - 엔트리 파일: CLAUDE.md"
|
||
echo ""
|
||
echo "다음 작업을 진행해 주세요:"
|
||
echo " 1) $PROJECT_PATH/*.md 내용을 프로젝트에 맞게 채우기"
|
||
echo " 2) 변경 사항을 커밋하기"
|
||
echo " git add .gitmodules .claude CLAUDE.md"
|
||
echo " git commit -m 'chore: add gameservice-fe-agent submodule'"
|