CLI Harness — Claude CLI 제어 명세
Node.js 서버가 Claude CLI를 spawn으로 제어하는 하네스 구조 문서. 에이전트 역할 부여, 옵션 변경, 문제 발생 시 이 문서를 참조한다.
1. 현재 사용 중인 CLI 옵션
| # | 옵션 | 용도 | 비고 |
|---|
| 1 | -p | print mode — 비대화형, 한 번 응답 후 종료 | 필수. 서버가 프로세스 수명 관리 |
| 2 | --dangerously-skip-permissions | 모든 도구 권한 자동 승인 (y/n 프롬프트 스킵) | 추후 모바일 권한 UI로 대체 예정 |
| 3 | --model <model> | 사용할 모델 지정 | 기본값: sonnet (env LLM_MODEL) |
| 4 | --output-format stream-json | stdout을 JSON 이벤트 스트림으로 출력 | 활동 로그 + 최종 결과 파싱용 |
| 5 | --verbose | 상세 로그 출력 | 디버깅용 |
| 6 | -c | continue — 이전 대화 이어서 | 두 번째 메시지부터 자동 추가 |
| 7 | --append-system-prompt <text> | 시스템 프롬프트에 HARD_RULES 추가 | 프로젝트 규칙 강제 |
| 8 | --session-id <uuid> | 세션 격리 | 병렬 에이전트 시 필수 (에이전트별 UUID) |
| 9 | message (마지막 인자) | 사용자/오케스트레이터가 보낸 메시지 | |
아직 미사용이지만 활용 가능한 옵션
| 옵션 | 용도 | 활용 시나리오 |
|---|
--system-prompt <text> | 기본 시스템 프롬프트 교체 | 에이전트별 역할 프롬프트로 교체 |
--allowedTools <tools> | 도구 화이트리스트 | 역할별 도구 제한 (보안 에이전트는 Edit 금지 등) |
--disallowedTools <tools> | 도구 블랙리스트 | 위와 반대 |
--max-budget-usd <amount> | API 비용 상한 | 에이전트별 비용 제어 |
--effort <level> | 응답 노력 수준 (low/medium/high/max) | 단순 작업은 low, 복잡한 설계는 max |
--json-schema <schema> | 구조화된 출력 | PM 보고서 등 정형 응답 강제 |
--input-format stream-json | stdin 스트리밍 입력 | 실시간 양방향 통신 (권한 UI 등) |
--allowedTools + 권한 제거 | 세밀한 도구 제어 | --dangerously-skip-permissions 없이 특정 도구만 허용 |
2. Node.js 하네스 구조
| # | 기능 | 용도 |
|---|
| 1 | spawn(provider, args, { cwd, stdio }) | Claude CLI를 자식 프로세스로 실행 |
| 2 | stdio: ['pipe', 'pipe', 'pipe'] | stdin/stdout/stderr 모두 파이프. stdin은 권한 UI 연동 시 사용 예정 |
| 3 | proc.stdout 파싱 | stream-json 이벤트에서 활동 로그 + 최종 결과 추출 |
| 4 | proc.stderr | 에러 로그 출력 (no stdin data 경고 무시) |
| 5 | channelStarted Set | 채널별 첫 호출 여부 추적 → -c 플래그 결정 |
| 6 | sendActivityLog() | 활동 로그를 Supabase messages 테이블에 저장 (모바일 표시용) |
프로세스 생명주기
callClaude(message, cwd, channelId)
│
├─ clearActivityLogs() // 이전 활동 로그 정리
├─ sendActivityLog('🚀 시작') // 시작 알림
│
├─ args 조합
│ ├─ 기본: -p, --dangerously-skip-permissions, --model, --output-format, --verbose
│ ├─ 이어서: -c (channelStarted에 있으면)
│ ├─ 규칙: --append-system-prompt HARD_RULES
│ └─ 메시지: message
│
├─ spawn('claude', args, { cwd, stdio: pipe })
│
├─ stdout 이벤트 루프
│ ├─ JSON 파싱 (줄 단위)
│ ├─ tool_use → 활동 로그 (Read, Write, Edit, Bash, Glob, Grep, Agent)
│ └─ result → finalResult 저장
│
├─ proc.on('close')
│ ├─ 성공: channelStarted.add(channelId), resolve(finalResult)
│ └─ 실패: reject(Error)
│
└─ sendActivityLog('✅ 완료')
3. 도메인 특화 에이전트 역할 부여
방식
각 에이전트에 역할을 부여하는 데 사용할 수 있는 CLI 옵션 조합:
const args = [
'-p',
'--session-id', agentSessionId, // 에이전트별 세션 격리 (UUID)
'--model', agentModel, // 에이전트별 모델 (haiku/sonnet/opus)
'--output-format', 'stream-json',
'--system-prompt', agentSystemPrompt, // 역할 정의 (DB agents.system_prompt)
'--append-system-prompt', HARD_RULES, // 공통 규칙
'--allowedTools', agentAllowedTools, // 역할별 도구 제한
'--effort', agentEffort, // 역할별 노력 수준
message,
];
역할별 allowedTools (4명 병렬 토론 결과)
| 역할 | allowedTools | 비고 |
|---|
| Director | Read, Grep, Glob, WebSearch, WebFetch | 코딩 금지, DELEGATE 강제 |
| System/Data/Cloud Architect | Read, Grep, Glob, Write, Edit, WebSearch | 설계 문서만 |
| App/DB/Infra Security | Read, Grep, Glob, Bash, WebSearch | 감사+스캔만, 패치는 Developer에 위임 |
| API/BizLogic/DB Developer | 전체 허용 | 코딩 전담 |
| Web/iOS/Android Developer | 전체 허용 | 코딩 전담 |
| UI/UX Designer | 전체 허용 | 디자인+코딩 |
| Functional/Performance Tester | Read, Grep, Glob, Bash | 테스트 실행만 |
| CI/CD/Infra Engineer | Read, Grep, Glob, Bash, Edit, Write | 인프라 코드만 |
| Tech/Market Researcher | Read, Grep, Glob, WebSearch, WebFetch | 조사만 |
| Growth/Content Marketer | Read, Grep, Glob, WebSearch, WebFetch | 분석만 |
| Accountant | Read, Grep, Glob | 비용 조회만 |
세션 격리
에이전트 A (backend_dev_a) → --session-id aaa-bbb-111 → 독립 대화
에이전트 B (frontend_dev_a) → --session-id ccc-ddd-222 → 독립 대화
에이전트 C (security_a) → --session-id eee-fff-333 → 독립 대화
- 같은 CWD에서 여러 에이전트가 동시 실행 가능
-c 대신 --session-id로 대화 이어감 (재사용 시 동일 UUID)- 세션 ID는 서버가 에이전트별로 생성/관리
4. 병렬 실행 검증 결과
=== 병렬 spawn 테스트 (3개 에이전트) ===
✅ [be-arch] (18.4s) — 아키텍처 일관성 검증
✅ [fe-arch] (10.1s) — 클라이언트 간 아키텍처 일관성
✅ [security] (8.9s) — RLS 정책 검증
총 소요: 18.4s (순차였으면 ~37.4s)
- 3개 동시 spawn → 전부 성공
- 병렬 실행 시 약 2배 속도 향상
--session-id로 세션 충돌 없음 확인
5. 알려진 이슈 & 주의사항
| 이슈 | 상태 | 설명 |
|---|
| 파일 동시 수정 충돌 | ⚠️ 미해결 | 여러 에이전트가 같은 파일을 동시에 수정하면 충돌. 역할별 담당 파일/디렉토리 분리 또는 작업 큐로 해결 필요 |
| API 레이트 리밋 | ⚠️ 주의 | 프리티어 동시 요청 제한. 에이전트 수 × 요청 빈도 고려 |
| Realtime TIMED_OUT | ✅ 해결 | 폴링 fallback 추가 (supabase.ts) |
-c 세션 충돌 | ✅ 해결 | --session-id로 대체 |
--dangerously-skip-permissions | 🔜 개선예정 | 모바일 권한 UI로 대체 예정 (stdin 파이프 활용) |
proc.stdin 미사용 | 🔜 개선예정 | 권한/질문 프롬프트 시 모바일 → 서버 → stdin 연결 예정 |
6. 파일 위치
| 파일 | 역할 |
|---|
server/src/orchestrator/llm.ts | Claude CLI spawn + stdout 파싱 + 활동 로그 |
server/src/orchestrator/supabase.ts | Supabase 연결 + Realtime + 폴링 fallback |
server/src/index.ts | 메시지 라우팅 + 에이전트 Roster 출력 |
server/src/types/index.ts | Message 인터페이스 |
supabase/migrations/004_seed.sql | 에이전트 시드 데이터 |
7. DELEGATE (병렬 위임)
Director가 에이전트에게 작업을 위임할 때 사용하는 태그:
[DELEGATE]
api_dev_1: 로그인 API 엔드포인트 구현
ios_dev_1: iOS 로그인 화면 구현
db_security_1: 인증 관련 RLS 정책 검토
[/DELEGATE]
서버 처리 흐름:
- Director 응답에서
[DELEGATE]...[/DELEGATE] 블록 파싱 - DB에서 해당 에이전트 존재 확인 + system_prompt 로드
callAgentsParallel() — 모든 에이전트 동시 spawn- 결과 수집 → Director에게 전달 → 종합 보고
관련 함수:
parseDelegates(content) — DELEGATE 블록 파싱callAgent(agentId, systemPrompt, message, cwd) — 개별 에이전트 spawncallAgentsParallel(tasks[], cwd) — 병렬 실행
8. 조직 구조
회장 (모바일)
└── Director (고정, 운영 총괄)
├── Architecture: System, Data, Cloud
├── Backend: API, Business Logic, Database
├── Frontend: Web, iOS, Android, Designer
├── Security: App, DB, Infra
├── QA: Functional, Performance
├── DevOps: CI/CD, Infrastructure
├── Research: Tech, Market
├── Marketing: Growth, Content
└── Finance: Accountant
- Director: 고정 (해고 불가). 회장 메시지 수신 → 분석 → DELEGATE → 종합 보고
- 에이전트: 회장이 모바일에서 고용/해고. 같은 직종 복수 고용 가능 (난제시 토론)
변경 이력
| 날짜 | 변경 |
|---|
| 2026-03-28 | 초기 문서 작성. 현재 옵션, 하네스 구조, 병렬 검증 결과, 역할 부여 방식 정리 |
| 2026-03-28 | PM→Director 교체, DELEGATE 태그 추가, 21개 프리셋, callAgent/callAgentsParallel 추가 |