feat: 공통 Skill 관리 및 링크 스크립트 추가

This commit is contained in:
hyeonggil
2026-04-12 16:32:51 +09:00
parent 5f1b0e9130
commit 982661cb1c
43 changed files with 2570 additions and 2 deletions

View File

@@ -97,10 +97,35 @@ else
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 "다음 작업을 진행해 주세요:"

139
scripts/link-skills.sh Executable file
View File

@@ -0,0 +1,139 @@
#!/usr/bin/env bash
#
# fe-common-rules skill linker
# 공통 저장소의 skills/* 를 프로젝트의 .claude/skills/* 로 심볼릭 링크합니다.
# 심볼릭 링크이므로 submodule 업데이트 시 skill 도 자동으로 최신 버전이 됩니다.
#
# 사용법:
# bash .claude/common/scripts/link-skills.sh # 모든 skill 링크
# bash .claude/common/scripts/link-skills.sh <skill-name> # 특정 skill 만
# bash .claude/common/scripts/link-skills.sh --dry-run # 실제 링크 없이 미리보기
# bash .claude/common/scripts/link-skills.sh --force # 기존 링크/폴더 덮어쓰기
# bash .claude/common/scripts/link-skills.sh --unlink # 공통 skill 링크 제거
#
set -euo pipefail
COMMON_PATH=".claude/common"
SKILLS_SRC="$COMMON_PATH/skills"
SKILLS_DEST=".claude/skills"
MODE="safe" # safe | force | dry-run | unlink
TARGET=""
for arg in "$@"; do
case "$arg" in
--dry-run) MODE="dry-run" ;;
--force) MODE="force" ;;
--unlink) MODE="unlink" ;;
-h|--help)
grep '^#' "$0" | sed 's/^# \{0,1\}//'
exit 0
;;
-*)
echo "❌ 알 수 없는 옵션: $arg" >&2
exit 1
;;
*)
TARGET="$arg"
;;
esac
done
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "❌ 현재 디렉토리는 Git 저장소가 아닙니다." >&2
exit 1
fi
cd "$(git rev-parse --show-toplevel)"
if [[ ! -d "$SKILLS_SRC" ]]; then
echo "$SKILLS_SRC 가 없습니다. 먼저 submodule 을 설치/업데이트하세요:" >&2
echo " git submodule update --init --recursive" >&2
exit 1
fi
mkdir -p "$SKILLS_DEST"
# 링크 대상 결정
declare -a skills
if [[ -n "$TARGET" ]]; then
if [[ ! -d "$SKILLS_SRC/$TARGET" ]]; then
echo "❌ '$TARGET' skill 을 $SKILLS_SRC 에서 찾지 못했습니다." >&2
echo " 사용 가능한 skill:" >&2
ls -1 "$SKILLS_SRC" 2>/dev/null | grep -v '^README' | sed 's/^/ - /' >&2
exit 1
fi
skills=("$TARGET")
else
shopt -s nullglob
for dir in "$SKILLS_SRC"/*/; do
name="$(basename "$dir")"
# README 같은 파일은 이미 걸러지지만 추가 보호
[[ "$name" == "README"* ]] && continue
skills+=("$name")
done
fi
if [[ ${#skills[@]} -eq 0 ]]; then
echo " 링크할 skill 이 없습니다."
exit 0
fi
echo "🔗 공통 skill 링크 (mode=$MODE)"
echo " source: $SKILLS_SRC"
echo " dest: $SKILLS_DEST"
echo ""
linked=0
skipped=0
removed=0
for name in "${skills[@]}"; do
src="../common/skills/$name" # 심볼릭 링크의 상대 경로 (.claude/skills 기준)
dest="$SKILLS_DEST/$name"
case "$MODE" in
unlink)
if [[ -L "$dest" ]]; then
rm "$dest"
echo " 🗑 $dest (링크 제거)"
removed=$((removed + 1))
else
echo "$dest (링크 아님 - 건너뜀)"
fi
;;
dry-run)
if [[ -e "$dest" || -L "$dest" ]]; then
echo "$dest (이미 존재)"
else
echo " ln -s $src $dest"
fi
;;
force)
rm -rf "$dest"
ln -s "$src" "$dest"
echo "$dest$src (덮어씀)"
linked=$((linked + 1))
;;
safe)
if [[ -L "$dest" ]]; then
echo "$dest (이미 링크됨)"
skipped=$((skipped + 1))
elif [[ -e "$dest" ]]; then
echo " ⚠️ $dest (실제 파일/폴더가 존재. --force 로 덮어쓰세요)"
skipped=$((skipped + 1))
else
ln -s "$src" "$dest"
echo "$dest$src"
linked=$((linked + 1))
fi
;;
esac
done
echo ""
case "$MODE" in
unlink) echo "🎉 제거 완료: $removed 개 링크 제거됨";;
dry-run) echo "🔍 미리보기 완료 (실제 변경 없음)";;
*) echo "🎉 완료: 링크 $linked개 / 건너뜀 $skipped개";;
esac