From ee1297e0c2098c96fe8b0b2f289a185ce139d96e Mon Sep 17 00:00:00 2001 From: toki Date: Tue, 14 Apr 2026 08:52:30 +0900 Subject: [PATCH] update agent-ops: add bin scripts, remove version-bump skill --- .claude/settings.json | 9 +- agent-ops/bin/bump-version.sh | 28 ++++ agent-ops/bin/sync.sh | 157 ++++++++++++++++++ .../skills/common/init-agent-ops/SKILL.md | 39 ++--- agent-ops/skills/common/router.md | 3 +- .../skills/common/sync-agent-ops/SKILL.md | 73 +++----- agent-ops/skills/common/version-bump/SKILL.md | 81 --------- 7 files changed, 228 insertions(+), 162 deletions(-) create mode 100755 agent-ops/bin/bump-version.sh create mode 100755 agent-ops/bin/sync.sh delete mode 100644 agent-ops/skills/common/version-bump/SKILL.md diff --git a/.claude/settings.json b/.claude/settings.json index 712dac1..68317d8 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -9,10 +9,15 @@ "Bash(ls *.log)", "Bash(tools/check_proto_sync.sh)", "Bash(mv CODE_REVIEW.md code_review_0.log)", - "Bash(mv PLAN.md plan_0.log)" + "Bash(mv PLAN.md plan_0.log)", + "Bash(chmod +x /config/workspace/toki_socket/agent-ops/sync.sh)", + "Bash(bash agent-ops/sync.sh)", + "Bash(bash agent-ops/sync.sh push)", + "Bash(git checkout:*)" ], "additionalDirectories": [ - "/config/workspace/toki_socket/tasks" + "/config/workspace/toki_socket/tasks", + "/config/workspace/agentic-framework/agent-ops/skills/common/sync-agent-ops" ] } } 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..f262a63 --- /dev/null +++ b/agent-ops/bin/sync.sh @@ -0,0 +1,157 @@ +#!/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" +} + +# ── common 폴더 동기화 (삭제된 파일도 반영) ─────────────────────────────────── +sync_common() { + local src="$1" dst="$2" + for folder in rules/common skills/common; do + rm -rf "$dst/$folder" + mkdir -p "$dst/$folder" + cp -r "$src/$folder/." "$dst/$folder/" + done +} + +# ── 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 + RULES_MD="$SRC_AO/rules/common/rules.md" + + if [[ ! -d "$DST_AO" ]]; then + echo " 최초 진행: agent-ops 전체 복사" + cp -r "$SRC_AO" "$TARGET/" + rm -f "$DST_AO/rules/common/rules.md" + else + echo " 이후 진행: common/ 동기화" + sync_common "$SRC_AO" "$DST_AO" + rm -f "$DST_AO/rules/common/rules.md" + fi + + apply_entry_files "$RULES_MD" "$TARGET" + 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/.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/.version +git commit -m "sync: to agentic-framework v$NEW_VER" +git push + +echo -e "${GREEN}✓ 완료 (v$SRC_VER → v$NEW_VER)${RESET}" diff --git a/agent-ops/skills/common/init-agent-ops/SKILL.md b/agent-ops/skills/common/init-agent-ops/SKILL.md index 3654b71..c105459 100644 --- a/agent-ops/skills/common/init-agent-ops/SKILL.md +++ b/agent-ops/skills/common/init-agent-ops/SKILL.md @@ -60,10 +60,9 @@ description: 프로젝트 상태를 판별하고 agent-ops 기본 스캐폴드 | 파일 | 방법 | |------|------| -| `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md` | 공통 관리 레포의 `rules/common/rules.md` 내용을 프로젝트 루트에 기본 진입 파일로 자동 생성 | -| `.clinerules` 등 추가 진입 파일 | 사용자가 요청했거나 기존 파일이 있을 때만 같은 내용으로 생성/갱신 | +| `CLAUDE.md`,`GEMINI.md`,`AGENTS.md`, `.cursorrules`, `.clinerules` 등 진입 파일 | `rules/common/rules.md`를 에이전트별 파일명으로 프로젝트 루트에 복사 후 `rules/common/rules.md` 삭제 | | `agent-ops/.version` | 공통 관리 레포의 VERSION 파일을 그대로 복사 (프레임워크 버전 추적용) | -| `agent-ops/rules/common/` | 공통 폴더를 복사하되, 진입 파일 생성 후 `rules.md`는 삭제하고 `_templates/` 등 보조 파일만 최종 유지 | +| `agent-ops/rules/common/` | 공통 폴더 전체 복사 (수정 금지) | | `agent-ops/skills/common/` | 공통 폴더 전체 복사 (수정 금지) | | `agent-ops/rules/project/rules.md` | 프로젝트 분석 후 생성 | | `agent-ops/rules/project/domain//rules.md` | 도메인 분석 후 생성 | @@ -76,27 +75,20 @@ description: 프로젝트 상태를 판별하고 agent-ops 기본 스캐폴드 |---------|--------| | Claude | `CLAUDE.md` | | Gemini | `GEMINI.md` | -| Cursor | `.cursorrules` | | Kilo Code / OpenCode | `AGENTS.md` | +| Cursor | `.cursorrules` | | Cline | `.clinerules` | -기본 자동 생성 대상은 `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md`다. -`.clinerules` 등 추가 진입 파일은 사용자가 요청했거나 기존 파일이 있을 때만 생성/갱신한다. - ## 에이전트 진입 파일 원칙 -기본 진입 파일인 `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md`는 프로젝트 루트에 항상 자동 생성한다. -진입 파일은 공통 관리 레포의 `rules/common/rules.md` 원본 내용 그대로를 에이전트별 파일명으로 복사한다. +진입 파일은 `rules/common/rules.md` 내용 그대로를 에이전트별 파일명으로 복사한다. 별도 내용을 추가하거나 수정하지 않는다. -진입 파일 생성 후 프로젝트 안의 `agent-ops/rules/common/rules.md`는 삭제한다. ## Rule 구조 원칙 ### rules/common/rules.md -- 공통 관리 레포에서 제공하는 진입 파일 생성용 원본이다. -- 프로젝트에서는 직접 수정하지 않는다. -- 실제 사용은 진입점 파일들에서 이루어진다. -- 진입 파일 생성 후 프로젝트 최종 산출물에는 남기지 않는다. +- 공통 관리 레포에서 제공. 프로젝트에서 직접 수정하지 않는다. +- 실제 사용은 진입점 파일들에서 사용된다. 포함 항목: - 기본 원칙 @@ -162,16 +154,14 @@ common/rules.md와 내용이 중복되지 않도록 한다. 1. **상태 판별** - 프로젝트 구조, 모듈 경계, agent-ops 파일 유무를 분석하여 신규/운영중을 판별한다 -2. **agent-ops 폴더 구조 복사** +2. **에이전트 진입 파일 생성** + - `rules/common/rules.md`를 에이전트별 파일명으로 프로젝트 루트에 복사한다 + - 복사 후 `rules/common/rules.md`를 삭제한다 + +3. **agent-ops 폴더 구조 복사** - 공통 관리 레포의 `agent-ops/` 공통 폴더(rules/common, skills/common)를 복사한다 - `agent-ops/.version` 파일을 복사한다 -3. **에이전트 진입 파일 생성** - - 공통 관리 레포의 `rules/common/rules.md` 원본을 `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md`로 프로젝트 루트에 자동 생성한다 - - `.clinerules` 등 추가 진입 파일은 사용자가 요청했거나 기존 파일이 있을 때만 같은 내용으로 생성/갱신한다 - - 복사 후 프로젝트 안의 `agent-ops/rules/common/rules.md`를 삭제한다 - - 삭제 후 `agent-ops/rules/common/`에는 `_templates/` 등 보조 파일만 남긴다 - 4. **rules/project/rules.md 생성** - 프로젝트를 분석하여 응답 언어, 프로젝트 개요, 기술 스택 등을 채운다 - common/rules.md와 내용이 중복되지 않도록 한다 @@ -214,8 +204,7 @@ common/rules.md와 내용이 중복되지 않도록 한다. ## 실행 결과 검증 -- [ ] `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md`가 프로젝트 루트에 존재하고, 내용이 공통 관리 레포의 `rules/common/rules.md` 원본과 일치하는가 -- [ ] 프로젝트 안에 `agent-ops/rules/common/rules.md`가 남아 있지 않은가 +- [ ] 진입 파일이 프로젝트 루트에 존재하고, 내용이 `rules/common/rules.md`와 일치하는가 - [ ] `agent-ops/rules/project/rules.md`가 생성되었고, 필수 항목(응답 언어, 프로젝트 개요, 기술 스택)이 포함되어 있는가 - [ ] 생성된 domain rules.md가 `domain-rule-template.md` 형식을 따르는가 - [ ] `rules/project/rules.md`의 도메인 매핑 테이블에 생성된 도메인이 모두 등록되어 있는가 @@ -224,8 +213,8 @@ common/rules.md와 내용이 중복되지 않도록 한다. ## 금지 사항 -- 진입 파일에 공통 관리 레포의 rules/common/rules.md 원본 외 내용을 추가하지 않는다. +- 진입 파일에 rules/common/rules.md 외 내용을 추가하지 않는다. - 실제 구조보다 앞선 추상 구조를 강요하지 않는다. - 처음부터 많은 domain / skill을 만들지 않는다. -- 공통 관리 레포의 rules/common/rules.md 원본을 프로젝트에서 직접 수정하지 않는다. +- rules/common/rules.md를 프로젝트에서 직접 수정하지 않는다. - rules/project/rules.md에 rules/common/rules.md와 중복되는 내용을 넣지 않는다. diff --git a/agent-ops/skills/common/router.md b/agent-ops/skills/common/router.md index 50ac9c0..6fe73f5 100644 --- a/agent-ops/skills/common/router.md +++ b/agent-ops/skills/common/router.md @@ -8,5 +8,4 @@ | 계획 세워줘, 구현 계획, PLAN.md, plan | `agent-ops/skills/common/plan/SKILL.md` | | 코드 리뷰해줘, code review, CODE_REVIEW.md, 리뷰 루프 | `agent-ops/skills/common/code-review/SKILL.md` | | 커밋해줘, 푸시해줘, commit, push, 반영해줘 | `agent-ops/skills/common/commit-push/SKILL.md` | -| 버전 올려줘, 버전 변경 | `agent-ops/skills/common/version-bump/SKILL.md` | -| agent-ops 업데이트해줘, 진입 파일 재적용해줘 | `agent-ops/skills/common/sync-agent-ops/SKILL.md` | +| agent-ops 싱크해, agent-ops 동기화해, agentic-framework에 올려줘, agent-ops를 [프로젝트]로 싱크해 | `agent-ops/skills/common/sync-agent-ops/SKILL.md` | diff --git a/agent-ops/skills/common/sync-agent-ops/SKILL.md b/agent-ops/skills/common/sync-agent-ops/SKILL.md index 909afb2..bc3f9ae 100644 --- a/agent-ops/skills/common/sync-agent-ops/SKILL.md +++ b/agent-ops/skills/common/sync-agent-ops/SKILL.md @@ -1,75 +1,44 @@ --- name: sync-agent-ops -version: 1.0.0 -description: 공통 관리 레포의 rules/common/rules.md 변경 내용을 기본 진입 파일에 재적용한다. "agent-ops 업데이트해줘", "진입 파일 재적용해줘" 요청 시 사용한다. +description: agent-ops를 agentic-framework와 동기화한다. "agent-ops 싱크해", "agent-ops 동기화해" 요청 시 사용한다. --- # sync-agent-ops ## 목적 -공통 관리 레포에서 `rules/common/rules.md`가 변경됐을 때, -프로젝트 루트의 기본 에이전트 진입 파일들에 변경 내용을 반영한다. +`agent-ops/bin/sync.sh`를 호출해 agent-ops를 동기화한다. +현재 프로젝트가 agentic-framework인지 여부에 따라 동작이 달라진다. ## 언제 호출할지 -- 공통 관리 레포에서 `rules/common/`이 업데이트된 후 -- "agent-ops 업데이트해줘", "진입 파일 재적용해줘" 요청 시 -- 진입 파일이 공통 관리 레포의 `rules/common/rules.md` 원본과 동기화되지 않은 것이 확인됐을 때 - -## 입력 - -- 없음 (파라미터 없이 실행) - -## 먼저 확인할 것 - -- [ ] 공통 관리 레포의 `rules/common/rules.md` 원본을 읽을 수 있는가 -- [ ] 프로젝트 루트의 기존 진입 파일 상태를 확인했는가 +- "agent-ops 싱크해", "agent-ops 동기화해" 요청 시 +- "agentic-framework에 올려줘" 요청 시 +- "agent-ops를 [프로젝트]로 싱크해" 요청 시 ## 실행 절차 -1. `agent-ops/.version` 파일이 있으면 현재 프레임워크 버전을 읽고 출력한다 -2. 공통 관리 레포의 `rules/common/rules.md` 원본을 읽는다 -3. 프로젝트 루트의 `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md`를 원본 내용으로 생성/덮어쓴다 -4. `.clinerules` 등 추가 진입 파일은 사용자가 요청했거나 기존 파일이 있을 때만 같은 내용으로 생성/덮어쓴다 -5. 업데이트 과정에서 프로젝트 안에 `agent-ops/rules/common/rules.md`가 생겼다면 삭제한다 -6. 결과를 출력한다 +### 현 프로젝트가 일반 프로젝트인 경우 (`.agent-ops-source` 없음) -## 에이전트별 진입 파일 +1. 동일 레벨에 `agentic-framework` 폴더가 있는지 확인한다 +2. **있으면**: `agent-ops/bin/sync.sh agentic-framework` 실행 +3. **없으면**: 사용자에게 agentic-framework 경로 입력을 안내하고, 입력받은 경로로 실행 -| 에이전트 | 파일명 | -|---------|--------| -| Claude | `CLAUDE.md` | -| Gemini | `GEMINI.md` | -| Kilo Code / OpenCode | `AGENTS.md` | -| Cursor | `.cursorrules` | -| Cline | `.clinerules` | +### 현 프로젝트가 agentic-framework인 경우 (`.agent-ops-source` 있음) -기본 자동 생성/갱신 대상은 `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md`다. -`.clinerules` 등 추가 진입 파일은 사용자가 요청했거나 기존 파일이 있을 때만 생성/갱신한다. +1. 사용자 요청에서 target 프로젝트명 또는 경로를 추출한다 +2. **명시된 경우**: `agent-ops/bin/sync.sh ` 실행 +3. **명시되지 않은 경우**: 사용자에게 대상 프로젝트 입력을 요청한다 + +```bash +agent-ops/bin/sync.sh +``` ## 실행 결과 검증 -- [ ] `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md`가 프로젝트 루트에 존재하고, 내용이 공통 관리 레포의 `rules/common/rules.md` 원본과 정확히 일치하는가 -- [ ] 요청되었거나 기존에 존재하던 추가 진입 파일이 누락 없이 업데이트되었는가 -- [ ] 프로젝트 안에 `agent-ops/rules/common/rules.md`가 남아 있지 않은가 -- 검증 실패 시: 불일치하는 파일명과 차이점을 사용자에게 알린다 - -## 출력 형식 - -``` -## 동기화 완료 - -- 프레임워크 버전: {버전} (해당 시) -- 업데이트된 진입 파일: - - {파일명}: 업데이트 완료 -- 생성된 진입 파일: - - {파일명}: 생성 완료 -- 변경 없는 파일: {파일명} (해당 시) -``` +- [ ] sync.sh 가 오류 없이 완료됐는가 +- [ ] 버전 충돌 경고가 없었는가 — 있었다면 사용자에게 수동 머지 필요함을 알린다 ## 금지 사항 -- 공통 관리 레포의 `rules/common/rules.md` 원본을 수정하지 않는다. -- `rules/project/rules.md` 등 다른 파일을 건드리지 않는다. -- 프로젝트 안의 `agent-ops/rules/common/rules.md`를 최종 산출물로 남기지 않는다. +- sync.sh 를 거치지 않고 직접 파일을 복사하지 않는다 diff --git a/agent-ops/skills/common/version-bump/SKILL.md b/agent-ops/skills/common/version-bump/SKILL.md deleted file mode 100644 index 178447c..0000000 --- a/agent-ops/skills/common/version-bump/SKILL.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -name: version-bump -version: 1.0.0 -description: 프로젝트의 버전 정보를 업데이트한다. "버전 올려줘", "버전 변경" 요청 시 사용한다. ---- - -# version-bump - -## 목적 - -프로젝트의 버전 정보를 관리하며, 요청에 따라 버전을 올리거나 지정된 값으로 변경한다. - -## 언제 호출할지 - -- "버전 올려줘", "버전 변경해줘" 요청 시 -- 릴리스 준비 시 버전 업데이트가 필요할 때 -- patch, minor, major 버전 변경 요청 시 - -## 입력 - -- `version-type`: patch / minor / major 중 하나 (선택, 기본값: patch) -- `version-value`: 직접 지정할 버전 값 (선택, version-type과 배타적) - -## 먼저 확인할 것 - -- [ ] 버전 관리 파일(빌드 설정 또는 패키지 파일)이 프로젝트에 존재하는가 -- [ ] 현재 버전 값을 읽을 수 있는가 - -## 실행 절차 -1. 현재 버전 정보를 읽는다 -2. 사용자에게 변경할 버전을 확인한다 - - 인자 없으면: patch 버전 +1 - - 인자 있으면: 지정된 값으로 변경 -3. 버전 파일의 해당 값을 수정 -4. 변경 결과를 출력 - -## 버전 규칙 - -### 형식 -`major.minor.patch` (예: `1.0.0`) - -### 각 자리 제약 -| 자리 | 최대값 | 제약 | -|------|--------|------| -| major | 제한 없음 | 자유롭게 증가 | -| minor | 999 | 0~999 범위 | -| patch | 999 | 0~999 범위 | - -### 올림(carry) 규칙 -버전을 +1 할 때 해당 자리가 999이면 상위 자리를 올리고 현재 자리를 0으로 초기화한다. - -``` -patch +1 시: - patch < 999 → patch + 1 - patch = 999 → minor + 1, patch = 0 - (minor도 999이면 → major + 1, minor = 0, patch = 0) - -예시: - 1.0.998 → 1.0.999 - 1.0.999 → 1.1.0 - 1.999.999 → 2.0.0 -``` - -## 출력 형식 -``` -버전 업데이트 완료: -- 이전: 1.0.0 -- 이후: 1.0.1 -``` - -## 실행 결과 검증 - -- [ ] 버전 파일을 다시 읽어 변경된 버전 값이 의도한 값과 일치하는가 -- [ ] 버전 형식이 `major.minor.patch` 규칙을 준수하는가 (minor, patch가 0~999 범위) -- 검증 실패 시: 변경 전 버전과 현재 값을 사용자에게 보여주고 수동 확인을 요청한다 - -## 금지 사항 - -- 사용자 확인 없이 버전을 변경하지 않는다 -- 버전 형식(`major.minor.patch`)을 벗어나는 값으로 변경하지 않는다 -- minor, patch 값을 999 초과로 설정하지 않는다