터미널 UI
인자 없이 snowpea를 실행하면 터미널 UI가 열립니다. 이 UI는 얇은 클라이언트입니다 — 어떤 툴을 실행할지, 명령이 무슨 뜻인지, 언제 압축할지 같은 판단은 전부 데몬이 합니다. 이 문서는 그 판단이 드러나는 화면에 관한 이야기입니다.
다른 언어: English · 日本語 · 简体中文 · Español · 전체 목록
시작 화면
세션이 가장 먼저 그리는 것은 터미널 너비에 맞춘 워드마크, 그리고 지금 어디에 있는지 알려주는 세 줄입니다.
██████████ ██ ██ ██████████ ██ ██ ██████████ ██████████ ██████████
██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████████ ██ ██ ██ ██ ██ ██ ██ ██████████ ██████████ ██████████
██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ████ ████ ██ ██ ██ ██
██████████ ██ ██ ██████████ ██ ██ ██ ██████████ ██ ██
🌱 snowpea v0.1.2
Open-source multi-vendor coding agent and personal AI assistant
v0.1.2 · anthropic/claude-sonnet-4-5 · /home/you/project · ACCEPT
Last session: 26m ago · "add the worktree parallel session story to the IDE plan"
Press R or type /resume to continue it마지막 세션 안내는 이 디렉터리의 세션을 데몬이 아직 들고 있을 때만 나옵니다 — 다른 터미널에서 연 세션, 헤드리스 실행, 크래시가 남기고 간 세션. 빈 입력에서 R을 누르면 그 세션을 이 창으로 불러옵니다. /resume은 대신 저장된 세션 전체를 훑는 선택기를 엽니다. 데몬에 그런 세션이 없으면 안내 자체가 나오지 않습니다. 받을 수 없는 제안은 제안이 없는 것만 못하니까요.
배너는 한 번만 출력됩니다. 다른 출력처럼 위로 밀려 올라가고 다시 그려지지 않습니다.
저장된 세션
시작 화면이 내미는 것은 가장 최근 하나뿐입니다. 이 머신이 지금까지 돌린 세션은 모두 디스크에 남아 있고, /sessions가 그 위로 선택기를 엽니다.
╭──────────────────────────────────────────────────────────────────────╮
│ ❯ 01J9F2… · 2026-03-14 09:41 · fix the flaky worktree test │
│ 01J9DR… · 2026-03-13 18:02 · add the scheduler reminder story │
│ 01J9C7… · 2026-03-13 11:26 · (no prompt) │
│ Cancel │
│ ↑↓ move · Enter resume · Esc cancel │
╰──────────────────────────────────────────────────────────────────────╯목록에는 데몬이 아직 들고 있는 세션뿐 아니라 닫힌 세션도 들어갑니다. 각 줄은 그 세션이 마지막으로 받은 프롬프트를 달고 있어서, id를 외우지 않고도 어느 줄인지 알아볼 수 있습니다. 정렬은 최신순이고, 범위는 이 디렉터리이며, 지금 있는 세션은 목록에 넣지 않습니다.
| 입력 | 하는 일 |
|---|---|
/sessions | 선택기 열기 |
/resume | 같은 선택기 |
/resume <sessionId> | 선택기 없이 그 세션을 바로 다시 열기 |
빈 입력에서 R | 선택기를 건너뛰고 이 디렉터리의 가장 최근 세션으로 |
/session delete <id> | 저장된 세션 하나 삭제 |
/session clear | 이 디렉터리의 저장된 세션 삭제 |
/session clear --all | 이 머신의 저장된 세션 전부 삭제 |
이어가기는 그 세션의 기록을 이 창으로 되살리고 거기서 계속합니다. 작업 디렉터리, 모드, 프로바이더, 모델, 팀이 함께 돌아오며, 데몬이 그 세션을 아직 들고 있었는지는 상관없습니다.
삭제는 메시지와 이벤트와 세션 행을 한꺼번에 가져가고, 그 세션이 갖고 있던 첨부와 음성 파일도 같이 지웁니다. 붙여넣은 것 때문에 지운 대화가 붙여넣은 것을 남겨두면 안 되니까요. 살아 있는 세션은 절대 삭제되지 않습니다. 먼저 닫으세요. 그전까지 clear는 그 세션을 건너뜁니다. 반대로 이어가기는 턴이 쉬고 있어야 합니다 — 돌고 있는 동안에는 /resume과 /sessions가 거절합니다. 살아 있는 턴 밑에서 기록을 갈아끼우면 기록이 반으로 찢어지기 때문입니다.
화면 구성
UI는 전체 화면 앱입니다. 입력줄, 모드·상태 줄, 에이전트 패널은 화면 아래에 고정되고, 그 위의 대화 기록은 마우스 휠, PgUp/PgDn, Ctrl+U/Ctrl+D로 스크롤하는 창입니다. 바뀐 줄만 다시 그리므로 입력할 때 화면 전체가 다시 그려지지 않습니다. 워드마크는 빈 세션에서만 보이고, 첫 프롬프트를 보내면 그 자리를 대화 기록에 내줍니다. 종료하면 터미널은 실행 전 모습 그대로 돌아옵니다. 예전 인라인 화면은 snowpea --inline으로 쓸 수 있습니다(인라인 화면 참고).
› 재시도 로직 설명해줘 ← 대화 기록: 스크롤되는 부분, 나머지는 고정
⏺ Read 3 files (128 lines)
◆ 재시도는 `client.ts`에 있습니다…
✢ Pondering… (12s · ↓ 3.7k tokens) ← 여기부터가 살아 있는 영역
> 다음에 칠 것
⏵⏵ auto mode on · 1 shell · ← 2 agents
snowpea v0.1.2 | ~/project | Model: anthropic/claude-sonnet-4-5 | Mode: ACCEPT | ctx 34% (68k/200k)
[!!] context 85% — /compact to free space
● main
✳ executor Implement story IDE-004 running · 27s · ↓ 159.1k tokens
◯ 4 idle agents아래쪽 패널은 위에서부터 모드 요약 줄, 상태 줄, (있을 때만) 컨텍스트 경고, 에이전트 행 순서입니다. 모드가 맨 위에 오는 것은 의도한 것입니다 — 다음 턴이 무엇을 해도 되는지 정하는 줄이니, 지금 치고 있는 입력줄에 가장 가까이 붙습니다. 입력줄은 그 위에 있고, 작업 표시줄은 다시 그 위에 있습니다. 바뀌지 않은 줄은 다시 그리지 않습니다.
작업 중일 때
턴이 도는 동안 입력줄 위에 한 줄이 뜨고, 그 줄은 지금 실제로 무슨 일이 일어나는지 말합니다.
| 표시 | 뜻 |
|---|---|
✢ Pondering… (12s · ↓ 3.7k tokens) | 모델이 생각 중. 동사는 몇 초마다 바뀝니다 |
✳ Running shell: npm test… (4s · …) | 툴이 실행 중, 이름과 인자까지 |
✶ 3 agents working… (1m 2s · …) | 턴이 하위 에이전트에 위임했습니다 |
✳ /ralph… (3m 10s · …) | 명령 워크플로가 턴을 잡고 있습니다 |
⏸ Waiting for approval | 사람 답을 기다리는 중 |
시계와 토큰 수는 세션 전체가 아니라 이번 턴의 것입니다. 세션 합계는 상태 줄에 있습니다. Esc로 중단합니다.
연달아 실행된 툴 호출은 끝나면 카드 여러 장이 아니라 스크롤백의 한 줄로 접힙니다.
⏺ Ran 2 shell commands (34 lines)
⏺ Read 3 files (128 lines)실패한 호출만은 출력과 함께 자기 카드를 유지합니다. 정작 읽어야 하는 것이 그것이기 때문입니다. Ctrl+O는 아직 살아 있는 영역에 있는 가장 최근 툴 호출이나 diff를 펼칩니다.
상태줄 아래 에이전트 패널에는 이 세션을 위해 일하는 에이전트가 나옵니다: 실행 중·완료된 위임 에이전트, 그 뒤에 활성 팀의 대기 로스터. Tab으로 패널에 들어가 ↑↓로 행을 고르고 Enter를 누르면 그 에이전트의 대화가 열립니다. /mouse(또는 /mouse on)를 입력하면 행을 클릭해도 열립니다. 터미널은 특정 영역만 클릭을 보고할 수 없어서, 마우스가 켜져 있는 동안 터미널 고유의 드래그 선택은 Shift를 누른 채로 해야 하고, /mouse off(또는 /mouse 다시)로 되돌립니다. 전체 화면 TUI는 켜진 상태로, --inline은 꺼진 상태로 시작합니다.
모드
Shift+Tab이 accept → auto → plan → accept 순으로 모드를 돌립니다. 현재 모드는 상태 줄과 요약 줄에 있고, 각 모드가 무엇을 허용하는지는 모드에 있습니다. Ctrl+P는 순회 없이 plan 모드만 켜고 끕니다.
다음 모드가 아니라 특정 모드를 고르고 싶을 때를 위한 선택기도 있습니다. 가장 최근 기록 항목에서 한 번 더 누른 ↓가 커서를 요약 줄로 내리고, 거기서 Enter를 누르면 열립니다.
⏵⏵ auto mode on · 1 shell · ← 2 agents · Enter to choose mode
❯ accept mode
auto mode
plan mode커서는 지금 모드에서 시작하고, Enter가 선택한 줄을 고르고, Esc는 모드를 그대로 둡니다. 어느 쪽이든 모드 요약 줄은 상태 줄 아래가 아니라 위에 그려집니다.
모델 고르기
/model <ref> 는 세션을 그 모델 id나 이름 있는 프로필로 바꿉니다. /model 만 치면, 읽고 다시 받아쳐야 하는 목록을 출력하는 대신 고르는 화면이 열립니다.
╭──────────────────────────────────────────────────────────────╮
│ Model │
│ ❯ fast anthropic/claude-haiku-4-5 · used by reviewer │
│ deep anthropic/claude-sonnet-4-5 · default │
│ claude-opus-4-1 anthropic │
│ ↑↓ move · Enter pick · Esc cancel │
╰──────────────────────────────────────────────────────────────╯목록은 먼저 설정의 모델 프로필입니다 — models.profiles 와, 무엇이 기본이고 어떤 에이전트가 무엇을 쓰는지 말해 주는 models.default·agents.models. 그다음이 벤더 엔드포인트가 알려준 모델들, 마지막이 아무도 언급하지 않았다면 지금 쓰는 모델입니다. Enter 는 커서가 있는 줄로 /model <ref> 를 실행합니다. 상태 줄의 Model: 은 지금 쓰는 모델을 말하고, 데몬이 알려줄 때는 어디서 온 값인지도 덧붙입니다.
고르기
TUI가 보여 주는 모든 목록 — 승인, 에이전트의 질문, /model, MCP 카탈로그, 도구 체크리스트, /skill create 와 /mcp add 안의 작은 메뉴 — 은 같은 위젯이고 키도 같습니다. 한 번만 익히면 됩니다 (M15b §2).
| 키 | 단일 선택 | 다중 선택 | 질문 묶음 |
|---|---|---|---|
↑ ↓ (또는 j k) | 이동 | 이동 | 현재 질문 안에서 이동 |
Space | — | 행 토글 | 행 토글 |
Enter | 고르고 제출 | 선택 확정 | 고르기; 마지막 탭에서는 전체 제출 |
1–9 | N 번째 행으로 이동, 제출은 안 함 | N 번째 행 토글 | 같음 |
← →, Tab / Shift+Tab | — | — | 이전 / 다음 질문 |
Esc | 거절 / 취소 | 거절 / 취소 | 묶음 전체 거절 |
기타 / Other… + Enter | 한 줄 입력이 열림. Enter 로 저장, Esc 로 되돌아감 | 같음 | 같음 |
커서는 항상 첫 행, 즉 추천 항목에서 시작합니다. 화면 아래에는 그 목록에서 실제로 동작하는 키만 적은 한 줄 힌트가 늘 보입니다. 목록이 떠 있는 동안에는 키보드를 그 목록이 가지므로, 입력한 글자가 뒤의 입력줄로 새지 않습니다.
snowpea setup 마법사도 같은 키 맵을 씁니다. 그래서 마법사와 TUI 가 Space 의 뜻을 두고 서로 다르게 말하는 일이 없습니다.
승인
데몬이 물을 때는 메뉴로 묻습니다. ↑/↓로 옮기고, Enter로 선택한 줄을 고르고, Esc는 거절입니다.
╭──────────────────────────────────────────────────────╮
│ Approval required │
│ shell risk=high timeout=300s │
│ command: rm -rf build │
│ │
│ ❯ Yes (y) │
│ Yes, and don't ask again this session (a) │
│ Yes for this project (p) │
│ adds an allowlist rule the daemon keeps │
│ No (n) │
│ No, and tell it why (r) │
│ the model reads what you type as the refusal │
│ ↑↓ move · Enter confirm · 1-9 pick · Esc cancel │
╰──────────────────────────────────────────────────────╯데몬이 따로 경고할 것이 있을 때 — 작업 디렉터리 밖으로 손이 나가는 명령이라거나, 인자만 봐서는 드러나지 않는 위험이라거나 — 요청에 note가 실리고, TUI와 헤드리스 CLI 양쪽에서 인자 위에 빨간 줄로 그려집니다.
shell risk=high timeout=300s
⚠ this deletes a directory outside the working tree
command: rm -rf ../build커서는 Yes에서 시작하므로 Enter는 곧 예입니다. y, a, p, n도 그대로 동작합니다. 프롬프트가 떠 있는 동안에는 키보드를 프롬프트가 가집니다 — 입력한 글자가 뒤의 입력줄로 새지 않고, Shift+Tab도 모드를 바꾸지 않습니다.
마지막 줄은 거절하면서 이유를 말합니다. 한 줄 입력이 열리고, Enter를 누르면 적은 문장이 그대로 도구의 거절 사유로 모델에게 전달됩니다. 그래서 다음 턴은 같은 호출을 모양만 바꿔 다시 시도하는 대신 그 이유에 답해야 합니다. 입력칸에서 Esc는 선택지로 돌아가고, 메뉴에서 누른 Esc는 그냥 거절입니다.
보는 사람 없이 도는 턴이 올린 승인 — 예약 작업, Telegram 메시지 — 은 대기열에 쌓입니다. Ctrl+R이 그 대기열에 키보드를 넘기고, /approvals가 목록을 보여줍니다.
질문
승인은 데몬이 "이걸 해도 됩니까"를 묻는 것입니다. 질문은 에이전트가 ask_user 도구로 당신에게 묻는 것이고, 대화에 "(a) … (b) … (c) …"를 적는 대신 선택 목록으로 그려집니다.
╭──────────────────────────────────────────────────────╮
│ 렌더러 │
│ 렌더링을 무엇으로 할까요? 여기서 고른 것이 엔진 │
│ 통제력을 정합니다. │
│ │
│ ❯ 1. ● three.js (추천) │
│ 빠른 시작, 엔진 통제력 낮음 │
│ 2. ○ Raw WebGL2 │
│ 공수 큼, 완전한 통제 │
│ 기타 / Other… │
│ │
│ ❯ 확인 / Confirm │
│ ↑↓ 이동 · Enter 확인 · 1-9 고르기 · Esc 취소 │
╰──────────────────────────────────────────────────────╯당신이 보내겠다고 할 때까지 아무것도 전송되지 않습니다. ↑/↓(또는 j/k)로 옮기고, 선택지에서 Enter를 누르면 ●로 표시되며 커서가 맨 아래 확인 / Confirm 줄로 내려갑니다. 거기서 Enter를 누르면 제출됩니다. 1–9는 그 줄을 표시만 하고 제출하지 않습니다. 여러 개를 고를 수 있는 질문이면 Space로 켜고 끄고([x]) 확인 줄에서 한꺼번에 보냅니다. 기타 / Other… 줄은 아무도 제시하지 않은 답을 위한 한 줄 입력을 엽니다. Esc는 "고르지 않겠습니다"라는 답이고, 에이전트는 침묵을 동의로 읽는 대신 거절되었다는 사실을 전달받습니다.
ask_user 한 번에 질문이 여러 개일 수 있습니다. 한꺼번에 도착해서 위쪽 탭이 되므로, 전체를 훑어보고 아무 순서로나 답하고, 제출 전에 되돌아가 답을 바꿀 수 있습니다.
╭──────────────────────────────────────────────────────╮
│ ✓ 렌더러 │ 저장 │ 네트워크 │
│ 세계를 어디에 저장할까요? │
│ │
│ ❯ 1. ● IndexedDB │
│ 2. ○ 서버 │
│ 기타 / Other… │
│ │
│ ❯ 다음 질문 / Next question 1/3 │
│ ↑↓ 이동 · ←→ 질문 이동 · Enter 확인 · Esc 취소 │
╰──────────────────────────────────────────────────────╯←/→(또는 Tab / Shift+Tab)로 탭을 옮기고, 답한 탭에는 ✓가 붙고, 탭마다 자기 선택을 그대로 들고 있습니다. 맨 아래 줄은 마지막 탭이 아니면 다음 질문 / Next question이고, 마지막 탭에서 확인 / Confirm이 되어 모든 답을 한 번에 제출합니다. 어느 탭에서든 Esc는 전체를 거절합니다.
질문은 대기 중인 승인보다 먼저 그려지고, 떠 있는 동안 키보드를 가집니다. 기본 10분 뒤에 포기하며, settings.json의 questions.timeoutSec으로 바꿉니다.
스킬에서 쓰는 모습, 두 줄:
ask_user(question="캐시를 어디에 둘까요? 인프로세스는 단순하고, Redis는 재시작을 견딥니다.",
options=[{"label": "인프로세스 (추천)", "description": "새 서비스 없음"}, {"label": "Redis", "description": "재시작을 견딤, 운영할 것이 하나 늘어남"}])인자 스키마는 Claude Code의 AskUserQuestion(questions[], header, question, options[]의 {label, description}, multiSelect, 선택적 preview)의 상위집합이고, Hermes clarify의 문자열 choices[]와 multi_select도 받습니다. 두 쪽 어디서 옮겨온 스킬이든 그대로 동작합니다. allow_other는 기본 참이고 "기타" 줄은 알아서 붙습니다.
메신저 바인딩에서는 같은 질문이 번호 붙은 본문과 선택지별 버튼(그리고 "기타" 버튼)으로 도착하고, 2(다중 선택이면 1,3)라고 답장해도 답이 됩니다. 대화방에는 탭이 없으므로 질문이 여러 개면 한 번에 하나씩 진행하며 지금 몇 번째인지((1/3)) 알려 줍니다. 헤드리스 snowpea -c는 그릴 선택 목록이 없으므로 타임아웃을 기다리지 않고 즉시 거절하며 stderr에 그 사실을 적습니다.
TUI 안에서 설정하기
예전에는 키를 파이썬 마법사에서만 입력할 수 있었습니다. 여기서 고른 제공자는 자격 증명을 넣을 곳이 없어서, 나가서 snowpea setup을 돌리고 돌아와야 했습니다. 명령 두 개가 그 틈을 메웁니다.
/setup # 모든 화면을 차례로
/setup browser # 하나만 — providers, search, browser, audio
/login anthropic # 어떤 흐름으로 로그인할지 먼저 묻습니다
/login gemini browser # 바로 브라우저 로그인다른 모든 것과 같은 질문 UI를 씁니다. 추천 항목이 맨 위에 표시되고, 화살표나 1-9로 고르고, Esc로 거절합니다. 다른 점은 답이 자격 증명일 때입니다.
키는 입력하는 동안 가려집니다. 글자 대신 ••••를 그리되 글자 수만큼 점을 찍으므로, 붙여넣기가 잘린 경우와 제대로 된 경우가 눈에 띄게 다릅니다. 하단에 hidden이라고 표시됩니다. 값은 대화 기록에도, 여러 질문 묶음의 검토 탭에도, 로그에도 남지 않습니다. settings.json에만, 늘 그렇듯 0600 권한으로 저장됩니다.
데몬이 그런 질문에 secret 표시를 직접 붙이므로, 질문을 그리는 어떤 화면이든 어느 제공자가 키를 쓰는지 따로 알 필요 없이 같은 처리를 받습니다. URL이나 프로젝트 id는 가리지 않고 묻습니다. 비밀이 아니고, 붙여넣는 동안 가려봐야 도움이 되지 않기 때문입니다.
/setup은 snowpea setup이 쓰는 것과 똑같은 것을 같은 코드로 씁니다. 어떤 제공자가 키를 필요로 하는지, 힌트에 뭐라고 적을지, 답을 어디에 저장할지는 한 곳에서 정해지므로 둘이 어긋날 수 없습니다.
물어볼 사람이 없는 세션 — 무인 실행, 예약 잡, 위임된 자식 — 에서는 둘 다 거절합니다. 그런 곳에서 키를 물으면 타임아웃까지 멈춰 있거나, 침묵을 답으로 받아들이기 때문입니다.
Diff
파일 변경은 그 일이 일어난 자리, 대화 안에 그려집니다.
✎ Edited README.md (+4 −2)
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# snowpea
-an agent
+an open-source multi-vendor coding agent
… 3 more lines (Ctrl+O)새 파일은 ✚ Created notes.md (7 lines)로 나옵니다. 긴 패치는 열두 줄에서 잘리고, 아직 살아 있는 영역에 있다면 Ctrl+O로 펼칩니다.
컨텍스트
상태 줄은 모델의 컨텍스트 윈도가 얼마나 찼는지 들고 다닙니다.
ctx 34% (68k/200k)70%까지는 흐리게, 거기서부터 노랑, 85%부터 빨강이고, 80%를 넘으면 요약 줄 위에 무엇을 해야 하는지가 한 줄 뜹니다.
[!!] context 85% — /compact to free space/compact [지시]는 지금까지의 대화를 요약하고 그 요약에서 이어갑니다. 뒤에 붙이는 지시는 무엇을 남길지 말해 줍니다. 데몬도 턴이 context.autoCompactPercent를 넘길 것 같으면 스스로 압축합니다. 어느 쪽이든 어디서 일어났는지는 기록에 남습니다.
───────────── compacted (68.0k → 12.1k tokens) ─────────────퍼센트 없이 ctx 12.3k used로 보인다면 데몬이 그 모델의 윈도 크기를 모른다는 뜻입니다. snowpea session context와 providers.<vendor>.context_window 설정은 명령에 있습니다.
입력
↑는 이전에 보낸 프롬프트를 거슬러 올라가고, ↓는 쓰던 것으로 돌아옵니다. 기록은 세션이 아니라 머신 단위입니다 — $SNOWPEA_HOME/tui-history.jsonl에 최근 500개까지 남고, 같은 프롬프트가 연달아 두 번 기록되지는 않습니다.
가장 최근 항목에서 한 번 더 누른 ↓는 다른 일을 합니다. 커서가 입력줄을 빠져나와 아래 행으로 내려갑니다. 먼저 요약 줄이고, 거기서 Enter를 누르면 모드 선택기가 열립니다.
⏵⏵ auto mode on · 1 shell · ← 2 agents · Enter to choose mode그다음은 에이전트 행이 한 줄씩입니다. Esc나 ↑로 입력줄로 돌아옵니다.
돌고 있는 동안 보내기
턴이 끝나기를 기다릴 필요는 없습니다. 턴이 도는 중에 보낸 프롬프트는 거절되지 않고 받아들여집니다.
기본값(/busy steer)에서는 프롬프트가 잠깐 대기열에 들어갔다가 실행 중인 턴의 다음 모델 호출 전에 같은 턴으로 합쳐져, 이미 진행 중인 작업 방향을 바로 바꿀 수 있습니다(Hermes식 busy steer). 실행 중인 서브에이전트와 팀 작업자도 다음 단계에서 사용자 작업 중간 지침 접두어와 함께 같은 내용을 전달받습니다. 이때 대기열 turn id는 turn.dequeued의 reason steered로 종료되며, 별도 턴으로 시작하지 않습니다.
/busy queue를 설정하면 예전 동작으로 돌아가며, 대기열 프롬프트가 보낸 순서(FIFO)대로 별도 턴으로 실행됩니다. 이 경우에도 한 번에 한 턴씩, 하나의 기록 위에서만 돌아 같은 대화를 두 개의 프로바이더 루프가 동시에 밟지 않습니다. 대기열 모드는 도우미에게 작업 도중 조향을 전달하는 브로드캐스트도 비활성화합니다.
첨부는 Enter를 누른 시점에 붙잡아 두므로, 바쁜 동안 보낸 칩도 모델이 볼 때 여전히 의도한 그 파일입니다. 대기열은 메모리에만 있습니다. 데몬을 재시작하면 남지 않습니다.
Esc는 실행 중인 턴, 진행 중인 도구 호출, 서브에이전트와 팀 작업자를 중단하고 그 뒤의 대기열을 버립니다. 중단은 내가 시킨 것을 멈추라는 뜻이고, 거기에는 뒤에 줄 서 있는 후속 프롬프트도 들어가야 합니다. 그러지 않으면 중단한 다음에 대기열이 그대로 실행될 테니까요. 버려진 프롬프트는 각각 turn.dequeued(reason dropped)로, 이어서 자기 몫의 turn.done으로 클라이언트에 알려집니다. 그 턴 id를 기다리던 쪽이 영원히 매달려 있지 않도록요. 중단 후 다음 메시지가 같은 세션을 이어갑니다.
대기열이 빠지는 동안 UI가 그것을 보여줍니다. 작업 표시줄에 ⏳ N queued 가 붙고, 대기 중인 프롬프트는 실행될 순서대로 번호가 붙어 입력줄 아래에 흐리게 나열됩니다.
✽ Noodling… (4s · ↓ 0 tokens) · ⏳ 2 queued
1. run the tests after this
2. then read the diff
> ask anything, or /command프롬프트는 실행 중 턴으로 합쳐지거나(steered), 자기 턴이 시작되는 순간 목록에서 사라집니다. Esc 는 대기열 전체를 비우고, 프롬프트마다 한 줄씩이 아니라 2 queued prompts dropped 처럼 한 번만 알려 줍니다.
프롬프트 하나를 에이전트에게 넘기기
$이름 으로 시작하는 입력은 메인 세션이 아니라 그 에이전트에게 갑니다. 보내기 전에 입력줄이 먼저 그렇게 말해 줍니다.
[delegate to executor]
> $executor review the queue work이름은 데몬의 에이전트 목록에서 옵니다. 아무도 그 이름으로 답하지 않으면 (no such agent) 를 붙여 그대로 보여 줍니다. Enter 를 누른 뒤보다 누르기 전에 알아차리는 편이 낫기 때문입니다.
에이전트 안을 들여다보기
에이전트 행에서 Enter를 누르면 화면의 기록이 그 에이전트의 대화로 바뀝니다 — 받은 지시, 실행한 툴, 내놓은 답까지.
╭────────────────────────────────────────────────────────────────────╮
│ ◯ executor · Implement story IDE-004 running · 28s · ↓ 159.1k │
│ › Implement story IDE-004 (Worktree parallel sessions) │
│ ✓ read_file path=docs/stories/IDE-004.md (1 lines) │
│ ◆ Added the worktree manager and its tests; 3 files changed. │
│ ↑↓ PgUp/PgDn scroll · Esc back to the main transcript │
╰────────────────────────────────────────────────────────────────────╯위임된 에이전트는 저마다 자기 세션에서 돕니다. 이 화면이 바로 그 세션이고, 이미 지나간 부분을 다시 재생한 뒤 이어서 따라갑니다. Esc, 또는 ● main에서 Enter를 누르면 돌아옵니다. Ctrl+A는 접기 규칙을 풀어 패널을 전부 펼치므로, 쉬고 있는 에이전트와 ↓ N more 뒤에 숨은 행까지 보입니다.
업데이트
새 버전이 있으면 상태 줄이 알려주고, 빈 입력에서 U를 누르거나 /update를 치면 확인 메뉴가 열립니다. 업그레이드가 돌고 데몬이 재시작한 뒤 UI가 새 버전으로 돌아옵니다.
snowpea v0.1.2 → v0.1.3 (U to update)첨부
파일 경로를 입력줄에 붙여넣거나 끌어다 놓으면 글자가 아니라 칩이 됩니다.
[📎 screenshot.png 1.2MB] (backspace removes the last · Ctrl+X clears)
> 이 레이아웃 뭐가 문제야?터미널이 실제로 건네주는 형태를 그대로 알아듣습니다 — 경로 하나, 여러 개, 공백을 이스케이프한 경로, 이스케이프하지 않은 경로, file:// URL, 파일 관리자가 붙인 따옴표. Ctrl+V는 시스템 클립보드의 이미지를 바로 가져와 $SNOWPEA_HOME/tmp/ 아래에 저장합니다 — wl-paste, xclip, AppleScript, PowerShell 중 이 머신에 있는 것을 씁니다. /attach <경로>는 손으로 붙이는 방법입니다.
빈 입력에서 Backspace는 가장 최근 칩을 떼고, Ctrl+X는 전부 지웁니다. 프롬프트를 보내면 파일도 함께 가고, 기록에는 무엇이 갔는지 남습니다.
› 이 레이아웃 뭐가 문제야?
📎 screenshot.png파일은 경로로 보내므로 복사본이 생기지 않습니다. 그 파일을 모델이 어떻게 다루는지 — 20MB 제한, 축소, 이미지를 못 보는 모델에서 벌어지는 일 — 은 첨부와 음성에 있습니다.
@로 파일 참조
프롬프트에 @를 입력하면 파일 전체를 붙여 넣지 않고 이름만 지정할 수 있습니다. 입력 중 file.complete 제안이 뜨고, ↑/↓와 Enter 또는 Tab으로 고릅니다. 공백이 있는 경로는 따옴표로 감싸세요: @"docs/plan.md". 텍스트 파일은 줄 범위를 붙일 수 있습니다: @src/app.py:10-40.
보내기를 누르면 데몬이 각 @ 참조를 해석합니다: 이미지는 모델이 볼 수 있는 첨부가 되고, 텍스트 파일은 줄 번호와 함께 인라인됩니다(파일당 60k자까지). 디렉터리는 얕은 목록으로, 해석되지 않은 참조는 오류 없이 글자 그대로 남습니다. 대화 기록에는 입력한 짧은 글과 refs 목록(경로·종류)만 보이고, 파일 본문은 붙지 않습니다. @ 없이 적은 이미지 경로는 agent.autoAttachImages가 true(기본값)일 때 자동으로 첨부됩니다. 경로 뒤에 붙은 한국어 조사(@src/a.py를, shot.png에서)는 자동으로 잘립니다. 비밀 파일(.env, 키, 붙여넣은 첨부를 제외한 snowpea 홈 아래)은 거부되어 모델로 가지 않습니다.
음성
음성은 백엔드가 있어야 동작하고, 백엔드를 가진 쪽은 데몬입니다. snowpea setup audio로 설정하고, 무엇이 필요한지는 첨부와 음성에 있습니다.
| 키·명령 | 하는 일 |
|---|---|
/voice | 음성 입력을 켭니다 |
Ctrl+Space(macOS는 Ctrl+T) 또는 /rec | 녹음 시작, 다시 누르면 중지 |
/tts on, /tts off | 답변이 끝날 때마다 읽어 줍니다 |
Esc | 읽는 중인 답변을 멈춥니다 |
녹음 중에는 작업 표시줄 자리가 시간을 셉니다.
● REC 00:07멈추면 받아쓴 다음 곧바로 보내지 않고 입력줄에 넣습니다. 음성 인식은 틀릴 때가 충분히 잦아서 한 번은 읽어야 합니다. 녹음은 데몬에 마이크가 있으면 데몬에서, 없으면 이 머신에서 합니다.
상태 줄의 🔊는 답변을 읽어 주는 중이라는 뜻입니다. 없는 기능을 요청하면 아무 일도 안 일어나는 대신 데몬이 자기 말로 이유를 돌려줍니다.
voice input needs speech-to-text: no transcription backend: install the whisper CLI, set an OpenAI API key, or …MCP 서버
/mcp는 이 세션이 호출할 수 있는 MCP 서버를 관리합니다. /mcp 또는 /mcp list는 표를 출력하고, /mcp 까지 입력하면 하위 동작이 제안됩니다. 서버 이름을 받는 동작은 이미 설정된 서버 이름을 자동완성합니다.
/mcp add를 인자 없이 입력하면 문법을 외우는 대신 폼이 열립니다. 이름 → Command 또는 URL → 실행할 명령줄(셸처럼 따옴표를 인식해 인자로 나누지만 셸로 실행하지는 않습니다) 또는 엔드포인트 → KEY=value 변수(URL 서버는 헤더) → 이 프로젝트의 .mcp.json에 넣을지 전역 파일에 넣을지 순서로 묻습니다. 입력한 값은 KEY=•••로만 다시 표시됩니다. 값은 파일에 저장되고 화면에는 다시 나오지 않습니다.
저장 전에 mcp.test로 먼저 접속해 봅니다. 성공하면 Connected — N tools: …와 함께 Enable all, Select tools(체크리스트, tools.include로 저장), Cancel을 제안합니다. 실패하면 오류를 보여주고 Retry, Save anyway(접속 확인 없이 항목만 저장하며, 안전 점검에 걸린 경우에는 한 번 더 확인합니다), Cancel을 제안합니다. 어느 단계에서든 Esc로 취소하면 아무것도 쓰지 않습니다.
/mcp catalog는 미리 준비된 프리셋 목록입니다. 하나를 고르면 그 명령과 필요한 변수가 채워진 같은 폼이 열립니다. 이미 저장된 서버는 /mcp configure <이름>으로 도구 체크리스트를 열 수 있습니다.
하단 HUD에는 mcp 2/3(준비된 서버 / 설정된 서버)이 표시되며, 설정된 서버가 없으면 표시하지 않습니다. 서버가 멈추면 재시도마다 반복하지 않고 한 번만 알려 줍니다.
인라인 화면
기본은 전체 화면입니다. --inline(또는 SNOWPEA_TUI_INLINE=1)을 주면 git log처럼 그립니다. 끝난 출력은 터미널 스크롤백에 넘기고, 살아 움직이는 것은 화면 아래쪽뿐입니다.
snowpea --inline전체 화면에서 마우스 휠로 대화 기록이 스크롤되는 것은 TUI가 터미널에 마우스 보고를 요청하기 때문입니다. 그동안 마우스로 글자를 선택하려면 Shift를 누른 채 드래그해야 합니다. /mouse off로 선택을 되돌릴 수 있고(그러면 휠로 기록이 스크롤되지 않습니다), /mouse로 다시 켭니다. 인라인 화면은 꺼진 상태로 시작합니다.
키
| 키 | 하는 일 |
|---|---|
Enter | 보내기, 또는 선택한 항목 확정 |
@ | 파일 참조 (@path 또는 @"공백 포함 경로") |
Shift+Tab | 모드 순회 |
Ctrl+P | plan 모드 토글 |
↑ / ↓ | 이전 프롬프트. 가장 최근에서 한 번 더 ↓면 패널로 |
Esc | 턴 중단, 읽기 중지, 에이전트 화면 나가기 |
Ctrl+O | 가장 최근 툴 호출이나 diff 펼치기 |
Ctrl+A | 에이전트 패널 전부 펼치기 |
Ctrl+R | 대기 중인 승인 대기열로 |
Ctrl+V | 클립보드 이미지 첨부 |
Ctrl+X | 첨부 전부 비우기 |
Ctrl+Space(macOS는 입력 소스 전환과 겹쳐 Ctrl+T) | 녹음 시작·중지 |
U | 제안된 업데이트 받기 |
R | 시작 화면이 제안한 세션 이어가기 |
F1 | 도움말 |
Ctrl+C | 종료 |
/help는 플러그인이 추가한 것까지 데몬이 가진 명령 전부를 보여주고, 이 표도 함께 출력합니다.
Markdown 표
응답의 Markdown 표는 열 너비를 맞춘 테두리 표로 표시합니다. 한글·CJK·이모지의 터미널 표시 폭을 계산하며, 긴 경로나 문장은 셀 안에서 줄바꿈합니다. 열이 너무 많아 화면에 들어가지 않으면 열 이름과 값을 세로로 표시합니다. 일반 화면과 전체 화면에 동일하게 적용되며 코드 블록 안의 표 원문은 그대로 유지합니다.
기본 에이전트와 커스텀 에이전트
/agent list는 기본 역할(architect, critic, executor, explorer, test-engineer, verifier)과 커스텀 정의를 함께 보여줍니다. 기본 역할은 별도 파일 생성 없이 사용할 수 있으며 출처는 builtin으로 표시합니다. 같은 이름의 커스텀 정의가 있으면 해당 정의가 우선합니다. 전역 정의보다 프로젝트 정의가 우선하며, delegate_task의 agent 인자에도 같은 이름을 사용할 수 있습니다.
시작 시 업데이트 알림
실행할 때 백그라운드에서 최신 업데이트를 확인합니다. /update는 이전의 “업데이트 없음” 캐시를 사용하지 않고 항상 다시 확인하며, 새 버전이 없으면 설치 실패 대신 이미 최신 상태라고 안내합니다. 업데이트가 있으면 배너가 표시되며 빈 입력줄에서 U 또는 /update로 확인 메뉴를 열 수 있습니다. y를 선택하면 설치 후 재시작하고, n이나 Esc로 미룹니다. 입력 중인 소문자 u는 단축키로 처리하지 않습니다.
Git의 main/master 설치본은 설치된 커밋과 비교하므로 버전 번호가 같아도 새 커밋을 감지합니다. 확인 실패, 동일 버전/커밋, 이전 커밋으로의 다운그레이드는 설치하지 않습니다. PyPI/릴리스 설치본은 기존 버전 확인을 유지합니다.
구버전 자동 업데이트 후 Cannot read properties of undefined (reading 'rawCall')로 실행이 막힌 경우, 현재 main으로 재설치할 수 있습니다:
uv tool install --force --reinstall 'snowpea-agent[images] @ git+https://github.com/Wafour-Developer/snowpea-agent@main'재설치 후 진행 중인 작업이 없을 때 snowpea daemon stop으로 기존 데몬을 종료하고 snowpea를 실행하면 새 코드가 적용됩니다.
도움말은 화면 높이에 맞춰 표시됩니다. ↑/↓, PgUp/PgDn으로 스크롤하고 Esc, F1, q 또는 Enter로 닫습니다. 도움말에서 Esc를 눌러도 진행 중인 작업은 중단하지 않습니다.
하단의 입력, 연결/모델 상태, 모드 요약, 에이전트 목록은 터미널 내용 폭 전체의 가로선으로 구분되어 현재 키 입력이 어느 영역에 적용되는지 쉽게 확인할 수 있습니다.
팀과 짧은 위임
최초 snowpea setup은 내장 역할로 default 팀을 구성합니다. /team create delivery architect executor verifier는 존재하는 에이전트만 골라 프로젝트 팀을 만들고 즉시 현재 세션에 적용합니다. /team list, /team use <이름>, /team delete <이름>으로 관리합니다. 활성 팀에서는 하단에 팀명과 해당 팀원만 표시되고 자동 위임도 팀원으로 제한됩니다.
$executor 테스트를 고쳐줘처럼 입력하거나(또는 /delegate executor 테스트를 고쳐줘) 긴 명령 없이 해당 팀원에게 직접 위임합니다. 둘 다 평범한 턴 하나로 실행됩니다 — 데몬이 접두사를 직접 해석하므로 어떤 클라이언트에서도 동일하게 동작하고, 그 턴이 delegate_task를 호출해 자식이 끝나기를 기다린 뒤 보고받은 내용을 답으로 알려줍니다 — 자식이 끝나도 조용히 아무 대답이 없던 예전과 다릅니다. 존재하지 않거나 현재 팀 밖인 이름은 일반 에이전트로 대체하지 않고 오류로 알려줍니다. 에이전트를 명시하지 않은 내부 위임은 팀의 executor, 없으면 첫 팀원에게 결정적으로 배정됩니다.
자식은 언제나 읽을 것을 남기고 돌아옵니다. 브리프에 자기 도구 라운드 예산이 적혀 있고(도구 호출 한도), 그것을 다 쓰면 도구를 끈 채로 "무엇을 했고, 무엇을 찾았고, 무엇이 남았는지" 보고한 뒤에야 턴이 끝납니다. 위임한 에이전트가 받는 것은 status: / reason: / roundsUsed: 세 줄 아래의 그 보고문이며, 중간에 멈춘 경우에는 마지막 도구 호출 몇 개가 함께 붙습니다. 예산이 떨어진 위임은 빈손으로 돌아오는 대신 그렇다고 말하므로, 같은 일을 처음부터 다시 시키지 않고 멈춘 지점부터 이어갈 수 있습니다.
delegate_task에는 선택 인자 title이 있습니다. 이 위임이 무엇인지 사용자의 언어로 적은 한 줄이며, 자식이 도는 동안 에이전트 패널과 스크롤백에 그대로 표시됩니다 — Ran delegate_task가 아니라 요약 표시 방식 조사처럼요. 없으면 동사와 에이전트 이름으로 대체합니다. 출력 언어는 브리프에 자동으로 덧붙습니다 — 답변 언어를 참고하세요.
Reconnecting
TUI가 열려 있는 상태에서 데몬이 재시작되거나 업그레이드되면 클라이언트는 제한된 지수 백오프로 자동 재연결을 시도합니다. daemon.json에서 새로 갱신된 접속 정보와 토큰을 다시 읽어 system.hello 핸드셰이크를 수행하고, session.resume을 통해 시퀀스 번호 기준으로 중단된 세션을 원활하게 복구합니다. 연결이 끊겨 있는 동안 HUD에는 ⟳ reconnecting… (n)(여기서 n은 재시도 횟수)이 표시되며, 연결이 복구되면 ● connected로 전환되면서 daemon restarted — session resumed 토스트 알림이 뜹니다. 만약 데몬이 종료되었거나 20초 이상 연결할 수 없는 경우 HUD에 daemon is not running — press R to start it이 표시되며, R 키를 눌러 데몬을 바로 시작하고 재연결할 수 있습니다.