TRENDSHIFT #25 · 2026.05.24 · KUNCHENGUID

gnhf — 자기 전에 에이전트한테 "잘 자, 재밌게 놀아"라고 말하는 야간 오케스트레이터

노트북 덮고 자는 동안 Claude Code·Codex·Copilot·Pi 같은 코딩 에이전트를 한 번에 한 step씩 커밋·롤백·재시도하며 굴려놓고, 아침에 깨끗한 git 브랜치 + 실행 로그로 받는 TypeScript CLI. 1.8k stars / MIT / Node 20+ / 2026-03-31 생성, 2개월 만에 trending #25 진입.

1,810
GITHUB STARS
125
FORKS
7
지원 에이전트 (Claude·Codex·Copilot·Pi·Rovo·OpenCode·ACP)
v0.1.42
현재 npm 버전 (2개월 42 릴리스)

1한줄 요약

정확히 무엇을 하는 도구인가

gnhf는 — 이름 그대로 Good Night, Have Fun — 사용자가 자거나 자리를 비운 사이에 코딩 에이전트를 한 번에 한 step씩 무한 루프로 돌리는 오케스트레이터다. 각 iteration은 "작은 변화 → git commit → 다음 iteration"이라는 원자적 사이클을 갖고, 실패하면 git reset --hard로 롤백한다. 아침에 일어나면 brand-new gnhf/<slug> 브랜치에 깨끗한 commit 더미와 무엇이 일어났는지 적은 로그가 기다리고 있다.

한 줄 비유

밤새 돌리는 RPA + 매 step마다 git commit 찍는 자동 빵공장

제빵사가 자는 사이에 반죽기가 한 번 돌면 빵 한 덩이가 나오고, 잘 구워졌으면 트레이에 올리고(commit), 타거나 모양이 망가졌으면 버린다(reset). 다음 반죽은 이전 트레이에 뭐가 있는지 보고 다시 시작한다.

아침에 일어나면 트레이 위에 빵 10개가 있고, 각각 어떤 레시피로 어떻게 구워졌는지가 적혀 있는 식이다. 빵공장 = gnhf, 반죽기 = Claude/Codex CLI, 트레이 = git 브랜치, 레시피 노트 = notes.md.

2왜 주목받는가

2026년 봄, AI 코딩 에이전트 생태계에서 차지한 자리

2026년 들어 Claude Code·Codex·Copilot CLI 같은 비대화식(non-interactive) 코딩 에이전트가 흔해지면서, "밤새 알아서 굴려놓고 아침에 결과만 본다"는 패턴이 본격적으로 떠올랐다. 이를 가능하게 한 두 가지 선행 작업이 있다:

gnhf는 이 두 흐름을 가져와서 production-grade UX로 다듬은 결과물이다.

경쟁 대비 강점

관점ralph / 단순 while loopgnhf
커밋 단위전체 task 끝나야 1 commititeration마다 atomic commit → cherry-pick·revert 자유
실패 처리실패 시 그냥 멈춤3종 분류: 일시적 → 백오프, 영구 → abort, commit 실패 → 다음 step에 "복구해줘" 위임
병렬 실행지원 X--worktree로 동일 repo에서 여러 에이전트 동시 실행
에이전트 락인특정 CLI 종속7개 native + ACP 프로토콜 → 에이전트 무관
중단/재개처음부터 다시gnhf/<branch> 위에서 다시 실행 → history 이어받기
슬립 방지OS에 맡김macOS caffeinate / Linux systemd-inhibit / Win PowerShell 내장
왜 지금 #25에 진입했나

2026년 5월 X(트위터)에서 "밤새 에이전트 돌려놓고 아침에 PR 리뷰" 워크플로가 핫토픽이 되었고, gnhf는 그 워크플로에 가장 적합한 도구 중 하나로 빠르게 입소문을 탔다. 특히 "complete no-op iteration도 실패로 간주" 같은 디테일 — 즉 에이전트가 사실상 아무것도 안 하고 "끝났다"고 거짓말하는 경우까지 잡아내는 — 이 신뢰성을 만들어낸다.

3기술 스택 전체 지도

단순한 TypeScript CLI지만, 굉장히 신중하게 골라진 도구들

코어 런타임

