코딩 에이전트를
여러 개 돌리고,

그 결과를 한 화면에서
확인하세요.

작업 하나에 worktree 하나. 그 안에서 Claude Code와 Codex를 띄우고,
바뀐 코드와 테스트를 같은 창에서 봅니다.

아래 화면은 실제 작업 흐름을 그대로 재생합니다.

저장소payments-api 브랜치feat/webhook-retry origin에서 받기↑1 ↓2
에이전트 깃 히스토리
Claude Codefeat/webhook-retry 대기 중

webhook 재시도에 지수 백오프와 jitter를 추가하고 테스트해줘

기존 재시도 흐름과 테스트 경계를 확인하고 있습니다.

코드 검색retry · webhook · backoff완료

고정 지연을 capped exponential backoff로 바꾸고 jitter를 적용합니다.

npm test -- retry18 passed · 0 failed통과

완료. 재시도 정책과 회귀 테스트를 함께 업데이트했습니다.

에이전트를 시작합니다… ⌘ ↵
에이전트 변경 retry.ts 내 작업
에이전트가 바꾼 것파일 2개 · 세션 시작 시점 기준 +14−3
src/webhook/retry.ts+8−2
@@ -18,7 +18,11 @@
 export function retryDelay(attempt) {
-  return 1000;
+  const cap = Math.min(BASE * 2 ** attempt, MAX);
+  return Math.random() * cap;
 }
+if (attempt > LIMIT) return deadLetter(job);
src/webhook/retry.test.ts+6−1
@@ -4,3 +4,9 @@
+it("caps the delay", () => {
+  expect(retryDelay(9)).toBeLessThanOrEqual(MAX);
+});
터미널
$ npm test -- retry▋
✓ 18 passed in 1.24s
$ ▋
도커 빌드 DB

이 프로젝트가 띄운 것2

postgrespostgres:16Up 12분5432→5432

redisredis:7-alpineUp 12분6379→6379

그 밖1

mailhogmailhog/mailhogExited (0)

gradlew build2

cannot find symbolsymbol: variable delayMsRetryPolicy.java:42

incompatible types: long cannot be converted to DurationWebhookSender.javaWebhookSender.java:88

$ ./gradlew build --console=plain

payments · postgres 165432

public.webhook_deliveryid · endpoint · status · attempts12,480행

public.webhook_attemptdelivery_id · delay_ms · error48,102행

public.idempotency_keykey · created_at3,914행

select count(*) from webhook_attempt where error is not null;

시작 2.4s 전환 240ms 메모리 128MB 터미널 2 버퍼 1.2MB / 8MB 감시 3 절전 허용 정리
  • 창 하나worktree · 코드 · 터미널 · 에이전트
  • 계정 없음로그인도 텔레메트리도 서버도 없이
  • 메모리 128MB브라우저 엔진을 번들하지 않는 Tauri 2 셸
  • macOSApple Silicon · Intel

VS Code · IntelliJ 에서 오셨다면

손에 익은 키, 그대로.

IDE 를 버리라는 게 아닙니다. worktree 는 평범한 폴더라 쓰던 IDE 로도 그대로 열립니다 — 에이전트 여러 개를 돌리고 결과를 보는 일만 codeme 에 맡기세요. 단축키는 두 제품이 실제로 싣는 키맵 파일에서 옮겨 왔습니다.

