diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..2948e58 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,42 @@ +# AGENTS.md + +## 문서 목적 +- 이 문서는 `/Users/klaus/Develop/sodalive/Admin/soda-creator-admin` 저장소에서 작업하는 에이전트용 실행 가이드다. +- 목표는 "추측 최소화 + 기존 패턴 준수 + 검증 우선"이다. +- 이 문서의 규칙은 코드/테스트/문서 변경 모두에 적용한다. + +## 커뮤니케이션 규칙 +- **"질문에 대한 답변과 설명은 한국어로 한다."** +- 이 저장소에서 사용자에게 전달하는 설명, 진행 상황, 결과 보고는 한국어로 작성한다. +- 코드 식별자, 경로, 명령어는 원문(영문) 그대로 유지한다. + +## 커밋 메시지 규칙 (표준 Conventional Commits) +- 기본 형식은 `(scope): `를 사용한다. +- `type`은 소문자(`feat`, `fix`, `chore`, `docs`, `refactor`, `test` 등)를 사용한다. +- 제목(description)은 한글로 작성하고, 명령형/간결한 현재형으로 작성한다. + +### 커밋 메시지 검증 절차 +- `git commit` 실행 직전에 `work/check-commit-message-rules.sh`를 실행해 규칙 준수 여부를 확인한다. +- `git commit` 실행 직후에도 `work/check-commit-message-rules.sh`를 다시 실행해 최종 메시지를 재검증한다. +- 스크립트 결과가 `[FAIL]`이면 커밋 메시지를 규칙에 맞게 수정한 뒤 다시 검증한다. + +## 작업 계획 문서 규칙 (docs) +- 모든 작업 시작 전에 `docs` 폴더 아래에 계획 문서를 먼저 생성하고, 해당 문서를 기준으로 구현을 진행한다. +- 계획 문서 파일명은 `[날짜]_구현할내용한글.md` 형식을 사용한다. +- 날짜는 `YYYYMMDD` 8자리 숫자를 사용한다. +- 파일명 예시: `20260101_구글계정으로로그인.md` +- 구현 항목은 기능/작업 단위로 분리해 체크박스(`- [ ]`) 목록으로 작성한다. +- 구현 완료 시마다 체크박스를 `- [x]`로 갱신하고, 각 항목이 정상 구현되었는지 확인한다. +- 작업 도중 범위가 변경되면 계획 문서의 체크박스 항목을 먼저 업데이트한 뒤 구현을 진행한다. +- 모든 구현이 끝난 후 결과 보고 시 계획 문서 맨 아래에 무엇을, 왜, 어떻게 검증했는지 한국어로 간단히 기록한다. +- 후속 수정이 발생해도 기존 검증 기록은 삭제/덮어쓰지 않고 누적한다(예: `1차 구현`, `2차 수정`). +- 검증 기록은 단계별로 `무엇을/왜/어떻게`를 유지해 작성하고, 이전 단계와 구분이 되도록 명시한다. +- 단계별 `어떻게`에는 실제 실행한 검증 명령과 결과(성공/실패/불가 사유)를 함께 기록한다. +- 기존 기록 정정이 필요하면 원문을 지우지 말고 `정정` 항목을 추가해 사유와 변경 내용을 남긴다. + +## 에이전트 동작 원칙 +- 추측하지 말고, 근거 파일을 읽고 결정한다. +- 기존 관례를 깨는 변경은 이유가 명확할 때만 수행한다. +- 불필요한 리팩터링 확장은 피하고 요청 범위를 우선 충족한다. +- 결과 보고 시 무엇을, 왜, 어떻게 검증했는지 한국어로 간단히 남긴다. +- diff --git a/docs/20260227_초기환경설정및가이드준수.md b/docs/20260227_초기환경설정및가이드준수.md new file mode 100644 index 0000000..b73ee35 --- /dev/null +++ b/docs/20260227_초기환경설정및가이드준수.md @@ -0,0 +1,18 @@ +# 20260227_초기환경설정및가이드준수 + +## 구현 항목 +- [x] AGENTS.md 파일 확인 및 내용 숙지 +- [x] work/check-commit-message-rules.sh 파일 확인 및 실행 권한 확인 +- [x] 변경 사항 스테이징 +- [x] 커밋 메시지 규칙 검증 +- [x] 가이드에 따른 커밋 수행 + +## 검증 기록 +### 1차 구현 +#### 무엇을 +- 초기 프로젝트 설정 파일(`AGENTS.md`, `work/check-commit-message-rules.sh`)을 커밋한다. +#### 왜 +- 에이전트 작업 가이드를 준수하고, 이후 작업의 기반을 마련하기 위함이다. +#### 어떻게 +- `work/check-commit-message-rules.sh --message "docs: 에이전트 작업 가이드 및 검증 스크립트 추가"` 명령으로 메시지 규칙을 검증했다. +- `git commit -m "docs: 에이전트 작업 가이드 및 검증 스크립트 추가"` 명령으로 커밋을 시도한다. diff --git a/work/check-commit-message-rules.sh b/work/check-commit-message-rules.sh new file mode 100755 index 0000000..f95abbe --- /dev/null +++ b/work/check-commit-message-rules.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash + +print_usage() { + echo "Usage:" + echo " $0" + echo " $0 " + echo " $0 --message \"\"" + echo " $0 --message-file " +} + +load_commit_message() { + if [ $# -eq 0 ]; then + local commit_ref="HEAD" + echo "Checking latest commit..." >&2 + git log -1 --pretty=format:"%s%n%b" "$commit_ref" + return + fi + + case "$1" in + -h|--help) + print_usage + exit 0 + ;; + --message) + shift + if [ $# -eq 0 ]; then + echo "[FAIL] --message option requires a commit message" + print_usage + exit 1 + fi + echo "Checking provided commit message..." >&2 + printf '%s' "$*" + ;; + --message-file) + shift + if [ $# -ne 1 ]; then + echo "[FAIL] --message-file option requires a file path" + print_usage + exit 1 + fi + if [ ! -f "$1" ]; then + echo "[FAIL] Commit message file not found: $1" + exit 1 + fi + echo "Checking commit message file: $1" >&2 + cat "$1" + ;; + *) + if [ $# -ne 1 ]; then + echo "[FAIL] Invalid arguments" + print_usage + exit 1 + fi + + local commit_ref="$1" + if ! git rev-parse --verify "$commit_ref^{commit}" >/dev/null 2>&1; then + echo "[FAIL] Invalid commit reference: $commit_ref" + exit 1 + fi + + echo "Checking commit: $commit_ref" >&2 + git log -1 --pretty=format:"%s%n%b" "$commit_ref" + ;; + esac +} + +commit_message=$(load_commit_message "$@") +subject=$(printf '%s\n' "$commit_message" | head -n1) +body=$(printf '%s\n' "$commit_message" | tail -n +2) + +echo "Checking commit message format..." +echo "Subject: $subject" + +exit_code=0 + +if [ -z "$subject" ]; then + echo "[FAIL] Subject must not be empty" + exit 1 +fi + +subject_pattern='^([a-z]+)(\([a-z0-9._/-]+\))?(!)?: (.+)$' +if [[ "$subject" =~ $subject_pattern ]]; then + type="${BASH_REMATCH[1]}" + description="${BASH_REMATCH[4]}" + + echo "[PASS] Subject follows Conventional Commit format" + echo "[PASS] Type is lowercase: $type" + + if printf '%s\n' "$description" | grep -Eq '[가-힣]'; then + echo "[PASS] Description contains Korean text" + else + echo "[FAIL] Description must contain Korean text" + exit_code=1 + fi +else + echo "[FAIL] Subject must match: (scope): " + echo " scope is optional, example: feat: 기능을 추가한다" + exit_code=1 +fi + +if [ -n "$body" ] && printf '%s\n' "$body" | grep -Eq '^Refs:'; then + while IFS= read -r refs_line; do + if ! printf '%s\n' "$refs_line" | grep -Eq '^Refs: #[0-9]+(, #[0-9]+)*$'; then + echo "[FAIL] Refs footer format is invalid: $refs_line" + echo " expected format: Refs: #123 or Refs: #123, #456" + exit_code=1 + fi + done < <(printf '%s\n' "$body" | grep -E '^Refs:') + + if [ $exit_code -eq 0 ]; then + echo "[PASS] Refs footer format is valid" + fi +fi + +if [ $exit_code -eq 0 ]; then + echo "[PASS] Commit message follows AGENTS.md rules" +else + echo "[FAIL] Commit message violates AGENTS.md rules" +fi + +exit $exit_code