Plandex Plan 全面指南:创建、切换、归档与项目目录管理
【免费下载链接】plandexOpen source AI coding agent. Designed for large projects and real world tasks.项目地址: https://gitcode.com/GitHub_Trending/pl/plandex
Plandex 是一个面向大型项目与真实世界任务的开源 AI 编码代理(AI coding agent),而plan(计划)是 Plandex 中最核心的工作单元。本指南将以 plans.md 为主体,结合仓库 CLI 源码,系统讲解 plan 的概念、创建方式、命名与 draft 规则、列表与当前 plan 的切换、删除与归档,以及.plandex目录和项目子目录规划等完整实战方案,帮助你高效组织多任务、多分支的 AI 编码工作流。
什么是 Plan
在 Plandex 中,plan 相当于 ChatGPT 或 Claude 里的一次对话(conversation)。它既可以只包含一条 prompt 和一次模型响应、完成一个很小的任务;也可以是一次漫长的、与模型来回多轮的完整协作过程,最终生成几十个文件、构建出一个完整功能甚至整个项目。
一个 plan 聚合了三类核心内容:
- Context(上下文):你或模型加载的任何上下文,包括文件、目录、URL、图片等;
- Conversation(对话):你与模型之间的全部对话记录;
- Pending changes(待应用更改):在对话过程中累积起来的、尚未应用到工作区的更改。
此外,plan 原生支持版本控制与分支(branches),这意味着同一个 plan 可以像 git 一样在不同的分支上演化,随时回退、比较或切换到其他分支继续开发。
Plan 在源码中的落点
从服务端数据模型看,plan 由服务端数据库统一存储与维护,CLI 通过 API 与之交互。例如在 app/cli/cmd/new.go 中,plandex new会调用api.Client.CreatePlan(lib.CurrentProjectId, shared.CreatePlanRequest{Name: name})在服务端创建 plan 并拿到其 ID;在 app/cli/cmd/plans.go 中,plandex plans通过api.Client.ListPlans(projectIds)拉取 plan 列表。也就是说,plan 的数据并不只存在于本地,而是作为项目(project)下的实体被持久化在服务端。
创建新 Plan
创建 plan 之前,需要先进入项目目录。如果是从零开始的新项目,先创建目录:
mkdir your-project-dir cd your-project-dir通过 REPL 创建
直接运行:
plandex如果当前目录此前没有创建过 plan,REPL 启动时会自动创建一个新 plan。如果 REPL 中已经加载了某个 plan(可以用\current查看),则通过\new开启新 plan。
通过 CLI 创建
plandex newnew命令在源码中对应 app/cli/cmd/new.go 的newCmd,并注册了别名n。它的完整工作流程是:
- 解析账号与组织(
auth.MustResolveAuthWithOrg),解析或创建项目(lib.MustResolveOrCreateProject); - 并行发起两个请求:创建 plan(
CreatePlan)与获取默认 plan 配置(GetDefaultPlanConfig); - 将新 plan 写入本地为「当前 plan」(
lib.WriteCurrentPlan),并把当前分支设为main(lib.WriteCurrentBranch("main")); - 若未指定名称,plan 默认命名为
draft(app/cli/cmd/new.go); - 若配置开启了自动加载上下文(
AutoLoadContext),则立即对--context-dir指定的目录做一次「仅定义」级别的自动上下文加载(app/cli/cmd/new.go)。
可以看到,new不仅创建 plan,还会顺带完成当前 plan / 当前分支的本地状态写入与自动上下文加载,让新 plan 立即可用。
new 命令的实用参数
从 app/cli/cmd/new.go 的 flag 定义可以整理出new支持的参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
-n, --name | 新 plan 的名称,不传则自动命名为draft | 空(即draft) |
--context-dir | 开启自动上下文加载时,从哪个目录作为基准加载上下文 | .(当前目录) |
Plan 名称与 Draft 规则
创建 plan 后,Plandex 会在你发送第一条 prompt 之后根据内容自动为 plan 命名;当然你也可以在创建时就指定名称:
plandex new -n foo-adapters-component如果不预先指定名称,plan 会一直叫draft,直到你发送初始 prompt 才会获得自动生成的正式名称。
Draft 的唯一性约束:为了保持整洁,同一时间只允许存在一个名为draft的活动 plan。如果你创建了新的 draft plan,之前存在的 draft plan 会被自动移除。这一规则意味着「draft」是临时占位名,正式命名后才算真正开始一个长期任务。
结合源码可以进一步印证:服务端在创建 plan 时(对应shared.CreatePlanRequest{Name: name})接收名称;当name为空时 CLI 侧直接以draft兜底(app/cli/cmd/new.go),而「仅一个 draft」的约束由服务端在保存 plan 时执行——创建新 draft 时会清理旧 draft。
列出 Plan
当项目中积累多个 plan 后,使用plans命令查看:
plandex plans该命令在 app/cli/cmd/plans.go 中定义,注册了别名pl,并支持-a, --archived参数用于只列出已归档的 plan。
从源码(app/cli/cmd/plans.go)可以看到列表输出远比字面上丰富:
- 当前目录的 plan 表:以表格展示序号(
#)、名称、更新时间、当前分支、上下文 token 数与对话 token 数,当前 plan 会用绿色高亮并标记👈; - 父目录中的 plan:
plans会通过fs.GetParentProjectIdsWithPaths找到上级目录里存在的项目,以树状结构展示; - 子目录中的 plan:通过
fs.GetChildProjectIdsWithPaths(带 500ms 超时)找到下级目录里的项目并展示; - 输出底部还会给出
new、cd、delete-plan、archive、plans --archived等快捷命令提示。
也就是说,plandex plans是从「当前目录出发、向上下两个方向」搜索整个项目层级中的所有 plan,而不是只显示当前目录,这正是文档「Project Directories」一节所述能力的实现基础。
当前 Plan(Current Plan)
Plandex 的大多数命令都针对当前 plan执行,因此弄清楚「某个目录下当前是哪个 plan」非常重要。
查看当前 plan:
plandex currentcurrent命令(app/cli/cmd/current.go)会拉取当前 plan 的详细信息,并以表格展示当前 plan 名称、更新时间、创建时间、分支、上下文 token 与对话 token(app/cli/lib/current.go)。
切换当前 plan 使用cd命令:
plandex cd # 从列表中选择一个 plan plandex cd some-other-plan # 按名称切换到指定 plan plandex cd 2 # 按 `plandex plans` 列表中的序号切换cd命令(别名set-plan,见 app/cli/cmd/cd.go)的实现细节值得注意:
- 不传参数时通过交互式列表选择(
term.SelectFromList); - 传参时先尝试解析为数字序号(
strconv.Atoi),序号范围在1..len(plans)之间才有效;解析失败则按名称精确匹配; - 选定后调用
lib.WriteCurrentPlan把 plan ID 写入本地状态文件,再调用lib.MustLoadCurrentPlan重新加载当前 plan(同时恢复该 plan 的当前分支); - 还会异步调用
api.Client.SetProjectPlan把当前 plan 同步到服务端,用于新设备首次使用时的状态恢复(app/cli/cmd/cd.go)。
当前 plan 的本地持久化机制
「当前 plan」不是凭空存在的状态,它被持久化在用户的本地 Plandex 目录中。相关实现见 app/cli/lib/plans.go 与 app/cli/lib/current.go:
- 项目级状态:
.plandex/projects-v2.json(记录当前项目 ID,按账号区分); - 计划级状态:
~/.plandex/<projectId>/current-plans-v2.json(记录当前 plan ID,按账号区分,见 app/cli/lib/plans.go 的WriteCurrentPlan/ClearCurrentPlan); - 分支级状态:
~/.plandex/<projectId>/<planId>/settings-v2.json(记录每个 plan 当前的 branch,默认main,见 app/cli/lib/plans.go 的WriteCurrentBranch)。
这些状态文件都以用户 ID 为键,意味着同一台机器上多个 Plandex 账号可以各自维护独立的当前 plan / 分支。
删除 Plan
使用delete-plan命令删除 plan:
plandex delete-plan # 从列表中选择要删除的 plan plandex delete-plan some-plan # 按名称删除 plandex delete-plan 4 # 按 `plandex plans` 列表中的序号删除delete-plan(别名dp,见 app/cli/cmd/delete_plan.go)的能力比文档字面描述的更强,从源码(app/cli/cmd/delete_plan.go)可以整理出四种删除方式:
| 方式 | 示例 | 说明 |
|---|---|---|
| 交互选择 | plandex delete-plan | 弹出列表供选择 |
| 数字序号 | plandex delete-plan 4 | 按列表序号删除 |
| 名称精确匹配 | plandex delete-plan some-plan | 按名称删除 |
| 通配符模式 | plandex delete-plan foo-* | 使用path.Match匹配多个 plan |
| 序号区间 | plandex delete-plan 1-3 | 删除一段范围内的多个 plan |
| 全部删除 | plandex delete-plan --all | 删除当前项目全部 plan |
删除前会列出待删除的 plan 并要求交互确认(term.ConfirmYesNo),确认后才逐个调用api.Client.DeletePlan执行删除;如果删除的正是当前 plan,还会调用lib.ClearCurrentPlan清空本地当前 plan 状态(app/cli/cmd/delete_plan.go)。
归档 Plan
对于暂时不做了但想保留的 plan,可以归档而不是删除。归档后的 plan 不会出现在plandex plans的常规列表中。
plandex archive # 从列表中选择要归档的 plan plandex archive some-plan # 按名称归档 plandex archive 2 # 按 `plandex plans` 列表中的序号归档 plandex unarchive # 从列表中选择要恢复的 plan plandex unarchive some-plan # 按名称恢复 plandex unarchive 2 # 按 `plandex plans --archived` 列表中的序号恢复查看当前目录下已归档的 plan:
plandex plans --archived从源码看,archive(app/cli/cmd/archive.go)与unarchive(app/cli/cmd/unarchive.go)的参数解析逻辑与cd一致:不传参数时交互选择,传参时优先按数字序号、其次按名称匹配。归档列表接口为api.Client.ListArchivedPlans,归档/恢复接口分别为api.Client.ArchivePlan/api.Client.UnarchivePlan。plans --archived输出同样是一张「序号 / 名称 / 更新时间」的表格(app/cli/cmd/plans.go)。
.plandex 目录
在任何目录中第一次运行plandex(REPL)或plandex new时,Plandex 会在此目录创建一个.plandex目录,用于存放轻量级的项目级配置。
从源码看,.plandex目录的核心职责包括:
- 记录项目与 Plandex 服务端的映射:
.plandex/projects-v2.json保存当前项目 ID(见 app/cli/lib/current.go 的mustInitProject); - 与
~/.plandex主目录配合:项目级状态存于项目内.plandex/,账号级状态(当前 plan、分支)存于用户主目录~/.plandex/下; - 自动上下文加载时会以
.plandex所在目录为基准扫描项目文件。
多人协作的两种推荐做法:
- 提交
.plandex目录,并让所有协作者加入同一个 org,这样大家共享同一套项目映射与协作语义; - 或者把
.plandex/加入.gitignore,避免把个人状态提交进代码仓库。
注意:在 app/cli/fs/paths.go 的
skipDirs列表中,.plandex、.plandex-dev、.plandex-v2等目录都被显式排除在项目文件扫描范围之外,避免 Plandex 的元数据被当作上下文加载给模型。
在项目子目录中创建 Plan
前文默认你是在项目根目录运行plandex或plandex new,这也是最常见的用法。但在项目子目录中创建 plan 同样非常有用,原因有三:
- 缩短上下文路径:Plandex 中上下文文件路径是相对于创建 plan 时的目录解析的。如果某个 plan 只关注项目的一部分,在子目录中创建 plan,加载上下文、在 prompt 中引用文件时路径都会更短、更直观。
- 缩小自动上下文加载范围:使用自动上下文加载时,在子目录启动 plan(或 REPL)能限制 project map 的大小,并限制模型可加载的文件范围——模型只会在该子目录及其规则范围内发现和加载文件,从而节省 token 并让模型更聚焦。
- 便于组织大量 plan:当 plan 数量很多时,按子目录分区存放更易管理。
层级感知的plans列表:plandex plans除了显示当前目录的 plan,还会显示附近父目录和子目录中的 plan(实现见 app/cli/cmd/plans.go 中对父/子项目 ID 的并发查询与树状渲染)。这样无论 plan 散落在项目层级的哪个位置,你都能看到它们并知道其所在路径。想切换到其他目录下的 plan 时,先cd到那个目录,再运行plandex cd选择即可。
小结:Plan 生命周期与常用命令速查
| 场景 | 命令 |
|---|---|
| 进入项目目录 | cd your-project-dir |
| REPL 中自动创建 / 新建 | plandex/\new |
| CLI 创建(可指定名称) | plandex new/plandex new -n name |
| 列出(含父/子目录) | plandex plans |
| 列出已归档 | plandex plans --archived |
| 查看当前 plan | plandex current(REPL 中用\current) |
| 切换当前 plan | plandex cd [名称\|序号] |
| 删除 plan | plandex delete-plan [名称\|序号\|模式\|区间] |
| 归档 / 恢复 | plandex archive [名称\|序号]/plandex unarchive [名称\|序号] |
掌握 plan 的创建、命名、切换、删除与归档,再结合版本控制、分支与上下文管理,就能在大型项目上以清晰、可控的方式并行推进多个 AI 编码任务。
【免费下载链接】plandexOpen source AI coding agent. Designed for large projects and real world tasks.项目地址: https://gitcode.com/GitHub_Trending/pl/plandex
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考