Update project configuration files
This commit is contained in:
parent
0fce3ac7ca
commit
976322bf17
28 changed files with 1795 additions and 116 deletions
16
.cursorrules
Normal file
16
.cursorrules
Normal 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
1
.gitignore
vendored
|
|
@ -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
16
AGENTS.md
Normal 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
129
CLAUDE.md
|
|
@ -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
16
GEMINI.md
Normal 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
1
agent-ops/.version
Normal file
|
|
@ -0,0 +1 @@
|
|||
1.1.2
|
||||
168
agent-ops/GUIDE.md
Normal file
168
agent-ops/GUIDE.md
Normal 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
28
agent-ops/bin/bump-version.sh
Executable 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
173
agent-ops/bin/sync.sh
Executable 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}"
|
||||
29
agent-ops/rules/common/_templates/domain-rule-template.md
Normal file
29
agent-ops/rules/common/_templates/domain-rule-template.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# <domain-name>
|
||||
|
||||
## 목적 / 책임
|
||||
|
||||
<이 도메인이 담당하는 책임을 1~2문장으로>
|
||||
|
||||
## 포함 경로
|
||||
|
||||
- `<path>/` — <이 경로가 이 도메인에 속하는 이유>
|
||||
|
||||
## 제외 경로
|
||||
|
||||
- `<path>/` — <왜 이 도메인이 아닌지>
|
||||
|
||||
## 주요 구성 요소
|
||||
|
||||
- `<ClassName>` — <역할>
|
||||
|
||||
## 유지할 패턴
|
||||
|
||||
- <네이밍 규칙 또는 아키텍처 패턴>
|
||||
|
||||
## 다른 도메인과의 경계
|
||||
|
||||
- **<인접 domain>**: <어디까지가 이 도메인이고 어디서부터 저 도메인인지>
|
||||
|
||||
## 금지 사항
|
||||
|
||||
- <이 도메인 코드에서 하면 안 되는 것>
|
||||
0
agent-ops/rules/project/.gitkeep
Normal file
0
agent-ops/rules/project/.gitkeep
Normal file
39
agent-ops/rules/project/domain/cli/rules.md
Normal file
39
agent-ops/rules/project/domain/cli/rules.md
Normal 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 커맨드 핸들러에 넣지 않는다
|
||||
49
agent-ops/rules/project/domain/command/rules.md
Normal file
49
agent-ops/rules/project/domain/command/rules.md
Normal 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 매핑을 추가하지 않는다
|
||||
37
agent-ops/rules/project/domain/core/rules.md
Normal file
37
agent-ops/rules/project/domain/core/rules.md
Normal 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에 넣지 않는다
|
||||
40
agent-ops/rules/project/domain/pipeline/rules.md
Normal file
40
agent-ops/rules/project/domain/pipeline/rules.md
Normal 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에 넣지 않는다
|
||||
86
agent-ops/rules/project/rules.md
Normal file
86
agent-ops/rules/project/rules.md
Normal 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` |
|
||||
57
agent-ops/skills/common/_templates/skill-template.md
Normal file
57
agent-ops/skills/common/_templates/skill-template.md
Normal 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>
|
||||
- 검증 실패 시: <실패 시 취할 행동 — 롤백, 사용자 알림, 재시도 등>
|
||||
|
||||
## 출력 형식
|
||||
|
||||
```
|
||||
<출력 예시>
|
||||
```
|
||||
|
||||
## 금지 사항
|
||||
|
||||
- <절대 하면 안 되는 것>
|
||||
- <절대 하면 안 되는 것>
|
||||
218
agent-ops/skills/common/code-review/SKILL.md
Normal file
218
agent-ops/skills/common/code-review/SKILL.md
Normal 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`.
|
||||
4
agent-ops/skills/common/code-review/agents/openai.yaml
Normal file
4
agent-ops/skills/common/code-review/agents/openai.yaml
Normal 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."
|
||||
124
agent-ops/skills/common/commit-push/SKILL.md
Normal file
124
agent-ops/skills/common/commit-push/SKILL.md
Normal 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` 옵션을 사용하지 않는다
|
||||
104
agent-ops/skills/common/create-domain-rule/SKILL.md
Normal file
104
agent-ops/skills/common/create-domain-rule/SKILL.md
Normal 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 파일 생성만 담당한다
|
||||
95
agent-ops/skills/common/create-skill/SKILL.md
Normal file
95
agent-ops/skills/common/create-skill/SKILL.md
Normal 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 에 여러 독립적인 책임을 묶지 않는다
|
||||
220
agent-ops/skills/common/init-agent-ops/SKILL.md
Normal file
220
agent-ops/skills/common/init-agent-ops/SKILL.md
Normal 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와 중복되는 내용을 넣지 않는다.
|
||||
202
agent-ops/skills/common/plan/SKILL.md
Normal file
202
agent-ops/skills/common/plan/SKILL.md
Normal 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.
|
||||
4
agent-ops/skills/common/plan/agents/openai.yaml
Normal file
4
agent-ops/skills/common/plan/agents/openai.yaml
Normal 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."
|
||||
11
agent-ops/skills/common/router.md
Normal file
11
agent-ops/skills/common/router.md
Normal 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` |
|
||||
44
agent-ops/skills/common/sync-agent-ops/SKILL.md
Normal file
44
agent-ops/skills/common/sync-agent-ops/SKILL.md
Normal 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 를 거치지 않고 직접 파일을 복사하지 않는다
|
||||
0
agent-ops/skills/project/.gitkeep
Normal file
0
agent-ops/skills/project/.gitkeep
Normal file
Loading…
Reference in a new issue