Update project configuration files

This commit is contained in:
toki 2026-04-14 15:12:47 +09:00
parent 0fce3ac7ca
commit 976322bf17
28 changed files with 1795 additions and 116 deletions

16
.cursorrules Normal file
View file

@ -0,0 +1,16 @@
# 공통 규칙
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
아래 요청은 `agent-ops/skills/common/router.md`를 읽고 수행한다.
- agent-ops 초기화
- domain rule 생성
- skill 생성
- git commit / git push
- agent-ops 업데이트 / 진입 파일 재적용
`agent-ops/rules/project/rules.md`와
`agent-ops/rules/private/rules.md`를 읽고 작업을 시작한다. 파일이 없을경우 무시한다.

1
.gitignore vendored
View file

@ -56,3 +56,4 @@ release/
# End of https://www.toptal.com/developers/gitignore/api/dart,visualstudiocode
assets/data/app_data.json
.DS_Store
agent-ops/rules/private/

16
AGENTS.md Normal file
View file

@ -0,0 +1,16 @@
# 공통 규칙
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
아래 요청은 `agent-ops/skills/common/router.md`를 읽고 수행한다.
- agent-ops 초기화
- domain rule 생성
- skill 생성
- git commit / git push
- agent-ops 업데이트 / 진입 파일 재적용
`agent-ops/rules/project/rules.md`
`agent-ops/rules/private/rules.md`를 읽고 작업을 시작한다. 파일이 없을경우 무시한다.

129
CLAUDE.md
View file

@ -1,119 +1,16 @@
# OTO CLI Guide for AI Assistants
# 공통 규칙
## Project Overview
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
OTO CLI is a Dart command-line tool that executes build/deploy pipelines defined in YAML files.
It integrates with Jenkins, runs local test builds, and supports a scheduler mode.
아래 요청은 `agent-ops/skills/common/router.md`를 읽고 수행한다.
- agent-ops 초기화
- domain rule 생성
- skill 생성
- git commit / git push
- agent-ops 업데이트 / 진입 파일 재적용
## Execution Flow
```
bin/main.dart
└── Application (singleton)
└── DataComposer ← parses YAML + Jenkins env
└── Pipeline
└── Command.byType(CommandType) → Command.execute(DataCommand)
```
1. **`bin/main.dart`** Entry point. Registers three CLI commands: `template`, `exe`, `scheduler`.
2. **`lib/cli/commands/command_exe.dart`** Parses CLI flags (`-j` Jenkins, `-t` test, `-f` file path) and calls `Application.build()`.
3. **`lib/oto/application.dart`** Singleton. Owns `property` map, `commonData`, `commandStates`. Calls `registerAllCommands()` then runs the pipeline.
4. **`lib/oto/core/data_composer.dart`** Reads YAML and Jenkins env into structured data.
5. **`lib/oto/pipeline/pipeline.dart`** Iterates `DataCommand` list and dispatches to `Command.byType()`.
6. **`lib/oto/commands/command_registry.dart`** Single place where all `CommandType → Command` mappings are registered.
## BuildType Enum
Defined in `lib/oto/application.dart`:
| Value | Description |
|-------|-------------|
| `jenkins` | CI mode reads workspace and env from Jenkins environment variables |
| `test` | Local test mode uses hardcoded test data |
| `file` | Reads pipeline YAML from a local file path |
| `scheduler` | Scheduler daemon mode |
## Tag System (`lib/oto/core/tag_system.dart`)
Tags are resolved inside YAML values at runtime.
### Read tag: `<!namespace.key>`
Substitutes a value from the runtime store.
```yaml
param:
workspace: <!property.workspace> # flat property access
version: <!property.build.version> # nested property access
state: <!state.myCommandId> # command state (ready/progress/complete)
```
- If the tag occupies the **entire** string, the original type is returned (e.g. a List stays a List).
- If the tag is **embedded** in a string, it is converted via `toString()`.
### Write tag: `<@namespace.key>`
Stores the command result back into a property.
```yaml
param:
set-version: <@property.appVersion> # saves result into property["appVersion"]
```
Used via `Command.setProperty()` / `TagSystem.setPropertyValue()`.
## Adding a New Command
1. **Define data model** in the appropriate `lib/oto/data/*_data.dart` file, extending `DataParam`.
2. **Add enum value** to `CommandType` in `lib/oto/commands/command.dart`.
3. **Implement command class** extending `Command` with `execute(DataCommand)`.
4. **Register** in `lib/oto/commands/command_registry.dart`.
5. Run `dart run build_runner build` if you added a new `@JsonSerializable` class.
## Key Directory Structure
```
lib/
├── bin/main.dart # entry point
├── cli/commands/ # CLI-layer commands (exe, template, scheduler)
└── oto/
├── application.dart # singleton orchestrator, BuildType enum
├── commands/
│ ├── command.dart # Command base class, CommandType enum
│ ├── command_registry.dart # all command registrations
│ ├── build/ # iOS/Flutter/Dart/MSBuild build commands
│ ├── file/ # file operations (copy, rename, delete, zip…)
│ ├── git/ # git commands
│ ├── infra/ # FTP, SMB
│ ├── notification/ # Slack, Mattermost
│ ├── process/ # process management
│ └── util/ # timers, JSON, string utils
├── core/
│ ├── tag_system.dart # tag substitution engine
│ ├── data_composer.dart # YAML + env → structured data
│ └── defined_data.dart # built-in YAML templates
├── data/
│ ├── base_data.dart # DataParam (base), DataCommon (Jenkins env)
│ ├── command_data.dart # DataCommand (re-exports all data types)
│ └── *_data.dart # domain-specific data models
└── pipeline/
└── pipeline.dart # command dispatch loop
```
## Data Model Conventions
- All command parameters extend `DataParam` (`lib/oto/data/base_data.dart`).
- JSON serialization uses `json_annotation`. Generated files are `*.g.dart`.
- `*.g.dart` files are normally generated by `dart run build_runner build` but can be edited directly when needed.
- `DataCommon` holds Jenkins environment data (workspace, job name, build number, etc.).
- `DataCommand` (in `command_data.dart`) is the unified container passed to every `Command.execute()`.
## Error Handling
- `Application.build()` in `application.dart` uses `catch (e, stacktrace)` (not `on Exception`) to also catch `Error` subtypes such as `TypeError`.
- On error, `exit(10)` is called to signal failure to the parent process.
## Workspace Resolution (Command base class)
`getWorkspace()` in `command.dart` resolves in this order:
1. `workspace` field on the command's data model
2. `property['workspace']` in the global property map
3. `commonData.workspace` (Jenkins environment)
`agent-ops/rules/project/rules.md`
`agent-ops/rules/private/rules.md`를 읽고 작업을 시작한다. 파일이 없을경우 무시한다.

16
GEMINI.md Normal file
View file

@ -0,0 +1,16 @@
# 공통 규칙
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
아래 요청은 `agent-ops/skills/common/router.md`를 읽고 수행한다.
- agent-ops 초기화
- domain rule 생성
- skill 생성
- git commit / git push
- agent-ops 업데이트 / 진입 파일 재적용
`agent-ops/rules/project/rules.md`
`agent-ops/rules/private/rules.md`를 읽고 작업을 시작한다. 파일이 없을경우 무시한다.

1
agent-ops/.version Normal file
View file

@ -0,0 +1 @@
1.1.2

168
agent-ops/GUIDE.md Normal file
View file

@ -0,0 +1,168 @@
# Agent Context Framework 적용 가이드
이 문서는 `agent-ops/` 폴더를 프로젝트에 복사한 뒤 참고하는 가이드입니다.
---
## 간단 적용
**1. `agent-ops/` 폴더를 타겟 프로젝트 루트에 복사합니다.**
**2. 에이전트에게 아래와 같이 정확한 경로를 지정해 초기화를 요청합니다.**
> 초기 세팅 전에는 진입 파일(CLAUDE.md 등)이 없어 라우팅이 불가능하므로, 반드시 스킬 파일 경로를 직접 안내해야 합니다.
```
agent-ops/skills/common/init-agent-ops/SKILL.md 를 읽고 실행해줘.
```
`init-agent-ops` 스킬이 프로젝트를 분석하고 다음을 자동 생성합니다.
- 진입 파일 (CLAUDE.md 등)
- `rules/project/rules.md`
- `rules/project/domain/<name>/rules.md`
---
## 구성
```
agent-ops/
├── GUIDE.md # 이 파일 (적용 가이드)
├── .version # 프레임워크 버전 (타겟 프로젝트 버전 추적용)
├── rules/
│ ├── common/ # 공통 규칙 (수정 금지)
│ │ ├── rules.md # 공통 규칙 (에이전트 진입 파일로 사용)
│ │ └── _templates/
│ │ └── domain-rule-template.md
│ ├── project/ # 프로젝트 규칙 (수정 가능)
│ │ ├── rules.md # 프로젝트 특화 규칙 (init-agent-ops가 생성)
│ │ └── domain/ # 도메인별 규칙
│ │ └── <domain-name>/rules.md
│ └── private/ # 개인 규칙 (git 제외, 선택)
│ └── rules.md
└── skills/
├── common/ # 공통 스킬 (수정 금지)
│ ├── router.md # 공통 스킬 라우터
│ ├── _templates/
│ │ └── skill-template.md
│ ├── init-agent-ops/SKILL.md # scaffold 초기화
│ ├── sync-agent-ops/SKILL.md # 진입 파일 재적용
│ ├── commit-push/SKILL.md # 커밋 & 푸시
│ ├── create-domain-rule/SKILL.md # 도메인 규칙 생성
│ ├── create-skill/SKILL.md # 스킬 생성
│ └── version-bump/SKILL.md # 버전 업데이트
└── project/ # 프로젝트 스킬 (수정 가능)
└── <skill-name>/SKILL.md
```
---
## 적용 방법
### 1. 복사
이 레포의 `agent-ops/` 폴더를 타겟 프로젝트 루트에 복사합니다.
```
project-root/
├── agent-ops/ ← 복사
└── ...
```
### 2. 진입 파일 배치
`agent-ops/rules/common/rules.md`를 사용하는 에이전트에 맞는 파일명으로 프로젝트 루트에 복사합니다.
| 에이전트 | 파일명 |
|---------|--------|
| Claude | `CLAUDE.md` |
| Gemini | `GEMINI.md` |
| Kilo Code / OpenCode | `AGENTS.md` |
| Cursor | `.cursorrules` |
| Cline | `.clinerules` |
```
project-root/
├── CLAUDE.md ← rules/common/rules.md 복사
├── agent-ops/
└── ...
```
### 3. scaffold 스킬 실행
AI 에이전트에게 초기화를 요청합니다.
```
agent-ops 초기화해줘.
```
에이전트가 프로젝트 구조를 분석하고 다음을 자동 생성합니다:
- `rules/project/rules.md` — 프로젝트 특화 규칙 (응답 언어, 프로젝트 개요, 기술 스택)
- `rules/project/domain/<name>/rules.md` — 도메인별 규칙 초안
### 4. 개인 규칙 설정 (선택)
`agent-ops/rules/private/rules.md`를 생성하여 개인 선호 규칙을 정의할 수 있습니다.
- 응답 언어, 출력 스타일 등 개인 설정
- 팀 공통 규칙(`project/rules.md`)과 충돌하지 않는 범위에서 자유롭게 작성
- `.gitignore``agent-ops/rules/private/`가 추가되어 있으므로 커밋되지 않습니다
### 6. 내용 확인 및 보완
스킬 실행 후 다음 항목을 확인합니다.
| 파일 | 확인할 내용 |
|------|------------|
| `rules/project/rules.md` | 응답 언어, 프로젝트 개요, 기술 스택, 특화 컨벤션, 도메인 매핑 테이블 |
| `rules/project/domain/*/rules.md` | 도메인별 경로, 구성 요소, 패턴, 경계 |
### 7. 개발 시작
구성이 완료되면 에이전트는 모든 작업 요청 시 자동으로 rules와 skills를 참조합니다.
---
## 파일 흐름
```
진입 파일 (CLAUDE.md 등) = rules/common/rules.md 내용
→ skills/common/router.md (공통 스킬 요청 시)
→ skills/common/<skill>/SKILL.md
→ rules/project/rules.md
→ skills/project/<skill>/SKILL.md 또는 rules/project/domain/<name>/rules.md
```
---
## 공통 파일 수정 보호
에이전트는 프로젝트 루트의 `.agent-ops-source` 마커 파일 유무로 공통 파일 수정 가능 여부를 판단합니다.
| 마커 | 의미 | 공통 파일 수정 |
|------|------|--------------|
| `.agent-ops-source` 있음 | 공통 관리 레포 | 허용 |
| `.agent-ops-source` 없음 | 타겟 프로젝트 | **금지** |
**중요**: `agent-ops/` 폴더를 타겟 프로젝트에 복사할 때 `.agent-ops-source` 파일은 복사하지 마세요. 이 파일은 `agent-ops/` 밖(프로젝트 루트)에 있으므로 `agent-ops/` 폴더만 복사하면 자연스럽게 제외됩니다.
수정이 필요한 경우 공통 관리 레포에 반영하고, 해당 변경 내용을 각 프로젝트에 수동으로 싱크합니다.
각 공통 파일의 frontmatter에는 개별 `version`이 명시되어 있습니다.
프레임워크 전체 버전은 `agent-ops/.version` 파일에 기록됩니다. `init-agent-ops` 실행 시 이 파일이 타겟 프로젝트에 함께 복사되므로, 타겟 프로젝트의 `agent-ops/.version`을 확인하면 어느 시점의 프레임워크를 기반으로 하는지 파악할 수 있습니다.
---
## 수정 가능 / 불가능 파일 구분
| 구분 | 파일 | 수정 |
|------|------|------|
| 공통 (수정 금지) | `.version` | 공통 레포에서만 수정 |
| 공통 (수정 금지) | `rules/common/rules.md` | 공통 레포에서만 수정 |
| 공통 (수정 금지) | `rules/common/_templates/*.md` | 공통 레포에서만 수정 |
| 공통 (수정 금지) | `skills/common/*/SKILL.md` (공통 스킬) | 공통 레포에서만 수정 |
| 공통 (수정 금지) | `skills/common/_templates/*.md` | 공통 레포에서만 수정 |
| 프로젝트 (수정 가능) | `rules/project/rules.md` | 프로젝트에 맞게 수정 |
| 프로젝트 (수정 가능) | `rules/project/domain/*/rules.md` | 프로젝트에 맞게 수정 |
| 프로젝트 (수정 가능) | `skills/project/*/SKILL.md` (프로젝트 스킬) | 자유롭게 수정 |

28
agent-ops/bin/bump-version.sh Executable file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# bump-version.sh <version>
# patch +1, 999 초과 시 minor 올림. major는 수동 관리.
# 결과 버전을 stdout으로 출력.
set -euo pipefail
YELLOW='\033[1;33m'; RESET='\033[0m'
VERSION="${1:-}"
if [[ -z "$VERSION" ]]; then
echo "사용법: $0 <major.minor.patch>" >&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"

173
agent-ops/bin/sync.sh Executable file
View file

@ -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 <target>"
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}"

View file

@ -0,0 +1,29 @@
# <domain-name>
## 목적 / 책임
< 도메인이 담당하는 책임을 1~2문장으로>
## 포함 경로
- `<path>/`< 경로가 도메인에 속하는 이유>
## 제외 경로
- `<path>/`< 도메인이 아닌지>
## 주요 구성 요소
- `<ClassName>`<역할>
## 유지할 패턴
- <네이밍 규칙 또는 아키텍처 패턴>
## 다른 도메인과의 경계
- **<인접 domain>**: <어디까지가 도메인이고 어디서부터 도메인인지>
## 금지 사항
- < 도메인 코드에서 하면 되는 >

View file

View file

@ -0,0 +1,39 @@
# cli
## 목적 / 책임
사용자로부터 CLI 인자를 받아 파싱하고, `Application`을 통해 파이프라인을 시작하거나 스케줄러 데몬을 관리하는 진입 계층이다.
## 포함 경로
- `lib/cli/` — CLI 레이어 전체 (명령 파싱, 스케줄러 관리)
## 제외 경로
- `lib/oto/` — 비즈니스 로직·파이프라인 엔진 (cli는 진입만 담당)
## 주요 구성 요소
- `Cli` (`cli.dart`) — CLI 루트 객체
- `CommandExe``-j`(Jenkins), `-t`(test), `-f`(file) 플래그 파싱 → `Application.build()` 호출
- `CommandInstall` — PATH 등록 (`install/regist_path.dart`)
- `CommandScheduler` — 스케줄러 데몬 시작
- `CommandStart` — 시작 커맨드
- `CommandTemplate` — 템플릿 출력
- `CommandManager` — CLI 커맨드 등록 관리
- `SchedulerManager` — 스케줄러 실행 조정 (interval, isolate, OS별 구현)
## 유지할 패턴
- CLI 커맨드는 `CommandBase` 상속
- OS별 스케줄러는 `scheduler_linux.dart` / `scheduler_osx.dart` / `scheduler_windows.dart` 분리 유지
## 다른 도메인과의 경계
- **pipeline/command**: cli는 `Application.build()`만 호출. 파이프라인·커맨드 내부를 직접 참조하지 않는다
- **core**: DataComposer 호출은 Application 내부에서 이루어지며 cli는 관여하지 않는다
## 금지 사항
- cli 레이어에서 Pipeline 또는 Command를 직접 인스턴스화하지 않는다
- 비즈니스 로직을 cli 커맨드 핸들러에 넣지 않는다

View file