키맵
파일로 이동 ⌘P⌘⇧O
파일에서 찾기 ⌘⇧F⌘⇧F
심볼로 이동 ⌘T⌘⌥O
파일에서 바꾸기 ⌘⇧H⌘⇧R
커밋 · 소스 컨트롤 ⌃⇧G⌘K
터미널 ⌃`⌥F12
디버거 열기 ⌘⇧D⌘5
다음 줄로 F10F8
안으로 F11F7
중단점 켜고 끄기 F9⌘F8
줄 복제 ⇧⌥↓⌘D
줄로 이동 ⌃G⌘L
코드 포맷 ⇧⌥F⌘⌥L
문제 목록 ⌘⇧M⌘6
에이전트 변경 ⌃⇧X⌃⇧X
여러 에이전트에게 한 번에 ⌘⌥⇧A⌘⌥⇧A

macOS 기준. 안 맞는 키는 설정의 「단축키」에서 명령마다 눌러서 다시 기록합니다.

확장으로 깔던 것이, 처음부터.

  • Prettier · ESLint저장할 때 프로젝트가 선언한 포매터와 린터를 돌립니다. 선언이 없으면 아무것도 돌리지 않습니다.
  • GitLens지금 줄을 마지막으로 바꾼 사람이 줄 끝에, 커밋 그래프는 히스토리 탭에.
  • Docker컴포즈가 띄운 컨테이너를 도커 탭에서 — 시작 · 정지 · 재시작 · 로그.
  • SQLTools데이터베이스 탭. 접속 정보는 워크스페이스에서 찾아냅니다.
  • Error Lens언어 서버의 진단이 에디터 거터에 바로.
  • launch.json.vscode/launch.json 이 있으면 디버거가 그대로 읽습니다.

도구 창이 있던 자리에.

  • Project⌘1파일 사이드바
  • Run⌘4테스트 — 실패는 클릭할 수 있는 줄 목록으로
  • DebugF8스텝 키는 IntelliJ 식 그대로 — F7 · F8 · ⇧F8
  • Services⌘8도커 탭 — 컴포즈가 띄운 컨테이너
  • Version Control⌘9히스토리 그래프와 커밋
  • Database⌃⇧Q데이터베이스 탭 — postgres · mysql · sqlite · H2 …

편집기는 Monaco, 언어 서버는 이미 깔린 것을 씁니다. Gradle · Maven 은 래퍼로 돌리고, 무엇도 대신 설치하지 않습니다.

장면 01

브랜치는 그대로.
자리를 하나 더.

작업 하나에 worktree 하나. 브랜치를 오가지 않으니 빌드 캐시도 node_modules도 그대로 살아 있고, 만든 자리에서 바로 에이전트를 띄우면 됩니다.

  • 만들기 · 지우기 · 옮겨 다니기가 한 메뉴 안에
  • 브랜치가 이 머신에 없으면 가져온 다음 만듭니다

장면 02

에이전트마다 자기 자리.

Claude Code든 Codex든, 쓰던 CLI를 그 자리에서 띄웁니다. 지금 몇 개가 돌고 있고 몇 개가 내 답을 기다리는지는 메뉴 막대에 뜹니다.

  • + 메뉴가 "새로 시작"인지 "이어서"인지 먼저 묻습니다
  • 다른 worktree로 옮겨도 세션은 자기 자리에 남습니다

장면 03

바뀐 것만, 한눈에.

기준점은 세션이 시작한 순간입니다. 그 전에 내가 해 둔 편집은 섞이지 않고, 테스트는 같은 창의 터미널에서 그대로 돌립니다.

  • 문법 하이라이트가 붙은 diff, 접힌 줄은 펼쳐서
  • 스테이징 · 커밋 · 푸시가 같은 창 안에

장면 04

왜 그렇게 바꿨는지도.

diff 는 무엇이 바뀌었는지만 말합니다. 왜 그렇게 했는지는 터미널을 지나 사라집니다. codeme 는 그 대화를 바뀐 파일 옆에 붙여 둡니다.

  • 파일을 고르면 그 파일을 쓴 대화가 열립니다
  • 새로 기록하지 않습니다 — 이미 디스크에 있는 것을 읽습니다

직접 해 보기

하나 더, 또 하나 더.

에이전트마다 자기 worktree 가 있어서 서로의 파일을 밟지 않습니다. 몇 개가 돌고 몇 개가 내 답을 기다리는지는 메뉴 막대가 셉니다 — 다른 앱에 있어도.

  • 기다리는 카드의 「답하기」를 누르면 그 에이전트가 이어서 일합니다
  • 창이 앞에 없으면 OS 알림이 대신 말합니다

codeme 2실행 중 1나를 기다림

  • feat/webhook-retry+14−3 재시도에 지수 백오프와 jitter 완료Claude Code
  • fix/idempotency-key+31−8 같은 키로 온 중복 요청 막기 나를 기다림Codex 마이그레이션 파일도 만들까요?
  • feat/invoice-table+22−1 청구서 표에 합계 행 추가 코드 작성 중Claude Code
  • chore/bump-deps+6−6 의존성 올리고 테스트 돌리기 테스트 실행 중Codex 메이저 버전도 올릴까요?

더 들여다보기

워크트리 여럿을 나란히 돌릴 때.

포트, 브라우저, 리뷰, 되돌리기 — 여러 갈래로 일할 때 필요한 것들입니다. 탭을 눌러 하나씩 보세요. 무엇이 언제 들어왔는지는 릴리즈 노트에 있습니다.

payments-api워크트리 3

  • feat/webhook-retry:5173 ✓ 검사… CI✓ CI
  • fix/idempotency-key:5174 ✓ 검사✕ CI
  • feat/invoice-table:5175 … 검사 origin/main 에 합치면 부딪힐 파일 1개src/webhook/retry.ts

카드마다 그 워크트리가 켠 서버의 포트가 붙고, 켜 두면 새 워크트리의 포트를 겹치지 않게 옮깁니다. 부딪힘은 1분마다, 창으로 돌아올 때 다시 잽니다.

retry.tsInvoices

localhost:5173/invoices

Invoices

INV-1042Acme$1,200
INV-1043Globex$860
Total$2,060

ConsoleNetworkElements

200GET /api/invoices38ms

200GET /api/invoices?total=121ms

주소창에 3000 만 넣어도 localhost 가 열립니다. 페이지를 보고 있어도 앱 단축키가 듣고, 개발자 도구는 그 탭 안에 붙습니다.

#482 webhook 재시도 큐 정리jiwon → 나

src/webhook/retry.ts

 export function retryDelay(attempt) {+  const cap = BASE * 2 ** attempt;+  return Math.random() * cap;

jiwon방금

상한이 없으면 지연이 30초를 넘길 수 있어요. MAX 로 막아 주세요.

에이전트에 붙여넣기답글

Claude Code · feat/webhook-retry› jiwon 의 코멘트 — 상한이 없으면 지연이 30초를 넘길 수 있어요.

PR 의 브랜치가 열린 worktree 에 에이전트가 있으면, 스레드마다 「에이전트에 붙여넣기」가 붙습니다. GitHub · Forgejo 는 줄 코멘트를 쓰고, Bitbucket Cloud 는 읽습니다.

로컬 히스토리feat/webhook-retry

  1. 14:32에이전트 턴retry.ts · retry.test.ts
  2. 14:28저장retry.ts
  3. 14:05에이전트 턴queue.ts — 지운 파일
-  return Math.random() * cap;+  return cap / 2 + Math.random() * cap / 2;

이 때로 되돌리기

저장할 때마다, 그리고 에이전트가 한 턴을 마칠 때마다 이전 내용을 남깁니다. 커밋과 커밋 사이, git 이 모르는 시간으로 돌아갑니다.

기능

codeme 하나가 맡는 일.

worktree부터 diff, 터미널, 테스트, 빌드, 디버거, 컨테이너, 티켓까지. 앱을 옮겨 다니며 하던 일이 모두 이 창 안에서 끝납니다.

  • 01

    worktree

    프로젝트마다 만들고, 지우고, 옮겨 다닙니다. 브랜치를 갈아끼우지 않으니 빌드 캐시도 node_modules도 그대로 살아 있습니다.

  • 02

    에이전트 세션

    Claude Code · Codex를 worktree 안에서 띄웁니다. 몇 개가 돌고 있고 몇 개가 답을 기다리는지는 메뉴 막대에 뜹니다.

  • 03

    에이전트 변경

    에이전트가 무엇을 바꿨는지만 따로 봅니다. 기준점은 세션이 시작한 순간이라, 그 전에 내가 해 둔 편집은 섞이지 않습니다.

    ⌃⇧X

  • 04

    편집기

    Monaco 기반. 완성 · 호버 · 정의와 구현으로 이동 · 사용처 · 호출한 곳 · 하이라이팅까지 이미 깔려 있는 언어 서버가 답합니다 — 무엇도 번들하거나 대신 설치하지 않습니다.

  • 05

    테스트 · 빌드

    프로젝트가 자기 파일로 선언한 러너만 돌립니다 — Gradle · Maven 은 래퍼로. 실패는 사백 줄 로그가 아니라 클릭할 수 있는 줄 목록으로 나옵니다.

    ⌃⇧U · ⌘⇧B

  • 06

    도커 · 데이터베이스

    컴포즈가 띄운 컨테이너와 그 안의 테이블을 같은 창에서 봅니다. 접속 정보는 워크스페이스에서 찾아냅니다 — 호스트와 포트를 다시 타이핑하지 않습니다.

  • 07

    디버거

    Go · Python · Java · C · C++ · Rust. 조건 · 횟수 중단점과 로그포인트, 감시식까지. 어댑터는 이미 깔린 것을 쓰고, 설정은 VS Code 의 launch.json 을 그대로 읽습니다.

    ⌘⇧D · F5

  • 08

    로컬 히스토리

    저장할 때마다 이전 내용을 남깁니다. 커밋과 커밋 사이, git 이 모르는 그 시간의 파일로 한 번에 되돌립니다.

    ⌃⌥⇧H

  • 09

    일 맡기기 · 검사

    자리를 비운 사이 에이전트가 일을 하나씩 처리합니다. 한 지시를 여러 갈래로 던져 이긴 갈래만 남기고, 멈추면 프로젝트가 선언한 검사가 돕니다.

    ⌃⌥Q

  • 10

    내 작업

    GitHub · Forgejo · Gitea · Bitbucket · Jira를 각자의 API로 직접 읽습니다. 연결은 브라우저에서 로그인하고, 토큰은 OS 자격증명 저장소에 들어갑니다. 티켓에서 worktree를, worktree에서 PR을 만들고 — 나에게 온 리뷰는 앱 안에서 읽고 줄마다 답합니다.

    ⌃⇧Y · ⌃⌥Y

비교

에이전트를 위해 만든 앱.

편집기는 한 사람이 타이핑하도록 만들어졌고, 에이전트 래퍼는 대개 터미널에서 멈춥니다. codeme는 worktree · diff · 터미널 · 컨테이너가 처음부터 한 창에 있는 환경입니다.

항목 codeme 편집기 · 에이전트 래퍼
작업마다 독립된 git worktree ✓ 일부
에이전트가 바꾼 것만 따로 보는 diff ✓ —
기준점이 세션이 시작한 순간 ✓ —
터미널 · 도커 · 데이터베이스가 같은 창에 ✓ 확장
이미 깔린 언어 서버를 그대로 사용 ✓ 번들
GitHub · Forgejo · Jira에서 바로 worktree ✓ —
계정 · 서버 · 텔레메트리 없음 ✓ 제품마다
브라우저 엔진을 번들하지 않는 셸 ✓ 번들
창 하나가 쓰는 메모리 128MB 제품마다

흐름

티켓에서 커밋까지, codeme 하나로.

  1. 내 작업에서 티켓을 고릅니다

    리뷰 요청이 위, 내가 맡은 일이 아래에 옵니다. 이 머신에 없는 브랜치면 가져온 다음 worktree를 만듭니다.

  2. 만든 worktree에서 에이전트를 띄웁니다

    "새로 시작"과 "이어서"는 다른 동작입니다. 어느 쪽인지 + 메뉴가 먼저 묻습니다.

  3. 바뀌는 파일을 옆에서 봅니다

    문법 하이라이트가 붙은 diff. 접힌 줄을 펼치면 이 세 줄이 어느 함수 안인지까지 보입니다.

  4. 스테이징하고, 커밋하고, 푸시합니다

    히스토리 그래프도 커밋 화면도 같은 창 안에 있습니다. 푸시는 커밋한 자리에서 바로 이어집니다.

local-first

전부 codeme 앱 안에.

열린 파일, PTY 프로세스, worktree, 커밋 — 이 앱이 다루는 상태는 모두 디스크에 있습니다. 서버도, 계정도, 화면이 그려지기 전에 기다려야 하는 요청도 없습니다.

예외는 하나, 의도적으로. 내 작업 패널만 GitHub · Forgejo · Jira의 API를 읽습니다. 토큰은 맥 키체인에 들어가고, 설정 파일에는 주소만 남으며, 어떤 IPC 명령도 토큰을 창으로 돌려주지 않습니다. 개인정보 처리방침에 그대로 적혀 있습니다.

받기

오늘 쓰던 브랜치부터.

계정도 서버도 없어서 받은 다음 로그인할 것이 없습니다. 설치하고 열면 바로 시작입니다.

지금은 macOS 와 Linux — 설치할 것은 앱 하나, 에이전트 CLI는 쓰던 그대로.

이미 써 보셨다면 피드백을 남겨 주세요. 별점 하나만 눌러도 됩니다.