레이어도구역할 / 선택 이유
언어TypeScript 5.8+type-safe + Node 20+ ESM 네이티브
런타임Node.js ≥20ESM·Fetch·AbortController 등 표준 API 안정화 버전
패키지 매니저pnpm 11monorepo·workspaces·deterministic install
빌드tsdown 0.21esbuild 기반 초고속 ts→mjs 번들러 (단일 dist/cli.mjs 산출)
CLI 파서commander 14오랜 검증을 거친 사실상 표준
설정 파서js-yaml 4~/.gnhf/config.yml 읽고 쓰기

테스트·품질

도구역할
vitest 4.1유닛 테스트 + e2e 테스트 + v8 커버리지
acp-mock / acpx 0.6ACP 프로토콜 mocking으로 외부 에이전트 없이 테스트
ESLint 9 + typescript-eslint 8 + prettier 3코드 스타일 + 정적 분석
release-pleaseConventional Commits → 자동 changelog + npm publish

외부 의존성 (지원 에이전트)

gnhf는 에이전트 자체를 번들하지 않는다 — 사용자가 별도로 설치한 CLI를 spawn해서 호출하는 구조. 따라서 의존성은 매우 가볍다(commanderjs-yaml 단 2개).

에이전트플래그호출 방식
Claude Code--agent claudeclaude 비대화식 모드 직접 spawn
OpenAI Codex--agent codexcodex exec 비대화식
GitHub Copilot CLI--agent copilot비대화식 JSONL 모드
Pi CLI--agent piJSON 모드 + --no-session
Rovo Dev--agent rovodev로컬에서 acli rovodev serve 자동 기동
OpenCode--agent opencode로컬 opencode serve 자동 기동 + 세션 생성
ACP target--agent acp:<name>번들된 acpx를 통해 어떤 ACP 호환 에이전트도 가능
용어 풀이
ACP (Agent Client Protocol)
에이전트와 클라이언트가 stdin/stdout으로 JSON 메시지를 주고받는 표준. 한 번 표준에 맞춰두면 Claude, Gemini, 자체 fork 등 어떤 백엔드든 같은 인터페이스로 쓸 수 있다. gnhf는 acpx(openclaw가 만든 ACP 멀티플렉서)를 내장해 acp:gemini 같은 짧은 이름으로 부른다.

4아키텍처 심화 분석

한 iteration이 어떻게 흘러가는가

핵심 사이클 (README 다이어그램을 한글로 재구성)

┌──────────────┐ │ gnhf start │ └──────┬───────┘ ▼ ┌─────────────────────┐ │ git 작업 트리 청결 검증 │ │ gnhf/<slug> 브랜치 생성 │ │ prompt.md / notes.md 기록 │ └──────────┬──────────┘ ▼ ┌───────────────────────────┐ │ iteration prompt 조립 │◄────────┐ │ (notes.md 컨텍스트 주입) │ │ └────────────┬──────────────┘ │ ▼ │ ┌───────────────────────────┐ │ │ 실제 에이전트 spawn │ │ │ (claude / codex / copilot ...) │ │ └────────────┬──────────────┘ │ ▼ │ ┌──────────────┐ │ │ 결과 success? │ │ └──┬──────┬────┘ │ yes │ │ no │ ▼ ▼ │ ┌──────────┐ ┌────────────┐ │ │ git │ │ git reset │ │ │ commit │ │ 또는 commit │ │ │ +notes.md│ │ 실패 보존 │ │ └────┬─────┘ └──────┬─────┘ │ │ │ │ │ ┌───────────┘ │ ▼ ▼ │ ┌─────────────┐ yes ┌────────────┐ │ │ 연속 3회 실패 ├──────►│ abort │ │ │ or 영구 오류 │ └─────▲──────┘ │ └────┬────────┘ │ │ no│ │ │ └───────────────────────┴───────────┘

설계 패턴 3가지

PATTERN 1

"Atomic commit 단위" — 모든 iteration이 분리 가능한 변경

전통적 LLM 스크립트는 task가 끝나야 결과를 받는다. gnhf는 각 iteration 자체가 하나의 git commit이다. 그 결과:

PATTERN 2

"Failure trichotomy" — 실패를 3가지로 분류

모든 에러를 같이 처리하면 안 된다. gnhf는 신중하게 나눈다:

유형예시대응
일시적 (retryable)네트워크 끊김, rate-limit지수 백오프로 재시도
영구 (permanent)Claude 크레딧 잔액 0, 인증 만료즉시 abort + 로그 경로 출력
commit 실패pre-commit hook 실패다음 iteration에 "복구해줘" 위임 + 작업 트리 보존
no-op에이전트가 변경 0건 + "성공" 보고실패로 카운트 (3연속이면 abort)

