refactor(core): unify filesystem search service (#31566)
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { FileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { Ripgrep } from "@opencode-ai/core/filesystem/ripgrep"
|
||||
import { NonNegativeInt } from "@opencode-ai/core/schema"
|
||||
import { LSP } from "@/lsp/lsp"
|
||||
import { Schema } from "effect"
|
||||
@@ -38,6 +37,20 @@ export const FindSymbolQuery = Schema.Struct({
|
||||
query: Schema.String,
|
||||
})
|
||||
|
||||
export const LegacyMatch = Schema.Struct({
|
||||
path: Schema.Struct({ text: Schema.String }),
|
||||
lines: Schema.Struct({ text: Schema.String }),
|
||||
line_number: NonNegativeInt,
|
||||
absolute_offset: NonNegativeInt,
|
||||
submatches: Schema.Array(
|
||||
Schema.Struct({
|
||||
match: Schema.Struct({ text: Schema.String }),
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
}),
|
||||
),
|
||||
})
|
||||
|
||||
export const LegacyEntry = Schema.Struct({
|
||||
name: Schema.String,
|
||||
path: Schema.String,
|
||||
@@ -94,7 +107,7 @@ export const FileApi = HttpApi.make("file")
|
||||
.add(
|
||||
HttpApiEndpoint.get("findText", FilePaths.findText, {
|
||||
query: FindTextQuery,
|
||||
success: described(Schema.Array(Ripgrep.SearchMatch), "Matches"),
|
||||
success: described(Schema.Array(LegacyMatch), "Matches"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "find.text",
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import * as InstanceState from "@/effect/instance-state"
|
||||
import { FileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { LocationServiceMap } from "@opencode-ai/core/location-layer"
|
||||
import { Ripgrep } from "@opencode-ai/core/filesystem/ripgrep"
|
||||
import { Search } from "@opencode-ai/core/filesystem/search"
|
||||
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"
|
||||
@@ -15,7 +14,6 @@ import { InstanceHttpApi } from "../api"
|
||||
export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
const ripgrep = yield* Ripgrep.Service
|
||||
const search = yield* Search.Service
|
||||
const locations = yield* LocationServiceMap
|
||||
|
||||
const filesystem = Effect.fnUntraced(function* <A, E, R>(effect: Effect.Effect<A, E, R>) {
|
||||
@@ -26,8 +24,18 @@ export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handl
|
||||
|
||||
const findText = Effect.fn("FileHttpApi.findText")(function* (ctx: { query: { pattern: string } }) {
|
||||
return (yield* ripgrep
|
||||
.search({ cwd: (yield* InstanceState.context).directory, pattern: ctx.query.pattern, limit: 10 })
|
||||
.pipe(Effect.orDie)).items
|
||||
.grep({ cwd: (yield* InstanceState.context).directory, pattern: ctx.query.pattern, limit: 10 })
|
||||
.pipe(Effect.orDie)).map((match) => ({
|
||||
path: { text: match.entry.path },
|
||||
lines: { text: match.text },
|
||||
line_number: match.line,
|
||||
absolute_offset: match.offset,
|
||||
submatches: match.submatches.map((submatch) => ({
|
||||
match: { text: submatch.text },
|
||||
start: submatch.start,
|
||||
end: submatch.end,
|
||||
})),
|
||||
}))
|
||||
})
|
||||
|
||||
const findFile = Effect.fn("FileHttpApi.findFile")(function* (ctx: {
|
||||
@@ -35,19 +43,18 @@ export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handl
|
||||
}) {
|
||||
const directory = (yield* InstanceState.context).directory
|
||||
const limit = ctx.query.limit ?? 10
|
||||
const kind = ctx.query.type ?? (ctx.query.dirs === "false" ? "file" : "all")
|
||||
const type = ctx.query.type ?? (ctx.query.dirs === "false" ? "file" : undefined)
|
||||
const started = performance.now()
|
||||
const fff = yield* search.file({ cwd: directory, query: ctx.query.query, limit, kind }).pipe(Effect.orDie)
|
||||
const found = yield* filesystem(FileSystem.Service.use((fs) => fs.find({ query: ctx.query.query, limit, type })))
|
||||
yield* Effect.logInfo("find file", {
|
||||
engine: "fff",
|
||||
query: ctx.query.query,
|
||||
kind,
|
||||
type,
|
||||
directory,
|
||||
limit,
|
||||
results: fff.length,
|
||||
results: found.length,
|
||||
duration: Math.round(performance.now() - started),
|
||||
})
|
||||
return fff.map((item) => item.path)
|
||||
return found.map((item) => item.path)
|
||||
})
|
||||
|
||||
const findSymbol = Effect.fn("FileHttpApi.findSymbol")(function* () {
|
||||
@@ -73,10 +80,10 @@ export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handl
|
||||
return (yield* fs.list({ path: RelativePath.make(ctx.query.path) })).map((item) => ({
|
||||
name: path.basename(item.path),
|
||||
path: item.path,
|
||||
absolute: path.join(directory, item.path),
|
||||
absolute: path.resolve(location.directory, item.path),
|
||||
type: item.type,
|
||||
ignored: ignored.ignores(
|
||||
path.relative(location.project.directory, path.join(location.directory, item.path)) +
|
||||
path.relative(location.project.directory, path.resolve(location.directory, item.path)) +
|
||||
(item.type === "directory" ? "/" : ""),
|
||||
),
|
||||
}))
|
||||
@@ -112,4 +119,4 @@ export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handl
|
||||
.handle("content", content)
|
||||
.handle("status", status)
|
||||
}),
|
||||
).pipe(Layer.provide(LocationServiceMap.layer), Layer.provide(Search.defaultLayer))
|
||||
).pipe(Layer.provide(LocationServiceMap.layer))
|
||||
|
||||
@@ -17,7 +17,7 @@ import { BackgroundJob } from "@/background/job"
|
||||
import { Config } from "@/config/config"
|
||||
import { Command } from "@/command"
|
||||
import * as Observability from "@opencode-ai/core/observability"
|
||||
import { Ripgrep } from "@opencode-ai/core/filesystem/ripgrep"
|
||||
import { Ripgrep } from "@opencode-ai/core/ripgrep"
|
||||
import { Format } from "@/format"
|
||||
import { RuntimeFlags } from "@/effect/runtime-flags"
|
||||
import { LSP } from "@/lsp/lsp"
|
||||
@@ -234,7 +234,6 @@ export function createRoutes(
|
||||
Provider.defaultLayer,
|
||||
PtyTicket.defaultLayer,
|
||||
Question.defaultLayer,
|
||||
Ripgrep.defaultLayer,
|
||||
RuntimeFlags.defaultLayer,
|
||||
Session.defaultLayer,
|
||||
SessionCompaction.defaultLayer,
|
||||
@@ -259,6 +258,7 @@ export function createRoutes(
|
||||
HttpServer.layerServices,
|
||||
]),
|
||||
Layer.provide(Layer.succeed(CorsConfig)(corsOptions)),
|
||||
Layer.provideMerge(Ripgrep.defaultLayer),
|
||||
Layer.provide(InstanceLayer.layer),
|
||||
Layer.provideMerge(Observability.layer),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user