news 2026/8/1 10:36:33

[基础篇08] 操作OpenCode文件系统与工作区目录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[基础篇08] 操作OpenCode文件系统与工作区目录

前言

你是不是遇到过这样的情况——让AI“读取项目根目录的配置文件”,结果它翻来翻去就是找不到;或者让AI“参考另一个仓库的代码来写东西”,它却告诉你“没有权限访问那个目录”?

上篇我们学会了用插件给OpenCode加新功能,但插件要真正干活,离不开对文件系统的操作。文件系统是OpenCode的“手脚”——没有它,AI再聪明也动不了你项目里的一行代码。

建议先点个关注,收藏这个专栏,这篇我们来彻底搞懂OpenCode是怎么读写文件、管理目录、控制访问权限的。

上篇回顾

上篇我们掌握了插件开发的核心技能——用config钩子注册斜杠命令、用tool钩子让AI调用自定义函数、用event钩子订阅系统事件、用tool.execute.before拦截工具调用。

但插件的能力再强,最终都要落到“读写文件”这个基本动作上。这一篇就是解决“怎么让AI安全、高效地操作你项目里的文件”这个问题。

环境与前置说明

本篇依赖上篇的产出成果:

  • OpenCode已安装并可用
  • 熟悉插件开发的基本流程
  • 了解opencode.json配置文件的用法

不需要安装任何新依赖。所有文件操作功能都是OpenCode内置的。

文章目录

    • 前言
    • 上篇回顾
    • 环境与前置说明
    • 核心内容
      • 第一步:理解工作区目录(Working Directory)的概念
      • 第二步:用`client.file`读取文件
      • 第三步:列出目录内容
      • 第四步:理解文件操作权限体系
      • 第五步:用`external_directory`访问工作区外的文件
      • 第六步:用`add-dir`插件动态添加工作目录
      • 第七步:文件变更的Diff与追踪
    • 异常处理与常见坑
      • 报错1:AI读取文件时报“Permission denied”
      • 报错2:AI修改文件时一直弹确认框
      • 报错3:`/add-dir`命令不存在
    • 本章产出总结
    • 作者互动与资源引导
    • 下篇预告

核心内容

第一步:理解工作区目录(Working Directory)的概念

目标:搞清楚OpenCode的“工作区”到底是什么,以及它跟普通文件夹有什么区别。

你可能会问:工作区不就是我启动OpenCode的那个文件夹吗?这有什么好理解的?

对,但也不全对。OpenCode启动时所在的目录确实是它的“工作区根目录”。但工作区这个概念比单纯一个文件夹要复杂——它包含三个维度:

维度说明
directory你启动OpenCode时所在的目录(当前工作目录)
worktreeGit工作树的根目录(如果有Git仓库的话)
project项目的逻辑分组(可以包含多个目录)

这三个维度共同定义了一个“工作单元”。OpenCode的会话是绑定到特定目录的,每个项目维护自己的会话列表。

注意了:如果你在项目的子目录启动OpenCode,directory是那个子目录,而worktree是Git仓库的根目录。这意味着AI默认只能访问directory下面的文件,但可以感知整个worktree的结构。

在插件中,你可以通过ctx.directoryctx.worktree获取这两个值:

