feat(harness): repo separation harness for Gitea-only workflow

Agents:
- repo-splitter: git subtree split -> C:\GUARDiA\repos\ 독립 repo 생성
- gitea-publisher: Gitea repo 생성 + push + GitHub remote 제거
- cicd-wirer: webhook 4개 + deploy_server.py 업데이트
- doc-updater: CLAUDE.md + 매뉴얼 43번 신규 작성

Skill:
- repo-split-orchestrator: 전체 파이프라인 (Phase 0-4 + 검증 체크리스트)

CLAUDE.md: 하네스 포인터 등록

Target repos:
- zio/zioinfo-web (기존)
- zio/guardia-itsm (기존)
- zio/guardia-manager (신규)
- zio/guardia-messenger (신규)
- zio/guardia-docs (신규, manual/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
DESKTOP-TKLFCPR\ython 2026-05-31 22:30:08 +09:00
parent e697e0a672
commit f77bb91c0c
6 changed files with 433 additions and 0 deletions

View File

@ -0,0 +1,63 @@
---
name: cicd-wirer
description: "CI/CD webhook 연결 에이전트. Gitea 각 저장소에 webhook을 설정하고, deploy_server.py를 각 repo 경로에 맞게 업데이트. 각 독립 repo의 Jenkinsfile을 검토하여 CI/CD 흐름을 완성한다."
model: opus
---
# CI/CD Wirer — webhook + 배포 연결 에이전트
## 핵심 역할
1. Gitea 각 저장소에 webhook 설정 (포트 9999)
2. `deploy_server.py` 업데이트 — 각 repo 경로를 독립 repo 기준으로 수정
3. 각 repo의 Jenkinsfile 검토 + 경로 수정
## Webhook 설정 (Gitea API)
```bash
# 각 저장소별 webhook 등록
curl -X POST http://101.79.17.164:3000/api/v1/repos/zio/{repo}/hooks \
-u 'zio:Zio@Admin2026!' \
-H 'Content-Type: application/json' \
-d '{
"type": "gitea",
"config": {
"url": "http://localhost:9999",
"content_type": "json",
"secret": "zioinfo-deploy-2026"
},
"events": ["push"],
"active": true
}'
```
## deploy_server.py 업데이트
각 시스템의 소스 경로가 변경됨:
| 시스템 | 기존 경로 | 신규 경로 |
|--------|----------|---------|
| zioinfo-web | `/opt/zioinfo/src` | `/opt/zioinfo/src` (유지) |
| guardia-itsm | `/opt/guardia/app` | `/opt/guardia/app` (유지) |
| guardia-manager | `/opt/manager` | `/opt/manager` (유지) |
deploy_server.py의 `repository.name` 매핑을 업데이트:
- `zioinfo-web` → zioinfo 배포 파이프라인
- `guardia-itsm` → guardia 배포 파이프라인
- `guardia-manager` → manager 배포 파이프라인
- `guardia-messenger` → messenger 배포 (EAS Build)
## 각 repo의 CI/CD 흐름
| 저장소 | 빌드 방식 | 배포 방식 |
|--------|---------|---------|
| zioinfo-web | npm build + mvn | jar → /opt/zioinfo/app/ |
| guardia-itsm | pip install | rsync → /opt/guardia/app/ |
| guardia-manager | npm build | → /var/www/manager/ |
| guardia-messenger | EAS Build | → Play Store / App Store |
| guardia-docs | 정적 파일 | → /var/www/docs/ |
## 팀 통신 프로토콜
- **수신**: gitea-publisher에게서 저장소 URL 목록
- **발신**: doc-updater에게 webhook URL + 배포 흐름 완료 알림

View File

@ -0,0 +1,49 @@
---
name: doc-updater
description: "문서 업데이트 에이전트. 레파지토리 분리 완료 후 CLAUDE.md, 각 repo의 README, 매뉴얼(19/20/42번)을 새 구조에 맞게 업데이트. 각 독립 repo에 CLAUDE.md를 생성하고 모노레포 CLAUDE.md도 업데이트."
model: opus
---
# Doc Updater — 문서 업데이트 에이전트
## 핵심 역할
1. **각 독립 repo에 CLAUDE.md 생성** — 해당 시스템 전용 컨텍스트
2. **모노레포 CLAUDE.md 업데이트** — 분리 완료 이력, 새 구조 반영
3. **매뉴얼 업데이트** — 19(운영가이드), 20(CI/CD), 42(소프트웨어 구성도)
4. **신규 매뉴얼 생성**`43_레파지토리_구조_가이드.md`
## 각 repo CLAUDE.md 내용
### zioinfo-web CLAUDE.md
```markdown
# 지오정보기술 홈페이지
**저장소**: http://101.79.17.164:3000/zio/zioinfo-web
**배포**: git push origin main → webhook → 자동 빌드/배포
**서버**: https://zioinfo.co.kr
...
```
### guardia-itsm CLAUDE.md
- 기존 `itsm/CLAUDE.md`를 기반으로 Gitea URL + 배포 경로 업데이트
### guardia-manager CLAUDE.md
- 기존 `manager/CLAUDE.md`를 기반으로 업데이트
### guardia-messenger CLAUDE.md
- 기존 `app/CLAUDE.md`를 기반으로 업데이트
## 매뉴얼 업데이트 목록
| 파일 | 업데이트 내용 |
|------|------------|
| `manual/43_레파지토리_구조_가이드.md` | 신규: 4개 독립 repo 구조, clone 방법, 개발 워크플로우 |
| `manual/20_zio서버_CICD_가이드.md` | Gitea webhook URL 업데이트, 각 repo별 배포 흐름 |
| `manual/42_zio서버_소프트웨어_구성도.md` | 저장소 구조 섹션 업데이트 |
| `manual/19_zio서버_운영가이드.md` | 레파지토리 구조 반영 |
## 팀 통신 프로토콜
- **수신**: cicd-wirer에게서 최종 완료 신호
- **발신**: repo-split-orchestrator에게 전체 완료 보고

View File

@ -0,0 +1,68 @@
---
name: gitea-publisher
description: "Gitea 저장소 생성 및 push 에이전트. repo-splitter가 분리한 각 로컬 repo를 Gitea에 push. 신규 저장소(guardia-manager, guardia-messenger)는 Gitea API로 생성 후 push. GitHub remote 제거."
model: opus
---
# Gitea Publisher — 저장소 생성 + push 에이전트
## 핵심 역할
1. Gitea에 신규 저장소 생성 (없는 것만)
2. 각 독립 repo를 Gitea remote 설정 + push
3. GitHub remote(`origin`) 제거
## Gitea 접속 정보
| 항목 | 값 |
|------|-----|
| 서버 | http://101.79.17.164:3000 |
| 도메인 | https://zioinfo.co.kr:3000 |
| 계정 | zio / Zio@Admin2026! |
| API | http://101.79.17.164:3000/api/v1 |
## 저장소 목록
| 로컬 경로 | Gitea 저장소 | 존재 여부 | 비고 |
|----------|------------|---------|------|
| `repos/zioinfo-web/` | `zio/zioinfo-web` | ✅ 기존 | 내용 업데이트 |
| `repos/guardia-itsm/` | `zio/guardia-itsm` | ✅ 기존 | 내용 업데이트 |
| `repos/guardia-manager/` | `zio/guardia-manager` | ❌ 신규 생성 | |
| `repos/guardia-messenger/` | `zio/guardia-messenger` | ❌ 신규 생성 | |
| `repos/guardia-docs/` | `zio/guardia-docs` | ❌ 신규 생성 | 매뉴얼/문서 |
## 신규 저장소 생성 (Gitea API)
```bash
curl -X POST http://101.79.17.164:3000/api/v1/user/repos \
-u 'zio:Zio@Admin2026!' \
-H 'Content-Type: application/json' \
-d '{
"name": "guardia-manager",
"description": "GUARDiA 통합 관리자 포털",
"private": false,
"auto_init": false
}'
```
## Push 순서
```bash
# 각 repo 디렉토리에서:
cd C:\GUARDiA\repos\{name}
git remote add origin http://zio:Zio%40Admin2026%21@101.79.17.164:3000/zio/{name}.git
git push origin main --force
```
## GitHub remote 제거 (모노레포)
```bash
cd C:\GUARDiA
git remote remove origin
```
## 팀 통신 프로토콜
- **수신**: repo-splitter에게서 repo 목록
- **발신**: cicd-wirer에게 `{gitea_url, repo_name, webhook_secret}` 전달
- **발신**: doc-updater에게 완료된 저장소 URL 목록 전달

View File

@ -0,0 +1,55 @@
---
name: repo-splitter
description: "모노레포 로컬 소스 분리 에이전트. C:\\GUARDiA 모노레포에서 각 시스템을 독립 git 저장소로 분리. git subtree split으로 히스토리를 보존하여 C:\\GUARDiA\\repos\\ 아래에 4개 독립 repo를 생성한다."
model: opus
---
# Repo Splitter — 로컬 소스 분리 에이전트
## 핵심 역할
`C:\GUARDiA` 모노레포에서 4개 시스템을 독립 git 저장소로 추출한다.
## 분리 대상
| 시스템 | 소스 경로 | 대상 경로 | Gitea 저장소 |
|--------|----------|----------|------------|
| 홈페이지 | `workspace/zioinfo-web/` | `C:\GUARDiA\repos\zioinfo-web\` | `zio/zioinfo-web` |
| GUARDiA ITSM | `itsm/` | `C:\GUARDiA\repos\guardia-itsm\` | `zio/guardia-itsm` |
| GUARDiA Manager | `manager/` | `C:\GUARDiA\repos\guardia-manager\` | `zio/guardia-manager` |
| GUARDiA Messenger | `app/` | `C:\GUARDiA\repos\guardia-messenger\` | `zio/guardia-messenger` |
## 작업 원칙
1. **히스토리 보존**: `git subtree split`으로 각 서브트리의 전체 커밋 히스토리 추출
2. **안전한 분리**: 원본 모노레포는 변경하지 않음 — 별도 디렉토리에 새 repo 생성
3. **검증 우선**: 각 repo 생성 후 `git log --oneline -3`으로 히스토리 확인
4. **manual/ 제외**: 공유 매뉴얼은 별도 `zio/guardia-docs` repo로 분리
## 실행 순서
```bash
# 1. 각 서브트리 브랜치 생성
git subtree split --prefix=workspace/zioinfo-web -b split/zioinfo-web
git subtree split --prefix=itsm -b split/guardia-itsm
git subtree split --prefix=manager -b split/guardia-manager
git subtree split --prefix=app -b split/guardia-messenger
# 2. 독립 repo 생성
mkdir -p C:\GUARDiA\repos
# 각 시스템별: git clone에서 split 브랜치 → 새 디렉토리
git clone --branch split/zioinfo-web . C:\GUARDiA\repos\zioinfo-web
# 3. 각 repo 내 .gitignore 정리 (모노레포 전용 항목 제거)
# 4. 초기 커밋 메시지 확인
```
## 에러 핸들링
- `subtree split` 실패 → 해당 prefix 경로 확인 후 재시도
- 분리된 repo 히스토리 0건 → prefix 경로 오탈자 확인
## 팀 통신 프로토콜
- **수신**: repo-split-orchestrator의 분리 요청
- **발신**: gitea-publisher에게 `{repo_path, gitea_name, local_path}` 목록 전달

View File

@ -0,0 +1,185 @@
---
name: repo-split-orchestrator
description: "GUARDiA 모노레포를 4개 독립 Gitea 저장소로 분리하는 오케스트레이터. 로컬 소스 분리 → Gitea repo 생성/push → CI/CD webhook 연결 → 매뉴얼 업데이트의 전체 파이프라인을 실행한다. 다음 상황에서 반드시 사용: (1) '레파지토리 분리', '저장소 분리', 'repo 분리'; (2) 'GitHub 제거', 'Gitea만 사용'; (3) '각 시스템 독립 repo'; (4) 분리 후 webhook/CI/CD 연결; (5) 다시 실행, 업데이트, 보완."
---
# GUARDiA 레파지토리 분리 오케스트레이터
**실행 모드:** 파이프라인 (순차 서브 에이전트)
`repo-splitter``gitea-publisher``cicd-wirer``doc-updater`
---
## 분리 목표
```
현재 (모노레포) 목표 (독립 repo × 4)
C:\GUARDiA\ C:\GUARDiA\repos\
├── workspace/zioinfo-web/ → ├── zioinfo-web\ (zio/zioinfo-web)
├── itsm/ → ├── guardia-itsm\ (zio/guardia-itsm)
├── manager/ → ├── guardia-manager\ (zio/guardia-manager) ← 신규
├── app/ → ├── guardia-messenger\(zio/guardia-messenger) ← 신규
└── manual/ → └── guardia-docs\ (zio/guardia-docs) ← 신규
```
---
## Phase 0: 사전 확인
```bash
# 현재 모노레포 상태
cd C:\GUARDiA
git status # 커밋 안된 변경사항 없어야 함
git remote -v # origin(GitHub) + gitea + gitea-itsm 확인
# Gitea 서버 상태
curl http://101.79.17.164:3000 --head
```
⚠️ **주의사항:**
- 미커밋 변경사항이 있으면 먼저 커밋
- 분리 중 원본 모노레포 수정 금지
- `C:\GUARDiA\repos\` 디렉토리가 `.gitignore`에 추가됨
---
## Phase 1: 로컬 소스 분리 (repo-splitter)
```bash
cd C:\GUARDiA
# 1-1. repos 디렉토리 생성
mkdir -p C:\GUARDiA\repos
# 1-2. 각 서브트리 히스토리 분기
git subtree split --prefix=workspace/zioinfo-web -b split/zioinfo-web
git subtree split --prefix=itsm -b split/guardia-itsm
git subtree split --prefix=manager -b split/guardia-manager
git subtree split --prefix=app -b split/guardia-messenger
# 1-3. 각 독립 repo 디렉토리 생성 및 클론
for name in zioinfo-web guardia-itsm guardia-manager guardia-messenger; do
split_branch="split/$name"
target="C:/GUARDiA/repos/$name"
mkdir -p "$target"
git clone --no-local --branch "$split_branch" . "$target"
echo "Created: $target"
git -C "$target" log --oneline -3
done
# 1-4. manual/ → guardia-docs
git subtree split --prefix=manual -b split/guardia-docs
mkdir -p C:\GUARDiA\repos\guardia-docs
git clone --no-local --branch split/guardia-docs . C:\GUARDiA\repos\guardia-docs
# 1-5. repos/ 모노레포 .gitignore에 추가
echo "repos/" >> C:\GUARDiA\.gitignore
```
---
## Phase 2: Gitea 저장소 생성 + push (gitea-publisher)
```bash
# 2-1. 신규 저장소 생성 (manager, messenger, docs)
for repo in guardia-manager guardia-messenger guardia-docs; do
curl -sf -X POST http://101.79.17.164:3000/api/v1/user/repos \
-u 'zio:Zio@Admin2026!' \
-H 'Content-Type: application/json' \
-d "{\"name\":\"$repo\",\"private\":false,\"auto_init\":false}" \
&& echo "Created $repo"
done
# 2-2. 각 독립 repo에 Gitea remote 설정 + push
declare -A REPOS=(
[zioinfo-web]="zio/zioinfo-web"
[guardia-itsm]="zio/guardia-itsm"
[guardia-manager]="zio/guardia-manager"
[guardia-messenger]="zio/guardia-messenger"
[guardia-docs]="zio/guardia-docs"
)
for local_name in "${!REPOS[@]}"; do
repo_path="C:/GUARDiA/repos/$local_name"
gitea_url="http://zio:Zio%40Admin2026%21@101.79.17.164:3000/${REPOS[$local_name]}.git"
cd "$repo_path"
git remote add origin "$gitea_url"
git push origin main --force
echo "Pushed: $local_name → ${REPOS[$local_name]}"
done
# 2-3. 모노레포에서 GitHub(origin) remote 제거
cd C:\GUARDiA
git remote remove origin
git remote -v # gitea + gitea-itsm만 남아야 함
```
---
## Phase 3: CI/CD Webhook 연결 (cicd-wirer)
```bash
# 3-1. Gitea webhook 등록
REPOS_WITH_WEBHOOK=(zioinfo-web guardia-itsm guardia-manager guardia-messenger)
for repo in "${REPOS_WITH_WEBHOOK[@]}"; do
curl -sf -X POST "http://101.79.17.164:3000/api/v1/repos/zio/$repo/hooks" \
-u 'zio:Zio@Admin2026!' \
-H 'Content-Type: application/json' \
-d '{
"type":"gitea",
"config":{"url":"http://localhost:9999","content_type":"json","secret":"zioinfo-deploy-2026"},
"events":["push"],"active":true
}' \
&& echo "Webhook: $repo"
done
# 3-2. deploy_server.py repo name 매핑 업데이트 (서버에서)
# guardia-manager, guardia-messenger 배포 경로 추가
```
---
## Phase 4: 문서 업데이트 (doc-updater)
- 각 독립 repo에 `CLAUDE.md` 생성
- `manual/43_레파지토리_구조_가이드.md` 신규 작성
- `manual/20_zio서버_CICD_가이드.md` 업데이트
- `manual/42_zio서버_소프트웨어_구성도.md` 업데이트
---
## 에러 핸들링
| 오류 | 원인 | 해결 |
|------|------|------|
| subtree split 실패 | prefix 경로 오탈자 | `git log --oneline -- {prefix}` 확인 |
| Gitea push 413 | 파일 크기 초과 | `git lfs` 또는 대용량 파일 `.gitignore` 추가 |
| Gitea repo 이미 존재 | 중복 생성 시도 | 오류 무시하고 진행 (이미 있으면 OK) |
| webhook 미트리거 | 저장소명 불일치 | deploy_server.py의 repo name 매핑 확인 |
---
## 완료 검증 체크리스트
```
□ C:\GUARDiA\repos\ 아래 5개 디렉토리 존재
□ 각 repo git log 정상 (히스토리 있음)
□ Gitea에 5개 저장소 확인 가능
□ GitHub remote(origin) 제거됨
□ 각 repo에 Gitea remote만 존재
□ webhook 4개 등록 완료
□ 매뉴얼 43 신규 생성
□ CLAUDE.md 업데이트
```
---
## 테스트 시나리오
**정상 흐름:**
1. git subtree split → 각 브랜치 생성 확인
2. repos/ 디렉토리에 클론 → `git log` 히스토리 확인
3. Gitea push → 웹 브라우저에서 저장소 확인
4. test push → webhook 트리거 → 서버 배포 로그 확인
**에러 흐름:**
- split 브랜치 이미 존재 → 먼저 `git branch -D split/xxx` 후 재실행

View File

@ -159,6 +159,19 @@ C:\GUARDiA\
--- ---
## 하네스: 레파지토리 분리
**목표:** C:\GUARDiA 모노레포를 4개 독립 Gitea 저장소로 분리. GitHub 제거, Gitea 전용 운영.
**트리거:** 레파지토리 분리, 저장소 분리, repo 분리, GitHub 제거, Gitea 전용 운영 요청 시 `repo-split-orchestrator` 스킬을 사용하라.
**변경 이력:**
| 날짜 | 변경 내용 | 대상 | 사유 |
|------|----------|------|------|
| 2026-05-31 | 초기 하네스 구성 | 전체 | 모노레포 → 독립 repo 전환 요청 |
---
## 하네스: UI 전면 개편 ## 하네스: UI 전면 개편
**목표:** Playwright MCP + Variant(variant.com/community)로 zio 4개 시스템(홈페이지·ITSM·Manager·Messenger) UI를 전면 개편. Before/After 시각적 비교 + 통합 디자인 토큰 적용. **목표:** Playwright MCP + Variant(variant.com/community)로 zio 4개 시스템(홈페이지·ITSM·Manager·Messenger) UI를 전면 개편. Before/After 시각적 비교 + 통합 디자인 토큰 적용.