세션 파일을 복사하는 방법이 작동하지 않는 이유
Claude Code 세션은 프로젝트 디렉토리에 연결되어 저장된 대화입니다. 기본적으로 트랜스크립트는 ~/.claude/projects/<project>/<session-id>.jsonl 경로에 JSONL 형식으로 저장됩니다. 여기서 프로젝트 세그먼트는 영숫자가 아닌 문자가 하이픈으로 대체된 작업 디렉토리 경로입니다.
따라서 파일은 바로 그곳에 있으며, 이를 복사하는 것이 해결책처럼 보입니다. 하지만 복사했을 때의 공식 문서상 동작은 다음과 같습니다.
"프로젝트 간 검색은 정확히 하나의 다른 프로젝트에만 해당 메시지가 포함된 트랜스크립트가 있을 때만 ID를 확인합니다. 따라서 직접 복사한 중복 파일이 있으면 Claude Code는 임의의 복사본을 재개하는 대신 찾을 수 없음(not-found)을 보고합니다."
이 문장을 자세히 읽어보세요. 검색 시스템이 복사본을 찾지 못하는 것이 아닙니다. 두 개의 후보를 찾았기 때문에 임의로 추측하여 선택하기를 거부하는 것입니다. 파일을 복사하는 행위 자체가 재개를 망치는 원인이며, 원본을 안전하게 보관하기 위해 이동 대신 복사를 선택하는 등 더 신중하게 행동했을수록 실패할 확률은 더 높아집니다.
이 파일을 기반으로 무언가를 구축하면 안 되는 두 번째 이유도 명확하게 명시되어 있습니다.
"엔트리 형식은 Claude Code 내부용이며 버전 간에 변경되므로, 이 파일을 직접 파싱하는 스크립트는 릴리스마다 깨질 수 있습니다. 세션 데이터를 활용하려면 대신 /export 또는 스크립트 인터페이스를 사용하세요."그리고 파일 중심의 계획을 세우기 전에 알아두어야 할 세 번째 사실은 트랜스크립트가 만료된다는 점입니다. 보존 정리(retention sweep)는 기본 30일 주기로 실행되며 설정 키를 통해 조정할 수 있습니다. 트랜스크립트는 아카이브가 아니라 임시 작업 결과물입니다.
이는 단일 기기 및 단일 세션 내에서 진행되는 세션을 이전 시점으로 되돌리기와는 다른 문제이며, 도구에 의해 복사본이 생성되고 올바르게 등록되는 Claude 앱에서 원격 세션 포크하기와도 다른 문제입니다. 여기서 핵심은 대화의 실질적인 내용이 해당 대화가 전혀 존재하지 않았던 다른 기기에 어떻게 도달하느냐 하는 것입니다.
사람들이 대신 시도하는 방법들
JSONL을 복사하고 ID로 재개하기. 위에서 다룬 내용입니다. 중복 파일이 존재하기 때문에 '찾을 수 없음' 오류가 발생합니다.
~/.claude/projects 아래의 전체 프로젝트 디렉토리 복사하기. 동일한 메커니즘이지만 영향 범위가 더 넓어집니다. 이제 동일한 ID에 대한 메시지가 포함된 트랜스크립트를 가진 두 개의 디렉토리가 존재하게 됩니다.
JSONL을 파싱하여 요약본을 만드는 스크립트 작성하기. 다음 릴리스 전까지만 작동합니다. 이 형식은 명시적으로 내부용이며 버전 간에 변경된다고 문서화되어 있습니다.
재개할 때 실행 구성(launch configuration)도 함께 복원되기를 기대하기. 복원되지 않으며, 다시 전달해야 하는 항목 목록은 명확합니다. "세션이 --mcp-config, --settings, --plugin-dir, --fallback-model 또는 --add-dir로 추가된 디렉토리에 의존하는 경우, 재개할 때 이를 다시 전달해야 합니다." 세션 중간에 add-directory 명령으로 추가된 디렉토리도 복원되지 않습니다. 설정 파일은 실행 시 다시 읽으므로 설정 파일에 있는 내용은 복원됩니다.
대화의 모든 내용이 보존된다고 가정하기. 대부분은 보존됩니다. 재개된 세션은 도구 호출 및 결과를 포함한 전체 기록을 복원합니다. 하지만 이전 프로세스가 종료될 때 여전히 실행 중이던 도구는 "재개할 때 완료되거나 다시 실행되지 않으며, Claude는 해당 출력 없이 계속 진행합니다." 마지막 작업이 긴 빌드였다면 그 결과는 재개된 대화에 포함되지 않습니다.
요청하지 않은 요약에 의존하기. Pro 또는 Max 플랜에서는 약 1시간 이상 비활성 상태였고 100,000 토큰이 넘는 세션을 재개할 때 먼저 대화 상자가 열립니다. 한 가지 옵션은 즉시 압축(compaction)을 실행하여 "기록을 요약, 가장 최근의 대화, 그리고 최근에 읽은 최대 5개의 파일로 대체"하는 것입니다. 이는 합리적인 기본값이지만, 압축 후 남길 내용을 선택하는 것이 의도적인 행동이어야 하는 이유와 동일한 이유로 아카이브로서는 부적절합니다.
해결책: 읽을 수 있는 기록을 내보낸 다음, 결정 사항을 별도로 전달하기
두 가지 결과물은 서로 다른 역할을 합니다. 내보내기(Export)는 대화를 문서로 제공합니다. 대화 내부의 결정 사항은 트랜스크립트가 아니라 '사실(facts)'로 전달되어야 합니다.
Step 1: 세션이 아직 열려 있는 동안 대화 내보내기
세션 내부에서 export 명령을 실행합니다. 이 명령은 대화를 클립보드에 복사하거나 메시지와 도구 출력이 읽기 쉬운 텍스트로 렌더링된 일반 텍스트 파일로 저장할 수 있는 메뉴를 엽니다. 파일 이름을 전달하면 메뉴를 건너뛰고 해당 파일에 바로 기록합니다.
결과물은 다음과 같이 정확하게 설명되어 있습니다. "/export는 사람이 읽을 수 있도록 렌더링된 트랜스크립트를 생성합니다." 이것이 올바른 기대치입니다. 이는 귀하 또는 동료가 Claude Code 버전에 구애받지 않고 모든 기기, 모든 에디터에서 읽을 수 있는 문서입니다.
이 작업은 하루 일과를 마친 후가 아니라 마치기 전에 수행하세요. 내보내기는 실시간 대화를 대상으로 실행되며, 보존 정리나 압축 대화 상자가 한 번 실행되고 나면 더 까다로워지는 단계입니다.
Step 2: 내보낸 파일에서 결정 사항을 독립적인 사실로 추출하기
내보낸 파일을 열고 전체적인 이야기 흐름보다는 결론 위주로 읽으십시오. 내일 누군가의 작업 방식을 바꿀 수 있는 몇 줄의 핵심 내용을 찾아야 합니다.
추출할 가치가 있는 것은 세 가지 종류입니다. 논쟁 끝에 해결된 결정 사항(예: 백필 전에 마이그레이션을 실행해야 하는 이유), 어렵게 발견한 제약 조건(예: 작업이 실행되는 동안에는 이 테이블을 변경할 수 없음), 다음 세션에서 잘못 이해할 수 있는 어휘(예: 팀에서 정의하는 테넌트의 의미) 등입니다.
각 항목을 대화 내용을 참조하지 않고도 그 자체로 이해할 수 있는 한 문장으로 작성하세요. "우리는 마이그레이션을 먼저 실행하기로 결정했다"는 이식성이 없습니다. "백필이 새 열을 읽기 때문에 마이그레이션은 백필 전에 실행되어야 한다"는 이식성이 있습니다. 기준은 해당 세션을 전혀 보지 못한 사람도 그 문장을 이해할 수 있는지 여부이며, 이는 무슨 일이 일어났는지 기록한 인덱싱된 로그와 사용 가능한 메모리를 구분하는 기준과 동일합니다.
Step 3: 원래 기기에서는 ID로 재개하고, 새 기기에서는 새로 시작하기
세션을 실행했던 기기에서는 아무 디렉토리에서나 ID로 재개합니다. 검색 시스템은 현재 프로젝트와 작업 트리(worktrees)를 먼저 검색한 다음 기기의 다른 모든 프로젝트를 검색하므로, 다른 곳에서 시작되었거나 이동된 세션도 정확히 하나의 트랜스크립트만 메시지를 보유하고 있다면 여전히 해결됩니다. 세션이 의존했던 실행 플래그를 함께 전달하세요.
새 기기에서는 재개를 시도하지 마세요. 세션을 시작하고 Step 2에서 정리한 사실들을 제공하세요. 이것이 인계 작업의 전부이며, 사실들이 구조적으로 짧게 작성되어 있기 때문에 생각보다 빠르게 끝납니다.
내보낸 파일 자체를 두 기기 모두에서 사용하고 싶다면 작업 문서를 보관하는 곳에 보관하세요. 다만 ~/.claude/projects에는 두지 마세요. 두 번째 프로젝트 디렉토리에 있는 트랜스크립트 복사본은 '찾을 수 없음' 오류를 일으키는 바로 그 중복 파일이 되기 때문입니다.
MemoryLake에서 설정하기
Step 2에서는 다음번에 어떤 기기에 앉더라도 읽을 수 있어야 하는 한 문장으로 된 사실 세트가 생성됩니다. MemoryLake는 동기화하는 것을 깜빡할 수 있는 파일에 의존하지 않고 이러한 사실들을 보관할 수 있는 공간입니다.
항목은 본인의 언어로 직접 작성합니다. Claude Code의 트랜스크립트 파일, ~/.claude 또는 다른 공급업체의 저장소에서 데이터를 읽거나 쓰거나 삭제하지 않습니다.
Step 1: API 키 생성하기
로그인하고 대시보드에서 키를 생성합니다. 이 키는 복사된 파일이 제공할 수 없는 부분으로, 모든 기기의 에이전트가 항목을 읽을 수 있도록 해줍니다.

