omp packages

pi-cwd-portal1.1.34

Switch the session working directory in place, with /portal and switch_cwd. (PiDeck integration is an optional local module, not bundled.)

15066212pp Published 3 hours ago MIT ~6.6K downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-cwd-portal

存在目的与所解决问题

pi 把 cwd 绑在会话 runtime 上,既没有原地改 cwd 的 API,也没有换目录的命令。缺这个插件时,跨项目工作只剩两条烂路:开新会话(上下文、技能加载状态全丢),或留在旧 cwd 用绝对路径手工绕——此时 AGENTS.md、技能、设置与工具的默认路径仍指向旧项目,模型按旧项目的规则干活。 本插件原地改写会话文件的 cwd 字段,并以同一路径重建 runtime,让规则文件、技能、设置与路径基准一起搬到新项目。 边界:只换工作目录——不搬会话文件(历史仍在原路径)、不复制任何项目文件、不改任何默认值;PiDeck 界面同步是包外的可选模块,缺失即跳过;同一时刻只允许一次切换。

把会话的工作目录切到另一个项目,而不换会话。

你说「去 Vue3_V2.0 那个项目看看」,理想情况是我在同一个对话里直接过去:读那边的文件、用那边的规则、加载那边的技能。而不是开一个新会话,也不是让你手动切。

这个插件换掉会话的 cwd。此后 bash、read、write 的路径基准,项目规则文件(AGENTS.md),技能与设置全部跟过去。会话文件本身不动——路径不变,PiDeck 的列表和标签页也不会丢。

它做什么

两个入口,一个动作:

  • 工具 switch_cwd(path, reason?),我在任务从资料目录转入工程目录时调用
  • 命令 /portal <path>,你手动切

切换在本轮回答结束后派发(agent_end 时发一条 /portal),可能延迟到后面某轮生效。实际执行是三步:

  1. 解析目标目录(展开 ~、判等)——只读,不创建;目录不存在时在真正执行切换前才创建
  2. 改写会话文件头里的 cwd 字段(原子写,失败从内存快照回滚),并把这次切换记成一条会话记录
  3. 用同一个会话文件重新打开会话——runtime 按新的 cwd 重建

进程的 cwd 也跟着切(chdirFollow,默认开),LSP 之类依赖 process.cwd() 的东西一起跟过去。

怎么用

pi install npm:pi-cwd-portal

配置是可选的 ~/.pi/cwd-portal.json:

键 默认 作用
chdirFollow true 进程 cwd 是否跟随
debug 不设 调试日志文件路径,设了才写

/portal 不带参数会打印当前目录;带参数直接切。AI 排程的切换由 /portal 无参形式消费。

为什么这样设计

代价必须写在工具描述里。 cwd 是 system 段的一部分,改它就是改 system;system 在整段对话之前,一变就让后面所有前缀缓存作废。本机 60 次切换实测:切换后第一个请求的前缀命中中位数从 283k 掉到 111k,丢 61%。这个代价消不掉,是架构决定的,所以插件把它写进工具描述,让我调用前就知道值不值。

短途别切。 读一个文件用绝对路径;给一条命令换目录用 git -C <path>。

切回当前目录会清掉待派发的切换。 目标等于当前目录时,工具直接返回「已在目标目录」,并清除排程。

失败时你会看到什么

原文来自源码,不加工:

已在目标目录 C:/work/B,无需切换(已清除待派发的切换)。
已排程:本轮结束后派发切换至 C:/work/B(整理资料);生效可能延迟到后续轮次(勿重复排程)。生效后,所有工具、上下文、技能与设置指向新目录。
cwd 切换正在进行中,请稍候再试。
无会话持久化(--no-session),无法切 cwd。
无法读取会话头,取消切换。
会话文件改写失败:<err>
cwd 切换被取消(会话恢复原状)。
cwd 切换被拒绝:会话文件格式版本 4 高于本插件已知的 3。
cwd 已切换:C:/work/A → C:/work/B(整理资料)

失败或取消时,除了界面提示,还会给模型发一条尾部消息说明「仍在原目录」和下一步动作——否则我可能以为切成功了。

边界

  • 会话文件不搬家:历史仍记在原来的路径下。
  • PiDeck 的界面同步不在这个包里,由本机模块 cwd-portal-local 负责(~/.pi/agent/extensions/cwd-portal-local/,不进仓库);两处 paths.ts 要一起改。
  • 目录补全一次最多 200 条,特别宽的目录会被截断。
  • 同一时刻只允许一次切换(并发守卫),后来的会被拒绝。
  • canon 与项目规则落点跟着 cwd 变:切走后这个会话读不到原目录的 .canon 项目知识;工具返回里会先提示原目录有几项(2026-10-20 实测)。
  • 会话格式版本未知时拒绝切换:本实现已知 header.version = 3(pi 1.2.0 / 1.3.0 实测)。版本更高时直接拒绝并报错,不猜布局、不写文件——改写 header 是拿宿主内部格式当持久层,赌错的代价是会话损坏。

实测

60 次真实切换(2026-10-18):切换后首个请求前缀命中中位 283k → 111k(−61%);不切的普通请求维持 283k。

2026-10-20 单次全程测量(17 万 token 会话,切换时记录):切换前 cacheRead 177,280 / 单请求 $0.00287;切换后首个请求 cacheRead 9,856、input 169,373 / $0.05207;第二个请求即恢复(cacheRead 178,816 / $0.00299)。所以断层是一次性全量 miss,约 5 美分,不需要重新积累多轮——上面那个「−61%」是首请求瞬时的命中量,不是持续成本。

MIT · Node >= 22.19