npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@epoch-agent/plugin-file

v0.9.0

Published

epoch-agent 文件系统操作插件

Readme

@epoch-agent/plugin-file

文件工具插件。8 个工具

  • :读 / 写 / 精确编辑 / V4A 多文件补丁 / 搜索 / 列目录
  • 不做:git 操作、跨机同步、任何引擎逻辑
  • 依赖diff(算 diff)。protocolinfra 是 peer

工具

只读五个:file_read file_multi_read file_search file_list file_diff_preview; 破坏性三个:file_write file_patch file_multi_patch

每个工具干什么、分页与 output_mode 那些边界在 docs/TOOLS.md —— 那份是工具清单的唯一真源, 这里只写这个包自己的实现取舍。

file_searchripgrep,但不要求用户自己装rg 从哪来由 infra 的 resolveRipgrep() 三级决定 —— 系统 PATH 上有就用系统的, 没有就用随包带的 vendor 二进制,两个都没有才退回「工具在、一调才报错 + 给安装提示」 的老行为(启动诊断一条 warn,其余七个工具不受影响)。

本插件不再导出 probeRipgrep() / RIPGREP_INSTALL_HINT,它们搬去 infra 了: file_list 和将来的 @ 文件补全也要用同一份解析,而 plugin 之间不许互相依赖。 这里只管参数怎么拼输出怎么收

只读的四个 + file_diff_preview 标了 supportsParallel: true,引擎可以并发调。

处理的几类脏输入

  • 二进制:扩展名黑名单拦截(.png / .exe / .zip 等),不把乱码喂给模型
  • BOM:剥掉 Windows 编辑器留的 UTF-8 BOM,否则第一行的 patch 匹配永远不中
  • 行尾:CRLF ↔ LF 归一,patch 匹配不受平台影响
  • 路径~~user 展开
  • 工作区边界resolveSafePath 防路径穿越——resolve 之后用 relative 判, 不是 startsWith。判定本身是 infra 的 isInWorkspace()(全仓唯一一份,权限层和 plugin-terminal 共用),这里只管 ~ 展开和抛 PathEscapeErrorctx.extraRootsepoch --add-dir)一并透传:落在额外根里的绝对路径 不算越界,但相对路径仍然只按 ctx.workDir 解析——否则 src/a.ts 会在每个 根里各找一遍,同一个相对路径有多个答案,而模型无从知道命中的是哪一个
  • 读类工具多认一格:本会话的 artifact 目录(方案 47)。file_read / file_search / file_list / file_multi_read 走的是 resolveReadablePath, 它在上面那套之外再认 artifactsDir(ctx.sessionId)。理由是大输出落盘之后 取回提示会告诉模型「用 file_search 在这个路径里搜」,而那个路径在工作区外—— 不放开这一格,那句提示就是一句必定失败的指令。 口子收窄到三条:只放开读file_write / file_patch 仍走 resolveSafePath, 模型没有理由改写「命令当时输出了什么」这份证据)、只放开本会话那一个子目录 (不是 ~/.epoch/artifacts,更不是 ~/.epoch——后者等于把 .env 里的 API key 和 sessions.db 一起交出去)、sessionId 由引擎给且 artifactsDir() 内部再洗一次。 这三条各有一条否定用例钉着,见 __tests__/artifact-readable.test.ts

四个读类工具自己收进 ctx.outputBudget(2026-09-08)

预算从 ctx.outputBudget 现拿 —— 那是引擎将要用的同一个数,所以自己截完不会 再被引擎切一次,工具说的那句「还有多少、怎么接着读」也就是真的。 MAX_OUTPUT_CHARS(50_000)退化成兜底,只在宿主自己拼 ToolContext 时用(那条路上也没有引擎在截)。

改之前是两处各量一遍、而且两个数不一样:这四个按 50_000 截并明说截了多少, 引擎再按自己那个数切一刀 —— 模型看到的既不是全文,也不是我们说的那句话。

file_read 那一格更具体:它的分页单位是offset / limit),预算的单位是 字符。两个单位不换算的后果是那条工具描述里的假话「一次读 500 行」—— 500 行长行早就越过预算被引擎从中间切掉,而它报的 nextOffset 是按行算的, 模型照它翻页正好跳过被切掉的那一段,两侧都不报错。现在按行收进预算 (fitLines),报的是真正读到的那一行。

file_diff_preview 的 operation 是故意填错的

它的真实语义是只读(只算 diff 不落盘),annotations 照实写。但 operation 仍填 file_write:老白名单把它归在 FILE_WRITE_TOOLS 里,只改一边会让 recordApproval 那条路径与这里分叉。往严的方向偏,代价只是多一次确认。

开发

pnpm --filter @epoch-agent/plugin-file test

path-boundary.test.ts 记的是具体的穿越手法,改 resolveSafePath 之前先读它。