Time Machine: 모든 도구 호출을 담는 Claude Code 타임라인
모든 도구 호출을 분기 가능한 타임라인으로 기록하고, 섀도 git 스냅샷으로 비교·복원·분기·재실행합니다.
권한
- 파일 읽기컴퓨터의 파일을 읽고 디렉터리 목록을 볼 수 있습니다($.fs.read / list / stat / exists).
- 파일 쓰기컴퓨터에 파일을 만들거나 덮어쓸 수 있습니다($.fs.write).
- 명령어 실행컴퓨터에서 셸 프로그램을 실행할 수 있습니다($.process.run / spawn). 정확히 어떤 프로그램인지는 소스를 확인하세요.
- 도구 호출 가로채기Claude가 하는 모든 도구 호출을 볼 수 있고(tool.call / tool.check), 이를 차단하거나 변경할 수 있습니다.
- 프롬프트 읽기입력한 내용과 대화 기록을 볼 수 있습니다(prompt.* / session.append / session.messages).
- UI 변경Claude Code 화면에 밴드, 패널, 상태 텍스트, 토스트를 그립니다(ui.render / $.ui.*).
- 명령어/도구 추가사용자나 Claude가 호출할 수 있는 새 슬래시 명령어나 도구를 등록합니다($.command.register / $.tool.register).
- 데이터 저장플러그인 전용 저장소에 세션 간 데이터를 보관합니다($.store.*).
- 테스트 버전
- v2.1.303
- 마지막 테스트
- 필요 버전
- Claude Code ≥ 2.1.287
- 표시 위치
- 상태 표시줄, 패널
Claude Code 안에서 설치:
/plugin install time-machine --marketplace YeonwooSung/my-claude-code-mods이 모드는 무엇을 하나요?
Time Machine은 YeonwooSung(my-claude-code-mods)이 만든 커뮤니티 모드로, 각 Claude Code 세션에 Claude Code 타임라인을 제공합니다. 에이전트가 여러 파일을 고쳤는데 엉뚱한 상태가 되었을 때, git diff는 무엇이 바뀌었는지만 알려 줍니다. Time Machine은 어떤 도구 호출이 어떤 순서로 실행되었고 그 뒤 파일이 어떤 모습이었는지를 기록하므로, 어느 단계로든 돌아갈 수 있습니다.
모든 기능은 /tm 명령 하나로 사용합니다. /tm은 타임라인을 그리고, /tm show <n>은 한 단계를 보여 주며, /tm diff <a> [b]는 두 단계 시점의 파일을 비교하고, /tm why는 실패한 테스트 실행의 원인일 가능성이 높은 수정을 나열합니다. /tm restore <n>과 /tm branch <n>은 파일을 그 단계의 상태로 되돌리고, /tm compare는 두 브랜치나 세션을 비교하며, /tm rerun <n>은 한 단계를 다시 실행하고, /tm sessions는 기록된 세션을 나열합니다. /tm-pane은 실시간 타임라인 패널을 열고, 상태 표시줄에는 tm ② · 1 snaps · 79ms 같은 내용이 나타납니다.
파일을 복원하고 도구를 다시 실행할 뿐, 모델의 답변을 재생하지 않으며 대화를 되돌리지도 않습니다.
데모
녹화에서는 작은 데모 프로젝트에서 이 모드를 불러온 Claude Code를 시작하고, 저장 폴더를 임시 폴더로 지정합니다. Claude에게 프로젝트를 한 줄로 설명하는 NOTES.md를 만들어 달라고 요청합니다. Claude가 README.md를 읽고 파일을 쓰는 동안 상태 표시줄이 tm ⓪에서 tm ②로 올라가고 1 snaps가 표시됩니다. 이어서 /tm을 입력하면 타임라인에 베이스라인 스냅샷(파일 5개), ① Read README.md, 그리고 자체 스냅샷이 있는 ② Write NOTES.md가 나열되며, A NOTES.md는 추가된 파일을 뜻합니다.
설치
설치 블록의 방법 중 아무것이나 사용하세요. 모두 작성자 본인의 마켓플레이스에서 바로 설치합니다. 모드는 다음 세션부터 동작하며, /tm은 세션 시작 시 등록됩니다.
$ install time-machine
Claude Code 2.1.287 이상 필요
작성자의 마켓플레이스에서 설치: YeonwooSung/my-claude-code-mods
1.Claude Code 안에서 한 줄로
/plugin install time-machine --marketplace YeonwooSung/my-claude-code-mods실행 중인 세션(v2.1.275 이상)에 붙여 넣으세요. Claude Code가 먼저 마켓플레이스 추가 여부를 묻습니다.
2.셸에서 설치
claude plugin marketplace add YeonwooSung/my-claude-code-mods claude plugin install time-machine@my-claude-code-mods그런 다음 이미 열려 있는 세션에서 /reload-plugins를 실행하세요.
3.설치하지 않고 사용해 보기
git clone https://github.com/YeonwooSung/my-claude-code-mods claude --plugin-dir ./my-claude-code-mods/time-machine한 세션에서만 모드를 불러옵니다. 설정에는 아무것도 추가되지 않습니다.
작동 방식
tool.call이 있을 때마다 한 단계를 기록합니다. 파일을 바꾸는 도구(편집, 쓰기, 기본적으로 모든 Bash 호출, 알 수 없는 도구와 MCP 도구) 뒤에는 자체 인덱스를 사용해 작업 트리를 자신의 저장 폴더에 있는 베어 "섀도" 저장소에 커밋하므로 사용자의 .git은 읽거나 쓰지 않습니다. 도구가 실행되기 전에 작업 트리가 마지막 스냅샷 이후 바뀌어 있으면(예: IDE에서 파일을 고친 경우) 에이전트 탓으로 돌리지 않고 external 단계로 기록합니다. 파일을 바꾸는 명령의 보호 로직은 다음과 같으며 hooks/register.tsx에서 가져왔습니다.
// Origins a person typed: the only ones allowed to change files or run commands through /tm.
const TYPED = new Set(['composer', 'bridge', 'sdk'])
const sub = changesFiles(args)
const kind = e.origin?.kind ?? 'unknown'
if (sub !== undefined && !TYPED.has(kind)) return { text: `time-machine: ${sub} changes files or runs commands and only runs when you type it (this came from ${kind})` }/tm why는 증명이 아니라 추정입니다. 실패한 실행 이전에 같은 테스트 명령이 마지막으로 통과한 실행을 기준으로 삼아, 그 사이에 바뀐 각 파일에 점수를 매기며, 실패 출력에 해당 경로가 나올수록 점수가 높습니다. 테스트 출력은 pytest, jest와 vitest, go, cargo, node:test 형식을 해석하고, 그 밖의 출력은 종료 상태만 사용합니다.
사용자 지정
플러그인 설정에는 네 가지 옵션이 있습니다.
storeDir: 스냅샷과 타임라인이 저장되는 위치로, 프로젝트마다 폴더 하나입니다. 절대 경로이거나~/로 시작해야 하고 프로젝트 밖에 있어야 하며, 그렇지 않으면 스냅샷이 꺼집니다. 기본값은~/.claude/time-machine입니다.retentionDays: 이 일수보다 오래된 세션을 삭제하며, 확인은 하루에 최대 한 번입니다. 기본값은 14이고0이면 모두 보관합니다.recordModelOutput: 기본값은 꺼짐입니다. 켜면 모델의 응답 텍스트와 각 프롬프트의 앞 200자를 저장하고, 끄면 길이와 해시만 저장합니다.skipSearchBash: 기본값은 꺼짐입니다. 켜면 검색으로 분류된 Bash 명령(rg,grep,ls,cat) 뒤에는 스냅샷을 찍지 않습니다.
권한 및 안전
플러그인이 불러오는 모든 파일을 읽었습니다. plugin.json, hooks/hooks.json, hooks/register.tsx, hooks/git.ts, hooks/core/의 모든 파일, 그리고 README와 테스트입니다. package.json, 설치 스크립트, 바이너리, 번들된 코드는 없습니다. fetch, http, child_process, eval, 동적 import(), WebSocket, 폭 없는 문자나 양방향 유니코드 문자를 검색했지만 아무것도 나오지 않았습니다. 눈여겨볼 점은 다음과 같습니다.
- 프로세스를 실행합니다:
$.process.run을 통해git(섀도 저장소 대상)과mkdir,rm -rf,cp,find -delete,sh를 실행합니다.rm -rf와find -delete는 저장 폴더 안의 경로로 제한됩니다(register.tsx와git.ts의isInside검사)./tm rerun --isolated --yes는 기록된 Bash 명령을 스냅샷 복사본 안에서sh -lc로 실행합니다. 샌드박스가 아니며 권한 대화상자도 거치지 않습니다. 사용자가 직접 입력했을 때만 실행되고, 프로젝트의 절대 경로가 들어 있는 명령은 거부합니다. - 파일을 씁니다: 저장 폴더(기본값
~/.claude/time-machine) 아래에 씁니다.settings.json, 셸 파일, LaunchAgents, git 훅에는 쓰지 않습니다./tm restore --yes는 프로젝트의 추적 파일을 다시 쓰지만, 사용자가 입력했을 때만, 복원 전 스냅샷을 저장한 뒤에 실행되며, 무시된 파일을 덮어쓰게 되면 거부합니다. - 작업 내용을 기록합니다: 스냅샷에는 무시되지 않은 파일의 전체 내용이 들어가므로 프로젝트에 둔 비밀 값도 포함됩니다. 도구 입력과 결과는 최선의 노력으로 마스킹되지만 스냅샷 속 파일 내용은 마스킹되지 않습니다. 저장 폴더를 공유하기 전에 확인하세요.
- 대화에 텍스트를 넣는 것은 한 번뿐입니다. 복원 후에 파일이 복원되었고 이전 도구 결과가 오래되었다는 메모를 덧붙입니다. 그 밖에는 프롬프트나 도구 결과를 고쳐 쓰지 않습니다.
- 모든 도구 호출을 감쌉니다(
.catch가 있는tool.call게이팅 훅). 거부를 포함해 답을 그대로 전달하며, 기록 오류가 도구를 막지 않습니다. 병렬로 실행되는 변경 호출은 외부 변경 검사가 끝나기를 기다립니다. - 네트워크, 데몬, 텔레메트리는 없습니다. 정리 작업은 시작 후 분리되어 실행되지만 세션과 함께 끝납니다. 읽는 환경 변수는
HOME뿐입니다. - 외부 요구 사항:
git이 설치되어 있어야 합니다. 세션 루트가 홈 폴더 또는/이면 스냅샷이 꺼집니다. - 라이선스: Apache-2.0(저장소 루트에 LICENSE 파일 있음)이며 재배포를 허용합니다.
claude plugin validate는 오류와 경고를 보고하지 않았습니다. 작성자의 테스트는 Claude Code 2.1.303에서 103개 통과, 0개 실패였습니다.
- 파일 읽기
- 컴퓨터의 파일을 읽고 디렉터리 목록을 볼 수 있습니다($.fs.read / list / stat / exists).
- 파일 쓰기
- 컴퓨터에 파일을 만들거나 덮어쓸 수 있습니다($.fs.write).
- 명령어 실행
- 컴퓨터에서 셸 프로그램을 실행할 수 있습니다($.process.run / spawn). 정확히 어떤 프로그램인지는 소스를 확인하세요.
- 도구 호출 가로채기
- Claude가 하는 모든 도구 호출을 볼 수 있고(tool.call / tool.check), 이를 차단하거나 변경할 수 있습니다.
- 프롬프트 읽기
- 입력한 내용과 대화 기록을 볼 수 있습니다(prompt.* / session.append / session.messages).
- UI 변경
- Claude Code 화면에 밴드, 패널, 상태 텍스트, 토스트를 그립니다(ui.render / $.ui.*).
- 명령어/도구 추가
- 사용자나 Claude가 호출할 수 있는 새 슬래시 명령어나 도구를 등록합니다($.command.register / $.tool.register).
- 데이터 저장
- 플러그인 전용 저장소에 세션 간 데이터를 보관합니다($.store.*).
호환성 및 문제 해결
macOS의 Claude Code 2.1.303에서 확인했습니다(validate, 작성자의 테스트, 데모 녹화). 작성자는 Claude Code 2.1.287 이상을 안내합니다. 이상이 있다면 다음을 확인하세요.
- 상태 표시줄에
snapshots off가 보임:/tm을 실행하면 맨 위에 이유가 나옵니다. 흔한 원인은 세션 루트가 홈 폴더인 경우,storeDir가 상대 경로이거나 프로젝트 안에 있는 경우,git이 없는 경우, 베이스라인 스냅샷이 5초 넘게 걸린 경우입니다. - 큰 저장소에서는 변경 도구마다 스냅샷 시간이 듭니다. 평균은 상태 표시줄에 표시됩니다.
- 프로젝트 안에서 계속 바뀌는 로그 파일이 있으면 변경 도구 앞마다
external단계가 생깁니다. - 무시된 파일(빌드 산출물,
node_modules,.env)은 스냅샷도 복원도 되지 않습니다. - 패널과 상태 표시줄은 터미널에서 보입니다. VS Code 채팅 패널에서는 명령만 동작합니다.
자주 묻는 질문
- Time Machine이 프로젝트의 .git을 건드리나요?
- 아니요. 스냅샷은 저장 폴더 아래의 별도 베어 저장소에 쌓이고, 세션마다 자체 인덱스를 가집니다. git을 호출할 때마다 환경 변수가 그 저장소로 고정되므로 사용자의 .git에는 쓰지 않습니다. 로컬 .git/info/exclude는 섀도 저장소로 복사되고 .gitignore 규칙도 적용됩니다.
- 스냅샷은 어디에 저장되고 얼마나 보관되나요?
- 기본값은 ~/.claude/time-machine이며 프로젝트마다 폴더가 하나씩 생깁니다. storeDir 옵션으로 바꿀 수 있습니다. 14일이 지난 세션은 하루에 최대 한 번 삭제되며, retentionDays를 0으로 두면 모두 보관합니다.
- Claude가 스스로 파일을 복원하거나 명령을 다시 실행할 수 있나요?
- 아니요. --yes가 붙은 restore와 branch, 그리고 --isolated 드라이런을 제외한 모든 rerun은 사용자가 직접 입력했을 때만 실행됩니다. 다른 경로에서 온 요청이면 명령이 거부되고 그 경로를 알려 줍니다. 모델이 호출할 수 있는 도구로는 노출되지 않습니다.
- 네트워크로 무언가를 보내나요?
- 확인한 범위에서는 보내지 않습니다. 플러그인에 네트워크 코드가 없고, git, mkdir, rm, cp, find, sh를 로컬에서 실행하며 자체 저장 폴더에만 씁니다.
- Claude Code의 /rewind와 무엇이 다른가요?
- 작성자는 /rewind를 대체하지 않는다고 밝힙니다. Time Machine은 Bash가 바꾼 파일도 스냅샷으로 남기고, 도구를 가로지르는 타임라인을 유지하며, 테스트 실패의 원인이 되었을 만한 수정을 추정하고, 두 실행을 비교하고, 한 단계를 다시 실행합니다. 복원하는 것은 파일뿐이며 대화는 되돌리지 않습니다.
# 관련 모드
추천Blast Radius
Claude Code가 rm -r, 강제 푸시, 마이그레이션을 실행하기 전에 멈추고, 바뀔 파일이나 커밋을 보여 준 뒤 확인을 기다립니다.
- 패널
- 프롬프트 위
- 명령어 실행
- 도구 호출 가로채기
- UI 변경
v2.1.291에서 테스트됨
추천도구 호출 카운터
Claude의 도구 호출을 턴별·세션별로 세어 스피너 옆에 표시하고, 상세 내역을 보는 /tally 명령을 추가합니다.
- 스피너
- 대화 기록
- 상태 표시줄
- 도구 호출 가로채기
- UI 변경
- 명령어/도구 추가
v2.1.310에서 테스트됨
더 보기: 타이머, 할 일, 스탠드업, 슬래시 명령.