@ -0,0 +1,49 @@
# command
## 목적 / 책임
외부 시스템(Git, Jenkins, FTP, Slack, iOS 빌드 등)과의 실제 연동을 구현하는 커맨드 계층과, 커맨드 파라미터 데이터 모델을 담당한다.
## 포함 경로
- `lib/oto/commands/` — 커맨드 구현체 (카테고리별 하위 폴더)
- `lib/oto/data/` — 커맨드 파라미터 데이터 모델 (`*_data.dart`, `*.g.dart`)
## 제외 경로
- `lib/oto/pipeline/` — 실행 흐름 제어 (커맨드 dispatch 이전)
- `lib/oto/core/` — 태그 치환, 데이터 합성 (커맨드 실행 이전)
## 주요 구성 요소
- `Command` (`command.dart`) — 커맨드 베이스 클래스, `CommandType` enum
- `CommandRegistry` (`command_registry.dart`) — CommandType → Command 매핑 등록소
- `DataParam` (`base_data.dart`) — 모든 커맨드 파라미터의 베이스
- `DataCommand` (`command_data.dart`) — 모든 커맨드에 전달되는 통합 컨테이너
커맨드 카테고리:
- `build/` — iOS/Flutter/Dart/MSBuild/.NET 빌드
- `file/` — 파일 복사·삭제·이름 변경·압축
- `git/` — Git, GitHub 연동
- `ftp/` — FTP 업로드·다운로드
- `notification/` — Slack, Mattermost 알림
- `jenkins/` — Jenkins API 연동
- `aws/`, `docker/`, `gradle/`, `proto/`, `jira/`, `infra/`, `shell/`, `web/`, `process/`, `util/`
## 유지할 패턴
- 새 커맨드는 반드시 `Command` 상속 후 `CommandRegistry`에 등록
- 파라미터 모델은 `DataParam` 상속 + `@JsonSerializable`
- `*.g.dart``dart run build_runner build`로 생성 (필요 시 직접 수정 가능)
- `getWorkspace()`: workspace 필드 → `property['workspace']``commonData.workspace` 순으로 resolve
## 다른 도메인과의 경계
- **pipeline**: `Command.execute(DataCommand)`를 호출하는 시점이 경계. 커맨드는 흐름을 모른다
- **core**: 태그 치환은 core가 완료한 후 DataCommand가 커맨드에 전달됨
## 금지 사항
- 커맨드에서 다른 커맨드를 직접 인스턴스화하거나 호출하지 않는다
- 흐름 제어(if/loop) 로직을 커맨드 내부에 넣지 않는다
- `CommandRegistry` 외 장소에서 CommandType 매핑을 추가하지 않는다

View file

@ -0,0 +1,37 @@
# core
## 목적 / 책임
파이프라인 실행 전 단계에서 YAML 파싱, Jenkins 환경 변수 합성, 태그 치환을 담당하는 공통 인프라 레이어다.
## 포함 경로
- `lib/oto/core/` — 태그 시스템, 데이터 합성, 정의 데이터
- `lib/oto/utils/` — 공통 유틸리티 (Mattermost 등 재사용 헬퍼)
## 제외 경로
- `lib/oto/pipeline/` — 실행 흐름 (core 처리 이후)
- `lib/oto/commands/` — 커맨드 구현체 (core 결과물을 소비)
## 주요 구성 요소
- `TagSystem` (`tag_system.dart`) — `<!namespace.key>` 읽기 / `<@namespace.key>` 쓰기 태그 처리
- `DataComposer` (`data_composer.dart`) — YAML + Jenkins env → `DataCommand` 리스트 변환
- `DefinedData` (`defined_data.dart`) — 내장 YAML 템플릿 (빌트인 정의)
- `MattermostSender` / `MattermostData` (`utils/mattermost/`) — 공통 알림 헬퍼
## 유지할 패턴
- 태그 치환은 반드시 `TagSystem`을 통해 처리
- 태그 전체 문자열이면 원본 타입 유지, 부분 삽입이면 `toString()` 변환 원칙 유지
## 다른 도메인과의 경계
- **pipeline**: DataComposer가 DataCommand 리스트 생성을 완료한 후 Pipeline이 실행 시작
- **command**: 커맨드 실행 중 쓰기 태그(`<@...>`) 처리는 TagSystem에 위임
## 금지 사항
- core에서 외부 시스템(Git, Jenkins API 등)을 직접 호출하지 않는다
- 커맨드별 파싱 로직을 DataComposer에 넣지 않는다

View file

@ -0,0 +1,40 @@
# pipeline
## 목적 / 책임
YAML에서 파싱된 `DataCommand` 리스트를 순차 실행하고, 조건 분기·반복·대기 등 파이프라인 흐름 제어를 담당한다.
## 포함 경로
- `lib/oto/pipeline/` — 파이프라인 실행 엔진 전체
## 제외 경로
- `lib/oto/commands/` — 실제 커맨드 구현체 (pipeline은 dispatch만 한다)
- `lib/oto/core/` — 태그 치환·데이터 합성 (pipeline 이전 단계)
## 주요 구성 요소
- `Pipeline` — 커맨드 디스패치 루프
- `PipelineExe` — 단일 커맨드 실행 핸들
- `PipelineExeHandle` — 실행 결과 처리
- `PipelineCondition` — 조건 평가
- `PipelineIf` / `PipelineSwitch` — 분기 흐름
- `PipelineForeach` / `PipelineWhile` — 반복 흐름
- `PipelineContain` — 중첩 파이프라인
- `PipelineWaitUntil` — 대기 흐름
## 유지할 패턴
- 파이프라인 노드는 단일 책임: 흐름 제어만 한다, I/O는 커맨드에 위임
- 새 흐름 제어 유형은 `Pipeline*` 네이밍으로 추가
## 다른 도메인과의 경계
- **command**: `Pipeline``Command.byType()`을 호출하는 시점이 경계. 커맨드 내부 로직은 pipeline이 모른다
- **core**: `DataComposer`가 YAML → `DataCommand` 변환을 마친 후 pipeline이 실행 시작
## 금지 사항
- pipeline 코드에서 외부 시스템(Git, Jenkins 등)을 직접 호출하지 않는다
- 커맨드별 비즈니스 로직을 pipeline에 넣지 않는다

View file

@ -0,0 +1,86 @@
# oto_cli 프로젝트 규칙
## 응답 언어
한국어로 응답한다.
## 프로젝트 개요
OTO CLI는 YAML 파일로 정의된 빌드/배포 파이프라인을 실행하는 Dart CLI 도구다.
Jenkins, FTP, Git, Slack/Mattermost, iOS/Flutter/Android 빌드 등 다양한 CI/CD 작업을 커맨드로 추상화하고 파이프라인 엔진이 순차 실행한다.
## 실행 흐름
```
bin/main.dart
└── Application (singleton)
└── DataComposer ← YAML + Jenkins env 파싱
└── Pipeline
└── Command.byType(CommandType) → Command.execute(DataCommand)
```
## 주요 구조
```
lib/
├── cli/ # CLI 레이어 (명령 파싱, 스케줄러 관리)
└── oto/
├── application.dart # 싱글턴 오케스트레이터, BuildType enum
├── commands/ # 커맨드 구현체 (카테고리별)
├── core/ # 태그 시스템, 데이터 합성, 정의 데이터
├── data/ # JSON 직렬화 데이터 모델
└── pipeline/ # 파이프라인 실행 엔진
```
## 기술 스택
- 언어: Dart (SDK >=2.18.6 <4.0.0)
- 의존성: dart_framework (커스텀), http, json_annotation, cron, xml
- 코드 생성: json_serializable + build_runner (`dart run build_runner build`)
## BuildType
| Value | 설명 |
|-------|------|
| `jenkins` | CI 모드 Jenkins 환경 변수에서 워크스페이스·환경 읽기 |
| `test` | 로컬 테스트 모드 하드코딩된 테스트 데이터 사용 |
| `file` | 로컬 파일 경로에서 파이프라인 YAML 읽기 |
| `scheduler` | 스케줄러 데몬 모드 |
## 태그 시스템 (`lib/oto/core/tag_system.dart`)
- **읽기 태그** `<!namespace.key>` — 런타임 저장소에서 값 치환
- **쓰기 태그** `<@namespace.key>` — 커맨드 결과를 property에 저장
태그가 문자열 전체인 경우 원본 타입 유지 (List 등), 부분 삽입이면 toString() 변환.
## 데이터 모델 컨벤션
- 모든 커맨드 파라미터는 `DataParam` (`lib/oto/data/base_data.dart`) 상속
- JSON 직렬화: `json_annotation` 사용, 생성 파일은 `*.g.dart`
- `DataCommon` Jenkins 환경 데이터 (workspace, job name, build number 등)
- `DataCommand` (`command_data.dart`) 모든 `Command.execute()`에 전달되는 통합 컨테이너
## 새 커맨드 추가 절차
1. `lib/oto/data/*_data.dart`에 데이터 모델 정의 (`DataParam` 상속)
2. `lib/oto/commands/command.dart``CommandType` enum에 값 추가
3. `Command` 상속하여 커맨드 클래스 구현
4. `lib/oto/commands/command_registry.dart`에 등록
5. `@JsonSerializable` 클래스 추가 시 `dart run build_runner build` 실행
## 에러 처리
- `Application.build()``catch (e, stacktrace)` (Exception이 아닌 Error 포함 캐치)
- 에러 시 `exit(10)` 호출로 부모 프로세스에 실패 신호 전달
## 도메인 매핑
| 경로 패턴 | 도메인 | rules.md |
|----------|--------|----------|
| `lib/oto/pipeline/**` | pipeline | `agent-ops/rules/project/domain/pipeline/rules.md` |
| `lib/oto/commands/**` | command | `agent-ops/rules/project/domain/command/rules.md` |
| `lib/oto/data/**` | command | `agent-ops/rules/project/domain/command/rules.md` |
| `lib/cli/**` | cli | `agent-ops/rules/project/domain/cli/rules.md` |
| `lib/oto/core/**` | core | `agent-ops/rules/project/domain/core/rules.md` |
| `lib/oto/utils/**` | core | `agent-ops/rules/project/domain/core/rules.md` |