이 디테일이 "사실은 못하는 일을 끝났다고 보고하는" LLM 특유의 거짓말을 막아준다.

PATTERN 3

"notes.md 영속 메모리" — iteration 간 컨텍스트 전달

각 iteration은 새로운 LLM 호출이라 컨텍스트가 리셋된다. gnhf는 .gnhf/runs/<runId>/notes.md에 매 iteration의 요약을 append하고, 다음 prompt 조립 시 이 파일을 주입한다. 결과적으로 에이전트는 "방금 직전에 내가 무엇을 시도했고 무엇이 실패했는가"를 기억한 채 다음 step에 진입한다.

비유

건망증이 심한 청소부 10명이 1시간씩 교대로 같은 집을 청소하는데, 각자 들어올 때 전임자의 메모를 읽고 들어가는 것과 같다. "거실은 끝, 부엌 싱크대 막힌 거 빼고는 다 했음" 같은 메모가 있으면 다음 사람은 부엌 싱크대만 집중하면 된다.

5디렉토리 구조 해부

~5MB짜리 작은 레포지만 모든 책임이 명확하게 분리됨

gnhf/ ├── src/ │ ├── cli.ts ← commander로 플래그 파싱, 진입점 │ ├── core/ ← 비즈니스 로직 (UI와 분리) │ │ ├── orchestrator.ts ★ 메인 루프: iteration → commit/reset → 반복 │ │ ├── run.ts ← 한 run의 lifecycle 관리 │ │ ├── git.ts ← worktree·branch·commit·reset 추상화 │ │ ├── config.ts ← ~/.gnhf/config.yml 로드·검증 │ │ ├── commit-message.ts ← 기본 vs Conventional 프리셋 │ │ ├── exit-summary.ts ← 종료 시 영구 stdout 요약 │ │ ├── interrupt-state.ts ← Ctrl+C / SIGTERM 우아한 처리 │ │ ├── sleep.ts ← OS별 슬립 방지 (caffeinate / systemd-inhibit) │ │ ├── debug-log.ts ← .gnhf/runs/<id>/gnhf.log JSONL 출력 │ │ ├── telemetry.ts ← 익명 사용 통계 (GNHF_TELEMETRY=0으로 끔) │ │ └── stdin.ts ← echo "prompt" | gnhf 파이프 입력 │ ├── renderer.ts ← 대화식 TUI 렌더링 (live status bar) │ ├── renderer-diff.ts ← 매 프레임 diff만 그려 깜박임 방지 │ ├── mock-orchestrator.ts ← 테스트 더블 (에이전트 없이 시나리오 검증) │ ├── templates/ ← prompt 합성 템플릿 │ └── utils/ ← 작은 헬퍼들 ├── skills/gnhf/SKILL.md ← Anthropic Agent Skills 호환 스킬 │ "Hands-Off vs Companion 두 모드 사용법" ├── e2e/ ← end-to-end 테스트 ├── docs/ ← splash 이미지 등 문서 자산 ├── .airlock/ ← Atlassian no-mistakes 워크플로 검증 ├── package.json ← npm 메타 (bin: gnhf, dependencies 2개) ├── tsdown.config.ts ← esbuild 기반 번들러 설정 └── eslint.config.js ← Flat config 형식

주목할 만한 디렉토리 3가지

🅐 src/core/orchestrator.ts

이 파일이 사실상 gnhf의 심장이다. git ↔ 에이전트 ↔ notes.md ↔ TUI ↔ 종료 조건을 모두 조율한다. 단일 함수 안에 다 박지 않고 의존성 주입으로 git/agent/clock을 받아 mock-orchestrator.ts에서 테스트할 수 있게 분리한 것이 깔끔하다.

🅑 skills/gnhf/SKILL.md

gnhf는 자기 자신을 Anthropic의 Agent Skill로도 배포한다. 즉 Claude Code 같은 host 에이전트가 "내가 자고 일어나야 하는데 어떻게 gnhf를 쓰지?"를 학습할 수 있게 메타 가이드를 제공한다. Hands-Off 모드(완전 위임)와 Companion 모드(중간 점검) 두 가지 사용 패턴을 정의한다.

🅒 .gnhf/runs/<runId>/

실행 산출물 — prompt.md(원본 prompt), notes.md(누적 메모), gnhf.log(JSONL lifecycle 로그), iteration-<n>.jsonl(에이전트 스트리밍 출력). 모두 .gitignore 처리되어 깨끗한 branch만 남는다.