importtype{Plugin}from"@opencode-ai/plugin"exportconstWorkspacePlugin:Plugin=async(ctx)=>{// 打印当前工作目录和Git工作树根目录console.log("📁 当前工作目录:",ctx.directory)console.log("🌳 Git工作树根目录:",ctx.worktree)return{}}

运行验证:在任意Git项目中创建这个插件,在.opencode/plugins/目录下保存为workspace.ts,重启OpenCode。观察终端输出——ctx.directory应该是你启动OpenCode的目录,ctx.worktree应该是Git仓库的根目录。

第二步:用client.file读取文件

目标:学会在插件中通过SDK Client读取项目文件。

上篇我们简单提过SDK Client,但没深入讲文件操作。client.file是操作文件系统的核心入口。

.opencode/plugins/file-reader.ts中写入:

importtype{Plugin}from"@opencode-ai/plugin"exportconstFileReaderPlugin:Plugin=async(ctx)=>{const{client,directory}=ctxreturn{// 注册一个工具,让AI能调用它来读取文件统计信息tool:{file_stats:tool({description:"获取指定文件的统计信息(行数、大小、修改时间)",args:{// 文件路径参数,相对于项目根目录filePath:tool.schema.string().describe("要统计的文件路径,相对于项目根目录")},asyncexecute(args){// 使用client.file.read读取文件内容// 注意:read返回的是文件内容,不是文件元数据constresult=awaitclient.file.read({path:{file:args.filePath}})// 从ctx中获取工作目录,构造完整路径来获取文件信息constfullPath=`${directory}/${args.filePath}`constfileInfo=awaitBun.file(fullPath).stat()// 统计行数(按换行符分割)constlines=result.data.split("\n").lengthreturn{fileName:args.filePath,lineCount:lines,fileSize:fileInfo.size,modifiedAt:fileInfo.mtime}}})}}}

逐行解释一下:

  • client.file.read:读取文件内容,path.file指定文件路径
  • Bun.file(fullPath).stat():获取文件的元数据(大小、修改时间等)
  • 工具的参数用tool.schema.string()定义,底层是Zod schema

运行验证:保存插件,重启OpenCode。在TUI中让AI“统计package.json的文件信息”,AI应该会调用file_stats工具,返回行数、大小和修改时间。

第三步:列出目录内容

目标:学会用client.file.list列出目录下的所有文件和子目录。

client.file.list可以列出指定目录的内容:

// 在插件中列出目录内容constfiles=awaitctx.client.file.list({query:{path:ctx.directory}// path指定要列出的目录})// files.data是一个数组,每个元素包含文件/目录信息for(constfoffiles.data){console.log(f.name,f.isDirectory?"📁":"📄")}

你可以把目录列表能力封装成一个工具,让AI随时查看项目结构:

importtype{Plugin}from"@opencode-ai/plugin"exportconstDirListPlugin:Plugin=async(ctx)=>{const{client,directory}=ctxreturn{tool:{list_project:tool({description:"列出项目根目录下的所有文件和文件夹",args:{},asyncexecute(){constresult=awaitclient.file.list({query:{path:directory}})// 格式化成易读的列表constitems=result.data.map(f=>{consticon=f.isDirectory?"📁":"📄"return`${icon}${f.name}`}).join("\n")return`项目目录内容:\n${items}`}})}}}

运行验证:加载插件后,在TUI中让AI“列出项目根目录的内容”,AI会调用list_project工具,返回目录列表。

第四步:理解文件操作权限体系

目标:搞清楚OpenCode的权限模型,知道怎么控制AI能读哪些文件、能改哪些文件。

OpenCode有一套精细的权限体系,每个工具(read、edit、write、glob、grep等)都可以单独配置权限。

权限的默认规则是这样的:

工具默认行为
read允许(AI可以读取工作区内的任何文件)
edit/write/patch需要确认(AI每次修改文件都需要你批准)
glob/grep允许(AI可以搜索文件)
bash需要确认(AI执行命令需要你批准)

注意了:read默认是允许的,这意味着AI可以看到你项目里的所有代码。如果你有敏感文件(比如.envsecrets.json),需要用配置文件明确禁止读取。

opencode.json中配置权限:

{"$schema":"https://opencode.ai/config.json","permission":{// 禁止读取.env文件"read":{"**/.env":"deny","**/.env.*":"deny"},// 禁止修改配置文件"edit":{"opencode.json":"deny",".opencode/**":"deny"},// bash命令需要每次都确认"bash":"ask"}}

权限配置支持模式匹配(glob pattern)。**表示任意层级的子目录,*表示任意文件名。

运行验证:在opencode.json中添加禁止读取.env的规则,然后重启OpenCode。在TUI中让AI“读取.env文件的内容”——AI应该会收到权限错误,无法读取。

第五步:用external_directory访问工作区外的文件

目标:学会配置OpenCode,让它能读取和修改工作区目录之外的文件。

默认情况下,OpenCode只能访问当前工作区目录内的文件。如果你想让AI读取另一个项目的代码,或者访问~/Documents里的文档,就需要配置external_directory

opencode.json中添加:

{"$schema":"https://opencode.ai/config.json","permission":{// 允许访问 ~/projects/ 下的所有子目录"external_directory":{"~/projects/**":"allow"}}}

这个配置的意思是:允许工具访问~/projects/目录下的所有文件。一旦某个目录被加入external_directory,它就会继承工作区的默认权限规则。

如果你想允许读取但禁止修改某个外部目录:

{"$schema":"https://opencode.ai/config.json","permission":{"external_directory":{"~/projects/legacy/**":"allow"},// 在外部目录中禁止编辑,但允许读取"edit":{"~/projects/legacy/**":"deny"}}}

这样AI可以读取~/projects/legacy/里的代码作为参考,但不会误修改它们。

运行验证:配置external_directory指向另一个项目目录,重启OpenCode。在TUI中让AI“读取~/projects/另一个项目/package.json的内容”——AI应该能成功读取。

第六步:用add-dir插件动态添加工作目录

目标:学会在运行时动态添加额外的工作目录,无需修改配置文件。

前面我们说了,配置external_directory需要改opencode.json然后重启。但有时候你只是想临时让AI看一眼别的目录——每次都改配置太麻烦了。

社区有一个opencode-add-dir插件可以解决这个问题:

# 安装add-dir插件opencode plugin opencode-add-dir-gf

安装后,在TUI中可以这样用:

/add-dir ~/projects/another-project

这个命令会动态地把~/projects/another-project加入当前会话的允许目录列表,AI立刻就能访问那个目录的文件。

这里有个坑:/add-dir添加的目录只在当前会话中有效。关闭会话后,需要重新添加。

运行验证:安装插件后,在TUI中输入/add-dir ~/Downloads,然后让AI“列出~/Downloads目录下的文件”——AI应该能成功列出。

第七步:文件变更的Diff与追踪

目标:学会查看AI对文件做了哪些修改,以及怎么追踪文件的变更历史。

OpenCode会追踪所有文件操作,你可以通过client.session.diff查看当前会话的文件变更:

// 在插件中获取当前会话的文件变更constdiff=awaitctx.client.session.diff({path:{id:sessionId}})// diff包含了所有被修改、新增、删除的文件for(constchangeofdiff.data.changes){console.log(`📄${change.path}:${change.type}`)// change.type 可能是 "add"、"modify"、"delete"}

在TUI中,你也可以用/diff命令快速查看当前会话的所有文件变更。这个命令会显示一个清晰的列表,告诉你AI改了哪些文件、新增了哪些文件、删除了哪些文件。

运行验证:让AI修改一个文件(比如在某个文件里加一行注释),然后在TUI中输入/diff——你应该能看到那个文件出现在变更列表中,并且能看到具体的改动内容。

异常处理与常见坑

报错1:AI读取文件时报“Permission denied”

Error: Permission denied: /path/to/file

原因:AI尝试读取工作区外的文件,但external_directory没有配置允许该路径。

解决方案

  1. opencode.json中添加external_directory配置:
    {"permission":{"external_directory":{"/path/to/target/**":"allow"}}}
  2. 或者安装opencode-add-dir插件,在TUI中用/add-dir动态添加
  3. 完全退出并重启OpenCode(修改配置文件后必须重启)

报错2:AI修改文件时一直弹确认框

(每次AI要修改文件,都弹出"Allow tool edit?"的确认提示)

原因edit工具的默认行为是ask(需要用户确认)。

解决方案

  1. 如果信任AI的修改,可以在opencode.json中把edit改为allow
    {"permission":{"edit":"allow"}}
  2. 强烈不推荐这样做——让AI自动修改文件而不经确认,风险太高
  3. 更好的做法:在Build模式下工作,每次修改前AI会展示变更内容,你确认后再执行

报错3:/add-dir命令不存在

(输入/add-dir后显示"command not found")

原因opencode-add-dir插件没有安装。

解决方案

  1. 安装插件:
    opencode plugin opencode-add-dir-gf
  2. 确认插件已加载:
    opencode plugin list
  3. 如果列表中没有opencode-add-dir,检查opencode.json中是否包含:
    {"plugins":["opencode-add-dir"]}
  4. 完全退出并重启OpenCode

本章产出总结

完成本篇后,你获得了以下能力/产出:

序号产出物/能力说明
1理解工作区概念知道directoryworktreeproject的区别
2文件读取能用client.file.read读取任何项目文件
3目录列表能用client.file.list列出目录内容
4权限配置能用opencode.json精细控制AI的文件访问权限
5跨目录访问能用external_directory让AI访问工作区外的文件
6动态添加目录能用/add-dir在运行时临时添加工作目录
7文件变更追踪能用/diff查看AI对文件做的所有修改

文件系统是OpenCode的“双手”——学会了操作它,你就知道AI是怎么读写你的代码、怎么理解你的项目结构的。从此你不会再被“文件找不到”、“权限不够”这些问题困扰了。

作者互动与资源引导

你在使用过程中有没有遇到过文件权限方面的困惑?或者你有什么好用的文件操作技巧想跟大家分享?欢迎在评论区留言,我看到就会回复。

如果觉得这个专栏对你有帮助:

  • 关注我,后续每一篇更新你都不会错过
  • 关注后私信我,发送暗号“爱学Python”,我会把Python全栈学习路线图本专栏的源码包发给你

我们还有一个技术交流群,群里的小伙伴们每天都在讨论OpenCode的各种用法。想进群的朋友在评论区扣个“1”,我拉你进来。

下篇预告

下一篇是[[基础篇09] 实现OpenCode基础错误处理与重试逻辑],我们会深入OpenCode的错误处理机制——AI调用失败怎么办?API超时怎么重试?怎么让插件在面对错误时更健壮?

如果本篇对你有帮助,点赞、收藏、关注走一波,咱们下篇见!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/1 10:35:39

2026抖音运营十大精选榜单评测:制造业与工程企业获客选型指南

行业开篇:2026年短视频与AI搜索融合下的ToB营销新变局2026年,数字营销全面迈入短视频与AI搜索(GEO)深度融合的新阶段。抖音、视频号、小红书已不再是单纯的娱乐阵地,而是工业品、制造业、生产加工、工程建设等ToB高客单…

作者头像 李华
网站建设 2026/8/1 10:32:46

ESP32-P4开发板全攻略:从硬件解析到AI物联网项目实战

1. 项目概述:ESP32-P4-Module-DEV-KIT 是什么?如果你一直在关注乐鑫的微控制器产品线,那么ESP32-P4这颗芯片的名字应该不陌生。它被看作是ESP32-S3的“性能增强版”,集成了更强大的双核RISC-V处理器、更丰富的接口和更强的AI加速能…

作者头像 李华
网站建设 2026/8/1 10:31:24

iOS越狱完全指南:5步解锁iPhone隐藏功能,从新手到高手

iOS越狱完全指南:5步解锁iPhone隐藏功能,从新手到高手 【免费下载链接】Jailbreak iOS 26.4 - 26, 17 - 17.7.5 & iOS 18 - 18.7.3 Jailbreak Tools, Cydia/Sileo/Zebra Tweaks & Jailbreak News Updates || AI Jailbreak Finder 👇 …

作者头像 李华
网站建设 2026/8/1 10:25:58

什么是晶圆间隔纸?半导体晶圆防护耗材基础知识详解

在半导体产业链里,大家的关注点大多集中在光刻胶、靶材、抛光液、载具盒这类核心物料,很容易忽略一张薄薄的晶圆间隔纸。实际晶圆切割、研磨、测试、封装、仓储转运全流程中,晶圆片堆叠存放必须依靠间隔纸做隔离防护,微粒污染、晶…

作者头像 李华