oh-my-ag 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/skills/_shared/api-contracts/README.md +56 -0
- package/.agent/skills/_shared/api-contracts/template.md +88 -0
- package/.agent/skills/_shared/clarification-protocol.md +217 -0
- package/.agent/skills/_shared/common-checklist.md +31 -0
- package/.agent/skills/_shared/context-budget.md +118 -0
- package/.agent/skills/_shared/context-loading.md +105 -0
- package/.agent/skills/_shared/difficulty-guide.md +55 -0
- package/.agent/skills/_shared/lessons-learned.md +113 -0
- package/.agent/skills/_shared/memory-protocol.md +79 -0
- package/.agent/skills/_shared/reasoning-templates.md +161 -0
- package/.agent/skills/_shared/skill-routing.md +80 -0
- package/.agent/skills/_shared/verify.sh +252 -0
- package/.agent/skills/backend-agent/SKILL.md +47 -0
- package/.agent/skills/backend-agent/resources/api-template.py +326 -0
- package/.agent/skills/backend-agent/resources/checklist.md +36 -0
- package/.agent/skills/backend-agent/resources/error-playbook.md +98 -0
- package/.agent/skills/backend-agent/resources/examples.md +85 -0
- package/.agent/skills/backend-agent/resources/execution-protocol.md +45 -0
- package/.agent/skills/backend-agent/resources/snippets.md +197 -0
- package/.agent/skills/backend-agent/resources/tech-stack.md +39 -0
- package/.agent/skills/commit/SKILL.md +121 -0
- package/.agent/skills/commit/config/commit-config.yaml +55 -0
- package/.agent/skills/commit/resources/conventional-commits.md +166 -0
- package/.agent/skills/debug-agent/SKILL.md +51 -0
- package/.agent/skills/debug-agent/resources/bug-report-template.md +332 -0
- package/.agent/skills/debug-agent/resources/checklist.md +30 -0
- package/.agent/skills/debug-agent/resources/common-patterns.md +734 -0
- package/.agent/skills/debug-agent/resources/debugging-checklist.md +362 -0
- package/.agent/skills/debug-agent/resources/error-playbook.md +94 -0
- package/.agent/skills/debug-agent/resources/examples.md +87 -0
- package/.agent/skills/debug-agent/resources/execution-protocol.md +51 -0
- package/.agent/skills/frontend-agent/SKILL.md +48 -0
- package/.agent/skills/frontend-agent/resources/checklist.md +38 -0
- package/.agent/skills/frontend-agent/resources/component-template.tsx +92 -0
- package/.agent/skills/frontend-agent/resources/error-playbook.md +108 -0
- package/.agent/skills/frontend-agent/resources/examples.md +77 -0
- package/.agent/skills/frontend-agent/resources/execution-protocol.md +49 -0
- package/.agent/skills/frontend-agent/resources/snippets.md +205 -0
- package/.agent/skills/frontend-agent/resources/tailwind-rules.md +343 -0
- package/.agent/skills/frontend-agent/resources/tech-stack.md +36 -0
- package/.agent/skills/mobile-agent/SKILL.md +46 -0
- package/.agent/skills/mobile-agent/resources/checklist.md +35 -0
- package/.agent/skills/mobile-agent/resources/error-playbook.md +106 -0
- package/.agent/skills/mobile-agent/resources/examples.md +79 -0
- package/.agent/skills/mobile-agent/resources/execution-protocol.md +49 -0
- package/.agent/skills/mobile-agent/resources/screen-template.dart +298 -0
- package/.agent/skills/mobile-agent/resources/snippets.md +235 -0
- package/.agent/skills/mobile-agent/resources/tech-stack.md +45 -0
- package/.agent/skills/orchestrator/SKILL.md +99 -0
- package/.agent/skills/orchestrator/config/cli-config.yaml +78 -0
- package/.agent/skills/orchestrator/resources/memory-schema.md +212 -0
- package/.agent/skills/orchestrator/resources/subagent-prompt-template.md +153 -0
- package/.agent/skills/orchestrator/scripts/parallel-run.sh +330 -0
- package/.agent/skills/orchestrator/scripts/spawn-agent.sh +263 -0
- package/.agent/skills/orchestrator/templates/backend-task.md +18 -0
- package/.agent/skills/orchestrator/templates/debug-task.md +16 -0
- package/.agent/skills/orchestrator/templates/frontend-task.md +17 -0
- package/.agent/skills/orchestrator/templates/mobile-task.md +17 -0
- package/.agent/skills/orchestrator/templates/qa-task.md +16 -0
- package/.agent/skills/orchestrator/templates/tasks-example.yaml +15 -0
- package/.agent/skills/pm-agent/SKILL.md +47 -0
- package/.agent/skills/pm-agent/resources/error-playbook.md +75 -0
- package/.agent/skills/pm-agent/resources/examples.md +121 -0
- package/.agent/skills/pm-agent/resources/execution-protocol.md +46 -0
- package/.agent/skills/pm-agent/resources/task-template.json +57 -0
- package/.agent/skills/qa-agent/SKILL.md +43 -0
- package/.agent/skills/qa-agent/resources/checklist.md +294 -0
- package/.agent/skills/qa-agent/resources/error-playbook.md +95 -0
- package/.agent/skills/qa-agent/resources/examples.md +100 -0
- package/.agent/skills/qa-agent/resources/execution-protocol.md +50 -0
- package/.agent/skills/qa-agent/resources/self-check.md +27 -0
- package/.agent/skills/workflow-guide/SKILL.md +57 -0
- package/.agent/skills/workflow-guide/resources/examples.md +68 -0
- package/README.ko.md +459 -0
- package/README.md +563 -0
- package/bin/cli.js +205 -0
- package/package.json +75 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Lessons Learned
|
|
2
|
+
|
|
3
|
+
세션 간 누적되는 교훈 저장소. 모든 에이전트는 실행 시작 시 이 파일을 참조한다.
|
|
4
|
+
QA Agent와 Orchestrator가 세션 종료 후 새 교훈을 추가한다.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 사용 방법
|
|
9
|
+
|
|
10
|
+
### 읽기 (모든 에이전트)
|
|
11
|
+
- Complex 태스크 시작 시: 자신의 도메인 섹션을 읽고 동일 실수 방지
|
|
12
|
+
- Medium 태스크: 관련 항목이 있으면 참고
|
|
13
|
+
- Simple 태스크: 스킵 가능
|
|
14
|
+
|
|
15
|
+
### 쓰기 (QA Agent, Orchestrator)
|
|
16
|
+
세션 종료 후 아래 형식으로 추가:
|
|
17
|
+
```markdown
|
|
18
|
+
### {YYYY-MM-DD}: {agent-type} - {한줄 요약}
|
|
19
|
+
- **문제**: {무엇이 잘못되었나}
|
|
20
|
+
- **원인**: {왜 발생했나}
|
|
21
|
+
- **해결**: {어떻게 고쳤나}
|
|
22
|
+
- **예방**: {앞으로 어떻게 방지하나}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Backend Lessons
|
|
28
|
+
|
|
29
|
+
> 이 섹션은 backend-agent, debug-agent (backend 버그 시) 가 참조합니다.
|
|
30
|
+
|
|
31
|
+
### 초기 교훈 (프로젝트 설정 시 기록)
|
|
32
|
+
- **SQLAlchemy 2.0 스타일만 사용**: `query()` 대신 `select()` 사용. 레거시 스타일은 경고 발생.
|
|
33
|
+
- **Alembic autogenerate 후 반드시 리뷰**: 자동 생성된 마이그레이션에 인덱스 누락 또는 잘못된 타입이 있을 수 있음.
|
|
34
|
+
- **FastAPI Depends 체인**: 의존성 함수 내에서 다른 Depends를 호출하면 순서 문제 발생 가능. 테스트로 확인.
|
|
35
|
+
- **async/await 일관성**: 하나의 라우터에서 sync/async 혼용하지 말 것. 모두 async로 통일.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Frontend Lessons
|
|
40
|
+
|
|
41
|
+
> 이 섹션은 frontend-agent, debug-agent (frontend 버그 시) 가 참조합니다.
|
|
42
|
+
|
|
43
|
+
### 초기 교훈
|
|
44
|
+
- **Next.js App Router**: `useSearchParams()`는 반드시 `<Suspense>` 바운더리 안에서 사용. 안 그러면 빌드 에러.
|
|
45
|
+
- **shadcn/ui 컴포넌트**: import 경로가 `@/components/ui/button`이지 `shadcn/ui`가 아님.
|
|
46
|
+
- **TanStack Query v5**: `useQuery`의 첫 번째 인자가 객체 형태 `{ queryKey, queryFn }`. v4의 `useQuery(key, fn)` 형태 사용 불가.
|
|
47
|
+
- **Tailwind 다크 모드**: `dark:` 접두사는 `darkMode: 'class'` 설정이 있어야 동작.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Mobile Lessons
|
|
52
|
+
|
|
53
|
+
> 이 섹션은 mobile-agent, debug-agent (mobile 버그 시) 가 참조합니다.
|
|
54
|
+
|
|
55
|
+
### 초기 교훈
|
|
56
|
+
- **Riverpod 2.4+ code generation**: `@riverpod` 어노테이션 사용 시 `build_runner` 실행 필요. 빌드 전에 `dart run build_runner build`.
|
|
57
|
+
- **GoRouter redirect**: redirect 함수에서 현재 경로를 반환하면 무한 루프. 반드시 `null` 반환하여 리다이렉트 없음을 표시.
|
|
58
|
+
- **Flutter 3.19+ Material 3**: `useMaterial3: true`가 기본값. ThemeData에서 명시적으로 설정하지 않아도 M3 적용됨.
|
|
59
|
+
- **iOS 시뮬레이터에서 네트워크**: localhost 대신 `127.0.0.1` 사용. 또는 Android는 `10.0.2.2`.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## QA / Security Lessons
|
|
64
|
+
|
|
65
|
+
> 이 섹션은 qa-agent가 참조합니다.
|
|
66
|
+
|
|
67
|
+
### 초기 교훈
|
|
68
|
+
- **rate limiting 확인 방법**: `curl`로 연속 요청 보내서 429 응답 확인. 코드 리뷰만으로는 부족.
|
|
69
|
+
- **CORS 와일드카드**: 개발 환경에서 `*` 사용은 OK, 하지만 production 빌드에서는 반드시 특정 도메인으로 제한.
|
|
70
|
+
- **npm audit vs safety**: frontend는 `npm audit`, backend (Python)은 `pip-audit` 또는 `safety check`.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Debug Lessons
|
|
75
|
+
|
|
76
|
+
> 이 섹션은 debug-agent가 참조합니다.
|
|
77
|
+
|
|
78
|
+
### 초기 교훈
|
|
79
|
+
- **React hydration 에러**: `Date.now()`, `Math.random()`, `window.innerWidth` 등 서버/클라이언트 값이 다른 코드가 원인. `useEffect` + `useState`로 감싸기.
|
|
80
|
+
- **N+1 쿼리 감지**: SQLAlchemy에서 `echo=True` 설정하면 모든 쿼리 로깅. 같은 패턴 쿼리가 반복되면 N+1.
|
|
81
|
+
- **Flutter hot reload 후 상태 유실**: StatefulWidget의 initState가 hot reload 시 재실행되지 않음. 상태 초기화 로직은 didChangeDependencies에.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Cross-Domain Lessons
|
|
86
|
+
|
|
87
|
+
> 모든 에이전트가 참조합니다.
|
|
88
|
+
|
|
89
|
+
### 초기 교훈
|
|
90
|
+
- **API 계약 불일치**: backend가 `snake_case`, frontend가 `camelCase` 기대 시 파싱 실패. 계약서에 casing 명시 필수.
|
|
91
|
+
- **시간대 문제**: backend는 UTC로 저장, frontend는 로컬 타임존으로 표시. ISO 8601 형식 통일.
|
|
92
|
+
- **인증 토큰 전달**: backend가 `Authorization: Bearer {token}` 기대하는데 frontend가 `token` 헤더로 보내는 실수 주의.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 교훈 추가 프로토콜
|
|
97
|
+
|
|
98
|
+
### QA Agent가 추가하는 경우
|
|
99
|
+
리뷰 중 반복되는 이슈를 발견하면:
|
|
100
|
+
1. 해당 도메인 섹션에 교훈 추가
|
|
101
|
+
2. 형식: `### {날짜}: {한줄 요약}` + 문제/원인/해결/예방
|
|
102
|
+
3. MCP 메모리 도구: `[EDIT]("lessons-learned.md", 추가 내용)`
|
|
103
|
+
|
|
104
|
+
### Orchestrator가 추가하는 경우
|
|
105
|
+
세션 종료 시 실패한 태스크가 있으면:
|
|
106
|
+
1. 실패 원인 분석
|
|
107
|
+
2. 해당 도메인 섹션에 교훈 추가
|
|
108
|
+
3. 다음 세션에서 같은 실수 방지
|
|
109
|
+
|
|
110
|
+
### 교훈이 너무 많아지면 (50개 이상)
|
|
111
|
+
- 오래된 교훈 (6개월+)은 아카이브로 이동
|
|
112
|
+
- 프레임워크 버전 업그레이드로 무효화된 교훈 삭제
|
|
113
|
+
- 이 정리는 수동으로 수행 (에이전트가 임의 삭제하지 말 것)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Memory Protocol (CLI Mode)
|
|
2
|
+
|
|
3
|
+
When running as a CLI subagent via `gemini -p "..." --approval-mode=yolo`, follow this protocol.
|
|
4
|
+
|
|
5
|
+
## Tool Reference
|
|
6
|
+
|
|
7
|
+
Tool names are configurable via `mcp.json → memoryConfig.tools`:
|
|
8
|
+
- `[READ]` → default: `read_memory`
|
|
9
|
+
- `[WRITE]` → default: `write_memory`
|
|
10
|
+
- `[EDIT]` → default: `edit_memory`
|
|
11
|
+
- `[LIST]` → default: `list_memories`
|
|
12
|
+
- `[DELETE]` → default: `delete_memory`
|
|
13
|
+
|
|
14
|
+
Memory base path is configurable via `memoryConfig.basePath` (default: `.serena/memories`).
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## On Start
|
|
19
|
+
|
|
20
|
+
1. `[READ]("task-board.md")` to confirm your assigned task
|
|
21
|
+
2. `[WRITE]("progress-{agent-id}.md", initial progress entry)` with Turn 1 status
|
|
22
|
+
|
|
23
|
+
## During Execution
|
|
24
|
+
|
|
25
|
+
- Every 3-5 turns: `[EDIT]("progress-{agent-id}.md")` to append a new turn entry
|
|
26
|
+
- Include: action taken, current status, files created/modified
|
|
27
|
+
|
|
28
|
+
## On Completion
|
|
29
|
+
|
|
30
|
+
- `[WRITE]("result-{agent-id}.md")` with final result including:
|
|
31
|
+
- Status: `completed` or `failed`
|
|
32
|
+
- Summary of work done
|
|
33
|
+
- Files created/modified
|
|
34
|
+
- Acceptance criteria checklist
|
|
35
|
+
|
|
36
|
+
## On Failure
|
|
37
|
+
|
|
38
|
+
- Still create `result-{agent-id}.md` with Status: `failed`
|
|
39
|
+
- Include detailed error description and what remains incomplete
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Example with Default Tools (Serena)
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
# On Start
|
|
47
|
+
read_memory("task-board.md")
|
|
48
|
+
write_memory("progress-backend.md", initial_content)
|
|
49
|
+
|
|
50
|
+
# During Execution
|
|
51
|
+
edit_memory("progress-backend.md", turn_update)
|
|
52
|
+
|
|
53
|
+
# On Completion
|
|
54
|
+
write_memory("result-backend.md", final_result)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Example with Custom Tools
|
|
58
|
+
|
|
59
|
+
If `memoryConfig.tools` is configured differently:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"memoryConfig": {
|
|
64
|
+
"tools": {
|
|
65
|
+
"read": "fs_read",
|
|
66
|
+
"write": "fs_write",
|
|
67
|
+
"edit": "fs_patch"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Then use:
|
|
74
|
+
```python
|
|
75
|
+
fs_read("task-board.md")
|
|
76
|
+
fs_write("progress-backend.md", initial_content)
|
|
77
|
+
fs_patch("progress-backend.md", turn_update)
|
|
78
|
+
fs_write("result-backend.md", final_result)
|
|
79
|
+
```
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Reasoning Templates
|
|
2
|
+
|
|
3
|
+
멀티스텝 추론이 필요한 상황에서 이 템플릿의 빈칸을 채우며 진행한다.
|
|
4
|
+
중간에 방향을 잃지 않도록 **각 단계를 완료한 후** 다음 단계로 넘어간다.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. 디버깅 추론 (Debug Agent, Backend/Frontend/Mobile Agent)
|
|
9
|
+
|
|
10
|
+
버그의 원인을 찾을 때 아래 루프를 반복한다. 최대 3회 반복 후에도 해결 안 되면 `Status: blocked` 기록.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
=== 가설 #{N} ===
|
|
14
|
+
|
|
15
|
+
관찰: {에러 메시지, 증상, 재현 조건}
|
|
16
|
+
가설: "{현상}은 {추정 원인}으로 인한 것이다"
|
|
17
|
+
검증 방법: {어떻게 확인할 것인가 — 코드 읽기, 로그, 테스트 등}
|
|
18
|
+
검증 결과: {실제로 확인한 내용}
|
|
19
|
+
판정: 맞음 / 틀림
|
|
20
|
+
|
|
21
|
+
맞으면 → 수정 단계로 이동
|
|
22
|
+
틀리면 → 새 가설 #{N+1} 작성
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**예시:**
|
|
26
|
+
```
|
|
27
|
+
=== 가설 #1 ===
|
|
28
|
+
관찰: TodoList에서 "Cannot read property 'map' of undefined"
|
|
29
|
+
가설: "API 응답 전에 todos가 undefined 상태로 .map()이 호출된다"
|
|
30
|
+
검증 방법: TodoList 컴포넌트에서 todos의 초기값 확인
|
|
31
|
+
검증 결과: useState()에 초기값 없음 → undefined
|
|
32
|
+
판정: 맞음 → todos의 기본값을 [] 로 설정
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. 아키텍처 결정 (PM Agent, Backend Agent)
|
|
38
|
+
|
|
39
|
+
기술 선택이나 설계 결정이 필요할 때 이 매트릭스를 채운다.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
=== 결정: {무엇을 선택해야 하는가} ===
|
|
43
|
+
|
|
44
|
+
선택지:
|
|
45
|
+
A: {선택지 A}
|
|
46
|
+
B: {선택지 B}
|
|
47
|
+
C: {선택지 C} (있으면)
|
|
48
|
+
|
|
49
|
+
평가 기준과 점수 (1-5):
|
|
50
|
+
| 기준 | A | B | C | 가중치 |
|
|
51
|
+
|-------------|---|---|---|--------|
|
|
52
|
+
| 성능 | | | | {H/M/L} |
|
|
53
|
+
| 구현 복잡도 | | | | {H/M/L} |
|
|
54
|
+
| 팀 익숙도 | | | | {H/M/L} |
|
|
55
|
+
| 확장성 | | | | {H/M/L} |
|
|
56
|
+
| 기존 코드 일관성 | | | | {H/M/L} |
|
|
57
|
+
|
|
58
|
+
결론: {선택지}
|
|
59
|
+
이유: {1-2줄 근거}
|
|
60
|
+
트레이드오프: {선택하지 않은 것의 장점을 포기하는 이유}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**예시:**
|
|
64
|
+
```
|
|
65
|
+
=== 결정: 상태 관리 라이브러리 ===
|
|
66
|
+
|
|
67
|
+
선택지:
|
|
68
|
+
A: Zustand
|
|
69
|
+
B: Redux Toolkit
|
|
70
|
+
C: React Context
|
|
71
|
+
|
|
72
|
+
| 기준 | A | B | C | 가중치 |
|
|
73
|
+
|-------------|---|---|---|--------|
|
|
74
|
+
| 성능 | 4 | 4 | 3 | M |
|
|
75
|
+
| 구현 복잡도 | 5 | 3 | 4 | H |
|
|
76
|
+
| 팀 익숙도 | 3 | 5 | 5 | M |
|
|
77
|
+
| 확장성 | 4 | 5 | 2 | M |
|
|
78
|
+
| 기존 코드 일관성 | 2 | 5 | 3 | H |
|
|
79
|
+
|
|
80
|
+
결론: Redux Toolkit
|
|
81
|
+
이유: 기존 코드가 RTK 사용 중이며, 팀 익숙도 최고
|
|
82
|
+
트레이드오프: Zustand의 간결함을 포기하지만 일관성 확보
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 3. 원인-결과 체인 (Debug Agent)
|
|
88
|
+
|
|
89
|
+
복잡한 버그에서 실행 흐름을 단계별로 추적할 때 사용한다.
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
=== 실행 흐름 추적 ===
|
|
93
|
+
|
|
94
|
+
1. [진입점] {파일:함수} - {입력값}
|
|
95
|
+
2. [호출] {파일:함수} - {전달된 값}
|
|
96
|
+
3. [처리] {파일:함수} - {변환/로직}
|
|
97
|
+
4. [실패 지점] {파일:함수} - {여기서 예상과 다른 일이 발생}
|
|
98
|
+
- 예상: {예상 동작}
|
|
99
|
+
- 실제: {실제 동작}
|
|
100
|
+
- 원인: {왜 다른가}
|
|
101
|
+
5. [결과] {에러 메시지 또는 잘못된 출력}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**예시:**
|
|
105
|
+
```
|
|
106
|
+
1. [진입점] pages/todos.tsx:TodoPage - 유저가 /todos 접근
|
|
107
|
+
2. [호출] hooks/useTodos.ts:useTodos - fetchTodos() 호출
|
|
108
|
+
3. [처리] api/todos.ts:fetchTodos - GET /api/todos 요청
|
|
109
|
+
4. [실패 지점] hooks/useTodos.ts:23 - data가 undefined인 채로 반환
|
|
110
|
+
- 예상: data = [] (빈 배열)
|
|
111
|
+
- 실제: data = undefined (fetch 완료 전)
|
|
112
|
+
- 원인: useQuery의 initialData 미설정
|
|
113
|
+
5. [결과] TodoList에서 undefined.map() → TypeError
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 4. 리팩토링 판단 (모든 구현 에이전트)
|
|
119
|
+
|
|
120
|
+
코드를 수정할 때 "고칠 것인가, 그대로 둘 것인가" 판단에 사용한다.
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
=== 리팩토링 판단 ===
|
|
124
|
+
|
|
125
|
+
현재 코드 문제: {무엇이 문제인가}
|
|
126
|
+
태스크와 관련성: 직접 관련 / 간접 관련 / 무관
|
|
127
|
+
|
|
128
|
+
직접 관련 → 수정한다
|
|
129
|
+
간접 관련 → result에 기록하되, 현재 태스크 범위 내에서만 수정
|
|
130
|
+
무관 → result에 기록만 한다 (절대 수정하지 않는다)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 5. 성능 병목 분석 (Debug Agent, QA Agent)
|
|
136
|
+
|
|
137
|
+
"느리다"는 보고에 대해 체계적으로 병목을 찾는다.
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
=== 성능 병목 분석 ===
|
|
141
|
+
|
|
142
|
+
측정:
|
|
143
|
+
- 전체 응답 시간: {ms}
|
|
144
|
+
- DB 쿼리 시간: {ms} (쿼리 {N}개)
|
|
145
|
+
- 비즈니스 로직: {ms}
|
|
146
|
+
- 직렬화/렌더링: {ms}
|
|
147
|
+
|
|
148
|
+
병목 위치: {가장 시간이 오래 걸리는 단계}
|
|
149
|
+
원인: {N+1 쿼리 / 무거운 연산 / 큰 응답 / 인덱스 부재 / ...}
|
|
150
|
+
해결: {구체적 수정 방법}
|
|
151
|
+
예상 개선: {X}ms → {Y}ms
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 사용 규칙
|
|
157
|
+
|
|
158
|
+
1. **언제 사용하나**: Complex 난이도 태스크에서 필수, Medium에서 권장
|
|
159
|
+
2. **어디에 기록하나**: `progress-{agent-id}.md`에 추론 과정 기록
|
|
160
|
+
3. **빈칸을 채울 수 없으면**: 해당 정보를 먼저 수집 (Serena, 코드 읽기, 로그 확인)
|
|
161
|
+
4. **3회 반복 후에도 미해결**: `Status: blocked` + 현재까지의 추론 기록을 result에 포함
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Skill Routing Map
|
|
2
|
+
|
|
3
|
+
Orchestrator와 workflow-guide가 태스크를 올바른 에이전트에 배정하기 위한 라우팅 규칙.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 키워드 → 스킬 매핑
|
|
8
|
+
|
|
9
|
+
| 사용자 요청 키워드 | 1차 스킬 | 비고 |
|
|
10
|
+
|-------------------|---------|------|
|
|
11
|
+
| API, endpoint, REST, GraphQL, database, migration | **backend-agent** | |
|
|
12
|
+
| 인증, auth, JWT, login, register, password | **backend-agent** | frontend에도 auth UI 태스크 생성 가능 |
|
|
13
|
+
| UI, 컴포넌트, component, page, form, 화면(웹) | **frontend-agent** | |
|
|
14
|
+
| 스타일, Tailwind, 반응형, responsive, CSS | **frontend-agent** | |
|
|
15
|
+
| 모바일, iOS, Android, Flutter, React Native, 앱 | **mobile-agent** | |
|
|
16
|
+
| 오프라인, push notification, camera, GPS | **mobile-agent** | |
|
|
17
|
+
| 버그, bug, error, crash, 안됨, 깨짐, 느림 | **debug-agent** | |
|
|
18
|
+
| 리뷰, review, 보안, security, 성능, performance | **qa-agent** | |
|
|
19
|
+
| 접근성, accessibility, WCAG, a11y | **qa-agent** | |
|
|
20
|
+
| 계획, plan, 분해, breakdown, 태스크, sprint | **pm-agent** | |
|
|
21
|
+
| 자동, automatic, 병렬, parallel, orchestrate | **orchestrator** | |
|
|
22
|
+
| 워크플로우, workflow, 가이드, manual, step-by-step | **workflow-guide** | |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 복합 요청 라우팅
|
|
27
|
+
|
|
28
|
+
| 요청 패턴 | 실행 순서 |
|
|
29
|
+
|----------|----------|
|
|
30
|
+
| "풀스택 앱 만들어줘" | pm → (backend + frontend) 병렬 → qa |
|
|
31
|
+
| "모바일 앱 만들어줘" | pm → (backend + mobile) 병렬 → qa |
|
|
32
|
+
| "풀스택 + 모바일" | pm → (backend + frontend + mobile) 병렬 → qa |
|
|
33
|
+
| "버그 수정하고 리뷰해줘" | debug → qa |
|
|
34
|
+
| "기능 추가하고 테스트해줘" | pm → 해당 agent → qa |
|
|
35
|
+
| "자동으로 다 해줘" | orchestrator (내부적으로 pm → agents → qa) |
|
|
36
|
+
| "수동으로 관리할게" | workflow-guide |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 에이전트 간 의존성 규칙
|
|
41
|
+
|
|
42
|
+
### 병렬 실행 가능 (의존성 없음)
|
|
43
|
+
- backend + frontend (API 계약서가 사전 정의된 경우)
|
|
44
|
+
- backend + mobile (API 계약서가 사전 정의된 경우)
|
|
45
|
+
- frontend + mobile (서로 독립)
|
|
46
|
+
|
|
47
|
+
### 순차 실행 필수
|
|
48
|
+
- pm → 다른 모든 에이전트 (계획이 먼저)
|
|
49
|
+
- 구현 에이전트 → qa (구현 완료 후 리뷰)
|
|
50
|
+
- 구현 에이전트 → debug (구현 완료 후 디버깅)
|
|
51
|
+
- backend → frontend/mobile (API 계약서 없이 병렬 실행 시)
|
|
52
|
+
|
|
53
|
+
### QA는 항상 마지막
|
|
54
|
+
- qa-agent는 모든 구현 태스크 완료 후에 실행
|
|
55
|
+
- 예외: 사용자가 특정 파일만 리뷰 요청한 경우 즉시 실행 가능
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 에스컬레이션 규칙
|
|
60
|
+
|
|
61
|
+
| 상황 | 에스컬레이션 대상 |
|
|
62
|
+
|------|-----------------|
|
|
63
|
+
| 에이전트가 다른 도메인 버그 발견 | debug-agent에 태스크 생성 |
|
|
64
|
+
| QA에서 CRITICAL 발견 | 해당 도메인 에이전트 재실행 |
|
|
65
|
+
| 아키텍처 변경 필요 | pm-agent에 재계획 요청 |
|
|
66
|
+
| 성능 이슈 발견 (구현 중) | 현재 에이전트가 수정, 심각하면 debug-agent |
|
|
67
|
+
| API 계약 불일치 | orchestrator가 backend 에이전트 재실행 |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 에이전트별 턴 제한 가이드
|
|
72
|
+
|
|
73
|
+
| 에이전트 | 기본 턴 | 최대 턴 (재시도 포함) |
|
|
74
|
+
|---------|--------|---------------------|
|
|
75
|
+
| pm-agent | 10 | 15 |
|
|
76
|
+
| backend-agent | 20 | 30 |
|
|
77
|
+
| frontend-agent | 20 | 30 |
|
|
78
|
+
| mobile-agent | 20 | 30 |
|
|
79
|
+
| debug-agent | 15 | 25 |
|
|
80
|
+
| qa-agent | 15 | 20 |
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Subagent Result Auto-Verification Script
|
|
4
|
+
# Used by orchestrator after agent completion to objectively verify deliverables.
|
|
5
|
+
#
|
|
6
|
+
# Usage: bash .agent/skills/_shared/verify.sh <agent-type> <workspace-path>
|
|
7
|
+
# agent-type: backend | frontend | mobile | qa | debug | pm
|
|
8
|
+
# workspace-path: project root or agent workspace directory
|
|
9
|
+
#
|
|
10
|
+
# Exit codes:
|
|
11
|
+
# 0 = all checks passed
|
|
12
|
+
# 1 = some checks failed (see output)
|
|
13
|
+
# 2 = invalid arguments
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
AGENT_TYPE="${1:-}"
|
|
19
|
+
WORKSPACE="${2:-.}"
|
|
20
|
+
PASS=0
|
|
21
|
+
FAIL=0
|
|
22
|
+
WARN=0
|
|
23
|
+
|
|
24
|
+
if [ -z "$AGENT_TYPE" ]; then
|
|
25
|
+
echo "Usage: verify.sh <agent-type> <workspace-path>"
|
|
26
|
+
echo " agent-type: backend | frontend | mobile | qa | debug | pm"
|
|
27
|
+
exit 2
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
cd "$WORKSPACE" || { echo "FAIL: Cannot access workspace $WORKSPACE"; exit 2; }
|
|
31
|
+
|
|
32
|
+
# --- Helper functions ---
|
|
33
|
+
check_pass() { echo " PASS: $1"; ((PASS++)); }
|
|
34
|
+
check_fail() { echo " FAIL: $1"; ((FAIL++)); }
|
|
35
|
+
check_warn() { echo " WARN: $1"; ((WARN++)); }
|
|
36
|
+
check_skip() { echo " SKIP: $1"; }
|
|
37
|
+
|
|
38
|
+
echo "=========================================="
|
|
39
|
+
echo "Verification: $AGENT_TYPE agent"
|
|
40
|
+
echo "Workspace: $WORKSPACE"
|
|
41
|
+
echo "=========================================="
|
|
42
|
+
echo ""
|
|
43
|
+
|
|
44
|
+
# --- Common checks (all agents) ---
|
|
45
|
+
echo "[Common Checks]"
|
|
46
|
+
|
|
47
|
+
# Check for hardcoded secrets
|
|
48
|
+
if grep -rn --include="*.py" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.dart" \
|
|
49
|
+
-E "(password|secret|api_key|token)\s*=\s*['\"][^'\"]{8,}" . 2>/dev/null | grep -v "test" | grep -v "example" | grep -v "node_modules" | head -5; then
|
|
50
|
+
check_fail "Possible hardcoded secrets found (see above)"
|
|
51
|
+
else
|
|
52
|
+
check_pass "No hardcoded secrets detected"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Check for TODO/FIXME left behind
|
|
56
|
+
TODO_COUNT=$(grep -rn --include="*.py" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.dart" \
|
|
57
|
+
-E "TODO|FIXME|HACK|XXX" . 2>/dev/null | grep -v "node_modules" | grep -v ".agent/" | wc -l | tr -d ' ')
|
|
58
|
+
if [ "$TODO_COUNT" -gt 0 ]; then
|
|
59
|
+
check_warn "$TODO_COUNT TODO/FIXME comments found"
|
|
60
|
+
else
|
|
61
|
+
check_pass "No TODO/FIXME comments"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
echo ""
|
|
65
|
+
|
|
66
|
+
# --- Agent-specific checks ---
|
|
67
|
+
case "$AGENT_TYPE" in
|
|
68
|
+
|
|
69
|
+
backend)
|
|
70
|
+
echo "[Backend Checks]"
|
|
71
|
+
|
|
72
|
+
# Python syntax check
|
|
73
|
+
if command -v python3 &>/dev/null; then
|
|
74
|
+
PY_ERRORS=$(find . -name "*.py" -not -path "*/node_modules/*" -not -path "*/.venv/*" -exec python3 -m py_compile {} \; 2>&1 | head -10)
|
|
75
|
+
if [ -z "$PY_ERRORS" ]; then
|
|
76
|
+
check_pass "Python syntax valid"
|
|
77
|
+
else
|
|
78
|
+
echo "$PY_ERRORS"
|
|
79
|
+
check_fail "Python syntax errors found"
|
|
80
|
+
fi
|
|
81
|
+
else
|
|
82
|
+
check_skip "python3 not available"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Check for raw SQL string interpolation
|
|
86
|
+
if grep -rn --include="*.py" -E "f['\"].*SELECT|f['\"].*INSERT|f['\"].*UPDATE|f['\"].*DELETE" . 2>/dev/null | grep -v "test" | grep -v "node_modules" | head -5; then
|
|
87
|
+
check_fail "Possible SQL injection: f-string with SQL keywords"
|
|
88
|
+
else
|
|
89
|
+
check_pass "No SQL string interpolation detected"
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# Check for pytest
|
|
93
|
+
if command -v pytest &>/dev/null || [ -f "pyproject.toml" ]; then
|
|
94
|
+
if pytest --co -q 2>/dev/null | tail -1 | grep -q "no tests"; then
|
|
95
|
+
check_warn "No tests found"
|
|
96
|
+
else
|
|
97
|
+
if pytest -q --tb=no 2>/dev/null; then
|
|
98
|
+
check_pass "Tests pass"
|
|
99
|
+
else
|
|
100
|
+
check_fail "Tests failing"
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
else
|
|
104
|
+
check_skip "pytest not available"
|
|
105
|
+
fi
|
|
106
|
+
;;
|
|
107
|
+
|
|
108
|
+
frontend)
|
|
109
|
+
echo "[Frontend Checks]"
|
|
110
|
+
|
|
111
|
+
# TypeScript check
|
|
112
|
+
if [ -f "tsconfig.json" ] && command -v npx &>/dev/null; then
|
|
113
|
+
if npx tsc --noEmit 2>/dev/null; then
|
|
114
|
+
check_pass "TypeScript compilation clean"
|
|
115
|
+
else
|
|
116
|
+
check_fail "TypeScript errors found"
|
|
117
|
+
fi
|
|
118
|
+
else
|
|
119
|
+
check_skip "TypeScript not configured or npx not available"
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# Check for inline styles
|
|
123
|
+
INLINE_COUNT=$(grep -rn --include="*.tsx" --include="*.jsx" 'style={{' . 2>/dev/null | grep -v "node_modules" | wc -l | tr -d ' ')
|
|
124
|
+
if [ "$INLINE_COUNT" -gt 0 ]; then
|
|
125
|
+
check_warn "$INLINE_COUNT inline styles found (should use Tailwind)"
|
|
126
|
+
else
|
|
127
|
+
check_pass "No inline styles"
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
# Check for 'any' type
|
|
131
|
+
ANY_COUNT=$(grep -rn --include="*.ts" --include="*.tsx" ': any' . 2>/dev/null | grep -v "node_modules" | grep -v ".d.ts" | wc -l | tr -d ' ')
|
|
132
|
+
if [ "$ANY_COUNT" -gt 3 ]; then
|
|
133
|
+
check_fail "$ANY_COUNT 'any' types found (limit: 3)"
|
|
134
|
+
elif [ "$ANY_COUNT" -gt 0 ]; then
|
|
135
|
+
check_warn "$ANY_COUNT 'any' types found"
|
|
136
|
+
else
|
|
137
|
+
check_pass "No 'any' types"
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Run tests
|
|
141
|
+
if [ -f "package.json" ] && command -v npx &>/dev/null; then
|
|
142
|
+
if npx vitest run --reporter=verbose 2>/dev/null; then
|
|
143
|
+
check_pass "Tests pass"
|
|
144
|
+
else
|
|
145
|
+
check_warn "Tests failed or vitest not configured"
|
|
146
|
+
fi
|
|
147
|
+
else
|
|
148
|
+
check_skip "No package.json or npx not available"
|
|
149
|
+
fi
|
|
150
|
+
;;
|
|
151
|
+
|
|
152
|
+
mobile)
|
|
153
|
+
echo "[Mobile Checks]"
|
|
154
|
+
|
|
155
|
+
# Dart analysis
|
|
156
|
+
if command -v flutter &>/dev/null; then
|
|
157
|
+
ANALYSIS=$(flutter analyze 2>/dev/null | tail -3)
|
|
158
|
+
if echo "$ANALYSIS" | grep -q "No issues found"; then
|
|
159
|
+
check_pass "Flutter analysis clean"
|
|
160
|
+
else
|
|
161
|
+
echo "$ANALYSIS"
|
|
162
|
+
check_fail "Flutter analysis issues found"
|
|
163
|
+
fi
|
|
164
|
+
elif command -v dart &>/dev/null; then
|
|
165
|
+
if dart analyze 2>/dev/null | grep -q "No issues found"; then
|
|
166
|
+
check_pass "Dart analysis clean"
|
|
167
|
+
else
|
|
168
|
+
check_fail "Dart analysis issues found"
|
|
169
|
+
fi
|
|
170
|
+
else
|
|
171
|
+
check_skip "Flutter/Dart not available"
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# Check for undisposed controllers
|
|
175
|
+
UNDISPOSED=$(grep -rn --include="*.dart" "Controller()" . 2>/dev/null | grep -v "dispose" | grep -v "test" | grep -v ".dart_tool" | wc -l | tr -d ' ')
|
|
176
|
+
if [ "$UNDISPOSED" -gt 0 ]; then
|
|
177
|
+
check_warn "$UNDISPOSED controllers found — verify dispose() is called"
|
|
178
|
+
else
|
|
179
|
+
check_pass "Controller disposal looks correct"
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# Run tests
|
|
183
|
+
if command -v flutter &>/dev/null; then
|
|
184
|
+
if flutter test 2>/dev/null; then
|
|
185
|
+
check_pass "Flutter tests pass"
|
|
186
|
+
else
|
|
187
|
+
check_fail "Flutter tests failed"
|
|
188
|
+
fi
|
|
189
|
+
else
|
|
190
|
+
check_skip "Flutter not available for tests"
|
|
191
|
+
fi
|
|
192
|
+
;;
|
|
193
|
+
|
|
194
|
+
qa)
|
|
195
|
+
echo "[QA Report Checks]"
|
|
196
|
+
# QA agent produces reports, not code — verify report quality
|
|
197
|
+
check_pass "QA agent report verified by self-check.md (manual)"
|
|
198
|
+
;;
|
|
199
|
+
|
|
200
|
+
debug)
|
|
201
|
+
echo "[Debug Checks]"
|
|
202
|
+
# Debug agent fixes bugs — run the relevant test suite
|
|
203
|
+
echo " Running project test suite to verify fix..."
|
|
204
|
+
if [ -f "pyproject.toml" ] && command -v pytest &>/dev/null; then
|
|
205
|
+
if pytest -q --tb=short 2>/dev/null; then
|
|
206
|
+
check_pass "All tests pass after fix"
|
|
207
|
+
else
|
|
208
|
+
check_fail "Tests failing after fix"
|
|
209
|
+
fi
|
|
210
|
+
elif [ -f "package.json" ] && command -v npx &>/dev/null; then
|
|
211
|
+
if npx vitest run 2>/dev/null; then
|
|
212
|
+
check_pass "All tests pass after fix"
|
|
213
|
+
else
|
|
214
|
+
check_fail "Tests failing after fix"
|
|
215
|
+
fi
|
|
216
|
+
else
|
|
217
|
+
check_skip "No test runner detected"
|
|
218
|
+
fi
|
|
219
|
+
;;
|
|
220
|
+
|
|
221
|
+
pm)
|
|
222
|
+
echo "[PM Plan Checks]"
|
|
223
|
+
# PM produces plans, not code
|
|
224
|
+
if [ -f ".agent/plan.json" ]; then
|
|
225
|
+
check_pass "plan.json exists"
|
|
226
|
+
# Validate JSON
|
|
227
|
+
if python3 -c "import json; json.load(open('.agent/plan.json'))" 2>/dev/null; then
|
|
228
|
+
check_pass "plan.json is valid JSON"
|
|
229
|
+
else
|
|
230
|
+
check_fail "plan.json is invalid JSON"
|
|
231
|
+
fi
|
|
232
|
+
else
|
|
233
|
+
check_warn "plan.json not found at .agent/plan.json"
|
|
234
|
+
fi
|
|
235
|
+
;;
|
|
236
|
+
|
|
237
|
+
*)
|
|
238
|
+
echo "Unknown agent type: $AGENT_TYPE"
|
|
239
|
+
exit 2
|
|
240
|
+
;;
|
|
241
|
+
esac
|
|
242
|
+
|
|
243
|
+
echo ""
|
|
244
|
+
echo "=========================================="
|
|
245
|
+
echo "Results: $PASS passed, $FAIL failed, $WARN warnings"
|
|
246
|
+
echo "=========================================="
|
|
247
|
+
|
|
248
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
249
|
+
exit 1
|
|
250
|
+
else
|
|
251
|
+
exit 0
|
|
252
|
+
fi
|