6학습 포인트 (기술별)

이 레포를 깊게 읽으면 배울 수 있는 것들

1) Node CLI 설계 패턴

2) Git 자동화 베스트 프랙티스

3) 신뢰성 엔지니어링 (SRE 사고방식)

4) Process Spawning · IPC

실습 아이디어

"내가 만든 LLM CLI"를 gnhf의 7번째 에이전트로 추가해보자. src/core/orchestrator.ts에서 에이전트 spawn하는 부분을 찾아 똑같이 추가하고, "성공 시 JSON 반환" 약속만 지키면 끝. 이 과정에서 모든 에이전트가 따르는 공통 인터페이스가 무엇인지 자연스럽게 학습된다.

7시스템 요구사항

바닥이 낮아 누구나 시도 가능

항목요구사항
OSmacOS / Linux / Windows 모두 지원
Node.js≥20 (ESM·Fetch·AbortController 안정 버전)
git≥2.20 정도 (worktree 정상 동작 버전)
패키지 매니저npm 또는 (소스 빌드 시) pnpm 11 + corepack
에이전트 CLI최소 1개: claude / codex / copilot / pi / rovodev / opencode 중 하나, 사전 로그인 필요
비용gnhf 자체는 무료, 에이전트 호출 비용은 사용자 부담 (밤새 돌리면 토큰 비용 폭증 가능)
네트워크에이전트 API 호출용. GNHF_TELEMETRY=0으로 텔레메트리 차단 가능
주의
토큰 비용 폭증 위험

아무 가드 없이 밤새 Claude Sonnet 돌리면 아침에 십수만~수십만 원 청구가 가능하다. 반드시 --max-iterations·--max-tokens·--stop-when 중 하나는 걸어둘 것. gnhf는 --max-tokens 도달 시 iteration 중간에도 abort한다.

8직접 해볼 수 있는 실습 과제

난이도별 4개

난이도 ★☆☆☆

Lv.1 — 가장 단순한 첫 실행

아무 git repo에 들어가서 깨끗한 작업 트리 상태에서 다음을 실행:

npm install -g gnhf cd ~/my-project gnhf --agent claude --max-iterations 3 \ "README.md의 오타와 어색한 문장을 고쳐줘"

3 iteration이 끝나면 git log gnhf/<slug>로 어떤 commit이 생겼는지 본다. 목표: gnhf가 iteration마다 commit을 어떻게 쪼개는지 체감.

난이도 ★★☆☆

Lv.2 — --stop-when으로 자연어 종료 조건

유닛 테스트가 있는 작은 프로젝트에서:

gnhf --agent codex \ --max-iterations 20 \ --stop-when "pnpm test 가 0개 실패로 끝난다" \ "src/utils 모듈의 테스트 커버리지를 100%로 올려줘"

목표: gnhf가 매 iteration 에이전트의 출력을 보고 "조건 만족" 여부를 어떻게 판정하는지 notes.md로 확인.

난이도 ★★★☆

Lv.3 — --worktree로 병렬 3 에이전트

같은 repo에 3 작업을 동시에 굴린다:

gnhf --worktree --agent claude "기능 A 구현" & gnhf --worktree --agent codex "기능 B 구현" & gnhf --worktree --agent copilot "테스트 추가" & wait

목표: <repo>-gnhf-worktrees/ 디렉토리에 각자 격리된 작업 환경이 생기는 걸 확인하고, 어떤 worktree를 merge할지 선택하는 경험.

난이도 ★★★★

Lv.4 — gnhf 소스 읽고 8번째 에이전트 추가

src/core/orchestrator.ts에서 --agent 분기 처리 부분을 찾아, 자체 ACP 호환 에이전트(또는 자체 CLI wrapper)를 추가한다. 테스트는 e2e/ 디렉토리의 mock 패턴을 따라 작성.

목표: 실제 OSS에 컨트리뷰션할 수 있을 정도로 코드베이스 친숙해지기. + PR 보너스 가능.

9관련 기술 심화 학습 로드맵

gnhf 한 레포가 아니라, 그 주변 생태계를 4주에 걸쳐

