@runminton/pi-cwd-memory
Minimal and reliable memory for pi that gives the agent plain Markdown files and stays out of the way, in about 90 lines of code.
Package details
Install @runminton/pi-cwd-memory from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@runminton/pi-cwd-memory- Package
@runminton/pi-cwd-memory- Version
0.1.1- Published
- Nov 2, 2026
- Downloads
- 487/mo · 487/wk
- Author
- runminton
- License
- MIT
- Types
- extension
- Size
- 15.2 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-cwd-memory
给 pi 用的文件式长期记忆,按启动目录隔离:从 ~/a 启动只看到 ~/a 的记忆,从 ~/b 启动只看到 ~/b 的记忆。
作者本人把它作为日常使用的记忆方案。它是一个纯本地、无网络的扩展:准备目录、注入上下文、给旧记忆加时效提醒,别的事一律不做。
pi install npm:@runminton/pi-cwd-memory
也可以用 git 源(钉在 tag 上):
pi install git:github.com/RunMintOn/pi-cwd-memory@v0.1.0
只想试一次,不写进配置:
pi -e npm:@runminton/pi-cwd-memory
# 本地目录也行
pi -e ./index.ts
需要持久启用时,也可以直接装本地目录(本项目不会自动修改 pi 配置):
pi install /绝对路径/pi-cwd-memory
安装后它对你的 pi 做了什么
会改变的就这三件事:
| 时机 | 行为 | 影响 |
|---|---|---|
| 会话开始 | 建记忆目录(mkdir -p),读 memory-prompt.md 和 MEMORY.md 生成本次会话的快照 |
磁盘上多一个目录 |
| 每次给模型发请求前 | 把快照写进系统提示词的两段:memory 和 memory_index |
==会替换 pi 内置的 memory 段==,两者是替代关系而非叠加 |
| 你读取记忆文件时 | 若文件超过 48 小时,在读取结果前加一句时效提醒 | 只改这一次工具返回值,不改文件、不改历史消息 |
明确不会做的事:
- 不注册任何工具、命令或快捷键
- 不安装第二份
@earendil-works/pi-coding-agent(声明为 peer dependency,由宿主提供) - 不修改
settings.json、.pi/settings.json或任何 pi 配置 - 不写你的项目文件,不碰 git,不创建
.pi目录 - 不联网,不上传任何内容,记忆只存在本机
- 不自动保存、不自动整理、不自动召回——存什么、改什么由模型按
memory-prompt.md的规则自己决定 - 不创建空的
MEMORY.md(没有记忆就什么都不注入) - 不迁移、不删除你已有的旧记忆目录
卸载
pi remove npm:@runminton/pi-cwd-memory
卸载并重启 pi 后系统提示词恢复原样,记忆文件不会被自动删除。如果你想连记忆一起清理(先确认路径):
trash ~/.pi/agent/memory/--Users-ziqian-project-- # 没有 trash 就用 rm -rf
pi -e 不写进配置,结束即无痕(npm 源只缓存在 pi 的临时目录)。
存储位置
~/.pi/agent/memory/<启动目录的可读路径编码>/
├── MEMORY.md # 索引,每次会话注入
└── 各条记忆.md # 正文,按需读取
目录在 getAgentDir() 下,因此遵循 PI_CODING_AGENT_DIR。
- ==记忆不放进项目工作区==,不会被
git status看到,也不会误提交或误上传。 - 与 session 文件分开存放,删 session 不会删记忆。
- 目录命名沿用 pi 的 session 规则:去掉绝对路径开头的分隔符,把
/、\、:换成-,首尾各加--。/Users/ziqian/project→--Users-ziqian-project--。 - 记忆就是普通的 Markdown 文件,你可以随时用编辑器直接看、直接改、直接备份。
- 启动时仅预建目录,不创建空的
MEMORY.md,不改动已有文件。
子目录隔离:一个要知道的取舍
隔离键是启动目录的绝对路径,不是 git 仓库根。所以:
- 今天在
~/repo启动、明天在~/repo/src启动,你会看到两套互不相通的记忆。 - 想共用一套,就固定从同一个目录启动(通常建议从项目根)。
这么设计是为了"不同项目绝不串味",代价是同一仓库内换目录会分裂记忆。如果你希望按 git 仓库聚合,需要改成向上查找 .git,这属于行为变更,本包不做。
上下文、token 与缓存
每次请求注入的内容只有两块:
memory段:memory-prompt.md全文(约 2 KB,几百 token),其中{{MEMORY_DIR}}已替换为绝对记忆目录路径,结尾带路径分隔符。除路径替换和工具名调整外,其余文字保留参考原文。memory_index段:Contents of <绝对索引路径> (user's auto-memory, persists across conversations):加MEMORY.md全文——==索引越大,每次请求的固定开销越大==。建议保持"一条记忆一行",控制条目数量。索引不存在或为空时不注入这一段。
这两段只写进系统提示词,不追加任何聊天消息,也不改磁盘上的索引。
关于 prompt 缓存:快照在 session_start 时确定,before_agent_start 每次都复用同一份,不读磁盘。所以会话内系统提示词前缀不会因为记忆文件被改动而变,不会在会话中途打断缓存命中。新会话会重新读取,索引变了新会话的前缀自然不同——这是预期行为,不影响已有会话。
其余细节:
- 只预载索引,不预载各条记忆正文;正文由模型用现有工具按需读取。
- 会话内修改索引、记忆正文或
memory-prompt.md都不刷新快照。重新进入会话或/reload才生效。 - pi 自身的压缩、工具切换引起的上下文变化不由本插件控制。
memory-prompt.md用{{MEMORY_DIR}}占位符注入绝对路径,并把工具名改成write/apply_patch,兼容两种 pi 工具配置。- 不注入
node_type、originSessionId、modified等元数据。
旧记忆的时效提醒
记忆是某个时间点的观察,不是当前状态。所以读取旧记忆时会被提醒核实:
- 只处理当前记忆目录内文件的成功
read结果;其他路径、失败读取一律不动。 - 按文件 mtime 算完整天数,满 48 小时起,在读取结果的第一段文本前插入
<system-reminder>This memory is N days old. ...</system-reminder>,提醒核实当前状态。 - 同时更新文本形式的
structuredContent,所以在 codemode 里嵌套调用read也能收到提醒。 - 手动读
MEMORY.md同样生效;会话初始化时直接加载索引不经过工具,因此不附加提醒。 - 无法获取 mtime 时保留原始读取结果——提醒永远不会把一次成功的读取变成失败。
- 不修改文件、不修改历史消息、不修改系统快照;也不实现自动召回。
已知限制
- 没有文件锁:同一启动目录下并行开多个会话时,它们共享同一批文件,同时写入可能互相覆盖。单会话使用没有这个问题。
- 索引无截断:
MEMORY.md会全量注入,没有大小上限或自动裁剪,索引膨胀会直接推高每次请求的固定开销。 - 只对
read工具的结果加提醒;用bash cat之类方式读记忆不会触发。 - 旧版哈希命名的记忆目录既不会自动迁移、也不会自动删除,需要你手动搬到新的可读目录,然后重新进入会话或执行
/reload才会生效。 - 依赖
session_start、before_agent_start、tool_result三个钩子,跟随当前 pi 版本开发,未在旧版本上验证。
验证
需要 Node.js 22.19 或更新版本,无需安装依赖:
npm test
在 pi 1.5.0 上开发并验证。
License
MIT