summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-19 07:23:37 -0600
committerAdam <[email protected]>2026-02-19 07:32:58 -0600
commit8ebdbe0ea2bbf4b2ca7499d59ff9549d3e291557 (patch)
tree2110b32d1567ff172bec13a27715bad66eeb85b2 /packages
parent38f7071da95075bce7029eff52ec7153046dd318 (diff)
downloadopencode-8ebdbe0ea2bbf4b2ca7499d59ff9549d3e291557.tar.gz
opencode-8ebdbe0ea2bbf4b2ca7499d59ff9549d3e291557.zip
fix(core): text files missclassified as binary
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/file/index.ts73
-rw-r--r--packages/opencode/test/file/index.test.ts60
2 files changed, 130 insertions, 3 deletions
diff --git a/packages/opencode/src/file/index.ts b/packages/opencode/src/file/index.ts
index bfe120f13..d1d24c364 100644
--- a/packages/opencode/src/file/index.ts
+++ b/packages/opencode/src/file/index.ts
@@ -166,7 +166,6 @@ export namespace File {
"efi",
"rom",
"com",
- "bat",
"cmd",
"ps1",
"sh",
@@ -203,11 +202,77 @@ export namespace File {
"x3f",
])
+ const textExtensions = new Set([
+ "ts",
+ "tsx",
+ "mts",
+ "cts",
+ "mtsx",
+ "ctsx",
+ "js",
+ "jsx",
+ "mjs",
+ "cjs",
+ "sh",
+ "bash",
+ "zsh",
+ "fish",
+ "ps1",
+ "psm1",
+ "cmd",
+ "bat",
+ "json",
+ "jsonc",
+ "json5",
+ "yaml",
+ "yml",
+ "toml",
+ "md",
+ "mdx",
+ "txt",
+ "xml",
+ "html",
+ "htm",
+ "css",
+ "scss",
+ "sass",
+ "less",
+ "graphql",
+ "gql",
+ "sql",
+ "ini",
+ "cfg",
+ "conf",
+ "env",
+ ])
+
+ const textNames = new Set([
+ "dockerfile",
+ "makefile",
+ ".gitignore",
+ ".gitattributes",
+ ".editorconfig",
+ ".npmrc",
+ ".nvmrc",
+ ".prettierrc",
+ ".eslintrc",
+ ])
+
function isImageByExtension(filepath: string): boolean {
const ext = path.extname(filepath).toLowerCase().slice(1)
return imageExtensions.has(ext)
}
+ function isTextByExtension(filepath: string): boolean {
+ const ext = path.extname(filepath).toLowerCase().slice(1)
+ return textExtensions.has(ext)
+ }
+
+ function isTextByName(filepath: string): boolean {
+ const name = path.basename(filepath).toLowerCase()
+ return textNames.has(name)
+ }
+
function getImageMimeType(filepath: string): string {
const ext = path.extname(filepath).toLowerCase().slice(1)
const mimeTypes: Record<string, string> = {
@@ -445,7 +510,9 @@ export namespace File {
return { type: "text", content: "" }
}
- if (isBinaryByExtension(file)) {
+ const text = isTextByExtension(file) || isTextByName(file)
+
+ if (isBinaryByExtension(file) && !text) {
return { type: "binary", content: "" }
}
@@ -454,7 +521,7 @@ export namespace File {
}
const mimeType = Filesystem.mimeType(full)
- const encode = await shouldEncode(mimeType)
+ const encode = text ? false : await shouldEncode(mimeType)
if (encode && !isImage(mimeType)) {
return { type: "binary", content: "", mimeType }
diff --git a/packages/opencode/test/file/index.test.ts b/packages/opencode/test/file/index.test.ts
index 758886bd5..053a64e20 100644
--- a/packages/opencode/test/file/index.test.ts
+++ b/packages/opencode/test/file/index.test.ts
@@ -283,6 +283,66 @@ describe("file/index Bun.file patterns", () => {
})
describe("shouldEncode() logic", () => {
+ test("treats .ts files as text", async () => {
+ await using tmp = await tmpdir()
+ const filepath = path.join(tmp.path, "test.ts")
+ await fs.writeFile(filepath, "export const value = 1", "utf-8")
+
+ await Instance.provide({
+ directory: tmp.path,
+ fn: async () => {
+ const result = await File.read("test.ts")
+ expect(result.type).toBe("text")
+ expect(result.content).toBe("export const value = 1")
+ },
+ })
+ })
+
+ test("treats .mts files as text", async () => {
+ await using tmp = await tmpdir()
+ const filepath = path.join(tmp.path, "test.mts")
+ await fs.writeFile(filepath, "export const value = 1", "utf-8")
+
+ await Instance.provide({
+ directory: tmp.path,
+ fn: async () => {
+ const result = await File.read("test.mts")
+ expect(result.type).toBe("text")
+ expect(result.content).toBe("export const value = 1")
+ },
+ })
+ })
+
+ test("treats .sh files as text", async () => {
+ await using tmp = await tmpdir()
+ const filepath = path.join(tmp.path, "test.sh")
+ await fs.writeFile(filepath, "#!/usr/bin/env bash\necho hello", "utf-8")
+
+ await Instance.provide({
+ directory: tmp.path,
+ fn: async () => {
+ const result = await File.read("test.sh")
+ expect(result.type).toBe("text")
+ expect(result.content).toBe("#!/usr/bin/env bash\necho hello")
+ },
+ })
+ })
+
+ test("treats Dockerfile as text", async () => {
+ await using tmp = await tmpdir()
+ const filepath = path.join(tmp.path, "Dockerfile")
+ await fs.writeFile(filepath, "FROM alpine:3.20", "utf-8")
+
+ await Instance.provide({
+ directory: tmp.path,
+ fn: async () => {
+ const result = await File.read("Dockerfile")
+ expect(result.type).toBe("text")
+ expect(result.content).toBe("FROM alpine:3.20")
+ },
+ })
+ })
+
test("returns encoding info for text files", async () => {
await using tmp = await tmpdir()
const filepath = path.join(tmp.path, "test.txt")