andersonaguiar/haiflow
요약
Haiflow는 Claude Code의 기능을 HTTP 헤드리스 AI 에이전트로 자동화하는 도구입니다. 이를 통해 API 키 비용 없이도 코드 생성, 리팩토링 등 다양한 작업을 n8n이나 웹훅 같은 외부 자동화 도구를 이용해 실행할 수 있습니다. tmux 세션으로 Claude Code를 감싸 REST API를 노출하여 기존 구독만으로 강력한 워크플로우 구축이 가능합니다.
핵심 포인트
- Claude Code 기능을 HTTP로 자동화하여 에이전트 구현
- API 비용 없이도 코드 생성, 리팩토링 등 작업 수행 가능
- tmux 세션을 활용해 Claude Code에 REST API 노출
- n8n, 웹훅 등 외부 자동화 도구와 연동 용이
hooks · ai · flow
HTTP를 통해 헤드리스 AI 에이전트로 Claude Code 실행 — API 키 비용 없음, SDK 불필요, 기존 Claude Code 구독만 사용하면 됩니다.
Haiflow는 Claude Code를 tmux 세션으로 감싸고 REST API를 노출하여 프롬프트 트리거, 작업 큐잉, 응답 캡처가 가능하게 합니다. 코드 생성, 리팩토링, 버그 트리아지(bug triage), 일일 보고서 작성 등 Claude Code에서 할 수 있는 모든 것을 어떤 HTTP 클라이언트에서도 자동화할 수 있습니다.
Claude API를 사용하지 않는 이유? Claude Code는 도구 사용(tool use), 파일 접근, git 통합 및 사용자 정의 스킬을 기본적으로 포함하고 있습니다. Haiflow를 사용하면 토큰당 API 비용을 지불하지 않고도 이 모든 것을 HTTP를 통해 자동화할 수 있습니다. n8n, cron, 웹훅 또는 다른 자동화 도구를 사용하여 구동할 수 있습니다.
POST /trigger ───┐
│ ┌────────────────┐
┌───▼───┐ │ tmux session │
...
설정은 Pipeline을 참고하세요.
macOS와 Linux에서만 사용 가능합니다. Windows는 아직 지원되지 않습니다 (haiflow는 tmux 및 POSIX 셸 스크립트에 의존하기 때문입니다).
- Bun v1.2.3+
- tmux
- Claude Code CLI
- jq
- Redis — 선택 사항, 이벤트 지속성(event persistence) 및 전송 재시도(delivery retry)를 활성화합니다. 이것이 없으면 파이프라인 이벤트는 발생하지만 영속화되지 않습니다. 다음 명령어로 실행하세요:
docker run -d -p 6379:6379 redis
`curl -fsSL https://raw.githubusercontent.com/andersonaguiar/haiflow/main/install.sh | bash`
설치되지 않은 경우 Bun을 설치하고, `tmux`, `jq`, `claude`, `redis`의 존재 여부를 확인한 후, `haiflow` CLI를 전역적으로 설치하고 Claude Code 훅(hooks)을 연결합니다.
export HAIFLOW_API_KEY=your-secret
haiflow serve # 서버 실행
haiflow init /path/to/your/project # 다른 셸에서: 훅 연결, 세션 시작, 스모크 테스트 실행
`haiflow init`은 가장 빠르게 작동하는 환경을 구축할 수 있는 방법입니다. 훅을 설치하고, 세션을 시작하며, 스모크 테스트 프롬프트를 발생시키고, 훅이 제대로 연결되지 않은 경우(가장 흔한 무음 실패) 즉시 알려줍니다. 언제든지 상태를 확인하려면 `haiflow doctor` 또는 `GET /doctor`를 실행하세요.
수동으로 진행하는 것을 선호하나요? `haiflow start worker --cwd /path/to/your/project`를 사용하세요.
`HAIFLOW_SKIP_SETUP=1`로 훅 설정을 건너뛸 수 있습니다.
`HAIFLOW_INSTALL_METHOD=npm`으로 npm 레지스트리를 강제할 수 있습니다.
선호한다면 파이프하기 전에 스크립트를 검사할 수 있습니다: `curl -fsSL .../install.sh | less`
git clone https://github.com/andersonaguiar/haiflow.git
cd haiflow
bun install # Claude Code hooks도 자동으로 설치합니다
...
export HAIFLOW_API_KEY="your-secret-key"
Claude 세션 시작
curl -X POST http://localhost:3333/session/start
...
또는 CLI를 사용합니다:
bun run bin/haiflow.ts start worker --cwd /path/to/your/project
bun run bin/haiflow.ts trigger "explain this codebase" --session worker
bun run bin/haiflow.ts status worker
...
`bun install`
Haiflow는 Claude Code hooks를 사용하여 세션 상태를 추적합니다. 설정 명령어는 훅 설정을 `~/.claude/settings.json`에 병합합니다.
:
`bun run setup`
이 훅들은 가느다란 HTTP 포워더입니다. Claude Code 이벤트를 haiflow 서버로 POST합니다. 서버가 실행되고 있지 않으면 조용히 아무 작업도 하지 않습니다(no-op). 오케스트레이션되지 않은 Claude 세션에는 영향을 주지 않습니다(서버는 알 수 없는 세션 ID를 무시합니다).
`cp .env.example .env`
| 변수 | 기본값 | 설명 |
|---|---|---|
`PORT` | `3333` | HTTP 서버 포트 |
`HAIFLOW_ENV` | `development` | 배포 환경 (`development`/`production`; `NODE_ENV`로 폴백). `production`에서는 보안에 취약한 노출 시 부팅 시 실패하며 약하거나 플레이스홀더 키를 거부합니다. 개발(Dev)은 관대합니다 (터널 필요 없음). |
`HAIFLOW_HOST` | `127.0.0.1` | 바인드 주소. 기본적으로 루프백이므로 원본은 프론트 프록시/터널을 통해서만 도달할 수 있습니다—식별 계층(identity layer)이 포트를 직접 건드려 우회될 수 없습니다. 프로덕션에서 공개 바인드를 하려면 `HAIFLOW_ALLOW_PUBLIC_BIND=true`가 필요합니다. DEPLOYMENT.md를 참조하세요. |
`HAIFLOW_ALLOW_PUBLIC_BIND` | `false` | 프로덕션에서 공개 바인드(`0.0.0.0`/LAN/공개 IP)를 승인합니다—포트를 방화벽으로 보호하고 자체 식별 계층을 실행해야 합니다. 이것이 없으면 프로덕션은 공개적으로 바인딩될 때 시작을 거부합니다.
|
`HAIFLOW_DATA_DIR` |
`/tmp/haiflow` |
세션 상태, 큐 및 응답을 위한 디렉터리 |
`HAIFLOW_PORT` |
`3333` |
hook 스크립트가 사용하는 포트 (PORT와 다를 경우 설정) |
`HAIFLOW_API_KEY` |
— | 필수. 원하는 임의의 문자열 — 이것은 사용자 본인의 비밀이며, 유료 키가 아닙니다. `production` 환경에서는 24자 이상이어야 하며 플레이스홀더가 아니어야 합니다. |
`HAIFLOW_CWD` |
— | 설정할 경우 모든 세션이 이 cwd를 사용하도록 강제됩니다. `/session/start` 요청 본문의 `cwd` 필드는 무시됩니다 (다를 경우 경고가 기록됨). |
`HAIFLOW_ALLOW_REQUEST_CWD` |
`true` |
`false`로 설정하면 `/session/start`는 자체 `cwd`를 설정하려는 요청을 거부합니다 — 이 경우 서버에서 `HAIFLOW_CWD`가 설정되어야 합니다. |
`HAIFLOW_GUARDRAILS` |
`true` |
서버 부팅 시 `~/.claude/skills/haiflow-guardrails/SKILL.md`를 설치하고, 모든 새 tmux 세션에 `/haiflow-guardrails`를 주입합니다. 이 스킬은 Claude에게 cwd 외부 경로를 거부하고, 비밀 정보를 읽는 것을 거부하며, 네트워크 유출을 거부하도록 지시합니다. |
`REDIS_URL` |
`redis://localhost:6379` |
필수. 이벤트 지속성 및 전송 추적을 위한 Redis URL |
`HAIFLOW_START_READY_TIMEOUT_MS` |
`15000` |
`/session/start`가 SessionStart hook이 Claude 세션 ID를 연결하기 위해 기다리는 시간 (밀리초). 실패할 때까지의 시간입니다. (세션이 절대 연결되지 않으면 모든 응답을 조용히 누락하게 되며 — 보통 hooks가 제대로 구성되지 않았음을 의미합니다) |
`HAIFLOW_ALLOW_TRIGGER_CALLBACK` |
`false` |
개별 `/trigger` `callbackUrl` 완료 웹훅을 활성화합니다. 기본적으로 비활성화되어 있는데, 임의의 콜백 URL은 SSRF(Server-Side Request Forgery) 취약점이 될 수 있기 때문입니다. |
`HAIFLOW_CALLBACK_ALLOW_HOSTS` |
— | `callbackUrl`에 대한 선택적 쉼표 구분 호스트 허용 목록. 이것을 설정하면 다른 모든 호스트로의 콜백은 `400`으로 거부됩니다. |
`N8N_API_KEY` |
— | 워크플로우 통합을 위한 n8n API 키 |
`HAIFLOW_USAGE_ALERT_TOKENS` |
— | 설정할 경우, 롤링(rolling) 5시간 동안의 토큰 총량이 이 값을 초과하면 `GET /usage/window`가 `alert: true`를 플래그합니다 (경고 전용이며, 절대 제한하지는 않습니다). |
`HAIFLOW_TASK_TIMEOUT_SEC` |
`0` |
선택적 하드(hard) 작업별 시간 초과. `0`은 이를 비활성화합니다.
워치독은 시간 초과된 태스크를 플래그합니다 |
`HAIFLOW_WAITING_GRACE_SEC` |
`120` |
Claude의 Notification hook에 의해 `waiting`으로 플래그된 세션이 워치독이 작동하기 전에 얼마나 오래 차단 상태로 머무를 수 있는지|
`HAIFLOW_WATCHDOG_RECOVER` |
`false` |
`true`일 경우, 워치독은 멈춘(wedged) 세션을 자동으로 복구합니다 (Escape, `timed_out` 표시, drain). 기본값은 경고만 발생시킵니다 |
`HAIFLOW_MAP_MAX_ITEMS` |
`200` |
하나의 `POST /map` 호출이 풀(pool)에 걸쳐 분산할 수 있는 최대 항목 수|
`HAIFLOW_MAP_TIMEOUT_SEC` |
`1800` |
맵 실행이 리듀서가 부분 결과와 함께 작동하기를 기다리는 시간입니다 (stragglers).
🔒 전체 위협 모델(threat model), 신뢰 경계(trust boundaries), 심층 방어 계층(defense-in-depth layers) 및 강화 체크리스트(hardening checklist)는 SECURITY.md를 참조하세요.
`HAIFLOW_API_KEY`
필수입니다 — 원하는 아무 문자열이나 선택할 수 있습니다 (예: `openssl rand -hex 32`). 이는 제3자 키나 유료 자격 증명이 아니며, 서버를 보호하기 위해 정의하는 비밀 값일 뿐입니다.
**이것이 중요한 이유:** 인증(auth) 없이는, 서버에 접근할 수 있는 누구나 파일 및 git 액세스 권한을 가지고 실행되는 Claude Code에 임의의 프롬프트를 보낼 수 있습니다. 이는 소스 코드를 읽거나, 파일을 수정하거나, 쉘 명령을 실행하거나, 데이터를 유출하는 것을 의미하며 — 모두 간단한 HTTP 요청을 통해 가능합니다.
에이전트가 디버깅 중 읽은 비밀 값을 출력할 때의 심층 방어(defence-in-depth)로서, haiflow는 모든 아웃바운드 텍스트(응답, 파이프라인 메시지, 웹훅, 채팅 회신)가 외부로 나가기 전에 최선의 노력으로 검열(redaction) 과정을 거칩니다. 이는 알려진 자격 증명 형태(AWS/GitHub/Stripe/Google/Anthropic/OpenAI 키, JWT, Bearer 토큰, 개인 키 블록 등)를 제거하고 각각을 `[REDACTED:type]`로 대체하며 카운트를 기록합니다. 기본적으로 활성화되어 있습니다 (비활성화하려면 `HAIFLOW_REDACT=false`); 이메일은 선택 사항입니다 (`HAIFLOW_REDACT_EMAILS=true`); 자체 패턴을 추가하려면 `HAIFLOW_REDACT_EXTRA`를 사용하세요. 이것은 방화벽(firewall)이 아닌 최선의 노력 DLP(Data Loss Prevention)이며: 인코딩되거나 재구성된 비밀 값은 포착하지 못하며, 에이전트가 작업 디렉토리 내부에 작성하는 파일은 절대 수정하지 않고 오직 아웃바운드 텍스트만 다시 작성합니다.
서버는 이것 없이는 시작을 거부합니다. 모든 API 엔드포인트( `/health` 및 `/hooks/*` 제외)는 `Authorization` 헤더를 필요로 합니다:
`curl -H "Authorization: Bearer your-secret-key" http://localhost:3333/sessions`
Hooks는 로컬에서 실행되는 Claude Code에서 오기 때문에 인증 대상에서 제외됩니다. `/hooks/*`로의 요청은 localhost로 제한됩니다.
haiflow를 원격으로 액세스해야 하는 경우(n8n cloud, 웹훅 등), Cloudflare Zero Trust Access 설정 가이드는 DEPLOYMENT.md를 참조하십시오. 이는 신원 계층을 추가하여 API 키가 도난당하더라도 충분하지 않게 만듭니다.
전체 개발자 문서는 `docs/`에 있으며, 빠른 시작(quickstart), 모든 엔드포인트( `docs/openapi.json`에서 생성된 상호 작용 가능한 플레이그라운드 포함), MCP 서버, n8n 노드, 파이프라인, 워커 풀, 배포 및 보안을 다루는 검색 가능한 Mintlify 사이트입니다. 로컬에서 미리보기를 하려면 다음 명령어를 사용하십시오:
`cd docs && npx mint dev # http://localhost:3000`
전체 API 레퍼런스는 API.md를 참조하십시오: 모든 엔드포인트, 매개변수 및 예시가 포함됩니다. 동일한 내용은 문서 사이트에서도 상호 작용 가능한 레퍼런스로 게시됩니다.
haiflow는 실시간으로 세션을 모니터링하고 제어하기 위한 내장 웹 대시보드를 포함합니다.
Enter HAIFLOW_API_KEY를 입력하여 인증한 후, 두 개의 패널 레이아웃을 얻게 됩니다:
왼쪽 패널 — 실시간 상태 배지(idle/busy/offline)가 있는 모든 세션. 오프라인 세션은 ×로 제거할 수 있습니다.
오른쪽 패널 — 현재 프롬프트 (작업 중일 때). 확장 가능한 항목을 포함하는 탭 기반의 Queue/Responses/History 보기에는 전체 프롬프트 및 응답 텍스트가 표시됩니다.
History 탭 — 모든 작업의 도구/명령어/diff 타임라인, 토큰 사용량, 지속 시간 및 "절약된 API 비용"이 포함되며, 지난 5시간/7일 사용 창도 볼 수 있습니다(Task history & savings 참조).
Live terminal — 기본적으로 읽기 전용입니다. Take control을 클릭하여 쓰기가 가능한 attach로 전환하고 브라우저에서 고정된 세션에 직접 입력할 수 있습니다 (API 키에 의해 제한되며, HAIFLOW_ALLOW_TAKEOVER=false로 비활성화할 수 있습니다.)
)). 사용자가 직접 제어할 때(wheel을 잡고 있을 때)는 자동 드레인 기능이 일시 중지되어 큐에 있는 내용이 입력 내용을 덮어쓰지 않습니다.액션(Actions) — 세션 시작/중지, 프롬프트 전송, 큐/응답 지우기
대시보드는 3초마다 자동 새로고침됩니다. 추가적인 설정은 필요하지 않으며, 동일한 Bun 서버를 통해 제공됩니다.
모든 작업은 영구적인 SQLite 원장(ledger)(haiflow.db in HAIFLOW_DATA_DIR)에 기록됩니다. 완료되면 haiflow는 Stop 훅을 위해 파싱된 Claude Code 트랜스크립트와 동일한 내용을 마이닝하여, 해당 작업이 실제로 수행한 내용—순서가 지정된 도구 호출(tool calls), 실행된 명령어(commands run), 변경된 파일(files changed), 실제 차이점(real diffs), 토큰 사용량(token usage), 모델(model), 그리고 타이밍(timing)—을 저장합니다. GET /tasks, GET /tasks/:id, 및 GET /responses/:id/timeline를 통해 쿼리하거나, 대시보드의 History 탭에서 탐색할 수 있습니다.
haiflow는 평평한 Claude Code 구독 기반으로 실행되므로, 작업당 토큰 비용이 들지 않습니다. GET /usage와 GET /usage/window는 이동하는 5시간 및 7일 창(구독 비율 제한 창) 동안 측정된 토큰 소비량과, 토큰당 호출자가 지불했을 것과 동일한 API 비용—즉, 이 도구가 제공하기 위해 존재하는 절감액—을 보고합니다. 달러 금액은 청구서가 아닌 유지 관리되는 가격표를 기반으로 한 추정치입니다. HAIFLOW_USAGE_ALERT_TOKENS를 설정하여 5시간 창이 임계값을 초과할 때만 알림 플래그를 받도록 할 수 있습니다(작업을 제한하지는 않습니다).
내구성 참고: 원장은 HAIFLOW_DATA_DIR에 존재하며, 기본값은 /tmp/haiflow이고 재부팅 시 지워집니다. 기록을 재시작 간에도 유지하려면 영구적인 디렉터리를 가리키도록 설정하세요.
Haiflow는 모든 주요 이벤트에 대해 구조화된 JSON 로그를 stdout/stderr로 출력합니다:
{"ts":"2026-03-18T02:35:00Z","level":"info","event":"server_started","port":3333,"auth":true}
{"ts":"2026-03-18T02:35:01Z","level":"info","event":"session_started","session":"worker","cwd":"/app"}
{"ts":"2026-03-18T02:35:02Z","level":"info","event":"trigger_sent","session":"worker","taskId":"task-001"}
...
이벤트: server_started, sessions_recovered, stale_prompts_swept, sessions_pruned, session_started, session_start_cwd_defaulted
, 세션 중지 (session_stopped)
, 세션 시작 실패 (session_start_failed)
, 트리거 전송 (trigger_sent)
, 트리거 대기열에 추가됨 (trigger_queued)
, 트리거 중복 제거됨 (trigger_deduped)
, 트리거 실패 (trigger_failed)
, 대기열 비움 (queue_drained)
, 대기열 정리됨 (queue_cleared)
, 대기열 항목 제거됨 (queue_item_removed)
, 대기열 항목 재우선순위 지정됨 (queue_item_reprioritized)
, 작업 취소됨 (task_cancelled)
, 응답 저장됨 (response_saved)
, 스트림 열림 (stream_opened)
, 훅 세션 시작 (hook_session_start)
, 훅 중지 (hook_stop)
, 훅 세션 종료 (hook_session_end)
, 훅 알림 (hook_notification)
, 인터럽트 전송 (interrupt_sent)
, 워치독 트리거됨 (watchdog_triggered)
, 워치독 복구됨 (watchdog_recovered)
, 인증 거부됨 (auth_rejected)
, Redis 연결됨 (redis_connected)
, Redis 연결 끊김 (redis_disconnected)
, Redis 사용 불가 (redis_unavailable)
, 이벤트 발행됨 (event_published)
, 직접 이벤트 발행됨 (event_published_direct)
, 파이프라인 전송됨 (pipeline_dispatched)
, 파이프라인 대기열에 추가됨 (pipeline_queued)
, 파이프라인 순환 건너뜀 (pipeline_circular_skipped)
, 파이프라인 프롬프트 너무 큼 (pipeline_prompt_too_large)
, 파이프라인 웹훅 전송됨 (pipeline_webhook_sent)
, 파이프라인 웹훅 실패 (pipeline_webhook_failed)
, 알 수 없는 토픽 발행 (publish_unknown_topic)
, 권한 없음으로 발행 (publish_unauthorized)
, 풀 전송됨 (pool_dispatched)
, 맵 시작됨 (map_started)
, 맵 진행률 (map_progress)
, 맵 축소됨 (map_reduced)
, 부분 맵 축소됨 (map_reduced_partial)
, 수집 트리거됨 (ingest_triggered
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub Claude Ecosystem의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기