跳到正文
Hacker News· ilkerguldali·· 5 天前AI 评分30

社区工具 claude-migrate:切换账号后恢复 Claude Code Desktop 会话

Show HN: Recover Claude Code Desktop sessions after switching accounts

AI 导读

非官方社区工具 claude-migrate 可将 Claude Desktop 的 Code 会话侧边栏记录从旧账号迁移到同一台 Mac 上的新账号,切换账号后消失的会话重新出现在侧边栏。

正文 · AI 翻译

claude-migrate mascot: a hermit crab leaving a small cracked shell for a bigger one, carrying a stack of terminal sessions with a pushpin

非官方社区工具。与 Anthropic 无关联,也未获其认可。

CI Release Go version License Platform

将你的 Claude Desktop Code 会话迁移到同一台 Mac 上的另一个账户,让侧边栏重新显示它们。

当你切换 Claude 账户(例如从个人版切换到 Team 版)时,Claude Desktop 中的 Code 标签页会变成空的。并没有任何东西被删除:根据在 Claude Desktop(2026 年 10 月)中的观察,它为每个账户和组织各保留一个侧边栏存储,并且只读取你当前登录账户的存储。claude-migrate 会将会话记录从旧账户的存储复制到新账户的存储,保留它们的 ID(因此置顶会一并保留),清除属于旧账户的链接,并且绝不触碰转录内容或现有文件。

工作原理

一个 Desktop Code 会话由两部分组成。其中只有一部分与账户绑定。此处描述的 Desktop 存储基于在 Claude Desktop(2026 年 10 月)中的观察;它没有文档记录,且可能发生变化。

flowchart LR
    subgraph shared["Account-independent"]
        T["~/.claude/projects/#lt;project#gt;/#lt;session#gt;.jsonl<br/>transcript: the conversation"]
    end
    subgraph old["Old account store"]
        R1["claude-code-sessions/#lt;acct#gt;/#lt;org#gt;/local_#lt;id#gt;.json<br/>sidebar record"]
    end
    subgraph new["New account store"]
        R2["claude-code-sessions/#lt;acct#gt;/#lt;org#gt;/local_#lt;id#gt;.json<br/>sidebar record"]
    end
    R1 -- "claude-migrate copies<br/>(same file name and ID)" --> R2
    R1 -. points to .-> T
    R2 -. points to .-> T

加载中

  • 转录内容由所有账户共享。无论谁登录,claude --resume 都能看到它。
  • 侧边栏记录存放在一个 <account>/<org> 文件夹中。这就是切换后“消失”的东西。
  • claude-migrate 只复制记录。转录内容绝不会被读取内容、移动或修改。

功能

  • 在账户/组织存储之间复制侧边栏记录,保留每个无需更改字段的 JSON 值,包括未知字段。
  • 保留会话 ID,因此置顶会一并保留:根据观察,Desktop 维护一个以会话 ID 为键的全局置顶列表,由所有账户共享。
  • 默认试运行。apply 仅做增量添加,绝不覆盖文件。
  • 每次写入之前都会先记录到清单中;undo 只删除某次运行所创建的内容,且仅当这些文件未被更改时才会删除。
  • 在 Claude Desktop 运行时拒绝写入,并将目标账户与 Desktop 上次使用的账户进行交叉核对。
  • 跳过转录内容已丢失的会话(它们打开后会是空的);--include-orphans 仍会复制它们。
  • 绝不恢复你在目标账户中删除的会话:根据观察,Desktop 会留下一个 deleted_<id> 标记,而在保留 ID 的情况下,该标记指向同一个会话。
  • 遇到无法识别的文件夹布局时安全失败。
  • 除 version 外,每条命令都输出机器可读的 --json。仅使用标准库,无网络访问。

安装

Homebrew cask:

brew install --cask onlyilkr/tap/claude-migrate

该二进制文件未签名或未公证,因此 cask 会在安装时移除其 macOS 隔离标志;否则 Gatekeeper 会拒绝运行它。如果你不希望由 cask 来做这件事,请使用 go install(在你的 Mac 上构建,无需变通方法):

