refactor(server): serve raw filesystem content (#31911)

This commit is contained in:
Dax
2026-06-11 11:20:11 -04:00
committed by GitHub
parent 31b233e9db
commit 31c5454ee6
12 changed files with 67 additions and 93 deletions
+5 -2
View File
@@ -38,8 +38,11 @@ const FileReadCommand = effectCmd({
description: "File path to read",
}),
handler: Effect.fn("Cli.debug.file.read")(function* (args) {
const content = yield* filesystem(FileSystem.Service.use((svc) => svc.read({ path: RelativePath.make(args.path) })))
process.stdout.write(JSON.stringify(content, null, 2) + EOL)
const file = yield* filesystem(FileSystem.Service.use((svc) => svc.read({ path: RelativePath.make(args.path) })))
process.stdout.write(
JSON.stringify({ content: Buffer.from(file.content).toString("base64"), encoding: "base64", mime: file.mime }, null, 2) +
EOL,
)
}),
})
@@ -5,7 +5,7 @@ import { Ripgrep } from "@opencode-ai/core/ripgrep"
import { FSUtil } from "@opencode-ai/core/fs-util"
import { Location } from "@opencode-ai/core/location"
import { AbsolutePath, RelativePath } from "@opencode-ai/core/schema"
import { Effect, Layer } from "effect"
import { Effect, Layer, Option } from "effect"
import ignore from "ignore"
import path from "path"
import { HttpApiBuilder } from "effect/unstable/httpapi"
@@ -101,11 +101,26 @@ export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handl
return yield* filesystem(
FileSystem.Service.use((fs) => fs.read({ path: RelativePath.make(ctx.query.path) })),
).pipe(
Effect.map((item) => ({
type: item.encoding === "utf8" ? ("text" as const) : ("binary" as const),
content: item.encoding === "utf8" ? item.content.trim() : item.content,
...(item.encoding === "base64" ? { encoding: item.encoding, mimeType: item.mime } : {}),
})),
Effect.flatMap((item) =>
Effect.gen(function* () {
const text = item.content.includes(0)
? Option.none<string>()
: yield* Effect.sync(() => new TextDecoder("utf-8", { fatal: true }).decode(item.content)).pipe(
Effect.option,
)
return { item, text }
}),
),
Effect.map(({ item, text }) =>
Option.isSome(text)
? { type: "text" as const, content: text.value.trim() }
: {
type: "binary" as const,
content: Buffer.from(item.content).toString("base64"),
encoding: "base64" as const,
mimeType: item.mime,
},
),
)
})