oh-my-pi `/tree` 会话树导航命令完整指南:分支跳转、筛选搜索与摘要切换实战

发布时间:2026/9/12 18:15:46
oh-my-pi `/tree` 会话树导航命令完整指南:分支跳转、筛选搜索与摘要切换实战 oh-my-pi/tree会话树导航命令完整指南分支跳转、筛选搜索与摘要切换实战【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi/tree是 oh-my-piCoding agent with the IDE wired in内置的交互式Session Tree会话树导航器用于在当前会话文件中任意跳转并继续对话。本文以 docs/tree.md 为骨架结合packages/coding-agent下的真实源码系统讲解/tree的打开方式、树形 UI 模型、全部快捷键、五种筛选模式、搜索语义、选中节点的分支决策逻辑、摘要切换流程与标签机制并给出四个可直接上手的操作工作流。/tree是什么/tree打开交互式Session Tree 导航器让你跳到当前会话文件中的任意条目并从该点继续。这是一种文件内叶子leaf移动不会导出新会话也不会改动已有条目——现有条目从不被修改或删除只是把当前叶子重新定位。核心工作链路如下从当前会话条目构建树SessionManager.getTree()打开TreeSelectorComponent支持键盘导航、筛选与搜索选中后调用AgentSession.navigateTree(targetId, { summarize, customInstructions })按新的叶子路径重建可见对话选中用户/自定义消息时可选地预填编辑器文本。关键实现文件均在packages/coding-agent/src下slash-commands/builtin-session.ts/tree、/branch斜杠命令注册modes/controllers/input-controller.ts按键绑定接线与双 Esc 行为modes/controllers/selector-controller.ts树 UI 启动与摘要提示流程modes/components/tree-selector.ts导航、筛选、搜索、标签与渲染session/agent-session.tsnavigateTree叶子切换与可选摘要session/session-manager.tsgetTree、branch、branchWithSummary、resetLeaf、appendLabelChange与标签持久化。如何打开会话树以下任意方式都会打开同一个选择器输入斜杠命令/tree按下为app.session.treeaction 配置的按键绑定默认键位见 config/keybindings.ts。此外还有一个隐藏入口在空编辑器中双击 Esc。input-controller.ts的逻辑是编辑器中存在未完成草稿时 Esc 不会破坏草稿只有当编辑器为空且 500ms 内连续按下两次 Esc 时才触发配置的doubleEscapeActionrewind默认打开全屏 transcript 回退选择器回放 transcript、标出回退将落到的块然后对用户提示用branch()、对其他条目用navigateTree()执行回退tree直接打开会话树选择器none禁用该行为。配置项doubleEscapeAction定义于 config/settings-schema.ts可选值为rewind | tree | none。注意 config/settings.ts 中做了向后兼容迁移旧值branch会自动映射为rewind。树形 UI 模型树完全由会话条目的父子指针id/parentId渲染而来SessionManager.getTree()通过会话索引的tree()方法构建见 session-manager.ts。渲染规则子节点按时间戳升序排列包含当前叶子的分支在选择器中排在最前其他历史分支仍然可达活动分支根到叶子的路径以 bullet•标记标签以[label]形式渲染在节点文本之前缺失父节点、自引用的父节点以及显式 null 父节点都会成为根多个根共享一个虚拟分支根。示例树视图活动路径以•标记├─ user: Start task │ └─ assistant: Plan │ ├─ • user: Try approach A │ │ └─ • assistant: A result │ │ └─ • [milestone] user: Continue A │ └─ user: Try approach B │ └─ assistant: B result选择器会围绕当前选中项重新居中最多显示max(5, floor(terminalHeight / 2))行受面板边框行数限制见 tree-selector.ts。树选择器内的按键绑定按键行为Up/Down移动选择循环AltUp/AltDown跳到上/下一个 user 或 assistant 轮次Page Up/Page Down或Left/Right翻页Home/End跳到第一个/最后一个可见项Enter选中节点ShiftEnter直接摘要并切换不打开摘要选择提示Esc若有搜索词则清空搜索否则关闭选择器CtrlC关闭选择器输入字符追加到搜索查询Backspace删除搜索字符ShiftL搜索为空时编辑/清除标签CtrlO向前循环筛选模式ShiftCtrlO向后循环筛选模式AltD/T/U/L/A直接跳到某个筛选模式快捷键的源码实现集中在 tree-selector.tsctrlo/shiftctrlo在五种模式间循环altd/t/u/l/a分别直达default/no-tools/user-only/labeled-only/allshiftl在搜索为空时触发onLabelEdit。筛选模式与搜索语义初始模式来自treeFilterMode设置默认default。模式按以下顺序循环defaultno-toolsuser-onlylabeled-onlyalldefault显示对话节点以及所有未被显式抑制的条目类型。它隐藏以下设置/簿记类条目labelcustommodel_changethinking_level_change其他没有专门渲染的条目类型例如 service-tier、title、credential-pin、reset、mode 条目在当前代码中可能以空白行出现。no-tools与default相同但额外隐藏toolResult消息。user-only只显示role为user的message条目。labeled-only只显示当前解析出标签的条目。all显示会话树中的一切包括簿记/自定义条目。纯工具调用的 assistant 节点行为只包含工具调用无规范文本的 assistant 消息在所有筛选模式下都会被隐藏包括all除非满足以下任一条件消息是错误/中止状态stopReason既不是stop也不是toolUse它是当前叶子。搜索行为查询按空格分词匹配是模糊子序列且不区分大小写的fuzzyMatch由 utils 包 提供所有 token 都必须匹配AND 语义实现为searchTokens.every(token fuzzyMatch(token, nodeText).matches)见 tree-selector.ts可搜索文本包括标签、角色以及类型特定内容消息文本、分支摘要文本、自定义类型、工具命令片段等。选中节点的行为选择结果navigateTree根据选中条目的类型计算新的叶子行为。以下是源码中的完整决策逻辑agent-session.ts选中user消息新叶子变为选中条目的parentId根 user 消息将叶子重置为 root文本与图片附件会重构为可编辑草稿editorText与editorImages并行返回图片以[Image #N]位置标记对齐选择器只在编辑器当前为空时写入该草稿。源码细节newLeafId targetEntry.parentId文本由#extractUserMessageText(...)提取图片由#extractUserMessageImages(...)提取。选中custom_message普通自定义消息沿用与 user 消息相同的父叶子规则和文本预填skill-prompt自定义消息SKILL_PROMPT_MESSAGE_TYPE不可编辑选中它像其他非 user 条目一样落在该节点上。选中过去的ask工具结果这是/tree交互式选择器特有的两阶段重答协议源码注释标注为 issue #5642仅由交互式/tree选择器设置allowAskReopen交互式/tree重新打开原始问题 UI而不是复用陈旧的答案取消则保持树不变新答案作为兄弟工具结果追加保留旧答案分支然后 agent 从新答案继续如果旧/损坏数据无法恢复原始问题选择回退为普通叶子移动。实现要点第一遍调用返回reopenAsk: { toolCallId, questions }且不修改任何内容调用方重新打开 picker 后以reanswerAskResult完成第二遍调用此时通过appendMessageToBranch(toolResultMessage, targetEntry.parentId)在相同toolCallId下分支出一个新的兄弟 toolResultagent-session.ts。成功提交后返回askReanswerCommitted交互调用方在重建 transcript之后通过resumeAfterAskReanswer()恢复 agentissue #6483。其他公开调用方扩展、hooks、ACP、会话扩展 action不设置allowAskReopen直接走普通的叶子移动。选中其他节点新叶子变为选中节点 id不预填编辑器。选中当前叶子通常关闭并提示Already at this point当前叶子如果是 user 消息则例外叶子 user 提示会回退到自身之前——叶子指向 parent、文本进编辑器这仍是一次真实移动ask 结果也例外见上文。决策树简化selected node │ ├─ current leaf (not ask result)? ── close selector (no-op) │ ├─ ask tool result? ── re-answer as a sibling branch when questions are recoverable │ ├─ user or ordinary custom message? ── leaf : parentId (or root) │ prefill only into an empty editor │ └─ otherwise ── leaf : selected node id no editor prefill摘要切换流程Summary-on-switch摘要提示由branchSummary.enabled控制默认false见 config/settings-schema.ts。ShiftEnter无论该设置如何都直接请求摘要此时必须已有可用的模型和 provider 凭证navigateTree中options.summarize !this.model会直接抛错。摘要使用的 token 预留由branchSummary.reserveTokens控制默认16384。当提示开启时普通Enter会提供三个选项No summary不摘要Summarize摘要Summarize with custom prompt自定义提示摘要流程细节在摘要提示中按Esc会重新打开树选择器取消自定义提示会返回摘要选择摘要过程中 UI 显示加载器并将Esc绑定到abortBranchSummary()如果摘要被中止树选择器重新打开且不应用任何移动。navigateTree内部流程agent-session.ts冲刷待处理的 bash 输出并校验目标条目通过collectEntriesForBranchSummary收集从旧叶子到公共祖先之间被弃分支的条目发出可取消的session_before_tree事件——扩展可以供应所请求的摘要仅在请求了摘要、条目需要摘要且没有 hook 摘要时运行默认摘要器generateBranchSummary需解析 model 与 API key视情况应用branchWithSummary(...)、branch(newLeafId)或resetLeaf()resetLeaf在newLeafId null时调用见 session-manager.ts重建模型上下文、checkpoint/rewind 状态、advisor 状态、todos以及受历史重写影响的 provider 会话replaceMessages、rehydrateCheckpointRewindState、advisors.resetSessionState、todo.syncFromBranch、closeCodexProviderSessionsForHistoryRewrite发出session_tree事件若 handler 可能追加了条目则再次重建。如果请求了摘要但无可摘要内容导航会在不添加摘要条目的情况下继续。摘要条目的归属位置是导航目标位置新叶子而非旧分支——这一点与直觉相反但很关键。标签Labels树 UI 中的标签编辑调用appendLabelChange(targetId, label)session-manager.ts非空标签设置/更新解析后的标签空标签清除它标签存储为只追加append-only的label条目type: labeltargetId树节点显示的是解析后的标签状态而不是原始 label 条目的历史。会话索引中的labelsInEffect()负责从追加历史中解析当前生效的标签。注意在createBranchedSession/branch 到新文件时路径上的 label 条目会被丢弃再从解析后的标签映射中按生效状态重建避免携带冗余历史。/tree与相邻操作的对比操作作用域结果/tree当前会话文件将叶子移动到选中点同一文件内/branch通常是当前会话文件 → 新会话文件打开 transcript 回退选择器user消息目标分支到新会话文件其他目标在原地重定位叶子/fork整个当前会话将会话复制为新的持久化会话文件/resume会话列表切换到另一个会话文件关键区别/tree是单个会话文件内部的导航/重定位工具/branch、/fork、/resume都会改变会话文件的上下文。命令注册源码见 builtin-session.ts/branch别名rewind调用showUserMessageSelector()/tree调用showTreeSelector()/fork调用handleForkCommand()。操作工作流从更早的 user 提示重新运行不丢失当前分支/tree搜索/选择更早的 user 消息选择No summary如需要可摘要在编辑器中编辑预填文本提交效果新分支从同一会话文件内的选中点开始生长。带上下文面包屑离开当前分支开启branchSummary.enabled/tree并选择目标节点选择Summarize或自定义提示效果在继续之前目标位置会追加一个branch_summary条目作为后续跳回该分支的上下文面包屑。排查隐藏的簿记条目/tree按AltAall模式搜索model、thinking、custom或标签效果查看完整的内部时间线而不只是对话节点——适合排查model_change、thinking_level_change、label等设置条目。为后续跳转标记关键节点/tree移动到目标条目ShiftL设置标签之后用AltLlabeled-only快速跳转效果在持久的分支地标之间快速导航。标签只追加存储、可随时用空标签清除适合长期会话中的里程碑管理。小结/tree把会话文件变成一个可自由穿梭的分支树Enter按类型分派叶子落点、ShiftEnter直通摘要、五种筛选模式配合模糊 AND 搜索覆盖从对话到内部簿记的全谱条目ask工具结果还有专门的两阶段重答协议避免复用陈旧答案。结合branchSummary、doubleEscapeAction和标签机制它是在单个会话内安全重放、对比与延续多条实验路径的核心工具——且全程不修改任何历史条目。【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考