go install github.com/onlyilkr/claude-migrate/cmd/claude-migrate@latest

或者从 releases 页面 下载发布版二进制文件(darwin/arm64 或 darwin/amd64),并对照已发布的校验和进行验证:

shasum -a 256 -c --ignore-missing checksums.txt   # run next to the downloaded archive

快速开始

  1. 先在 Claude Desktop 中登录新账户一次,使其存储存在。然后用 Cmd+Q 完全退出 Desktop。
  2. 打开终端并在其中运行该工具。不要从 Desktop 自带的 Code 标签页运行它:退出 Desktop 会结束该会话,而且该工具在 Desktop 运行时拒绝写入。
  3. Preview. Nothing is written:
    claude-migrate            # same as: claude-migrate plan
    With several candidate stores, run claude-migrate doctor to list them.
  4. Apply, using the command the plan printed:
    claude-migrate apply --from 1a2b3c4d/5e6f7a8b
  5. 打开 Claude Desktop。这些会话会出现在新账户的侧边栏中,已置顶的会话仍然处于置顶状态。

改变主意了?claude-migrate undo 只删除上次运行所创建的文件。

命令

命令 作用 是否写入?
claude-migrate / plan 显示将复制哪些内容以及哪些需要手动跟进。当只有一个候选来源时会自动为你选择;否则在 TTY 上询问。 否
apply --from X 复制记录并将清单写入 ~/.claude-migrate/runs/。--from 为必需项。 是
undo [manifest] 删除某次运行创建的文件(默认是最近一次运行),跳过自那以后你改动过的任何文件。不带路径时它会拒绝执行,而不是在较新的运行文件无法读取时去挑一个更早的运行。 是(删除)
pins 列出正在被复制或已在目标中的固定源会话(被跳过的会话,无论是没有记录、已删除还是名称冲突,都不列出),每个以 pinned in target、copied under a different ID; pin it again in Desktop 或 not migrated yet 表示。 否
doctor Desktop 状态、已登录账户、Desktop 上次是否使用同一账户、存储、cleanupPeriodDays。 否
version 打印版本。 否
标志 适用于 含义
--from <acct>/<org> plan、apply、pins 源存储。唯一前缀可用(1a2b3c4d/5e6f7a8b)。
--to <acct>/<org> plan、apply、pins 目标存储。默认为 Claude Code 已登录的账户(~/.claude.json)。传入它会跳过 Desktop 账户交叉检查。
--include-orphans plan、apply 也复制记录缺失的会话。它们在 Desktop 中会以空内容打开。
--force undo 也删除自该次运行以来改动过的文件。不绕过其他任何保护。
--json 除 version 外全部 机器可读输出。

退出码

代码 含义
0 正常
1 错误(I/O 失败、撤销不完整)
2 用法错误:错误的标志、无法解析或有歧义的存储、源等于目标、没有已登录账户、无法读取或解析的 ~/.claude.json、清单路径不存在的 undo、在没有运行或较新的运行文件无法读取时未带路径的 undo,或账户不匹配的 apply(见下文)
3 Claude Desktop 正在运行,或无法检查(SSH 会话)
4 无法识别的 Desktop 文件夹布局,或目标存储不存在

复制记录中会改变的内容

字段 结果
bridgeSessionIds 清空。这些是旧账户的云会话 ID。
scheduledTaskId 移除。它指向旧账户的一个任务。
sessionId 和文件名 保留。副本与源具有相同的 local_<id>.json 名称。
其他所有内容 值保留:每个字段的原始 JSON 逐字保留(键会重新排序并重新缩进),包括本工具不了解的字段。

未知字段绝不会阻止运行;plan 会列出它们以供参考。