View file

@ -0,0 +1,57 @@
---
name: <skill-name>
version: 1.0.0
description: < skill이 하는 일을 줄로 설명. 트리거 키워드 포함 권장>
depends: [<other-skill>] # 선택 — 의존 skill이 없으면 이 줄 삭제
---
# <skill-name>
## 목적
< skill이 해결하는 문제를 1~2문장으로 설명>
## 언제 호출할지
- < skill을 호출해야 하는 상황 1>
- < skill을 호출해야 하는 상황 2>
- < skill을 호출해야 하는 상황 3>
## 입력
- `<param-name>`: <설명> (필수)
- `<param-name>`: <설명> (선택)
## 먼저 확인할 것
- [ ] <실행 반드시 확인해야 조건 1>
- [ ] <실행 반드시 확인해야 조건 2>
## 실행 절차
1. **<단계명>**
- <세부 행동>
- <세부 행동>
2. **<단계명>**
- <세부 행동>
3. **결과 보고**
- <출력할 내용>
## 실행 결과 검증
- [ ] <실행 확인해야 성공 조건 1>
- [ ] <실행 확인해야 성공 조건 2>
- 검증 실패 시: <실패 취할 행동 롤백, 사용자 알림, 재시도 >
## 출력 형식
```
<출력 예시>
```
## 금지 사항
- <절대 하면 되는 >
- <절대 하면 되는 >

View file

@ -0,0 +1,218 @@
---
name: code-review
description: Review completed implementation work in the current repository. Reads PLAN.md and CODE_REVIEW.md from the active task, reviews the actual changed source files, appends a verdict to CODE_REVIEW.md, then archives both files as .log. On PASS, writes complete.log summarising the full loop history. If Required or Suggested issues are found (FAIL or WARN), writes a new PLAN.md and CODE_REVIEW.md stub so the loop continues immediately. Nit-only findings may still PASS.
---
# Code Review
## Purpose
Review the implementation phase of the plan-code-review loop:
```text
plan skill -> implementation -> code-review skill
^ |
+----- issues found: new PLAN.md
```
## Workflow Contract
Active work must live at `agent-task/{task_name}/PLAN.md` and `agent-task/{task_name}/CODE_REVIEW.md`. These paths are the state protocol shared with the plan skill. Do not adapt them per repository unless the whole loop contract is intentionally changed in both skills.
Directory states:
| State | Meaning |
|-------|---------|
| `PLAN.md` + `CODE_REVIEW.md` | Ready for review |
| `complete.log` + `*.log` files | Task complete (PASS) |
| Only `*.log` files (no `complete.log`) | Task terminated mid-loop or abandoned |
The implementing agent never archives or deletes active files; archiving is this skill's responsibility.
## Step 1 - Find Active Task
Glob `agent-task/*/CODE_REVIEW.md`:
| Result | Action |
|--------|--------|
| Exactly one | Review that task; `PLAN.md` is expected beside it |
| None | Nothing to review; stop and report |
| Multiple | List paths and ask which task to review |
## Step 2 - Load Context
Count `agent-task/{task_name}/code_review_*.log`:
- `0`: first review. Read `CODE_REVIEW.md`, `PLAN.md`, every planned source file, related tests, and files importing/imported by changed files up to 2 levels deep.
- `>=1`: follow-up review. Start with `git diff`, `git diff --cached`, and `git log --oneline -5`, then expand to related callers, implementers, tests, and any planned files missing from the diff.
The diff is the starting point, not the boundary. Follow behavior and API connections far enough to judge correctness.
## Step 3 - Pre-Review Checklist
Before writing the verdict:
- Compare actual source files against every planned checklist item.
- Grep renamed/removed symbols for stale references.
- Confirm every required test exists, name matches, and assertions are meaningful.
- Cross-check claimed verification output in `CODE_REVIEW.md` against actual code and project commands.
- For follow-up reviews, compare diff against the plan and scan for unplanned changes, debug prints, dead code, TODOs, formatting-only noise, and unrelated edits.
## Step 4 - Append Verdict
Append `코드리뷰 결과` to `CODE_REVIEW.md`.
Required fields:
- `종합 판정`: exactly `PASS`, `WARN`, or `FAIL`.
- `차원별 평가`: Pass/Warn/Fail for correctness, completeness, test coverage, API contract, code quality, plan deviation, verification trust.
- `발견된 문제`: `없음`, or bullets using `Required`, `Suggested`, or `Nit` with `file:line` and a concrete fix.
- `다음 단계`: keep only the matching PASS/WARN/FAIL line.
Severity semantics:
| Verdict | Meaning | Follow-up plan |
|---------|---------|----------------|
| `PASS` | No Required/Suggested issues. Nit-only findings may still PASS. | No |
| `WARN` | One or more Suggested issues, zero Required. | Yes |
| `FAIL` | One or more Required issues. | Yes |
Issue severity:
- `Required`: correctness, API contract, missing required test, or plan-completeness issue.
- `Suggested`: useful improvement that should enter the loop but does not block correctness.
- `Nit`: tiny cleanup; may be recorded without forcing WARN.
## Step 5 - Archive Active Files
Archive order is fixed:
1. Count existing `code_review_*.log` as `N`; rename `CODE_REVIEW.md` to `code_review_N.log`.
2. Count existing `plan_*.log` as `M`; rename `PLAN.md` to `plan_M.log`.
After archiving, neither active `.md` file remains unless Step 6 writes a follow-up.
## Step 6 - Post-Review Actions
For `PASS`, write `agent-task/{task_name}/complete.log` before reporting:
Required fields in `complete.log`:
- `완료 일시`: date completed.
- `요약`: one-line task description and loop count.
- `루프 이력`: table of plan/code_review log pairs with their verdict.
- `최종 리뷰 요약`: bullet list of what was implemented.
- `잔여 Nit`: any Nit-only findings recorded but not acted on (omit section if none).
Then report:
- Verdict.
- Archive filenames.
- `complete.log` written; task complete.
For `WARN` or `FAIL`, write a new `PLAN.md` and `CODE_REVIEW.md` stub using the plan skill format:
- New plan number is the count of `plan_*.log` after archive.
- Header tag is `REVIEW_<PARENT_TAG>`.
- `FAIL`: one plan item per Required issue.
- `WARN`: one grouped plan item for Suggested issues, plus related Nit issues if useful.
- Each plan item needs problem, solution with before/after when non-trivial, checklist, test decision, intermediate verification.
`CODE_REVIEW.md` stub template (fill `{…}` placeholders; everything else is fixed and must not be changed by the implementing agent):
```markdown
<!-- task={task_name} plan={N} tag={TAG} -->
# Code Review Reference - {TAG}
## 개요
date={YYYY-MM-DD}
task={task_name}, plan={N}, tag={TAG}
## 이 파일을 읽는 리뷰 에이전트에게
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.
1. `CODE_REVIEW.md``code_review_N.log` (N = 기존 code_review_*.log 수)
2. `PLAN.md``plan_M.log` (M = 기존 plan_*.log 수)
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.
---
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [{TAG}-1] {item description} | [ ] |
| [{TAG}-2] {item description} | [ ] |
## 계획 대비 변경 사항
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
## 주요 설계 결정
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
## 리뷰어를 위한 체크포인트
{pre-filled from plan — one bullet per review focus area}
## 검증 결과
_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._
### {TAG}-1 중간 검증
```
$ {verification command from plan}
(output)
```
### 최종 검증
```
$ {final verification command from plan}
(output)
```
```
Sections and their ownership:
| 섹션 | 소유자 | 설명 |
|------|--------|------|
| 헤더 주석, 개요(date/task/plan/tag), 리뷰 에이전트 지시 | 스텁 생성 시 고정 | 구현 에이전트가 수정하지 않음 |
| 구현 항목별 완료 여부 (항목명) | 스텁 생성 시 고정 | `[ ]``[x]` 체크만 구현 에이전트가 수행 |
| 계획 대비 변경 사항, 주요 설계 결정 | 구현 에이전트가 채움 | placeholder 텍스트를 실제 내용으로 교체 |
| 리뷰어를 위한 체크포인트 | 스텁 생성 시 고정 | 계획에서 추출한 리뷰 포인트 |
| 검증 결과 (섹션 제목 + 명령) | 스텁 생성 시 고정 | 실행 출력만 구현 에이전트가 채움 |
| 코드리뷰 결과 | 리뷰 에이전트가 append | 스텁에 포함하지 않음 |
Report Required/Suggested counts, archive names, and the new plan path.
## Review Dimensions
| Dimension | Check |
|-----------|-------|
| Correctness | Logic, edge cases, concurrency, errors |
| Completeness | All planned checklist items done |
| Test coverage | Required tests present and meaningful |
| API contract | Call sites, compatibility, docs |
| Code quality | No debug prints, dead code, leftover TODOs |
| Plan deviation | Deviations justified, no unrelated risk |
| Verification trust | Reported output matches actual code |
## Quality Rules
- Lead with findings; use specific `file:line`.
- Provide a concrete fix for every Required issue.
- Name exact stale symbols or missing tests.
- Do not write vague praise or style opinions without a rule.
- Every dimension gets Pass/Warn/Fail.
## Final Checklist
- `code_review_N.log` exists with verdict appended.
- `plan_M.log` exists.
- No active `.md` files remain after PASS.
- PASS: `complete.log` written with loop history, implementation summary, and residual Nits.
- WARN/FAIL: new active `PLAN.md` and `CODE_REVIEW.md` created with matching headers; no `complete.log`.

