diff --git a/agent-ops/.version b/agent-ops/.version index 524cb55..45a1b3f 100644 --- a/agent-ops/.version +++ b/agent-ops/.version @@ -1 +1 @@ -1.1.1 +1.1.2 diff --git a/agent-ops/bin/bump-version.sh b/agent-ops/bin/bump-version.sh new file mode 100755 index 0000000..4cc50ef --- /dev/null +++ b/agent-ops/bin/bump-version.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# bump-version.sh +# patch +1, 999 초과 시 minor 올림. major는 수동 관리. +# 결과 버전을 stdout으로 출력. + +set -euo pipefail + +YELLOW='\033[1;33m'; RESET='\033[0m' + +VERSION="${1:-}" +if [[ -z "$VERSION" ]]; then + echo "사용법: $0 " >&2 + exit 1 +fi + +IFS='.' read -r major minor patch <<< "$VERSION" + +patch=$((patch + 1)) +if [[ $patch -gt 999 ]]; then + patch=0 + minor=$((minor + 1)) +fi +if [[ $minor -gt 999 ]]; then + minor=0 + echo -e "${YELLOW}⚠ minor 버전이 999를 초과했습니다. major 버전을 수동으로 올려주세요.${RESET}" >&2 +fi + +echo "$major.$minor.$patch" diff --git a/agent-ops/bin/sync.sh b/agent-ops/bin/sync.sh new file mode 100755 index 0000000..62155ce --- /dev/null +++ b/agent-ops/bin/sync.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ── 경로 설정 ──────────────────────────────────────────────────────────────── +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +AGENT_OPS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +PROJECT_ROOT="$(cd "$AGENT_OPS_DIR/.." && pwd)" + +# ── 색상 ───────────────────────────────────────────────────────────────────── +RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m'; RESET='\033[0m' + +# ── 대상 경로 해석 (폴더명 / 상대경로 / 절대경로) ──────────────────────────── +resolve_target() { + local input="$1" + if [[ "$input" == /* ]]; then + [[ -d "$input" ]] && echo "$input" || echo "" + return + fi + if [[ "$input" == */* ]]; then + local resolved + resolved="$(cd "$input" 2>/dev/null && pwd)" || { echo ""; return; } + echo "$resolved" + return + fi + local sibling="$(dirname "$PROJECT_ROOT")/$input" + [[ -d "$sibling" ]] && echo "$sibling" || echo "" +} + +# ── 버전 비교: v1 > v2 이면 0 반환 ─────────────────────────────────────────── +version_gt() { + local v1="$1" v2="$2" + [[ "$v1" == "$v2" ]] && return 1 + [[ "$(printf '%s\n%s' "$v1" "$v2" | sort -V | head -1)" == "$v2" ]] +} + +# ── 버전 +1 ────────────────────────────────────────────────────────────────── +bump_version() { + bash "$SCRIPT_DIR/bump-version.sh" "$1" +} + +# ── 폴더 동기화 (rules.md 제외, 삭제된 파일도 반영) ───────────────────────── +sync_folder() { + local src="$1" dst="$2" exclude="${3:-}" + mkdir -p "$dst" + # dst에서 src에 없는 항목 제거 (exclude 파일 보존) + find "$dst" -mindepth 1 -maxdepth 1 | while IFS= read -r item; do + local name + name="$(basename "$item")" + [[ -n "$exclude" && "$name" == "$exclude" ]] && continue + if [[ ! -e "$src/$name" ]]; then + rm -rf "$item" + fi + done + # src에서 dst로 복사 (exclude 파일 제외) + find "$src" -mindepth 1 -maxdepth 1 | while IFS= read -r item; do + local name + name="$(basename "$item")" + [[ -n "$exclude" && "$name" == "$exclude" ]] && continue + rm -rf "$dst/$name" + cp -r "$item" "$dst/" + done +} + +sync_common() { + local src="$1" dst="$2" + sync_folder "$src/rules/common" "$dst/rules/common" "rules.md" + sync_folder "$src/skills/common" "$dst/skills/common" + sync_folder "$src/bin" "$dst/bin" +} + +# ── rules.md 내용을 진입 파일들에 반영 ─────────────────────────────────────── +apply_entry_files() { + local rules_md="$1" + local target_root="$2" + + if [[ ! -f "$rules_md" ]]; then + echo -e "${YELLOW} rules.md 없음, 진입 파일 재적용 건너뜀${RESET}" + return + fi + + # 기본 자동 생성/갱신 대상 + local default_files=("CLAUDE.md" "GEMINI.md" ".cursorrules" "AGENTS.md") + # 존재할 때만 갱신 + local optional_files=(".clinerules") + + for f in "${default_files[@]}"; do + cp "$rules_md" "$target_root/$f" + echo " 진입 파일 적용: $f" + done + + for f in "${optional_files[@]}"; do + if [[ -f "$target_root/$f" ]]; then + cp "$rules_md" "$target_root/$f" + echo " 진입 파일 적용: $f" + fi + done +} + +# ── 사용법 ──────────────────────────────────────────────────────────────────── +usage() { + echo "사용법: $0 " + echo "" + echo " 현재 프로젝트 → target 으로 동기화" + echo "" + echo " target: 폴더명 (동일 레벨 탐색) | 상대경로 | 절대경로" +} + +# ───────────────────────────────────────────────────────────────────────────── +TARGET_INPUT="${1:-}" +if [[ -z "$TARGET_INPUT" ]]; then + usage; exit 1 +fi + +TARGET="$(resolve_target "$TARGET_INPUT")" +if [[ -z "$TARGET" ]]; then + echo -e "${RED}Error: 대상을 찾을 수 없습니다: $TARGET_INPUT${RESET}" + exit 1 +fi + +SRC_AO="$AGENT_OPS_DIR" +DST_AO="$TARGET/agent-ops" +IS_FRAMEWORK="$([[ -f "$PROJECT_ROOT/.agent-ops-source" ]] && echo "1" || echo "0")" + +echo "▶ $(basename "$PROJECT_ROOT") → $(basename "$TARGET")" + +# ── agentic-framework에서 다른 프로젝트로 ──────────────────────────────────── +if [[ "$IS_FRAMEWORK" == "1" ]]; then + if [[ ! -d "$DST_AO" ]]; then + echo " 최초 진행: agent-ops 전체 복사" + cp -r "$SRC_AO" "$TARGET/" + echo -e "${YELLOW} init-agent-ops 스킬로 초기화를 진행하세요.${RESET}" + else + echo " 이후 진행: common/ 동기화" + sync_common "$SRC_AO" "$DST_AO" + apply_entry_files "$SRC_AO/rules/common/rules.md" "$TARGET" + fi + echo -e "${GREEN}✓ 완료 → $(basename "$TARGET")${RESET}" + exit 0 +fi + +# ── 일반 프로젝트에서 agentic-framework로 ──────────────────────────────────── +if [[ ! -f "$TARGET/.agent-ops-source" ]]; then + echo -e "${RED}Error: target이 agentic-framework가 아닙니다 (.agent-ops-source 없음)${RESET}" + exit 1 +fi + +SRC_VER="$(cat "$SRC_AO/.version" 2>/dev/null || echo "0.0.0")" +DST_VER="$(cat "$DST_AO/.version" 2>/dev/null || echo "0.0.0")" +echo " 현재 버전: $SRC_VER | framework 버전: $DST_VER" + +if version_gt "$DST_VER" "$SRC_VER"; then + sync_common "$SRC_AO" "$DST_AO" + echo -e "${RED}⚠ 버전 충돌: framework($DST_VER) > current($SRC_VER)${RESET}" + echo -e "${YELLOW} 파일은 복사됐지만 push하지 않았습니다. 수동 머지 후 재시도하세요.${RESET}" + exit 1 +fi + +NEW_VER="$(bump_version "$SRC_VER")" +sync_common "$SRC_AO" "$DST_AO" +echo "$NEW_VER" > "$SRC_AO/.version" +echo "$NEW_VER" > "$DST_AO/.version" + +cd "$TARGET" +git add agent-ops/rules/common agent-ops/skills/common agent-ops/bin agent-ops/.version +git commit -m "sync: from $(basename "$PROJECT_ROOT") v$NEW_VER" +git push +cd "$PROJECT_ROOT" + +git add agent-ops/rules/common agent-ops/skills/common agent-ops/bin agent-ops/.version +git commit -m "sync: to agentic-framework v$NEW_VER" +git push + +echo -e "${GREEN}✓ 완료 (v$SRC_VER → v$NEW_VER)${RESET}"