claude --resume를 사용하면 목록에서 선택하여 같은 폴더에서 시작된 이전 Claude Code 대화로 돌아갈 수 있습니다. 문제는 이 목록에 답변을 기다리는 세션과 이미 완료된 세션들이 나란히 배치되어 있고, 어떤 것이 아직 대기 중인지 표시하는 것이 아무것도 없다는 것입니다. 그래서 저는 대기 중인 세션을 아예 닫지 않게 되었습니다.
이 문제는 Claude Code에만 국한된 것이 아닙니다. AI 코딩 에이전트(AI coding agent)인 Claude Code, Codex 또는 다른 곳에 작업을 맡기는 사람은 검토를 기다리거나, 다른 리포지토리(repository)를 기다리거나, 사람을 기다리는 등 오직 대기 상태인 세션들을 갖게 됩니다. Codex는 유사한 codex resume 선택기를 가지고 있습니다.
이것은 제가 그 문제를 위해 만든 스킬인 eln-park에 대한 기록입니다. 이는 Claude Code와 함께 사용하는 사내 플러그인 제품군(in-house plugin suite)인 ELN workflow의 일부입니다. eln-park는 Claude Code hooks(Claude Code가 특정 시점에 자동으로 실행하는 스크립트)에 의존하므로, 오늘날에는 Claude Code에서만 작동합니다. 이 아이디어 자체, 즉 대기 중인 세션이 남기는 메모와 다음에 선택할 수 있는 목록은 모든 AI 에이전트에 적용될 것입니다. 저는 2026년 10월에 이것을 추가했습니다. 시리즈 개요였던 Ship discipline as skills, not documents — introducing the 165 skills of ELN workflow가 9월에 게시되었기 때문에, 이것은 그 165개 항목 중 하나는 아닙니다. 이 글을 해당 시리즈의 부록(addendum)으로 생각하시면 됩니다.
요약 버전
- 이 목록에는 다음 단계가 남아 있는 작업물만 포함됩니다. 완료된 대화는 여기에 나타나지 않습니다. eln-park는 기다리는 각 작업물에 대해 작은 기록, 즉 '재개 노트(resume note)'를 작성하고 오직 그 노트들만을 나열합니다.
- 각 노트는 무엇을 기다리고 있는지 알려줍니다. 제목, 세션이 무엇을 기다리는지, 다음 단계, 인계 메모(handover note), 그리고 대화 로그가 어디에 저장되어 있는지 등을 담고 있어, 세션을 닫아도 아무것도 손실되지 않습니다.
- 만약 깜빡한다면, 노트가 스스로 작성합니다. 저희 Claude Code는 모든 답변 끝에 짧은 상태 요약(진행률 백분율, 남은 작업물)을 추가합니다. 최신 요약이 작업물이 미완료라고 말하면, 다음에 Claude Code가 해당 리포지토리(repository)에서 시작할 때 재개 노트가 생성됩니다.
- Claude Code를 시작하면 목록이 표시됩니다. 동일한 리포지토리의 새 세션은 가장 최근의 순서대로 재개 노트와 함께 시작합니다. "continue 1"이라고 말하면, 새로운 세션이 노트 1을 가져옵니다(claims note 1).
- 잘못된 작업물을 넘겨주지 않습니다. 만약 다른 세션이 해당 노트를 계속 작업 중이거나, 사용자의 브랜치(branch)가 노트의 브랜치와 일치하지 않거나, 또는 이 세션이 이미 다른 노트를 가지고 있다면, 이유와 함께 요청이 거부됩니다.
- 사용자에게는 세션 ID를 다룰 필요가 없습니다. 메커니즘이 자체적으로 ID를 가져옵니다. 사용자는 리포지토리별 번호와 제목을 보게 됩니다. 원래의 대화 자체를 다시 열려면 터미널에
cpark 1이라고 입력합니다.
아래 화면들은 실제 출력물이며, 제 실제 노트가 건드려지지 않도록 격리된 테스트 환경에서 캡처되었습니다. 명령어 줄은 읽기 쉽도록 정리되었고(일부 인자 값은 "..."로 단축됨), 긴 테스트 폴더 경로는 /work으로 대체되었으며, #로 시작하는 회색 이탤릭 줄들은 제가 추가한 장면 노트이며 도구의 출력물이 아닙니다. 나머지 모든 내용은 도구가 그대로 출력합니다. 도구 자체 화면에서는 세션을 'tab', 저장된 노트를 'parked', 그리고 노트 자체를 'card'라고 표시하며, 이 단어들은 인용 부호로 표시됩니다.
보이는 것들
세션이 작업을 인계하고 대기 상태가 되면 /eln-park를 입력합니다. Claude는 재개 메모(제목, 대기 유형, 다음 단계 및 인계 노트)를 작성한 후, 해당 메모가 저장되었고 다음에 작업 목록에 나타날 것이라는 문장으로 마무리합니다.
[Terminal (recomposed from real output in an isolated test setup, captured October 27, 2026, with the display language set to English by ELN_PARK_LANG=en): in session A, on branch feat/iam-least-privilege, typing /eln-park makes Claude run raw eln-park.sh park endraw with the title "Least-privilege IAM policy — waiting for infra-ops handoff reply", the wait kind manual, the next step and a handover note file (some argument values shortened to "…"). The tool answers with its fixed wording, "Parked: [1] …" and "You can close this tab. It shows up in the list next time you open this repo."
제목은 고정된 형태를 가지고 있습니다: 작업 내용, 그리고 무엇을 기다리는지. 해당 기능의 자체 지침에서는 나쁜 예시인 "infra fix"와 좋은 예시인 "IAM policy least privilege, waiting for infra-ops to answer the handoff"(번역됨)를 제시합니다. 이 제목 덕분에 유사한 두 가지 연속 작업(continuation)을 구분할 수 있습니다.
다음에 해당 저장소에서 Claude Code를 시작하면, 목록이 가장 먼저 보이게 됩니다:
![Terminal (실제 출력에서 재구성되었으며 격리된 테스트 환경에서 캡처됨, ELN_PARK_LANG=en으로 표시 언어가 설정됨: 동일한 리포지토리에서 새로운 Claude Code 세션 C가 시작될 때 SessionStart 훅이 출력하는 내용. 도구의 제목 '🅿️ Parked work (demo-app)' 아래에는 두 개의 메모가 있습니다: [2] 결제 웹훅 서명 확인, 대기 중: 알 수 없음 ❔, feat/billing-webhook, 다음: 주소 검토 코멘트 및 병합, 0분 전 (자동); 그리고 [1] 최소 권한 IAM 정책 — infra-ops 인수인계 답변 대기 중, 대기 중: 사용자가 infra-ops에게 허용 목록을 요청함 ❔, feat/iam-least-privilege, 다음: 그들의 허용 목록에서 정책 재작성, 0분 전. 마지막 줄에는 다음과 같이 쓰여 있습니다: 이 탭에서 재개하려면 "continue N"이라고 말하세요. 원래 대화에 다시 접속하려면 터미널에서 raw cpark N endraw 를 실행하세요.]
| 메모별 표시 내용 | 예시 |
|---|
| 번호 | [2] — 리포지토리당 카운트되며, 재사용되지 않음 |
| ... | |
| Nobody가 수동으로 메모 [2]를 작성하지 않았습니다. 세션 B가 풀 리퀘스트(pull request)를 열고 "80% 완료됨, 병합되지 않은 PR #12"라는 요약과 함께 닫혔기 때문에, 세션 C를 시작하면서 이 내용이 제목에 포함된 메모로 변환되었습니다. | |
이 목록은 새로운 시작이나 /clear를 할 때만 나타나며, 압축(compaction)을 하거나 재개(resume)할 때는 그렇지 않습니다. 이 정보는 화면과 Claude의 컨텍스트 모두에 전달되며, 사용자가 "continue N"이라고 말했을 때 무엇을 해야 하는지에 대한 지침도 함께 제공됩니다. 최대 8개의 노트가 표시될 수 있으며, 그 이상은 "N more"로 요약되고 cpark에서는 모든 노트를 보여줍니다. 파란색 마커는 다른 세션이 해당 노트에서 작업 중임을 의미하며, 14일보다 오래된 노트에는 레이블이 붙습니다. 동일한 리포지토리를 사용하는 Git worktree들은 하나의 목록을 공유합니다.
계속하는 방법은 두 가지가 있으며, 사용자가 하나를 선택하게 됩니다. 새 세션에서 계속하려면 "continue 1"이라고 말합니다: Claude가 먼저 해당 노트를 선점(claim)하고 그 후에 읽기 때문에, 이미 다른 세션이 작업 중인 노트나 잘못된 브랜치에서 시작하는 일이 없습니다. 대신 원래 대화를 다시 열려면 건너뛰고 터미널에 cpark 1을 입력합니다. cpark 역시 다른 세션이 해당 노트를 여전히 작업 중일 때는 거부합니다.
| 새 세션에서 계속하기 | 터미널에서 cpark 1 |
|---|
| 대화 내용 | 새 세션, 핸드오버 로드됨 | 원래 세션 재개됨 |
| ... | | |
새 세션에서 계속하는 것은 노트의 현재 대기 상태(wait status), 브랜치, 폴더, 다음 단계, 핸드오버 노트, 마지막 20개의 상태 요약, 그리고 원본 대화의 최근 몇 개 메시지(각 최대 1,500자까지 총 여섯 개)를 로드합니다. 백업은 대화 로그에 대한 하드 링크이므로, Claude Code가 원본 파일을 제거하더라도 내용물은 살아남습니다. 이 파일은 어떤 노트도 가리키지 않을 때만 제거됩니다. cpark는 eln-park.sh install로 한 번 설치하며, 이름이 C 컴파일러인 cc와 충돌하는 것을 방지합니다.
Terminal (recomposed from real output in an isolated test setup, captured October 27, 2026, with the display language set to English by ELN_PARK_LANG=en): eln-park.sh brief 1 after the claim. Under the note's title come the wait, the branch and folder (/work/demo-app) and the next step; then "Handoff notes" (goal, decision, what it waits on, next step), "Progress (recap history)" with one summary at task 60%, and the last two messages of the original conversation.
세션 ID는 이 모든 곳에서 나타나지 않습니다. Claude Code가 ID를 훅(hooks)과 쉘(shell)로 전달하므로, eln-park가 자체적으로 기록하고 cpark가 이를 화면에 보여주지 않고 claude --resume으로 전달합니다.
거부되는 경우
클레임은 다음의 경우 거부됩니다:
- 브랜치가 다릅니다(the branch differs). 피처 브랜치(feature branch)에서 작업한 내용을
main에 계속 진행하면 변경 사항이 잘못된 브랜치에 적용됩니다. 거부 메시지는 전환하거나 cpark 1을 사용하라고 알려줍니다. 만약 노트의 브랜치가 더 이상 존재하지 않는다면, 해당 클레임은 현재 브랜치에서 통과되며 그 사실을 알립니다.
- 다른 세션이 작업 중입니다(another session is working on it). 동일한 작업을 계속하는 두 개의 세션은 진실의 두 가지 버전을 생성합니다.
- 이 세션에 이미 노트가 있습니다(this session already holds a note). 하나의 세션에는 하나의 노트만 존재합니다.
거부될 경우, Claude는 이유를 전달하고 중단합니다. 해당 스킬은 거부를 우회하지 않도록 지시합니다. 번호를 제공하는 대신 작업 내용을 설명하면, Claude는 제목으로 노트를 찾고 일치하는 노트가 여러 개일 경우 질문을 하나 합니다.
[Terminal (실제 테스트 환경에서 재구성되었으며, 2026년 10월 27일 포착, 표시 언어는 ELN_PARK_LANG=en으로 영어 설정됨): main 브랜치에 있는 세션 C의 클레임 1이 도구 문구 "this card is work on branch raw feat/iam-least-privilege endraw , but this tab is raw main endraw "와 함께 거부됩니다. 브랜치를 전환한 후, 해당 클레임은 성공합니다("Claimed: [1] …"). 다른 세션 D의 동일한 클레임 1은 도구 문구 "[1] is in use in another tab"와 함께 거부되며, 목록에는 노트 [1]에 대해 "🔵 in use in another tab"이 표시됩니다.
노트를 잊어버렸을 때 작성되는 방식
매번 /eln-park를 입력하는 것이 이상적일 것입니다. 하지만 실제로는 세션을 닫는 경우가 대부분입니다. 그래서 다음과 같습니다:
- 답변이 있을 때마다(After every reply), Stop 후크가 해당 세션에 대한 작은 기록을 작성합니다. 이 기록에는 ID, 폴더, 브랜치 및 답변 끝 부분의 상태 요약이 포함됩니다.
- 세션이 종료될 때(When the session ends), SessionEnd 후크는 단순히 종료된 것으로 표시만 합니다. 이 후크는 시간이 매우 짧습니다(기본값 1.5초, 당시 Claude Code가 문서화한 후크 동작에 따름). 따라서 다른 작업은 수행하지 않습니다.
- 다음에 해당 저장소에서 Claude Code를 시작하거나 (
cpark 및 유사한 명령을 실행할 때), 종료된 세션들이 처리됩니다.
규칙:
- 미완료(Unfinished): 요약이 100% 미만이거나, "남은 작업(remaining)" 목록에 무언가(예: 병합되지 않은 풀 리퀘스트)가 나열된 경우입니다. 검토를 기다리는 풀 리퀘스트는 100%일지라도 미완료로 간주됩니다. 요약의 작업 이름으로 제목이 지정된 재개 메모(resume note)가 생성됩니다.
- 완료(Finished): 100%이고 남은 작업이 없는 경우입니다. 해당 세션이 가지고 있던 모든 메모는 보관(archived)됩니다.
- 세션 내에 요약이 전혀 없는 경우: 아무 일도 일어나지 않습니다. 마지막 답변에만 요약이 누락된 경우, 가장 최근의 이전 요약을 사용합니다.
시스템은 다른 세션이 동일한 폴더를 사용하고 있을 수 있으므로 의도적으로 git status를 확인하지 않습니다. 세션이 여전히 활성화되어 있는지 여부는 경과된 시간이 아니라 프로세스에 의해 결정되므로, 몇 시간 동안 대기해 온 세션도 여전히 살아 있습니다. 터미널과 함께 종료된(killed) 세션들도 마찬가지로 처리됩니다.
실시간 상태 확인 및 정리