View file

@ -0,0 +1,4 @@
interface:
display_name: "Code Review"
short_description: "Review task implementation"
default_prompt: "Use $code-review to review the active repository task and archive or continue the loop."

View file

@ -0,0 +1,124 @@
---
name: commit-push
version: 1.0.0
description: 변경 사항을 커밋하고 원격에 푸시한다. "커밋해줘", "푸시해줘", "커밋하고 푸시" 요청 시 사용한다.
---
# commit-push
## 목적
현재 변경 내용을 분석하여 한국어 커밋 메시지를 작성하고, 커밋 및 푸시를 수행한다.
## 언제 호출할지
- "커밋해줘", "커밋하고 푸시해줘" 요청 시
- "변경 사항 올려줘", "푸시해줘" 요청 시
- 코드 작업 완료 후 "반영해줘", "올려줘" 요청 시
## 입력
- `scope`: 커밋 범위 — all(전체) 또는 특정 파일/경로 (선택, 기본값: all)
- `push`: 푸시 여부 (선택, 기본값: true)
## 먼저 확인할 것
- [ ] 커밋할 변경 사항이 존재하는가 (`git status`로 확인)
- [ ] 현재 브랜치가 올바른 브랜치인가
- [ ] `.env`, 시크릿 파일 등 민감한 파일이 스테이징에 포함되어 있지 않은가
## 실행 절차
1. **변경 사항 파악**
- `git status`로 변경/추가/삭제된 파일 목록을 확인한다
- `git diff`로 구체적인 변경 내용을 확인한다
- 변경 사항이 없으면 사용자에게 알리고 종료한다
2. **민감 파일 검사**
- 스테이징 대상에 아래 패턴이 포함되면 해당 파일을 제외하고 사용자에게 경고한다
- `.env`, `.env.*`
- `*secret*`, `*credential*`, `*password*`
- `*.pem`, `*.key`, `*.p12`
- `.gitignore`에 이미 등록된 파일은 무시한다
3. **커밋 메시지 작성**
- 변경 내용을 분석하여 한국어로 커밋 메시지를 작성한다
- 아래 메시지 규칙을 따른다
4. **사용자 확인**
- 커밋 메시지와 대상 파일 목록을 보여주고 승인을 받는다
- 사용자가 메시지 수정을 요청하면 반영한다
5. **커밋 실행**
- scope에 따라 파일을 스테이징한다
- all: 변경된 전체 파일을 개별적으로 `git add`
- 특정 경로: 해당 파일만 `git add`
- 승인된 메시지로 `git commit`을 실행한다
6. **푸시 실행**
- push가 true인 경우에만 실행한다
- 현재 브랜치를 원격에 푸시한다
- 원격 브랜치가 없으면 `-u origin {branch}`로 설정한다
- 충돌 발생 시 사용자에게 알리고 중단한다
7. **결과 보고**
- 커밋 해시, 메시지, 변경 파일 수, 푸시 결과를 출력한다
## 커밋 메시지 규칙
### 형식
```
<타입>: <변경 요약>
<본문> (선택)
```
### 타입 목록
| 타입 | 용도 |
|------|------|
| 기능 | 새로운 기능 추가 |
| 수정 | 버그 수정 |
| 개선 | 기존 기능 개선, 리팩토링 |
| 문서 | 문서 추가/수정 |
| 설정 | 빌드, CI/CD, 설정 파일 변경 |
| 테스트 | 테스트 추가/수정 |
| 정리 | 코드 정리, 불필요 코드 제거 |
### 작성 원칙
- **한국어**로 작성한다
- 요약은 50자 이내로 간결하게 작성한다
- 요약은 "~한다" 형태의 서술형으로 끝낸다 (예: "로그인 검증 로직을 추가한다")
- 본문은 **무엇을** 변경했는지가 아니라 **왜** 변경했는지를 쓴다
- 변경 파일이 3개 이하이면 본문을 생략할 수 있다
- 여러 성격의 변경이 섞여 있으면 가장 핵심적인 변경을 기준으로 타입을 정한다
## 출력 형식
```
## 커밋 완료
- 브랜치: {브랜치명}
- 커밋: {해시} — {커밋 메시지 요약}
- 변경 파일: {n}개
- {파일 경로}: {변경 유형}
- 푸시: {성공/생략/실패}
```
## 실행 결과 검증
- [ ] `git log -1`로 방금 생성한 커밋이 존재하고, 메시지가 승인된 내용과 일치하는가
- [ ] 커밋에 포함된 파일 목록이 의도한 scope와 일치하는가 (`git diff-tree --no-commit-id --name-only -r HEAD`)
- [ ] push가 true인 경우, `git status`에서 "Your branch is up to date" 또는 원격과 동기화 상태인가
- 검증 실패 시: 실패 원인(커밋 누락, 푸시 실패 등)을 사용자에게 알리고 재시도 여부를 확인한다
## 금지 사항
- `git add -A` 또는 `git add .`을 사용하지 않는다 (민감 파일 혼입 방지)
- `git push --force`를 사용하지 않는다
- 사용자 확인 없이 커밋하지 않는다
- 영어로 커밋 메시지를 작성하지 않는다
- 변경 내용과 무관한 커밋 메시지를 작성하지 않는다
- `--no-verify` 옵션을 사용하지 않는다

View file