주차주제구체 액션
Week 1야간 에이전트 패턴의 기원karpathy/autoresearch 레포 읽기 + ghuntley의 "ralph" 블로그 포스트 읽기. "왜 한 prompt를 무한 루프로 돌리면 잘 되는가?"의 직관 잡기.
Week 2Agent Skills 표준anthropics/skills 레포의 SKILL.md 표준 학습 후, gnhf의 skills/gnhf/SKILL.md를 다시 읽기. Hands-Off / Companion 모드 구분을 본인 도구에 적용해보기.
Week 3ACP & Multi-agentopenclaw/acpx 레포 읽기 + ACP 사양 (Agent Client Protocol) 훑기. gnhf가 어떻게 7종 에이전트를 추상화하는지 본인 코드에 옮기기.
Week 4OSS Release 자동화release-please + Conventional Commits로 자기 npm 패키지에 자동 changelog/release 설정해보기 — gnhf가 2개월에 42릴리스를 낼 수 있는 이유.

10핵심 키워드 사전

처음 보는 용어 정리

TERM 01
orchestrator (오케스트레이터)
여러 실행 단위를 정해진 규칙으로 묶어서 순서대로 또는 병렬로 굴리는 도구. 음악의 지휘자처럼. gnhf는 "코딩 에이전트 한 마리"를 orchestrating한다.
TERM 02
atomic commit
하나의 git commit이 의미적으로 완결된 한 가지 변경만 담고 있어, 단독으로 revert/cherry-pick 가능한 상태. gnhf의 모든 iteration이 이런 단위로 떨어진다.
TERM 03
git worktree
하나의 git repo에 대해 여러 개의 작업 디렉토리를 동시에 가질 수 있게 하는 기능. git worktree add ../foo my-branch. gnhf는 이걸로 한 repo에 여러 에이전트를 격리해서 동시에 돌린다.
TERM 04
exponential backoff (지수 백오프)
재시도 사이 대기 시간을 1s → 2s → 4s → 8s ... 지수적으로 늘리는 패턴. 일시적 오류가 자기 회복할 시간을 주면서도 과부하를 피한다.
TERM 05
non-interactive mode
키보드 입력을 받지 않고 prompt를 인자로 받아 결과를 stdout으로 뱉고 종료하는 CLI 모드. claude의 --print, codex의 exec 같은 플래그가 활성화한다. 자동화에 필수.
TERM 06
ACP (Agent Client Protocol)
에이전트 ↔ 클라이언트가 stdin/stdout JSON 메시지로 대화하는 표준. ANP·MCP와 비슷하지만 별개. acpx가 reference 멀티플렉서.
TERM 07
caffeinate / systemd-inhibit
각각 macOS / Linux의 "이 프로세스가 도는 동안 시스템 슬립 막아줘"를 OS에 요청하는 도구. Windows에서는 SetThreadExecutionState API를 PowerShell로 호출.
TERM 08
no-op iteration
에이전트가 파일을 하나도 안 바꾸고 "끝났다"고 보고하는 케이스. LLM이 사실상 게으름 피우는 시그널. gnhf는 이걸 실패로 카운트한다.
TERM 09
Conventional Commits
feat:, fix:, chore: 같은 prefix로 commit 메시지의 의미를 약속하는 표준. release-please 같은 도구가 이걸 보고 자동 changelog를 만든다.
TERM 10
Agent Skill (SKILL.md)
Anthropic이 정의한 "에이전트가 특정 도구·도메인을 다루는 법을 학습하는 가이드 문서" 표준. YAML frontmatter(name·description) + Markdown 본문. gnhf 자체도 skills/gnhf/SKILL.md를 통해 자기 자신 사용법을 가르친다.

11참고 링크

5분 미니 실습

지금 바로 — 가벼운 prompt로 gnhf 1회 돌려보기

  1. npm install -g gnhf — Node 20+ 환경에서 글로벌 설치 (10초)
  2. 아무 git repo로 이동 + git status가 깨끗한 상태인지 확인
  3. gnhf --agent claude --max-iterations 2 "README의 첫 단락을 더 매력적으로 다시 써줘" 실행
  4. 2 iteration 끝나면 새로 만들어진 gnhf/<slug> 브랜치로 자동 이동된 상태. git log --oneline으로 commit 2개가 쌓였는지 확인
  5. .gnhf/runs/<runId>/notes.md 열어보기 — 에이전트가 iteration 사이에 무엇을 기억했는지 보이면 성공.
딥다이브 작성: 2026-05-24 · TrendShift 25위 (kunchenguid/gnhf, 1.8k stars, MIT)
출처: github.com/kunchenguid/gnhf · trendshift.io