CLI Harness — Claude CLI 제어 명세

Node.js 서버가 Claude CLI를 spawn으로 제어하는 하네스 구조 문서. 에이전트 역할 부여, 옵션 변경, 문제 발생 시 이 문서를 참조한다.

1. 현재 사용 중인 CLI 옵션

#옵션용도비고
1-pprint mode — 비대화형, 한 번 응답 후 종료필수. 서버가 프로세스 수명 관리
2--dangerously-skip-permissions모든 도구 권한 자동 승인 (y/n 프롬프트 스킵)추후 모바일 권한 UI로 대체 예정
3--model <model>사용할 모델 지정기본값: sonnet (env LLM_MODEL)
4--output-format stream-jsonstdout을 JSON 이벤트 스트림으로 출력활동 로그 + 최종 결과 파싱용
5--verbose상세 로그 출력디버깅용
6-ccontinue — 이전 대화 이어서두 번째 메시지부터 자동 추가
7--append-system-prompt <text>시스템 프롬프트에 HARD_RULES 추가프로젝트 규칙 강제
8--session-id <uuid>세션 격리병렬 에이전트 시 필수 (에이전트별 UUID)
9message (마지막 인자)사용자/오케스트레이터가 보낸 메시지

아직 미사용이지만 활용 가능한 옵션

옵션용도활용 시나리오
--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-jsonstdin 스트리밍 입력실시간 양방향 통신 (권한 UI 등)
--allowedTools + 권한 제거세밀한 도구 제어--dangerously-skip-permissions 없이 특정 도구만 허용

2. Node.js 하네스 구조

#기능용도
1spawn(provider, args, { cwd, stdio })Claude CLI를 자식 프로세스로 실행
2stdio: ['pipe', 'pipe', 'pipe']stdin/stdout/stderr 모두 파이프. stdin은 권한 UI 연동 시 사용 예정
3proc.stdout 파싱stream-json 이벤트에서 활동 로그 + 최종 결과 추출
4proc.stderr에러 로그 출력 (no stdin data 경고 무시)
5channelStarted Set채널별 첫 호출 여부 추적 → -c 플래그 결정
6sendActivityLog()활동 로그를 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비고
DirectorRead, Grep, Glob, WebSearch, WebFetch코딩 금지, DELEGATE 강제
System/Data/Cloud ArchitectRead, Grep, Glob, Write, Edit, WebSearch설계 문서만
App/DB/Infra SecurityRead, Grep, Glob, Bash, WebSearch감사+스캔만, 패치는 Developer에 위임
API/BizLogic/DB Developer전체 허용코딩 전담
Web/iOS/Android Developer전체 허용코딩 전담
UI/UX Designer전체 허용디자인+코딩
Functional/Performance TesterRead, Grep, Glob, Bash테스트 실행만
CI/CD/Infra EngineerRead, Grep, Glob, Bash, Edit, Write인프라 코드만
Tech/Market ResearcherRead, Grep, Glob, WebSearch, WebFetch조사만
Growth/Content MarketerRead, Grep, Glob, WebSearch, WebFetch분석만
AccountantRead, 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.tsClaude CLI spawn + stdout 파싱 + 활동 로그
server/src/orchestrator/supabase.tsSupabase 연결 + Realtime + 폴링 fallback
server/src/index.ts메시지 라우팅 + 에이전트 Roster 출력
server/src/types/index.tsMessage 인터페이스
supabase/migrations/004_seed.sql에이전트 시드 데이터

7. DELEGATE (병렬 위임)

Director가 에이전트에게 작업을 위임할 때 사용하는 태그:

[DELEGATE]
api_dev_1: 로그인 API 엔드포인트 구현
ios_dev_1: iOS 로그인 화면 구현
db_security_1: 인증 관련 RLS 정책 검토
[/DELEGATE]

서버 처리 흐름:

  1. Director 응답에서 [DELEGATE]...[/DELEGATE] 블록 파싱
  2. DB에서 해당 에이전트 존재 확인 + system_prompt 로드
  3. callAgentsParallel() — 모든 에이전트 동시 spawn
  4. 결과 수집 → Director에게 전달 → 종합 보고

관련 함수:

  • parseDelegates(content) — DELEGATE 블록 파싱
  • callAgent(agentId, systemPrompt, message, cwd) — 개별 에이전트 spawn
  • callAgentsParallel(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-28PM→Director 교체, DELEGATE 태그 추가, 21개 프리셋, callAgent/callAgentsParallel 추가