Просмотр исходного кода

fix(read): narrow .env file blocking to not block .envrc (#5654)

Co-authored-by: Claude <[email protected]>
Buck Evan 3 месяцев назад
Родитель
Сommit
60db171b44
2 измененных файлов с 47 добавлено и 3 удалено
  1. 5 3
      packages/opencode/src/tool/read.ts
  2. 42 0
      packages/opencode/test/tool/read.test.ts

+ 5 - 3
packages/opencode/src/tool/read.ts

@@ -60,10 +60,12 @@ export const ReadTool = Tool.define("read", {
     }
 
     const block = iife(() => {
-      const whitelist = [".env.sample", ".example"]
+      const basename = path.basename(filepath)
+      const whitelist = [".env.sample", ".env.example", ".example", ".env.template"]
 
-      if (whitelist.some((w) => filepath.endsWith(w))) return false
-      if (filepath.includes(".env")) return true
+      if (whitelist.some((w) => basename.endsWith(w))) return false
+      // Block .env, .env.local, .env.production, etc. but not .envrc
+      if (/^\.env(\.|$)/.test(basename)) return true
 
       return false
     })

+ 42 - 0
packages/opencode/test/tool/read.test.ts

@@ -0,0 +1,42 @@
+import { describe, expect, test } from "bun:test"
+import path from "path"
+import { ReadTool } from "../../src/tool/read"
+import { Instance } from "../../src/project/instance"
+import { tmpdir } from "../fixture/fixture"
+
+const ctx = {
+  sessionID: "test",
+  messageID: "",
+  callID: "",
+  agent: "build",
+  abort: AbortSignal.any([]),
+  metadata: () => {},
+}
+
+describe("tool.read env file blocking", () => {
+  test.each([
+    [".env", true],
+    [".env.local", true],
+    [".env.production", true],
+    [".env.sample", false],
+    [".env.example", false],
+    [".envrc", false],
+    ["environment.ts", false],
+  ])("%s blocked=%s", async (filename, blocked) => {
+    await using tmp = await tmpdir({
+      init: (dir) => Bun.write(path.join(dir, filename), "content"),
+    })
+    await Instance.provide({
+      directory: tmp.path,
+      fn: async () => {
+        const read = await ReadTool.init()
+        const promise = read.execute({ filePath: path.join(tmp.path, filename) }, ctx)
+        if (blocked) {
+          await expect(promise).rejects.toThrow("blocked")
+        } else {
+          expect((await promise).output).toContain("content")
+        }
+      },
+    })
+  })
+})