@ -0,0 +1,104 @@
---
name: create-domain-rule
version: 1.0.0
description: 새로운 도메인 rules.md 파일을 생성하기 위한 범용 스킬
---
# Create Domain Rule
## 목적
`agent-ops/rules/project/domain/<domain-name>/rules.md` 파일을 올바른 형식으로 생성한다.
실제 프로젝트 폴더 구조를 분석하여 경로와 구성 요소를 자동으로 채운다.
생성 후 `rules/project/rules.md`의 도메인 매핑 테이블에 항목을 추가한다.
## 언제 호출할지
- 새로운 도메인 영역의 코드를 처음 변경하기 전에
- 기존 domain rule이 없는 경로에 대해 규칙이 필요할 때
- 사용자가 특정 도메인의 rule 파일을 만들어 달라고 요청할 때
- agent-ops 초기 scaffold 이후 도메인을 추가 확장할 때
## 입력
- `domain-name`: 생성할 도메인 이름, kebab-case (필수)
- `domain-type`: `core` / `supporting` / `generic` 중 하나 (필수)
- `path-hints`: 이 도메인에 해당하는 경로 힌트 목록 (선택, 없으면 자동 탐색)
## 먼저 확인할 것
- [ ] `agent-ops/rules/project/domain/<domain-name>/rules.md` 가 이미 존재하는지 확인
- [ ] `agent-ops/rules/common/_templates/domain-rule-template.md` 를 읽어 최신 템플릿 형식 파악
- [ ] `agent-ops/rules/project/domain/` 하위 기존 domain rule 목록을 확인하여 중복·유사 도메인 여부 판단
## 실행 절차
1. **중복 확인**
- `agent-ops/rules/project/domain/<domain-name>/` 폴더 존재 여부 확인
- 책임이 겹치는 기존 domain rule 이 있으면 사용자에게 알리고 중단한다
2. **경로 탐색**
- `path-hints` 가 제공된 경우: 해당 경로를 기준으로 폴더 구조 확인
- `path-hints` 가 없는 경우: `domain-name` 과 연관된 폴더명·파일명으로 프로젝트를 탐색
- 실제로 존재하는 경로만 포함 경로에 기재한다
- 존재하지 않는 경로는 기재하지 않는다
3. **도메인 분석**
- 탐색된 경로의 주요 파일·모듈을 읽어 아래를 도출한다
- 도메인의 목적 / 책임 한 줄 요약
- 포함 경로 목록
- 제외 경로 (인접 도메인과 겹칠 수 있는 경로)
- 주요 구성 요소 (파일, 모듈, 클래스, 함수 등)
- 유지할 패턴 (네이밍 규칙, 아키텍처 패턴 등)
- 다른 도메인과의 경계
- 금지 사항
4. **도메인 rules.md 생성**
- 경로: `agent-ops/rules/project/domain/<domain-name>/rules.md`
- `domain-rule-template.md` 형식을 따른다
- 실제 코드에서 확인된 내용만 기재한다
- 불확실한 항목은 `<!-- TODO: 확인 필요 -->` 주석으로 남긴다
5. **rules/project/rules.md 업데이트**
- `agent-ops/rules/project/rules.md` 를 읽는다
- 도메인 매핑 테이블에 아래 형식으로 추가한다
```
| `<path-pattern>` | `agent-ops/rules/project/domain/<domain-name>/rules.md` |
```
- 경로 패턴은 실제 포함 경로를 기준으로 작성한다
- 기존 테이블 항목을 삭제하거나 재정렬하지 않는다
6. **결과 보고**
- 생성한 파일 경로
- rules/project/rules.md 에 추가한 항목
- 불확실하여 TODO로 남긴 항목 (해당 시)
## 출력 형식
```
## 생성 완료
- Domain Rule 경로: agent-ops/rules/project/domain/<domain-name>/rules.md
- 도메인 유형: <core | supporting | generic>
- rules/project/rules.md 추가 경로 패턴: <path-pattern>
## TODO 항목 (확인 필요)
- <불확실하여 직접 확인이 필요한 항목> (해당 시)
```
## 실행 결과 검증
- [ ] `agent-ops/rules/project/domain/<domain-name>/rules.md` 파일이 생성되었는가
- [ ] 생성된 파일이 `domain-rule-template.md`의 모든 섹션(목적, 포함 경로, 제외 경로, 주요 구성 요소, 유지할 패턴, 경계, 금지 사항)을 포함하는가
- [ ] `rules/project/rules.md`의 도메인 매핑 테이블에 해당 도메인 항목이 추가되었는가
- [ ] 포함 경로에 기재된 경로가 실제로 프로젝트에 존재하는가
- 검증 실패 시: 누락된 섹션 또는 잘못된 경로를 사용자에게 알리고 해당 부분만 보완한다
## 금지 사항
- 이미 존재하는 rules.md 를 덮어쓰지 않는다
- 실제 존재하지 않는 경로를 포함 경로에 넣지 않는다
- 추측으로 패턴이나 금지 사항을 채우지 않는다 — 확인된 내용만 기재한다
- rules/project/rules.md 의 기존 항목을 삭제하거나 재정렬하지 않는다
- 하나의 domain rule 에 여러 독립 도메인의 책임을 묶지 않는다
- 코드 변경을 수행하지 않는다 — 이 skill 은 rule 파일 생성만 담당한다

View file

@ -0,0 +1,95 @@
---
name: create-skill
version: 1.0.0
description: 새로운 SKILL.md 파일을 생성하기 위한 범용 스킬
---
# Create Skill
## 목적
`agent-ops/skills/` 하위에 올바른 형식의 SKILL.md 파일을 생성한다.
기존 skill-template.md 를 기반으로, 요청 목적에 맞는 내용을 채워 넣는다.
생성 후 라우팅 항목을 추가한다.
### 생성 위치 결정
- `.agent-ops-source` 파일이 **있으면** (공통 관리 레포): `agent-ops/skills/common/<skill-name>/SKILL.md`
- `.agent-ops-source` 파일이 **없으면** (타겟 프로젝트): `agent-ops/skills/project/<skill-name>/SKILL.md`
## 언제 호출할지
- 새로운 반복 작업 패턴이 생겨 skill로 정의해야 할 때
- 기존 skill이 없는 작업 유형을 처음 수행하기 전에
- 사용자가 특정 작업을 skill로 만들어 달라고 요청할 때
## 입력
- `skill-name`: 생성할 skill 이름, kebab-case (필수)
- `purpose`: 이 skill이 해결하는 문제 한 줄 요약 (필수)
- `trigger-cases`: 이 skill을 호출해야 하는 상황 목록 (선택)
## 먼저 확인할 것
- [ ] `agent-ops/skills/common/``agent-ops/skills/project/` 하위에 동일 이름의 디렉터리가 이미 존재하는지 확인
- [ ] `agent-ops/rules/common/rules.md``agent-ops/rules/project/rules.md` 에 이미 유사한 라우팅 항목이 있는지 확인
- [ ] `agent-ops/skills/common/_templates/skill-template.md` 를 읽어 최신 템플릿 형식 파악
## 실행 절차
1. **중복 확인**
- `agent-ops/skills/common/<skill-name>/``agent-ops/skills/project/<skill-name>/` 폴더 존재 여부 확인
- 기능이 겹치는 기존 skill이 있으면 사용자에게 알리고 중단한다
2. **목적 분석**
- `purpose``trigger-cases` 를 바탕으로 아래 항목을 도출한다
- 언제 호출할지 (2~4개)
- 필요한 입력 파라미터
- 사전 확인 항목
- 실행 절차 (3~7단계)
- 출력 형식
- 금지 사항
3. **SKILL.md 생성**
- 경로: 생성 위치 결정 규칙에 따라 `common/` 또는 `project/` 하위에 생성
- `skill-template.md` 형식을 따른다
- 프로젝트 특화 내용보다 범용 절차를 우선한다
- 절차는 구체적이되 지나치게 세부 구현을 기술하지 않는다
4. **라우팅 업데이트**
- `.agent-ops-source` 마커가 **있으면** (공통 관리 레포): `agent-ops/rules/common/rules.md`에 라우팅 항목 추가
- `.agent-ops-source` 마커가 **없으면** (타겟 프로젝트): `agent-ops/rules/project/rules.md`의 프로젝트 스킬 라우터 섹션에 라우팅 항목 추가
- 이 skill이 속할 라우팅 축(구조 분석/코드 변경/흐름 추적 등)을 판단한다
- 기존 라우팅 구조를 깨지 않는다
5. **결과 보고**
- 생성한 파일 경로
- 라우팅 항목을 추가한 파일과 내용
- 이 skill이 다루지 않는 범위(필요 시)
## 출력 형식
```
## 생성 완료
- SKILL 경로: agent-ops/skills/{common|project}/<skill-name>/SKILL.md
- 라우팅 추가: <대상 파일><라우팅 ><skill-name>
## 주의사항 (해당 시)
- < skill이 다루지 않는 범위 또는 주의할 >
```
## 실행 결과 검증
- [ ] `agent-ops/skills/{common|project}/<skill-name>/SKILL.md` 파일이 생성되었는가
- [ ] 생성된 파일이 `skill-template.md`의 필수 섹션(목적, 언제 호출할지, 실행 절차, 실행 결과 검증, 출력 형식, 금지 사항)을 포함하는가
- [ ] frontmatter에 name, version, description이 올바르게 기재되었는가
- [ ] 라우팅 대상 파일에 해당 스킬의 라우팅 항목이 추가되었는가
- 검증 실패 시: 누락된 섹션 또는 라우팅 항목을 사용자에게 알리고 해당 부분만 보완한다
## 금지 사항
- 이미 존재하는 skill 을 덮어쓰지 않는다
- 프로젝트 특화 경로(예: `app/screens/`)를 skill 본문에 하드코딩하지 않는다
- skill 생성과 무관한 코드 파일을 수정하지 않는다
- 라우팅 대상 파일의 기존 항목을 삭제하거나 재정렬하지 않는다
- 하나의 skill 에 여러 독립적인 책임을 묶지 않는다

View file