安全模型

  • 默认试运行。只有 apply 和 undo 会写入。
  • 仅追加。副本会写入一个唯一的临时文件,并用 link(2) 发布,如果名称已存在则会原子性地失败,因此即使存在竞争也绝不会覆盖。如果写入在其清单条目之后失败,该条目会被撤回,这样 undo 就不会把该路径上的任何东西当作我们的。如果目标中已存在同名但属于不同会话的文件,或存在同名但不是常规文件的条目(符号链接或文件夹),该记录会被跳过并报告(name_conflicts)。
  • 先写清单再写入。每个文件在写入之前都会(连同其 SHA-256)记录并 fsync 到运行日志,因此崩溃不会留下未记录的文件。
  • 哈希校验的撤销。undo 只删除清单中列出的、位于目标存储内、且哈希仍然匹配的文件。手工编辑的清单无法让它指向别处。较新的运行再次记录的文件(相同路径、相同保留 ID)属于那次运行:撤销较旧的运行会保留它并报告为 superseded(“为较新的运行保留”)。无法读取的较新运行会被列出,因为它们不保护任何东西。
  • Desktop 防护。apply 和 undo 在 Desktop 运行时拒绝执行。该检查会向 Launch Services 询问当前 GUI 登录会话,因此请在 Mac 本机的终端中运行该工具;通过 SSH 时它看不到 Desktop 并会拒绝(退出码 3)。使用 --home 时,只要目标按文件标识属于你真实主目录下的存储(包括符号链接、.、大小写变体),该防护仍然适用。
  • 账户交叉校验。Claude Desktop 会在 config.json 中记录它上次使用的账户。如果你不传入 --to,而该账户与 ~/.claude.json 中的账户不同,apply 会停止(退出码 2),并且 plan/pins 会在 stderr 上打印警告。传入 --to <account>/<org> 可显式选择。
  • 失败即关闭。陌生的文件夹布局、缺失的目标存储或格式错误的账户 ID 都会让运行停止,而不是进行猜测。该工具从不创建目标存储。

限制

  • 仅限 macOS。
  • 仅限本地 Desktop Code 会话。云会话、Cowork 会话以及 claude.ai 聊天、Projects、artifacts 和 memory 都位于 Anthropic 的服务器或其他存储中,不在范围内。
  • 计划任务只会被报告,不会被移动:请在目标账户中重新创建它们。
  • cwd 位于旧账户暂存文件夹内的会话,仅在该文件夹存在时才能继续工作;不要删除它。
  • 早于 cleanupPeriodDays(默认 30 天)的对话记录会被 Claude Code 删除。当该设置缺失时,plan 会发出警告。
  • 它依赖未公开的 Desktop 文件,因此 Desktop 更新可能会使其失效。更新后请运行 doctor,并预期会出现失败即关闭的行为,而不是静默损坏。

故障排除

我在新账户中删除的会话没有被再次复制。这是设计使然:目标的 deleted_<id> 标记会被尊重,计划会将其列为“已在目标中删除”。如果某个会话被旧版工具以不同的 ID 复制,随后又被你删除,则无法通过这种方式匹配,因为其标记指向的是另一个 ID。

账户交叉校验没有发现错误的组织。Desktop 的 config.json 只记录最后一个账户(lastKnownAccountUuid),不记录组织。如果一个账户有多个组织,请检查 plan 的 Target: 行,或传入 --to <account>/<org>。

之后我可以从旧账户中删除这些会话吗?请等到你在新账户中打开过几个已迁移的会话之后再说。两份副本共享相同的会话 ID 和对话记录,而 Desktop 在删除其中一份副本时如何处理共享状态并未公开。

运行 apply 后侧边栏仍然是空的。据观察,Desktop 会在退出时将其内存中的列表写回。请用 Cmd+Q 完全退出(而不只是关闭窗口),重新启动,并确保你已登录到目标账户。

~/.claude.json is signed in to account … but Claude Desktop last used account …。两者对哪个账户是当前账户意见不一致。检查 claude-migrate doctor,然后为你实际想要的存储传入 --to <account>/<org>。

“no transcript (skipped)”并不等于零。这些记录指向的对话记录已不在 ~/.claude/projects 中(通常是被 cleanupPeriodDays 移除的)。在 Desktop 中它们会以空内容打开。可以用 --include-orphans 照常复制它们,或者将它们留下。