Step 2: 첫 번째 메모리 업로드하기
위의 Step 2에서 도출한 결정 사항, 제약 조건, 어휘를 항목당 하나의 사실로 추가합니다. 내보낸 트랜스크립트는 긴 형식의 기록으로 보관하고, 이 항목들은 다음 세션이 시작될 때 읽어야 하는 부분입니다.

Step 3: AI 및 에이전트 연결하기
두 기기의 에이전트가 동일한 워크스페이스를 가리키도록 설정합니다. 그러면 열 수 없는 대화에서 시작하는 대신, 이미 확정된 결정 사항을 사용할 수 있는 상태로 새 세션이 시작됩니다.

실제 업무에서 달라지는 점
첫 번째 변화는 인계 작업이 더 이상 파일 작업이 아니게 된다는 점입니다. 더 이상 한 기기의 로컬 상태를 다른 기기에 억지로 표시하려고 애쓸 필요가 없습니다. 이는 도구가 의도적으로 해결해주지 않는 문제입니다.
두 번째는 두 결과물이 서로 충돌하지 않는다는 점입니다. 내보낸 파일은 특정 지점에 도달한 과정을 보여주는 읽기 쉬운 기록으로, 풀 리퀘스트(PR) 설명, 인수인계서 또는 장애 보고서에 유용합니다. 반면 '사실'은 다음 세션에 로드해야 할 내용입니다. 하나의 결과물로 두 가지 역할을 모두 수행하려다 보면 아무도 읽지 않는 거대한 트랜스크립트와 아무것도 모르는 새 세션만 남게 됩니다.
세 번째는 버전 변경이 더 이상 중요하지 않다는 점입니다. 렌더링되어 내보내진 파일은 영원히 일반 텍스트로 남습니다. 반면 JSONL 트랜스크립트는 릴리스 간에 변경되는 내부 형식이므로, 이를 기반으로 구축한 모든 것은 의도치 않은 유지보수 부담이 됩니다.
개인정보 보호 측면도 언급할 가치가 있습니다. 이는 무엇을 내보내야 할지 결정하는 기준이 되기 때문입니다. 환경 변수를 통해 트랜스크립트 기록을 완전히 억제할 수 있으며, 단일 비대화형 실행의 경우 세션을 유지하지 않도록 설정할 수 있습니다. 대화 내용이 디스크에 남아 있으면 안 되는 환경에서 작업하는 경우 이러한 스위치를 사용할 수 있으며, 이 경우 내보내기 단계가 유일한 기록이 되므로 신중하게 실행해야 합니다. 이는 CLI의 로컬 트랜스크립트가 아닌 일반 소비자용 앱을 대상으로 하는 Claude에 요청하는 계정 수준 데이터 내보내기와는 다른 결과물입니다.
노트북과 데스크톱을 오가며 작업하는 팀이 이 문제를 가장 빠르게 겪게 되며, 해결책은 기기를 변경할 때 컨텍스트가 유실되는 현상을 방지하는 방법과 동일합니다. 즉, 영구적으로 보존되어야 할 부분은 두 기기 모두에 속하지 않는 제3의 공간에 존재해야 합니다.
기기 간 작업 이동을 위한 모범 사례
다음 세션을 시작할 때가 아니라, 작업 세션이 끝날 때 내보내기를 수행하세요. 내보내기는 현재 대화를 대상으로 하는 실시간 작업입니다. 보존 정리, 압축 대화 상자, 그리고 단순한 망각 등이 어제의 세션과 여러분 사이를 가로막을 수 있습니다.
트랜스크립트 복사본을 두 번째 프로젝트 디렉토리 내부에 절대 두지 마세요. 이는 재개 실패를 유발하는 가장 결정적인 행동입니다. 내보낸 파일은 일반 문서 보관함에 보관하세요.
내보낸 파일 옆에 실행 플래그를 함께 적어두세요. 재개된 세션은 시작할 때 사용했던 구성 플래그를 복원하지 않습니다. 세션에 필요했던 플래그가 무엇인지 적어둔 한 줄의 메모는 도구가 왜 누락되었는지 파악하느라 허비할 20분을 아껴줍니다.
30일 보존 기간을 실제 마감일로 취급하세요. 기본 정리 주기는 30일이며 이는 설정 키일 뿐 보장된 약속이 아닙니다. 6개월 후에도 필요한 내용은 트랜스크립트가 아니라 내보낸 파일이나 사실(fact)로 보관해야 합니다.
세션에 이름을 지정하세요. 이름이 지정된 세션은 리포지토리와 작업 트리 전체에서 이름으로 검색되므로 원래 기기에서 쉽게 재개할 수 있고 메모를 읽기도 편해집니다. 이름이 지정되지 않은 세션은 알아보기 힘든 ID로만 남습니다.
"결정된 사항"과 "논의된 사항"을 구분하세요. 전자는 짧고 인계 사항에 속합니다. 후자는 길고 내보낸 파일에 속합니다. 맥락을 잃어버리는 세션은 대개 프로젝트의 결정 사항이 대화 외부의 그 어떤 곳에도 기록되지 않았기 때문에 발생합니다.
파서 대신 요약 요청을 사용하세요. 이전 세션에서 구조화된 출력을 얻고 싶다면, ID를 통해 후속 프롬프트를 보내고 구조화된 응답을 캡처하세요. 이것이 지원되는 인터페이스입니다. JSONL을 파싱하는 것은 지원되지 않습니다.
결론
Claude Code는 대화 내용을 눈에 보이는 파일에 저장하므로, 이를 복사하는 것이 작업을 이동하는 가장 뻔한 방법처럼 느껴집니다. 하지만 이는 도구가 의도적으로 거부하도록 설계된 유일한 접근 방식이며, 검증할 수 없는 복사본을 재개하는 대신 '찾을 수 없음'을 보고함으로써 이를 거부합니다.
공식적으로 지원되는 경로는 더 가볍고 내구성이 뛰어납니다. 세션이 열려 있는 동안 대화를 읽을 수 있는 문서로 내보내세요. 그 안에서 몇 가지 결정 사항, 제약 조건, 용어들을 독립적인 문장으로 추출하세요. 트랜스크립트가 있는 기기에서는 ID로 재개하고, 트랜스크립트가 없는 새 기기에서는 이미 로드된 사실들을 바탕으로 새로 시작하세요.
이러한 역할 분담은 여러 사람이 작업을 이어받을 수 있도록 돕는 핵심이기도 합니다. 세션 간에 컨텍스트를 공유하는 것이 도구의 문제이기 전에 작성의 문제인 이유와 일맥상통합니다.