恢复项目
当会话开启时,之前会话中的重要信息分散在多个地方。这个技能提供了回归之路:它收集这些信息,与最近可用数据进行核对,并以简短几行告知用户,让他们无需记忆任何内容即可决定今天的工作内容。
其工作方式由四个方面决定:
- 只读。 不写入任何文件、笔记、数据库或记忆。因此,它不需要为每一步请求许可:读取不会改变任何东西。将用户计算机中的文件复制到会话中阅读算作读取。唯一的写入操作是
git fetch --prune,且仅在references/claude-code.md指定时执行。将会话访问权限授予新仓库不仅仅是读取:不要自行操作(参见步骤 0 中的 GitHub 行)。其他插件的钩子可能会在会话开启时写入(合并记忆、保存日志):这不是本技能在写入,无需提及,除非它改变了你即将读取的来源。 - 读取文件,不启动工作流。 许多技能在启动时会写入遥测数据或状态、创建文件夹、要求自己的输出格式或以自己的问题结束。当你知道某个技能的数据存储位置时,直接读取该文件。仅在没有其他方法时才启动该技能,并且在那种情况下,获取其数据,跳过其最终问题及其格式,并停止任何会写入的步骤。
- 项目指令优先。 如果项目指令、
CLAUDE.md或用户的偏好指明了状态存储位置、可读取的文件夹、冲突解决方式或每日计划方式,则优先于本技能。 - 以提问和交接结束。 会话结束技能(例如 wrap-up)以说明会话可以归档结束;本技能以询问今天要做什么并将答案传递至步骤 6 结束。
0. 清单:你实际可以读取的内容
不要根据环境名称选择来源。相同的会话可以同时在云端、claude.ai 项目内部并与用户的计算机连接。在读取任何内容之前,查看会话拥有的工具(包括延迟工具,通过搜索来发现),并记录哪些能力存在:
| 能力 | 如何识别 | 其开启的来源 |
|---|---|---|
| 仓库中的终端 | 工作文件夹是用户的某个仓库,或者在其计算机上有一个终端(device_bash 或类似工具)且仓库位于连接的文件夹中 | Git 和远程 (C),以及 references/claude-code.md |
| 无终端的计算机文件 | 用于列出和复制计算机中文件的工具,没有终端 | 仓库 (D)、会话日志(B,如果设置写入的话)和移交记录(E,如果它们位于连接的文件夹中),以及其文件夹已连接的仓库的 CLAUDE.md(D)。不包含本地 Git |
| 无仓库终端的 GitHub | 会话中安装了 gh,或有工具可将仓库添加到会话 | 远程上的拉取请求、分支和提交 (C2) |
| 项目管理器 | 一个 Notion 连接器或其他项目管理器,加上说明某个数据库或页面保存了项目的指令或 CLAUDE.md | 状态、下一步行动和任务 (A) |
| 之前的聊天记录 | 用于搜索或列出聊天记录的工具 | 聊天记录 (F),以及 references/claude-ai.md |
| Claude Code 会话 | 用于列出或搜索桌面应用会话的工具(list_sessions、search_session_transcripts、list_events 或类似工具) | 之前的会话 (F2),以及 references/claude-code.md |
| 已发布的制品 | 用于列出已发布制品、页面或文档的工具(Artifact 带有 list,或类似工具) | 仓库外部的交付物 (I) |
| 记忆 | 上下文中的记忆,或记忆工具 | 记忆 (G) |
| claude.ai 项目 | 上下文中的项目指令或文件,或项目工具 | 指令和文件 (H) |
参考文献提供了 Git(references/claude-code.md)、claude.ai 聊天记录(references/claude-ai.md)以及由钩子写入的每个项目会话日志(references/session-log.md)的详细信息。仅读取你拥有的能力所开启的那个,并且仅当设置写入此类日志时才读取 session-log.md。如果某参考文献说某物不存在(仓库、磁盘、Git)而清单说它存在,则以清单为准。如果参考文献缺失,则继续使用此文件中的内容。
如果会话有许多延迟工具,不要全部加载它们来进行清单:搜索表格中的词语(notion、session、transcript、chat、memory、project、repository、artifact),并仅加载你将使用的那些工具的 schema。gh 不是会话工具而是一个程序:使用 gh auth status 检查。如果延迟工具的名称已在上下文中可见,则从该列表中选择并仅加载它们,无需搜索。
此文件中的来源字母(A 到 I)不与 claude-code.md 的字母(A 到 H)相同:此处的 E 是移交记录,而该参考文献中的 E 是 CLAUDE.md。当此文件引用 claude-code.md 的某个类别时,会通过名称引用;根据名称而非字母进行查找。
允许的文件夹。 仅读取用户已连接到会话的文件夹,或他们的指令允许你读取的、且会话确实可以访问的文件夹。不要为了恢复而请求访问其中任何一个。将所有不可达的内容放入一个单独的“提醒”行:
- 已连接文件夹外部的有用来源(例如,在没有终端的会话中,主文件夹中的
~/.gstack); - 指令允许你读取但未连接的文件夹(例如项目自己的文件夹)。如果它属于某个出现在摘要中的项目,则添加说明:关于该项目的所有已知信息就是项目管理器所说的内容。
1. 是哪个项目
- 一个仓库、一个文件夹或一个名称。 如果会话位于一个仓库中,那就是项目。如果用户命名了项目,则在项目管理器(A)和仓库(D)中查找它,不区分大小写,并尝试记忆给出的别名:名称可能不匹配,并且项目可能正在重命名过程中。
- 一个总括项目。 如果上下文是一个包含多个项目的空间(一个组织所有工作的 claude.ai 项目、一个带有项目数据库的项目管理器、一个包含多个文件夹的仓库),并且用户没有命名一个项目,不要静默选择。用那些最近有活动的项目以及指令标记为短期优先级的项目编写一个多项目摘要(步骤 4)。
- 用户视为当然的事情。 如果开启消息断言了一个状态(未完成的 Git 操作、分支、PR、部署),一旦你读取了来源,立即对其进行核对:快速 Git 快照、GitHub,或者如果有会话日志,则核对会话日志。如果不匹配,在摘要之前用一行说明每个来源的说法。如果它命名的内容属于另一个项目(另一个文件夹、仓库或笔记),则在进一步读取之前询问正在恢复的是哪一个;在没有用户的会话中,继续使用工作文件夹的项目,并在摘要顶部说明。
- 没有可恢复的内容。 没有笔记、日志、聊天记录或提交:用一句话说明,然后转到步骤 6,处理用户想做的任何事情。
同一项目如何跨来源匹配
项目管理器、仓库,以及如果有会话日志,它们各自以不同的方式命名项目。通过以下键进行匹配,而不是仅凭名称,按此顺序:
- 路径。 如果设置写入了会话日志,则将其路径与仓库笔记(D)的 frontmatter 中的
path:字段进行匹配,如references/session-log.md中“按路径匹配”所述。 - 项目管理器链接。 指向笔记的项目管理器字段(例如,在 Notion 中,一个“Obsidian 笔记”字段),对照笔记的文件夹。
- 名称。 不区分大小写,并使用记忆中的别名。
如果项目管理器中的某个项目没有链接其笔记但笔记存在(通过路径或名称匹配),则在“提醒”中用一行说明。
2. 来源,按读取顺序
首先读取那些告诉你每条笔记价值多少的信息(实际发生了什么以及何时发生),然后读取告诉你下一步是什么的信息,最后是为什么。
B. 会话日志,可选。 如果设置写入了一个,则遵循 references/session-log.md。
C. Git 和远程。 仅在仓库中有终端时使用。遵循 references/claude-code.md 中的“快速 Git 快照”和“Git 与远程的实际状态”类别。
C2. 无终端的 GitHub。 用于确认本地来源无法知道的信息:分支是否已推送、是否有拉取请求以及是否已合并。从项目的仓库笔记(url: 字段或 github.com/... 行)、CLAUDE.md 或会话日志的 Merge pull request #N from <owner>/... 提交中获取 owner/repository。
- 首先通过读取检查会话是否已有访问权限:
gh api "repos/<owner>/<repo>/pulls?state=all&sort=updated&direction=desc&per_page=10"。使用 REST API(gh api repos/...):gh pr list可能因为 GraphQL 并非始终可用而失败。每个 PR 都有created_at和merged_at:合并时间由merged_at给出,而不是创建日期。 - 如果响应成功,也读取分支(
repos/<owner>/<repo>/branches)和主分支上的最新提交(repos/<owner>/<repo>/commits?per_page=5)。这样,另一个来源命名的未合并分支将变为“有打开的 PR #N”、“已合并”或“未在远程上”。 - 同时读取主分支的 CI(
repos/<owner>/<repo>/actions/runs?branch=<main>&per_page=1)。如果上次运行失败,则放入“待处理”;如果通过,则不提及;如果根本没有运行(仓库没有 CI),也不提及。 - 如果响应表明仓库未对会话启用,不要自行添加:授予仓库访问权限不仅仅是读取。在“提醒”中注明,并在步骤 5(“在 GitHub 上确认”)中将其作为选项提供。在没有用户的会话中,跳过。
A. 项目管理器。 如果指令说明状态、优先级或下一步行动存储在项目管理器(Notion 或其他)中,则读取它:这是下一步行动信息来源。从指令或 CLAUDE.md 中获取数据库地址;如果你已经有了,不要按名称搜索它。
- 在 Notion 中:获取数据库 schema 并查询包含其链接(
url)、名称、领域或分支、状态、优先级、关键日期、下一步行动和笔记的行。 - 已归档。 移除 Notion 已归档的行,并且如果数据库也有自己的复选框或状态(例如“已归档”复选框或“已关闭”状态),也移除那些设置了该状态的行。
- 编辑日期。 查询不返回最后编辑日期。打开你将要与另一个来源核对的行,并且在总括项目中,也打开指令标记为短期优先级的项目,即使它们没有日志或笔记:这样没有代码的项目也可以进入“你离开的地方”。
- 批量编辑。 如果同一数据库中的多个页面编辑日期相差几秒钟,则是一次性对所有页面进行的更改(新字段、导入、模板),而不是对这些项目的工作。不要将该日期用作活动:将这些项目保留为无日期,除非另一个来源给了它们一个日期。
- 任务。 如果指令命名了一个任务数据库,获取其 schema 并查询过期或在未来七天内到期的未完成任务。只有出现在摘要中的项目的任务才计入:暂停、关闭或摘要外项目的任务即使过期也不算作待处理。它们放在各自项目条目下的“待处理”中,并附上日期。对于没有下一步行动的优先级项目,也查询其没有日期过滤器的开放任务(见下文)。
- 没有项目的任务。 它们不放入“待处理”。但如果某个任务匹配了一个“提醒”警告(例如,当项目没有链接其自己的笔记时,链接笔记的任务),则在该警告中命名该任务,而不是将其呈现为一个新发现。
- 没有下一步行动的行不是待处理项:不要编造一个。如果项目是优先级项目,则将其放入“待处理”作为“无下一步行动”。如果它有开放任务,无论有无日期,命名第一个(日期最近的,或第一个无日期的):“无下一步行动;开放任务:<任务>”。这是项目管理器的数据,不是建议。优先级 指指令标记为短期优先级的项目,加上其长期优先级中的第一个;如果指令没有设置优先级,则为项目管理器中的最高优先级。当指令设置了其他优先级时,项目管理器说“高”是不够的。
- 如果它们放不下。 “待处理”最多有五个项目。如果有更多项目要包括,短期项目以及有下一步行动或未完成事项的项目优先放入;只会添加“无下一步行动”的优先级项目则合并为一行“提醒”:“无下一步行动:X、Y 和 Z”。
- 如果项目管理器的状态明显与另一个更新的来源相矛盾(例如,项目管理器中是“构思”而仓库笔记中有已完成的工作),则在“提醒”中说明,并附上两个日期。
D. Obsidian 仓库。 项目笔记,位于仓库的项目文件夹中(指令或 CLAUDE.md 通常会说明是哪个;例如,在 PARA 风格的仓库中,2 Projects/<project>/),以及其 updated: 字段。其 path: 字段(如果有)是匹配它的一个键(参见步骤 1)。读取标题和最新条目,而不是整个笔记。读取它不需要技能。在 Claude Code 中,参考文献说明了何时启动仓库技能以及何时不启动。
- 仓库的
CLAUDE.md。 如果可以访问(终端,或仓库文件夹已连接),其状态和待处理部分(“当前状态”、“待处理”)是本地可用的最可靠的待处理列表;仅读取这些部分。有了终端,请遵循...