@ -0,0 +1,220 @@
---
name: init-agent-ops
version: 1.1.0
description: 프로젝트 상태를 판별하고 agent-ops 기본 스캐폴드를 생성하기 위한 초기 규칙
---
# init-agent-ops
## 목적
프로젝트에 Agent-Ops 구조가 없거나 불완전할 때,
현재 프로젝트 상태를 분석하여 다음을 세팅한다.
1. 에이전트 진입 파일
2. agent-ops 기본 폴더 구조
3. rules/project/rules.md (프로젝트 특화 규칙, 분석 후 생성)
4. 초기 domain rule 초안
5. 초기 skill (필요 시)
"현재 프로젝트에 맞는 최소 스캐폴드" 생성을 우선한다.
## 언제 호출할지
- 프로젝트에 agent-ops 구조가 없을 때
- agent-ops 구조가 불완전하여 재설정이 필요할 때
- 사용자가 "agent-ops 초기화해줘", "에이전트 설정해줘" 요청 시
## 입력
- `project-type`: 신규 / 운영중 (선택, 미지정 시 자동 판별)
## 먼저 확인할 것
- [ ] 프로젝트 루트에 기존 agent-ops 관련 파일(`CLAUDE.md`, `agent-ops/` 등)이 있는지 확인
- [ ] `.agent-ops-source` 파일이 있는지 확인 (공통 관리 레포 여부)
- [ ] 기존 진입 파일(`CLAUDE.md`, `GEMINI.md` 등)이 있는지 확인
## 핵심 원칙
- 기존 구조를 우선한다.
- 새 파일 생성은 꼭 필요한 최소 범위로 제한한다.
- 도메인은 발명하지 말고 현재 구조에서 발견한다.
- 처음에는 핵심 도메인만 생성한다.
- 반복되는 작업만 초기 skill로 만든다.
- 불확실한 내용은 후보로 제시한다.
## 상태 판별
### 신규 프로젝트
- 코드/폴더 구조가 단순하다
- 도메인 경계가 아직 약하다
- Agent-Ops 관련 파일이 없다
### 운영중 프로젝트
- 모듈/폴더/패키지 경계가 보인다
- 반복 작업이 드러난다
- 핵심 책임 경계가 식별된다
## 생성 대상
| 파일 | 방법 |
|------|------|
| `CLAUDE.md`,`GEMINI.md`,`AGENTS.md`, `.cursorrules`, `.clinerules` 등 진입 파일 | `rules/common/rules.md`를 에이전트별 파일명으로 프로젝트 루트에 복사 후 `rules/common/rules.md` 삭제 |
| `agent-ops/.version` | 공통 관리 레포의 VERSION 파일을 그대로 복사 (프레임워크 버전 추적용) |
| `agent-ops/rules/common/` | 공통 폴더 전체 복사 (수정 금지) |
| `agent-ops/skills/common/` | 공통 폴더 전체 복사 (수정 금지) |
| `agent-ops/rules/project/rules.md` | 프로젝트 분석 후 생성 |
| `agent-ops/rules/project/domain/<domain>/rules.md` | 도메인 분석 후 생성 |
| `agent-ops/rules/private/` | 폴더만 생성 (내용은 개인이 작성) |
| `.gitignore``agent-ops/rules/private/` 추가 | git 추적 제외 |
에이전트별 파일명:
| 에이전트 | 파일명 |
|---------|--------|
| Claude | `CLAUDE.md` |
| Gemini | `GEMINI.md` |
| Kilo Code / OpenCode | `AGENTS.md` |
| Cursor | `.cursorrules` |
| Cline | `.clinerules` |
## 에이전트 진입 파일 원칙
진입 파일은 `rules/common/rules.md` 내용 그대로를 에이전트별 파일명으로 복사한다.
별도 내용을 추가하거나 수정하지 않는다.
## Rule 구조 원칙
### rules/common/rules.md
- 공통 관리 레포에서 제공. 프로젝트에서 직접 수정하지 않는다.
- 실제 사용은 진입점 파일들에서 사용된다.
포함 항목:
- 기본 원칙
- 공통 스킬 라우팅 (router.md 참조)
- project/rules.md 로드 지시
### rules/project/rules.md
init-agent-ops가 프로젝트를 분석하여 생성한다.
포함 항목:
- 응답 언어
- 프로젝트 개요 / 주요 구조
- 기술 스택
- 프로젝트 특화 컨벤션
- 도메인 매핑 테이블 (경로 패턴 → domain rules.md)
- 프로젝트 스킬 라우팅 (해당 시)
common/rules.md와 내용이 중복되지 않도록 한다.
#### 도메인 매핑 테이블 형식
```markdown
## 도메인 매핑
| 경로 패턴 | 도메인 | rules.md |
|----------|--------|----------|
| `src/order/**` | order | `agent-ops/rules/project/domain/order/rules.md` |
| `src/payment/**` | payment | `agent-ops/rules/project/domain/payment/rules.md` |
| `src/common/**` | common | `agent-ops/rules/project/domain/common/rules.md` |
```
#### 프로젝트 스킬 라우팅 형식
```markdown
## 스킬 라우팅
| 요청 키워드 | SKILL.md |
|------------|----------|
| 테스트 실행해줘 | `agent-ops/skills/project/run-test/SKILL.md` |
```
### domain rule
각 도메인 rules.md에는 아래만 둔다.
- 목적 / 책임
- 포함 경로
- 제외 경로
- 주요 구성 요소
- 유지할 패턴
- 다른 도메인과의 경계
- 금지 사항
## DDD 기준
- **Core Domain**: 핵심 가치와 주요 유즈케이스
- **Supporting Domain**: 핵심 도메인을 지원
- **Generic / Common**: 여러 도메인이 공통으로 사용
도메인은 실제 폴더, 모듈, 패키지, 책임 경계와 연결되어야 한다.
## 실행 절차
1. **상태 판별**
- 프로젝트 구조, 모듈 경계, agent-ops 파일 유무를 분석하여 신규/운영중을 판별한다
2. **에이전트 진입 파일 생성**
- `rules/common/rules.md`를 에이전트별 파일명으로 프로젝트 루트에 복사한다
- 복사 후 `rules/common/rules.md`를 삭제한다
3. **agent-ops 폴더 구조 복사**
- 공통 관리 레포의 `agent-ops/` 공통 폴더(rules/common, skills/common)를 복사한다
- `agent-ops/.version` 파일을 복사한다
4. **rules/project/rules.md 생성**
- 프로젝트를 분석하여 응답 언어, 프로젝트 개요, 기술 스택 등을 채운다
- common/rules.md와 내용이 중복되지 않도록 한다
5. **도메인 분석 및 domain rule 생성**
- 신규 프로젝트: 핵심 domain placeholder 2~4개만 제안한다. domain rules를 과도하게 채우지 않는다
- 운영중 프로젝트: Core/Supporting/Generic 도메인을 식별하고 실제 경로를 반영한 초안을 생성한다
6. **초기 skill 제안**
- 신규 프로젝트: 최소 2개만 제안한다
- 운영중 프로젝트: 반복 작업 기반으로 필요한 skill을 제안한다
7. **결과 보고**
- 상태 판별 결과, 생성된 파일 목록, 도메인 제안, skill 제안, 주의사항을 출력한다
## 출력 형식
### 상태 판별
- Agent-Ops 상태: 없음 / 부분 적용 / 운영중
- 프로젝트 상태: 신규 / 운영중
- 근거: 짧게 요약
### 스캐폴드 계획
- 생성할 파일
- 바로 채울 파일
- placeholder로 둘 파일
### 도메인 제안
- Core Domain
- Supporting Domain
- Generic / Common
### 초기 skill 제안
- skill 이름
- 필요한 이유
### 주의사항
- 지금 만들지 말아야 할 것
- 아직 확정하면 안 되는 것
## 실행 결과 검증
- [ ] 진입 파일이 프로젝트 루트에 존재하고, 내용이 `rules/common/rules.md`와 일치하는가
- [ ] `agent-ops/rules/project/rules.md`가 생성되었고, 필수 항목(응답 언어, 프로젝트 개요, 기술 스택)이 포함되어 있는가
- [ ] 생성된 domain rules.md가 `domain-rule-template.md` 형식을 따르는가
- [ ] `rules/project/rules.md`의 도메인 매핑 테이블에 생성된 도메인이 모두 등록되어 있는가
- [ ] `.gitignore``agent-ops/rules/private/` 항목이 추가되어 있는가
- 검증 실패 시: 누락된 파일/항목을 사용자에게 알리고 해당 부분만 보완한다
## 금지 사항
- 진입 파일에 rules/common/rules.md 외 내용을 추가하지 않는다.
- 실제 구조보다 앞선 추상 구조를 강요하지 않는다.
- 처음부터 많은 domain / skill을 만들지 않는다.
- rules/common/rules.md를 프로젝트에서 직접 수정하지 않는다.
- rules/project/rules.md에 rules/common/rules.md와 중복되는 내용을 넣지 않는다.

View file

@ -0,0 +1,202 @@
---
name: plan
description: Analyze the current repository and write a detailed PLAN.md for implementation work. Also writes the CODE_REVIEW.md stub that the implementing agent will fill in after coding. Use for any feature, refactor, bug fix, or follow-up fix that should enter the plan-code-review loop. A separate implementing agent, or the same agent in an implementation pass, reads PLAN.md and does the coding. The code-review skill archives both files after review.
---
# Plan
## Purpose
Create the planning artifacts for the implementation loop:
```text
plan skill -> PLAN.md + CODE_REVIEW.md stub
implementation -> code changes + filled CODE_REVIEW.md
code-review skill -> verdict + archive, or new follow-up PLAN.md
```
## Workflow Contract
This skill intentionally uses `agent-task/{task_name}/PLAN.md` and `agent-task/{task_name}/CODE_REVIEW.md` as the state protocol between planning, implementation, and review. Do not change these paths or filenames unless the paired plan and code-review skills are updated together. This convention is not project-specific; it is the workflow contract for this skill loop.
Directory states:
| State | Meaning |
|-------|---------|
| `PLAN.md` only | Invalid; plan skill always writes both files |
| `PLAN.md` + `CODE_REVIEW.md` stub | Implementation is pending/in progress |
| `PLAN.md` + filled `CODE_REVIEW.md` | Ready for code-review skill |
| `complete.log` + `*.log` files | Task complete (PASS) |
| Only `*.log` files (no `complete.log`) | Task terminated mid-loop or abandoned |
## Step 1 - Determine Task
If the user names the task explicitly, use that task name.
Otherwise, glob `agent-task/*/PLAN.md`:
| Result | Action |
|--------|--------|
| Exactly one | Continue that task |
| None | Create a new task only for a feature/refactor/fix/follow-up that belongs in this workflow |
| Multiple | List paths and ask which task to use |
`PLAN.md` is the loop entry point. A missing `PLAN.md` normally means only that no plan has been started for a new task; do not create task files for casual analysis, status, or review requests unless the user explicitly asks for a plan.
Use short snake_case task names, e.g. `api_refactor`.
## Step 2 - Analyze Before Writing
Complete these before creating files:
- Read every source file the change will touch, whole file.
- Read every test file that exercises changed behavior.
- For each behavior change, note whether existing tests cover it.
- Grep renamed/removed symbols for all call sites and import chains.
- Check package manifests/dependency files before adding dependencies.
- Anticipate compile issues: missing overrides, type mismatches, broken imports.
- Confirm final verification commands work in this repository layout.
## Step 3 - Archive Existing Active Files
Before writing new active files for the chosen task:
- Count existing `agent-task/{task_name}/plan_*.log`; call it `N`. If `PLAN.md` exists, rename it to `plan_N.log`.
- Count existing `agent-task/{task_name}/code_review_*.log`; call it `M`. If `CODE_REVIEW.md` exists, rename it to `code_review_M.log`.
The new plan number is the count of `plan_*.log` after archiving.
## Step 4 - Write PLAN.md
Header line must be exactly:
```markdown
<!-- task={task_name} plan={N} tag={TAG} -->
```
Required sections:
- Title.
- `이 파일을 읽는 구현 에이전트에게`: tell the implementer to complete checklists, run intermediate/final verification, and fill every `CODE_REVIEW.md` section with actual implementation notes and command output.
- `배경`: 2-4 sentences explaining why the work is needed.
- One item per change: `### [TAG-1] Title`, `TAG-2`, etc.
- `수정 파일 요약`: table mapping files to item ids.
- `최종 검증`: runnable commands and expected outcome.
Each plan item must include:
- `문제`: concrete problem with file:line references.
- `해결 방법`: exact approach and before/after code block for non-trivial changes.
- `수정 파일 및 체크리스트`: exhaustive file-level checklist.
- `테스트 작성`: explicit write/skip decision. If writing tests, include path, test name, assertion goal, and fixtures. If skipping, justify.
- `중간 검증`: runnable commands and expected result.
Include `의존 관계 및 구현 순서` only when order matters.
Quality rules:
- Exact line numbers in every Before snippet.
- Use the language's required override annotation/keyword wherever an abstract method is implemented.
- Include full import statements for new packages.
- List all call sites for renamed/removed symbols.
- Never write "add tests as needed"; decide up front.
- Do not cite files you did not read.
Test policy:
| Change | Test requirement |
|--------|------------------|
| Bug fix | Regression test required |
| New public API | Normal + boundary tests required |
| API rename | Existing test call-site updates usually enough |
| Internal refactor | Existing tests may be enough |
| Concurrency logic | Race/ordering test recommended |
## Step 5 - Write CODE_REVIEW.md Stub
Use the template below exactly. Fill `{…}` placeholders from the plan; everything else is fixed and must not be changed by the implementing agent.
```markdown
<!-- task={task_name} plan={N} tag={TAG} -->
# Code Review Reference - {TAG}
## 개요
date={YYYY-MM-DD}
task={task_name}, plan={N}, tag={TAG}
## 이 파일을 읽는 리뷰 에이전트에게
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.
1. `CODE_REVIEW.md``code_review_N.log` (N = 기존 code_review_*.log 수)
2. `PLAN.md``plan_M.log` (M = 기존 plan_*.log 수)
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.
---
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [{TAG}-1] {item description} | [ ] |
| [{TAG}-2] {item description} | [ ] |
## 계획 대비 변경 사항
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
## 주요 설계 결정
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
## 리뷰어를 위한 체크포인트
{pre-filled from plan — one bullet per review focus area}
## 검증 결과
_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._
### {TAG}-1 중간 검증
```
$ {verification command from plan}
(output)
```
### 최종 검증
```
$ {final verification command from plan}
(output)
```
```
Sections and their ownership:
| 섹션 | 소유자 | 설명 |
|------|--------|------|
| 헤더 주석, 개요(date/task/plan/tag), 리뷰 에이전트 지시 | 스텁 생성 시 고정 | 구현 에이전트가 수정하지 않음 |
| 구현 항목별 완료 여부 (항목명) | 스텁 생성 시 고정 | `[ ]``[x]` 체크만 구현 에이전트가 수행 |
| 계획 대비 변경 사항, 주요 설계 결정 | 구현 에이전트가 채움 | placeholder 텍스트를 실제 내용으로 교체 |
| 리뷰어를 위한 체크포인트 | 스텁 생성 시 고정 | 계획에서 추출한 리뷰 포인트 |
| 검증 결과 (섹션 제목 + 명령) | 스텁 생성 시 고정 | 실행 출력만 구현 에이전트가 채움 |
| 코드리뷰 결과 | 리뷰 에이전트가 append | 스텁에 포함하지 않음 |
## Naming
| Tag | Use for |
|-----|---------|
| `API` | Public API changes |
| `REFACTOR` | Internal refactoring |
| `TEST` | Test additions/fixes |
| `REVIEW_<TAG>` | Follow-up fixes after review |
## Final Checklist
- `PLAN.md` and `CODE_REVIEW.md` both exist under `agent-task/{task_name}/`.
- Both first lines match `<!-- task={task_name} plan={N} tag={TAG} -->`.
- Previous active files, if any, were archived with correct numeric suffixes.
- Every plan item has problem, solution, checklist, test decision, and intermediate verification.
- `CODE_REVIEW.md` completion table lists every plan item.