固定(pin)是如何工作的?据在 Claude Desktop(2026 年 10 月)中观察,固定项以 local_<id> 值的单一列表形式存储在 claude_desktop_config.json 中,由所有账户共享。由于副本保留其 ID,它一出现就会被固定。该工具会读取该列表(只读)来判断哪些源会话被固定;只有当该列表无法读取时,记录自身的 isStarred 标志才作为回退。claude-migrate pins 会将每个被固定的源会话显示为 pinned in target 或 not migrated yet。如果某个会话被旧版工具以新 ID 复制,而你之后又固定了该副本,则它计为 pinned in target,否则计为 copied under a different ID; pin it again in Desktop;plan 在其固定后续行中只计入后者。

某条记录因名称冲突而被跳过。目标中已存在一个同名文件,但对应的是不同的会话。该文件保持原样,并会在计划中列出。

在副本上试用

要在不触碰真实 Desktop 数据的情况下查看运行效果,请构建一个布局类似主目录的暂存目录,并将 --home 指向它:

SCRATCH=$(mktemp -d)
mkdir -p "$SCRATCH/Library/Application Support/Claude"
cp -R ~/Library/Application\ Support/Claude/claude-code-sessions "$SCRATCH/Library/Application Support/Claude/"
cp ~/Library/Application\ Support/Claude/config.json "$SCRATCH/Library/Application Support/Claude/"  # enables the account cross-check
# Copy only the pin list (jq ships with macOS 15+): the full claude_desktop_config.json can hold MCP server secrets.
jq '{preferences:{epitaxyPrefs:{"starred-local-code-sessions":.preferences.epitaxyPrefs["starred-local-code-sessions"]}}}' \
  ~/Library/Application\ Support/Claude/claude_desktop_config.json > "$SCRATCH/Library/Application Support/Claude/claude_desktop_config.json"
cp ~/.claude.json "$SCRATCH/"
claude-migrate plan --home "$SCRATCH" --include-orphans
claude-migrate apply --home "$SCRATCH" --from <old-account>/<old-org> --include-orphans
claude-migrate undo --home "$SCRATCH"

对于不属于你的主目录,会跳过 Desktop 检查,并且不会触碰 scratch 目录之外的任何内容。~/.claude/projects 无需复制;--include-orphans 代表你省略的转录记录。完成后删除 scratch 目录:~/.claude.json 的副本包含你的账户详细信息。--home 是一个对 claude-migrate help 隐藏的测试标志。

替代方案

其他涉及同一问题领域的社区项目(均与本项目无关联)。描述概括了各项目截至 2026 年 10 月的 README 内容:

工具 功能
claude-code-export-import 在机器、账户和应用构建之间导出和导入 Claude Code 会话;重写转录记录。
transfer-claude-sessions 通过试运行、备份和撤销,将 Desktop 会话复制到新账户;Windows PowerShell。
claude-session-migrate Claude Code 技能和脚本,可将 Desktop 侧边栏记录复制到新账户;面向 Windows,先备份 sessions 文件夹。
claude-account-migration 说明 Desktop 将会话保存在何处以及为何切换会隐藏它们,并附有辅助脚本;macOS 和 Windows。
cowork-migrate 在 Mac 之间迁移 Cowork 会话。
claude-folder-move 当项目文件夹移动时,重新定位 Claude Code 会话。

开发

make check      # test (race), vet, gofmt check, staticcheck
make build      # bin/claude-migrate
make snapshot   # local GoReleaser build, nothing published

有关 TDD 工作流和 fixture 规则,请参阅 CONTRIBUTING.md。若要从你自己的存储中添加回归 fixture 而不泄露数据,请使用 go run ./scripts/anonymize -src <store dir> -out <dir>,并用 CONTRIBUTING.md 中描述的隐私 grep 检查输出。

贡献与安全

欢迎贡献;请先阅读 CONTRIBUTING.md。请按 SECURITY.md 中所述私下报告漏洞,不要公开提交 issue。发布说明见 CHANGELOG.md。

许可证

MIT

来源:Hacker News · github.com