agent-ops AI ignore 동기화 정책 정리
This commit is contained in:
parent
5a67729cd6
commit
5e44499307
9 changed files with 236 additions and 85 deletions
|
|
@ -8,7 +8,7 @@ AI 에이전트가 매 작업마다 필요한 컨텍스트만 읽도록 `agent-o
|
|||
|
||||
이 저장소는 `agent-ops/` 공통 파일의 원본 저장소입니다. 루트의 `.agent-ops-source` 마커가 있으므로 공통 규칙, 공통 스킬, 동기화 스크립트는 이 저장소에서 수정하고 다른 프로젝트로 배포합니다.
|
||||
|
||||
현재 프레임워크 버전은 `agent-ops/.version`에 기록되며, 이 README를 갱신한 시점의 버전은 `1.1.30`입니다. 이 저장소는 애플리케이션 런타임이 아니라 문서와 셸 스크립트 중심의 프레임워크라서 별도의 빌드나 테스트 설정 파일은 없습니다.
|
||||
현재 프레임워크 버전은 `agent-ops/.version`에 기록되며, 이 README를 갱신한 시점의 버전은 `1.1.31`입니다. 이 저장소는 애플리케이션 런타임이 아니라 문서와 셸 스크립트 중심의 프레임워크라서 별도의 빌드나 테스트 설정 파일은 없습니다.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
|
|
@ -44,6 +44,7 @@ agent-ops/
|
|||
GUIDE.md
|
||||
.version
|
||||
bin/
|
||||
ai-ignore.sh
|
||||
entry-files.sh
|
||||
init-agent-ops.sh
|
||||
sync.sh
|
||||
|
|
@ -155,7 +156,7 @@ Phase와 Milestone에는 순번을 강제하지 않습니다. 진행 순서는 `
|
|||
4. 반복 작업은 공통 스킬 또는 프로젝트 스킬로 정의합니다.
|
||||
5. 공통 파일 변경은 agentic-framework에서 관리하고 `sync-push` / `sync-pull`로 동기화합니다.
|
||||
|
||||
초기화 스크립트는 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`를 에이전트가 기본적으로 읽지 않도록 각 도구별 ignore 또는 permission 파일도 함께 보강합니다.
|
||||
초기화와 framework에서 일반 프로젝트로 내려가는 동기화는 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`를 에이전트가 기본적으로 읽지 않도록 각 도구별 ignore 또는 permission 파일도 함께 보강합니다.
|
||||
|
||||
## 동기화 흐름
|
||||
|
||||
|
|
@ -168,7 +169,7 @@ Phase와 Milestone에는 순번을 강제하지 않습니다. 진행 순서는 `
|
|||
| 일반 프로젝트 | `agent-ops/bin/sync.sh` | 현재 프로젝트의 공통 변경을 sibling `agentic-framework`로 push |
|
||||
| 일반 프로젝트 | `agent-ops/bin/sync.sh --pull agentic-framework` | `agentic-framework` 공통 파일을 현재 프로젝트로 pull |
|
||||
|
||||
push 대상은 `agent-ops/.version`, `agent-ops/bin`, `agent-ops/rules/common`, `agent-ops/skills/common`, 그리고 `entry-files.sh`에 정의된 진입 파일로 제한됩니다.
|
||||
push 대상은 `agent-ops/.version`, `agent-ops/bin`, `agent-ops/rules/common`, `agent-ops/skills/common`, `entry-files.sh`에 정의된 진입 파일로 제한됩니다. 단, framework에서 일반 프로젝트로 내려보내는 push에서는 대상 프로젝트의 AI ignore / permission 파일을 덮어쓰지 않고 누락된 표준 설정만 보강합니다. 일반 프로젝트에서 framework로 올리는 push에서는 AI ignore / permission 파일을 보강하거나 stage하지 않습니다.
|
||||
|
||||
## 관리 원칙
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.1.30
|
||||
1.1.31
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ agent-ops/
|
|||
├── .version # 프레임워크 버전 (타겟 프로젝트 버전 추적용)
|
||||
├── bin/
|
||||
│ ├── entry-files.sh # 진입 파일 목록의 단일 기준
|
||||
│ ├── ai-ignore.sh # AI ignore / permission 기본 설정
|
||||
│ ├── init-agent-ops.sh # 초기화 스크립트
|
||||
│ ├── sync.sh # 동기화 스크립트
|
||||
│ └── bump-version.sh # 버전 증가 스크립트
|
||||
|
|
|
|||
188
agent-ops/bin/ai-ignore.sh
Executable file
188
agent-ops/bin/ai-ignore.sh
Executable file
|
|
@ -0,0 +1,188 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Shared AI ignore / permission defaults for init and sync flows.
|
||||
AGENT_OPS_TASK_ARCHIVE_IGNORE_PATTERN="agent-task/archive/**"
|
||||
AGENT_OPS_ROADMAP_ARCHIVE_IGNORE_PATTERN="agent-ops/roadmap/archive/**"
|
||||
AGENT_OPS_AI_IGNORE_FILES=(".geminiignore" ".aiexclude" ".cursorignore" ".clineignore")
|
||||
AGENT_OPS_AI_PERMISSION_FILES=(".claude/settings.json" "opencode.json")
|
||||
AGENT_OPS_AI_SYNC_FILES=("${AGENT_OPS_AI_IGNORE_FILES[@]}" "${AGENT_OPS_AI_PERMISSION_FILES[@]}")
|
||||
|
||||
agent_ops_append_unique_line() {
|
||||
local file="$1"
|
||||
local line="$2"
|
||||
|
||||
touch "$file"
|
||||
if ! grep -qxF "$line" "$file"; then
|
||||
printf "%s\n" "$line" >> "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
agent_ops_merge_json_with_jq() {
|
||||
local file="$1"
|
||||
local filter="$2"
|
||||
local fallback_note="$3"
|
||||
local tmp
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "$fallback_note"
|
||||
return
|
||||
fi
|
||||
|
||||
tmp="$(mktemp "$file.tmp.XXXXXX")"
|
||||
if jq "$filter" "$file" > "$tmp"; then
|
||||
mv "$tmp" "$file"
|
||||
else
|
||||
rm -f "$tmp"
|
||||
echo "$fallback_note"
|
||||
fi
|
||||
}
|
||||
|
||||
agent_ops_merge_claude_settings() {
|
||||
local file="$1"
|
||||
local filter='
|
||||
def append_unique($item):
|
||||
if index($item) then . else . + [$item] end;
|
||||
def as_array:
|
||||
if type == "array" then . elif . == null then [] else [.] end;
|
||||
def as_object:
|
||||
if type == "object" then . else {} end;
|
||||
|
||||
.permissions = ((.permissions // {}) | as_object)
|
||||
| .permissions.deny = (
|
||||
(.permissions.deny | as_array)
|
||||
| append_unique("Read(./agent-task/archive/**)")
|
||||
| append_unique("Read(./agent-ops/roadmap/archive/**)")
|
||||
)
|
||||
'
|
||||
|
||||
agent_ops_merge_json_with_jq \
|
||||
"$file" \
|
||||
"$filter" \
|
||||
"Note: .claude/settings.json exists; add Read(./agent-task/archive/**) and Read(./agent-ops/roadmap/archive/**) manually."
|
||||
}
|
||||
|
||||
agent_ops_claude_settings_complete() {
|
||||
local file="$1"
|
||||
local filter='
|
||||
def as_array:
|
||||
if type == "array" then . elif . == null then [] else [.] end;
|
||||
|
||||
(.permissions.deny | as_array)
|
||||
| index("Read(./agent-task/archive/**)") and index("Read(./agent-ops/roadmap/archive/**)")
|
||||
'
|
||||
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
jq -e "$filter" "$file" >/dev/null 2>&1
|
||||
else
|
||||
grep -q "agent-task/archive" "$file" && grep -q "agent-ops/roadmap/archive" "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
agent_ops_merge_opencode_config() {
|
||||
local file="$1"
|
||||
local filter='
|
||||
def append_unique($item):
|
||||
if index($item) then . else . + [$item] end;
|
||||
def as_array:
|
||||
if type == "array" then . elif . == null then [] else [.] end;
|
||||
def as_object:
|
||||
if type == "object" then . else {} end;
|
||||
|
||||
.permission = ((.permission // {}) | as_object)
|
||||
| .permission.read = ((.permission.read // {}) | as_object)
|
||||
| .permission.read["agent-task/archive/**"] = "deny"
|
||||
| .permission.read["agent-ops/roadmap/archive/**"] = "deny"
|
||||
| .permission.glob = ((.permission.glob // {}) | as_object)
|
||||
| .permission.glob["agent-task/archive/**"] = "deny"
|
||||
| .permission.glob["agent-ops/roadmap/archive/**"] = "deny"
|
||||
| .watcher = ((.watcher // {}) | as_object)
|
||||
| .watcher.ignore = (
|
||||
(.watcher.ignore | as_array)
|
||||
| append_unique("agent-task/archive/**")
|
||||
| append_unique("agent-ops/roadmap/archive/**")
|
||||
)
|
||||
'
|
||||
|
||||
agent_ops_merge_json_with_jq \
|
||||
"$file" \
|
||||
"$filter" \
|
||||
"Note: opencode.json exists; add agent-task/archive/** and agent-ops/roadmap/archive/** read/glob deny and watcher ignore manually."
|
||||
}
|
||||
|
||||
agent_ops_opencode_config_complete() {
|
||||
local file="$1"
|
||||
local filter='
|
||||
def as_array:
|
||||
if type == "array" then . elif . == null then [] else [.] end;
|
||||
|
||||
(.permission.read["agent-task/archive/**"] == "deny")
|
||||
and (.permission.read["agent-ops/roadmap/archive/**"] == "deny")
|
||||
and (.permission.glob["agent-task/archive/**"] == "deny")
|
||||
and (.permission.glob["agent-ops/roadmap/archive/**"] == "deny")
|
||||
and ((.watcher.ignore | as_array) | index("agent-task/archive/**") and index("agent-ops/roadmap/archive/**"))
|
||||
'
|
||||
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
jq -e "$filter" "$file" >/dev/null 2>&1
|
||||
else
|
||||
grep -q "agent-task/archive" "$file" && grep -q "agent-ops/roadmap/archive" "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_agent_ops_ai_ignore_config() {
|
||||
local target_dir="$1"
|
||||
local ignore_file
|
||||
|
||||
if [[ -f "$target_dir/.agent-ops-source" ]]; then
|
||||
echo " AI ignore 보강 건너뜀: .agent-ops-source repo"
|
||||
return
|
||||
fi
|
||||
|
||||
for ignore_file in "${AGENT_OPS_AI_IGNORE_FILES[@]}"; do
|
||||
agent_ops_append_unique_line "$target_dir/$ignore_file" "$AGENT_OPS_TASK_ARCHIVE_IGNORE_PATTERN"
|
||||
agent_ops_append_unique_line "$target_dir/$ignore_file" "$AGENT_OPS_ROADMAP_ARCHIVE_IGNORE_PATTERN"
|
||||
done
|
||||
|
||||
mkdir -p "$target_dir/.claude"
|
||||
if [[ ! -f "$target_dir/.claude/settings.json" ]]; then
|
||||
cat > "$target_dir/.claude/settings.json" <<'EOF'
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||
"permissions": {
|
||||
"deny": [
|
||||
"Read(./agent-task/archive/**)",
|
||||
"Read(./agent-ops/roadmap/archive/**)"
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
elif ! agent_ops_claude_settings_complete "$target_dir/.claude/settings.json"; then
|
||||
agent_ops_merge_claude_settings "$target_dir/.claude/settings.json"
|
||||
fi
|
||||
|
||||
if [[ ! -f "$target_dir/opencode.json" ]]; then
|
||||
cat > "$target_dir/opencode.json" <<'EOF'
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"permission": {
|
||||
"read": {
|
||||
"agent-task/archive/**": "deny",
|
||||
"agent-ops/roadmap/archive/**": "deny"
|
||||
},
|
||||
"glob": {
|
||||
"agent-task/archive/**": "deny",
|
||||
"agent-ops/roadmap/archive/**": "deny"
|
||||
}
|
||||
},
|
||||
"watcher": {
|
||||
"ignore": [
|
||||
"agent-task/archive/**",
|
||||
"agent-ops/roadmap/archive/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
elif ! agent_ops_opencode_config_complete "$target_dir/opencode.json"; then
|
||||
agent_ops_merge_opencode_config "$target_dir/opencode.json"
|
||||
fi
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ set -e
|
|||
SCRIPT_DIR=$(realpath "$(dirname "$0")")
|
||||
SOURCE_DIR=$(realpath "$SCRIPT_DIR/..")
|
||||
source "$SCRIPT_DIR/entry-files.sh"
|
||||
source "$SCRIPT_DIR/ai-ignore.sh"
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <target_directory>"
|
||||
|
|
@ -15,18 +16,6 @@ if [ -z "$1" ]; then
|
|||
fi
|
||||
|
||||
TARGET_DIR=$(realpath "$1")
|
||||
TASK_ARCHIVE_IGNORE_PATTERN="agent-task/archive/**"
|
||||
ROADMAP_ARCHIVE_IGNORE_PATTERN="agent-ops/roadmap/archive/**"
|
||||
|
||||
append_unique_line() {
|
||||
local file="$1"
|
||||
local line="$2"
|
||||
|
||||
touch "$file"
|
||||
if ! grep -qxF "$line" "$file"; then
|
||||
printf "%s\n" "$line" >> "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
create_project_agent_ops_dirs() {
|
||||
local agent_ops_dir="$1"
|
||||
|
|
@ -82,57 +71,7 @@ apply_agent_ops_entry_files "$COMMON_RULES" "$TARGET_DIR"
|
|||
ensure_common_rules_file "$SOURCE_DIR" "$TARGET_DIR/agent-ops"
|
||||
|
||||
# 4. AI ignore / permission 설정
|
||||
append_unique_line "$TARGET_DIR/.geminiignore" "$TASK_ARCHIVE_IGNORE_PATTERN"
|
||||
append_unique_line "$TARGET_DIR/.geminiignore" "$ROADMAP_ARCHIVE_IGNORE_PATTERN"
|
||||
append_unique_line "$TARGET_DIR/.aiexclude" "$TASK_ARCHIVE_IGNORE_PATTERN"
|
||||
append_unique_line "$TARGET_DIR/.aiexclude" "$ROADMAP_ARCHIVE_IGNORE_PATTERN"
|
||||
append_unique_line "$TARGET_DIR/.cursorignore" "$TASK_ARCHIVE_IGNORE_PATTERN"
|
||||
append_unique_line "$TARGET_DIR/.cursorignore" "$ROADMAP_ARCHIVE_IGNORE_PATTERN"
|
||||
append_unique_line "$TARGET_DIR/.clineignore" "$TASK_ARCHIVE_IGNORE_PATTERN"
|
||||
append_unique_line "$TARGET_DIR/.clineignore" "$ROADMAP_ARCHIVE_IGNORE_PATTERN"
|
||||
|
||||
mkdir -p "$TARGET_DIR/.claude"
|
||||
if [ ! -f "$TARGET_DIR/.claude/settings.json" ]; then
|
||||
cat > "$TARGET_DIR/.claude/settings.json" <<'EOF'
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||
"permissions": {
|
||||
"deny": [
|
||||
"Read(./agent-task/archive/**)",
|
||||
"Read(./agent-ops/roadmap/archive/**)"
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
elif ! grep -q "agent-task/archive" "$TARGET_DIR/.claude/settings.json" || ! grep -q "agent-ops/roadmap/archive" "$TARGET_DIR/.claude/settings.json"; then
|
||||
echo "Note: .claude/settings.json exists; add Read(./agent-task/archive/**) and Read(./agent-ops/roadmap/archive/**) manually."
|
||||
fi
|
||||
|
||||
if [ ! -f "$TARGET_DIR/opencode.json" ]; then
|
||||
cat > "$TARGET_DIR/opencode.json" <<'EOF'
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"permission": {
|
||||
"read": {
|
||||
"agent-task/archive/**": "deny",
|
||||
"agent-ops/roadmap/archive/**": "deny"
|
||||
},
|
||||
"glob": {
|
||||
"agent-task/archive/**": "deny",
|
||||
"agent-ops/roadmap/archive/**": "deny"
|
||||
}
|
||||
},
|
||||
"watcher": {
|
||||
"ignore": [
|
||||
"agent-task/archive/**",
|
||||
"agent-ops/roadmap/archive/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
elif ! grep -q "agent-task/archive" "$TARGET_DIR/opencode.json" || ! grep -q "agent-ops/roadmap/archive" "$TARGET_DIR/opencode.json"; then
|
||||
echo "Note: opencode.json exists; add agent-task/archive/** and agent-ops/roadmap/archive/** read/glob deny and watcher ignore manually."
|
||||
fi
|
||||
ensure_agent_ops_ai_ignore_config "$TARGET_DIR"
|
||||
|
||||
# 5. .gitignore 설정
|
||||
TOUCH_GITIGNORE="$TARGET_DIR/.gitignore"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m'; RESET='\033[0m'
|
|||
|
||||
# ── 진입 파일 공통 관리 ──────────────────────────────────────────────────────
|
||||
source "$SCRIPT_DIR/entry-files.sh"
|
||||
source "$SCRIPT_DIR/ai-ignore.sh"
|
||||
|
||||
# ── 대상 경로 해석 (폴더명 / 상대경로 / 절대경로) ────────────────────────────
|
||||
resolve_target() {
|
||||
|
|
@ -119,6 +120,8 @@ discover_agent_ops_targets() {
|
|||
}
|
||||
|
||||
agent_ops_git_paths() {
|
||||
local include_ai_config="${1:-1}"
|
||||
|
||||
printf '%s\n' "agent-ops/.version"
|
||||
printf '%s\n' "agent-ops/bin"
|
||||
printf '%s\n' "agent-ops/rules/common"
|
||||
|
|
@ -130,10 +133,19 @@ agent_ops_git_paths() {
|
|||
printf '%s\n' "$f"
|
||||
fi
|
||||
done
|
||||
if [[ "$include_ai_config" != "1" || -f ".agent-ops-source" ]]; then
|
||||
return
|
||||
fi
|
||||
for f in "${AGENT_OPS_AI_SYNC_FILES[@]}"; do
|
||||
if [[ -e "$f" ]] || git ls-files --error-unmatch "$f" >/dev/null 2>&1; then
|
||||
printf '%s\n' "$f"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
commit_and_push_agent_ops_scope() {
|
||||
local repo="$1" message="$2"
|
||||
local include_ai_config="${3:-1}"
|
||||
|
||||
if ! git -C "$repo" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
echo -e "${RED}Error: git 저장소가 아닙니다: $repo${RESET}"
|
||||
|
|
@ -142,7 +154,7 @@ commit_and_push_agent_ops_scope() {
|
|||
|
||||
(
|
||||
cd "$repo"
|
||||
mapfile -t paths < <(agent_ops_git_paths)
|
||||
mapfile -t paths < <(agent_ops_git_paths "$include_ai_config")
|
||||
git add -- "${paths[@]}"
|
||||
|
||||
if git diff --cached --quiet -- "${paths[@]}"; then
|
||||
|
|
@ -179,6 +191,7 @@ sync_framework_to_target() {
|
|||
cp "$SRC_AO/.version" "$dst_ao/.version"
|
||||
apply_agent_ops_entry_files "$SRC_AO/rules/common/rules.md" "$target"
|
||||
fi
|
||||
ensure_agent_ops_ai_ignore_config "$target"
|
||||
|
||||
commit_and_push_agent_ops_scope "$target" "sync: agent-ops from $(basename "$PROJECT_ROOT") v$src_ver"
|
||||
echo -e "${GREEN}✓ 완료 → $(basename "$target")${RESET}"
|
||||
|
|
@ -234,11 +247,8 @@ if [[ "$PULL_MODE" == "1" ]]; then
|
|||
sync_common "$DST_AO" "$SRC_AO"
|
||||
cp "$DST_AO/.version" "$SRC_AO/.version"
|
||||
apply_agent_ops_entry_files "$DST_AO/rules/common/rules.md" "$PROJECT_ROOT"
|
||||
cd "$PROJECT_ROOT"
|
||||
git add agent-ops/rules/common agent-ops/skills/common agent-ops/bin agent-ops/.version \
|
||||
"${AGENT_OPS_ENTRY_FILES[@]}"
|
||||
git commit -m "sync: pull from agentic-framework v$DST_VER"
|
||||
git push
|
||||
ensure_agent_ops_ai_ignore_config "$PROJECT_ROOT"
|
||||
commit_and_push_agent_ops_scope "$PROJECT_ROOT" "sync: pull from agentic-framework v$DST_VER"
|
||||
echo -e "${GREEN}✓ 완료 (pull v$DST_VER)${RESET}"
|
||||
exit 0
|
||||
fi
|
||||
|
|
@ -293,24 +303,29 @@ 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"
|
||||
|
||||
COMMON_CHANGED="1"
|
||||
if ! common_differs "$SRC_AO" "$DST_AO"; then
|
||||
echo " 공통 파일 변경 없음: .version 차이는 무시하고 버전 갱신/커밋을 건너뜀"
|
||||
echo -e "${GREEN}✓ 완료 (변경 없음)${RESET}"
|
||||
exit 0
|
||||
COMMON_CHANGED="0"
|
||||
fi
|
||||
|
||||
if version_gt "$DST_VER" "$SRC_VER"; then
|
||||
if [[ "$COMMON_CHANGED" == "1" ]] && version_gt "$DST_VER" "$SRC_VER"; then
|
||||
echo -e "${RED}⚠ 버전 충돌: framework($DST_VER) > current($SRC_VER)${RESET}"
|
||||
echo -e "${YELLOW} 먼저 sync-pull로 내려받은 뒤 재시도하세요.${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$COMMON_CHANGED" == "0" ]]; then
|
||||
echo " 공통 파일 변경 없음: .version 차이는 무시하고 버전 갱신/커밋을 건너뜀"
|
||||
echo -e "${GREEN}✓ 완료 (공통 변경 없음)${RESET}"
|
||||
exit 0
|
||||
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"
|
||||
|
||||
commit_and_push_agent_ops_scope "$TARGET" "sync: from $(basename "$PROJECT_ROOT") v$NEW_VER"
|
||||
commit_and_push_agent_ops_scope "$PROJECT_ROOT" "sync: to agentic-framework v$NEW_VER"
|
||||
commit_and_push_agent_ops_scope "$TARGET" "sync: from $(basename "$PROJECT_ROOT") v$NEW_VER" "0"
|
||||
commit_and_push_agent_ops_scope "$PROJECT_ROOT" "sync: to agentic-framework v$NEW_VER" "0"
|
||||
|
||||
echo -e "${GREEN}✓ 완료 (v$SRC_VER → v$NEW_VER)${RESET}"
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ description: 프로젝트 상태를 판별하고 agent-ops 기본 스캐폴드
|
|||
| `agent-ops/rules/private/` | 폴더만 생성 (내용은 개인이 작성) |
|
||||
| `.gitignore`에 `agent-ops/rules/private/` 추가 | git 추적 제외 |
|
||||
| `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore` | `agent-task/archive/**`, `agent-ops/roadmap/archive/**` 한 줄씩 추가 |
|
||||
| `.claude/settings.json`, `opencode.json` | 파일이 없으면 `agent-task/archive/**`, `agent-ops/roadmap/archive/**` 읽기/검색 제외 설정 생성, 있으면 덮어쓰지 않고 수동 병합 안내 |
|
||||
| `.claude/settings.json`, `opencode.json` | 파일이 없으면 `agent-task/archive/**`, `agent-ops/roadmap/archive/**` 읽기/검색 제외 설정 생성, 있으면 구조적으로 병합하고 병합할 수 없을 때 수동 병합 안내 |
|
||||
|
||||
에이전트별 파일명:
|
||||
|
||||
|
|
@ -178,7 +178,8 @@ common/rules.md와 내용이 중복되지 않도록 한다.
|
|||
|
||||
3. **AI ignore / permission 기본 설정**
|
||||
- `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`를 추가한다
|
||||
- `.claude/settings.json`, `opencode.json`이 없으면 archive 읽기/검색 제외 설정을 생성한다
|
||||
- `.claude/settings.json`, `opencode.json`이 없으면 archive 읽기/검색 제외 설정을 생성하고, 있으면 가능한 경우 기존 설정을 보존하며 필요한 제외 설정만 병합한다
|
||||
- 대상 루트에 `.agent-ops-source`가 있으면 AI ignore / permission 파일은 보강하지 않는다
|
||||
- `agent-task/archive/**`와 `agent-ops/roadmap/archive/**` 제외는 `.gitignore`에 추가하지 않는다
|
||||
|
||||
4. **agent-ops 폴더 구조 복사**
|
||||
|
|
@ -234,7 +235,7 @@ common/rules.md와 내용이 중복되지 않도록 한다.
|
|||
- [ ] `rules/project/rules.md`의 도메인 매핑 테이블에 생성된 도메인이 모두 등록되어 있는가
|
||||
- [ ] `.gitignore`에 `agent-ops/rules/private/` 항목이 추가되어 있는가
|
||||
- [ ] `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`가 포함되어 있는가
|
||||
- [ ] `.claude/settings.json`, `opencode.json`에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**` 제외 설정이 있거나, 기존 파일 수동 병합 안내를 출력했는가
|
||||
- [ ] `.claude/settings.json`, `opencode.json`에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**` 제외 설정이 있거나, 병합 불가 시 수동 병합 안내를 출력했는가
|
||||
- [ ] `.gitignore`에 `agent-task/archive/**` 또는 `agent-ops/roadmap/archive/**`를 추가하지 않았는가
|
||||
- 검증 실패 시: 누락된 파일/항목을 사용자에게 알리고 해당 부분만 보완한다
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ agent-ops/bin/sync.sh --pull <target>
|
|||
- [ ] sync.sh 가 오류 없이 완료됐는가
|
||||
- [ ] 현재 프로젝트 버전이 framework 버전과 일치하는가
|
||||
- [ ] `agent-ops/bin/entry-files.sh`의 모든 진입 파일이 갱신됐고, 내용이 framework의 `agent-ops/rules/common/rules.md`와 일치하는가
|
||||
- [ ] `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`가 포함되어 있는가
|
||||
- [ ] agentic-framework의 AI ignore / permission 파일은 수정되거나 stage되지 않았는가
|
||||
|
||||
## 금지 사항
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ description: 현재 프로젝트의 agent-ops를 agentic-framework로 올리거
|
|||
2. **있으면**: `agent-ops/bin/sync.sh` 실행 또는 `agent-ops/bin/sync.sh agentic-framework` 실행
|
||||
3. **없으면**: 사용자에게 agentic-framework 경로 입력을 안내하고, 입력받은 경로로 실행
|
||||
4. 공통 관리 파일 변경 없이 `agent-ops/.version`만 다른 경우 `sync.sh`는 버전 갱신과 commit/push를 건너뛴다
|
||||
5. 일반 프로젝트에서 agentic-framework로 올릴 때는 AI ignore / permission 파일을 보강하거나 stage하지 않는다
|
||||
|
||||
### 현 프로젝트가 agentic-framework인 경우 (`.agent-ops-source` 있음)
|
||||
|
||||
|
|
@ -35,7 +36,8 @@ description: 현재 프로젝트의 agent-ops를 agentic-framework로 올리거
|
|||
3. **명시되지 않은 경우**: `agent-ops/bin/sync.sh` 실행
|
||||
4. target이 없으면 `sync.sh`가 현재 프로젝트 기준 상위 폴더(`../`)의 하위 디렉터리 중 `agent-ops/` 폴더가 있는 프로젝트를 모두 대상으로 삼는다
|
||||
5. `sync.sh`는 현재 agentic-framework의 `agent-ops/rules/common/rules.md` 내용을 대상 프로젝트 루트의 진입 파일에 덮어쓴다
|
||||
6. 적용 후 각 대상 repo에서 agent-ops 공통 관리 경로(`rules/common/rules.md` 포함)와 진입 파일만 stage 하여 commit/push 한다
|
||||
6. 적용 후 각 대상 repo에서 agent-ops 공통 관리 경로(`rules/common/rules.md` 포함), 진입 파일, AI ignore / permission 파일을 stage 하여 commit/push 한다
|
||||
7. AI ignore / permission 파일은 대상 프로젝트의 기존 내용을 덮어쓰지 않고, 누락된 표준 archive 제외 설정만 보강한다
|
||||
|
||||
덮어쓰기 대상은 `init-agent-ops` 초기 세팅과 동일하며, 실제 목록은 `agent-ops/bin/entry-files.sh`의 `AGENT_OPS_ENTRY_FILES`를 단일 기준으로 사용한다.
|
||||
|
||||
|
|
@ -53,7 +55,7 @@ description: 현재 프로젝트의 agent-ops를 agentic-framework로 올리거
|
|||
agent-ops/bin/sync.sh [target]
|
||||
```
|
||||
|
||||
푸시 대상 path는 항상 `agent-ops/.version`, `agent-ops/bin`, `agent-ops/rules/common`, `agent-ops/skills/common`과 `AGENT_OPS_ENTRY_FILES`의 진입 파일로 제한한다.
|
||||
푸시 대상 path는 항상 `agent-ops/.version`, `agent-ops/bin`, `agent-ops/rules/common`, `agent-ops/skills/common`, `AGENT_OPS_ENTRY_FILES`의 진입 파일로 제한한다. AI ignore / permission 파일은 framework에서 일반 프로젝트로 내려보내는 경우에만 대상 repo에서 추가 stage한다.
|
||||
|
||||
## 실행 결과 검증
|
||||
|
||||
|
|
@ -61,7 +63,9 @@ agent-ops/bin/sync.sh [target]
|
|||
- [ ] 버전 충돌 경고가 없었는가 — 있었다면 사용자에게 수동 머지 필요함을 알린다
|
||||
- [ ] 대상 repo의 `agent-ops/rules/common/rules.md`가 현재 agentic-framework의 `agent-ops/rules/common/rules.md`와 일치하는가
|
||||
- [ ] agentic-framework에서 대상 프로젝트로 push한 경우, `agent-ops/bin/entry-files.sh`의 모든 진입 파일 내용이 현재 agentic-framework의 `agent-ops/rules/common/rules.md`와 일치하는가
|
||||
- [ ] 대상 repo에 commit/push 된 path가 agent-ops 공통 관리 경로와 진입 파일로 제한되었는가
|
||||
- [ ] framework에서 대상 프로젝트로 push한 경우, `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`가 포함되어 있는가
|
||||
- [ ] 일반 프로젝트에서 agentic-framework로 push한 경우, AI ignore / permission 파일이 agentic-framework에 유입되지 않았는가
|
||||
- [ ] 대상 repo에 commit/push 된 path가 방향별 허용 범위로 제한되었는가
|
||||
|
||||
## 금지 사항
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue