Claude Code의 대화 로그(jsonl)를 읽고 'Claude가 읽은 파일' 목록 만들기
요약
본 문서는 Claude Code의 대화 로그(jsonl) 파일을 분석하여 AI가 어떤 파일들을 읽거나 수정했는지 추적하는 방법을 안내합니다. `jq`와 쉘 스크립트를 활용해 대화 기록에서 '읽은 파일'과 '수정한 파일' 목록을 추출할 수 있습니다.
핵심 포인트
- 대화 로그는 JSONL 형식의 파일로 존재하며, 위치를 파악하는 방법이 제시됩니다.
- 파일 읽기/쓰기는 `assistant`의 `tool_use`나 `attachment` 필드를 통해 추적 가능합니다.
- `jq`와 쉘 스크립트를 조합하여 원하는 파일을 목록화할 수 있습니다.
Claude Code에 작업을 맡기고 있다 보면, 이런 점이 궁금하지 않으신가요?
- Claude는 어떤 파일을 읽은 후에 이 판단을 내렸는지
- 방금 보여준 파일을 압축한 후에도 기억하는지
- 긴 대화 속에서 자신이 무엇을 요청했는지 되돌아보고 싶다
답변은 Claude Code가 남겨둔 대화 로그에 적혀 있습니다. 본문에서는 대화 로그의 행 종류를 살펴본 뒤, jq를 사용해 '현재 대화에서 Claude가 읽거나 쓴 파일' 목록을 만듭니다.
stale /Users/you/work/README.md
read /Users/you/work/src/a.ts
edited /Users/you/work/src/b.ts
read는 읽었다, edited는 썼다, stale은 읽기만 했지만 압축 과정에서 요약으로 대체되었다는 의미입니다.
대화 로그의 위치
대화 로그는 대화마다 하나의 jsonl 파일로 존재합니다.
~/.claude/projects/<폴더>/<세션 ID>.jsonl
<폴더>는 Claude Code를 실행한 폴더 경로의 /를 -로 바꾼 이름입니다. 예를 들어, /Users/you/work에서 실행했다면, -Users-you-work가 됩니다.
가장 최신 대화 로그는 업데이트된 날짜 순으로 정렬하면 찾을 수 있습니다.
ls -t ~/.claude/projects/-Users-you-work/*.jsonl | head -1
현재 대화의 대화 로그 경로는 statusLine의 JSON에 transcript_path에도 들어있습니다. statusLine의 JSON에 대해서는 이전 기사에서 다루었습니다.
행의 종류
jsonl은 한 줄이 하나의 JSON 객체입니다. 종류는 type으로 구분됩니다. 짧은 대화 로그를 세어보면 다음과 같습니다.
jq -r '[.type, .subtype // .attachment.type //
의 행은 Claude Code가 추가한 내용(스킬 본문 등)입니다.
## Claude가 읽거나 쓴 파일을 목록화하기
Claude가 읽거나 쓴 파일은 다음 줄부터 알 수 있습니다.
| 항목 | 의미 |
|---|---|
| `assistant`의 `tool_use`에서 `name`이 `Read` | 읽음 (`input.file_path`) |
| `assistant`의 `tool_use`에서 `name`이 `Edit`・`MultiEdit`・`Write`・`NotebookEdit` | 씀 (입력 파일 경로: `input.file_path`. `NotebookEdit`은 `input.notebook_path`) |
| `attachment`에서 `attachment.type`이 `file`・`edited_text_file` | 첨부됨 (파일 경로: `input.file_path`. `NotebookEdit`은 `input.notebook_path`) |
| 대화에 첨부된 파일 (`@`을 통한 첨부 또는 변경 알림. `attachment.filename`) | 시스템에서 `subtype`이 `compact_boundary`일 때|
| 압축의 구분선. 이보다 전에 읽은 것은 요약으로 대체됨 | `attachment`에서 `attachment.type`이 `compact_file_reference`일 때 |
| 압축되어 요약으로 대체된 파일 |
이를 하나의 스크립트로 만듭니다.
```bash
#!/bin/bash
# 대화 로그(jsonl)에서 Claude가 읽거나 쓴 파일을 목록화하기
jq -rn '
...
chmod +x claude-files.sh
./claude-files.sh "$(ls -t ~/.claude/projects/-Users-you-work/*.jsonl | head -1)"
시험 삼아, 다음 순서로 진행된 대화 로그를 읽어보겠습니다.
a.ts
을 읽고 수정하며, b.ts와 README.md를 읽습니다(서브 에이전트가 sub.ts를 읽음) - 압축합니다.
b.ts는 압축 후에 다시 첨부됩니다 -
c.ts와 a.ts를 읽습니다
read /Users/you/work/src/a.ts
read /Users/you/work/src/b.ts
stale /Users/you/work/README.md
...
README.md는 압축 전에 읽었기 때문에 stale입니다. a.ts는 압축 전에 수정했지만, 압축 후에 다시 읽었기 때문에 read로 돌아왔습니다. 서브 에이전트가 읽은 sub.ts는 나오지 않습니다.
주의해야 할 점 (취약점)
- 서브 에이전트의 행을 제외:
isSidechain이true인 행은 서브 에이전트와의 대화입니다. 서브 에이전트가 읽은 파일은 본체 Claude의 컨텍스트에 포함되지 않습니다 - - 하나의 응답이 여러 줄로 나뉨: 하나의 응답 내용(문장・도구 호출)은 블록별로 다른 행에 작성됩니다. 같은 응답의 행은
message.id가 같습니다. 응답 수나 토큰 수를 셀 때는message.id로 묶어서 계산해야 합니다 - - 사고 과정 내용은 남지 않음: 사고(Thinking) 블록은 대화 로그에는 서명만 남아 내용이 비어 있습니다 -
- 되감기 시 분기됨:
/rewind로 되돌리거나 응답 전에 Esc로 취소하면parentUuid의 연결이 분기됩니다. 이 기사 스크립트는 모든 행을 읽기 때문에, 되돌린 후에는 벗어난 가지에서 읽은 파일도 나옵니다 - - 작업 중인 행이 있음: Claude Code가 작동하는 동안 마지막 행은 작업 중일 수 있습니다. 추적하여 읽으려면 개행까지 도달한 행만 읽습니다
보너스: 이 방식으로 파일 트리에 표시를 합니다
Claude Code의 작업을 옆에서 확인하는 macOS 앱인 'tanacode'를 만들고 있습니다. tanacode의 파일 트리에서는 현재 대화에서 Claude가 읽은 파일에는 파란색, 쓴 파일에는 주황색 점을 찍습니다. 압축되어 요약으로 대체된 파일도 구분하여 표시합니다.
이 표시는 이 기사의 스크립트와 거의 같은 규칙으로 적용됩니다 (src/main/knowledge-tracker.ts).
본문의 대화 로그 행을 한 줄씩 받아와서, Read, Edit, Write 등의 호출과 파일 첨부 내용을 봅니다. - 서브 에이전트의 행(isSidechain)은 세지 않습니다. - 작성한 흔적은 나중에 다시 읽어도 남깁니다.
- 압축 경계(
compact_boundary)에서는 그전까지의 흔적을 '요약으로 대체됨'으로 만듭니다.
다른 점은, jsonl 파일을 처음부터 읽는 것이 아니라, fs.watch로 추적하여 늘어난 행만 읽는다는 것입니다.
채팅 자체도 터미널 화면이 아니라, 이 대화 로그로부터 구성됩니다. 채팅에서는 되감기(rewind)로 분기된 경우 parentUuid의 연결을 보고, 벗어난 가지의 행은 버립니다.
대화 로그 행 읽는 데 익숙해지면, Claude Code 내부에서 무슨 일이 일어나고 있는지 상당히 파악할 수 있게 됩니다.

브라우저에서 작동하는 데모에서는 파일 트리에도 흔적이 보입니다('Claude가 아는 범위' 장).
맺음말
대화 로그는 Claude Code가 무엇을 보고, 무엇을 했는지에 대한 기록입니다. 'Claude가 이 파일을 읽었는지'가 궁금하다면, jsonl을 jq로 들여다보면 답을 찾을 수 있습니다.
토론

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기