View file

@ -0,0 +1,4 @@
interface:
display_name: "Plan"
short_description: "Write implementation plans"
default_prompt: "Use $plan to create a task PLAN.md and CODE_REVIEW.md stub for this repository change."

View file

@ -0,0 +1,11 @@
# 공통 스킬 라우터
| 요청 키워드 | SKILL.md |
|------------|----------|
| agent-ops 세팅해줘, scaffold 만들어줘, 초기화해줘 | `agent-ops/skills/common/init-agent-ops/SKILL.md` |
| domain rule 만들어줘, rules.md 생성, 새 도메인 규칙 | `agent-ops/skills/common/create-domain-rule/SKILL.md` |
| skill 만들어줘, SKILL.md 생성, 새 스킬 추가 | `agent-ops/skills/common/create-skill/SKILL.md` |
| 계획 세워줘, 구현 계획, 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 싱크해, agent-ops 동기화해, agentic-framework에 올려줘, agent-ops를 [프로젝트]로 싱크해 | `agent-ops/skills/common/sync-agent-ops/SKILL.md` |

View file

@ -0,0 +1,44 @@
---
name: sync-agent-ops
description: agent-ops를 agentic-framework와 동기화한다. "agent-ops 싱크해", "agent-ops 동기화해" 요청 시 사용한다.
---
# sync-agent-ops
## 목적
`agent-ops/bin/sync.sh`를 호출해 agent-ops를 동기화한다.
현재 프로젝트가 agentic-framework인지 여부에 따라 동작이 달라진다.
## 언제 호출할지
- "agent-ops 싱크해", "agent-ops 동기화해" 요청 시
- "agentic-framework에 올려줘" 요청 시
- "agent-ops를 [프로젝트]로 싱크해" 요청 시
## 실행 절차
### 현 프로젝트가 일반 프로젝트인 경우 (`.agent-ops-source` 없음)
1. 동일 레벨에 `agentic-framework` 폴더가 있는지 확인한다
2. **있으면**: `agent-ops/bin/sync.sh agentic-framework` 실행
3. **없으면**: 사용자에게 agentic-framework 경로 입력을 안내하고, 입력받은 경로로 실행
### 현 프로젝트가 agentic-framework인 경우 (`.agent-ops-source` 있음)
1. 사용자 요청에서 target 프로젝트명 또는 경로를 추출한다
2. **명시된 경우**: `agent-ops/bin/sync.sh <target>` 실행
3. **명시되지 않은 경우**: 사용자에게 대상 프로젝트 입력을 요청한다
```bash
agent-ops/bin/sync.sh <target>
```
## 실행 결과 검증
- [ ] sync.sh 가 오류 없이 완료됐는가
- [ ] 버전 충돌 경고가 없었는가 — 있었다면 사용자에게 수동 머지 필요함을 알린다
## 금지 사항
- sync.sh 를 거치지 않고 직접 파일을 복사하지 않는다

View file